blob: 1d9ccb1c216abc18fb6eb2b750494e7752e2b04e [file] [log] [blame]
Mathias Agopian65ab4712010-07-14 17:59:35 -07001/*
Ruben Brunkd1176ef2014-02-21 10:51:38 -08002 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Mathias Agopian65ab4712010-07-14 17:59:35 -070016
17#define LOG_TAG "CameraService"
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -070018#define ATRACE_TAG ATRACE_TAG_CAMERA
Iliyan Malchev8951a972011-04-14 16:55:59 -070019//#define LOG_NDEBUG 0
Mathias Agopian65ab4712010-07-14 17:59:35 -070020
Ruben Brunkcc776712015-02-17 20:18:47 -080021#include <algorithm>
22#include <climits>
Mathias Agopian65ab4712010-07-14 17:59:35 -070023#include <stdio.h>
Ruben Brunkcc776712015-02-17 20:18:47 -080024#include <cstring>
25#include <ctime>
26#include <string>
Mathias Agopian65ab4712010-07-14 17:59:35 -070027#include <sys/types.h>
Ruben Brunkcc776712015-02-17 20:18:47 -080028#include <inttypes.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070029#include <pthread.h>
30
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080031#include <android/hardware/ICamera.h>
32#include <android/hardware/ICameraClient.h>
33
Alex Deymo9c2a2c22016-08-25 11:59:14 -070034#include <android-base/macros.h>
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -080035#include <binder/AppOpsManager.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070036#include <binder/IPCThreadState.h>
37#include <binder/IServiceManager.h>
38#include <binder/MemoryBase.h>
39#include <binder/MemoryHeapBase.h>
Ruben Brunkcc776712015-02-17 20:18:47 -080040#include <binder/ProcessInfoService.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070041#include <cutils/atomic.h>
Nipun Kwatrab5ca4612010-09-11 19:31:10 -070042#include <cutils/properties.h>
Mathias Agopiandf712ea2012-02-25 18:48:35 -080043#include <gui/Surface.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070044#include <hardware/hardware.h>
Eino-Ville Talvalad89821e2016-04-20 11:23:50 -070045#include <memunreachable/memunreachable.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070046#include <media/AudioSystem.h>
Andreas Huber1b86fe02014-01-29 11:13:26 -080047#include <media/IMediaHTTPService.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070048#include <media/mediaplayer.h>
Ruben Brunk99e69712015-05-26 17:25:07 -070049#include <mediautils/BatteryNotifier.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070050#include <utils/Errors.h>
51#include <utils/Log.h>
52#include <utils/String16.h>
Ruben Brunkd1176ef2014-02-21 10:51:38 -080053#include <utils/Trace.h>
Chien-Yu Chen98a668f2015-12-18 14:10:33 -080054#include <private/android_filesystem_config.h>
Ruben Brunkd1176ef2014-02-21 10:51:38 -080055#include <system/camera_vendor_tags.h>
Ruben Brunkb2119af2014-05-09 19:57:56 -070056#include <system/camera_metadata.h>
57#include <system/camera.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070058
59#include "CameraService.h"
Eino-Ville Talvala7b82efe2013-07-25 17:12:35 -070060#include "api1/CameraClient.h"
61#include "api1/Camera2Client.h"
Eino-Ville Talvala7b82efe2013-07-25 17:12:35 -070062#include "api2/CameraDeviceClient.h"
Igor Murashkinff3e31d2013-10-23 16:40:06 -070063#include "utils/CameraTraces.h"
Mathias Agopian65ab4712010-07-14 17:59:35 -070064
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080065namespace {
66 const char* kPermissionServiceName = "permission";
67}; // namespace anonymous
68
Mathias Agopian65ab4712010-07-14 17:59:35 -070069namespace android {
70
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080071using binder::Status;
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -080072using hardware::ICamera;
73using hardware::ICameraClient;
74using hardware::ICameraServiceListener;
75using hardware::camera::common::V1_0::CameraDeviceStatus;
76using hardware::camera::common::V1_0::TorchModeStatus;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080077
Mathias Agopian65ab4712010-07-14 17:59:35 -070078// ----------------------------------------------------------------------------
79// Logging support -- this is for debugging only
80// Use "adb shell dumpsys media.camera -v 1" to change it.
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -070081volatile int32_t gLogLevel = 0;
Mathias Agopian65ab4712010-07-14 17:59:35 -070082
Steve Blockb8a80522011-12-20 16:23:08 +000083#define LOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__);
84#define LOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__);
Mathias Agopian65ab4712010-07-14 17:59:35 -070085
86static void setLogLevel(int level) {
87 android_atomic_write(level, &gLogLevel);
88}
89
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080090// Convenience methods for constructing binder::Status objects for error returns
91
92#define STATUS_ERROR(errorCode, errorString) \
93 binder::Status::fromServiceSpecificError(errorCode, \
94 String8::format("%s:%d: %s", __FUNCTION__, __LINE__, errorString))
95
96#define STATUS_ERROR_FMT(errorCode, errorString, ...) \
97 binder::Status::fromServiceSpecificError(errorCode, \
98 String8::format("%s:%d: " errorString, __FUNCTION__, __LINE__, \
99 __VA_ARGS__))
100
Mathias Agopian65ab4712010-07-14 17:59:35 -0700101// ----------------------------------------------------------------------------
102
Igor Murashkincba2c162013-03-20 15:56:31 -0700103extern "C" {
104static void camera_device_status_change(
105 const struct camera_module_callbacks* callbacks,
106 int camera_id,
107 int new_status) {
108 sp<CameraService> cs = const_cast<CameraService*>(
Ruben Brunkcc776712015-02-17 20:18:47 -0800109 static_cast<const CameraService*>(callbacks));
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800110 String8 id = String8::format("%d", camera_id);
Igor Murashkincba2c162013-03-20 15:56:31 -0700111
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800112 CameraDeviceStatus newStatus{CameraDeviceStatus::NOT_PRESENT};
113 switch (new_status) {
114 case CAMERA_DEVICE_STATUS_NOT_PRESENT:
115 newStatus = CameraDeviceStatus::NOT_PRESENT;
116 break;
117 case CAMERA_DEVICE_STATUS_PRESENT:
118 newStatus = CameraDeviceStatus::PRESENT;
119 break;
120 case CAMERA_DEVICE_STATUS_ENUMERATING:
121 newStatus = CameraDeviceStatus::ENUMERATING;
122 break;
123 default:
124 ALOGW("Unknown device status change to %d", new_status);
125 break;
126 }
127 cs->onDeviceStatusChanged(id, newStatus);
Igor Murashkincba2c162013-03-20 15:56:31 -0700128}
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800129
130static void torch_mode_status_change(
131 const struct camera_module_callbacks* callbacks,
132 const char* camera_id,
133 int new_status) {
134 if (!callbacks || !camera_id) {
135 ALOGE("%s invalid parameters. callbacks %p, camera_id %p", __FUNCTION__,
136 callbacks, camera_id);
137 }
138 sp<CameraService> cs = const_cast<CameraService*>(
139 static_cast<const CameraService*>(callbacks));
140
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800141 TorchModeStatus status;
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800142 switch (new_status) {
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800143 case TORCH_MODE_STATUS_NOT_AVAILABLE:
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800144 status = TorchModeStatus::NOT_AVAILABLE;
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800145 break;
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800146 case TORCH_MODE_STATUS_AVAILABLE_OFF:
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800147 status = TorchModeStatus::AVAILABLE_OFF;
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800148 break;
149 case TORCH_MODE_STATUS_AVAILABLE_ON:
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800150 status = TorchModeStatus::AVAILABLE_ON;
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800151 break;
152 default:
153 ALOGE("Unknown torch status %d", new_status);
154 return;
155 }
156
157 cs->onTorchStatusChanged(
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800158 String8(camera_id),
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800159 status);
160}
Igor Murashkincba2c162013-03-20 15:56:31 -0700161} // extern "C"
162
Mathias Agopian65ab4712010-07-14 17:59:35 -0700163// ----------------------------------------------------------------------------
164
165// This is ugly and only safe if we never re-create the CameraService, but
166// should be ok for now.
167static CameraService *gCameraService;
168
Eino-Ville Talvala49c97052016-01-12 14:29:40 -0800169CameraService::CameraService() :
170 mEventLog(DEFAULT_EVENT_LOG_LENGTH),
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800171 mNumberOfCameras(0), mNumberOfNormalCameras(0),
172 mSoundRef(0), mModule(nullptr) {
Steve Blockdf64d152012-01-04 20:05:49 +0000173 ALOGI("CameraService started (pid=%d)", getpid());
Mathias Agopian65ab4712010-07-14 17:59:35 -0700174 gCameraService = this;
Igor Murashkinbfc99152013-02-27 12:55:20 -0800175
Igor Murashkincba2c162013-03-20 15:56:31 -0700176 this->camera_device_status_change = android::camera_device_status_change;
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800177 this->torch_mode_status_change = android::torch_mode_status_change;
178
Ruben Brunkcc776712015-02-17 20:18:47 -0800179 mServiceLockWrapper = std::make_shared<WaitableMutexWrapper>(&mServiceLock);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700180}
181
Iliyan Malchev8951a972011-04-14 16:55:59 -0700182void CameraService::onFirstRef()
183{
Ruben Brunkcc776712015-02-17 20:18:47 -0800184 ALOGI("CameraService process starting");
Igor Murashkin634a5152013-02-20 17:15:11 -0800185
Iliyan Malchev8951a972011-04-14 16:55:59 -0700186 BnCameraService::onFirstRef();
187
Ruben Brunk99e69712015-05-26 17:25:07 -0700188 // Update battery life tracking if service is restarting
189 BatteryNotifier& notifier(BatteryNotifier::getInstance());
190 notifier.noteResetCamera();
191 notifier.noteResetFlashlight();
192
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800193 camera_module_t *rawModule;
Eino-Ville Talvala1527f072015-04-07 15:55:31 -0700194 int err = hw_get_module(CAMERA_HARDWARE_MODULE_ID,
195 (const hw_module_t **)&rawModule);
196 if (err < 0) {
197 ALOGE("Could not load camera HAL module: %d (%s)", err, strerror(-err));
198 logServiceError("Could not load camera HAL module", err);
Eino-Ville Talvala1527f072015-04-07 15:55:31 -0700199 return;
Iliyan Malchev8951a972011-04-14 16:55:59 -0700200 }
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800201
Eino-Ville Talvala1527f072015-04-07 15:55:31 -0700202 mModule = new CameraModule(rawModule);
Eino-Ville Talvala1527f072015-04-07 15:55:31 -0700203 err = mModule->init();
204 if (err != OK) {
205 ALOGE("Could not initialize camera HAL module: %d (%s)", err,
206 strerror(-err));
207 logServiceError("Could not initialize camera HAL module", err);
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800208
Eino-Ville Talvala1527f072015-04-07 15:55:31 -0700209 delete mModule;
210 mModule = nullptr;
211 return;
Iliyan Malchev8951a972011-04-14 16:55:59 -0700212 }
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -0700213 ALOGI("Loaded \"%s\" camera module", mModule->getModuleName());
Eino-Ville Talvala1527f072015-04-07 15:55:31 -0700214
215 mNumberOfCameras = mModule->getNumberOfCameras();
Eino-Ville Talvalabad43582015-08-14 13:12:32 -0700216 mNumberOfNormalCameras = mNumberOfCameras;
Eino-Ville Talvala1527f072015-04-07 15:55:31 -0700217
Yin-Chia Yehd4a653a2015-10-14 11:05:44 -0700218 // Setup vendor tags before we call get_camera_info the first time
219 // because HAL might need to setup static vendor keys in get_camera_info
220 VendorTagDescriptor::clearGlobalVendorTagDescriptor();
221 if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_2) {
222 setUpVendorTags();
223 }
224
Eino-Ville Talvala1527f072015-04-07 15:55:31 -0700225 mFlashlight = new CameraFlashlight(*mModule, *this);
226 status_t res = mFlashlight->findFlashUnits();
227 if (res) {
228 // impossible because we haven't open any camera devices.
229 ALOGE("Failed to find flash units.");
230 }
231
Eino-Ville Talvalabad43582015-08-14 13:12:32 -0700232 int latestStrangeCameraId = INT_MAX;
Eino-Ville Talvala1527f072015-04-07 15:55:31 -0700233 for (int i = 0; i < mNumberOfCameras; i++) {
234 String8 cameraId = String8::format("%d", i);
235
Eino-Ville Talvalabad43582015-08-14 13:12:32 -0700236 // Get camera info
237
238 struct camera_info info;
239 bool haveInfo = true;
240 status_t rc = mModule->getCameraInfo(i, &info);
241 if (rc != NO_ERROR) {
242 ALOGE("%s: Received error loading camera info for device %d, cost and"
243 " conflicting devices fields set to defaults for this device.",
244 __FUNCTION__, i);
245 haveInfo = false;
246 }
247
248 // Check for backwards-compatibility support
249 if (haveInfo) {
250 if (checkCameraCapabilities(i, info, &latestStrangeCameraId) != OK) {
251 delete mModule;
252 mModule = nullptr;
253 return;
254 }
255 }
256
Eino-Ville Talvala1527f072015-04-07 15:55:31 -0700257 // Defaults to use for cost and conflicting devices
258 int cost = 100;
259 char** conflicting_devices = nullptr;
260 size_t conflicting_devices_length = 0;
261
262 // If using post-2.4 module version, query the cost + conflicting devices from the HAL
Eino-Ville Talvalabad43582015-08-14 13:12:32 -0700263 if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_4 && haveInfo) {
264 cost = info.resource_cost;
265 conflicting_devices = info.conflicting_devices;
266 conflicting_devices_length = info.conflicting_devices_length;
Eino-Ville Talvala1527f072015-04-07 15:55:31 -0700267 }
268
269 std::set<String8> conflicting;
270 for (size_t i = 0; i < conflicting_devices_length; i++) {
271 conflicting.emplace(String8(conflicting_devices[i]));
272 }
273
274 // Initialize state for each camera device
275 {
276 Mutex::Autolock lock(mCameraStatesLock);
277 mCameraStates.emplace(cameraId, std::make_shared<CameraState>(cameraId, cost,
278 conflicting));
279 }
280
281 if (mFlashlight->hasFlashUnit(cameraId)) {
282 mTorchStatusMap.add(cameraId,
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800283 TorchModeStatus::AVAILABLE_OFF);
Eino-Ville Talvala1527f072015-04-07 15:55:31 -0700284 }
285 }
286
287 if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_1) {
288 mModule->setCallbacks(this);
289 }
290
Ruben Brunk2823ce02015-05-19 17:25:13 -0700291 CameraService::pingCameraServiceProxy();
292}
293
Eino-Ville Talvala412fe562015-08-20 17:08:32 -0700294sp<ICameraServiceProxy> CameraService::getCameraServiceProxy() {
Christopher Wiley92c06fc2016-02-11 15:40:05 -0800295 sp<ICameraServiceProxy> proxyBinder = nullptr;
296#ifndef __BRILLO__
Ruben Brunk2823ce02015-05-19 17:25:13 -0700297 sp<IServiceManager> sm = defaultServiceManager();
Eino-Ville Talvalaf4db13d2016-12-08 11:20:51 -0800298 // Use checkService because cameraserver normally starts before the
299 // system server and the proxy service. So the long timeout that getService
300 // has before giving up is inappropriate.
301 sp<IBinder> binder = sm->checkService(String16("media.camera.proxy"));
Christopher Wiley92c06fc2016-02-11 15:40:05 -0800302 if (binder != nullptr) {
303 proxyBinder = interface_cast<ICameraServiceProxy>(binder);
Ruben Brunk2823ce02015-05-19 17:25:13 -0700304 }
Christopher Wiley92c06fc2016-02-11 15:40:05 -0800305#endif
Eino-Ville Talvala412fe562015-08-20 17:08:32 -0700306 return proxyBinder;
307}
308
309void CameraService::pingCameraServiceProxy() {
310 sp<ICameraServiceProxy> proxyBinder = getCameraServiceProxy();
311 if (proxyBinder == nullptr) return;
Ruben Brunk2823ce02015-05-19 17:25:13 -0700312 proxyBinder->pingForUserUpdate();
Iliyan Malchev8951a972011-04-14 16:55:59 -0700313}
314
Mathias Agopian65ab4712010-07-14 17:59:35 -0700315CameraService::~CameraService() {
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800316 if (mModule) {
317 delete mModule;
Ruben Brunkcc776712015-02-17 20:18:47 -0800318 mModule = nullptr;
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800319 }
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800320 VendorTagDescriptor::clearGlobalVendorTagDescriptor();
Ruben Brunkcc776712015-02-17 20:18:47 -0800321 gCameraService = nullptr;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700322}
323
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800324void CameraService::onDeviceStatusChanged(const String8& id,
325 CameraDeviceStatus newHalStatus) {
326 ALOGI("%s: Status changed for cameraId=%s, newStatus=%d", __FUNCTION__,
327 id.string(), newHalStatus);
Igor Murashkincba2c162013-03-20 15:56:31 -0700328
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800329 StatusInternal newStatus = mapToInternal(newHalStatus);
330
Ruben Brunkcc776712015-02-17 20:18:47 -0800331 std::shared_ptr<CameraState> state = getCameraState(id);
332
333 if (state == nullptr) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800334 ALOGE("%s: Bad camera ID %s", __FUNCTION__, id.string());
Igor Murashkincba2c162013-03-20 15:56:31 -0700335 return;
336 }
337
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800338 StatusInternal oldStatus = state->getStatus();
Ruben Brunkcc776712015-02-17 20:18:47 -0800339
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800340 if (oldStatus == newStatus) {
Ruben Brunkcc776712015-02-17 20:18:47 -0800341 ALOGE("%s: State transition to the same status %#x not allowed", __FUNCTION__, newStatus);
Igor Murashkincba2c162013-03-20 15:56:31 -0700342 return;
343 }
344
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800345 if (newStatus == StatusInternal::NOT_PRESENT) {
Ruben Brunka8ca9152015-04-07 14:23:40 -0700346 logDeviceRemoved(id, String8::format("Device status changed from %d to %d", oldStatus,
347 newStatus));
Ruben Brunkcc776712015-02-17 20:18:47 -0800348 sp<BasicClient> clientToDisconnect;
Igor Murashkincba2c162013-03-20 15:56:31 -0700349 {
Ruben Brunkcc776712015-02-17 20:18:47 -0800350 // Don't do this in updateStatus to avoid deadlock over mServiceLock
351 Mutex::Autolock lock(mServiceLock);
Igor Murashkincba2c162013-03-20 15:56:31 -0700352
Ruben Brunkcc776712015-02-17 20:18:47 -0800353 // Set the device status to NOT_PRESENT, clients will no longer be able to connect
354 // to this device until the status changes
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800355 updateStatus(StatusInternal::NOT_PRESENT, id);
Ruben Brunkb2119af2014-05-09 19:57:56 -0700356
Ruben Brunkcc776712015-02-17 20:18:47 -0800357 // Remove cached shim parameters
358 state->setShimParams(CameraParameters());
Igor Murashkincba2c162013-03-20 15:56:31 -0700359
Ruben Brunkcc776712015-02-17 20:18:47 -0800360 // Remove the client from the list of active clients
361 clientToDisconnect = removeClientLocked(id);
362
363 // Notify the client of disconnection
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800364 clientToDisconnect->notifyError(
365 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED,
Ruben Brunkcc776712015-02-17 20:18:47 -0800366 CaptureResultExtras{});
Igor Murashkincba2c162013-03-20 15:56:31 -0700367 }
368
Ruben Brunkcc776712015-02-17 20:18:47 -0800369 ALOGI("%s: Client for camera ID %s evicted due to device status change from HAL",
370 __FUNCTION__, id.string());
Igor Murashkincba2c162013-03-20 15:56:31 -0700371
Ruben Brunkcc776712015-02-17 20:18:47 -0800372 // Disconnect client
373 if (clientToDisconnect.get() != nullptr) {
374 // Ensure not in binder RPC so client disconnect PID checks work correctly
375 LOG_ALWAYS_FATAL_IF(getCallingPid() != getpid(),
376 "onDeviceStatusChanged must be called from the camera service process!");
377 clientToDisconnect->disconnect();
Igor Murashkincba2c162013-03-20 15:56:31 -0700378 }
379
Ruben Brunkcc776712015-02-17 20:18:47 -0800380 } else {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800381 if (oldStatus == StatusInternal::NOT_PRESENT) {
Ruben Brunka8ca9152015-04-07 14:23:40 -0700382 logDeviceAdded(id, String8::format("Device status changed from %d to %d", oldStatus,
383 newStatus));
384 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800385 updateStatus(newStatus, id);
Igor Murashkincba2c162013-03-20 15:56:31 -0700386 }
387
Igor Murashkincba2c162013-03-20 15:56:31 -0700388}
389
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800390void CameraService::onTorchStatusChanged(const String8& cameraId,
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800391 TorchModeStatus newStatus) {
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800392 Mutex::Autolock al(mTorchStatusMutex);
393 onTorchStatusChangedLocked(cameraId, newStatus);
394}
395
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800396void CameraService::onTorchStatusChangedLocked(const String8& cameraId,
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800397 TorchModeStatus newStatus) {
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800398 ALOGI("%s: Torch status changed for cameraId=%s, newStatus=%d",
399 __FUNCTION__, cameraId.string(), newStatus);
400
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800401 TorchModeStatus status;
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800402 status_t res = getTorchStatusLocked(cameraId, &status);
403 if (res) {
Chien-Yu Chenf6463fc2015-04-07 15:11:31 -0700404 ALOGE("%s: cannot get torch status of camera %s: %s (%d)",
405 __FUNCTION__, cameraId.string(), strerror(-res), res);
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800406 return;
407 }
408 if (status == newStatus) {
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800409 return;
410 }
411
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800412 res = setTorchStatusLocked(cameraId, newStatus);
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800413 if (res) {
Eino-Ville Talvalad309fb92015-11-25 12:12:45 -0800414 ALOGE("%s: Failed to set the torch status to %d: %s (%d)", __FUNCTION__,
415 (uint32_t)newStatus, strerror(-res), res);
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800416 return;
417 }
418
Ruben Brunkcc776712015-02-17 20:18:47 -0800419 {
Ruben Brunk99e69712015-05-26 17:25:07 -0700420 // Update battery life logging for flashlight
Chien-Yu Chenfe751be2015-09-01 14:16:44 -0700421 Mutex::Autolock al(mTorchUidMapMutex);
Ruben Brunk99e69712015-05-26 17:25:07 -0700422 auto iter = mTorchUidMap.find(cameraId);
423 if (iter != mTorchUidMap.end()) {
424 int oldUid = iter->second.second;
425 int newUid = iter->second.first;
426 BatteryNotifier& notifier(BatteryNotifier::getInstance());
427 if (oldUid != newUid) {
428 // If the UID has changed, log the status and update current UID in mTorchUidMap
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800429 if (status == TorchModeStatus::AVAILABLE_ON) {
Ruben Brunk99e69712015-05-26 17:25:07 -0700430 notifier.noteFlashlightOff(cameraId, oldUid);
431 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800432 if (newStatus == TorchModeStatus::AVAILABLE_ON) {
Ruben Brunk99e69712015-05-26 17:25:07 -0700433 notifier.noteFlashlightOn(cameraId, newUid);
434 }
435 iter->second.second = newUid;
436 } else {
437 // If the UID has not changed, log the status
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800438 if (newStatus == TorchModeStatus::AVAILABLE_ON) {
Ruben Brunk99e69712015-05-26 17:25:07 -0700439 notifier.noteFlashlightOn(cameraId, oldUid);
440 } else {
441 notifier.noteFlashlightOff(cameraId, oldUid);
442 }
443 }
444 }
445 }
446
447 {
Ruben Brunkcc776712015-02-17 20:18:47 -0800448 Mutex::Autolock lock(mStatusListenerLock);
449 for (auto& i : mListenerList) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800450 i->onTorchStatusChanged(mapToInterface(newStatus), String16{cameraId});
Ruben Brunkcc776712015-02-17 20:18:47 -0800451 }
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800452 }
453}
454
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800455Status CameraService::getNumberOfCameras(int32_t type, int32_t* numCameras) {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -0700456 ATRACE_CALL();
Eino-Ville Talvalabad43582015-08-14 13:12:32 -0700457 switch (type) {
458 case CAMERA_TYPE_BACKWARD_COMPATIBLE:
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800459 *numCameras = mNumberOfNormalCameras;
460 break;
Eino-Ville Talvalabad43582015-08-14 13:12:32 -0700461 case CAMERA_TYPE_ALL:
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800462 *numCameras = mNumberOfCameras;
463 break;
Eino-Ville Talvalabad43582015-08-14 13:12:32 -0700464 default:
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800465 ALOGW("%s: Unknown camera type %d",
Eino-Ville Talvalabad43582015-08-14 13:12:32 -0700466 __FUNCTION__, type);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800467 return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
468 "Unknown camera type %d", type);
Eino-Ville Talvalabad43582015-08-14 13:12:32 -0700469 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800470 return Status::ok();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700471}
472
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800473Status CameraService::getCameraInfo(int cameraId,
474 CameraInfo* cameraInfo) {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -0700475 ATRACE_CALL();
Iliyan Malchev8951a972011-04-14 16:55:59 -0700476 if (!mModule) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800477 return STATUS_ERROR(ERROR_DISCONNECTED,
478 "Camera subsystem is not available");
Iliyan Malchev8951a972011-04-14 16:55:59 -0700479 }
480
Mathias Agopian65ab4712010-07-14 17:59:35 -0700481 if (cameraId < 0 || cameraId >= mNumberOfCameras) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800482 return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT,
483 "CameraId is not valid");
Mathias Agopian65ab4712010-07-14 17:59:35 -0700484 }
485
Iliyan Malchev8951a972011-04-14 16:55:59 -0700486 struct camera_info info;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800487 Status rc = filterGetInfoErrorCode(
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800488 mModule->getCameraInfo(cameraId, &info));
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800489
490 if (rc.isOk()) {
491 cameraInfo->facing = info.facing;
492 cameraInfo->orientation = info.orientation;
Yin-Chia Yeh9b5a6e92016-04-22 13:24:05 -0700493 // CameraInfo is for android.hardware.Camera which does not
494 // support external camera facing. The closest approximation would be
495 // front camera.
Yin-Chia Yeh13cd59a2016-11-29 12:13:15 -0800496 if (cameraInfo->facing == CAMERA_FACING_EXTERNAL) {
497 cameraInfo->facing = CAMERA_FACING_FRONT;
Yin-Chia Yeh9b5a6e92016-04-22 13:24:05 -0700498 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800499 }
Iliyan Malchev8951a972011-04-14 16:55:59 -0700500 return rc;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700501}
502
Ruben Brunkcc776712015-02-17 20:18:47 -0800503int CameraService::cameraIdToInt(const String8& cameraId) {
504 errno = 0;
505 size_t pos = 0;
506 int ret = stoi(std::string{cameraId.string()}, &pos);
507 if (errno != 0 || pos != cameraId.size()) {
508 return -1;
509 }
510 return ret;
511}
Ruben Brunkb2119af2014-05-09 19:57:56 -0700512
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800513Status CameraService::getCameraCharacteristics(const String16& id,
514 CameraMetadata* cameraInfo) {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -0700515 ATRACE_CALL();
Zhijun He2b59be82013-09-25 10:14:30 -0700516 if (!cameraInfo) {
517 ALOGE("%s: cameraInfo is NULL", __FUNCTION__);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800518 return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "cameraInfo is NULL");
Zhijun He2b59be82013-09-25 10:14:30 -0700519 }
520
521 if (!mModule) {
522 ALOGE("%s: camera hardware module doesn't exist", __FUNCTION__);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800523 return STATUS_ERROR(ERROR_DISCONNECTED,
524 "Camera subsystem is not available");;
Zhijun He2b59be82013-09-25 10:14:30 -0700525 }
526
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800527 int cameraId = cameraIdToInt(String8(id));
528
Zhijun He2b59be82013-09-25 10:14:30 -0700529 if (cameraId < 0 || cameraId >= mNumberOfCameras) {
530 ALOGE("%s: Invalid camera id: %d", __FUNCTION__, cameraId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800531 return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
532 "Invalid camera id: %d", cameraId);
Zhijun He2b59be82013-09-25 10:14:30 -0700533 }
534
535 int facing;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800536 Status ret;
Chien-Yu Chen676b21b2015-02-24 10:28:19 -0800537 if (mModule->getModuleApiVersion() < CAMERA_MODULE_API_VERSION_2_0 ||
Eino-Ville Talvalad309fb92015-11-25 12:12:45 -0800538 getDeviceVersion(cameraId, &facing) < CAMERA_DEVICE_API_VERSION_3_0) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800539 return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT, "Can't get camera characteristics"
540 " for devices with HAL version < 3.0, %d is version %x", cameraId,
541 getDeviceVersion(cameraId, &facing));
542 }
543 struct camera_info info;
544 ret = filterGetInfoErrorCode(mModule->getCameraInfo(cameraId, &info));
545 if (ret.isOk()) {
546 *cameraInfo = info.static_camera_characteristics;
Ruben Brunkb2119af2014-05-09 19:57:56 -0700547 }
Zhijun He2b59be82013-09-25 10:14:30 -0700548
549 return ret;
550}
551
Ruben Brunkcc776712015-02-17 20:18:47 -0800552int CameraService::getCallingPid() {
553 return IPCThreadState::self()->getCallingPid();
554}
555
556int CameraService::getCallingUid() {
557 return IPCThreadState::self()->getCallingUid();
558}
559
560String8 CameraService::getFormattedCurrentTime() {
561 time_t now = time(nullptr);
562 char formattedTime[64];
563 strftime(formattedTime, sizeof(formattedTime), "%m-%d %H:%M:%S", localtime(&now));
564 return String8(formattedTime);
565}
566
567int CameraService::getCameraPriorityFromProcState(int procState) {
568 // Find the priority for the camera usage based on the process state. Higher priority clients
569 // win for evictions.
Ruben Brunkbe0b6b42015-05-12 16:10:52 -0700570 if (procState < 0) {
571 ALOGE("%s: Received invalid process state %d from ActivityManagerService!", __FUNCTION__,
572 procState);
573 return -1;
Ruben Brunkcc776712015-02-17 20:18:47 -0800574 }
Eino-Ville Talvala52aad852015-09-03 12:24:24 -0700575 // Treat sleeping TOP processes the same as regular TOP processes, for
576 // access priority. This is important for lock-screen camera launch scenarios
577 if (procState == PROCESS_STATE_TOP_SLEEPING) {
578 procState = PROCESS_STATE_TOP;
579 }
Ruben Brunkbe0b6b42015-05-12 16:10:52 -0700580 return INT_MAX - procState;
Ruben Brunkcc776712015-02-17 20:18:47 -0800581}
582
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800583Status CameraService::getCameraVendorTagDescriptor(
584 /*out*/
585 hardware::camera2::params::VendorTagDescriptor* desc) {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -0700586 ATRACE_CALL();
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800587 if (!mModule) {
588 ALOGE("%s: camera hardware module doesn't exist", __FUNCTION__);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800589 return STATUS_ERROR(ERROR_DISCONNECTED, "Camera subsystem not available");
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800590 }
Eino-Ville Talvala1e74e242016-03-03 11:24:28 -0800591 sp<VendorTagDescriptor> globalDescriptor = VendorTagDescriptor::getGlobalVendorTagDescriptor();
592 if (globalDescriptor != nullptr) {
593 *desc = *(globalDescriptor.get());
594 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800595 return Status::ok();
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800596}
597
Igor Murashkin634a5152013-02-20 17:15:11 -0800598int CameraService::getDeviceVersion(int cameraId, int* facing) {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -0700599 ATRACE_CALL();
Igor Murashkin634a5152013-02-20 17:15:11 -0800600 struct camera_info info;
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800601 if (mModule->getCameraInfo(cameraId, &info) != OK) {
Igor Murashkin634a5152013-02-20 17:15:11 -0800602 return -1;
603 }
604
605 int deviceVersion;
Chien-Yu Chen676b21b2015-02-24 10:28:19 -0800606 if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_0) {
Igor Murashkin634a5152013-02-20 17:15:11 -0800607 deviceVersion = info.device_version;
608 } else {
609 deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
610 }
611
612 if (facing) {
613 *facing = info.facing;
614 }
615
616 return deviceVersion;
617}
618
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800619Status CameraService::filterGetInfoErrorCode(status_t err) {
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -0700620 switch(err) {
621 case NO_ERROR:
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800622 return Status::ok();
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800623 case BAD_VALUE:
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800624 return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT,
625 "CameraId is not valid for HAL module");
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800626 case NO_INIT:
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800627 return STATUS_ERROR(ERROR_DISCONNECTED,
628 "Camera device not available");
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -0700629 default:
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800630 return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
631 "Camera HAL encountered error %d: %s",
632 err, strerror(-err));
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -0700633 }
Igor Murashkinbfc99152013-02-27 12:55:20 -0800634}
635
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800636bool CameraService::setUpVendorTags() {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -0700637 ATRACE_CALL();
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800638 vendor_tag_ops_t vOps = vendor_tag_ops_t();
639
640 // Check if vendor operations have been implemented
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800641 if (!mModule->isVendorTagDefined()) {
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800642 ALOGI("%s: No vendor tags defined for this device.", __FUNCTION__);
643 return false;
644 }
645
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800646 mModule->getVendorTagOps(&vOps);
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800647
648 // Ensure all vendor operations are present
649 if (vOps.get_tag_count == NULL || vOps.get_all_tags == NULL ||
650 vOps.get_section_name == NULL || vOps.get_tag_name == NULL ||
651 vOps.get_tag_type == NULL) {
652 ALOGE("%s: Vendor tag operations not fully defined. Ignoring definitions."
653 , __FUNCTION__);
654 return false;
655 }
656
657 // Read all vendor tag definitions into a descriptor
658 sp<VendorTagDescriptor> desc;
659 status_t res;
660 if ((res = VendorTagDescriptor::createDescriptorFromOps(&vOps, /*out*/desc))
661 != OK) {
662 ALOGE("%s: Could not generate descriptor from vendor tag operations,"
663 "received error %s (%d). Camera clients will not be able to use"
664 "vendor tags", __FUNCTION__, strerror(res), res);
665 return false;
666 }
667
668 // Set the global descriptor to use with camera metadata
669 VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
670 return true;
671}
672
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800673Status CameraService::makeClient(const sp<CameraService>& cameraService,
674 const sp<IInterface>& cameraCb, const String16& packageName, int cameraId,
Ruben Brunkcc776712015-02-17 20:18:47 -0800675 int facing, int clientPid, uid_t clientUid, int servicePid, bool legacyMode,
676 int halVersion, int deviceVersion, apiLevel effectiveApiLevel,
677 /*out*/sp<BasicClient>* client) {
678
Ruben Brunkcc776712015-02-17 20:18:47 -0800679 if (halVersion < 0 || halVersion == deviceVersion) {
680 // Default path: HAL version is unspecified by caller, create CameraClient
681 // based on device version reported by the HAL.
682 switch(deviceVersion) {
683 case CAMERA_DEVICE_API_VERSION_1_0:
684 if (effectiveApiLevel == API_1) { // Camera1 API route
685 sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800686 *client = new CameraClient(cameraService, tmp, packageName, cameraId, facing,
Ruben Brunkcc776712015-02-17 20:18:47 -0800687 clientPid, clientUid, getpid(), legacyMode);
688 } else { // Camera2 API route
689 ALOGW("Camera using old HAL version: %d", deviceVersion);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800690 return STATUS_ERROR_FMT(ERROR_DEPRECATED_HAL,
691 "Camera device \"%d\" HAL version %d does not support camera2 API",
692 cameraId, deviceVersion);
Ruben Brunkcc776712015-02-17 20:18:47 -0800693 }
694 break;
Ruben Brunkcc776712015-02-17 20:18:47 -0800695 case CAMERA_DEVICE_API_VERSION_3_0:
696 case CAMERA_DEVICE_API_VERSION_3_1:
697 case CAMERA_DEVICE_API_VERSION_3_2:
698 case CAMERA_DEVICE_API_VERSION_3_3:
Zhijun He4afbdec2016-05-04 15:42:51 -0700699 case CAMERA_DEVICE_API_VERSION_3_4:
Ruben Brunkcc776712015-02-17 20:18:47 -0800700 if (effectiveApiLevel == API_1) { // Camera1 API route
701 sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800702 *client = new Camera2Client(cameraService, tmp, packageName, cameraId, facing,
Ruben Brunkcc776712015-02-17 20:18:47 -0800703 clientPid, clientUid, servicePid, legacyMode);
704 } else { // Camera2 API route
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800705 sp<hardware::camera2::ICameraDeviceCallbacks> tmp =
706 static_cast<hardware::camera2::ICameraDeviceCallbacks*>(cameraCb.get());
707 *client = new CameraDeviceClient(cameraService, tmp, packageName, cameraId,
Ruben Brunkcc776712015-02-17 20:18:47 -0800708 facing, clientPid, clientUid, servicePid);
709 }
710 break;
711 default:
712 // Should not be reachable
713 ALOGE("Unknown camera device HAL version: %d", deviceVersion);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800714 return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
715 "Camera device \"%d\" has unknown HAL version %d",
716 cameraId, deviceVersion);
Ruben Brunkcc776712015-02-17 20:18:47 -0800717 }
718 } else {
719 // A particular HAL version is requested by caller. Create CameraClient
720 // based on the requested HAL version.
721 if (deviceVersion > CAMERA_DEVICE_API_VERSION_1_0 &&
722 halVersion == CAMERA_DEVICE_API_VERSION_1_0) {
723 // Only support higher HAL version device opened as HAL1.0 device.
724 sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800725 *client = new CameraClient(cameraService, tmp, packageName, cameraId, facing,
Ruben Brunkcc776712015-02-17 20:18:47 -0800726 clientPid, clientUid, servicePid, legacyMode);
727 } else {
728 // Other combinations (e.g. HAL3.x open as HAL2.x) are not supported yet.
729 ALOGE("Invalid camera HAL version %x: HAL %x device can only be"
730 " opened as HAL %x device", halVersion, deviceVersion,
731 CAMERA_DEVICE_API_VERSION_1_0);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800732 return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
733 "Camera device \"%d\" (HAL version %d) cannot be opened as HAL version %d",
734 cameraId, deviceVersion, halVersion);
Ruben Brunkcc776712015-02-17 20:18:47 -0800735 }
736 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800737 return Status::ok();
Ruben Brunkcc776712015-02-17 20:18:47 -0800738}
739
Ruben Brunk6267b532015-04-30 17:44:07 -0700740String8 CameraService::toString(std::set<userid_t> intSet) {
741 String8 s("");
742 bool first = true;
743 for (userid_t i : intSet) {
744 if (first) {
745 s.appendFormat("%d", i);
746 first = false;
747 } else {
748 s.appendFormat(", %d", i);
749 }
750 }
751 return s;
752}
753
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800754int32_t CameraService::mapToInterface(TorchModeStatus status) {
755 int32_t serviceStatus = ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE;
756 switch (status) {
757 case TorchModeStatus::NOT_AVAILABLE:
758 serviceStatus = ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE;
759 break;
760 case TorchModeStatus::AVAILABLE_OFF:
761 serviceStatus = ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF;
762 break;
763 case TorchModeStatus::AVAILABLE_ON:
764 serviceStatus = ICameraServiceListener::TORCH_STATUS_AVAILABLE_ON;
765 break;
766 default:
767 ALOGW("Unknown new flash status: %d", status);
768 }
769 return serviceStatus;
770}
771
772CameraService::StatusInternal CameraService::mapToInternal(CameraDeviceStatus status) {
773 StatusInternal serviceStatus = StatusInternal::NOT_PRESENT;
774 switch (status) {
775 case CameraDeviceStatus::NOT_PRESENT:
776 serviceStatus = StatusInternal::NOT_PRESENT;
777 break;
778 case CameraDeviceStatus::PRESENT:
779 serviceStatus = StatusInternal::PRESENT;
780 break;
781 case CameraDeviceStatus::ENUMERATING:
782 serviceStatus = StatusInternal::ENUMERATING;
783 break;
784 default:
785 ALOGW("Unknown new HAL device status: %d", status);
786 }
787 return serviceStatus;
788}
789
790int32_t CameraService::mapToInterface(StatusInternal status) {
791 int32_t serviceStatus = ICameraServiceListener::STATUS_NOT_PRESENT;
792 switch (status) {
793 case StatusInternal::NOT_PRESENT:
794 serviceStatus = ICameraServiceListener::STATUS_NOT_PRESENT;
795 break;
796 case StatusInternal::PRESENT:
797 serviceStatus = ICameraServiceListener::STATUS_PRESENT;
798 break;
799 case StatusInternal::ENUMERATING:
800 serviceStatus = ICameraServiceListener::STATUS_ENUMERATING;
801 break;
802 case StatusInternal::NOT_AVAILABLE:
803 serviceStatus = ICameraServiceListener::STATUS_NOT_AVAILABLE;
804 break;
805 case StatusInternal::UNKNOWN:
806 serviceStatus = ICameraServiceListener::STATUS_UNKNOWN;
807 break;
808 default:
809 ALOGW("Unknown new internal device status: %d", status);
810 }
811 return serviceStatus;
812}
813
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800814Status CameraService::initializeShimMetadata(int cameraId) {
Ruben Brunkcc776712015-02-17 20:18:47 -0800815 int uid = getCallingUid();
Ruben Brunkb2119af2014-05-09 19:57:56 -0700816
Chien-Yu Chen98a668f2015-12-18 14:10:33 -0800817 String16 internalPackageName("cameraserver");
Ruben Brunkcc776712015-02-17 20:18:47 -0800818 String8 id = String8::format("%d", cameraId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800819 Status ret = Status::ok();
Ruben Brunkcc776712015-02-17 20:18:47 -0800820 sp<Client> tmp = nullptr;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800821 if (!(ret = connectHelper<ICameraClient,Client>(
822 sp<ICameraClient>{nullptr}, id, static_cast<int>(CAMERA_HAL_API_VERSION_UNSPECIFIED),
823 internalPackageName, uid, USE_CALLING_PID,
824 API_1, /*legacyMode*/ false, /*shimUpdateOnly*/ true,
825 /*out*/ tmp)
826 ).isOk()) {
827 ALOGE("%s: Error initializing shim metadata: %s", __FUNCTION__, ret.toString8().string());
Ruben Brunkb2119af2014-05-09 19:57:56 -0700828 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800829 return ret;
Ruben Brunkb2119af2014-05-09 19:57:56 -0700830}
831
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800832Status CameraService::getLegacyParametersLazy(int cameraId,
Igor Murashkin65d14b92014-06-17 12:03:20 -0700833 /*out*/
834 CameraParameters* parameters) {
835
836 ALOGV("%s: for cameraId: %d", __FUNCTION__, cameraId);
837
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800838 Status ret = Status::ok();
Igor Murashkin65d14b92014-06-17 12:03:20 -0700839
840 if (parameters == NULL) {
841 ALOGE("%s: parameters must not be null", __FUNCTION__);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800842 return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Parameters must not be null");
Igor Murashkin65d14b92014-06-17 12:03:20 -0700843 }
844
Ruben Brunkcc776712015-02-17 20:18:47 -0800845 String8 id = String8::format("%d", cameraId);
846
847 // Check if we already have parameters
848 {
849 // Scope for service lock
Igor Murashkin65d14b92014-06-17 12:03:20 -0700850 Mutex::Autolock lock(mServiceLock);
Ruben Brunkcc776712015-02-17 20:18:47 -0800851 auto cameraState = getCameraState(id);
852 if (cameraState == nullptr) {
853 ALOGE("%s: Invalid camera ID: %s", __FUNCTION__, id.string());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800854 return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
855 "Invalid camera ID: %s", id.string());
Ruben Brunkcc776712015-02-17 20:18:47 -0800856 }
857 CameraParameters p = cameraState->getShimParams();
858 if (!p.isEmpty()) {
859 *parameters = p;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800860 return ret;
Igor Murashkin65d14b92014-06-17 12:03:20 -0700861 }
862 }
863
Ruben Brunkcc776712015-02-17 20:18:47 -0800864 int64_t token = IPCThreadState::self()->clearCallingIdentity();
865 ret = initializeShimMetadata(cameraId);
866 IPCThreadState::self()->restoreCallingIdentity(token);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800867 if (!ret.isOk()) {
Ruben Brunkcc776712015-02-17 20:18:47 -0800868 // Error already logged by callee
869 return ret;
870 }
871
872 // Check for parameters again
873 {
874 // Scope for service lock
875 Mutex::Autolock lock(mServiceLock);
876 auto cameraState = getCameraState(id);
877 if (cameraState == nullptr) {
878 ALOGE("%s: Invalid camera ID: %s", __FUNCTION__, id.string());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800879 return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
880 "Invalid camera ID: %s", id.string());
Igor Murashkin65d14b92014-06-17 12:03:20 -0700881 }
Ruben Brunkcc776712015-02-17 20:18:47 -0800882 CameraParameters p = cameraState->getShimParams();
883 if (!p.isEmpty()) {
884 *parameters = p;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800885 return ret;
Igor Murashkin65d14b92014-06-17 12:03:20 -0700886 }
887 }
888
Ruben Brunkcc776712015-02-17 20:18:47 -0800889 ALOGE("%s: Parameters were not initialized, or were empty. Device may not be present.",
890 __FUNCTION__);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800891 return STATUS_ERROR(ERROR_INVALID_OPERATION, "Unable to initialize legacy parameters");
Igor Murashkin65d14b92014-06-17 12:03:20 -0700892}
893
Chien-Yu Chen98a668f2015-12-18 14:10:33 -0800894// Can camera service trust the caller based on the calling UID?
895static bool isTrustedCallingUid(uid_t uid) {
896 switch (uid) {
Eino-Ville Talvalaaf9d0302016-06-29 14:40:10 -0700897 case AID_MEDIA: // mediaserver
Chien-Yu Chen98a668f2015-12-18 14:10:33 -0800898 case AID_CAMERASERVER: // cameraserver
Eino-Ville Talvalaaf9d0302016-06-29 14:40:10 -0700899 case AID_RADIO: // telephony
Chien-Yu Chen98a668f2015-12-18 14:10:33 -0800900 return true;
901 default:
902 return false;
903 }
904}
905
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800906Status CameraService::validateConnectLocked(const String8& cameraId,
Chien-Yu Chen18df60e2016-03-18 18:18:09 -0700907 const String8& clientName8, /*inout*/int& clientUid, /*inout*/int& clientPid,
908 /*out*/int& originalClientPid) const {
Tyler Luu5861a9a2011-10-06 00:00:03 -0500909
Alex Deymo9c2a2c22016-08-25 11:59:14 -0700910#ifdef __BRILLO__
911 UNUSED(clientName8);
912 UNUSED(clientUid);
913 UNUSED(clientPid);
914 UNUSED(originalClientPid);
915#else
Chien-Yu Chen7939aee2016-03-21 18:19:33 -0700916 Status allowed = validateClientPermissionsLocked(cameraId, clientName8, clientUid, clientPid,
917 originalClientPid);
Eino-Ville Talvala04926862016-03-02 15:42:53 -0800918 if (!allowed.isOk()) {
Christopher Wileyce761d12016-02-16 10:15:00 -0800919 return allowed;
920 }
Alex Deymo9c2a2c22016-08-25 11:59:14 -0700921#endif // __BRILLO__
Christopher Wileyce761d12016-02-16 10:15:00 -0800922
Eino-Ville Talvala04926862016-03-02 15:42:53 -0800923 int callingPid = getCallingPid();
924
Iliyan Malchev8951a972011-04-14 16:55:59 -0700925 if (!mModule) {
Ruben Brunkcc776712015-02-17 20:18:47 -0800926 ALOGE("CameraService::connect X (PID %d) rejected (camera HAL module not loaded)",
927 callingPid);
Eino-Ville Talvala04926862016-03-02 15:42:53 -0800928 return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
929 "No camera HAL module available to open camera device \"%s\"", cameraId.string());
Iliyan Malchev8951a972011-04-14 16:55:59 -0700930 }
931
Ruben Brunkcc776712015-02-17 20:18:47 -0800932 if (getCameraState(cameraId) == nullptr) {
933 ALOGE("CameraService::connect X (PID %d) rejected (invalid camera ID %s)", callingPid,
934 cameraId.string());
Eino-Ville Talvala04926862016-03-02 15:42:53 -0800935 return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
936 "No camera device with ID \"%s\" available", cameraId.string());
Mathias Agopian65ab4712010-07-14 17:59:35 -0700937 }
938
Eino-Ville Talvala04926862016-03-02 15:42:53 -0800939 status_t err = checkIfDeviceIsUsable(cameraId);
940 if (err != NO_ERROR) {
941 switch(err) {
942 case -ENODEV:
943 case -EBUSY:
944 return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
945 "No camera device with ID \"%s\" currently available", cameraId.string());
946 default:
947 return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
948 "Unknown error connecting to ID \"%s\"", cameraId.string());
949 }
950 }
951 return Status::ok();
Christopher Wiley0039bcf2016-02-05 10:29:50 -0800952}
953
Eino-Ville Talvala04926862016-03-02 15:42:53 -0800954Status CameraService::validateClientPermissionsLocked(const String8& cameraId,
Chien-Yu Chen7939aee2016-03-21 18:19:33 -0700955 const String8& clientName8, int& clientUid, int& clientPid,
956 /*out*/int& originalClientPid) const {
Christopher Wiley0039bcf2016-02-05 10:29:50 -0800957 int callingPid = getCallingPid();
Chien-Yu Chen98a668f2015-12-18 14:10:33 -0800958 int callingUid = getCallingUid();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700959
Chien-Yu Chen98a668f2015-12-18 14:10:33 -0800960 // Check if we can trust clientUid
Mathias Agopian65ab4712010-07-14 17:59:35 -0700961 if (clientUid == USE_CALLING_UID) {
Chien-Yu Chen98a668f2015-12-18 14:10:33 -0800962 clientUid = callingUid;
963 } else if (!isTrustedCallingUid(callingUid)) {
964 ALOGE("CameraService::connect X (calling PID %d, calling UID %d) rejected "
965 "(don't trust clientUid %d)", callingPid, callingUid, clientUid);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800966 return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
967 "Untrusted caller (calling PID %d, UID %d) trying to "
968 "forward camera access to camera %s for client %s (PID %d, UID %d)",
969 callingPid, callingUid, cameraId.string(),
970 clientName8.string(), clientUid, clientPid);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700971 }
972
Chien-Yu Chen98a668f2015-12-18 14:10:33 -0800973 // Check if we can trust clientPid
974 if (clientPid == USE_CALLING_PID) {
975 clientPid = callingPid;
976 } else if (!isTrustedCallingUid(callingUid)) {
977 ALOGE("CameraService::connect X (calling PID %d, calling UID %d) rejected "
978 "(don't trust clientPid %d)", callingPid, callingUid, clientPid);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800979 return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
980 "Untrusted caller (calling PID %d, UID %d) trying to "
981 "forward camera access to camera %s for client %s (PID %d, UID %d)",
982 callingPid, callingUid, cameraId.string(),
983 clientName8.string(), clientUid, clientPid);
Chien-Yu Chen98a668f2015-12-18 14:10:33 -0800984 }
985
986 // If it's not calling from cameraserver, check the permission.
987 if (callingPid != getpid() &&
988 !checkPermission(String16("android.permission.CAMERA"), clientPid, clientUid)) {
989 ALOGE("Permission Denial: can't use the camera pid=%d, uid=%d", clientPid, clientUid);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800990 return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
991 "Caller \"%s\" (PID %d, UID %d) cannot open camera \"%s\" without camera permission",
992 clientName8.string(), clientUid, clientPid, cameraId.string());
Chien-Yu Chen98a668f2015-12-18 14:10:33 -0800993 }
994
Chien-Yu Chen4f3d6202016-03-22 10:50:23 -0700995 // Only use passed in clientPid to check permission. Use calling PID as the client PID that's
996 // connected to camera service directly.
Chien-Yu Chen18df60e2016-03-18 18:18:09 -0700997 originalClientPid = clientPid;
Chien-Yu Chen4f3d6202016-03-22 10:50:23 -0700998 clientPid = callingPid;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700999
Ruben Brunk6267b532015-04-30 17:44:07 -07001000 userid_t clientUserId = multiuser_get_user_id(clientUid);
Wu-cheng Lia3355432011-05-20 14:54:25 +08001001
Ruben Brunka8ca9152015-04-07 14:23:40 -07001002 // Only allow clients who are being used by the current foreground device user, unless calling
1003 // from our own process.
Ruben Brunk6267b532015-04-30 17:44:07 -07001004 if (callingPid != getpid() && (mAllowedUsers.find(clientUserId) == mAllowedUsers.end())) {
1005 ALOGE("CameraService::connect X (PID %d) rejected (cannot connect from "
1006 "device user %d, currently allowed device users: %s)", callingPid, clientUserId,
1007 toString(mAllowedUsers).string());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001008 return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
1009 "Callers from device user %d are not currently allowed to connect to camera \"%s\"",
1010 clientUserId, cameraId.string());
Ruben Brunk36597b22015-03-20 22:15:57 -07001011 }
1012
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001013 return Status::ok();
Ruben Brunkcc776712015-02-17 20:18:47 -08001014}
1015
1016status_t CameraService::checkIfDeviceIsUsable(const String8& cameraId) const {
1017 auto cameraState = getCameraState(cameraId);
1018 int callingPid = getCallingPid();
1019 if (cameraState == nullptr) {
1020 ALOGE("CameraService::connect X (PID %d) rejected (invalid camera ID %s)", callingPid,
1021 cameraId.string());
1022 return -ENODEV;
1023 }
1024
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08001025 StatusInternal currentStatus = cameraState->getStatus();
1026 if (currentStatus == StatusInternal::NOT_PRESENT) {
Ruben Brunkcc776712015-02-17 20:18:47 -08001027 ALOGE("CameraService::connect X (PID %d) rejected (camera %s is not connected)",
1028 callingPid, cameraId.string());
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001029 return -ENODEV;
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08001030 } else if (currentStatus == StatusInternal::ENUMERATING) {
Ruben Brunkcc776712015-02-17 20:18:47 -08001031 ALOGE("CameraService::connect X (PID %d) rejected, (camera %s is initializing)",
1032 callingPid, cameraId.string());
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001033 return -EBUSY;
Igor Murashkincba2c162013-03-20 15:56:31 -07001034 }
Igor Murashkincba2c162013-03-20 15:56:31 -07001035
Ruben Brunkcc776712015-02-17 20:18:47 -08001036 return NO_ERROR;
Igor Murashkine6800ce2013-03-04 17:25:57 -08001037}
1038
Ruben Brunkcc776712015-02-17 20:18:47 -08001039void CameraService::finishConnectLocked(const sp<BasicClient>& client,
1040 const CameraService::DescriptorPtr& desc) {
Igor Murashkine6800ce2013-03-04 17:25:57 -08001041
Ruben Brunkcc776712015-02-17 20:18:47 -08001042 // Make a descriptor for the incoming client
1043 auto clientDescriptor = CameraService::CameraClientManager::makeClientDescriptor(client, desc);
1044 auto evicted = mActiveClientManager.addAndEvict(clientDescriptor);
1045
1046 logConnected(desc->getKey(), static_cast<int>(desc->getOwnerId()),
1047 String8(client->getPackageName()));
1048
1049 if (evicted.size() > 0) {
1050 // This should never happen - clients should already have been removed in disconnect
1051 for (auto& i : evicted) {
1052 ALOGE("%s: Invalid state: Client for camera %s was not removed in disconnect",
1053 __FUNCTION__, i->getKey().string());
1054 }
1055
1056 LOG_ALWAYS_FATAL("%s: Invalid state for CameraService, clients not evicted properly",
1057 __FUNCTION__);
1058 }
Eino-Ville Talvala24901c82015-09-04 14:15:58 -07001059
1060 // And register a death notification for the client callback. Do
1061 // this last to avoid Binder policy where a nested Binder
1062 // transaction might be pre-empted to service the client death
1063 // notification if the client process dies before linkToDeath is
1064 // invoked.
1065 sp<IBinder> remoteCallback = client->getRemote();
1066 if (remoteCallback != nullptr) {
1067 remoteCallback->linkToDeath(this);
1068 }
Ruben Brunkcc776712015-02-17 20:18:47 -08001069}
1070
1071status_t CameraService::handleEvictionsLocked(const String8& cameraId, int clientPid,
1072 apiLevel effectiveApiLevel, const sp<IBinder>& remoteCallback, const String8& packageName,
1073 /*out*/
1074 sp<BasicClient>* client,
1075 std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>* partial) {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -07001076 ATRACE_CALL();
Ruben Brunkcc776712015-02-17 20:18:47 -08001077 status_t ret = NO_ERROR;
Ruben Brunk4f9576b2015-04-10 17:26:56 -07001078 std::vector<DescriptorPtr> evictedClients;
Ruben Brunkcc776712015-02-17 20:18:47 -08001079 DescriptorPtr clientDescriptor;
1080 {
1081 if (effectiveApiLevel == API_1) {
1082 // If we are using API1, any existing client for this camera ID with the same remote
1083 // should be returned rather than evicted to allow MediaRecorder to work properly.
1084
1085 auto current = mActiveClientManager.get(cameraId);
1086 if (current != nullptr) {
1087 auto clientSp = current->getValue();
1088 if (clientSp.get() != nullptr) { // should never be needed
Ruben Brunk0bbf8b22015-04-30 14:35:42 -07001089 if (!clientSp->canCastToApiClient(effectiveApiLevel)) {
1090 ALOGW("CameraService connect called from same client, but with a different"
1091 " API level, evicting prior client...");
1092 } else if (clientSp->getRemote() == remoteCallback) {
Ruben Brunkcc776712015-02-17 20:18:47 -08001093 ALOGI("CameraService::connect X (PID %d) (second call from same"
Ruben Brunk0bbf8b22015-04-30 14:35:42 -07001094 " app binder, returning the same client)", clientPid);
Ruben Brunkcc776712015-02-17 20:18:47 -08001095 *client = clientSp;
1096 return NO_ERROR;
1097 }
1098 }
Wu-cheng Li2fd24402012-02-23 19:01:00 -08001099 }
Wu-cheng Li2fd24402012-02-23 19:01:00 -08001100 }
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +08001101
Ruben Brunkcc776712015-02-17 20:18:47 -08001102 // Get current active client PIDs
1103 std::vector<int> ownerPids(mActiveClientManager.getAllOwners());
1104 ownerPids.push_back(clientPid);
Igor Murashkine6800ce2013-03-04 17:25:57 -08001105
Chih-Hung Hsieh54b42462015-03-19 12:04:54 -07001106 // Use the value +PROCESS_STATE_NONEXISTENT, to avoid taking
1107 // address of PROCESS_STATE_NONEXISTENT as a reference argument
1108 // for the vector constructor. PROCESS_STATE_NONEXISTENT does
1109 // not have an out-of-class definition.
1110 std::vector<int> priorities(ownerPids.size(), +PROCESS_STATE_NONEXISTENT);
Igor Murashkine6800ce2013-03-04 17:25:57 -08001111
Ruben Brunkcc776712015-02-17 20:18:47 -08001112 // Get priorites of all active PIDs
1113 ProcessInfoService::getProcessStatesFromPids(ownerPids.size(), &ownerPids[0],
1114 /*out*/&priorities[0]);
Ruben Brunkb2119af2014-05-09 19:57:56 -07001115
Ruben Brunkcc776712015-02-17 20:18:47 -08001116 // Update all active clients' priorities
1117 std::map<int,int> pidToPriorityMap;
1118 for (size_t i = 0; i < ownerPids.size() - 1; i++) {
1119 pidToPriorityMap.emplace(ownerPids[i], getCameraPriorityFromProcState(priorities[i]));
1120 }
1121 mActiveClientManager.updatePriorities(pidToPriorityMap);
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001122
Ruben Brunkcc776712015-02-17 20:18:47 -08001123 // Get state for the given cameraId
1124 auto state = getCameraState(cameraId);
1125 if (state == nullptr) {
1126 ALOGE("CameraService::connect X (PID %d) rejected (no camera device with ID %s)",
1127 clientPid, cameraId.string());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001128 // Should never get here because validateConnectLocked should have errored out
Zhijun Heb10cdad2014-06-16 16:38:35 -07001129 return BAD_VALUE;
Zhijun Heb10cdad2014-06-16 16:38:35 -07001130 }
Ruben Brunkcc776712015-02-17 20:18:47 -08001131
1132 // Make descriptor for incoming client
1133 clientDescriptor = CameraClientManager::makeClientDescriptor(cameraId,
1134 sp<BasicClient>{nullptr}, static_cast<int32_t>(state->getCost()),
1135 state->getConflicting(),
1136 getCameraPriorityFromProcState(priorities[priorities.size() - 1]), clientPid);
1137
1138 // Find clients that would be evicted
1139 auto evicted = mActiveClientManager.wouldEvict(clientDescriptor);
1140
1141 // If the incoming client was 'evicted,' higher priority clients have the camera in the
1142 // background, so we cannot do evictions
1143 if (std::find(evicted.begin(), evicted.end(), clientDescriptor) != evicted.end()) {
1144 ALOGE("CameraService::connect X (PID %d) rejected (existing client(s) with higher"
1145 " priority).", clientPid);
1146
1147 sp<BasicClient> clientSp = clientDescriptor->getValue();
1148 String8 curTime = getFormattedCurrentTime();
1149 auto incompatibleClients =
1150 mActiveClientManager.getIncompatibleClients(clientDescriptor);
1151
1152 String8 msg = String8::format("%s : DENIED connect device %s client for package %s "
Ruben Brunka8ca9152015-04-07 14:23:40 -07001153 "(PID %d, priority %d) due to eviction policy", curTime.string(),
Ruben Brunkcc776712015-02-17 20:18:47 -08001154 cameraId.string(), packageName.string(), clientPid,
1155 getCameraPriorityFromProcState(priorities[priorities.size() - 1]));
1156
1157 for (auto& i : incompatibleClients) {
1158 msg.appendFormat("\n - Blocked by existing device %s client for package %s"
1159 "(PID %" PRId32 ", priority %" PRId32 ")", i->getKey().string(),
1160 String8{i->getValue()->getPackageName()}.string(), i->getOwnerId(),
1161 i->getPriority());
Eino-Ville Talvala022f0cb2015-05-19 16:31:16 -07001162 ALOGE(" Conflicts with: Device %s, client package %s (PID %"
1163 PRId32 ", priority %" PRId32 ")", i->getKey().string(),
1164 String8{i->getValue()->getPackageName()}.string(), i->getOwnerId(),
1165 i->getPriority());
Ruben Brunkcc776712015-02-17 20:18:47 -08001166 }
1167
1168 // Log the client's attempt
Ruben Brunka8ca9152015-04-07 14:23:40 -07001169 Mutex::Autolock l(mLogLock);
Ruben Brunkcc776712015-02-17 20:18:47 -08001170 mEventLog.add(msg);
1171
1172 return -EBUSY;
1173 }
1174
1175 for (auto& i : evicted) {
1176 sp<BasicClient> clientSp = i->getValue();
1177 if (clientSp.get() == nullptr) {
1178 ALOGE("%s: Invalid state: Null client in active client list.", __FUNCTION__);
1179
1180 // TODO: Remove this
1181 LOG_ALWAYS_FATAL("%s: Invalid state for CameraService, null client in active list",
1182 __FUNCTION__);
1183 mActiveClientManager.remove(i);
1184 continue;
1185 }
1186
1187 ALOGE("CameraService::connect evicting conflicting client for camera ID %s",
1188 i->getKey().string());
Ruben Brunk4f9576b2015-04-10 17:26:56 -07001189 evictedClients.push_back(i);
Ruben Brunkcc776712015-02-17 20:18:47 -08001190
Ruben Brunkcc776712015-02-17 20:18:47 -08001191 // Log the clients evicted
Ruben Brunka8ca9152015-04-07 14:23:40 -07001192 logEvent(String8::format("EVICT device %s client held by package %s (PID"
1193 " %" PRId32 ", priority %" PRId32 ")\n - Evicted by device %s client for"
1194 " package %s (PID %d, priority %" PRId32 ")",
Ruben Brunkcc776712015-02-17 20:18:47 -08001195 i->getKey().string(), String8{clientSp->getPackageName()}.string(),
1196 i->getOwnerId(), i->getPriority(), cameraId.string(),
1197 packageName.string(), clientPid,
1198 getCameraPriorityFromProcState(priorities[priorities.size() - 1])));
1199
1200 // Notify the client of disconnection
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001201 clientSp->notifyError(hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED,
Ruben Brunkcc776712015-02-17 20:18:47 -08001202 CaptureResultExtras());
Zhijun Heb10cdad2014-06-16 16:38:35 -07001203 }
Ruben Brunkb2119af2014-05-09 19:57:56 -07001204 }
1205
Ruben Brunkcc776712015-02-17 20:18:47 -08001206 // Do not hold mServiceLock while disconnecting clients, but retain the condition blocking
1207 // other clients from connecting in mServiceLockWrapper if held
1208 mServiceLock.unlock();
1209
1210 // Clear caller identity temporarily so client disconnect PID checks work correctly
1211 int64_t token = IPCThreadState::self()->clearCallingIdentity();
1212
1213 // Destroy evicted clients
1214 for (auto& i : evictedClients) {
1215 // Disconnect is blocking, and should only have returned when HAL has cleaned up
Ruben Brunk4f9576b2015-04-10 17:26:56 -07001216 i->getValue()->disconnect(); // Clients will remove themselves from the active client list
Ruben Brunkcc776712015-02-17 20:18:47 -08001217 }
Ruben Brunkcc776712015-02-17 20:18:47 -08001218
1219 IPCThreadState::self()->restoreCallingIdentity(token);
1220
Ruben Brunk4f9576b2015-04-10 17:26:56 -07001221 for (const auto& i : evictedClients) {
1222 ALOGV("%s: Waiting for disconnect to complete for client for device %s (PID %" PRId32 ")",
1223 __FUNCTION__, i->getKey().string(), i->getOwnerId());
1224 ret = mActiveClientManager.waitUntilRemoved(i, DEFAULT_DISCONNECT_TIMEOUT_NS);
1225 if (ret == TIMED_OUT) {
1226 ALOGE("%s: Timed out waiting for client for device %s to disconnect, "
1227 "current clients:\n%s", __FUNCTION__, i->getKey().string(),
1228 mActiveClientManager.toString().string());
1229 return -EBUSY;
1230 }
1231 if (ret != NO_ERROR) {
1232 ALOGE("%s: Received error waiting for client for device %s to disconnect: %s (%d), "
1233 "current clients:\n%s", __FUNCTION__, i->getKey().string(), strerror(-ret),
1234 ret, mActiveClientManager.toString().string());
1235 return ret;
1236 }
1237 }
1238
1239 evictedClients.clear();
1240
Ruben Brunkcc776712015-02-17 20:18:47 -08001241 // Once clients have been disconnected, relock
1242 mServiceLock.lock();
1243
1244 // Check again if the device was unplugged or something while we weren't holding mServiceLock
1245 if ((ret = checkIfDeviceIsUsable(cameraId)) != NO_ERROR) {
1246 return ret;
Ruben Brunkb2119af2014-05-09 19:57:56 -07001247 }
1248
Ruben Brunkcc776712015-02-17 20:18:47 -08001249 *partial = clientDescriptor;
1250 return NO_ERROR;
Ruben Brunkb2119af2014-05-09 19:57:56 -07001251}
1252
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001253Status CameraService::connect(
Igor Murashkine6800ce2013-03-04 17:25:57 -08001254 const sp<ICameraClient>& cameraClient,
1255 int cameraId,
Svetoslav Ganov280405a2015-05-12 02:19:27 +00001256 const String16& clientPackageName,
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001257 int clientUid,
Chien-Yu Chen98a668f2015-12-18 14:10:33 -08001258 int clientPid,
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001259 /*out*/
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001260 sp<ICamera>* device) {
Igor Murashkine6800ce2013-03-04 17:25:57 -08001261
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -07001262 ATRACE_CALL();
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001263 Status ret = Status::ok();
Ruben Brunkcc776712015-02-17 20:18:47 -08001264 String8 id = String8::format("%d", cameraId);
1265 sp<Client> client = nullptr;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001266 ret = connectHelper<ICameraClient,Client>(cameraClient, id,
1267 CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageName, clientUid, clientPid, API_1,
1268 /*legacyMode*/ false, /*shimUpdateOnly*/ false,
1269 /*out*/client);
Igor Murashkine6800ce2013-03-04 17:25:57 -08001270
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001271 if(!ret.isOk()) {
Svetoslav Ganov280405a2015-05-12 02:19:27 +00001272 logRejected(id, getCallingPid(), String8(clientPackageName),
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001273 ret.toString8());
Ruben Brunkcc776712015-02-17 20:18:47 -08001274 return ret;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001275 }
1276
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001277 *device = client;
1278 return ret;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001279}
1280
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001281Status CameraService::connectLegacy(
Zhijun Heb10cdad2014-06-16 16:38:35 -07001282 const sp<ICameraClient>& cameraClient,
1283 int cameraId, int halVersion,
Svetoslav Ganov280405a2015-05-12 02:19:27 +00001284 const String16& clientPackageName,
Zhijun Heb10cdad2014-06-16 16:38:35 -07001285 int clientUid,
1286 /*out*/
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001287 sp<ICamera>* device) {
Zhijun Heb10cdad2014-06-16 16:38:35 -07001288
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -07001289 ATRACE_CALL();
Ruben Brunka8ca9152015-04-07 14:23:40 -07001290 String8 id = String8::format("%d", cameraId);
Chien-Yu Chen676b21b2015-02-24 10:28:19 -08001291 int apiVersion = mModule->getModuleApiVersion();
Igor Murashkin3d07d1a2014-06-20 11:27:03 -07001292 if (halVersion != CAMERA_HAL_API_VERSION_UNSPECIFIED &&
Yin-Chia Yehe074a932015-01-30 10:29:02 -08001293 apiVersion < CAMERA_MODULE_API_VERSION_2_3) {
Igor Murashkin3d07d1a2014-06-20 11:27:03 -07001294 /*
1295 * Either the HAL version is unspecified in which case this just creates
1296 * a camera client selected by the latest device version, or
1297 * it's a particular version in which case the HAL must supported
1298 * the open_legacy call
1299 */
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001300 String8 msg = String8::format("Camera HAL module version %x too old for connectLegacy!",
1301 apiVersion);
1302 ALOGE("%s: %s",
1303 __FUNCTION__, msg.string());
Svetoslav Ganov280405a2015-05-12 02:19:27 +00001304 logRejected(id, getCallingPid(), String8(clientPackageName),
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001305 msg);
1306 return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.string());
Zhijun Heb10cdad2014-06-16 16:38:35 -07001307 }
1308
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001309 Status ret = Status::ok();
Ruben Brunkcc776712015-02-17 20:18:47 -08001310 sp<Client> client = nullptr;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001311 ret = connectHelper<ICameraClient,Client>(cameraClient, id, halVersion,
1312 clientPackageName, clientUid, USE_CALLING_PID, API_1,
1313 /*legacyMode*/ true, /*shimUpdateOnly*/ false,
1314 /*out*/client);
Zhijun Heb10cdad2014-06-16 16:38:35 -07001315
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001316 if(!ret.isOk()) {
Svetoslav Ganov280405a2015-05-12 02:19:27 +00001317 logRejected(id, getCallingPid(), String8(clientPackageName),
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001318 ret.toString8());
Ruben Brunkcc776712015-02-17 20:18:47 -08001319 return ret;
Zhijun Heb10cdad2014-06-16 16:38:35 -07001320 }
1321
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001322 *device = client;
1323 return ret;
Zhijun Heb10cdad2014-06-16 16:38:35 -07001324}
1325
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001326Status CameraService::connectDevice(
1327 const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb,
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08001328 const String16& cameraId,
Svetoslav Ganov280405a2015-05-12 02:19:27 +00001329 const String16& clientPackageName,
Ruben Brunkcc776712015-02-17 20:18:47 -08001330 int clientUid,
1331 /*out*/
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001332 sp<hardware::camera2::ICameraDeviceUser>* device) {
Ruben Brunkcc776712015-02-17 20:18:47 -08001333
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -07001334 ATRACE_CALL();
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001335 Status ret = Status::ok();
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08001336 String8 id = String8(cameraId);
Ruben Brunkcc776712015-02-17 20:18:47 -08001337 sp<CameraDeviceClient> client = nullptr;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001338 ret = connectHelper<hardware::camera2::ICameraDeviceCallbacks,CameraDeviceClient>(cameraCb, id,
1339 CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageName,
1340 clientUid, USE_CALLING_PID, API_2,
1341 /*legacyMode*/ false, /*shimUpdateOnly*/ false,
1342 /*out*/client);
Ruben Brunkcc776712015-02-17 20:18:47 -08001343
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001344 if(!ret.isOk()) {
Svetoslav Ganov280405a2015-05-12 02:19:27 +00001345 logRejected(id, getCallingPid(), String8(clientPackageName),
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001346 ret.toString8());
Ruben Brunkcc776712015-02-17 20:18:47 -08001347 return ret;
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001348 }
1349
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001350 *device = client;
1351 return ret;
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001352}
1353
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08001354template<class CALLBACK, class CLIENT>
1355Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
1356 int halVersion, const String16& clientPackageName, int clientUid, int clientPid,
1357 apiLevel effectiveApiLevel, bool legacyMode, bool shimUpdateOnly,
1358 /*out*/sp<CLIENT>& device) {
1359 binder::Status ret = binder::Status::ok();
1360
1361 String8 clientName8(clientPackageName);
1362
1363 int originalClientPid = 0;
1364
1365 ALOGI("CameraService::connect call (PID %d \"%s\", camera ID %s) for HAL version %s and "
1366 "Camera API version %d", clientPid, clientName8.string(), cameraId.string(),
1367 (halVersion == -1) ? "default" : std::to_string(halVersion).c_str(),
1368 static_cast<int>(effectiveApiLevel));
1369
1370 sp<CLIENT> client = nullptr;
1371 {
1372 // Acquire mServiceLock and prevent other clients from connecting
1373 std::unique_ptr<AutoConditionLock> lock =
1374 AutoConditionLock::waitAndAcquire(mServiceLockWrapper, DEFAULT_CONNECT_TIMEOUT_NS);
1375
1376 if (lock == nullptr) {
1377 ALOGE("CameraService::connect (PID %d) rejected (too many other clients connecting)."
1378 , clientPid);
1379 return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE,
1380 "Cannot open camera %s for \"%s\" (PID %d): Too many other clients connecting",
1381 cameraId.string(), clientName8.string(), clientPid);
1382 }
1383
1384 // Enforce client permissions and do basic sanity checks
1385 if(!(ret = validateConnectLocked(cameraId, clientName8,
1386 /*inout*/clientUid, /*inout*/clientPid, /*out*/originalClientPid)).isOk()) {
1387 return ret;
1388 }
1389
1390 // Check the shim parameters after acquiring lock, if they have already been updated and
1391 // we were doing a shim update, return immediately
1392 if (shimUpdateOnly) {
1393 auto cameraState = getCameraState(cameraId);
1394 if (cameraState != nullptr) {
1395 if (!cameraState->getShimParams().isEmpty()) return ret;
1396 }
1397 }
1398
1399 status_t err;
1400
1401 sp<BasicClient> clientTmp = nullptr;
1402 std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>> partial;
1403 if ((err = handleEvictionsLocked(cameraId, originalClientPid, effectiveApiLevel,
1404 IInterface::asBinder(cameraCb), clientName8, /*out*/&clientTmp,
1405 /*out*/&partial)) != NO_ERROR) {
1406 switch (err) {
1407 case -ENODEV:
1408 return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
1409 "No camera device with ID \"%s\" currently available",
1410 cameraId.string());
1411 case -EBUSY:
1412 return STATUS_ERROR_FMT(ERROR_CAMERA_IN_USE,
1413 "Higher-priority client using camera, ID \"%s\" currently unavailable",
1414 cameraId.string());
1415 default:
1416 return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
1417 "Unexpected error %s (%d) opening camera \"%s\"",
1418 strerror(-err), err, cameraId.string());
1419 }
1420 }
1421
1422 if (clientTmp.get() != nullptr) {
1423 // Handle special case for API1 MediaRecorder where the existing client is returned
1424 device = static_cast<CLIENT*>(clientTmp.get());
1425 return ret;
1426 }
1427
1428 // give flashlight a chance to close devices if necessary.
1429 mFlashlight->prepareDeviceOpen(cameraId);
1430
1431 // TODO: Update getDeviceVersion + HAL interface to use strings for Camera IDs
1432 int id = cameraIdToInt(cameraId);
1433 if (id == -1) {
1434 ALOGE("%s: Invalid camera ID %s, cannot get device version from HAL.", __FUNCTION__,
1435 cameraId.string());
1436 return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
1437 "Bad camera ID \"%s\" passed to camera open", cameraId.string());
1438 }
1439
1440 int facing = -1;
1441 int deviceVersion = getDeviceVersion(id, /*out*/&facing);
1442 sp<BasicClient> tmp = nullptr;
1443 if(!(ret = makeClient(this, cameraCb, clientPackageName, id, facing, clientPid,
1444 clientUid, getpid(), legacyMode, halVersion, deviceVersion, effectiveApiLevel,
1445 /*out*/&tmp)).isOk()) {
1446 return ret;
1447 }
1448 client = static_cast<CLIENT*>(tmp.get());
1449
1450 LOG_ALWAYS_FATAL_IF(client.get() == nullptr, "%s: CameraService in invalid state",
1451 __FUNCTION__);
1452
1453 if ((err = client->initialize(mModule)) != OK) {
1454 ALOGE("%s: Could not initialize client from HAL module.", __FUNCTION__);
1455 // Errors could be from the HAL module open call or from AppOpsManager
1456 switch(err) {
1457 case BAD_VALUE:
1458 return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
1459 "Illegal argument to HAL module for camera \"%s\"", cameraId.string());
1460 case -EBUSY:
1461 return STATUS_ERROR_FMT(ERROR_CAMERA_IN_USE,
1462 "Camera \"%s\" is already open", cameraId.string());
1463 case -EUSERS:
1464 return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE,
1465 "Too many cameras already open, cannot open camera \"%s\"",
1466 cameraId.string());
1467 case PERMISSION_DENIED:
1468 return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
1469 "No permission to open camera \"%s\"", cameraId.string());
1470 case -EACCES:
1471 return STATUS_ERROR_FMT(ERROR_DISABLED,
1472 "Camera \"%s\" disabled by policy", cameraId.string());
1473 case -ENODEV:
1474 default:
1475 return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
1476 "Failed to initialize camera \"%s\": %s (%d)", cameraId.string(),
1477 strerror(-err), err);
1478 }
1479 }
1480
1481 // Update shim paremeters for legacy clients
1482 if (effectiveApiLevel == API_1) {
1483 // Assume we have always received a Client subclass for API1
1484 sp<Client> shimClient = reinterpret_cast<Client*>(client.get());
1485 String8 rawParams = shimClient->getParameters();
1486 CameraParameters params(rawParams);
1487
1488 auto cameraState = getCameraState(cameraId);
1489 if (cameraState != nullptr) {
1490 cameraState->setShimParams(params);
1491 } else {
1492 ALOGE("%s: Cannot update shim parameters for camera %s, no such device exists.",
1493 __FUNCTION__, cameraId.string());
1494 }
1495 }
1496
1497 if (shimUpdateOnly) {
1498 // If only updating legacy shim parameters, immediately disconnect client
1499 mServiceLock.unlock();
1500 client->disconnect();
1501 mServiceLock.lock();
1502 } else {
1503 // Otherwise, add client to active clients list
1504 finishConnectLocked(client, partial);
1505 }
1506 } // lock is destroyed, allow further connect calls
1507
1508 // Important: release the mutex here so the client can call back into the service from its
1509 // destructor (can be at the end of the call)
1510 device = client;
1511 return ret;
1512}
1513
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001514Status CameraService::setTorchMode(const String16& cameraId, bool enabled,
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001515 const sp<IBinder>& clientBinder) {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -07001516
1517 ATRACE_CALL();
Ruben Brunk99e69712015-05-26 17:25:07 -07001518 if (enabled && clientBinder == nullptr) {
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001519 ALOGE("%s: torch client binder is NULL", __FUNCTION__);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001520 return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT,
1521 "Torch client Binder is null");
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001522 }
1523
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001524 String8 id = String8(cameraId.string());
Ruben Brunk99e69712015-05-26 17:25:07 -07001525 int uid = getCallingUid();
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001526
1527 // verify id is valid.
Ruben Brunkcc776712015-02-17 20:18:47 -08001528 auto state = getCameraState(id);
1529 if (state == nullptr) {
Chien-Yu Chenf6463fc2015-04-07 15:11:31 -07001530 ALOGE("%s: camera id is invalid %s", __FUNCTION__, id.string());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001531 return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
1532 "Camera ID \"%s\" is a not valid camera ID", id.string());
Ruben Brunkcc776712015-02-17 20:18:47 -08001533 }
1534
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08001535 StatusInternal cameraStatus = state->getStatus();
1536 if (cameraStatus != StatusInternal::PRESENT &&
1537 cameraStatus != StatusInternal::NOT_PRESENT) {
Chien-Yu Chenf6463fc2015-04-07 15:11:31 -07001538 ALOGE("%s: camera id is invalid %s", __FUNCTION__, id.string());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001539 return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
1540 "Camera ID \"%s\" is a not valid camera ID", id.string());
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001541 }
1542
1543 {
1544 Mutex::Autolock al(mTorchStatusMutex);
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08001545 TorchModeStatus status;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001546 status_t err = getTorchStatusLocked(id, &status);
1547 if (err != OK) {
1548 if (err == NAME_NOT_FOUND) {
1549 return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
1550 "Camera \"%s\" does not have a flash unit", id.string());
1551 }
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001552 ALOGE("%s: getting current torch status failed for camera %s",
1553 __FUNCTION__, id.string());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001554 return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
1555 "Error updating torch status for camera \"%s\": %s (%d)", id.string(),
1556 strerror(-err), err);
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001557 }
1558
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08001559 if (status == TorchModeStatus::NOT_AVAILABLE) {
1560 if (cameraStatus == StatusInternal::NOT_PRESENT) {
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001561 ALOGE("%s: torch mode of camera %s is not available because "
1562 "camera is in use", __FUNCTION__, id.string());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001563 return STATUS_ERROR_FMT(ERROR_CAMERA_IN_USE,
1564 "Torch for camera \"%s\" is not available due to an existing camera user",
1565 id.string());
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001566 } else {
1567 ALOGE("%s: torch mode of camera %s is not available due to "
1568 "insufficient resources", __FUNCTION__, id.string());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001569 return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE,
1570 "Torch for camera \"%s\" is not available due to insufficient resources",
1571 id.string());
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001572 }
1573 }
1574 }
1575
Ruben Brunk99e69712015-05-26 17:25:07 -07001576 {
1577 // Update UID map - this is used in the torch status changed callbacks, so must be done
1578 // before setTorchMode
Chien-Yu Chenfe751be2015-09-01 14:16:44 -07001579 Mutex::Autolock al(mTorchUidMapMutex);
Ruben Brunk99e69712015-05-26 17:25:07 -07001580 if (mTorchUidMap.find(id) == mTorchUidMap.end()) {
1581 mTorchUidMap[id].first = uid;
1582 mTorchUidMap[id].second = uid;
1583 } else {
1584 // Set the pending UID
1585 mTorchUidMap[id].first = uid;
1586 }
1587 }
1588
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001589 status_t err = mFlashlight->setTorchMode(id, enabled);
Ruben Brunk99e69712015-05-26 17:25:07 -07001590
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001591 if (err != OK) {
1592 int32_t errorCode;
1593 String8 msg;
1594 switch (err) {
1595 case -ENOSYS:
1596 msg = String8::format("Camera \"%s\" has no flashlight",
1597 id.string());
1598 errorCode = ERROR_ILLEGAL_ARGUMENT;
1599 break;
1600 default:
1601 msg = String8::format(
1602 "Setting torch mode of camera \"%s\" to %d failed: %s (%d)",
1603 id.string(), enabled, strerror(-err), err);
1604 errorCode = ERROR_INVALID_OPERATION;
1605 }
1606 ALOGE("%s: %s", __FUNCTION__, msg.string());
1607 return STATUS_ERROR(errorCode, msg.string());
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001608 }
1609
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001610 {
1611 // update the link to client's death
1612 Mutex::Autolock al(mTorchClientMapMutex);
1613 ssize_t index = mTorchClientMap.indexOfKey(id);
1614 if (enabled) {
1615 if (index == NAME_NOT_FOUND) {
1616 mTorchClientMap.add(id, clientBinder);
1617 } else {
Ruben Brunk99e69712015-05-26 17:25:07 -07001618 mTorchClientMap.valueAt(index)->unlinkToDeath(this);
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001619 mTorchClientMap.replaceValueAt(index, clientBinder);
1620 }
1621 clientBinder->linkToDeath(this);
1622 } else if (index != NAME_NOT_FOUND) {
Ruben Brunk99e69712015-05-26 17:25:07 -07001623 mTorchClientMap.valueAt(index)->unlinkToDeath(this);
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001624 }
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001625 }
1626
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001627 return Status::ok();
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001628}
1629
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001630Status CameraService::notifySystemEvent(int32_t eventId,
1631 const std::vector<int32_t>& args) {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -07001632 ATRACE_CALL();
1633
Ruben Brunk36597b22015-03-20 22:15:57 -07001634 switch(eventId) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001635 case ICameraService::EVENT_USER_SWITCHED: {
1636 doUserSwitch(/*newUserIds*/ args);
Ruben Brunk36597b22015-03-20 22:15:57 -07001637 break;
1638 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001639 case ICameraService::EVENT_NONE:
Ruben Brunk36597b22015-03-20 22:15:57 -07001640 default: {
1641 ALOGW("%s: Received invalid system event from system_server: %d", __FUNCTION__,
1642 eventId);
1643 break;
1644 }
1645 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001646 return Status::ok();
Ruben Brunk36597b22015-03-20 22:15:57 -07001647}
1648
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08001649Status CameraService::addListener(const sp<ICameraServiceListener>& listener,
1650 /*out*/
1651 std::vector<hardware::CameraStatus> *cameraStatuses) {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -07001652 ATRACE_CALL();
1653
Igor Murashkinbfc99152013-02-27 12:55:20 -08001654 ALOGV("%s: Add listener %p", __FUNCTION__, listener.get());
Igor Murashkin634a5152013-02-20 17:15:11 -08001655
Ruben Brunk3450ba72015-06-16 11:00:37 -07001656 if (listener == nullptr) {
Igor Murashkinbd3e2e02014-03-17 13:01:41 -07001657 ALOGE("%s: Listener must not be null", __FUNCTION__);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001658 return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Null listener given to addListener");
Igor Murashkinbd3e2e02014-03-17 13:01:41 -07001659 }
1660
Igor Murashkinbfc99152013-02-27 12:55:20 -08001661 Mutex::Autolock lock(mServiceLock);
1662
Ruben Brunkcc776712015-02-17 20:18:47 -08001663 {
1664 Mutex::Autolock lock(mStatusListenerLock);
1665 for (auto& it : mListenerList) {
1666 if (IInterface::asBinder(it) == IInterface::asBinder(listener)) {
1667 ALOGW("%s: Tried to add listener %p which was already subscribed",
1668 __FUNCTION__, listener.get());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001669 return STATUS_ERROR(ERROR_ALREADY_EXISTS, "Listener already registered");
Ruben Brunkcc776712015-02-17 20:18:47 -08001670 }
Igor Murashkinbfc99152013-02-27 12:55:20 -08001671 }
Ruben Brunkcc776712015-02-17 20:18:47 -08001672
1673 mListenerList.push_back(listener);
Igor Murashkinbfc99152013-02-27 12:55:20 -08001674 }
1675
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08001676 /* Collect current devices and status */
Igor Murashkincba2c162013-03-20 15:56:31 -07001677 {
Ruben Brunkcc776712015-02-17 20:18:47 -08001678 Mutex::Autolock lock(mCameraStatesLock);
1679 for (auto& i : mCameraStates) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08001680 cameraStatuses->emplace_back(i.first, mapToInterface(i.second->getStatus()));
Igor Murashkincba2c162013-03-20 15:56:31 -07001681 }
1682 }
1683
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08001684 /*
1685 * Immediately signal current torch status to this listener only
1686 * This may be a subset of all the devices, so don't include it in the response directly
1687 */
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001688 {
1689 Mutex::Autolock al(mTorchStatusMutex);
1690 for (size_t i = 0; i < mTorchStatusMap.size(); i++ ) {
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001691 String16 id = String16(mTorchStatusMap.keyAt(i).string());
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08001692 listener->onTorchStatusChanged(mapToInterface(mTorchStatusMap.valueAt(i)), id);
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001693 }
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001694 }
1695
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001696 return Status::ok();
Igor Murashkinbfc99152013-02-27 12:55:20 -08001697}
Ruben Brunkcc776712015-02-17 20:18:47 -08001698
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001699Status CameraService::removeListener(const sp<ICameraServiceListener>& listener) {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -07001700 ATRACE_CALL();
1701
Igor Murashkinbfc99152013-02-27 12:55:20 -08001702 ALOGV("%s: Remove listener %p", __FUNCTION__, listener.get());
1703
Igor Murashkinbd3e2e02014-03-17 13:01:41 -07001704 if (listener == 0) {
1705 ALOGE("%s: Listener must not be null", __FUNCTION__);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001706 return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Null listener given to removeListener");
Igor Murashkinbd3e2e02014-03-17 13:01:41 -07001707 }
1708
Igor Murashkinbfc99152013-02-27 12:55:20 -08001709 Mutex::Autolock lock(mServiceLock);
1710
Ruben Brunkcc776712015-02-17 20:18:47 -08001711 {
1712 Mutex::Autolock lock(mStatusListenerLock);
1713 for (auto it = mListenerList.begin(); it != mListenerList.end(); it++) {
1714 if (IInterface::asBinder(*it) == IInterface::asBinder(listener)) {
1715 mListenerList.erase(it);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001716 return Status::ok();
Ruben Brunkcc776712015-02-17 20:18:47 -08001717 }
Igor Murashkinbfc99152013-02-27 12:55:20 -08001718 }
1719 }
1720
1721 ALOGW("%s: Tried to remove a listener %p which was not subscribed",
1722 __FUNCTION__, listener.get());
1723
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001724 return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Unregistered listener given to removeListener");
Igor Murashkin634a5152013-02-20 17:15:11 -08001725}
1726
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001727Status CameraService::getLegacyParameters(int cameraId, /*out*/String16* parameters) {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -07001728
1729 ATRACE_CALL();
Igor Murashkin65d14b92014-06-17 12:03:20 -07001730 ALOGV("%s: for camera ID = %d", __FUNCTION__, cameraId);
1731
1732 if (parameters == NULL) {
1733 ALOGE("%s: parameters must not be null", __FUNCTION__);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001734 return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Parameters must not be null");
Igor Murashkin65d14b92014-06-17 12:03:20 -07001735 }
1736
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001737 Status ret = Status::ok();
Igor Murashkin65d14b92014-06-17 12:03:20 -07001738
1739 CameraParameters shimParams;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001740 if (!(ret = getLegacyParametersLazy(cameraId, /*out*/&shimParams)).isOk()) {
Igor Murashkin65d14b92014-06-17 12:03:20 -07001741 // Error logged by caller
1742 return ret;
1743 }
1744
1745 String8 shimParamsString8 = shimParams.flatten();
1746 String16 shimParamsString16 = String16(shimParamsString8);
1747
1748 *parameters = shimParamsString16;
1749
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001750 return ret;
Igor Murashkin65d14b92014-06-17 12:03:20 -07001751}
1752
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08001753Status CameraService::supportsCameraApi(const String16& cameraId, int apiVersion,
1754 /*out*/ bool *isSupported) {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -07001755 ATRACE_CALL();
1756
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08001757 ALOGV("%s: for camera ID = %s", __FUNCTION__, String8(cameraId).string());
Igor Murashkin65d14b92014-06-17 12:03:20 -07001758
1759 switch (apiVersion) {
1760 case API_VERSION_1:
1761 case API_VERSION_2:
1762 break;
1763 default:
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001764 String8 msg = String8::format("Unknown API version %d", apiVersion);
1765 ALOGE("%s: %s", __FUNCTION__, msg.string());
1766 return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.string());
Igor Murashkin65d14b92014-06-17 12:03:20 -07001767 }
1768
1769 int facing = -1;
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08001770
1771 int id = cameraIdToInt(String8(cameraId));
1772 int deviceVersion = getDeviceVersion(id, &facing);
Igor Murashkin65d14b92014-06-17 12:03:20 -07001773
1774 switch(deviceVersion) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001775 case CAMERA_DEVICE_API_VERSION_1_0:
1776 case CAMERA_DEVICE_API_VERSION_3_0:
1777 case CAMERA_DEVICE_API_VERSION_3_1:
1778 if (apiVersion == API_VERSION_2) {
1779 ALOGV("%s: Camera id %d uses HAL version %d <3.2, doesn't support api2 without shim",
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08001780 __FUNCTION__, id, deviceVersion);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001781 *isSupported = false;
1782 } else { // if (apiVersion == API_VERSION_1) {
1783 ALOGV("%s: Camera id %d uses older HAL before 3.2, but api1 is always supported",
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08001784 __FUNCTION__, id);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001785 *isSupported = true;
1786 }
1787 break;
1788 case CAMERA_DEVICE_API_VERSION_3_2:
1789 case CAMERA_DEVICE_API_VERSION_3_3:
Zhijun He4afbdec2016-05-04 15:42:51 -07001790 case CAMERA_DEVICE_API_VERSION_3_4:
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001791 ALOGV("%s: Camera id %d uses HAL3.2 or newer, supports api1/api2 directly",
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08001792 __FUNCTION__, id);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001793 *isSupported = true;
1794 break;
1795 case -1: {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08001796 String8 msg = String8::format("Unknown camera ID %d", id);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001797 ALOGE("%s: %s", __FUNCTION__, msg.string());
1798 return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.string());
Igor Murashkin65d14b92014-06-17 12:03:20 -07001799 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001800 default: {
1801 String8 msg = String8::format("Unknown device version %d for device %d",
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08001802 deviceVersion, id);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001803 ALOGE("%s: %s", __FUNCTION__, msg.string());
1804 return STATUS_ERROR(ERROR_INVALID_OPERATION, msg.string());
1805 }
Igor Murashkin65d14b92014-06-17 12:03:20 -07001806 }
1807
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001808 return Status::ok();
Igor Murashkin65d14b92014-06-17 12:03:20 -07001809}
1810
Ruben Brunkcc776712015-02-17 20:18:47 -08001811void CameraService::removeByClient(const BasicClient* client) {
Igor Murashkinecf17e82012-10-02 16:05:11 -07001812 Mutex::Autolock lock(mServiceLock);
Ruben Brunkcc776712015-02-17 20:18:47 -08001813 for (auto& i : mActiveClientManager.getAll()) {
1814 auto clientSp = i->getValue();
1815 if (clientSp.get() == client) {
1816 mActiveClientManager.remove(i);
Igor Murashkin634a5152013-02-20 17:15:11 -08001817 }
Igor Murashkinecf17e82012-10-02 16:05:11 -07001818 }
Igor Murashkin634a5152013-02-20 17:15:11 -08001819}
1820
Ruben Brunkcc776712015-02-17 20:18:47 -08001821bool CameraService::evictClientIdByRemote(const wp<IBinder>& remote) {
1822 const int callingPid = getCallingPid();
1823 const int servicePid = getpid();
1824 bool ret = false;
1825 {
1826 // Acquire mServiceLock and prevent other clients from connecting
1827 std::unique_ptr<AutoConditionLock> lock =
1828 AutoConditionLock::waitAndAcquire(mServiceLockWrapper);
Igor Murashkin634a5152013-02-20 17:15:11 -08001829
Igor Murashkin634a5152013-02-20 17:15:11 -08001830
Ruben Brunkcc776712015-02-17 20:18:47 -08001831 std::vector<sp<BasicClient>> evicted;
1832 for (auto& i : mActiveClientManager.getAll()) {
1833 auto clientSp = i->getValue();
1834 if (clientSp.get() == nullptr) {
1835 ALOGE("%s: Dead client still in mActiveClientManager.", __FUNCTION__);
1836 mActiveClientManager.remove(i);
1837 continue;
1838 }
1839 if (remote == clientSp->getRemote() && (callingPid == servicePid ||
1840 callingPid == clientSp->getClientPid())) {
1841 mActiveClientManager.remove(i);
1842 evicted.push_back(clientSp);
Igor Murashkin634a5152013-02-20 17:15:11 -08001843
Ruben Brunkcc776712015-02-17 20:18:47 -08001844 // Notify the client of disconnection
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001845 clientSp->notifyError(
1846 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED,
Ruben Brunkcc776712015-02-17 20:18:47 -08001847 CaptureResultExtras());
Igor Murashkin634a5152013-02-20 17:15:11 -08001848 }
1849 }
1850
Ruben Brunkcc776712015-02-17 20:18:47 -08001851 // Do not hold mServiceLock while disconnecting clients, but retain the condition blocking
1852 // other clients from connecting in mServiceLockWrapper if held
1853 mServiceLock.unlock();
1854
Ruben Brunk36597b22015-03-20 22:15:57 -07001855 // Do not clear caller identity, remote caller should be client proccess
1856
Ruben Brunkcc776712015-02-17 20:18:47 -08001857 for (auto& i : evicted) {
1858 if (i.get() != nullptr) {
1859 i->disconnect();
1860 ret = true;
1861 }
Igor Murashkin634a5152013-02-20 17:15:11 -08001862 }
1863
Ruben Brunkcc776712015-02-17 20:18:47 -08001864 // Reacquire mServiceLock
1865 mServiceLock.lock();
Igor Murashkin634a5152013-02-20 17:15:11 -08001866
Ruben Brunkcc776712015-02-17 20:18:47 -08001867 } // lock is destroyed, allow further connect calls
1868
1869 return ret;
Igor Murashkinecf17e82012-10-02 16:05:11 -07001870}
1871
Igor Murashkinecf17e82012-10-02 16:05:11 -07001872
Eino-Ville Talvalabad43582015-08-14 13:12:32 -07001873/**
1874 * Check camera capabilities, such as support for basic color operation
Eino-Ville Talvalad309fb92015-11-25 12:12:45 -08001875 * Also check that the device HAL version is still in support
Eino-Ville Talvalabad43582015-08-14 13:12:32 -07001876 */
1877int CameraService::checkCameraCapabilities(int id, camera_info info, int *latestStrangeCameraId) {
Yin-Chia Yeh654b4bf2015-12-08 12:19:31 -08001878 // device_version undefined in CAMERA_MODULE_API_VERSION_1_0,
1879 // All CAMERA_MODULE_API_VERSION_1_0 devices are backward-compatible
1880 if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_0) {
1881 // Verify the device version is in the supported range
1882 switch (info.device_version) {
1883 case CAMERA_DEVICE_API_VERSION_1_0:
1884 case CAMERA_DEVICE_API_VERSION_3_0:
1885 case CAMERA_DEVICE_API_VERSION_3_1:
1886 case CAMERA_DEVICE_API_VERSION_3_2:
1887 case CAMERA_DEVICE_API_VERSION_3_3:
Zhijun He4afbdec2016-05-04 15:42:51 -07001888 case CAMERA_DEVICE_API_VERSION_3_4:
Yin-Chia Yeh654b4bf2015-12-08 12:19:31 -08001889 // in support
1890 break;
1891 case CAMERA_DEVICE_API_VERSION_2_0:
1892 case CAMERA_DEVICE_API_VERSION_2_1:
1893 // no longer supported
1894 default:
1895 ALOGE("%s: Device %d has HAL version %x, which is not supported",
1896 __FUNCTION__, id, info.device_version);
1897 String8 msg = String8::format(
1898 "Unsupported device HAL version %x for device %d",
1899 info.device_version, id);
1900 logServiceError(msg.string(), NO_INIT);
1901 return NO_INIT;
1902 }
Eino-Ville Talvalad309fb92015-11-25 12:12:45 -08001903 }
1904
Eino-Ville Talvalabad43582015-08-14 13:12:32 -07001905 // Assume all devices pre-v3.3 are backward-compatible
1906 bool isBackwardCompatible = true;
1907 if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_0
1908 && info.device_version >= CAMERA_DEVICE_API_VERSION_3_3) {
1909 isBackwardCompatible = false;
1910 status_t res;
1911 camera_metadata_ro_entry_t caps;
1912 res = find_camera_metadata_ro_entry(
1913 info.static_camera_characteristics,
1914 ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
1915 &caps);
1916 if (res != 0) {
1917 ALOGW("%s: Unable to find camera capabilities for camera device %d",
1918 __FUNCTION__, id);
1919 caps.count = 0;
1920 }
1921 for (size_t i = 0; i < caps.count; i++) {
1922 if (caps.data.u8[i] ==
1923 ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE) {
1924 isBackwardCompatible = true;
1925 break;
1926 }
1927 }
1928 }
1929
1930 if (!isBackwardCompatible) {
1931 mNumberOfNormalCameras--;
1932 *latestStrangeCameraId = id;
1933 } else {
1934 if (id > *latestStrangeCameraId) {
1935 ALOGE("%s: Normal camera ID %d higher than strange camera ID %d. "
1936 "This is not allowed due backward-compatibility requirements",
1937 __FUNCTION__, id, *latestStrangeCameraId);
Eino-Ville Talvalad309fb92015-11-25 12:12:45 -08001938 logServiceError("Invalid order of camera devices", NO_INIT);
Eino-Ville Talvalabad43582015-08-14 13:12:32 -07001939 mNumberOfCameras = 0;
1940 mNumberOfNormalCameras = 0;
Eino-Ville Talvalad309fb92015-11-25 12:12:45 -08001941 return NO_INIT;
Eino-Ville Talvalabad43582015-08-14 13:12:32 -07001942 }
1943 }
1944 return OK;
1945}
1946
Ruben Brunkcc776712015-02-17 20:18:47 -08001947std::shared_ptr<CameraService::CameraState> CameraService::getCameraState(
1948 const String8& cameraId) const {
1949 std::shared_ptr<CameraState> state;
1950 {
1951 Mutex::Autolock lock(mCameraStatesLock);
1952 auto iter = mCameraStates.find(cameraId);
1953 if (iter != mCameraStates.end()) {
1954 state = iter->second;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001955 }
1956 }
Ruben Brunkcc776712015-02-17 20:18:47 -08001957 return state;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001958}
1959
Ruben Brunkcc776712015-02-17 20:18:47 -08001960sp<CameraService::BasicClient> CameraService::removeClientLocked(const String8& cameraId) {
1961 // Remove from active clients list
1962 auto clientDescriptorPtr = mActiveClientManager.remove(cameraId);
1963 if (clientDescriptorPtr == nullptr) {
1964 ALOGW("%s: Could not evict client, no client for camera ID %s", __FUNCTION__,
1965 cameraId.string());
1966 return sp<BasicClient>{nullptr};
1967 }
1968
1969 return clientDescriptorPtr->getValue();
Keun young Parkd8973a72012-03-28 14:13:09 -07001970}
1971
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001972void CameraService::doUserSwitch(const std::vector<int32_t>& newUserIds) {
Ruben Brunk36597b22015-03-20 22:15:57 -07001973 // Acquire mServiceLock and prevent other clients from connecting
1974 std::unique_ptr<AutoConditionLock> lock =
1975 AutoConditionLock::waitAndAcquire(mServiceLockWrapper);
1976
Ruben Brunk6267b532015-04-30 17:44:07 -07001977 std::set<userid_t> newAllowedUsers;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001978 for (size_t i = 0; i < newUserIds.size(); i++) {
1979 if (newUserIds[i] < 0) {
Ruben Brunk6267b532015-04-30 17:44:07 -07001980 ALOGE("%s: Bad user ID %d given during user switch, ignoring.",
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001981 __FUNCTION__, newUserIds[i]);
Ruben Brunk6267b532015-04-30 17:44:07 -07001982 return;
1983 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001984 newAllowedUsers.insert(static_cast<userid_t>(newUserIds[i]));
Ruben Brunk36597b22015-03-20 22:15:57 -07001985 }
1986
Ruben Brunka8ca9152015-04-07 14:23:40 -07001987
Ruben Brunk6267b532015-04-30 17:44:07 -07001988 if (newAllowedUsers == mAllowedUsers) {
1989 ALOGW("%s: Received notification of user switch with no updated user IDs.", __FUNCTION__);
1990 return;
1991 }
1992
1993 logUserSwitch(mAllowedUsers, newAllowedUsers);
1994
1995 mAllowedUsers = std::move(newAllowedUsers);
Ruben Brunk36597b22015-03-20 22:15:57 -07001996
1997 // Current user has switched, evict all current clients.
1998 std::vector<sp<BasicClient>> evicted;
1999 for (auto& i : mActiveClientManager.getAll()) {
2000 auto clientSp = i->getValue();
2001
2002 if (clientSp.get() == nullptr) {
2003 ALOGE("%s: Dead client still in mActiveClientManager.", __FUNCTION__);
2004 continue;
2005 }
2006
Ruben Brunk6267b532015-04-30 17:44:07 -07002007 // Don't evict clients that are still allowed.
2008 uid_t clientUid = clientSp->getClientUid();
2009 userid_t clientUserId = multiuser_get_user_id(clientUid);
2010 if (mAllowedUsers.find(clientUserId) != mAllowedUsers.end()) {
2011 continue;
2012 }
2013
Ruben Brunk36597b22015-03-20 22:15:57 -07002014 evicted.push_back(clientSp);
2015
2016 String8 curTime = getFormattedCurrentTime();
2017
2018 ALOGE("Evicting conflicting client for camera ID %s due to user change",
2019 i->getKey().string());
Ruben Brunka8ca9152015-04-07 14:23:40 -07002020
Ruben Brunk36597b22015-03-20 22:15:57 -07002021 // Log the clients evicted
Ruben Brunka8ca9152015-04-07 14:23:40 -07002022 logEvent(String8::format("EVICT device %s client held by package %s (PID %"
Ruben Brunk36597b22015-03-20 22:15:57 -07002023 PRId32 ", priority %" PRId32 ")\n - Evicted due to user switch.",
Ruben Brunka8ca9152015-04-07 14:23:40 -07002024 i->getKey().string(), String8{clientSp->getPackageName()}.string(),
2025 i->getOwnerId(), i->getPriority()));
Ruben Brunk36597b22015-03-20 22:15:57 -07002026
2027 }
2028
2029 // Do not hold mServiceLock while disconnecting clients, but retain the condition
2030 // blocking other clients from connecting in mServiceLockWrapper if held.
2031 mServiceLock.unlock();
2032
2033 // Clear caller identity temporarily so client disconnect PID checks work correctly
2034 int64_t token = IPCThreadState::self()->clearCallingIdentity();
2035
2036 for (auto& i : evicted) {
2037 i->disconnect();
2038 }
2039
2040 IPCThreadState::self()->restoreCallingIdentity(token);
2041
2042 // Reacquire mServiceLock
2043 mServiceLock.lock();
2044}
Ruben Brunkcc776712015-02-17 20:18:47 -08002045
Ruben Brunka8ca9152015-04-07 14:23:40 -07002046void CameraService::logEvent(const char* event) {
Ruben Brunkcc776712015-02-17 20:18:47 -08002047 String8 curTime = getFormattedCurrentTime();
Ruben Brunka8ca9152015-04-07 14:23:40 -07002048 Mutex::Autolock l(mLogLock);
2049 mEventLog.add(String8::format("%s : %s", curTime.string(), event));
Mathias Agopian65ab4712010-07-14 17:59:35 -07002050}
2051
Ruben Brunka8ca9152015-04-07 14:23:40 -07002052void CameraService::logDisconnected(const char* cameraId, int clientPid,
Svetoslav Ganov280405a2015-05-12 02:19:27 +00002053 const char* clientPackage) {
Ruben Brunkcc776712015-02-17 20:18:47 -08002054 // Log the clients evicted
Ruben Brunka8ca9152015-04-07 14:23:40 -07002055 logEvent(String8::format("DISCONNECT device %s client for package %s (PID %d)", cameraId,
Svetoslav Ganov280405a2015-05-12 02:19:27 +00002056 clientPackage, clientPid));
Ruben Brunka8ca9152015-04-07 14:23:40 -07002057}
2058
2059void CameraService::logConnected(const char* cameraId, int clientPid,
Svetoslav Ganov280405a2015-05-12 02:19:27 +00002060 const char* clientPackage) {
Ruben Brunka8ca9152015-04-07 14:23:40 -07002061 // Log the clients evicted
2062 logEvent(String8::format("CONNECT device %s client for package %s (PID %d)", cameraId,
Svetoslav Ganov280405a2015-05-12 02:19:27 +00002063 clientPackage, clientPid));
Ruben Brunka8ca9152015-04-07 14:23:40 -07002064}
2065
2066void CameraService::logRejected(const char* cameraId, int clientPid,
Svetoslav Ganov280405a2015-05-12 02:19:27 +00002067 const char* clientPackage, const char* reason) {
Ruben Brunka8ca9152015-04-07 14:23:40 -07002068 // Log the client rejected
2069 logEvent(String8::format("REJECT device %s client for package %s (PID %d), reason: (%s)",
Svetoslav Ganov280405a2015-05-12 02:19:27 +00002070 cameraId, clientPackage, clientPid, reason));
Ruben Brunka8ca9152015-04-07 14:23:40 -07002071}
2072
Ruben Brunk6267b532015-04-30 17:44:07 -07002073void CameraService::logUserSwitch(const std::set<userid_t>& oldUserIds,
2074 const std::set<userid_t>& newUserIds) {
2075 String8 newUsers = toString(newUserIds);
2076 String8 oldUsers = toString(oldUserIds);
Ruben Brunka8ca9152015-04-07 14:23:40 -07002077 // Log the new and old users
Ruben Brunk6267b532015-04-30 17:44:07 -07002078 logEvent(String8::format("USER_SWITCH previous allowed users: %s , current allowed users: %s",
2079 oldUsers.string(), newUsers.string()));
Ruben Brunka8ca9152015-04-07 14:23:40 -07002080}
2081
2082void CameraService::logDeviceRemoved(const char* cameraId, const char* reason) {
2083 // Log the device removal
2084 logEvent(String8::format("REMOVE device %s, reason: (%s)", cameraId, reason));
2085}
2086
2087void CameraService::logDeviceAdded(const char* cameraId, const char* reason) {
2088 // Log the device removal
2089 logEvent(String8::format("ADD device %s, reason: (%s)", cameraId, reason));
2090}
2091
2092void CameraService::logClientDied(int clientPid, const char* reason) {
2093 // Log the device removal
2094 logEvent(String8::format("DIED client(s) with PID %d, reason: (%s)", clientPid, reason));
Igor Murashkinecf17e82012-10-02 16:05:11 -07002095}
2096
Eino-Ville Talvala1527f072015-04-07 15:55:31 -07002097void CameraService::logServiceError(const char* msg, int errorCode) {
2098 String8 curTime = getFormattedCurrentTime();
Eino-Ville Talvalad309fb92015-11-25 12:12:45 -08002099 logEvent(String8::format("SERVICE ERROR: %s : %d (%s)", msg, errorCode, strerror(-errorCode)));
Eino-Ville Talvala1527f072015-04-07 15:55:31 -07002100}
2101
Ruben Brunk36597b22015-03-20 22:15:57 -07002102status_t CameraService::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
2103 uint32_t flags) {
2104
2105 const int pid = getCallingPid();
2106 const int selfPid = getpid();
2107
Mathias Agopian65ab4712010-07-14 17:59:35 -07002108 // Permission checks
2109 switch (code) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08002110 case BnCameraService::NOTIFYSYSTEMEVENT: {
Ruben Brunk36597b22015-03-20 22:15:57 -07002111 if (pid != selfPid) {
2112 // Ensure we're being called by system_server, or similar process with
2113 // permissions to notify the camera service about system events
2114 if (!checkCallingPermission(
2115 String16("android.permission.CAMERA_SEND_SYSTEM_EVENTS"))) {
2116 const int uid = getCallingUid();
2117 ALOGE("Permission Denial: cannot send updates to camera service about system"
2118 " events from pid=%d, uid=%d", pid, uid);
2119 return PERMISSION_DENIED;
2120 }
2121 }
2122 break;
2123 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07002124 }
2125
2126 return BnCameraService::onTransact(code, data, reply, flags);
2127}
2128
Mathias Agopian65ab4712010-07-14 17:59:35 -07002129// We share the media players for shutter and recording sound for all clients.
2130// A reference count is kept to determine when we will actually release the
2131// media players.
2132
Chih-Chung Changff4f55c2011-10-17 19:03:12 +08002133MediaPlayer* CameraService::newMediaPlayer(const char *file) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07002134 MediaPlayer* mp = new MediaPlayer();
Andreas Huber1b86fe02014-01-29 11:13:26 -08002135 if (mp->setDataSource(NULL /* httpService */, file, NULL) == NO_ERROR) {
Eino-Ville Talvala60a78ac2012-01-05 15:34:53 -08002136 mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE);
Mathias Agopian65ab4712010-07-14 17:59:35 -07002137 mp->prepare();
2138 } else {
Steve Block29357bc2012-01-06 19:20:56 +00002139 ALOGE("Failed to load CameraService sounds: %s", file);
Mathias Agopian65ab4712010-07-14 17:59:35 -07002140 return NULL;
2141 }
2142 return mp;
2143}
2144
2145void CameraService::loadSound() {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -07002146 ATRACE_CALL();
2147
Mathias Agopian65ab4712010-07-14 17:59:35 -07002148 Mutex::Autolock lock(mSoundLock);
2149 LOG1("CameraService::loadSound ref=%d", mSoundRef);
2150 if (mSoundRef++) return;
2151
2152 mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
Chien-Yu Chen82104eb2015-10-14 11:29:31 -07002153 mSoundPlayer[SOUND_RECORDING_START] = newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");
2154 mSoundPlayer[SOUND_RECORDING_STOP] = newMediaPlayer("/system/media/audio/ui/VideoStop.ogg");
Mathias Agopian65ab4712010-07-14 17:59:35 -07002155}
2156
2157void CameraService::releaseSound() {
2158 Mutex::Autolock lock(mSoundLock);
2159 LOG1("CameraService::releaseSound ref=%d", mSoundRef);
2160 if (--mSoundRef) return;
2161
2162 for (int i = 0; i < NUM_SOUNDS; i++) {
2163 if (mSoundPlayer[i] != 0) {
2164 mSoundPlayer[i]->disconnect();
2165 mSoundPlayer[i].clear();
2166 }
2167 }
2168}
2169
2170void CameraService::playSound(sound_kind kind) {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -07002171 ATRACE_CALL();
2172
Mathias Agopian65ab4712010-07-14 17:59:35 -07002173 LOG1("playSound(%d)", kind);
2174 Mutex::Autolock lock(mSoundLock);
2175 sp<MediaPlayer> player = mSoundPlayer[kind];
2176 if (player != 0) {
Chih-Chung Chang8888a752011-10-20 10:47:26 +08002177 player->seekTo(0);
2178 player->start();
Mathias Agopian65ab4712010-07-14 17:59:35 -07002179 }
2180}
2181
2182// ----------------------------------------------------------------------------
2183
2184CameraService::Client::Client(const sp<CameraService>& cameraService,
Wu-cheng Lib7a67942010-08-17 15:45:37 -07002185 const sp<ICameraClient>& cameraClient,
Svetoslav Ganov280405a2015-05-12 02:19:27 +00002186 const String16& clientPackageName,
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002187 int cameraId, int cameraFacing,
2188 int clientPid, uid_t clientUid,
2189 int servicePid) :
Eino-Ville Talvalae992e752014-11-07 16:17:48 -08002190 CameraService::BasicClient(cameraService,
Marco Nelissenf8880202014-11-14 07:58:25 -08002191 IInterface::asBinder(cameraClient),
Svetoslav Ganov280405a2015-05-12 02:19:27 +00002192 clientPackageName,
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002193 cameraId, cameraFacing,
2194 clientPid, clientUid,
2195 servicePid)
Igor Murashkin634a5152013-02-20 17:15:11 -08002196{
Mathias Agopian65ab4712010-07-14 17:59:35 -07002197 int callingPid = getCallingPid();
Wu-cheng Li2fd24402012-02-23 19:01:00 -08002198 LOG1("Client::Client E (pid %d, id %d)", callingPid, cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -07002199
Igor Murashkin44cfcf02013-03-01 16:22:28 -08002200 mRemoteCallback = cameraClient;
Mathias Agopian65ab4712010-07-14 17:59:35 -07002201
Mathias Agopian65ab4712010-07-14 17:59:35 -07002202 cameraService->loadSound();
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002203
Wu-cheng Li2fd24402012-02-23 19:01:00 -08002204 LOG1("Client::Client X (pid %d, id %d)", callingPid, cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -07002205}
2206
Mathias Agopian65ab4712010-07-14 17:59:35 -07002207// tear down the client
2208CameraService::Client::~Client() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -07002209 ALOGV("~Client");
Igor Murashkin634a5152013-02-20 17:15:11 -08002210 mDestructionStarted = true;
2211
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002212 mCameraService->releaseSound();
Igor Murashkin036bc3e2012-10-08 15:09:46 -07002213 // unconditionally disconnect. function is idempotent
2214 Client::disconnect();
Mathias Agopian65ab4712010-07-14 17:59:35 -07002215}
2216
Igor Murashkin634a5152013-02-20 17:15:11 -08002217CameraService::BasicClient::BasicClient(const sp<CameraService>& cameraService,
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002218 const sp<IBinder>& remoteCallback,
Svetoslav Ganov280405a2015-05-12 02:19:27 +00002219 const String16& clientPackageName,
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002220 int cameraId, int cameraFacing,
2221 int clientPid, uid_t clientUid,
2222 int servicePid):
Svetoslav Ganov280405a2015-05-12 02:19:27 +00002223 mClientPackageName(clientPackageName), mDisconnected(false)
Igor Murashkin634a5152013-02-20 17:15:11 -08002224{
2225 mCameraService = cameraService;
Igor Murashkin44cfcf02013-03-01 16:22:28 -08002226 mRemoteBinder = remoteCallback;
Igor Murashkin634a5152013-02-20 17:15:11 -08002227 mCameraId = cameraId;
2228 mCameraFacing = cameraFacing;
2229 mClientPid = clientPid;
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002230 mClientUid = clientUid;
Igor Murashkin634a5152013-02-20 17:15:11 -08002231 mServicePid = servicePid;
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002232 mOpsActive = false;
Igor Murashkin634a5152013-02-20 17:15:11 -08002233 mDestructionStarted = false;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08002234
2235 // In some cases the calling code has no access to the package it runs under.
2236 // For example, NDK camera API.
2237 // In this case we will get the packages for the calling UID and pick the first one
2238 // for attributing the app op. This will work correctly for runtime permissions
2239 // as for legacy apps we will toggle the app op for all packages in the UID.
2240 // The caveat is that the operation may be attributed to the wrong package and
2241 // stats based on app ops may be slightly off.
2242 if (mClientPackageName.size() <= 0) {
2243 sp<IServiceManager> sm = defaultServiceManager();
2244 sp<IBinder> binder = sm->getService(String16(kPermissionServiceName));
2245 if (binder == 0) {
2246 ALOGE("Cannot get permission service");
2247 // Leave mClientPackageName unchanged (empty) and the further interaction
2248 // with camera will fail in BasicClient::startCameraOps
2249 return;
2250 }
2251
2252 sp<IPermissionController> permCtrl = interface_cast<IPermissionController>(binder);
2253 Vector<String16> packages;
2254
2255 permCtrl->getPackagesForUid(mClientUid, packages);
2256
2257 if (packages.isEmpty()) {
2258 ALOGE("No packages for calling UID");
2259 // Leave mClientPackageName unchanged (empty) and the further interaction
2260 // with camera will fail in BasicClient::startCameraOps
2261 return;
2262 }
2263 mClientPackageName = packages[0];
2264 }
Igor Murashkin634a5152013-02-20 17:15:11 -08002265}
2266
2267CameraService::BasicClient::~BasicClient() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -07002268 ALOGV("~BasicClient");
Igor Murashkin634a5152013-02-20 17:15:11 -08002269 mDestructionStarted = true;
2270}
2271
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08002272binder::Status CameraService::BasicClient::disconnect() {
2273 binder::Status res = Status::ok();
Ruben Brunk36597b22015-03-20 22:15:57 -07002274 if (mDisconnected) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08002275 return res;
Ruben Brunk36597b22015-03-20 22:15:57 -07002276 }
Eino-Ville Talvala24901c82015-09-04 14:15:58 -07002277 mDisconnected = true;
Ruben Brunkcc776712015-02-17 20:18:47 -08002278
2279 mCameraService->removeByClient(this);
2280 mCameraService->logDisconnected(String8::format("%d", mCameraId), mClientPid,
Svetoslav Ganov280405a2015-05-12 02:19:27 +00002281 String8(mClientPackageName));
Ruben Brunkcc776712015-02-17 20:18:47 -08002282
2283 sp<IBinder> remote = getRemote();
2284 if (remote != nullptr) {
2285 remote->unlinkToDeath(mCameraService);
2286 }
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07002287
2288 finishCameraOps();
Chien-Yu Chene4fe21b2016-08-04 12:42:40 -07002289 // Notify flashlight that a camera device is closed.
2290 mCameraService->mFlashlight->deviceClosed(String8::format("%d", mCameraId));
Ruben Brunkcc776712015-02-17 20:18:47 -08002291 ALOGI("%s: Disconnected client for camera %d for PID %d", __FUNCTION__, mCameraId, mClientPid);
2292
Igor Murashkincba2c162013-03-20 15:56:31 -07002293 // client shouldn't be able to call into us anymore
2294 mClientPid = 0;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08002295
2296 return res;
Igor Murashkin634a5152013-02-20 17:15:11 -08002297}
2298
Eino-Ville Talvalac4003962016-01-13 10:07:04 -08002299status_t CameraService::BasicClient::dump(int, const Vector<String16>&) {
2300 // No dumping of clients directly over Binder,
2301 // must go through CameraService::dump
2302 android_errorWriteWithInfoLog(SN_EVENT_LOG_ID, "26265403",
2303 IPCThreadState::self()->getCallingUid(), NULL, 0);
2304 return OK;
2305}
2306
Ruben Brunkcc776712015-02-17 20:18:47 -08002307String16 CameraService::BasicClient::getPackageName() const {
Svetoslav Ganov280405a2015-05-12 02:19:27 +00002308 return mClientPackageName;
Ruben Brunkcc776712015-02-17 20:18:47 -08002309}
2310
2311
2312int CameraService::BasicClient::getClientPid() const {
2313 return mClientPid;
2314}
2315
Ruben Brunk6267b532015-04-30 17:44:07 -07002316uid_t CameraService::BasicClient::getClientUid() const {
2317 return mClientUid;
2318}
2319
Ruben Brunk0bbf8b22015-04-30 14:35:42 -07002320bool CameraService::BasicClient::canCastToApiClient(apiLevel level) const {
2321 // Defaults to API2.
2322 return level == API_2;
2323}
2324
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002325status_t CameraService::BasicClient::startCameraOps() {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -07002326 ATRACE_CALL();
2327
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002328 int32_t res;
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07002329 // Notify app ops that the camera is not available
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002330 mOpsCallback = new OpsCallback(this);
2331
Igor Murashkine6800ce2013-03-04 17:25:57 -08002332 {
2333 ALOGV("%s: Start camera ops, package name = %s, client UID = %d",
Svetoslav Ganov280405a2015-05-12 02:19:27 +00002334 __FUNCTION__, String8(mClientPackageName).string(), mClientUid);
Igor Murashkine6800ce2013-03-04 17:25:57 -08002335 }
2336
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002337 mAppOpsManager.startWatchingMode(AppOpsManager::OP_CAMERA,
Svetoslav Ganov280405a2015-05-12 02:19:27 +00002338 mClientPackageName, mOpsCallback);
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002339 res = mAppOpsManager.startOp(AppOpsManager::OP_CAMERA,
Svetoslav Ganov280405a2015-05-12 02:19:27 +00002340 mClientUid, mClientPackageName);
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002341
Svetoslav28e8ef72015-05-11 19:21:31 -07002342 if (res == AppOpsManager::MODE_ERRORED) {
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002343 ALOGI("Camera %d: Access for \"%s\" has been revoked",
Svetoslav Ganov280405a2015-05-12 02:19:27 +00002344 mCameraId, String8(mClientPackageName).string());
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002345 return PERMISSION_DENIED;
2346 }
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07002347
Svetoslav28e8ef72015-05-11 19:21:31 -07002348 if (res == AppOpsManager::MODE_IGNORED) {
2349 ALOGI("Camera %d: Access for \"%s\" has been restricted",
2350 mCameraId, String8(mClientPackageName).string());
Eino-Ville Talvalae3afb2c2015-06-03 16:03:30 -07002351 // Return the same error as for device policy manager rejection
2352 return -EACCES;
Svetoslav28e8ef72015-05-11 19:21:31 -07002353 }
2354
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002355 mOpsActive = true;
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07002356
2357 // Transition device availability listeners from PRESENT -> NOT_AVAILABLE
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08002358 mCameraService->updateStatus(StatusInternal::NOT_AVAILABLE,
Ruben Brunkcc776712015-02-17 20:18:47 -08002359 String8::format("%d", mCameraId));
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07002360
Eino-Ville Talvala412fe562015-08-20 17:08:32 -07002361 // Transition device state to OPEN
2362 mCameraService->updateProxyDeviceState(ICameraServiceProxy::CAMERA_STATE_OPEN,
2363 String8::format("%d", mCameraId));
2364
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002365 return OK;
2366}
2367
2368status_t CameraService::BasicClient::finishCameraOps() {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -07002369 ATRACE_CALL();
2370
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07002371 // Check if startCameraOps succeeded, and if so, finish the camera op
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002372 if (mOpsActive) {
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07002373 // Notify app ops that the camera is available again
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002374 mAppOpsManager.finishOp(AppOpsManager::OP_CAMERA, mClientUid,
Svetoslav Ganov280405a2015-05-12 02:19:27 +00002375 mClientPackageName);
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002376 mOpsActive = false;
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07002377
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08002378 std::initializer_list<StatusInternal> rejected = {StatusInternal::PRESENT,
2379 StatusInternal::ENUMERATING};
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07002380
Ruben Brunkcc776712015-02-17 20:18:47 -08002381 // Transition to PRESENT if the camera is not in either of the rejected states
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08002382 mCameraService->updateStatus(StatusInternal::PRESENT,
Ruben Brunkcc776712015-02-17 20:18:47 -08002383 String8::format("%d", mCameraId), rejected);
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07002384
Eino-Ville Talvala412fe562015-08-20 17:08:32 -07002385 // Transition device state to CLOSED
2386 mCameraService->updateProxyDeviceState(ICameraServiceProxy::CAMERA_STATE_CLOSED,
2387 String8::format("%d", mCameraId));
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002388 }
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07002389 // Always stop watching, even if no camera op is active
Eino-Ville Talvalae992e752014-11-07 16:17:48 -08002390 if (mOpsCallback != NULL) {
2391 mAppOpsManager.stopWatchingMode(mOpsCallback);
2392 }
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002393 mOpsCallback.clear();
2394
2395 return OK;
2396}
2397
2398void CameraService::BasicClient::opChanged(int32_t op, const String16& packageName) {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -07002399 ATRACE_CALL();
2400
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002401 String8 name(packageName);
Svetoslav Ganov280405a2015-05-12 02:19:27 +00002402 String8 myName(mClientPackageName);
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002403
2404 if (op != AppOpsManager::OP_CAMERA) {
2405 ALOGW("Unexpected app ops notification received: %d", op);
2406 return;
2407 }
2408
2409 int32_t res;
2410 res = mAppOpsManager.checkOp(AppOpsManager::OP_CAMERA,
Svetoslav Ganov280405a2015-05-12 02:19:27 +00002411 mClientUid, mClientPackageName);
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002412 ALOGV("checkOp returns: %d, %s ", res,
2413 res == AppOpsManager::MODE_ALLOWED ? "ALLOWED" :
2414 res == AppOpsManager::MODE_IGNORED ? "IGNORED" :
2415 res == AppOpsManager::MODE_ERRORED ? "ERRORED" :
2416 "UNKNOWN");
2417
2418 if (res != AppOpsManager::MODE_ALLOWED) {
2419 ALOGI("Camera %d: Access for \"%s\" revoked", mCameraId,
2420 myName.string());
2421 // Reset the client PID to allow server-initiated disconnect,
2422 // and to prevent further calls by client.
2423 mClientPid = getCallingPid();
Jianing Weicb0652e2014-03-12 18:29:36 -07002424 CaptureResultExtras resultExtras; // a dummy result (invalid)
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08002425 notifyError(hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_SERVICE, resultExtras);
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002426 disconnect();
2427 }
2428}
2429
Mathias Agopian65ab4712010-07-14 17:59:35 -07002430// ----------------------------------------------------------------------------
2431
Ruben Brunkcc776712015-02-17 20:18:47 -08002432// Provide client strong pointer for callbacks.
2433sp<CameraService::Client> CameraService::Client::getClientFromCookie(void* user) {
2434 String8 cameraId = String8::format("%d", (int)(intptr_t) user);
2435 auto clientDescriptor = gCameraService->mActiveClientManager.get(cameraId);
2436 if (clientDescriptor != nullptr) {
2437 return sp<Client>{
2438 static_cast<Client*>(clientDescriptor->getValue().get())};
2439 }
2440 return sp<Client>{nullptr};
Mathias Agopian65ab4712010-07-14 17:59:35 -07002441}
2442
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08002443void CameraService::Client::notifyError(int32_t errorCode,
Jianing Weicb0652e2014-03-12 18:29:36 -07002444 const CaptureResultExtras& resultExtras) {
Eino-Ville Talvalad309fb92015-11-25 12:12:45 -08002445 (void) errorCode;
2446 (void) resultExtras;
Ranjith Kagathi Ananda3e600892015-10-08 16:00:33 -07002447 if (mRemoteCallback != NULL) {
2448 mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_RELEASED, 0);
2449 } else {
2450 ALOGE("mRemoteCallback is NULL!!");
2451 }
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002452}
2453
Igor Murashkin036bc3e2012-10-08 15:09:46 -07002454// NOTE: function is idempotent
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08002455binder::Status CameraService::Client::disconnect() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -07002456 ALOGV("Client::disconnect");
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08002457 return BasicClient::disconnect();
Wu-cheng Lie09591e2010-10-14 20:17:44 +08002458}
2459
Ruben Brunk0bbf8b22015-04-30 14:35:42 -07002460bool CameraService::Client::canCastToApiClient(apiLevel level) const {
2461 return level == API_1;
2462}
2463
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002464CameraService::Client::OpsCallback::OpsCallback(wp<BasicClient> client):
2465 mClient(client) {
2466}
2467
2468void CameraService::Client::OpsCallback::opChanged(int32_t op,
2469 const String16& packageName) {
2470 sp<BasicClient> client = mClient.promote();
2471 if (client != NULL) {
2472 client->opChanged(op, packageName);
2473 }
2474}
2475
Mathias Agopian65ab4712010-07-14 17:59:35 -07002476// ----------------------------------------------------------------------------
Ruben Brunkcc776712015-02-17 20:18:47 -08002477// CameraState
2478// ----------------------------------------------------------------------------
2479
2480CameraService::CameraState::CameraState(const String8& id, int cost,
2481 const std::set<String8>& conflicting) : mId(id),
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08002482 mStatus(StatusInternal::PRESENT), mCost(cost), mConflicting(conflicting) {}
Ruben Brunkcc776712015-02-17 20:18:47 -08002483
2484CameraService::CameraState::~CameraState() {}
2485
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08002486CameraService::StatusInternal CameraService::CameraState::getStatus() const {
Ruben Brunkcc776712015-02-17 20:18:47 -08002487 Mutex::Autolock lock(mStatusLock);
2488 return mStatus;
2489}
2490
2491CameraParameters CameraService::CameraState::getShimParams() const {
2492 return mShimParams;
2493}
2494
2495void CameraService::CameraState::setShimParams(const CameraParameters& params) {
2496 mShimParams = params;
2497}
2498
2499int CameraService::CameraState::getCost() const {
2500 return mCost;
2501}
2502
2503std::set<String8> CameraService::CameraState::getConflicting() const {
2504 return mConflicting;
2505}
2506
2507String8 CameraService::CameraState::getId() const {
2508 return mId;
2509}
2510
2511// ----------------------------------------------------------------------------
Ruben Brunk99e69712015-05-26 17:25:07 -07002512// ClientEventListener
2513// ----------------------------------------------------------------------------
2514
2515void CameraService::ClientEventListener::onClientAdded(
2516 const resource_policy::ClientDescriptor<String8,
2517 sp<CameraService::BasicClient>>& descriptor) {
Chih-Hung Hsieh5404ee12016-08-09 14:25:53 -07002518 const auto& basicClient = descriptor.getValue();
Ruben Brunk99e69712015-05-26 17:25:07 -07002519 if (basicClient.get() != nullptr) {
2520 BatteryNotifier& notifier(BatteryNotifier::getInstance());
2521 notifier.noteStartCamera(descriptor.getKey(),
2522 static_cast<int>(basicClient->getClientUid()));
2523 }
2524}
2525
2526void CameraService::ClientEventListener::onClientRemoved(
2527 const resource_policy::ClientDescriptor<String8,
2528 sp<CameraService::BasicClient>>& descriptor) {
Chih-Hung Hsieh5404ee12016-08-09 14:25:53 -07002529 const auto& basicClient = descriptor.getValue();
Ruben Brunk99e69712015-05-26 17:25:07 -07002530 if (basicClient.get() != nullptr) {
2531 BatteryNotifier& notifier(BatteryNotifier::getInstance());
2532 notifier.noteStopCamera(descriptor.getKey(),
2533 static_cast<int>(basicClient->getClientUid()));
2534 }
2535}
2536
2537
2538// ----------------------------------------------------------------------------
Ruben Brunkcc776712015-02-17 20:18:47 -08002539// CameraClientManager
2540// ----------------------------------------------------------------------------
2541
Ruben Brunk99e69712015-05-26 17:25:07 -07002542CameraService::CameraClientManager::CameraClientManager() {
2543 setListener(std::make_shared<ClientEventListener>());
2544}
2545
Ruben Brunkcc776712015-02-17 20:18:47 -08002546CameraService::CameraClientManager::~CameraClientManager() {}
2547
2548sp<CameraService::BasicClient> CameraService::CameraClientManager::getCameraClient(
2549 const String8& id) const {
2550 auto descriptor = get(id);
2551 if (descriptor == nullptr) {
2552 return sp<BasicClient>{nullptr};
2553 }
2554 return descriptor->getValue();
2555}
2556
2557String8 CameraService::CameraClientManager::toString() const {
2558 auto all = getAll();
2559 String8 ret("[");
2560 bool hasAny = false;
2561 for (auto& i : all) {
2562 hasAny = true;
2563 String8 key = i->getKey();
2564 int32_t cost = i->getCost();
2565 int32_t pid = i->getOwnerId();
2566 int32_t priority = i->getPriority();
2567 auto conflicting = i->getConflicting();
2568 auto clientSp = i->getValue();
2569 String8 packageName;
Eino-Ville Talvala022f0cb2015-05-19 16:31:16 -07002570 userid_t clientUserId = 0;
Ruben Brunkcc776712015-02-17 20:18:47 -08002571 if (clientSp.get() != nullptr) {
2572 packageName = String8{clientSp->getPackageName()};
Ruben Brunk6267b532015-04-30 17:44:07 -07002573 uid_t clientUid = clientSp->getClientUid();
2574 clientUserId = multiuser_get_user_id(clientUid);
Ruben Brunkcc776712015-02-17 20:18:47 -08002575 }
2576 ret.appendFormat("\n(Camera ID: %s, Cost: %" PRId32 ", PID: %" PRId32 ", Priority: %"
2577 PRId32 ", ", key.string(), cost, pid, priority);
2578
Ruben Brunk6267b532015-04-30 17:44:07 -07002579 if (clientSp.get() != nullptr) {
2580 ret.appendFormat("User Id: %d, ", clientUserId);
2581 }
Ruben Brunkcc776712015-02-17 20:18:47 -08002582 if (packageName.size() != 0) {
2583 ret.appendFormat("Client Package Name: %s", packageName.string());
2584 }
2585
2586 ret.append(", Conflicting Client Devices: {");
2587 for (auto& j : conflicting) {
2588 ret.appendFormat("%s, ", j.string());
2589 }
2590 ret.append("})");
2591 }
2592 if (hasAny) ret.append("\n");
2593 ret.append("]\n");
2594 return ret;
2595}
2596
2597CameraService::DescriptorPtr CameraService::CameraClientManager::makeClientDescriptor(
2598 const String8& key, const sp<BasicClient>& value, int32_t cost,
2599 const std::set<String8>& conflictingKeys, int32_t priority, int32_t ownerId) {
2600
2601 return std::make_shared<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>(
2602 key, value, cost, conflictingKeys, priority, ownerId);
2603}
2604
2605CameraService::DescriptorPtr CameraService::CameraClientManager::makeClientDescriptor(
2606 const sp<BasicClient>& value, const CameraService::DescriptorPtr& partial) {
2607 return makeClientDescriptor(partial->getKey(), value, partial->getCost(),
2608 partial->getConflicting(), partial->getPriority(), partial->getOwnerId());
2609}
2610
2611// ----------------------------------------------------------------------------
Mathias Agopian65ab4712010-07-14 17:59:35 -07002612
2613static const int kDumpLockRetries = 50;
2614static const int kDumpLockSleep = 60000;
2615
2616static bool tryLock(Mutex& mutex)
2617{
2618 bool locked = false;
2619 for (int i = 0; i < kDumpLockRetries; ++i) {
2620 if (mutex.tryLock() == NO_ERROR) {
2621 locked = true;
2622 break;
2623 }
2624 usleep(kDumpLockSleep);
2625 }
2626 return locked;
2627}
2628
2629status_t CameraService::dump(int fd, const Vector<String16>& args) {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -07002630 ATRACE_CALL();
2631
Ruben Brunka8ca9152015-04-07 14:23:40 -07002632 String8 result("Dump of the Camera Service:\n");
Mathias Agopian65ab4712010-07-14 17:59:35 -07002633 if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
dcashmanfefa6142015-09-09 13:43:01 -07002634 result = result.format("Permission Denial: "
Mathias Agopian65ab4712010-07-14 17:59:35 -07002635 "can't dump CameraService from pid=%d, uid=%d\n",
2636 getCallingPid(),
2637 getCallingUid());
Mathias Agopian65ab4712010-07-14 17:59:35 -07002638 write(fd, result.string(), result.size());
2639 } else {
2640 bool locked = tryLock(mServiceLock);
2641 // failed to lock - CameraService is probably deadlocked
2642 if (!locked) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -07002643 result.append("CameraService may be deadlocked\n");
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07002644 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07002645 }
2646
2647 bool hasClient = false;
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07002648 if (!mModule) {
2649 result = String8::format("No camera module available!\n");
2650 write(fd, result.string(), result.size());
Eino-Ville Talvala1527f072015-04-07 15:55:31 -07002651
2652 // Dump event log for error information
2653 dumpEventLog(fd);
2654
Kalle Lampila6ec3a152013-04-30 15:27:19 +03002655 if (locked) mServiceLock.unlock();
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07002656 return NO_ERROR;
2657 }
2658
Chien-Yu Chen676b21b2015-02-24 10:28:19 -08002659 result = String8::format("Camera module HAL API version: 0x%x\n", mModule->getHalApiVersion());
2660 result.appendFormat("Camera module API version: 0x%x\n", mModule->getModuleApiVersion());
2661 result.appendFormat("Camera module name: %s\n", mModule->getModuleName());
2662 result.appendFormat("Camera module author: %s\n", mModule->getModuleAuthor());
Ruben Brunkcc776712015-02-17 20:18:47 -08002663 result.appendFormat("Number of camera devices: %d\n", mNumberOfCameras);
Eino-Ville Talvala49c97052016-01-12 14:29:40 -08002664 result.appendFormat("Number of normal camera devices: %d\n", mNumberOfNormalCameras);
Ruben Brunkcc776712015-02-17 20:18:47 -08002665 String8 activeClientString = mActiveClientManager.toString();
2666 result.appendFormat("Active Camera Clients:\n%s", activeClientString.string());
Ruben Brunk6267b532015-04-30 17:44:07 -07002667 result.appendFormat("Allowed users:\n%s\n", toString(mAllowedUsers).string());
Ruben Brunkcc776712015-02-17 20:18:47 -08002668
Ruben Brunkf81648e2014-04-17 16:14:57 -07002669 sp<VendorTagDescriptor> desc = VendorTagDescriptor::getGlobalVendorTagDescriptor();
2670 if (desc == NULL) {
2671 result.appendFormat("Vendor tags left unimplemented.\n");
2672 } else {
2673 result.appendFormat("Vendor tag definitions:\n");
2674 }
2675
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07002676 write(fd, result.string(), result.size());
Ruben Brunkf81648e2014-04-17 16:14:57 -07002677
2678 if (desc != NULL) {
2679 desc->dump(fd, /*verbosity*/2, /*indentation*/4);
2680 }
2681
Eino-Ville Talvala1527f072015-04-07 15:55:31 -07002682 dumpEventLog(fd);
Ruben Brunkcc776712015-02-17 20:18:47 -08002683
2684 bool stateLocked = tryLock(mCameraStatesLock);
2685 if (!stateLocked) {
2686 result = String8::format("CameraStates in use, may be deadlocked\n");
2687 write(fd, result.string(), result.size());
2688 }
2689
2690 for (auto& state : mCameraStates) {
2691 String8 cameraId = state.first;
2692 result = String8::format("Camera %s information:\n", cameraId.string());
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07002693 camera_info info;
2694
Ruben Brunkcc776712015-02-17 20:18:47 -08002695 // TODO: Change getCameraInfo + HAL to use String cameraIds
2696 status_t rc = mModule->getCameraInfo(cameraIdToInt(cameraId), &info);
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07002697 if (rc != OK) {
2698 result.appendFormat(" Error reading static information!\n");
2699 write(fd, result.string(), result.size());
2700 } else {
2701 result.appendFormat(" Facing: %s\n",
Yin-Chia Yeh13cd59a2016-11-29 12:13:15 -08002702 info.facing == CAMERA_FACING_BACK ? "BACK" :
2703 info.facing == CAMERA_FACING_FRONT ? "FRONT" : "EXTERNAL");
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07002704 result.appendFormat(" Orientation: %d\n", info.orientation);
2705 int deviceVersion;
Chien-Yu Chen676b21b2015-02-24 10:28:19 -08002706 if (mModule->getModuleApiVersion() < CAMERA_MODULE_API_VERSION_2_0) {
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07002707 deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
2708 } else {
2709 deviceVersion = info.device_version;
2710 }
Ruben Brunkcc776712015-02-17 20:18:47 -08002711
2712 auto conflicting = state.second->getConflicting();
2713 result.appendFormat(" Resource Cost: %d\n", state.second->getCost());
2714 result.appendFormat(" Conflicting Devices:");
2715 for (auto& id : conflicting) {
Eino-Ville Talvalad309fb92015-11-25 12:12:45 -08002716 result.appendFormat(" %s", id.string());
Ruben Brunkcc776712015-02-17 20:18:47 -08002717 }
2718 if (conflicting.size() == 0) {
2719 result.appendFormat(" NONE");
2720 }
2721 result.appendFormat("\n");
2722
2723 result.appendFormat(" Device version: %#x\n", deviceVersion);
Eino-Ville Talvalad309fb92015-11-25 12:12:45 -08002724 if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_0) {
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07002725 result.appendFormat(" Device static metadata:\n");
2726 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -07002727 dump_indented_camera_metadata(info.static_camera_characteristics,
Ruben Brunkf81648e2014-04-17 16:14:57 -07002728 fd, /*verbosity*/2, /*indentation*/4);
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07002729 } else {
2730 write(fd, result.string(), result.size());
2731 }
Ruben Brunkcc776712015-02-17 20:18:47 -08002732
2733 CameraParameters p = state.second->getShimParams();
2734 if (!p.isEmpty()) {
2735 result = String8::format(" Camera1 API shim is using parameters:\n ");
2736 write(fd, result.string(), result.size());
2737 p.dump(fd, args);
2738 }
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07002739 }
2740
Ruben Brunkcc776712015-02-17 20:18:47 -08002741 auto clientDescriptor = mActiveClientManager.get(cameraId);
2742 if (clientDescriptor == nullptr) {
2743 result = String8::format(" Device %s is closed, no client instance\n",
2744 cameraId.string());
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07002745 write(fd, result.string(), result.size());
2746 continue;
2747 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07002748 hasClient = true;
Ruben Brunkcc776712015-02-17 20:18:47 -08002749 result = String8::format(" Device %s is open. Client instance dump:\n\n",
2750 cameraId.string());
2751 result.appendFormat("Client priority level: %d\n", clientDescriptor->getPriority());
2752 result.appendFormat("Client PID: %d\n", clientDescriptor->getOwnerId());
2753
2754 auto client = clientDescriptor->getValue();
2755 result.appendFormat("Client package: %s\n",
2756 String8(client->getPackageName()).string());
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07002757 write(fd, result.string(), result.size());
Ruben Brunkcc776712015-02-17 20:18:47 -08002758
Eino-Ville Talvalac4003962016-01-13 10:07:04 -08002759 client->dumpClient(fd, args);
Mathias Agopian65ab4712010-07-14 17:59:35 -07002760 }
Ruben Brunkcc776712015-02-17 20:18:47 -08002761
2762 if (stateLocked) mCameraStatesLock.unlock();
2763
Mathias Agopian65ab4712010-07-14 17:59:35 -07002764 if (!hasClient) {
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07002765 result = String8::format("\nNo active camera clients yet.\n");
2766 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07002767 }
2768
2769 if (locked) mServiceLock.unlock();
2770
Igor Murashkinff3e31d2013-10-23 16:40:06 -07002771 // Dump camera traces if there were any
2772 write(fd, "\n", 1);
2773 camera3::CameraTraces::dump(fd, args);
2774
Eino-Ville Talvalad89821e2016-04-20 11:23:50 -07002775 // Process dump arguments, if any
Mathias Agopian65ab4712010-07-14 17:59:35 -07002776 int n = args.size();
Eino-Ville Talvalad89821e2016-04-20 11:23:50 -07002777 String16 verboseOption("-v");
2778 String16 unreachableOption("--unreachable");
2779 for (int i = 0; i < n; i++) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -07002780 if (args[i] == verboseOption) {
Eino-Ville Talvalad89821e2016-04-20 11:23:50 -07002781 // change logging level
2782 if (i + 1 >= n) continue;
Mathias Agopian65ab4712010-07-14 17:59:35 -07002783 String8 levelStr(args[i+1]);
2784 int level = atoi(levelStr.string());
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07002785 result = String8::format("\nSetting log level to %d.\n", level);
Mathias Agopian65ab4712010-07-14 17:59:35 -07002786 setLogLevel(level);
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07002787 write(fd, result.string(), result.size());
Eino-Ville Talvalad89821e2016-04-20 11:23:50 -07002788 } else if (args[i] == unreachableOption) {
2789 // Dump memory analysis
2790 // TODO - should limit be an argument parameter?
2791 UnreachableMemoryInfo info;
2792 bool success = GetUnreachableMemory(info, /*limit*/ 10000);
2793 if (!success) {
2794 dprintf(fd, "\nUnable to dump unreachable memory. "
2795 "Try disabling SELinux enforcement.\n");
2796 } else {
2797 dprintf(fd, "\nDumping unreachable memory:\n");
2798 std::string s = info.ToString(/*log_contents*/ true);
2799 write(fd, s.c_str(), s.size());
2800 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07002801 }
2802 }
2803 }
2804 return NO_ERROR;
2805}
2806
Eino-Ville Talvala1527f072015-04-07 15:55:31 -07002807void CameraService::dumpEventLog(int fd) {
2808 String8 result = String8("\nPrior client events (most recent at top):\n");
2809
2810 Mutex::Autolock l(mLogLock);
2811 for (const auto& msg : mEventLog) {
2812 result.appendFormat(" %s\n", msg.string());
2813 }
2814
2815 if (mEventLog.size() == DEFAULT_EVENT_LOG_LENGTH) {
2816 result.append(" ...\n");
2817 } else if (mEventLog.size() == 0) {
2818 result.append(" [no events yet]\n");
2819 }
2820 result.append("\n");
2821
2822 write(fd, result.string(), result.size());
2823}
2824
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002825void CameraService::handleTorchClientBinderDied(const wp<IBinder> &who) {
Chien-Yu Chen88da5262015-02-17 13:56:46 -08002826 Mutex::Autolock al(mTorchClientMapMutex);
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002827 for (size_t i = 0; i < mTorchClientMap.size(); i++) {
2828 if (mTorchClientMap[i] == who) {
2829 // turn off the torch mode that was turned on by dead client
Chien-Yu Chen88da5262015-02-17 13:56:46 -08002830 String8 cameraId = mTorchClientMap.keyAt(i);
2831 status_t res = mFlashlight->setTorchMode(cameraId, false);
2832 if (res) {
2833 ALOGE("%s: torch client died but couldn't turn off torch: "
2834 "%s (%d)", __FUNCTION__, strerror(-res), res);
2835 return;
2836 }
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002837 mTorchClientMap.removeItemsAt(i);
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002838 break;
2839 }
2840 }
2841}
2842
Ruben Brunkcc776712015-02-17 20:18:47 -08002843/*virtual*/void CameraService::binderDied(const wp<IBinder> &who) {
Igor Murashkinecf17e82012-10-02 16:05:11 -07002844
Igor Murashkin294d0ec2012-10-05 10:44:57 -07002845 /**
Ruben Brunka8ca9152015-04-07 14:23:40 -07002846 * While tempting to promote the wp<IBinder> into a sp, it's actually not supported by the
2847 * binder driver
Igor Murashkin294d0ec2012-10-05 10:44:57 -07002848 */
2849
Ruben Brunka8ca9152015-04-07 14:23:40 -07002850 logClientDied(getCallingPid(), String8("Binder died unexpectedly"));
2851
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002852 // check torch client
2853 handleTorchClientBinderDied(who);
2854
2855 // check camera device client
Ruben Brunkcc776712015-02-17 20:18:47 -08002856 if(!evictClientIdByRemote(who)) {
2857 ALOGV("%s: Java client's binder death already cleaned up (normal case)", __FUNCTION__);
Igor Murashkinecf17e82012-10-02 16:05:11 -07002858 return;
2859 }
2860
Ruben Brunkcc776712015-02-17 20:18:47 -08002861 ALOGE("%s: Java client's binder died, removing it from the list of active clients",
2862 __FUNCTION__);
Igor Murashkinecf17e82012-10-02 16:05:11 -07002863}
2864
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08002865void CameraService::updateStatus(StatusInternal status, const String8& cameraId) {
Ruben Brunkcc776712015-02-17 20:18:47 -08002866 updateStatus(status, cameraId, {});
Igor Murashkinbfc99152013-02-27 12:55:20 -08002867}
2868
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08002869void CameraService::updateStatus(StatusInternal status, const String8& cameraId,
2870 std::initializer_list<StatusInternal> rejectSourceStates) {
Ruben Brunkcc776712015-02-17 20:18:47 -08002871 // Do not lock mServiceLock here or can get into a deadlock from
2872 // connect() -> disconnect -> updateStatus
2873
2874 auto state = getCameraState(cameraId);
2875
2876 if (state == nullptr) {
2877 ALOGW("%s: Could not update the status for %s, no such device exists", __FUNCTION__,
2878 cameraId.string());
2879 return;
Igor Murashkincba2c162013-03-20 15:56:31 -07002880 }
2881
Ruben Brunkcc776712015-02-17 20:18:47 -08002882 // Update the status for this camera state, then send the onStatusChangedCallbacks to each
2883 // of the listeners with both the mStatusStatus and mStatusListenerLock held
2884 state->updateStatus(status, cameraId, rejectSourceStates, [this]
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08002885 (const String8& cameraId, StatusInternal status) {
Ruben Brunkcc776712015-02-17 20:18:47 -08002886
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08002887 if (status != StatusInternal::ENUMERATING) {
Chien-Yu Chenf6463fc2015-04-07 15:11:31 -07002888 // Update torch status if it has a flash unit.
2889 Mutex::Autolock al(mTorchStatusMutex);
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08002890 TorchModeStatus torchStatus;
Chien-Yu Chenf6463fc2015-04-07 15:11:31 -07002891 if (getTorchStatusLocked(cameraId, &torchStatus) !=
2892 NAME_NOT_FOUND) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08002893 TorchModeStatus newTorchStatus =
2894 status == StatusInternal::PRESENT ?
2895 TorchModeStatus::AVAILABLE_OFF :
2896 TorchModeStatus::NOT_AVAILABLE;
Chien-Yu Chenf6463fc2015-04-07 15:11:31 -07002897 if (torchStatus != newTorchStatus) {
2898 onTorchStatusChangedLocked(cameraId, newTorchStatus);
2899 }
2900 }
Ruben Brunkcc776712015-02-17 20:18:47 -08002901 }
2902
2903 Mutex::Autolock lock(mStatusListenerLock);
2904
2905 for (auto& listener : mListenerList) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08002906 listener->onStatusChanged(mapToInterface(status), String16(cameraId));
Ruben Brunkcc776712015-02-17 20:18:47 -08002907 }
2908 });
Igor Murashkincba2c162013-03-20 15:56:31 -07002909}
2910
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08002911template<class Func>
2912void CameraService::CameraState::updateStatus(StatusInternal status,
2913 const String8& cameraId,
2914 std::initializer_list<StatusInternal> rejectSourceStates,
2915 Func onStatusUpdatedLocked) {
2916 Mutex::Autolock lock(mStatusLock);
2917 StatusInternal oldStatus = mStatus;
2918 mStatus = status;
2919
2920 if (oldStatus == status) {
2921 return;
2922 }
2923
2924 ALOGV("%s: Status has changed for camera ID %s from %#x to %#x", __FUNCTION__,
2925 cameraId.string(), oldStatus, status);
2926
2927 if (oldStatus == StatusInternal::NOT_PRESENT &&
2928 (status != StatusInternal::PRESENT &&
2929 status != StatusInternal::ENUMERATING)) {
2930
2931 ALOGW("%s: From NOT_PRESENT can only transition into PRESENT or ENUMERATING",
2932 __FUNCTION__);
2933 mStatus = oldStatus;
2934 return;
2935 }
2936
2937 /**
2938 * Sometimes we want to conditionally do a transition.
2939 * For example if a client disconnects, we want to go to PRESENT
2940 * only if we weren't already in NOT_PRESENT or ENUMERATING.
2941 */
2942 for (auto& rejectStatus : rejectSourceStates) {
2943 if (oldStatus == rejectStatus) {
2944 ALOGV("%s: Rejecting status transition for Camera ID %s, since the source "
2945 "state was was in one of the bad states.", __FUNCTION__, cameraId.string());
2946 mStatus = oldStatus;
2947 return;
2948 }
2949 }
2950
2951 onStatusUpdatedLocked(cameraId, status);
2952}
2953
Eino-Ville Talvala412fe562015-08-20 17:08:32 -07002954void CameraService::updateProxyDeviceState(ICameraServiceProxy::CameraState newState,
2955 const String8& cameraId) {
2956 sp<ICameraServiceProxy> proxyBinder = getCameraServiceProxy();
2957 if (proxyBinder == nullptr) return;
2958 String16 id(cameraId);
2959 proxyBinder->notifyCameraState(id, newState);
2960}
2961
Chien-Yu Chen88da5262015-02-17 13:56:46 -08002962status_t CameraService::getTorchStatusLocked(
2963 const String8& cameraId,
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08002964 TorchModeStatus *status) const {
Chien-Yu Chen88da5262015-02-17 13:56:46 -08002965 if (!status) {
2966 return BAD_VALUE;
2967 }
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002968 ssize_t index = mTorchStatusMap.indexOfKey(cameraId);
2969 if (index == NAME_NOT_FOUND) {
Chien-Yu Chen88da5262015-02-17 13:56:46 -08002970 // invalid camera ID or the camera doesn't have a flash unit
2971 return NAME_NOT_FOUND;
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002972 }
2973
Chien-Yu Chen88da5262015-02-17 13:56:46 -08002974 *status = mTorchStatusMap.valueAt(index);
2975 return OK;
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002976}
2977
Chien-Yu Chen88da5262015-02-17 13:56:46 -08002978status_t CameraService::setTorchStatusLocked(const String8& cameraId,
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08002979 TorchModeStatus status) {
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002980 ssize_t index = mTorchStatusMap.indexOfKey(cameraId);
2981 if (index == NAME_NOT_FOUND) {
2982 return BAD_VALUE;
2983 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08002984 mTorchStatusMap.editValueAt(index) = status;
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002985
2986 return OK;
2987}
2988
Mathias Agopian65ab4712010-07-14 17:59:35 -07002989}; // namespace android