blob: d65ac21bea943a3af3191a64a3b6ac673ef62757 [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"
Iliyan Malchev8951a972011-04-14 16:55:59 -070018//#define LOG_NDEBUG 0
Mathias Agopian65ab4712010-07-14 17:59:35 -070019
20#include <stdio.h>
Ruben Brunkd1176ef2014-02-21 10:51:38 -080021#include <string.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070022#include <sys/types.h>
23#include <pthread.h>
24
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -080025#include <binder/AppOpsManager.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070026#include <binder/IPCThreadState.h>
27#include <binder/IServiceManager.h>
28#include <binder/MemoryBase.h>
29#include <binder/MemoryHeapBase.h>
30#include <cutils/atomic.h>
Nipun Kwatrab5ca4612010-09-11 19:31:10 -070031#include <cutils/properties.h>
Amith Yamasani228711d2015-02-13 13:25:39 -080032#include <cutils/multiuser.h>
Mathias Agopiandf712ea2012-02-25 18:48:35 -080033#include <gui/Surface.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070034#include <hardware/hardware.h>
35#include <media/AudioSystem.h>
Andreas Huber1b86fe02014-01-29 11:13:26 -080036#include <media/IMediaHTTPService.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070037#include <media/mediaplayer.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070038#include <utils/Errors.h>
39#include <utils/Log.h>
40#include <utils/String16.h>
Ruben Brunkd1176ef2014-02-21 10:51:38 -080041#include <utils/Trace.h>
42#include <system/camera_vendor_tags.h>
Ruben Brunkb2119af2014-05-09 19:57:56 -070043#include <system/camera_metadata.h>
44#include <system/camera.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070045
46#include "CameraService.h"
Eino-Ville Talvala7b82efe2013-07-25 17:12:35 -070047#include "api1/CameraClient.h"
48#include "api1/Camera2Client.h"
49#include "api_pro/ProCamera2Client.h"
50#include "api2/CameraDeviceClient.h"
Igor Murashkinff3e31d2013-10-23 16:40:06 -070051#include "utils/CameraTraces.h"
Igor Murashkin98e24722013-06-19 19:51:04 -070052#include "CameraDeviceFactory.h"
Mathias Agopian65ab4712010-07-14 17:59:35 -070053
54namespace android {
55
56// ----------------------------------------------------------------------------
57// Logging support -- this is for debugging only
58// Use "adb shell dumpsys media.camera -v 1" to change it.
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -070059volatile int32_t gLogLevel = 0;
Mathias Agopian65ab4712010-07-14 17:59:35 -070060
Steve Blockb8a80522011-12-20 16:23:08 +000061#define LOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__);
62#define LOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__);
Mathias Agopian65ab4712010-07-14 17:59:35 -070063
64static void setLogLevel(int level) {
65 android_atomic_write(level, &gLogLevel);
66}
67
68// ----------------------------------------------------------------------------
69
70static int getCallingPid() {
71 return IPCThreadState::self()->getCallingPid();
72}
73
74static int getCallingUid() {
75 return IPCThreadState::self()->getCallingUid();
76}
77
Igor Murashkincba2c162013-03-20 15:56:31 -070078extern "C" {
79static void camera_device_status_change(
80 const struct camera_module_callbacks* callbacks,
81 int camera_id,
82 int new_status) {
83 sp<CameraService> cs = const_cast<CameraService*>(
84 static_cast<const CameraService*>(callbacks));
85
86 cs->onDeviceStatusChanged(
87 camera_id,
88 new_status);
89}
Chien-Yu Chen3068d732015-02-09 13:29:57 -080090
91static void torch_mode_status_change(
92 const struct camera_module_callbacks* callbacks,
93 const char* camera_id,
94 int new_status) {
95 if (!callbacks || !camera_id) {
96 ALOGE("%s invalid parameters. callbacks %p, camera_id %p", __FUNCTION__,
97 callbacks, camera_id);
98 }
99 sp<CameraService> cs = const_cast<CameraService*>(
100 static_cast<const CameraService*>(callbacks));
101
102 ICameraServiceListener::TorchStatus status;
103 switch (new_status) {
104 case TORCH_MODE_STATUS_AVAILABLE:
105 status = ICameraServiceListener::TORCH_STATUS_AVAILABLE;
106 break;
107 case TORCH_MODE_STATUS_RESOURCE_BUSY:
108 status = ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE;
109 break;
110 case TORCH_MODE_STATUS_OFF:
111 status = ICameraServiceListener::TORCH_STATUS_OFF;
112 break;
113 default:
114 ALOGE("Unknown torch status %d", new_status);
115 return;
116 }
117
118 cs->onTorchStatusChanged(
119 String16(camera_id),
120 status);
121}
Igor Murashkincba2c162013-03-20 15:56:31 -0700122} // extern "C"
123
Mathias Agopian65ab4712010-07-14 17:59:35 -0700124// ----------------------------------------------------------------------------
125
126// This is ugly and only safe if we never re-create the CameraService, but
127// should be ok for now.
128static CameraService *gCameraService;
129
130CameraService::CameraService()
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800131 :mSoundRef(0), mModule(0), mFlashlight(0)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700132{
Steve Blockdf64d152012-01-04 20:05:49 +0000133 ALOGI("CameraService started (pid=%d)", getpid());
Mathias Agopian65ab4712010-07-14 17:59:35 -0700134 gCameraService = this;
Igor Murashkinbfc99152013-02-27 12:55:20 -0800135
136 for (size_t i = 0; i < MAX_CAMERAS; ++i) {
Igor Murashkincba2c162013-03-20 15:56:31 -0700137 mStatusList[i] = ICameraServiceListener::STATUS_PRESENT;
Igor Murashkinbfc99152013-02-27 12:55:20 -0800138 }
Igor Murashkincba2c162013-03-20 15:56:31 -0700139
140 this->camera_device_status_change = android::camera_device_status_change;
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800141 this->torch_mode_status_change = android::torch_mode_status_change;
142
Mathias Agopian65ab4712010-07-14 17:59:35 -0700143}
144
Iliyan Malchev8951a972011-04-14 16:55:59 -0700145void CameraService::onFirstRef()
146{
Igor Murashkin634a5152013-02-20 17:15:11 -0800147 LOG1("CameraService::onFirstRef");
148
Iliyan Malchev8951a972011-04-14 16:55:59 -0700149 BnCameraService::onFirstRef();
150
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800151 camera_module_t *rawModule;
Iliyan Malchev8951a972011-04-14 16:55:59 -0700152 if (hw_get_module(CAMERA_HARDWARE_MODULE_ID,
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800153 (const hw_module_t **)&rawModule) < 0) {
Steve Block29357bc2012-01-06 19:20:56 +0000154 ALOGE("Could not load camera HAL module");
Iliyan Malchev8951a972011-04-14 16:55:59 -0700155 mNumberOfCameras = 0;
156 }
157 else {
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800158 mModule = new CameraModule(rawModule);
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800159 mFlashlight = new CameraFlashlight(*mModule, *this);
160
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800161 const hw_module_t *common = mModule->getRawModule();
162 ALOGI("Loaded \"%s\" camera module", common->name);
163 mNumberOfCameras = mModule->getNumberOfCameras();
Iliyan Malchev8951a972011-04-14 16:55:59 -0700164 if (mNumberOfCameras > MAX_CAMERAS) {
Steve Block29357bc2012-01-06 19:20:56 +0000165 ALOGE("Number of cameras(%d) > MAX_CAMERAS(%d).",
Iliyan Malchev8951a972011-04-14 16:55:59 -0700166 mNumberOfCameras, MAX_CAMERAS);
167 mNumberOfCameras = MAX_CAMERAS;
168 }
169 for (int i = 0; i < mNumberOfCameras; i++) {
170 setCameraFree(i);
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800171
172 String16 cameraName = String16(String8::format("%d", i));
173 if (mFlashlight->hasFlashUnit(cameraName)) {
174 mTorchStatusMap.add(cameraName,
175 ICameraServiceListener::TORCH_STATUS_AVAILABLE);
176 }
Iliyan Malchev8951a972011-04-14 16:55:59 -0700177 }
Igor Murashkincba2c162013-03-20 15:56:31 -0700178
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800179 if (common->module_api_version >= CAMERA_MODULE_API_VERSION_2_1) {
180 mModule->setCallbacks(this);
Igor Murashkincba2c162013-03-20 15:56:31 -0700181 }
Igor Murashkin98e24722013-06-19 19:51:04 -0700182
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800183 VendorTagDescriptor::clearGlobalVendorTagDescriptor();
184
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800185 if (common->module_api_version >= CAMERA_MODULE_API_VERSION_2_2) {
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800186 setUpVendorTags();
187 }
188
Igor Murashkin98e24722013-06-19 19:51:04 -0700189 CameraDeviceFactory::registerService(this);
Iliyan Malchev8951a972011-04-14 16:55:59 -0700190 }
191}
192
Mathias Agopian65ab4712010-07-14 17:59:35 -0700193CameraService::~CameraService() {
194 for (int i = 0; i < mNumberOfCameras; i++) {
195 if (mBusy[i]) {
Steve Block29357bc2012-01-06 19:20:56 +0000196 ALOGE("camera %d is still in use in destructor!", i);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700197 }
198 }
199
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800200 if (mModule) {
201 delete mModule;
202 }
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800203 VendorTagDescriptor::clearGlobalVendorTagDescriptor();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700204 gCameraService = NULL;
205}
206
Igor Murashkincba2c162013-03-20 15:56:31 -0700207void CameraService::onDeviceStatusChanged(int cameraId,
208 int newStatus)
209{
210 ALOGI("%s: Status changed for cameraId=%d, newStatus=%d", __FUNCTION__,
211 cameraId, newStatus);
212
213 if (cameraId < 0 || cameraId >= MAX_CAMERAS) {
214 ALOGE("%s: Bad camera ID %d", __FUNCTION__, cameraId);
215 return;
216 }
217
218 if ((int)getStatus(cameraId) == newStatus) {
219 ALOGE("%s: State transition to the same status 0x%x not allowed",
220 __FUNCTION__, (uint32_t)newStatus);
221 return;
222 }
223
224 /* don't do this in updateStatus
225 since it is also called from connect and we could get into a deadlock */
226 if (newStatus == CAMERA_DEVICE_STATUS_NOT_PRESENT) {
227 Vector<sp<BasicClient> > clientsToDisconnect;
228 {
229 Mutex::Autolock al(mServiceLock);
230
Ruben Brunkb2119af2014-05-09 19:57:56 -0700231 /* Remove cached parameters from shim cache */
232 mShimParams.removeItem(cameraId);
233
Igor Murashkincba2c162013-03-20 15:56:31 -0700234 /* Find all clients that we need to disconnect */
Igor Murashkine7ee7632013-06-11 18:10:18 -0700235 sp<BasicClient> client = mClient[cameraId].promote();
Igor Murashkincba2c162013-03-20 15:56:31 -0700236 if (client.get() != NULL) {
237 clientsToDisconnect.push_back(client);
238 }
239
240 int i = cameraId;
241 for (size_t j = 0; j < mProClientList[i].size(); ++j) {
242 sp<ProClient> cl = mProClientList[i][j].promote();
243 if (cl != NULL) {
244 clientsToDisconnect.push_back(cl);
245 }
246 }
247 }
248
249 /* now disconnect them. don't hold the lock
250 or we can get into a deadlock */
251
252 for (size_t i = 0; i < clientsToDisconnect.size(); ++i) {
253 sp<BasicClient> client = clientsToDisconnect[i];
254
255 client->disconnect();
256 /**
257 * The remote app will no longer be able to call methods on the
258 * client since the client PID will be reset to 0
259 */
260 }
261
Colin Crosse5729fa2014-03-21 15:04:25 -0700262 ALOGV("%s: After unplug, disconnected %zu clients",
Igor Murashkincba2c162013-03-20 15:56:31 -0700263 __FUNCTION__, clientsToDisconnect.size());
264 }
265
266 updateStatus(
267 static_cast<ICameraServiceListener::Status>(newStatus), cameraId);
268
269}
270
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800271void CameraService::onTorchStatusChanged(const String16& cameraId,
272 ICameraServiceListener::TorchStatus newStatus) {
273 Mutex::Autolock al(mTorchStatusMutex);
274 onTorchStatusChangedLocked(cameraId, newStatus);
275}
276
277void CameraService::onTorchStatusChangedLocked(const String16& cameraId,
278 ICameraServiceListener::TorchStatus newStatus) {
279 ALOGI("%s: Torch status changed for cameraId=%s, newStatus=%d",
280 __FUNCTION__, cameraId.string(), newStatus);
281
282 if (getTorchStatusLocked(cameraId) == newStatus) {
283 ALOGE("%s: Torch state transition to the same status 0x%x not allowed",
284 __FUNCTION__, (uint32_t)newStatus);
285 return;
286 }
287
288 status_t res = setTorchStatusLocked(cameraId, newStatus);
289 if (res) {
290 ALOGE("%s: Failed to set the torch status", __FUNCTION__,
291 (uint32_t)newStatus);
292 return;
293 }
294
295 Vector<sp<ICameraServiceListener> >::const_iterator it;
296 for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
297 (*it)->onTorchStatusChanged(newStatus, cameraId);
298 }
299}
300
301
Mathias Agopian65ab4712010-07-14 17:59:35 -0700302int32_t CameraService::getNumberOfCameras() {
303 return mNumberOfCameras;
304}
305
306status_t CameraService::getCameraInfo(int cameraId,
307 struct CameraInfo* cameraInfo) {
Iliyan Malchev8951a972011-04-14 16:55:59 -0700308 if (!mModule) {
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700309 return -ENODEV;
Iliyan Malchev8951a972011-04-14 16:55:59 -0700310 }
311
Mathias Agopian65ab4712010-07-14 17:59:35 -0700312 if (cameraId < 0 || cameraId >= mNumberOfCameras) {
313 return BAD_VALUE;
314 }
315
Iliyan Malchev8951a972011-04-14 16:55:59 -0700316 struct camera_info info;
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -0700317 status_t rc = filterGetInfoErrorCode(
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800318 mModule->getCameraInfo(cameraId, &info));
Iliyan Malchev8951a972011-04-14 16:55:59 -0700319 cameraInfo->facing = info.facing;
320 cameraInfo->orientation = info.orientation;
321 return rc;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700322}
323
Ruben Brunkb2119af2014-05-09 19:57:56 -0700324
325status_t CameraService::generateShimMetadata(int cameraId, /*out*/CameraMetadata* cameraInfo) {
326 status_t ret = OK;
327 struct CameraInfo info;
328 if ((ret = getCameraInfo(cameraId, &info)) != OK) {
329 return ret;
330 }
331
332 CameraMetadata shimInfo;
333 int32_t orientation = static_cast<int32_t>(info.orientation);
334 if ((ret = shimInfo.update(ANDROID_SENSOR_ORIENTATION, &orientation, 1)) != OK) {
335 return ret;
336 }
337
338 uint8_t facing = (info.facing == CAMERA_FACING_FRONT) ?
339 ANDROID_LENS_FACING_FRONT : ANDROID_LENS_FACING_BACK;
340 if ((ret = shimInfo.update(ANDROID_LENS_FACING, &facing, 1)) != OK) {
341 return ret;
342 }
343
Igor Murashkin65d14b92014-06-17 12:03:20 -0700344 CameraParameters shimParams;
345 if ((ret = getLegacyParametersLazy(cameraId, /*out*/&shimParams)) != OK) {
346 // Error logged by callee
347 return ret;
Ruben Brunkb2119af2014-05-09 19:57:56 -0700348 }
349
350 Vector<Size> sizes;
Ruben Brunk152dbcf2014-06-12 19:11:45 -0700351 Vector<Size> jpegSizes;
Ruben Brunkb2119af2014-05-09 19:57:56 -0700352 Vector<int32_t> formats;
353 const char* supportedPreviewFormats;
Igor Murashkin65d14b92014-06-17 12:03:20 -0700354 {
355 shimParams.getSupportedPreviewSizes(/*out*/sizes);
356 shimParams.getSupportedPreviewFormats(/*out*/formats);
357 shimParams.getSupportedPictureSizes(/*out*/jpegSizes);
Ruben Brunkb2119af2014-05-09 19:57:56 -0700358 }
359
360 // Always include IMPLEMENTATION_DEFINED
361 formats.add(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED);
362
363 const size_t INTS_PER_CONFIG = 4;
364
365 // Build available stream configurations metadata
Ruben Brunk152dbcf2014-06-12 19:11:45 -0700366 size_t streamConfigSize = (sizes.size() * formats.size() + jpegSizes.size()) * INTS_PER_CONFIG;
367
368 Vector<int32_t> streamConfigs;
369 streamConfigs.setCapacity(streamConfigSize);
370
Ruben Brunkb2119af2014-05-09 19:57:56 -0700371 for (size_t i = 0; i < formats.size(); ++i) {
372 for (size_t j = 0; j < sizes.size(); ++j) {
Ruben Brunk152dbcf2014-06-12 19:11:45 -0700373 streamConfigs.add(formats[i]);
374 streamConfigs.add(sizes[j].width);
375 streamConfigs.add(sizes[j].height);
376 streamConfigs.add(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
Ruben Brunkb2119af2014-05-09 19:57:56 -0700377 }
378 }
379
Ruben Brunk152dbcf2014-06-12 19:11:45 -0700380 for (size_t i = 0; i < jpegSizes.size(); ++i) {
381 streamConfigs.add(HAL_PIXEL_FORMAT_BLOB);
382 streamConfigs.add(jpegSizes[i].width);
383 streamConfigs.add(jpegSizes[i].height);
384 streamConfigs.add(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
385 }
386
Ruben Brunkb2119af2014-05-09 19:57:56 -0700387 if ((ret = shimInfo.update(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
Ruben Brunk152dbcf2014-06-12 19:11:45 -0700388 streamConfigs.array(), streamConfigSize)) != OK) {
Ruben Brunkb2119af2014-05-09 19:57:56 -0700389 return ret;
390 }
391
392 int64_t fakeMinFrames[0];
393 // TODO: Fixme, don't fake min frame durations.
394 if ((ret = shimInfo.update(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
395 fakeMinFrames, 0)) != OK) {
396 return ret;
397 }
398
399 int64_t fakeStalls[0];
400 // TODO: Fixme, don't fake stall durations.
401 if ((ret = shimInfo.update(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
402 fakeStalls, 0)) != OK) {
403 return ret;
404 }
405
406 *cameraInfo = shimInfo;
407 return OK;
408}
409
Zhijun He2b59be82013-09-25 10:14:30 -0700410status_t CameraService::getCameraCharacteristics(int cameraId,
411 CameraMetadata* cameraInfo) {
412 if (!cameraInfo) {
413 ALOGE("%s: cameraInfo is NULL", __FUNCTION__);
414 return BAD_VALUE;
415 }
416
417 if (!mModule) {
418 ALOGE("%s: camera hardware module doesn't exist", __FUNCTION__);
419 return -ENODEV;
420 }
421
Zhijun He2b59be82013-09-25 10:14:30 -0700422 if (cameraId < 0 || cameraId >= mNumberOfCameras) {
423 ALOGE("%s: Invalid camera id: %d", __FUNCTION__, cameraId);
424 return BAD_VALUE;
425 }
426
427 int facing;
Ruben Brunkb2119af2014-05-09 19:57:56 -0700428 status_t ret = OK;
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800429 if (mModule->getRawModule()->module_api_version < CAMERA_MODULE_API_VERSION_2_0 ||
Ruben Brunkb2119af2014-05-09 19:57:56 -0700430 getDeviceVersion(cameraId, &facing) <= CAMERA_DEVICE_API_VERSION_2_1 ) {
431 /**
432 * Backwards compatibility mode for old HALs:
433 * - Convert CameraInfo into static CameraMetadata properties.
434 * - Retrieve cached CameraParameters for this camera. If none exist,
435 * attempt to open CameraClient and retrieve the CameraParameters.
436 * - Convert cached CameraParameters into static CameraMetadata
437 * properties.
438 */
439 ALOGI("%s: Switching to HAL1 shim implementation...", __FUNCTION__);
Zhijun He2b59be82013-09-25 10:14:30 -0700440
Ruben Brunkb2119af2014-05-09 19:57:56 -0700441 if ((ret = generateShimMetadata(cameraId, cameraInfo)) != OK) {
442 return ret;
443 }
Zhijun Hef05e50e2013-10-01 11:05:33 -0700444
Ruben Brunkb2119af2014-05-09 19:57:56 -0700445 } else {
446 /**
447 * Normal HAL 2.1+ codepath.
448 */
449 struct camera_info info;
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800450 ret = filterGetInfoErrorCode(mModule->getCameraInfo(cameraId, &info));
Ruben Brunkb2119af2014-05-09 19:57:56 -0700451 *cameraInfo = info.static_camera_characteristics;
452 }
Zhijun He2b59be82013-09-25 10:14:30 -0700453
454 return ret;
455}
456
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800457status_t CameraService::getCameraVendorTagDescriptor(/*out*/sp<VendorTagDescriptor>& desc) {
458 if (!mModule) {
459 ALOGE("%s: camera hardware module doesn't exist", __FUNCTION__);
460 return -ENODEV;
461 }
462
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800463 desc = VendorTagDescriptor::getGlobalVendorTagDescriptor();
464 return OK;
465}
466
Igor Murashkin634a5152013-02-20 17:15:11 -0800467int CameraService::getDeviceVersion(int cameraId, int* facing) {
468 struct camera_info info;
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800469 if (mModule->getCameraInfo(cameraId, &info) != OK) {
Igor Murashkin634a5152013-02-20 17:15:11 -0800470 return -1;
471 }
472
473 int deviceVersion;
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800474 if (mModule->getRawModule()->module_api_version >= CAMERA_MODULE_API_VERSION_2_0) {
Igor Murashkin634a5152013-02-20 17:15:11 -0800475 deviceVersion = info.device_version;
476 } else {
477 deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
478 }
479
480 if (facing) {
481 *facing = info.facing;
482 }
483
484 return deviceVersion;
485}
486
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -0700487status_t CameraService::filterOpenErrorCode(status_t err) {
488 switch(err) {
489 case NO_ERROR:
490 case -EBUSY:
491 case -EINVAL:
492 case -EUSERS:
493 return err;
494 default:
495 break;
Igor Murashkinbfc99152013-02-27 12:55:20 -0800496 }
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -0700497 return -ENODEV;
498}
Igor Murashkinbfc99152013-02-27 12:55:20 -0800499
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -0700500status_t CameraService::filterGetInfoErrorCode(status_t err) {
501 switch(err) {
502 case NO_ERROR:
503 case -EINVAL:
504 return err;
505 default:
506 break;
507 }
508 return -ENODEV;
Igor Murashkinbfc99152013-02-27 12:55:20 -0800509}
510
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800511bool CameraService::setUpVendorTags() {
512 vendor_tag_ops_t vOps = vendor_tag_ops_t();
513
514 // Check if vendor operations have been implemented
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800515 if (!mModule->isVendorTagDefined()) {
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800516 ALOGI("%s: No vendor tags defined for this device.", __FUNCTION__);
517 return false;
518 }
519
520 ATRACE_BEGIN("camera3->get_metadata_vendor_tag_ops");
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800521 mModule->getVendorTagOps(&vOps);
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800522 ATRACE_END();
523
524 // Ensure all vendor operations are present
525 if (vOps.get_tag_count == NULL || vOps.get_all_tags == NULL ||
526 vOps.get_section_name == NULL || vOps.get_tag_name == NULL ||
527 vOps.get_tag_type == NULL) {
528 ALOGE("%s: Vendor tag operations not fully defined. Ignoring definitions."
529 , __FUNCTION__);
530 return false;
531 }
532
533 // Read all vendor tag definitions into a descriptor
534 sp<VendorTagDescriptor> desc;
535 status_t res;
536 if ((res = VendorTagDescriptor::createDescriptorFromOps(&vOps, /*out*/desc))
537 != OK) {
538 ALOGE("%s: Could not generate descriptor from vendor tag operations,"
539 "received error %s (%d). Camera clients will not be able to use"
540 "vendor tags", __FUNCTION__, strerror(res), res);
541 return false;
542 }
543
544 // Set the global descriptor to use with camera metadata
545 VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
546 return true;
547}
548
Ruben Brunkb2119af2014-05-09 19:57:56 -0700549status_t CameraService::initializeShimMetadata(int cameraId) {
550 int pid = getCallingPid();
551 int uid = getCallingUid();
552 status_t ret = validateConnect(cameraId, uid);
553 if (ret != OK) {
Igor Murashkin65d14b92014-06-17 12:03:20 -0700554 // Error already logged by callee
Ruben Brunkb2119af2014-05-09 19:57:56 -0700555 return ret;
556 }
557
558 bool needsNewClient = false;
559 sp<Client> client;
560
561 String16 internalPackageName("media");
562 { // Scope for service lock
563 Mutex::Autolock lock(mServiceLock);
564 if (mClient[cameraId] != NULL) {
565 client = static_cast<Client*>(mClient[cameraId].promote().get());
566 }
567 if (client == NULL) {
568 needsNewClient = true;
Igor Murashkina858ea02014-08-19 14:53:08 -0700569 ret = connectHelperLocked(/*out*/client,
570 /*cameraClient*/NULL, // Empty binder callbacks
Ruben Brunkb2119af2014-05-09 19:57:56 -0700571 cameraId,
572 internalPackageName,
573 uid,
Igor Murashkina858ea02014-08-19 14:53:08 -0700574 pid);
Ruben Brunkb2119af2014-05-09 19:57:56 -0700575
576 if (ret != OK) {
Igor Murashkin65d14b92014-06-17 12:03:20 -0700577 // Error already logged by callee
Ruben Brunkb2119af2014-05-09 19:57:56 -0700578 return ret;
579 }
580 }
581
582 if (client == NULL) {
583 ALOGE("%s: Could not connect to client camera device.", __FUNCTION__);
584 return BAD_VALUE;
585 }
586
587 String8 rawParams = client->getParameters();
588 CameraParameters params(rawParams);
589 mShimParams.add(cameraId, params);
590 }
591
592 // Close client if one was opened solely for this call
593 if (needsNewClient) {
594 client->disconnect();
595 }
596 return OK;
597}
598
Igor Murashkin65d14b92014-06-17 12:03:20 -0700599status_t CameraService::getLegacyParametersLazy(int cameraId,
600 /*out*/
601 CameraParameters* parameters) {
602
603 ALOGV("%s: for cameraId: %d", __FUNCTION__, cameraId);
604
605 status_t ret = 0;
606
607 if (parameters == NULL) {
608 ALOGE("%s: parameters must not be null", __FUNCTION__);
609 return BAD_VALUE;
610 }
611
612 ssize_t index = -1;
613 { // Scope for service lock
614 Mutex::Autolock lock(mServiceLock);
615 index = mShimParams.indexOfKey(cameraId);
616 // Release service lock so initializeShimMetadata can be called correctly.
617
618 if (index >= 0) {
619 *parameters = mShimParams[index];
620 }
621 }
622
623 if (index < 0) {
624 int64_t token = IPCThreadState::self()->clearCallingIdentity();
625 ret = initializeShimMetadata(cameraId);
626 IPCThreadState::self()->restoreCallingIdentity(token);
627 if (ret != OK) {
628 // Error already logged by callee
629 return ret;
630 }
631
632 { // Scope for service lock
633 Mutex::Autolock lock(mServiceLock);
634 index = mShimParams.indexOfKey(cameraId);
635
636 LOG_ALWAYS_FATAL_IF(index < 0, "index should have been initialized");
637
638 *parameters = mShimParams[index];
639 }
640 }
641
642 return OK;
643}
644
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700645status_t CameraService::validateConnect(int cameraId,
Igor Murashkine6800ce2013-03-04 17:25:57 -0800646 /*inout*/
647 int& clientUid) const {
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800648
Mathias Agopian65ab4712010-07-14 17:59:35 -0700649 int callingPid = getCallingPid();
Tyler Luu5861a9a2011-10-06 00:00:03 -0500650
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800651 if (clientUid == USE_CALLING_UID) {
652 clientUid = getCallingUid();
653 } else {
654 // We only trust our own process to forward client UIDs
655 if (callingPid != getpid()) {
656 ALOGE("CameraService::connect X (pid %d) rejected (don't trust clientUid)",
657 callingPid);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700658 return PERMISSION_DENIED;
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800659 }
660 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700661
Iliyan Malchev8951a972011-04-14 16:55:59 -0700662 if (!mModule) {
Steve Block29357bc2012-01-06 19:20:56 +0000663 ALOGE("Camera HAL module not loaded");
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700664 return -ENODEV;
Iliyan Malchev8951a972011-04-14 16:55:59 -0700665 }
666
Mathias Agopian65ab4712010-07-14 17:59:35 -0700667 if (cameraId < 0 || cameraId >= mNumberOfCameras) {
Steve Block29357bc2012-01-06 19:20:56 +0000668 ALOGE("CameraService::connect X (pid %d) rejected (invalid cameraId %d).",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700669 callingPid, cameraId);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700670 return -ENODEV;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700671 }
672
Wu-cheng Lia3355432011-05-20 14:54:25 +0800673 char value[PROPERTY_VALUE_MAX];
Amith Yamasani228711d2015-02-13 13:25:39 -0800674 char key[PROPERTY_KEY_MAX];
675 int clientUserId = multiuser_get_user_id(clientUid);
676 snprintf(key, PROPERTY_KEY_MAX, "sys.secpolicy.camera.off_%d", clientUserId);
677 property_get(key, value, "0");
Wu-cheng Lia3355432011-05-20 14:54:25 +0800678 if (strcmp(value, "1") == 0) {
679 // Camera is disabled by DevicePolicyManager.
Steve Blockdf64d152012-01-04 20:05:49 +0000680 ALOGI("Camera is disabled. connect X (pid %d) rejected", callingPid);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700681 return -EACCES;
Wu-cheng Lia3355432011-05-20 14:54:25 +0800682 }
683
Igor Murashkincba2c162013-03-20 15:56:31 -0700684 ICameraServiceListener::Status currentStatus = getStatus(cameraId);
685 if (currentStatus == ICameraServiceListener::STATUS_NOT_PRESENT) {
686 ALOGI("Camera is not plugged in,"
687 " connect X (pid %d) rejected", callingPid);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700688 return -ENODEV;
Igor Murashkincba2c162013-03-20 15:56:31 -0700689 } else if (currentStatus == ICameraServiceListener::STATUS_ENUMERATING) {
690 ALOGI("Camera is enumerating,"
691 " connect X (pid %d) rejected", callingPid);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700692 return -EBUSY;
Igor Murashkincba2c162013-03-20 15:56:31 -0700693 }
694 // Else don't check for STATUS_NOT_AVAILABLE.
695 // -- It's done implicitly in canConnectUnsafe /w the mBusy array
696
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700697 return OK;
Igor Murashkine6800ce2013-03-04 17:25:57 -0800698}
699
700bool CameraService::canConnectUnsafe(int cameraId,
701 const String16& clientPackageName,
702 const sp<IBinder>& remoteCallback,
Igor Murashkine7ee7632013-06-11 18:10:18 -0700703 sp<BasicClient> &client) {
Igor Murashkine6800ce2013-03-04 17:25:57 -0800704 String8 clientName8(clientPackageName);
705 int callingPid = getCallingPid();
706
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800707 if (mClient[cameraId] != 0) {
708 client = mClient[cameraId].promote();
709 if (client != 0) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700710 if (remoteCallback == client->getRemote()) {
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800711 LOG1("CameraService::connect X (pid %d) (the same client)",
712 callingPid);
Igor Murashkine6800ce2013-03-04 17:25:57 -0800713 return true;
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800714 } else {
Igor Murashkine6800ce2013-03-04 17:25:57 -0800715 // TODOSC: need to support 1 regular client,
716 // multiple shared clients here
717 ALOGW("CameraService::connect X (pid %d) rejected"
718 " (existing client).", callingPid);
719 return false;
Wu-cheng Li2fd24402012-02-23 19:01:00 -0800720 }
Wu-cheng Li2fd24402012-02-23 19:01:00 -0800721 }
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800722 mClient[cameraId].clear();
723 }
724
Igor Murashkin634a5152013-02-20 17:15:11 -0800725 /*
726 mBusy is set to false as the last step of the Client destructor,
727 after which it is guaranteed that the Client destructor has finished (
728 including any inherited destructors)
729
730 We only need this for a Client subclasses since we don't allow
731 multiple Clents to be opened concurrently, but multiple BasicClient
732 would be fine
733 */
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800734 if (mBusy[cameraId]) {
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800735 ALOGW("CameraService::connect X (pid %d, \"%s\") rejected"
736 " (camera %d is still busy).", callingPid,
737 clientName8.string(), cameraId);
Igor Murashkine6800ce2013-03-04 17:25:57 -0800738 return false;
739 }
740
741 return true;
742}
743
Igor Murashkina858ea02014-08-19 14:53:08 -0700744status_t CameraService::connectHelperLocked(
745 /*out*/
746 sp<Client>& client,
747 /*in*/
748 const sp<ICameraClient>& cameraClient,
749 int cameraId,
750 const String16& clientPackageName,
751 int clientUid,
752 int callingPid,
753 int halVersion,
754 bool legacyMode) {
Ruben Brunkb2119af2014-05-09 19:57:56 -0700755
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800756 // give flashlight a chance to close devices if necessary.
757 mFlashlight->prepareDeviceOpen();
758
Ruben Brunkb2119af2014-05-09 19:57:56 -0700759 int facing = -1;
760 int deviceVersion = getDeviceVersion(cameraId, &facing);
761
Zhijun Heb10cdad2014-06-16 16:38:35 -0700762 if (halVersion < 0 || halVersion == deviceVersion) {
763 // Default path: HAL version is unspecified by caller, create CameraClient
764 // based on device version reported by the HAL.
765 switch(deviceVersion) {
766 case CAMERA_DEVICE_API_VERSION_1_0:
767 client = new CameraClient(this, cameraClient,
768 clientPackageName, cameraId,
Igor Murashkina858ea02014-08-19 14:53:08 -0700769 facing, callingPid, clientUid, getpid(), legacyMode);
Zhijun Heb10cdad2014-06-16 16:38:35 -0700770 break;
771 case CAMERA_DEVICE_API_VERSION_2_0:
772 case CAMERA_DEVICE_API_VERSION_2_1:
773 case CAMERA_DEVICE_API_VERSION_3_0:
774 case CAMERA_DEVICE_API_VERSION_3_1:
775 case CAMERA_DEVICE_API_VERSION_3_2:
776 client = new Camera2Client(this, cameraClient,
777 clientPackageName, cameraId,
Igor Murashkina858ea02014-08-19 14:53:08 -0700778 facing, callingPid, clientUid, getpid(), legacyMode);
Zhijun Heb10cdad2014-06-16 16:38:35 -0700779 break;
780 case -1:
781 ALOGE("Invalid camera id %d", cameraId);
782 return BAD_VALUE;
783 default:
784 ALOGE("Unknown camera device HAL version: %d", deviceVersion);
785 return INVALID_OPERATION;
786 }
787 } else {
788 // A particular HAL version is requested by caller. Create CameraClient
789 // based on the requested HAL version.
790 if (deviceVersion > CAMERA_DEVICE_API_VERSION_1_0 &&
791 halVersion == CAMERA_DEVICE_API_VERSION_1_0) {
792 // Only support higher HAL version device opened as HAL1.0 device.
793 client = new CameraClient(this, cameraClient,
794 clientPackageName, cameraId,
Igor Murashkina858ea02014-08-19 14:53:08 -0700795 facing, callingPid, clientUid, getpid(), legacyMode);
Zhijun Heb10cdad2014-06-16 16:38:35 -0700796 } else {
797 // Other combinations (e.g. HAL3.x open as HAL2.x) are not supported yet.
798 ALOGE("Invalid camera HAL version %x: HAL %x device can only be"
799 " opened as HAL %x device", halVersion, deviceVersion,
800 CAMERA_DEVICE_API_VERSION_1_0);
801 return INVALID_OPERATION;
802 }
Ruben Brunkb2119af2014-05-09 19:57:56 -0700803 }
804
805 status_t status = connectFinishUnsafe(client, client->getRemote());
806 if (status != OK) {
807 // this is probably not recoverable.. maybe the client can try again
Ruben Brunkb2119af2014-05-09 19:57:56 -0700808 return status;
809 }
810
811 mClient[cameraId] = client;
812 LOG1("CameraService::connect X (id %d, this pid is %d)", cameraId,
813 getpid());
814
815 return OK;
816}
817
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700818status_t CameraService::connect(
Igor Murashkine6800ce2013-03-04 17:25:57 -0800819 const sp<ICameraClient>& cameraClient,
820 int cameraId,
821 const String16& clientPackageName,
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700822 int clientUid,
823 /*out*/
824 sp<ICamera>& device) {
Igor Murashkine6800ce2013-03-04 17:25:57 -0800825
826 String8 clientName8(clientPackageName);
827 int callingPid = getCallingPid();
828
829 LOG1("CameraService::connect E (pid %d \"%s\", id %d)", callingPid,
830 clientName8.string(), cameraId);
831
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700832 status_t status = validateConnect(cameraId, /*inout*/clientUid);
833 if (status != OK) {
834 return status;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700835 }
836
Igor Murashkine6800ce2013-03-04 17:25:57 -0800837
Igor Murashkine7ee7632013-06-11 18:10:18 -0700838 sp<Client> client;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700839 {
840 Mutex::Autolock lock(mServiceLock);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700841 sp<BasicClient> clientTmp;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700842 if (!canConnectUnsafe(cameraId, clientPackageName,
Marco Nelissenf8880202014-11-14 07:58:25 -0800843 IInterface::asBinder(cameraClient),
Igor Murashkine7ee7632013-06-11 18:10:18 -0700844 /*out*/clientTmp)) {
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700845 return -EBUSY;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700846 } else if (client.get() != NULL) {
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700847 device = static_cast<Client*>(clientTmp.get());
848 return OK;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700849 }
850
Igor Murashkina858ea02014-08-19 14:53:08 -0700851 status = connectHelperLocked(/*out*/client,
852 cameraClient,
Ruben Brunkb2119af2014-05-09 19:57:56 -0700853 cameraId,
854 clientPackageName,
855 clientUid,
Igor Murashkina858ea02014-08-19 14:53:08 -0700856 callingPid);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700857 if (status != OK) {
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700858 return status;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700859 }
860
Igor Murashkine6800ce2013-03-04 17:25:57 -0800861 }
Igor Murashkinacd695c2013-03-13 17:23:00 -0700862 // important: release the mutex here so the client can call back
863 // into the service from its destructor (can be at the end of the call)
Igor Murashkinbfc99152013-02-27 12:55:20 -0800864
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700865 device = client;
866 return OK;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700867}
868
Zhijun Heb10cdad2014-06-16 16:38:35 -0700869status_t CameraService::connectLegacy(
870 const sp<ICameraClient>& cameraClient,
871 int cameraId, int halVersion,
872 const String16& clientPackageName,
873 int clientUid,
874 /*out*/
875 sp<ICamera>& device) {
876
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800877 int apiVersion = mModule->getRawModule()->module_api_version;
Igor Murashkin3d07d1a2014-06-20 11:27:03 -0700878 if (halVersion != CAMERA_HAL_API_VERSION_UNSPECIFIED &&
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800879 apiVersion < CAMERA_MODULE_API_VERSION_2_3) {
Igor Murashkin3d07d1a2014-06-20 11:27:03 -0700880 /*
881 * Either the HAL version is unspecified in which case this just creates
882 * a camera client selected by the latest device version, or
883 * it's a particular version in which case the HAL must supported
884 * the open_legacy call
885 */
Zhijun Heb10cdad2014-06-16 16:38:35 -0700886 ALOGE("%s: camera HAL module version %x doesn't support connecting to legacy HAL devices!",
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800887 __FUNCTION__, apiVersion);
Zhijun Heb10cdad2014-06-16 16:38:35 -0700888 return INVALID_OPERATION;
889 }
890
891 String8 clientName8(clientPackageName);
892 int callingPid = getCallingPid();
893
894 LOG1("CameraService::connect legacy E (pid %d \"%s\", id %d)", callingPid,
895 clientName8.string(), cameraId);
896
897 status_t status = validateConnect(cameraId, /*inout*/clientUid);
898 if (status != OK) {
899 return status;
900 }
901
902 sp<Client> client;
903 {
904 Mutex::Autolock lock(mServiceLock);
905 sp<BasicClient> clientTmp;
906 if (!canConnectUnsafe(cameraId, clientPackageName,
Marco Nelissenf8880202014-11-14 07:58:25 -0800907 IInterface::asBinder(cameraClient),
Zhijun Heb10cdad2014-06-16 16:38:35 -0700908 /*out*/clientTmp)) {
909 return -EBUSY;
910 } else if (client.get() != NULL) {
911 device = static_cast<Client*>(clientTmp.get());
912 return OK;
913 }
914
Igor Murashkina858ea02014-08-19 14:53:08 -0700915 status = connectHelperLocked(/*out*/client,
916 cameraClient,
Zhijun Heb10cdad2014-06-16 16:38:35 -0700917 cameraId,
918 clientPackageName,
919 clientUid,
920 callingPid,
Igor Murashkina858ea02014-08-19 14:53:08 -0700921 halVersion,
922 /*legacyMode*/true);
Zhijun Heb10cdad2014-06-16 16:38:35 -0700923 if (status != OK) {
924 return status;
925 }
926
927 }
928 // important: release the mutex here so the client can call back
929 // into the service from its destructor (can be at the end of the call)
930
931 device = client;
932 return OK;
933}
934
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800935status_t CameraService::setTorchMode(const String16& cameraId, bool enabled,
936 const sp<IBinder>& clientBinder) {
937 if (enabled && clientBinder == NULL) {
938 ALOGE("%s: torch client binder is NULL", __FUNCTION__);
939 return -ENOSYS;
940 }
941
942 Mutex::Autolock al(mTorchStatusMutex);
943 status_t res = mFlashlight->setTorchMode(cameraId, enabled);
944 if (res) {
945 ALOGE("%s: setting torch mode of camera %s to %d failed", __FUNCTION__,
946 cameraId.string(), enabled);
947 return res;
948 }
949
950 // update the link to client's death
951 ssize_t index = mTorchClientMap.indexOfKey(cameraId);
952 if (enabled) {
953 if (index == NAME_NOT_FOUND) {
954 mTorchClientMap.add(cameraId, clientBinder);
955 } else {
956 const sp<IBinder> oldBinder = mTorchClientMap.valueAt(index);
957 oldBinder->unlinkToDeath(this);
958
959 mTorchClientMap.replaceValueAt(index, clientBinder);
960 }
961 clientBinder->linkToDeath(this);
962 } else if (index != NAME_NOT_FOUND) {
963 sp<IBinder> oldBinder = mTorchClientMap.valueAt(index);
964 oldBinder->unlinkToDeath(this);
965 }
966
967 // notify the listeners the change.
968 ICameraServiceListener::TorchStatus status = enabled ?
969 ICameraServiceListener::TORCH_STATUS_ON :
970 ICameraServiceListener::TORCH_STATUS_OFF;
971 onTorchStatusChangedLocked(cameraId, status);
972
973 return OK;
974}
975
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700976status_t CameraService::connectFinishUnsafe(const sp<BasicClient>& client,
977 const sp<IBinder>& remoteCallback) {
978 status_t status = client->initialize(mModule);
979 if (status != OK) {
Ruben Brunk5fc9d902014-11-20 13:34:36 -0800980 ALOGE("%s: Could not initialize client from HAL module.", __FUNCTION__);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700981 return status;
Igor Murashkine6800ce2013-03-04 17:25:57 -0800982 }
Ruben Brunkb2119af2014-05-09 19:57:56 -0700983 if (remoteCallback != NULL) {
984 remoteCallback->linkToDeath(this);
985 }
Igor Murashkine6800ce2013-03-04 17:25:57 -0800986
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700987 return OK;
Igor Murashkine6800ce2013-03-04 17:25:57 -0800988}
989
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700990status_t CameraService::connectPro(
Igor Murashkin634a5152013-02-20 17:15:11 -0800991 const sp<IProCameraCallbacks>& cameraCb,
Igor Murashkinc073ba52013-02-26 14:32:34 -0800992 int cameraId,
993 const String16& clientPackageName,
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700994 int clientUid,
995 /*out*/
996 sp<IProCameraUser>& device)
Igor Murashkin634a5152013-02-20 17:15:11 -0800997{
Natalie Silvanoviche1b55da2014-05-01 14:44:52 -0700998 if (cameraCb == 0) {
999 ALOGE("%s: Callback must not be null", __FUNCTION__);
1000 return BAD_VALUE;
1001 }
1002
Igor Murashkinbfc99152013-02-27 12:55:20 -08001003 String8 clientName8(clientPackageName);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001004 int callingPid = getCallingPid();
Igor Murashkin634a5152013-02-20 17:15:11 -08001005
Igor Murashkine6800ce2013-03-04 17:25:57 -08001006 LOG1("CameraService::connectPro E (pid %d \"%s\", id %d)", callingPid,
1007 clientName8.string(), cameraId);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001008 status_t status = validateConnect(cameraId, /*inout*/clientUid);
1009 if (status != OK) {
1010 return status;
Igor Murashkin634a5152013-02-20 17:15:11 -08001011 }
1012
Igor Murashkinacd695c2013-03-13 17:23:00 -07001013 sp<ProClient> client;
Igor Murashkine6800ce2013-03-04 17:25:57 -08001014 {
Igor Murashkinacd695c2013-03-13 17:23:00 -07001015 Mutex::Autolock lock(mServiceLock);
1016 {
Igor Murashkine7ee7632013-06-11 18:10:18 -07001017 sp<BasicClient> client;
Igor Murashkinacd695c2013-03-13 17:23:00 -07001018 if (!canConnectUnsafe(cameraId, clientPackageName,
Marco Nelissenf8880202014-11-14 07:58:25 -08001019 IInterface::asBinder(cameraCb),
Igor Murashkinacd695c2013-03-13 17:23:00 -07001020 /*out*/client)) {
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001021 return -EBUSY;
Igor Murashkinacd695c2013-03-13 17:23:00 -07001022 }
1023 }
1024
1025 int facing = -1;
1026 int deviceVersion = getDeviceVersion(cameraId, &facing);
1027
1028 switch(deviceVersion) {
1029 case CAMERA_DEVICE_API_VERSION_1_0:
1030 ALOGE("Camera id %d uses HALv1, doesn't support ProCamera",
1031 cameraId);
Ruben Brunk17963d12013-08-19 15:21:19 -07001032 return -EOPNOTSUPP;
Igor Murashkinacd695c2013-03-13 17:23:00 -07001033 break;
1034 case CAMERA_DEVICE_API_VERSION_2_0:
1035 case CAMERA_DEVICE_API_VERSION_2_1:
Zhijun He47110052013-07-22 17:34:34 -07001036 case CAMERA_DEVICE_API_VERSION_3_0:
Zhijun He95dd5ba2014-03-26 18:18:00 -07001037 case CAMERA_DEVICE_API_VERSION_3_1:
1038 case CAMERA_DEVICE_API_VERSION_3_2:
Eino-Ville Talvala63d877f2014-06-16 19:21:12 -07001039 client = new ProCamera2Client(this, cameraCb, clientPackageName,
1040 cameraId, facing, callingPid, clientUid, getpid());
Igor Murashkinacd695c2013-03-13 17:23:00 -07001041 break;
1042 case -1:
1043 ALOGE("Invalid camera id %d", cameraId);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001044 return BAD_VALUE;
Igor Murashkinacd695c2013-03-13 17:23:00 -07001045 default:
1046 ALOGE("Unknown camera device HAL version: %d", deviceVersion);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001047 return INVALID_OPERATION;
Igor Murashkine6800ce2013-03-04 17:25:57 -08001048 }
Igor Murashkinacd695c2013-03-13 17:23:00 -07001049
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001050 status_t status = connectFinishUnsafe(client, client->getRemote());
1051 if (status != OK) {
1052 return status;
Igor Murashkinacd695c2013-03-13 17:23:00 -07001053 }
1054
1055 mProClientList[cameraId].push(client);
1056
1057 LOG1("CameraService::connectPro X (id %d, this pid is %d)", cameraId,
1058 getpid());
Igor Murashkine6800ce2013-03-04 17:25:57 -08001059 }
Igor Murashkinacd695c2013-03-13 17:23:00 -07001060 // important: release the mutex here so the client can call back
1061 // into the service from its destructor (can be at the end of the call)
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001062 device = client;
1063 return OK;
Igor Murashkinbfc99152013-02-27 12:55:20 -08001064}
Igor Murashkin634a5152013-02-20 17:15:11 -08001065
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001066status_t CameraService::connectDevice(
Igor Murashkine7ee7632013-06-11 18:10:18 -07001067 const sp<ICameraDeviceCallbacks>& cameraCb,
1068 int cameraId,
1069 const String16& clientPackageName,
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001070 int clientUid,
1071 /*out*/
1072 sp<ICameraDeviceUser>& device)
Igor Murashkine7ee7632013-06-11 18:10:18 -07001073{
Igor Murashkine7ee7632013-06-11 18:10:18 -07001074
1075 String8 clientName8(clientPackageName);
1076 int callingPid = getCallingPid();
1077
1078 LOG1("CameraService::connectDevice E (pid %d \"%s\", id %d)", callingPid,
1079 clientName8.string(), cameraId);
1080
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001081 status_t status = validateConnect(cameraId, /*inout*/clientUid);
1082 if (status != OK) {
1083 return status;
Igor Murashkine7ee7632013-06-11 18:10:18 -07001084 }
1085
1086 sp<CameraDeviceClient> client;
1087 {
1088 Mutex::Autolock lock(mServiceLock);
1089 {
1090 sp<BasicClient> client;
1091 if (!canConnectUnsafe(cameraId, clientPackageName,
Marco Nelissenf8880202014-11-14 07:58:25 -08001092 IInterface::asBinder(cameraCb),
Igor Murashkine7ee7632013-06-11 18:10:18 -07001093 /*out*/client)) {
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001094 return -EBUSY;
Igor Murashkine7ee7632013-06-11 18:10:18 -07001095 }
1096 }
1097
1098 int facing = -1;
1099 int deviceVersion = getDeviceVersion(cameraId, &facing);
1100
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001101 // give flashlight a chance to close devices if necessary.
1102 mFlashlight->prepareDeviceOpen();
1103
Igor Murashkine7ee7632013-06-11 18:10:18 -07001104 switch(deviceVersion) {
1105 case CAMERA_DEVICE_API_VERSION_1_0:
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001106 ALOGW("Camera using old HAL version: %d", deviceVersion);
Ruben Brunk17963d12013-08-19 15:21:19 -07001107 return -EOPNOTSUPP;
Igor Murashkine7ee7632013-06-11 18:10:18 -07001108 // TODO: don't allow 2.0 Only allow 2.1 and higher
1109 case CAMERA_DEVICE_API_VERSION_2_0:
1110 case CAMERA_DEVICE_API_VERSION_2_1:
1111 case CAMERA_DEVICE_API_VERSION_3_0:
Zhijun He95dd5ba2014-03-26 18:18:00 -07001112 case CAMERA_DEVICE_API_VERSION_3_1:
1113 case CAMERA_DEVICE_API_VERSION_3_2:
Eino-Ville Talvala63d877f2014-06-16 19:21:12 -07001114 client = new CameraDeviceClient(this, cameraCb, clientPackageName,
1115 cameraId, facing, callingPid, clientUid, getpid());
Igor Murashkine7ee7632013-06-11 18:10:18 -07001116 break;
1117 case -1:
1118 ALOGE("Invalid camera id %d", cameraId);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001119 return BAD_VALUE;
Igor Murashkine7ee7632013-06-11 18:10:18 -07001120 default:
1121 ALOGE("Unknown camera device HAL version: %d", deviceVersion);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001122 return INVALID_OPERATION;
Igor Murashkine7ee7632013-06-11 18:10:18 -07001123 }
1124
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001125 status_t status = connectFinishUnsafe(client, client->getRemote());
1126 if (status != OK) {
Igor Murashkine7ee7632013-06-11 18:10:18 -07001127 // this is probably not recoverable.. maybe the client can try again
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001128 return status;
Igor Murashkine7ee7632013-06-11 18:10:18 -07001129 }
1130
1131 LOG1("CameraService::connectDevice X (id %d, this pid is %d)", cameraId,
1132 getpid());
1133
1134 mClient[cameraId] = client;
1135 }
1136 // important: release the mutex here so the client can call back
1137 // into the service from its destructor (can be at the end of the call)
1138
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001139 device = client;
1140 return OK;
Igor Murashkine7ee7632013-06-11 18:10:18 -07001141}
1142
1143
Igor Murashkinbfc99152013-02-27 12:55:20 -08001144status_t CameraService::addListener(
1145 const sp<ICameraServiceListener>& listener) {
1146 ALOGV("%s: Add listener %p", __FUNCTION__, listener.get());
Igor Murashkin634a5152013-02-20 17:15:11 -08001147
Igor Murashkinbd3e2e02014-03-17 13:01:41 -07001148 if (listener == 0) {
1149 ALOGE("%s: Listener must not be null", __FUNCTION__);
1150 return BAD_VALUE;
1151 }
1152
Igor Murashkinbfc99152013-02-27 12:55:20 -08001153 Mutex::Autolock lock(mServiceLock);
1154
1155 Vector<sp<ICameraServiceListener> >::iterator it, end;
1156 for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
Marco Nelissenf8880202014-11-14 07:58:25 -08001157 if (IInterface::asBinder(*it) == IInterface::asBinder(listener)) {
Igor Murashkinbfc99152013-02-27 12:55:20 -08001158 ALOGW("%s: Tried to add listener %p which was already subscribed",
1159 __FUNCTION__, listener.get());
1160 return ALREADY_EXISTS;
1161 }
1162 }
1163
1164 mListenerList.push_back(listener);
1165
Igor Murashkincba2c162013-03-20 15:56:31 -07001166 /* Immediately signal current status to this listener only */
1167 {
1168 Mutex::Autolock m(mStatusMutex) ;
1169 int numCams = getNumberOfCameras();
1170 for (int i = 0; i < numCams; ++i) {
1171 listener->onStatusChanged(mStatusList[i], i);
1172 }
1173 }
1174
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001175 /* Immediately signal current torch status to this listener only */
1176 {
1177 Mutex::Autolock al(mTorchStatusMutex);
1178 for (size_t i = 0; i < mTorchStatusMap.size(); i++ ) {
1179 listener->onTorchStatusChanged(mTorchStatusMap.valueAt(i),
1180 mTorchStatusMap.keyAt(i));
1181 }
1182
1183 }
1184
Igor Murashkinbfc99152013-02-27 12:55:20 -08001185 return OK;
1186}
1187status_t CameraService::removeListener(
1188 const sp<ICameraServiceListener>& listener) {
1189 ALOGV("%s: Remove listener %p", __FUNCTION__, listener.get());
1190
Igor Murashkinbd3e2e02014-03-17 13:01:41 -07001191 if (listener == 0) {
1192 ALOGE("%s: Listener must not be null", __FUNCTION__);
1193 return BAD_VALUE;
1194 }
1195
Igor Murashkinbfc99152013-02-27 12:55:20 -08001196 Mutex::Autolock lock(mServiceLock);
1197
1198 Vector<sp<ICameraServiceListener> >::iterator it;
1199 for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
Marco Nelissenf8880202014-11-14 07:58:25 -08001200 if (IInterface::asBinder(*it) == IInterface::asBinder(listener)) {
Igor Murashkinbfc99152013-02-27 12:55:20 -08001201 mListenerList.erase(it);
1202 return OK;
1203 }
1204 }
1205
1206 ALOGW("%s: Tried to remove a listener %p which was not subscribed",
1207 __FUNCTION__, listener.get());
1208
1209 return BAD_VALUE;
Igor Murashkin634a5152013-02-20 17:15:11 -08001210}
1211
Igor Murashkin65d14b92014-06-17 12:03:20 -07001212status_t CameraService::getLegacyParameters(
1213 int cameraId,
1214 /*out*/
1215 String16* parameters) {
1216 ALOGV("%s: for camera ID = %d", __FUNCTION__, cameraId);
1217
1218 if (parameters == NULL) {
1219 ALOGE("%s: parameters must not be null", __FUNCTION__);
1220 return BAD_VALUE;
1221 }
1222
1223 status_t ret = 0;
1224
1225 CameraParameters shimParams;
1226 if ((ret = getLegacyParametersLazy(cameraId, /*out*/&shimParams)) != OK) {
1227 // Error logged by caller
1228 return ret;
1229 }
1230
1231 String8 shimParamsString8 = shimParams.flatten();
1232 String16 shimParamsString16 = String16(shimParamsString8);
1233
1234 *parameters = shimParamsString16;
1235
1236 return OK;
1237}
1238
1239status_t CameraService::supportsCameraApi(int cameraId, int apiVersion) {
1240 ALOGV("%s: for camera ID = %d", __FUNCTION__, cameraId);
1241
1242 switch (apiVersion) {
1243 case API_VERSION_1:
1244 case API_VERSION_2:
1245 break;
1246 default:
1247 ALOGE("%s: Bad API version %d", __FUNCTION__, apiVersion);
1248 return BAD_VALUE;
1249 }
1250
1251 int facing = -1;
1252 int deviceVersion = getDeviceVersion(cameraId, &facing);
1253
1254 switch(deviceVersion) {
1255 case CAMERA_DEVICE_API_VERSION_1_0:
1256 case CAMERA_DEVICE_API_VERSION_2_0:
1257 case CAMERA_DEVICE_API_VERSION_2_1:
1258 case CAMERA_DEVICE_API_VERSION_3_0:
1259 case CAMERA_DEVICE_API_VERSION_3_1:
1260 if (apiVersion == API_VERSION_2) {
1261 ALOGV("%s: Camera id %d uses HAL prior to HAL3.2, doesn't support api2 without shim",
1262 __FUNCTION__, cameraId);
1263 return -EOPNOTSUPP;
1264 } else { // if (apiVersion == API_VERSION_1) {
1265 ALOGV("%s: Camera id %d uses older HAL before 3.2, but api1 is always supported",
1266 __FUNCTION__, cameraId);
1267 return OK;
1268 }
1269 case CAMERA_DEVICE_API_VERSION_3_2:
1270 ALOGV("%s: Camera id %d uses HAL3.2 or newer, supports api1/api2 directly",
1271 __FUNCTION__, cameraId);
1272 return OK;
1273 case -1:
1274 ALOGE("%s: Invalid camera id %d", __FUNCTION__, cameraId);
1275 return BAD_VALUE;
1276 default:
1277 ALOGE("%s: Unknown camera device HAL version: %d", __FUNCTION__, deviceVersion);
1278 return INVALID_OPERATION;
1279 }
1280
1281 return OK;
1282}
1283
Igor Murashkin634a5152013-02-20 17:15:11 -08001284void CameraService::removeClientByRemote(const wp<IBinder>& remoteBinder) {
1285 int callingPid = getCallingPid();
1286 LOG1("CameraService::removeClientByRemote E (pid %d)", callingPid);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001287
Igor Murashkinecf17e82012-10-02 16:05:11 -07001288 // Declare this before the lock to make absolutely sure the
1289 // destructor won't be called with the lock held.
1290 Mutex::Autolock lock(mServiceLock);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001291
Igor Murashkinecf17e82012-10-02 16:05:11 -07001292 int outIndex;
Igor Murashkine7ee7632013-06-11 18:10:18 -07001293 sp<BasicClient> client = findClientUnsafe(remoteBinder, outIndex);
Igor Murashkinecf17e82012-10-02 16:05:11 -07001294
1295 if (client != 0) {
1296 // Found our camera, clear and leave.
1297 LOG1("removeClient: clear camera %d", outIndex);
Igor Murashkinecf17e82012-10-02 16:05:11 -07001298
Ruben Brunkb2119af2014-05-09 19:57:56 -07001299 sp<IBinder> remote = client->getRemote();
1300 if (remote != NULL) {
1301 remote->unlinkToDeath(this);
1302 }
1303
1304 mClient[outIndex].clear();
Igor Murashkin634a5152013-02-20 17:15:11 -08001305 } else {
1306
1307 sp<ProClient> clientPro = findProClientUnsafe(remoteBinder);
1308
1309 if (clientPro != NULL) {
1310 // Found our camera, clear and leave.
1311 LOG1("removeClient: clear pro %p", clientPro.get());
1312
Marco Nelissenf8880202014-11-14 07:58:25 -08001313 IInterface::asBinder(clientPro->getRemoteCallback())->unlinkToDeath(this);
Igor Murashkin634a5152013-02-20 17:15:11 -08001314 }
Igor Murashkinecf17e82012-10-02 16:05:11 -07001315 }
1316
Igor Murashkin634a5152013-02-20 17:15:11 -08001317 LOG1("CameraService::removeClientByRemote X (pid %d)", callingPid);
1318}
1319
1320sp<CameraService::ProClient> CameraService::findProClientUnsafe(
1321 const wp<IBinder>& cameraCallbacksRemote)
1322{
1323 sp<ProClient> clientPro;
1324
1325 for (int i = 0; i < mNumberOfCameras; ++i) {
1326 Vector<size_t> removeIdx;
1327
1328 for (size_t j = 0; j < mProClientList[i].size(); ++j) {
1329 wp<ProClient> cl = mProClientList[i][j];
1330
1331 sp<ProClient> clStrong = cl.promote();
1332 if (clStrong != NULL && clStrong->getRemote() == cameraCallbacksRemote) {
1333 clientPro = clStrong;
1334 break;
1335 } else if (clStrong == NULL) {
1336 // mark to clean up dead ptr
1337 removeIdx.push(j);
1338 }
1339 }
1340
1341 // remove stale ptrs (in reverse so the indices dont change)
1342 for (ssize_t j = (ssize_t)removeIdx.size() - 1; j >= 0; --j) {
1343 mProClientList[i].removeAt(removeIdx[j]);
1344 }
1345
1346 }
1347
1348 return clientPro;
Igor Murashkinecf17e82012-10-02 16:05:11 -07001349}
1350
Igor Murashkine7ee7632013-06-11 18:10:18 -07001351sp<CameraService::BasicClient> CameraService::findClientUnsafe(
Igor Murashkin294d0ec2012-10-05 10:44:57 -07001352 const wp<IBinder>& cameraClient, int& outIndex) {
Igor Murashkine7ee7632013-06-11 18:10:18 -07001353 sp<BasicClient> client;
Igor Murashkinecf17e82012-10-02 16:05:11 -07001354
1355 for (int i = 0; i < mNumberOfCameras; i++) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001356
1357 // This happens when we have already disconnected (or this is
1358 // just another unused camera).
1359 if (mClient[i] == 0) continue;
1360
1361 // Promote mClient. It can fail if we are called from this path:
Igor Murashkin634a5152013-02-20 17:15:11 -08001362 // Client::~Client() -> disconnect() -> removeClientByRemote().
Mathias Agopian65ab4712010-07-14 17:59:35 -07001363 client = mClient[i].promote();
1364
Igor Murashkinecf17e82012-10-02 16:05:11 -07001365 // Clean up stale client entry
1366 if (client == NULL) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001367 mClient[i].clear();
1368 continue;
1369 }
1370
Igor Murashkine7ee7632013-06-11 18:10:18 -07001371 if (cameraClient == client->getRemote()) {
Igor Murashkinecf17e82012-10-02 16:05:11 -07001372 // Found our camera
1373 outIndex = i;
1374 return client;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001375 }
1376 }
1377
Igor Murashkinecf17e82012-10-02 16:05:11 -07001378 outIndex = -1;
1379 return NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001380}
1381
Igor Murashkine7ee7632013-06-11 18:10:18 -07001382CameraService::BasicClient* CameraService::getClientByIdUnsafe(int cameraId) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001383 if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
Keun young Parkd8973a72012-03-28 14:13:09 -07001384 return mClient[cameraId].unsafe_get();
1385}
1386
1387Mutex* CameraService::getClientLockById(int cameraId) {
1388 if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
1389 return &mClientLock[cameraId];
Mathias Agopian65ab4712010-07-14 17:59:35 -07001390}
1391
Igor Murashkin634a5152013-02-20 17:15:11 -08001392sp<CameraService::BasicClient> CameraService::getClientByRemote(
Igor Murashkin294d0ec2012-10-05 10:44:57 -07001393 const wp<IBinder>& cameraClient) {
Igor Murashkinecf17e82012-10-02 16:05:11 -07001394
1395 // Declare this before the lock to make absolutely sure the
1396 // destructor won't be called with the lock held.
Igor Murashkin634a5152013-02-20 17:15:11 -08001397 sp<BasicClient> client;
Igor Murashkinecf17e82012-10-02 16:05:11 -07001398
1399 Mutex::Autolock lock(mServiceLock);
1400
1401 int outIndex;
1402 client = findClientUnsafe(cameraClient, outIndex);
1403
1404 return client;
1405}
1406
Mathias Agopian65ab4712010-07-14 17:59:35 -07001407status_t CameraService::onTransact(
1408 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
1409 // Permission checks
1410 switch (code) {
1411 case BnCameraService::CONNECT:
Igor Murashkin634a5152013-02-20 17:15:11 -08001412 case BnCameraService::CONNECT_PRO:
Eino-Ville Talvala63d877f2014-06-16 19:21:12 -07001413 case BnCameraService::CONNECT_DEVICE:
Zhijun Heb10cdad2014-06-16 16:38:35 -07001414 case BnCameraService::CONNECT_LEGACY:
Mathias Agopian65ab4712010-07-14 17:59:35 -07001415 const int pid = getCallingPid();
1416 const int self_pid = getpid();
1417 if (pid != self_pid) {
1418 // we're called from a different process, do the real check
1419 if (!checkCallingPermission(
1420 String16("android.permission.CAMERA"))) {
1421 const int uid = getCallingUid();
Steve Block29357bc2012-01-06 19:20:56 +00001422 ALOGE("Permission Denial: "
Mathias Agopian65ab4712010-07-14 17:59:35 -07001423 "can't use the camera pid=%d, uid=%d", pid, uid);
1424 return PERMISSION_DENIED;
1425 }
1426 }
1427 break;
1428 }
1429
1430 return BnCameraService::onTransact(code, data, reply, flags);
1431}
1432
1433// The reason we need this busy bit is a new CameraService::connect() request
1434// may come in while the previous Client's destructor has not been run or is
1435// still running. If the last strong reference of the previous Client is gone
1436// but the destructor has not been finished, we should not allow the new Client
1437// to be created because we need to wait for the previous Client to tear down
1438// the hardware first.
1439void CameraService::setCameraBusy(int cameraId) {
1440 android_atomic_write(1, &mBusy[cameraId]);
Igor Murashkinecf17e82012-10-02 16:05:11 -07001441
1442 ALOGV("setCameraBusy cameraId=%d", cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001443}
1444
1445void CameraService::setCameraFree(int cameraId) {
1446 android_atomic_write(0, &mBusy[cameraId]);
Igor Murashkinecf17e82012-10-02 16:05:11 -07001447
1448 ALOGV("setCameraFree cameraId=%d", cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001449}
1450
1451// We share the media players for shutter and recording sound for all clients.
1452// A reference count is kept to determine when we will actually release the
1453// media players.
1454
Chih-Chung Changff4f55c2011-10-17 19:03:12 +08001455MediaPlayer* CameraService::newMediaPlayer(const char *file) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001456 MediaPlayer* mp = new MediaPlayer();
Andreas Huber1b86fe02014-01-29 11:13:26 -08001457 if (mp->setDataSource(NULL /* httpService */, file, NULL) == NO_ERROR) {
Eino-Ville Talvala60a78ac2012-01-05 15:34:53 -08001458 mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001459 mp->prepare();
1460 } else {
Steve Block29357bc2012-01-06 19:20:56 +00001461 ALOGE("Failed to load CameraService sounds: %s", file);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001462 return NULL;
1463 }
1464 return mp;
1465}
1466
1467void CameraService::loadSound() {
1468 Mutex::Autolock lock(mSoundLock);
1469 LOG1("CameraService::loadSound ref=%d", mSoundRef);
1470 if (mSoundRef++) return;
1471
1472 mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
1473 mSoundPlayer[SOUND_RECORDING] = newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");
1474}
1475
1476void CameraService::releaseSound() {
1477 Mutex::Autolock lock(mSoundLock);
1478 LOG1("CameraService::releaseSound ref=%d", mSoundRef);
1479 if (--mSoundRef) return;
1480
1481 for (int i = 0; i < NUM_SOUNDS; i++) {
1482 if (mSoundPlayer[i] != 0) {
1483 mSoundPlayer[i]->disconnect();
1484 mSoundPlayer[i].clear();
1485 }
1486 }
1487}
1488
1489void CameraService::playSound(sound_kind kind) {
1490 LOG1("playSound(%d)", kind);
1491 Mutex::Autolock lock(mSoundLock);
1492 sp<MediaPlayer> player = mSoundPlayer[kind];
1493 if (player != 0) {
Chih-Chung Chang8888a752011-10-20 10:47:26 +08001494 player->seekTo(0);
1495 player->start();
Mathias Agopian65ab4712010-07-14 17:59:35 -07001496 }
1497}
1498
1499// ----------------------------------------------------------------------------
1500
1501CameraService::Client::Client(const sp<CameraService>& cameraService,
Wu-cheng Lib7a67942010-08-17 15:45:37 -07001502 const sp<ICameraClient>& cameraClient,
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001503 const String16& clientPackageName,
1504 int cameraId, int cameraFacing,
1505 int clientPid, uid_t clientUid,
1506 int servicePid) :
Eino-Ville Talvalae992e752014-11-07 16:17:48 -08001507 CameraService::BasicClient(cameraService,
Marco Nelissenf8880202014-11-14 07:58:25 -08001508 IInterface::asBinder(cameraClient),
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001509 clientPackageName,
1510 cameraId, cameraFacing,
1511 clientPid, clientUid,
1512 servicePid)
Igor Murashkin634a5152013-02-20 17:15:11 -08001513{
Mathias Agopian65ab4712010-07-14 17:59:35 -07001514 int callingPid = getCallingPid();
Wu-cheng Li2fd24402012-02-23 19:01:00 -08001515 LOG1("Client::Client E (pid %d, id %d)", callingPid, cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001516
Igor Murashkin44cfcf02013-03-01 16:22:28 -08001517 mRemoteCallback = cameraClient;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001518
Mathias Agopian65ab4712010-07-14 17:59:35 -07001519 cameraService->setCameraBusy(cameraId);
1520 cameraService->loadSound();
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001521
Wu-cheng Li2fd24402012-02-23 19:01:00 -08001522 LOG1("Client::Client X (pid %d, id %d)", callingPid, cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001523}
1524
Mathias Agopian65ab4712010-07-14 17:59:35 -07001525// tear down the client
1526CameraService::Client::~Client() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -07001527 ALOGV("~Client");
Igor Murashkin634a5152013-02-20 17:15:11 -08001528 mDestructionStarted = true;
1529
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001530 mCameraService->releaseSound();
Igor Murashkin036bc3e2012-10-08 15:09:46 -07001531 // unconditionally disconnect. function is idempotent
1532 Client::disconnect();
Mathias Agopian65ab4712010-07-14 17:59:35 -07001533}
1534
Igor Murashkin634a5152013-02-20 17:15:11 -08001535CameraService::BasicClient::BasicClient(const sp<CameraService>& cameraService,
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001536 const sp<IBinder>& remoteCallback,
1537 const String16& clientPackageName,
1538 int cameraId, int cameraFacing,
1539 int clientPid, uid_t clientUid,
1540 int servicePid):
1541 mClientPackageName(clientPackageName)
Igor Murashkin634a5152013-02-20 17:15:11 -08001542{
1543 mCameraService = cameraService;
Igor Murashkin44cfcf02013-03-01 16:22:28 -08001544 mRemoteBinder = remoteCallback;
Igor Murashkin634a5152013-02-20 17:15:11 -08001545 mCameraId = cameraId;
1546 mCameraFacing = cameraFacing;
1547 mClientPid = clientPid;
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001548 mClientUid = clientUid;
Igor Murashkin634a5152013-02-20 17:15:11 -08001549 mServicePid = servicePid;
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001550 mOpsActive = false;
Igor Murashkin634a5152013-02-20 17:15:11 -08001551 mDestructionStarted = false;
1552}
1553
1554CameraService::BasicClient::~BasicClient() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -07001555 ALOGV("~BasicClient");
Igor Murashkin634a5152013-02-20 17:15:11 -08001556 mDestructionStarted = true;
1557}
1558
1559void CameraService::BasicClient::disconnect() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -07001560 ALOGV("BasicClient::disconnect");
Igor Murashkin44cfcf02013-03-01 16:22:28 -08001561 mCameraService->removeClientByRemote(mRemoteBinder);
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001562
1563 finishCameraOps();
Igor Murashkincba2c162013-03-20 15:56:31 -07001564 // client shouldn't be able to call into us anymore
1565 mClientPid = 0;
Igor Murashkin634a5152013-02-20 17:15:11 -08001566}
1567
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001568status_t CameraService::BasicClient::startCameraOps() {
1569 int32_t res;
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001570 // Notify app ops that the camera is not available
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001571 mOpsCallback = new OpsCallback(this);
1572
Igor Murashkine6800ce2013-03-04 17:25:57 -08001573 {
1574 ALOGV("%s: Start camera ops, package name = %s, client UID = %d",
1575 __FUNCTION__, String8(mClientPackageName).string(), mClientUid);
1576 }
1577
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001578 mAppOpsManager.startWatchingMode(AppOpsManager::OP_CAMERA,
1579 mClientPackageName, mOpsCallback);
1580 res = mAppOpsManager.startOp(AppOpsManager::OP_CAMERA,
1581 mClientUid, mClientPackageName);
1582
1583 if (res != AppOpsManager::MODE_ALLOWED) {
1584 ALOGI("Camera %d: Access for \"%s\" has been revoked",
1585 mCameraId, String8(mClientPackageName).string());
1586 return PERMISSION_DENIED;
1587 }
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001588
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001589 mOpsActive = true;
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001590
1591 // Transition device availability listeners from PRESENT -> NOT_AVAILABLE
1592 mCameraService->updateStatus(ICameraServiceListener::STATUS_NOT_AVAILABLE,
1593 mCameraId);
1594
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001595 return OK;
1596}
1597
1598status_t CameraService::BasicClient::finishCameraOps() {
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001599 // Check if startCameraOps succeeded, and if so, finish the camera op
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001600 if (mOpsActive) {
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001601 // Notify app ops that the camera is available again
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001602 mAppOpsManager.finishOp(AppOpsManager::OP_CAMERA, mClientUid,
1603 mClientPackageName);
1604 mOpsActive = false;
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001605
1606 // Notify device availability listeners that this camera is available
1607 // again
1608
1609 StatusVector rejectSourceStates;
1610 rejectSourceStates.push_back(ICameraServiceListener::STATUS_NOT_PRESENT);
1611 rejectSourceStates.push_back(ICameraServiceListener::STATUS_ENUMERATING);
1612
1613 // Transition to PRESENT if the camera is not in either of above 2
1614 // states
1615 mCameraService->updateStatus(ICameraServiceListener::STATUS_PRESENT,
1616 mCameraId,
1617 &rejectSourceStates);
1618
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001619 }
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001620 // Always stop watching, even if no camera op is active
Eino-Ville Talvalae992e752014-11-07 16:17:48 -08001621 if (mOpsCallback != NULL) {
1622 mAppOpsManager.stopWatchingMode(mOpsCallback);
1623 }
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001624 mOpsCallback.clear();
1625
1626 return OK;
1627}
1628
1629void CameraService::BasicClient::opChanged(int32_t op, const String16& packageName) {
1630 String8 name(packageName);
1631 String8 myName(mClientPackageName);
1632
1633 if (op != AppOpsManager::OP_CAMERA) {
1634 ALOGW("Unexpected app ops notification received: %d", op);
1635 return;
1636 }
1637
1638 int32_t res;
1639 res = mAppOpsManager.checkOp(AppOpsManager::OP_CAMERA,
1640 mClientUid, mClientPackageName);
1641 ALOGV("checkOp returns: %d, %s ", res,
1642 res == AppOpsManager::MODE_ALLOWED ? "ALLOWED" :
1643 res == AppOpsManager::MODE_IGNORED ? "IGNORED" :
1644 res == AppOpsManager::MODE_ERRORED ? "ERRORED" :
1645 "UNKNOWN");
1646
1647 if (res != AppOpsManager::MODE_ALLOWED) {
1648 ALOGI("Camera %d: Access for \"%s\" revoked", mCameraId,
1649 myName.string());
1650 // Reset the client PID to allow server-initiated disconnect,
1651 // and to prevent further calls by client.
1652 mClientPid = getCallingPid();
Jianing Weicb0652e2014-03-12 18:29:36 -07001653 CaptureResultExtras resultExtras; // a dummy result (invalid)
1654 notifyError(ICameraDeviceCallbacks::ERROR_CAMERA_SERVICE, resultExtras);
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001655 disconnect();
1656 }
1657}
1658
Mathias Agopian65ab4712010-07-14 17:59:35 -07001659// ----------------------------------------------------------------------------
1660
Keun young Parkd8973a72012-03-28 14:13:09 -07001661Mutex* CameraService::Client::getClientLockFromCookie(void* user) {
Kévin PETIT377b2ec2014-02-03 12:35:36 +00001662 return gCameraService->getClientLockById((int)(intptr_t) user);
Keun young Parkd8973a72012-03-28 14:13:09 -07001663}
1664
1665// Provide client pointer for callbacks. Client lock returned from getClientLockFromCookie should
1666// be acquired for this to be safe
1667CameraService::Client* CameraService::Client::getClientFromCookie(void* user) {
Kévin PETIT377b2ec2014-02-03 12:35:36 +00001668 BasicClient *basicClient = gCameraService->getClientByIdUnsafe((int)(intptr_t) user);
Igor Murashkine7ee7632013-06-11 18:10:18 -07001669 // OK: only CameraClient calls this, and they already cast anyway.
1670 Client* client = static_cast<Client*>(basicClient);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001671
1672 // This could happen if the Client is in the process of shutting down (the
1673 // last strong reference is gone, but the destructor hasn't finished
1674 // stopping the hardware).
Keun young Parkd8973a72012-03-28 14:13:09 -07001675 if (client == NULL) return NULL;
1676
1677 // destruction already started, so should not be accessed
1678 if (client->mDestructionStarted) return NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001679
Mathias Agopian65ab4712010-07-14 17:59:35 -07001680 return client;
1681}
1682
Jianing Weicb0652e2014-03-12 18:29:36 -07001683void CameraService::Client::notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode,
1684 const CaptureResultExtras& resultExtras) {
Igor Murashkin44cfcf02013-03-01 16:22:28 -08001685 mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_RELEASED, 0);
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001686}
1687
Igor Murashkin036bc3e2012-10-08 15:09:46 -07001688// NOTE: function is idempotent
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001689void CameraService::Client::disconnect() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -07001690 ALOGV("Client::disconnect");
Igor Murashkin634a5152013-02-20 17:15:11 -08001691 BasicClient::disconnect();
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001692 mCameraService->setCameraFree(mCameraId);
Wu-cheng Lie09591e2010-10-14 20:17:44 +08001693}
1694
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001695CameraService::Client::OpsCallback::OpsCallback(wp<BasicClient> client):
1696 mClient(client) {
1697}
1698
1699void CameraService::Client::OpsCallback::opChanged(int32_t op,
1700 const String16& packageName) {
1701 sp<BasicClient> client = mClient.promote();
1702 if (client != NULL) {
1703 client->opChanged(op, packageName);
1704 }
1705}
1706
Mathias Agopian65ab4712010-07-14 17:59:35 -07001707// ----------------------------------------------------------------------------
Igor Murashkin634a5152013-02-20 17:15:11 -08001708// IProCamera
1709// ----------------------------------------------------------------------------
1710
1711CameraService::ProClient::ProClient(const sp<CameraService>& cameraService,
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001712 const sp<IProCameraCallbacks>& remoteCallback,
1713 const String16& clientPackageName,
1714 int cameraId,
1715 int cameraFacing,
1716 int clientPid,
1717 uid_t clientUid,
1718 int servicePid)
Marco Nelissenf8880202014-11-14 07:58:25 -08001719 : CameraService::BasicClient(cameraService, IInterface::asBinder(remoteCallback),
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001720 clientPackageName, cameraId, cameraFacing,
1721 clientPid, clientUid, servicePid)
Igor Murashkin634a5152013-02-20 17:15:11 -08001722{
1723 mRemoteCallback = remoteCallback;
1724}
1725
1726CameraService::ProClient::~ProClient() {
Igor Murashkin634a5152013-02-20 17:15:11 -08001727}
1728
Jianing Weicb0652e2014-03-12 18:29:36 -07001729void CameraService::ProClient::notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode,
1730 const CaptureResultExtras& resultExtras) {
Igor Murashkine6800ce2013-03-04 17:25:57 -08001731 mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_RELEASED, 0);
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001732}
1733
Igor Murashkin634a5152013-02-20 17:15:11 -08001734// ----------------------------------------------------------------------------
Mathias Agopian65ab4712010-07-14 17:59:35 -07001735
1736static const int kDumpLockRetries = 50;
1737static const int kDumpLockSleep = 60000;
1738
1739static bool tryLock(Mutex& mutex)
1740{
1741 bool locked = false;
1742 for (int i = 0; i < kDumpLockRetries; ++i) {
1743 if (mutex.tryLock() == NO_ERROR) {
1744 locked = true;
1745 break;
1746 }
1747 usleep(kDumpLockSleep);
1748 }
1749 return locked;
1750}
1751
1752status_t CameraService::dump(int fd, const Vector<String16>& args) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001753 String8 result;
1754 if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -07001755 result.appendFormat("Permission Denial: "
Mathias Agopian65ab4712010-07-14 17:59:35 -07001756 "can't dump CameraService from pid=%d, uid=%d\n",
1757 getCallingPid(),
1758 getCallingUid());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001759 write(fd, result.string(), result.size());
1760 } else {
1761 bool locked = tryLock(mServiceLock);
1762 // failed to lock - CameraService is probably deadlocked
1763 if (!locked) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -07001764 result.append("CameraService may be deadlocked\n");
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001765 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001766 }
1767
1768 bool hasClient = false;
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001769 if (!mModule) {
1770 result = String8::format("No camera module available!\n");
1771 write(fd, result.string(), result.size());
Kalle Lampila6ec3a152013-04-30 15:27:19 +03001772 if (locked) mServiceLock.unlock();
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001773 return NO_ERROR;
1774 }
1775
Yin-Chia Yehe074a932015-01-30 10:29:02 -08001776 const hw_module_t* common = mModule->getRawModule();
1777 result = String8::format("Camera module HAL API version: 0x%x\n", common->hal_api_version);
1778 result.appendFormat("Camera module API version: 0x%x\n", common->module_api_version);
1779 result.appendFormat("Camera module name: %s\n", common->name);
1780 result.appendFormat("Camera module author: %s\n", common->author);
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001781 result.appendFormat("Number of camera devices: %d\n\n", mNumberOfCameras);
Ruben Brunkf81648e2014-04-17 16:14:57 -07001782
1783 sp<VendorTagDescriptor> desc = VendorTagDescriptor::getGlobalVendorTagDescriptor();
1784 if (desc == NULL) {
1785 result.appendFormat("Vendor tags left unimplemented.\n");
1786 } else {
1787 result.appendFormat("Vendor tag definitions:\n");
1788 }
1789
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001790 write(fd, result.string(), result.size());
Ruben Brunkf81648e2014-04-17 16:14:57 -07001791
1792 if (desc != NULL) {
1793 desc->dump(fd, /*verbosity*/2, /*indentation*/4);
1794 }
1795
Mathias Agopian65ab4712010-07-14 17:59:35 -07001796 for (int i = 0; i < mNumberOfCameras; i++) {
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001797 result = String8::format("Camera %d static information:\n", i);
1798 camera_info info;
1799
Yin-Chia Yehe074a932015-01-30 10:29:02 -08001800 status_t rc = mModule->getCameraInfo(i, &info);
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001801 if (rc != OK) {
1802 result.appendFormat(" Error reading static information!\n");
1803 write(fd, result.string(), result.size());
1804 } else {
1805 result.appendFormat(" Facing: %s\n",
1806 info.facing == CAMERA_FACING_BACK ? "BACK" : "FRONT");
1807 result.appendFormat(" Orientation: %d\n", info.orientation);
1808 int deviceVersion;
Yin-Chia Yehe074a932015-01-30 10:29:02 -08001809 if (common->module_api_version < CAMERA_MODULE_API_VERSION_2_0) {
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001810 deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
1811 } else {
1812 deviceVersion = info.device_version;
1813 }
1814 result.appendFormat(" Device version: 0x%x\n", deviceVersion);
1815 if (deviceVersion >= CAMERA_DEVICE_API_VERSION_2_0) {
1816 result.appendFormat(" Device static metadata:\n");
1817 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -07001818 dump_indented_camera_metadata(info.static_camera_characteristics,
Ruben Brunkf81648e2014-04-17 16:14:57 -07001819 fd, /*verbosity*/2, /*indentation*/4);
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001820 } else {
1821 write(fd, result.string(), result.size());
1822 }
1823 }
1824
Igor Murashkine7ee7632013-06-11 18:10:18 -07001825 sp<BasicClient> client = mClient[i].promote();
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001826 if (client == 0) {
1827 result = String8::format(" Device is closed, no client instance\n");
1828 write(fd, result.string(), result.size());
1829 continue;
1830 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001831 hasClient = true;
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001832 result = String8::format(" Device is open. Client instance dump:\n");
1833 write(fd, result.string(), result.size());
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001834 client->dump(fd, args);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001835 }
1836 if (!hasClient) {
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001837 result = String8::format("\nNo active camera clients yet.\n");
1838 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001839 }
1840
1841 if (locked) mServiceLock.unlock();
1842
Igor Murashkinff3e31d2013-10-23 16:40:06 -07001843 // Dump camera traces if there were any
1844 write(fd, "\n", 1);
1845 camera3::CameraTraces::dump(fd, args);
1846
Mathias Agopian65ab4712010-07-14 17:59:35 -07001847 // change logging level
1848 int n = args.size();
1849 for (int i = 0; i + 1 < n; i++) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -07001850 String16 verboseOption("-v");
1851 if (args[i] == verboseOption) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001852 String8 levelStr(args[i+1]);
1853 int level = atoi(levelStr.string());
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001854 result = String8::format("\nSetting log level to %d.\n", level);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001855 setLogLevel(level);
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001856 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001857 }
1858 }
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001859
Mathias Agopian65ab4712010-07-14 17:59:35 -07001860 }
1861 return NO_ERROR;
1862}
1863
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001864void CameraService::handleTorchClientBinderDied(const wp<IBinder> &who) {
1865 Mutex::Autolock al(mTorchStatusMutex);
1866 for (size_t i = 0; i < mTorchClientMap.size(); i++) {
1867 if (mTorchClientMap[i] == who) {
1868 // turn off the torch mode that was turned on by dead client
1869 String16 cameraId = mTorchClientMap.keyAt(i);
1870 mFlashlight->setTorchMode(cameraId, false);
1871 mTorchClientMap.removeItemsAt(i);
1872
1873 // notify torch mode was turned off
1874 onTorchStatusChangedLocked(cameraId,
1875 ICameraServiceListener::TORCH_STATUS_OFF);
1876 break;
1877 }
1878 }
1879}
1880
Igor Murashkinecf17e82012-10-02 16:05:11 -07001881/*virtual*/void CameraService::binderDied(
1882 const wp<IBinder> &who) {
1883
Igor Murashkin294d0ec2012-10-05 10:44:57 -07001884 /**
1885 * While tempting to promote the wp<IBinder> into a sp,
1886 * it's actually not supported by the binder driver
1887 */
1888
Igor Murashkinecf17e82012-10-02 16:05:11 -07001889 ALOGV("java clients' binder died");
1890
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001891 // check torch client
1892 handleTorchClientBinderDied(who);
1893
1894 // check camera device client
Igor Murashkin634a5152013-02-20 17:15:11 -08001895 sp<BasicClient> cameraClient = getClientByRemote(who);
Igor Murashkinecf17e82012-10-02 16:05:11 -07001896
Igor Murashkin294d0ec2012-10-05 10:44:57 -07001897 if (cameraClient == 0) {
Igor Murashkinecf17e82012-10-02 16:05:11 -07001898 ALOGV("java clients' binder death already cleaned up (normal case)");
1899 return;
1900 }
1901
Igor Murashkinecf17e82012-10-02 16:05:11 -07001902 ALOGW("Disconnecting camera client %p since the binder for it "
1903 "died (this pid %d)", cameraClient.get(), getCallingPid());
1904
1905 cameraClient->disconnect();
1906
1907}
1908
Igor Murashkinbfc99152013-02-27 12:55:20 -08001909void CameraService::updateStatus(ICameraServiceListener::Status status,
Igor Murashkin93747b92013-05-01 15:42:20 -07001910 int32_t cameraId,
1911 const StatusVector *rejectSourceStates) {
Igor Murashkinbfc99152013-02-27 12:55:20 -08001912 // do not lock mServiceLock here or can get into a deadlock from
1913 // connect() -> ProClient::disconnect -> updateStatus
1914 Mutex::Autolock lock(mStatusMutex);
Igor Murashkinbfc99152013-02-27 12:55:20 -08001915
1916 ICameraServiceListener::Status oldStatus = mStatusList[cameraId];
1917
1918 mStatusList[cameraId] = status;
1919
1920 if (oldStatus != status) {
1921 ALOGV("%s: Status has changed for camera ID %d from 0x%x to 0x%x",
1922 __FUNCTION__, cameraId, (uint32_t)oldStatus, (uint32_t)status);
1923
Igor Murashkincba2c162013-03-20 15:56:31 -07001924 if (oldStatus == ICameraServiceListener::STATUS_NOT_PRESENT &&
1925 (status != ICameraServiceListener::STATUS_PRESENT &&
1926 status != ICameraServiceListener::STATUS_ENUMERATING)) {
1927
1928 ALOGW("%s: From NOT_PRESENT can only transition into PRESENT"
1929 " or ENUMERATING", __FUNCTION__);
1930 mStatusList[cameraId] = oldStatus;
1931 return;
1932 }
1933
Igor Murashkin93747b92013-05-01 15:42:20 -07001934 if (rejectSourceStates != NULL) {
1935 const StatusVector &rejectList = *rejectSourceStates;
1936 StatusVector::const_iterator it = rejectList.begin();
1937
1938 /**
1939 * Sometimes we want to conditionally do a transition.
1940 * For example if a client disconnects, we want to go to PRESENT
1941 * only if we weren't already in NOT_PRESENT or ENUMERATING.
1942 */
1943 for (; it != rejectList.end(); ++it) {
1944 if (oldStatus == *it) {
1945 ALOGV("%s: Rejecting status transition for Camera ID %d, "
1946 " since the source state was was in one of the bad "
1947 " states.", __FUNCTION__, cameraId);
1948 mStatusList[cameraId] = oldStatus;
1949 return;
1950 }
1951 }
1952 }
1953
Igor Murashkinbfc99152013-02-27 12:55:20 -08001954 /**
1955 * ProClients lose their exclusive lock.
1956 * - Done before the CameraClient can initialize the HAL device,
1957 * since we want to be able to close it before they get to initialize
1958 */
1959 if (status == ICameraServiceListener::STATUS_NOT_AVAILABLE) {
1960 Vector<wp<ProClient> > proClients(mProClientList[cameraId]);
1961 Vector<wp<ProClient> >::const_iterator it;
1962
1963 for (it = proClients.begin(); it != proClients.end(); ++it) {
1964 sp<ProClient> proCl = it->promote();
1965 if (proCl.get() != NULL) {
1966 proCl->onExclusiveLockStolen();
1967 }
1968 }
1969 }
1970
1971 Vector<sp<ICameraServiceListener> >::const_iterator it;
1972 for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
1973 (*it)->onStatusChanged(status, cameraId);
1974 }
1975 }
1976}
1977
Igor Murashkincba2c162013-03-20 15:56:31 -07001978ICameraServiceListener::Status CameraService::getStatus(int cameraId) const {
1979 if (cameraId < 0 || cameraId >= MAX_CAMERAS) {
1980 ALOGE("%s: Invalid camera ID %d", __FUNCTION__, cameraId);
1981 return ICameraServiceListener::STATUS_UNKNOWN;
1982 }
1983
1984 Mutex::Autolock al(mStatusMutex);
1985 return mStatusList[cameraId];
1986}
1987
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001988ICameraServiceListener::TorchStatus CameraService::getTorchStatusLocked(
1989 const String16& cameraId) const {
1990 ssize_t index = mTorchStatusMap.indexOfKey(cameraId);
1991 if (index == NAME_NOT_FOUND) {
1992 return ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE;
1993 }
1994
1995 return mTorchStatusMap.valueAt(index);
1996}
1997
1998status_t CameraService::setTorchStatusLocked(const String16& cameraId,
1999 ICameraServiceListener::TorchStatus status) {
2000 ssize_t index = mTorchStatusMap.indexOfKey(cameraId);
2001 if (index == NAME_NOT_FOUND) {
2002 return BAD_VALUE;
2003 }
2004 ICameraServiceListener::TorchStatus& item =
2005 mTorchStatusMap.editValueAt(index);
2006 item = status;
2007
2008 return OK;
2009}
2010
Mathias Agopian65ab4712010-07-14 17:59:35 -07002011}; // namespace android