blob: 488fc42d38bc1385af6636cb4427acb462fe79d1 [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>
Mathias Agopiandf712ea2012-02-25 18:48:35 -080032#include <gui/Surface.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070033#include <hardware/hardware.h>
34#include <media/AudioSystem.h>
Andreas Huber1b86fe02014-01-29 11:13:26 -080035#include <media/IMediaHTTPService.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070036#include <media/mediaplayer.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070037#include <utils/Errors.h>
38#include <utils/Log.h>
39#include <utils/String16.h>
Ruben Brunkd1176ef2014-02-21 10:51:38 -080040#include <utils/Trace.h>
41#include <system/camera_vendor_tags.h>
Ruben Brunkb2119af2014-05-09 19:57:56 -070042#include <system/camera_metadata.h>
43#include <system/camera.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070044
45#include "CameraService.h"
Eino-Ville Talvala7b82efe2013-07-25 17:12:35 -070046#include "api1/CameraClient.h"
47#include "api1/Camera2Client.h"
48#include "api_pro/ProCamera2Client.h"
49#include "api2/CameraDeviceClient.h"
Igor Murashkinff3e31d2013-10-23 16:40:06 -070050#include "utils/CameraTraces.h"
Igor Murashkin98e24722013-06-19 19:51:04 -070051#include "CameraDeviceFactory.h"
Mathias Agopian65ab4712010-07-14 17:59:35 -070052
53namespace android {
54
55// ----------------------------------------------------------------------------
56// Logging support -- this is for debugging only
57// Use "adb shell dumpsys media.camera -v 1" to change it.
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -070058volatile int32_t gLogLevel = 0;
Mathias Agopian65ab4712010-07-14 17:59:35 -070059
Steve Blockb8a80522011-12-20 16:23:08 +000060#define LOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__);
61#define LOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__);
Mathias Agopian65ab4712010-07-14 17:59:35 -070062
63static void setLogLevel(int level) {
64 android_atomic_write(level, &gLogLevel);
65}
66
67// ----------------------------------------------------------------------------
68
69static int getCallingPid() {
70 return IPCThreadState::self()->getCallingPid();
71}
72
73static int getCallingUid() {
74 return IPCThreadState::self()->getCallingUid();
75}
76
Igor Murashkincba2c162013-03-20 15:56:31 -070077extern "C" {
78static void camera_device_status_change(
79 const struct camera_module_callbacks* callbacks,
80 int camera_id,
81 int new_status) {
82 sp<CameraService> cs = const_cast<CameraService*>(
83 static_cast<const CameraService*>(callbacks));
84
85 cs->onDeviceStatusChanged(
86 camera_id,
87 new_status);
88}
Chien-Yu Chen3068d732015-02-09 13:29:57 -080089
90static void torch_mode_status_change(
91 const struct camera_module_callbacks* callbacks,
92 const char* camera_id,
93 int new_status) {
94 if (!callbacks || !camera_id) {
95 ALOGE("%s invalid parameters. callbacks %p, camera_id %p", __FUNCTION__,
96 callbacks, camera_id);
97 }
98 sp<CameraService> cs = const_cast<CameraService*>(
99 static_cast<const CameraService*>(callbacks));
100
101 ICameraServiceListener::TorchStatus status;
102 switch (new_status) {
103 case TORCH_MODE_STATUS_AVAILABLE:
104 status = ICameraServiceListener::TORCH_STATUS_AVAILABLE;
105 break;
106 case TORCH_MODE_STATUS_RESOURCE_BUSY:
107 status = ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE;
108 break;
109 case TORCH_MODE_STATUS_OFF:
110 status = ICameraServiceListener::TORCH_STATUS_OFF;
111 break;
112 default:
113 ALOGE("Unknown torch status %d", new_status);
114 return;
115 }
116
117 cs->onTorchStatusChanged(
118 String16(camera_id),
119 status);
120}
Igor Murashkincba2c162013-03-20 15:56:31 -0700121} // extern "C"
122
Mathias Agopian65ab4712010-07-14 17:59:35 -0700123// ----------------------------------------------------------------------------
124
125// This is ugly and only safe if we never re-create the CameraService, but
126// should be ok for now.
127static CameraService *gCameraService;
128
129CameraService::CameraService()
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800130 :mSoundRef(0), mModule(0), mFlashlight(0)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700131{
Steve Blockdf64d152012-01-04 20:05:49 +0000132 ALOGI("CameraService started (pid=%d)", getpid());
Mathias Agopian65ab4712010-07-14 17:59:35 -0700133 gCameraService = this;
Igor Murashkinbfc99152013-02-27 12:55:20 -0800134
135 for (size_t i = 0; i < MAX_CAMERAS; ++i) {
Igor Murashkincba2c162013-03-20 15:56:31 -0700136 mStatusList[i] = ICameraServiceListener::STATUS_PRESENT;
Igor Murashkinbfc99152013-02-27 12:55:20 -0800137 }
Igor Murashkincba2c162013-03-20 15:56:31 -0700138
139 this->camera_device_status_change = android::camera_device_status_change;
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800140 this->torch_mode_status_change = android::torch_mode_status_change;
141
Mathias Agopian65ab4712010-07-14 17:59:35 -0700142}
143
Iliyan Malchev8951a972011-04-14 16:55:59 -0700144void CameraService::onFirstRef()
145{
Igor Murashkin634a5152013-02-20 17:15:11 -0800146 LOG1("CameraService::onFirstRef");
147
Iliyan Malchev8951a972011-04-14 16:55:59 -0700148 BnCameraService::onFirstRef();
149
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800150 camera_module_t *rawModule;
Iliyan Malchev8951a972011-04-14 16:55:59 -0700151 if (hw_get_module(CAMERA_HARDWARE_MODULE_ID,
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800152 (const hw_module_t **)&rawModule) < 0) {
Steve Block29357bc2012-01-06 19:20:56 +0000153 ALOGE("Could not load camera HAL module");
Iliyan Malchev8951a972011-04-14 16:55:59 -0700154 mNumberOfCameras = 0;
155 }
156 else {
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800157 mModule = new CameraModule(rawModule);
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800158 mFlashlight = new CameraFlashlight(*mModule, *this);
159
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800160 const hw_module_t *common = mModule->getRawModule();
161 ALOGI("Loaded \"%s\" camera module", common->name);
162 mNumberOfCameras = mModule->getNumberOfCameras();
Iliyan Malchev8951a972011-04-14 16:55:59 -0700163 if (mNumberOfCameras > MAX_CAMERAS) {
Steve Block29357bc2012-01-06 19:20:56 +0000164 ALOGE("Number of cameras(%d) > MAX_CAMERAS(%d).",
Iliyan Malchev8951a972011-04-14 16:55:59 -0700165 mNumberOfCameras, MAX_CAMERAS);
166 mNumberOfCameras = MAX_CAMERAS;
167 }
168 for (int i = 0; i < mNumberOfCameras; i++) {
169 setCameraFree(i);
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800170
171 String16 cameraName = String16(String8::format("%d", i));
172 if (mFlashlight->hasFlashUnit(cameraName)) {
173 mTorchStatusMap.add(cameraName,
174 ICameraServiceListener::TORCH_STATUS_AVAILABLE);
175 }
Iliyan Malchev8951a972011-04-14 16:55:59 -0700176 }
Igor Murashkincba2c162013-03-20 15:56:31 -0700177
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800178 if (common->module_api_version >= CAMERA_MODULE_API_VERSION_2_1) {
179 mModule->setCallbacks(this);
Igor Murashkincba2c162013-03-20 15:56:31 -0700180 }
Igor Murashkin98e24722013-06-19 19:51:04 -0700181
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800182 VendorTagDescriptor::clearGlobalVendorTagDescriptor();
183
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800184 if (common->module_api_version >= CAMERA_MODULE_API_VERSION_2_2) {
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800185 setUpVendorTags();
186 }
187
Igor Murashkin98e24722013-06-19 19:51:04 -0700188 CameraDeviceFactory::registerService(this);
Iliyan Malchev8951a972011-04-14 16:55:59 -0700189 }
190}
191
Mathias Agopian65ab4712010-07-14 17:59:35 -0700192CameraService::~CameraService() {
193 for (int i = 0; i < mNumberOfCameras; i++) {
194 if (mBusy[i]) {
Steve Block29357bc2012-01-06 19:20:56 +0000195 ALOGE("camera %d is still in use in destructor!", i);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700196 }
197 }
198
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800199 if (mModule) {
200 delete mModule;
201 }
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800202 VendorTagDescriptor::clearGlobalVendorTagDescriptor();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700203 gCameraService = NULL;
204}
205
Igor Murashkincba2c162013-03-20 15:56:31 -0700206void CameraService::onDeviceStatusChanged(int cameraId,
207 int newStatus)
208{
209 ALOGI("%s: Status changed for cameraId=%d, newStatus=%d", __FUNCTION__,
210 cameraId, newStatus);
211
212 if (cameraId < 0 || cameraId >= MAX_CAMERAS) {
213 ALOGE("%s: Bad camera ID %d", __FUNCTION__, cameraId);
214 return;
215 }
216
217 if ((int)getStatus(cameraId) == newStatus) {
218 ALOGE("%s: State transition to the same status 0x%x not allowed",
219 __FUNCTION__, (uint32_t)newStatus);
220 return;
221 }
222
223 /* don't do this in updateStatus
224 since it is also called from connect and we could get into a deadlock */
225 if (newStatus == CAMERA_DEVICE_STATUS_NOT_PRESENT) {
226 Vector<sp<BasicClient> > clientsToDisconnect;
227 {
228 Mutex::Autolock al(mServiceLock);
229
Ruben Brunkb2119af2014-05-09 19:57:56 -0700230 /* Remove cached parameters from shim cache */
231 mShimParams.removeItem(cameraId);
232
Igor Murashkincba2c162013-03-20 15:56:31 -0700233 /* Find all clients that we need to disconnect */
Igor Murashkine7ee7632013-06-11 18:10:18 -0700234 sp<BasicClient> client = mClient[cameraId].promote();
Igor Murashkincba2c162013-03-20 15:56:31 -0700235 if (client.get() != NULL) {
236 clientsToDisconnect.push_back(client);
237 }
238
239 int i = cameraId;
240 for (size_t j = 0; j < mProClientList[i].size(); ++j) {
241 sp<ProClient> cl = mProClientList[i][j].promote();
242 if (cl != NULL) {
243 clientsToDisconnect.push_back(cl);
244 }
245 }
246 }
247
248 /* now disconnect them. don't hold the lock
249 or we can get into a deadlock */
250
251 for (size_t i = 0; i < clientsToDisconnect.size(); ++i) {
252 sp<BasicClient> client = clientsToDisconnect[i];
253
254 client->disconnect();
255 /**
256 * The remote app will no longer be able to call methods on the
257 * client since the client PID will be reset to 0
258 */
259 }
260
Colin Crosse5729fa2014-03-21 15:04:25 -0700261 ALOGV("%s: After unplug, disconnected %zu clients",
Igor Murashkincba2c162013-03-20 15:56:31 -0700262 __FUNCTION__, clientsToDisconnect.size());
263 }
264
265 updateStatus(
266 static_cast<ICameraServiceListener::Status>(newStatus), cameraId);
267
268}
269
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800270void CameraService::onTorchStatusChanged(const String16& cameraId,
271 ICameraServiceListener::TorchStatus newStatus) {
272 Mutex::Autolock al(mTorchStatusMutex);
273 onTorchStatusChangedLocked(cameraId, newStatus);
274}
275
276void CameraService::onTorchStatusChangedLocked(const String16& cameraId,
277 ICameraServiceListener::TorchStatus newStatus) {
278 ALOGI("%s: Torch status changed for cameraId=%s, newStatus=%d",
279 __FUNCTION__, cameraId.string(), newStatus);
280
281 if (getTorchStatusLocked(cameraId) == newStatus) {
282 ALOGE("%s: Torch state transition to the same status 0x%x not allowed",
283 __FUNCTION__, (uint32_t)newStatus);
284 return;
285 }
286
287 status_t res = setTorchStatusLocked(cameraId, newStatus);
288 if (res) {
289 ALOGE("%s: Failed to set the torch status", __FUNCTION__,
290 (uint32_t)newStatus);
291 return;
292 }
293
294 Vector<sp<ICameraServiceListener> >::const_iterator it;
295 for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
296 (*it)->onTorchStatusChanged(newStatus, cameraId);
297 }
298}
299
300
Mathias Agopian65ab4712010-07-14 17:59:35 -0700301int32_t CameraService::getNumberOfCameras() {
302 return mNumberOfCameras;
303}
304
305status_t CameraService::getCameraInfo(int cameraId,
306 struct CameraInfo* cameraInfo) {
Iliyan Malchev8951a972011-04-14 16:55:59 -0700307 if (!mModule) {
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700308 return -ENODEV;
Iliyan Malchev8951a972011-04-14 16:55:59 -0700309 }
310
Mathias Agopian65ab4712010-07-14 17:59:35 -0700311 if (cameraId < 0 || cameraId >= mNumberOfCameras) {
312 return BAD_VALUE;
313 }
314
Iliyan Malchev8951a972011-04-14 16:55:59 -0700315 struct camera_info info;
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -0700316 status_t rc = filterGetInfoErrorCode(
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800317 mModule->getCameraInfo(cameraId, &info));
Iliyan Malchev8951a972011-04-14 16:55:59 -0700318 cameraInfo->facing = info.facing;
319 cameraInfo->orientation = info.orientation;
320 return rc;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700321}
322
Ruben Brunkb2119af2014-05-09 19:57:56 -0700323
324status_t CameraService::generateShimMetadata(int cameraId, /*out*/CameraMetadata* cameraInfo) {
325 status_t ret = OK;
326 struct CameraInfo info;
327 if ((ret = getCameraInfo(cameraId, &info)) != OK) {
328 return ret;
329 }
330
331 CameraMetadata shimInfo;
332 int32_t orientation = static_cast<int32_t>(info.orientation);
333 if ((ret = shimInfo.update(ANDROID_SENSOR_ORIENTATION, &orientation, 1)) != OK) {
334 return ret;
335 }
336
337 uint8_t facing = (info.facing == CAMERA_FACING_FRONT) ?
338 ANDROID_LENS_FACING_FRONT : ANDROID_LENS_FACING_BACK;
339 if ((ret = shimInfo.update(ANDROID_LENS_FACING, &facing, 1)) != OK) {
340 return ret;
341 }
342
Igor Murashkin65d14b92014-06-17 12:03:20 -0700343 CameraParameters shimParams;
344 if ((ret = getLegacyParametersLazy(cameraId, /*out*/&shimParams)) != OK) {
345 // Error logged by callee
346 return ret;
Ruben Brunkb2119af2014-05-09 19:57:56 -0700347 }
348
349 Vector<Size> sizes;
Ruben Brunk152dbcf2014-06-12 19:11:45 -0700350 Vector<Size> jpegSizes;
Ruben Brunkb2119af2014-05-09 19:57:56 -0700351 Vector<int32_t> formats;
352 const char* supportedPreviewFormats;
Igor Murashkin65d14b92014-06-17 12:03:20 -0700353 {
354 shimParams.getSupportedPreviewSizes(/*out*/sizes);
355 shimParams.getSupportedPreviewFormats(/*out*/formats);
356 shimParams.getSupportedPictureSizes(/*out*/jpegSizes);
Ruben Brunkb2119af2014-05-09 19:57:56 -0700357 }
358
359 // Always include IMPLEMENTATION_DEFINED
360 formats.add(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED);
361
362 const size_t INTS_PER_CONFIG = 4;
363
364 // Build available stream configurations metadata
Ruben Brunk152dbcf2014-06-12 19:11:45 -0700365 size_t streamConfigSize = (sizes.size() * formats.size() + jpegSizes.size()) * INTS_PER_CONFIG;
366
367 Vector<int32_t> streamConfigs;
368 streamConfigs.setCapacity(streamConfigSize);
369
Ruben Brunkb2119af2014-05-09 19:57:56 -0700370 for (size_t i = 0; i < formats.size(); ++i) {
371 for (size_t j = 0; j < sizes.size(); ++j) {
Ruben Brunk152dbcf2014-06-12 19:11:45 -0700372 streamConfigs.add(formats[i]);
373 streamConfigs.add(sizes[j].width);
374 streamConfigs.add(sizes[j].height);
375 streamConfigs.add(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
Ruben Brunkb2119af2014-05-09 19:57:56 -0700376 }
377 }
378
Ruben Brunk152dbcf2014-06-12 19:11:45 -0700379 for (size_t i = 0; i < jpegSizes.size(); ++i) {
380 streamConfigs.add(HAL_PIXEL_FORMAT_BLOB);
381 streamConfigs.add(jpegSizes[i].width);
382 streamConfigs.add(jpegSizes[i].height);
383 streamConfigs.add(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
384 }
385
Ruben Brunkb2119af2014-05-09 19:57:56 -0700386 if ((ret = shimInfo.update(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
Ruben Brunk152dbcf2014-06-12 19:11:45 -0700387 streamConfigs.array(), streamConfigSize)) != OK) {
Ruben Brunkb2119af2014-05-09 19:57:56 -0700388 return ret;
389 }
390
391 int64_t fakeMinFrames[0];
392 // TODO: Fixme, don't fake min frame durations.
393 if ((ret = shimInfo.update(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
394 fakeMinFrames, 0)) != OK) {
395 return ret;
396 }
397
398 int64_t fakeStalls[0];
399 // TODO: Fixme, don't fake stall durations.
400 if ((ret = shimInfo.update(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
401 fakeStalls, 0)) != OK) {
402 return ret;
403 }
404
405 *cameraInfo = shimInfo;
406 return OK;
407}
408
Zhijun He2b59be82013-09-25 10:14:30 -0700409status_t CameraService::getCameraCharacteristics(int cameraId,
410 CameraMetadata* cameraInfo) {
411 if (!cameraInfo) {
412 ALOGE("%s: cameraInfo is NULL", __FUNCTION__);
413 return BAD_VALUE;
414 }
415
416 if (!mModule) {
417 ALOGE("%s: camera hardware module doesn't exist", __FUNCTION__);
418 return -ENODEV;
419 }
420
Zhijun He2b59be82013-09-25 10:14:30 -0700421 if (cameraId < 0 || cameraId >= mNumberOfCameras) {
422 ALOGE("%s: Invalid camera id: %d", __FUNCTION__, cameraId);
423 return BAD_VALUE;
424 }
425
426 int facing;
Ruben Brunkb2119af2014-05-09 19:57:56 -0700427 status_t ret = OK;
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800428 if (mModule->getRawModule()->module_api_version < CAMERA_MODULE_API_VERSION_2_0 ||
Ruben Brunkb2119af2014-05-09 19:57:56 -0700429 getDeviceVersion(cameraId, &facing) <= CAMERA_DEVICE_API_VERSION_2_1 ) {
430 /**
431 * Backwards compatibility mode for old HALs:
432 * - Convert CameraInfo into static CameraMetadata properties.
433 * - Retrieve cached CameraParameters for this camera. If none exist,
434 * attempt to open CameraClient and retrieve the CameraParameters.
435 * - Convert cached CameraParameters into static CameraMetadata
436 * properties.
437 */
438 ALOGI("%s: Switching to HAL1 shim implementation...", __FUNCTION__);
Zhijun He2b59be82013-09-25 10:14:30 -0700439
Ruben Brunkb2119af2014-05-09 19:57:56 -0700440 if ((ret = generateShimMetadata(cameraId, cameraInfo)) != OK) {
441 return ret;
442 }
Zhijun Hef05e50e2013-10-01 11:05:33 -0700443
Ruben Brunkb2119af2014-05-09 19:57:56 -0700444 } else {
445 /**
446 * Normal HAL 2.1+ codepath.
447 */
448 struct camera_info info;
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800449 ret = filterGetInfoErrorCode(mModule->getCameraInfo(cameraId, &info));
Ruben Brunkb2119af2014-05-09 19:57:56 -0700450 *cameraInfo = info.static_camera_characteristics;
451 }
Zhijun He2b59be82013-09-25 10:14:30 -0700452
453 return ret;
454}
455
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800456status_t CameraService::getCameraVendorTagDescriptor(/*out*/sp<VendorTagDescriptor>& desc) {
457 if (!mModule) {
458 ALOGE("%s: camera hardware module doesn't exist", __FUNCTION__);
459 return -ENODEV;
460 }
461
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800462 desc = VendorTagDescriptor::getGlobalVendorTagDescriptor();
463 return OK;
464}
465
Igor Murashkin634a5152013-02-20 17:15:11 -0800466int CameraService::getDeviceVersion(int cameraId, int* facing) {
467 struct camera_info info;
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800468 if (mModule->getCameraInfo(cameraId, &info) != OK) {
Igor Murashkin634a5152013-02-20 17:15:11 -0800469 return -1;
470 }
471
472 int deviceVersion;
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800473 if (mModule->getRawModule()->module_api_version >= CAMERA_MODULE_API_VERSION_2_0) {
Igor Murashkin634a5152013-02-20 17:15:11 -0800474 deviceVersion = info.device_version;
475 } else {
476 deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
477 }
478
479 if (facing) {
480 *facing = info.facing;
481 }
482
483 return deviceVersion;
484}
485
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -0700486status_t CameraService::filterOpenErrorCode(status_t err) {
487 switch(err) {
488 case NO_ERROR:
489 case -EBUSY:
490 case -EINVAL:
491 case -EUSERS:
492 return err;
493 default:
494 break;
Igor Murashkinbfc99152013-02-27 12:55:20 -0800495 }
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -0700496 return -ENODEV;
497}
Igor Murashkinbfc99152013-02-27 12:55:20 -0800498
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -0700499status_t CameraService::filterGetInfoErrorCode(status_t err) {
500 switch(err) {
501 case NO_ERROR:
502 case -EINVAL:
503 return err;
504 default:
505 break;
506 }
507 return -ENODEV;
Igor Murashkinbfc99152013-02-27 12:55:20 -0800508}
509
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800510bool CameraService::setUpVendorTags() {
511 vendor_tag_ops_t vOps = vendor_tag_ops_t();
512
513 // Check if vendor operations have been implemented
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800514 if (!mModule->isVendorTagDefined()) {
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800515 ALOGI("%s: No vendor tags defined for this device.", __FUNCTION__);
516 return false;
517 }
518
519 ATRACE_BEGIN("camera3->get_metadata_vendor_tag_ops");
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800520 mModule->getVendorTagOps(&vOps);
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800521 ATRACE_END();
522
523 // Ensure all vendor operations are present
524 if (vOps.get_tag_count == NULL || vOps.get_all_tags == NULL ||
525 vOps.get_section_name == NULL || vOps.get_tag_name == NULL ||
526 vOps.get_tag_type == NULL) {
527 ALOGE("%s: Vendor tag operations not fully defined. Ignoring definitions."
528 , __FUNCTION__);
529 return false;
530 }
531
532 // Read all vendor tag definitions into a descriptor
533 sp<VendorTagDescriptor> desc;
534 status_t res;
535 if ((res = VendorTagDescriptor::createDescriptorFromOps(&vOps, /*out*/desc))
536 != OK) {
537 ALOGE("%s: Could not generate descriptor from vendor tag operations,"
538 "received error %s (%d). Camera clients will not be able to use"
539 "vendor tags", __FUNCTION__, strerror(res), res);
540 return false;
541 }
542
543 // Set the global descriptor to use with camera metadata
544 VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
545 return true;
546}
547
Ruben Brunkb2119af2014-05-09 19:57:56 -0700548status_t CameraService::initializeShimMetadata(int cameraId) {
549 int pid = getCallingPid();
550 int uid = getCallingUid();
551 status_t ret = validateConnect(cameraId, uid);
552 if (ret != OK) {
Igor Murashkin65d14b92014-06-17 12:03:20 -0700553 // Error already logged by callee
Ruben Brunkb2119af2014-05-09 19:57:56 -0700554 return ret;
555 }
556
557 bool needsNewClient = false;
558 sp<Client> client;
559
560 String16 internalPackageName("media");
561 { // Scope for service lock
562 Mutex::Autolock lock(mServiceLock);
563 if (mClient[cameraId] != NULL) {
564 client = static_cast<Client*>(mClient[cameraId].promote().get());
565 }
566 if (client == NULL) {
567 needsNewClient = true;
Igor Murashkina858ea02014-08-19 14:53:08 -0700568 ret = connectHelperLocked(/*out*/client,
569 /*cameraClient*/NULL, // Empty binder callbacks
Ruben Brunkb2119af2014-05-09 19:57:56 -0700570 cameraId,
571 internalPackageName,
572 uid,
Igor Murashkina858ea02014-08-19 14:53:08 -0700573 pid);
Ruben Brunkb2119af2014-05-09 19:57:56 -0700574
575 if (ret != OK) {
Igor Murashkin65d14b92014-06-17 12:03:20 -0700576 // Error already logged by callee
Ruben Brunkb2119af2014-05-09 19:57:56 -0700577 return ret;
578 }
579 }
580
581 if (client == NULL) {
582 ALOGE("%s: Could not connect to client camera device.", __FUNCTION__);
583 return BAD_VALUE;
584 }
585
586 String8 rawParams = client->getParameters();
587 CameraParameters params(rawParams);
588 mShimParams.add(cameraId, params);
589 }
590
591 // Close client if one was opened solely for this call
592 if (needsNewClient) {
593 client->disconnect();
594 }
595 return OK;
596}
597
Igor Murashkin65d14b92014-06-17 12:03:20 -0700598status_t CameraService::getLegacyParametersLazy(int cameraId,
599 /*out*/
600 CameraParameters* parameters) {
601
602 ALOGV("%s: for cameraId: %d", __FUNCTION__, cameraId);
603
604 status_t ret = 0;
605
606 if (parameters == NULL) {
607 ALOGE("%s: parameters must not be null", __FUNCTION__);
608 return BAD_VALUE;
609 }
610
611 ssize_t index = -1;
612 { // Scope for service lock
613 Mutex::Autolock lock(mServiceLock);
614 index = mShimParams.indexOfKey(cameraId);
615 // Release service lock so initializeShimMetadata can be called correctly.
616
617 if (index >= 0) {
618 *parameters = mShimParams[index];
619 }
620 }
621
622 if (index < 0) {
623 int64_t token = IPCThreadState::self()->clearCallingIdentity();
624 ret = initializeShimMetadata(cameraId);
625 IPCThreadState::self()->restoreCallingIdentity(token);
626 if (ret != OK) {
627 // Error already logged by callee
628 return ret;
629 }
630
631 { // Scope for service lock
632 Mutex::Autolock lock(mServiceLock);
633 index = mShimParams.indexOfKey(cameraId);
634
635 LOG_ALWAYS_FATAL_IF(index < 0, "index should have been initialized");
636
637 *parameters = mShimParams[index];
638 }
639 }
640
641 return OK;
642}
643
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700644status_t CameraService::validateConnect(int cameraId,
Igor Murashkine6800ce2013-03-04 17:25:57 -0800645 /*inout*/
646 int& clientUid) const {
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800647
Mathias Agopian65ab4712010-07-14 17:59:35 -0700648 int callingPid = getCallingPid();
Tyler Luu5861a9a2011-10-06 00:00:03 -0500649
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800650 if (clientUid == USE_CALLING_UID) {
651 clientUid = getCallingUid();
652 } else {
653 // We only trust our own process to forward client UIDs
654 if (callingPid != getpid()) {
655 ALOGE("CameraService::connect X (pid %d) rejected (don't trust clientUid)",
656 callingPid);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700657 return PERMISSION_DENIED;
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800658 }
659 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700660
Iliyan Malchev8951a972011-04-14 16:55:59 -0700661 if (!mModule) {
Steve Block29357bc2012-01-06 19:20:56 +0000662 ALOGE("Camera HAL module not loaded");
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700663 return -ENODEV;
Iliyan Malchev8951a972011-04-14 16:55:59 -0700664 }
665
Mathias Agopian65ab4712010-07-14 17:59:35 -0700666 if (cameraId < 0 || cameraId >= mNumberOfCameras) {
Steve Block29357bc2012-01-06 19:20:56 +0000667 ALOGE("CameraService::connect X (pid %d) rejected (invalid cameraId %d).",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700668 callingPid, cameraId);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700669 return -ENODEV;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700670 }
671
Wu-cheng Lia3355432011-05-20 14:54:25 +0800672 char value[PROPERTY_VALUE_MAX];
673 property_get("sys.secpolicy.camera.disabled", value, "0");
674 if (strcmp(value, "1") == 0) {
675 // Camera is disabled by DevicePolicyManager.
Steve Blockdf64d152012-01-04 20:05:49 +0000676 ALOGI("Camera is disabled. connect X (pid %d) rejected", callingPid);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700677 return -EACCES;
Wu-cheng Lia3355432011-05-20 14:54:25 +0800678 }
679
Igor Murashkincba2c162013-03-20 15:56:31 -0700680 ICameraServiceListener::Status currentStatus = getStatus(cameraId);
681 if (currentStatus == ICameraServiceListener::STATUS_NOT_PRESENT) {
682 ALOGI("Camera is not plugged in,"
683 " connect X (pid %d) rejected", callingPid);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700684 return -ENODEV;
Igor Murashkincba2c162013-03-20 15:56:31 -0700685 } else if (currentStatus == ICameraServiceListener::STATUS_ENUMERATING) {
686 ALOGI("Camera is enumerating,"
687 " connect X (pid %d) rejected", callingPid);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700688 return -EBUSY;
Igor Murashkincba2c162013-03-20 15:56:31 -0700689 }
690 // Else don't check for STATUS_NOT_AVAILABLE.
691 // -- It's done implicitly in canConnectUnsafe /w the mBusy array
692
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700693 return OK;
Igor Murashkine6800ce2013-03-04 17:25:57 -0800694}
695
696bool CameraService::canConnectUnsafe(int cameraId,
697 const String16& clientPackageName,
698 const sp<IBinder>& remoteCallback,
Igor Murashkine7ee7632013-06-11 18:10:18 -0700699 sp<BasicClient> &client) {
Igor Murashkine6800ce2013-03-04 17:25:57 -0800700 String8 clientName8(clientPackageName);
701 int callingPid = getCallingPid();
702
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800703 if (mClient[cameraId] != 0) {
704 client = mClient[cameraId].promote();
705 if (client != 0) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700706 if (remoteCallback == client->getRemote()) {
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800707 LOG1("CameraService::connect X (pid %d) (the same client)",
708 callingPid);
Igor Murashkine6800ce2013-03-04 17:25:57 -0800709 return true;
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800710 } else {
Igor Murashkine6800ce2013-03-04 17:25:57 -0800711 // TODOSC: need to support 1 regular client,
712 // multiple shared clients here
713 ALOGW("CameraService::connect X (pid %d) rejected"
714 " (existing client).", callingPid);
715 return false;
Wu-cheng Li2fd24402012-02-23 19:01:00 -0800716 }
Wu-cheng Li2fd24402012-02-23 19:01:00 -0800717 }
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800718 mClient[cameraId].clear();
719 }
720
Igor Murashkin634a5152013-02-20 17:15:11 -0800721 /*
722 mBusy is set to false as the last step of the Client destructor,
723 after which it is guaranteed that the Client destructor has finished (
724 including any inherited destructors)
725
726 We only need this for a Client subclasses since we don't allow
727 multiple Clents to be opened concurrently, but multiple BasicClient
728 would be fine
729 */
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800730 if (mBusy[cameraId]) {
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800731 ALOGW("CameraService::connect X (pid %d, \"%s\") rejected"
732 " (camera %d is still busy).", callingPid,
733 clientName8.string(), cameraId);
Igor Murashkine6800ce2013-03-04 17:25:57 -0800734 return false;
735 }
736
737 return true;
738}
739
Igor Murashkina858ea02014-08-19 14:53:08 -0700740status_t CameraService::connectHelperLocked(
741 /*out*/
742 sp<Client>& client,
743 /*in*/
744 const sp<ICameraClient>& cameraClient,
745 int cameraId,
746 const String16& clientPackageName,
747 int clientUid,
748 int callingPid,
749 int halVersion,
750 bool legacyMode) {
Ruben Brunkb2119af2014-05-09 19:57:56 -0700751
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800752 // give flashlight a chance to close devices if necessary.
753 mFlashlight->prepareDeviceOpen();
754
Ruben Brunkb2119af2014-05-09 19:57:56 -0700755 int facing = -1;
756 int deviceVersion = getDeviceVersion(cameraId, &facing);
757
Zhijun Heb10cdad2014-06-16 16:38:35 -0700758 if (halVersion < 0 || halVersion == deviceVersion) {
759 // Default path: HAL version is unspecified by caller, create CameraClient
760 // based on device version reported by the HAL.
761 switch(deviceVersion) {
762 case CAMERA_DEVICE_API_VERSION_1_0:
763 client = new CameraClient(this, cameraClient,
764 clientPackageName, cameraId,
Igor Murashkina858ea02014-08-19 14:53:08 -0700765 facing, callingPid, clientUid, getpid(), legacyMode);
Zhijun Heb10cdad2014-06-16 16:38:35 -0700766 break;
767 case CAMERA_DEVICE_API_VERSION_2_0:
768 case CAMERA_DEVICE_API_VERSION_2_1:
769 case CAMERA_DEVICE_API_VERSION_3_0:
770 case CAMERA_DEVICE_API_VERSION_3_1:
771 case CAMERA_DEVICE_API_VERSION_3_2:
772 client = new Camera2Client(this, cameraClient,
773 clientPackageName, cameraId,
Igor Murashkina858ea02014-08-19 14:53:08 -0700774 facing, callingPid, clientUid, getpid(), legacyMode);
Zhijun Heb10cdad2014-06-16 16:38:35 -0700775 break;
776 case -1:
777 ALOGE("Invalid camera id %d", cameraId);
778 return BAD_VALUE;
779 default:
780 ALOGE("Unknown camera device HAL version: %d", deviceVersion);
781 return INVALID_OPERATION;
782 }
783 } else {
784 // A particular HAL version is requested by caller. Create CameraClient
785 // based on the requested HAL version.
786 if (deviceVersion > CAMERA_DEVICE_API_VERSION_1_0 &&
787 halVersion == CAMERA_DEVICE_API_VERSION_1_0) {
788 // Only support higher HAL version device opened as HAL1.0 device.
789 client = new CameraClient(this, cameraClient,
790 clientPackageName, cameraId,
Igor Murashkina858ea02014-08-19 14:53:08 -0700791 facing, callingPid, clientUid, getpid(), legacyMode);
Zhijun Heb10cdad2014-06-16 16:38:35 -0700792 } else {
793 // Other combinations (e.g. HAL3.x open as HAL2.x) are not supported yet.
794 ALOGE("Invalid camera HAL version %x: HAL %x device can only be"
795 " opened as HAL %x device", halVersion, deviceVersion,
796 CAMERA_DEVICE_API_VERSION_1_0);
797 return INVALID_OPERATION;
798 }
Ruben Brunkb2119af2014-05-09 19:57:56 -0700799 }
800
801 status_t status = connectFinishUnsafe(client, client->getRemote());
802 if (status != OK) {
803 // this is probably not recoverable.. maybe the client can try again
Ruben Brunkb2119af2014-05-09 19:57:56 -0700804 return status;
805 }
806
807 mClient[cameraId] = client;
808 LOG1("CameraService::connect X (id %d, this pid is %d)", cameraId,
809 getpid());
810
811 return OK;
812}
813
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700814status_t CameraService::connect(
Igor Murashkine6800ce2013-03-04 17:25:57 -0800815 const sp<ICameraClient>& cameraClient,
816 int cameraId,
817 const String16& clientPackageName,
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700818 int clientUid,
819 /*out*/
820 sp<ICamera>& device) {
Igor Murashkine6800ce2013-03-04 17:25:57 -0800821
822 String8 clientName8(clientPackageName);
823 int callingPid = getCallingPid();
824
825 LOG1("CameraService::connect E (pid %d \"%s\", id %d)", callingPid,
826 clientName8.string(), cameraId);
827
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700828 status_t status = validateConnect(cameraId, /*inout*/clientUid);
829 if (status != OK) {
830 return status;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700831 }
832
Igor Murashkine6800ce2013-03-04 17:25:57 -0800833
Igor Murashkine7ee7632013-06-11 18:10:18 -0700834 sp<Client> client;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700835 {
836 Mutex::Autolock lock(mServiceLock);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700837 sp<BasicClient> clientTmp;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700838 if (!canConnectUnsafe(cameraId, clientPackageName,
Marco Nelissenf8880202014-11-14 07:58:25 -0800839 IInterface::asBinder(cameraClient),
Igor Murashkine7ee7632013-06-11 18:10:18 -0700840 /*out*/clientTmp)) {
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700841 return -EBUSY;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700842 } else if (client.get() != NULL) {
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700843 device = static_cast<Client*>(clientTmp.get());
844 return OK;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700845 }
846
Igor Murashkina858ea02014-08-19 14:53:08 -0700847 status = connectHelperLocked(/*out*/client,
848 cameraClient,
Ruben Brunkb2119af2014-05-09 19:57:56 -0700849 cameraId,
850 clientPackageName,
851 clientUid,
Igor Murashkina858ea02014-08-19 14:53:08 -0700852 callingPid);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700853 if (status != OK) {
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700854 return status;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700855 }
856
Igor Murashkine6800ce2013-03-04 17:25:57 -0800857 }
Igor Murashkinacd695c2013-03-13 17:23:00 -0700858 // important: release the mutex here so the client can call back
859 // into the service from its destructor (can be at the end of the call)
Igor Murashkinbfc99152013-02-27 12:55:20 -0800860
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700861 device = client;
862 return OK;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700863}
864
Zhijun Heb10cdad2014-06-16 16:38:35 -0700865status_t CameraService::connectLegacy(
866 const sp<ICameraClient>& cameraClient,
867 int cameraId, int halVersion,
868 const String16& clientPackageName,
869 int clientUid,
870 /*out*/
871 sp<ICamera>& device) {
872
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800873 int apiVersion = mModule->getRawModule()->module_api_version;
Igor Murashkin3d07d1a2014-06-20 11:27:03 -0700874 if (halVersion != CAMERA_HAL_API_VERSION_UNSPECIFIED &&
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800875 apiVersion < CAMERA_MODULE_API_VERSION_2_3) {
Igor Murashkin3d07d1a2014-06-20 11:27:03 -0700876 /*
877 * Either the HAL version is unspecified in which case this just creates
878 * a camera client selected by the latest device version, or
879 * it's a particular version in which case the HAL must supported
880 * the open_legacy call
881 */
Zhijun Heb10cdad2014-06-16 16:38:35 -0700882 ALOGE("%s: camera HAL module version %x doesn't support connecting to legacy HAL devices!",
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800883 __FUNCTION__, apiVersion);
Zhijun Heb10cdad2014-06-16 16:38:35 -0700884 return INVALID_OPERATION;
885 }
886
887 String8 clientName8(clientPackageName);
888 int callingPid = getCallingPid();
889
890 LOG1("CameraService::connect legacy E (pid %d \"%s\", id %d)", callingPid,
891 clientName8.string(), cameraId);
892
893 status_t status = validateConnect(cameraId, /*inout*/clientUid);
894 if (status != OK) {
895 return status;
896 }
897
898 sp<Client> client;
899 {
900 Mutex::Autolock lock(mServiceLock);
901 sp<BasicClient> clientTmp;
902 if (!canConnectUnsafe(cameraId, clientPackageName,
Marco Nelissenf8880202014-11-14 07:58:25 -0800903 IInterface::asBinder(cameraClient),
Zhijun Heb10cdad2014-06-16 16:38:35 -0700904 /*out*/clientTmp)) {
905 return -EBUSY;
906 } else if (client.get() != NULL) {
907 device = static_cast<Client*>(clientTmp.get());
908 return OK;
909 }
910
Igor Murashkina858ea02014-08-19 14:53:08 -0700911 status = connectHelperLocked(/*out*/client,
912 cameraClient,
Zhijun Heb10cdad2014-06-16 16:38:35 -0700913 cameraId,
914 clientPackageName,
915 clientUid,
916 callingPid,
Igor Murashkina858ea02014-08-19 14:53:08 -0700917 halVersion,
918 /*legacyMode*/true);
Zhijun Heb10cdad2014-06-16 16:38:35 -0700919 if (status != OK) {
920 return status;
921 }
922
923 }
924 // important: release the mutex here so the client can call back
925 // into the service from its destructor (can be at the end of the call)
926
927 device = client;
928 return OK;
929}
930
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800931status_t CameraService::setTorchMode(const String16& cameraId, bool enabled,
932 const sp<IBinder>& clientBinder) {
933 if (enabled && clientBinder == NULL) {
934 ALOGE("%s: torch client binder is NULL", __FUNCTION__);
935 return -ENOSYS;
936 }
937
938 Mutex::Autolock al(mTorchStatusMutex);
939 status_t res = mFlashlight->setTorchMode(cameraId, enabled);
940 if (res) {
941 ALOGE("%s: setting torch mode of camera %s to %d failed", __FUNCTION__,
942 cameraId.string(), enabled);
943 return res;
944 }
945
946 // update the link to client's death
947 ssize_t index = mTorchClientMap.indexOfKey(cameraId);
948 if (enabled) {
949 if (index == NAME_NOT_FOUND) {
950 mTorchClientMap.add(cameraId, clientBinder);
951 } else {
952 const sp<IBinder> oldBinder = mTorchClientMap.valueAt(index);
953 oldBinder->unlinkToDeath(this);
954
955 mTorchClientMap.replaceValueAt(index, clientBinder);
956 }
957 clientBinder->linkToDeath(this);
958 } else if (index != NAME_NOT_FOUND) {
959 sp<IBinder> oldBinder = mTorchClientMap.valueAt(index);
960 oldBinder->unlinkToDeath(this);
961 }
962
963 // notify the listeners the change.
964 ICameraServiceListener::TorchStatus status = enabled ?
965 ICameraServiceListener::TORCH_STATUS_ON :
966 ICameraServiceListener::TORCH_STATUS_OFF;
967 onTorchStatusChangedLocked(cameraId, status);
968
969 return OK;
970}
971
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700972status_t CameraService::connectFinishUnsafe(const sp<BasicClient>& client,
973 const sp<IBinder>& remoteCallback) {
974 status_t status = client->initialize(mModule);
975 if (status != OK) {
Ruben Brunk5fc9d902014-11-20 13:34:36 -0800976 ALOGE("%s: Could not initialize client from HAL module.", __FUNCTION__);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700977 return status;
Igor Murashkine6800ce2013-03-04 17:25:57 -0800978 }
Ruben Brunkb2119af2014-05-09 19:57:56 -0700979 if (remoteCallback != NULL) {
980 remoteCallback->linkToDeath(this);
981 }
Igor Murashkine6800ce2013-03-04 17:25:57 -0800982
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700983 return OK;
Igor Murashkine6800ce2013-03-04 17:25:57 -0800984}
985
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700986status_t CameraService::connectPro(
Igor Murashkin634a5152013-02-20 17:15:11 -0800987 const sp<IProCameraCallbacks>& cameraCb,
Igor Murashkinc073ba52013-02-26 14:32:34 -0800988 int cameraId,
989 const String16& clientPackageName,
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700990 int clientUid,
991 /*out*/
992 sp<IProCameraUser>& device)
Igor Murashkin634a5152013-02-20 17:15:11 -0800993{
Natalie Silvanoviche1b55da2014-05-01 14:44:52 -0700994 if (cameraCb == 0) {
995 ALOGE("%s: Callback must not be null", __FUNCTION__);
996 return BAD_VALUE;
997 }
998
Igor Murashkinbfc99152013-02-27 12:55:20 -0800999 String8 clientName8(clientPackageName);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001000 int callingPid = getCallingPid();
Igor Murashkin634a5152013-02-20 17:15:11 -08001001
Igor Murashkine6800ce2013-03-04 17:25:57 -08001002 LOG1("CameraService::connectPro E (pid %d \"%s\", id %d)", callingPid,
1003 clientName8.string(), cameraId);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001004 status_t status = validateConnect(cameraId, /*inout*/clientUid);
1005 if (status != OK) {
1006 return status;
Igor Murashkin634a5152013-02-20 17:15:11 -08001007 }
1008
Igor Murashkinacd695c2013-03-13 17:23:00 -07001009 sp<ProClient> client;
Igor Murashkine6800ce2013-03-04 17:25:57 -08001010 {
Igor Murashkinacd695c2013-03-13 17:23:00 -07001011 Mutex::Autolock lock(mServiceLock);
1012 {
Igor Murashkine7ee7632013-06-11 18:10:18 -07001013 sp<BasicClient> client;
Igor Murashkinacd695c2013-03-13 17:23:00 -07001014 if (!canConnectUnsafe(cameraId, clientPackageName,
Marco Nelissenf8880202014-11-14 07:58:25 -08001015 IInterface::asBinder(cameraCb),
Igor Murashkinacd695c2013-03-13 17:23:00 -07001016 /*out*/client)) {
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001017 return -EBUSY;
Igor Murashkinacd695c2013-03-13 17:23:00 -07001018 }
1019 }
1020
1021 int facing = -1;
1022 int deviceVersion = getDeviceVersion(cameraId, &facing);
1023
1024 switch(deviceVersion) {
1025 case CAMERA_DEVICE_API_VERSION_1_0:
1026 ALOGE("Camera id %d uses HALv1, doesn't support ProCamera",
1027 cameraId);
Ruben Brunk17963d12013-08-19 15:21:19 -07001028 return -EOPNOTSUPP;
Igor Murashkinacd695c2013-03-13 17:23:00 -07001029 break;
1030 case CAMERA_DEVICE_API_VERSION_2_0:
1031 case CAMERA_DEVICE_API_VERSION_2_1:
Zhijun He47110052013-07-22 17:34:34 -07001032 case CAMERA_DEVICE_API_VERSION_3_0:
Zhijun He95dd5ba2014-03-26 18:18:00 -07001033 case CAMERA_DEVICE_API_VERSION_3_1:
1034 case CAMERA_DEVICE_API_VERSION_3_2:
Eino-Ville Talvala63d877f2014-06-16 19:21:12 -07001035 client = new ProCamera2Client(this, cameraCb, clientPackageName,
1036 cameraId, facing, callingPid, clientUid, getpid());
Igor Murashkinacd695c2013-03-13 17:23:00 -07001037 break;
1038 case -1:
1039 ALOGE("Invalid camera id %d", cameraId);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001040 return BAD_VALUE;
Igor Murashkinacd695c2013-03-13 17:23:00 -07001041 default:
1042 ALOGE("Unknown camera device HAL version: %d", deviceVersion);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001043 return INVALID_OPERATION;
Igor Murashkine6800ce2013-03-04 17:25:57 -08001044 }
Igor Murashkinacd695c2013-03-13 17:23:00 -07001045
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001046 status_t status = connectFinishUnsafe(client, client->getRemote());
1047 if (status != OK) {
1048 return status;
Igor Murashkinacd695c2013-03-13 17:23:00 -07001049 }
1050
1051 mProClientList[cameraId].push(client);
1052
1053 LOG1("CameraService::connectPro X (id %d, this pid is %d)", cameraId,
1054 getpid());
Igor Murashkine6800ce2013-03-04 17:25:57 -08001055 }
Igor Murashkinacd695c2013-03-13 17:23:00 -07001056 // important: release the mutex here so the client can call back
1057 // into the service from its destructor (can be at the end of the call)
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001058 device = client;
1059 return OK;
Igor Murashkinbfc99152013-02-27 12:55:20 -08001060}
Igor Murashkin634a5152013-02-20 17:15:11 -08001061
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001062status_t CameraService::connectDevice(
Igor Murashkine7ee7632013-06-11 18:10:18 -07001063 const sp<ICameraDeviceCallbacks>& cameraCb,
1064 int cameraId,
1065 const String16& clientPackageName,
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001066 int clientUid,
1067 /*out*/
1068 sp<ICameraDeviceUser>& device)
Igor Murashkine7ee7632013-06-11 18:10:18 -07001069{
Igor Murashkine7ee7632013-06-11 18:10:18 -07001070
1071 String8 clientName8(clientPackageName);
1072 int callingPid = getCallingPid();
1073
1074 LOG1("CameraService::connectDevice E (pid %d \"%s\", id %d)", callingPid,
1075 clientName8.string(), cameraId);
1076
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001077 status_t status = validateConnect(cameraId, /*inout*/clientUid);
1078 if (status != OK) {
1079 return status;
Igor Murashkine7ee7632013-06-11 18:10:18 -07001080 }
1081
1082 sp<CameraDeviceClient> client;
1083 {
1084 Mutex::Autolock lock(mServiceLock);
1085 {
1086 sp<BasicClient> client;
1087 if (!canConnectUnsafe(cameraId, clientPackageName,
Marco Nelissenf8880202014-11-14 07:58:25 -08001088 IInterface::asBinder(cameraCb),
Igor Murashkine7ee7632013-06-11 18:10:18 -07001089 /*out*/client)) {
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001090 return -EBUSY;
Igor Murashkine7ee7632013-06-11 18:10:18 -07001091 }
1092 }
1093
1094 int facing = -1;
1095 int deviceVersion = getDeviceVersion(cameraId, &facing);
1096
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001097 // give flashlight a chance to close devices if necessary.
1098 mFlashlight->prepareDeviceOpen();
1099
Igor Murashkine7ee7632013-06-11 18:10:18 -07001100 switch(deviceVersion) {
1101 case CAMERA_DEVICE_API_VERSION_1_0:
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001102 ALOGW("Camera using old HAL version: %d", deviceVersion);
Ruben Brunk17963d12013-08-19 15:21:19 -07001103 return -EOPNOTSUPP;
Igor Murashkine7ee7632013-06-11 18:10:18 -07001104 // TODO: don't allow 2.0 Only allow 2.1 and higher
1105 case CAMERA_DEVICE_API_VERSION_2_0:
1106 case CAMERA_DEVICE_API_VERSION_2_1:
1107 case CAMERA_DEVICE_API_VERSION_3_0:
Zhijun He95dd5ba2014-03-26 18:18:00 -07001108 case CAMERA_DEVICE_API_VERSION_3_1:
1109 case CAMERA_DEVICE_API_VERSION_3_2:
Eino-Ville Talvala63d877f2014-06-16 19:21:12 -07001110 client = new CameraDeviceClient(this, cameraCb, clientPackageName,
1111 cameraId, facing, callingPid, clientUid, getpid());
Igor Murashkine7ee7632013-06-11 18:10:18 -07001112 break;
1113 case -1:
1114 ALOGE("Invalid camera id %d", cameraId);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001115 return BAD_VALUE;
Igor Murashkine7ee7632013-06-11 18:10:18 -07001116 default:
1117 ALOGE("Unknown camera device HAL version: %d", deviceVersion);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001118 return INVALID_OPERATION;
Igor Murashkine7ee7632013-06-11 18:10:18 -07001119 }
1120
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001121 status_t status = connectFinishUnsafe(client, client->getRemote());
1122 if (status != OK) {
Igor Murashkine7ee7632013-06-11 18:10:18 -07001123 // this is probably not recoverable.. maybe the client can try again
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001124 return status;
Igor Murashkine7ee7632013-06-11 18:10:18 -07001125 }
1126
1127 LOG1("CameraService::connectDevice X (id %d, this pid is %d)", cameraId,
1128 getpid());
1129
1130 mClient[cameraId] = client;
1131 }
1132 // important: release the mutex here so the client can call back
1133 // into the service from its destructor (can be at the end of the call)
1134
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001135 device = client;
1136 return OK;
Igor Murashkine7ee7632013-06-11 18:10:18 -07001137}
1138
1139
Igor Murashkinbfc99152013-02-27 12:55:20 -08001140status_t CameraService::addListener(
1141 const sp<ICameraServiceListener>& listener) {
1142 ALOGV("%s: Add listener %p", __FUNCTION__, listener.get());
Igor Murashkin634a5152013-02-20 17:15:11 -08001143
Igor Murashkinbd3e2e02014-03-17 13:01:41 -07001144 if (listener == 0) {
1145 ALOGE("%s: Listener must not be null", __FUNCTION__);
1146 return BAD_VALUE;
1147 }
1148
Igor Murashkinbfc99152013-02-27 12:55:20 -08001149 Mutex::Autolock lock(mServiceLock);
1150
1151 Vector<sp<ICameraServiceListener> >::iterator it, end;
1152 for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
Marco Nelissenf8880202014-11-14 07:58:25 -08001153 if (IInterface::asBinder(*it) == IInterface::asBinder(listener)) {
Igor Murashkinbfc99152013-02-27 12:55:20 -08001154 ALOGW("%s: Tried to add listener %p which was already subscribed",
1155 __FUNCTION__, listener.get());
1156 return ALREADY_EXISTS;
1157 }
1158 }
1159
1160 mListenerList.push_back(listener);
1161
Igor Murashkincba2c162013-03-20 15:56:31 -07001162 /* Immediately signal current status to this listener only */
1163 {
1164 Mutex::Autolock m(mStatusMutex) ;
1165 int numCams = getNumberOfCameras();
1166 for (int i = 0; i < numCams; ++i) {
1167 listener->onStatusChanged(mStatusList[i], i);
1168 }
1169 }
1170
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001171 /* Immediately signal current torch status to this listener only */
1172 {
1173 Mutex::Autolock al(mTorchStatusMutex);
1174 for (size_t i = 0; i < mTorchStatusMap.size(); i++ ) {
1175 listener->onTorchStatusChanged(mTorchStatusMap.valueAt(i),
1176 mTorchStatusMap.keyAt(i));
1177 }
1178
1179 }
1180
Igor Murashkinbfc99152013-02-27 12:55:20 -08001181 return OK;
1182}
1183status_t CameraService::removeListener(
1184 const sp<ICameraServiceListener>& listener) {
1185 ALOGV("%s: Remove listener %p", __FUNCTION__, listener.get());
1186
Igor Murashkinbd3e2e02014-03-17 13:01:41 -07001187 if (listener == 0) {
1188 ALOGE("%s: Listener must not be null", __FUNCTION__);
1189 return BAD_VALUE;
1190 }
1191
Igor Murashkinbfc99152013-02-27 12:55:20 -08001192 Mutex::Autolock lock(mServiceLock);
1193
1194 Vector<sp<ICameraServiceListener> >::iterator it;
1195 for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
Marco Nelissenf8880202014-11-14 07:58:25 -08001196 if (IInterface::asBinder(*it) == IInterface::asBinder(listener)) {
Igor Murashkinbfc99152013-02-27 12:55:20 -08001197 mListenerList.erase(it);
1198 return OK;
1199 }
1200 }
1201
1202 ALOGW("%s: Tried to remove a listener %p which was not subscribed",
1203 __FUNCTION__, listener.get());
1204
1205 return BAD_VALUE;
Igor Murashkin634a5152013-02-20 17:15:11 -08001206}
1207
Igor Murashkin65d14b92014-06-17 12:03:20 -07001208status_t CameraService::getLegacyParameters(
1209 int cameraId,
1210 /*out*/
1211 String16* parameters) {
1212 ALOGV("%s: for camera ID = %d", __FUNCTION__, cameraId);
1213
1214 if (parameters == NULL) {
1215 ALOGE("%s: parameters must not be null", __FUNCTION__);
1216 return BAD_VALUE;
1217 }
1218
1219 status_t ret = 0;
1220
1221 CameraParameters shimParams;
1222 if ((ret = getLegacyParametersLazy(cameraId, /*out*/&shimParams)) != OK) {
1223 // Error logged by caller
1224 return ret;
1225 }
1226
1227 String8 shimParamsString8 = shimParams.flatten();
1228 String16 shimParamsString16 = String16(shimParamsString8);
1229
1230 *parameters = shimParamsString16;
1231
1232 return OK;
1233}
1234
1235status_t CameraService::supportsCameraApi(int cameraId, int apiVersion) {
1236 ALOGV("%s: for camera ID = %d", __FUNCTION__, cameraId);
1237
1238 switch (apiVersion) {
1239 case API_VERSION_1:
1240 case API_VERSION_2:
1241 break;
1242 default:
1243 ALOGE("%s: Bad API version %d", __FUNCTION__, apiVersion);
1244 return BAD_VALUE;
1245 }
1246
1247 int facing = -1;
1248 int deviceVersion = getDeviceVersion(cameraId, &facing);
1249
1250 switch(deviceVersion) {
1251 case CAMERA_DEVICE_API_VERSION_1_0:
1252 case CAMERA_DEVICE_API_VERSION_2_0:
1253 case CAMERA_DEVICE_API_VERSION_2_1:
1254 case CAMERA_DEVICE_API_VERSION_3_0:
1255 case CAMERA_DEVICE_API_VERSION_3_1:
1256 if (apiVersion == API_VERSION_2) {
1257 ALOGV("%s: Camera id %d uses HAL prior to HAL3.2, doesn't support api2 without shim",
1258 __FUNCTION__, cameraId);
1259 return -EOPNOTSUPP;
1260 } else { // if (apiVersion == API_VERSION_1) {
1261 ALOGV("%s: Camera id %d uses older HAL before 3.2, but api1 is always supported",
1262 __FUNCTION__, cameraId);
1263 return OK;
1264 }
1265 case CAMERA_DEVICE_API_VERSION_3_2:
1266 ALOGV("%s: Camera id %d uses HAL3.2 or newer, supports api1/api2 directly",
1267 __FUNCTION__, cameraId);
1268 return OK;
1269 case -1:
1270 ALOGE("%s: Invalid camera id %d", __FUNCTION__, cameraId);
1271 return BAD_VALUE;
1272 default:
1273 ALOGE("%s: Unknown camera device HAL version: %d", __FUNCTION__, deviceVersion);
1274 return INVALID_OPERATION;
1275 }
1276
1277 return OK;
1278}
1279
Igor Murashkin634a5152013-02-20 17:15:11 -08001280void CameraService::removeClientByRemote(const wp<IBinder>& remoteBinder) {
1281 int callingPid = getCallingPid();
1282 LOG1("CameraService::removeClientByRemote E (pid %d)", callingPid);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001283
Igor Murashkinecf17e82012-10-02 16:05:11 -07001284 // Declare this before the lock to make absolutely sure the
1285 // destructor won't be called with the lock held.
1286 Mutex::Autolock lock(mServiceLock);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001287
Igor Murashkinecf17e82012-10-02 16:05:11 -07001288 int outIndex;
Igor Murashkine7ee7632013-06-11 18:10:18 -07001289 sp<BasicClient> client = findClientUnsafe(remoteBinder, outIndex);
Igor Murashkinecf17e82012-10-02 16:05:11 -07001290
1291 if (client != 0) {
1292 // Found our camera, clear and leave.
1293 LOG1("removeClient: clear camera %d", outIndex);
Igor Murashkinecf17e82012-10-02 16:05:11 -07001294
Ruben Brunkb2119af2014-05-09 19:57:56 -07001295 sp<IBinder> remote = client->getRemote();
1296 if (remote != NULL) {
1297 remote->unlinkToDeath(this);
1298 }
1299
1300 mClient[outIndex].clear();
Igor Murashkin634a5152013-02-20 17:15:11 -08001301 } else {
1302
1303 sp<ProClient> clientPro = findProClientUnsafe(remoteBinder);
1304
1305 if (clientPro != NULL) {
1306 // Found our camera, clear and leave.
1307 LOG1("removeClient: clear pro %p", clientPro.get());
1308
Marco Nelissenf8880202014-11-14 07:58:25 -08001309 IInterface::asBinder(clientPro->getRemoteCallback())->unlinkToDeath(this);
Igor Murashkin634a5152013-02-20 17:15:11 -08001310 }
Igor Murashkinecf17e82012-10-02 16:05:11 -07001311 }
1312
Igor Murashkin634a5152013-02-20 17:15:11 -08001313 LOG1("CameraService::removeClientByRemote X (pid %d)", callingPid);
1314}
1315
1316sp<CameraService::ProClient> CameraService::findProClientUnsafe(
1317 const wp<IBinder>& cameraCallbacksRemote)
1318{
1319 sp<ProClient> clientPro;
1320
1321 for (int i = 0; i < mNumberOfCameras; ++i) {
1322 Vector<size_t> removeIdx;
1323
1324 for (size_t j = 0; j < mProClientList[i].size(); ++j) {
1325 wp<ProClient> cl = mProClientList[i][j];
1326
1327 sp<ProClient> clStrong = cl.promote();
1328 if (clStrong != NULL && clStrong->getRemote() == cameraCallbacksRemote) {
1329 clientPro = clStrong;
1330 break;
1331 } else if (clStrong == NULL) {
1332 // mark to clean up dead ptr
1333 removeIdx.push(j);
1334 }
1335 }
1336
1337 // remove stale ptrs (in reverse so the indices dont change)
1338 for (ssize_t j = (ssize_t)removeIdx.size() - 1; j >= 0; --j) {
1339 mProClientList[i].removeAt(removeIdx[j]);
1340 }
1341
1342 }
1343
1344 return clientPro;
Igor Murashkinecf17e82012-10-02 16:05:11 -07001345}
1346
Igor Murashkine7ee7632013-06-11 18:10:18 -07001347sp<CameraService::BasicClient> CameraService::findClientUnsafe(
Igor Murashkin294d0ec2012-10-05 10:44:57 -07001348 const wp<IBinder>& cameraClient, int& outIndex) {
Igor Murashkine7ee7632013-06-11 18:10:18 -07001349 sp<BasicClient> client;
Igor Murashkinecf17e82012-10-02 16:05:11 -07001350
1351 for (int i = 0; i < mNumberOfCameras; i++) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001352
1353 // This happens when we have already disconnected (or this is
1354 // just another unused camera).
1355 if (mClient[i] == 0) continue;
1356
1357 // Promote mClient. It can fail if we are called from this path:
Igor Murashkin634a5152013-02-20 17:15:11 -08001358 // Client::~Client() -> disconnect() -> removeClientByRemote().
Mathias Agopian65ab4712010-07-14 17:59:35 -07001359 client = mClient[i].promote();
1360
Igor Murashkinecf17e82012-10-02 16:05:11 -07001361 // Clean up stale client entry
1362 if (client == NULL) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001363 mClient[i].clear();
1364 continue;
1365 }
1366
Igor Murashkine7ee7632013-06-11 18:10:18 -07001367 if (cameraClient == client->getRemote()) {
Igor Murashkinecf17e82012-10-02 16:05:11 -07001368 // Found our camera
1369 outIndex = i;
1370 return client;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001371 }
1372 }
1373
Igor Murashkinecf17e82012-10-02 16:05:11 -07001374 outIndex = -1;
1375 return NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001376}
1377
Igor Murashkine7ee7632013-06-11 18:10:18 -07001378CameraService::BasicClient* CameraService::getClientByIdUnsafe(int cameraId) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001379 if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
Keun young Parkd8973a72012-03-28 14:13:09 -07001380 return mClient[cameraId].unsafe_get();
1381}
1382
1383Mutex* CameraService::getClientLockById(int cameraId) {
1384 if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
1385 return &mClientLock[cameraId];
Mathias Agopian65ab4712010-07-14 17:59:35 -07001386}
1387
Igor Murashkin634a5152013-02-20 17:15:11 -08001388sp<CameraService::BasicClient> CameraService::getClientByRemote(
Igor Murashkin294d0ec2012-10-05 10:44:57 -07001389 const wp<IBinder>& cameraClient) {
Igor Murashkinecf17e82012-10-02 16:05:11 -07001390
1391 // Declare this before the lock to make absolutely sure the
1392 // destructor won't be called with the lock held.
Igor Murashkin634a5152013-02-20 17:15:11 -08001393 sp<BasicClient> client;
Igor Murashkinecf17e82012-10-02 16:05:11 -07001394
1395 Mutex::Autolock lock(mServiceLock);
1396
1397 int outIndex;
1398 client = findClientUnsafe(cameraClient, outIndex);
1399
1400 return client;
1401}
1402
Mathias Agopian65ab4712010-07-14 17:59:35 -07001403status_t CameraService::onTransact(
1404 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
1405 // Permission checks
1406 switch (code) {
1407 case BnCameraService::CONNECT:
Igor Murashkin634a5152013-02-20 17:15:11 -08001408 case BnCameraService::CONNECT_PRO:
Eino-Ville Talvala63d877f2014-06-16 19:21:12 -07001409 case BnCameraService::CONNECT_DEVICE:
Zhijun Heb10cdad2014-06-16 16:38:35 -07001410 case BnCameraService::CONNECT_LEGACY:
Mathias Agopian65ab4712010-07-14 17:59:35 -07001411 const int pid = getCallingPid();
1412 const int self_pid = getpid();
1413 if (pid != self_pid) {
1414 // we're called from a different process, do the real check
1415 if (!checkCallingPermission(
1416 String16("android.permission.CAMERA"))) {
1417 const int uid = getCallingUid();
Steve Block29357bc2012-01-06 19:20:56 +00001418 ALOGE("Permission Denial: "
Mathias Agopian65ab4712010-07-14 17:59:35 -07001419 "can't use the camera pid=%d, uid=%d", pid, uid);
1420 return PERMISSION_DENIED;
1421 }
1422 }
1423 break;
1424 }
1425
1426 return BnCameraService::onTransact(code, data, reply, flags);
1427}
1428
1429// The reason we need this busy bit is a new CameraService::connect() request
1430// may come in while the previous Client's destructor has not been run or is
1431// still running. If the last strong reference of the previous Client is gone
1432// but the destructor has not been finished, we should not allow the new Client
1433// to be created because we need to wait for the previous Client to tear down
1434// the hardware first.
1435void CameraService::setCameraBusy(int cameraId) {
1436 android_atomic_write(1, &mBusy[cameraId]);
Igor Murashkinecf17e82012-10-02 16:05:11 -07001437
1438 ALOGV("setCameraBusy cameraId=%d", cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001439}
1440
1441void CameraService::setCameraFree(int cameraId) {
1442 android_atomic_write(0, &mBusy[cameraId]);
Igor Murashkinecf17e82012-10-02 16:05:11 -07001443
1444 ALOGV("setCameraFree cameraId=%d", cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001445}
1446
1447// We share the media players for shutter and recording sound for all clients.
1448// A reference count is kept to determine when we will actually release the
1449// media players.
1450
Chih-Chung Changff4f55c2011-10-17 19:03:12 +08001451MediaPlayer* CameraService::newMediaPlayer(const char *file) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001452 MediaPlayer* mp = new MediaPlayer();
Andreas Huber1b86fe02014-01-29 11:13:26 -08001453 if (mp->setDataSource(NULL /* httpService */, file, NULL) == NO_ERROR) {
Eino-Ville Talvala60a78ac2012-01-05 15:34:53 -08001454 mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001455 mp->prepare();
1456 } else {
Steve Block29357bc2012-01-06 19:20:56 +00001457 ALOGE("Failed to load CameraService sounds: %s", file);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001458 return NULL;
1459 }
1460 return mp;
1461}
1462
1463void CameraService::loadSound() {
1464 Mutex::Autolock lock(mSoundLock);
1465 LOG1("CameraService::loadSound ref=%d", mSoundRef);
1466 if (mSoundRef++) return;
1467
1468 mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
1469 mSoundPlayer[SOUND_RECORDING] = newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");
1470}
1471
1472void CameraService::releaseSound() {
1473 Mutex::Autolock lock(mSoundLock);
1474 LOG1("CameraService::releaseSound ref=%d", mSoundRef);
1475 if (--mSoundRef) return;
1476
1477 for (int i = 0; i < NUM_SOUNDS; i++) {
1478 if (mSoundPlayer[i] != 0) {
1479 mSoundPlayer[i]->disconnect();
1480 mSoundPlayer[i].clear();
1481 }
1482 }
1483}
1484
1485void CameraService::playSound(sound_kind kind) {
1486 LOG1("playSound(%d)", kind);
1487 Mutex::Autolock lock(mSoundLock);
1488 sp<MediaPlayer> player = mSoundPlayer[kind];
1489 if (player != 0) {
Chih-Chung Chang8888a752011-10-20 10:47:26 +08001490 player->seekTo(0);
1491 player->start();
Mathias Agopian65ab4712010-07-14 17:59:35 -07001492 }
1493}
1494
1495// ----------------------------------------------------------------------------
1496
1497CameraService::Client::Client(const sp<CameraService>& cameraService,
Wu-cheng Lib7a67942010-08-17 15:45:37 -07001498 const sp<ICameraClient>& cameraClient,
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001499 const String16& clientPackageName,
1500 int cameraId, int cameraFacing,
1501 int clientPid, uid_t clientUid,
1502 int servicePid) :
Eino-Ville Talvalae992e752014-11-07 16:17:48 -08001503 CameraService::BasicClient(cameraService,
Marco Nelissenf8880202014-11-14 07:58:25 -08001504 IInterface::asBinder(cameraClient),
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001505 clientPackageName,
1506 cameraId, cameraFacing,
1507 clientPid, clientUid,
1508 servicePid)
Igor Murashkin634a5152013-02-20 17:15:11 -08001509{
Mathias Agopian65ab4712010-07-14 17:59:35 -07001510 int callingPid = getCallingPid();
Wu-cheng Li2fd24402012-02-23 19:01:00 -08001511 LOG1("Client::Client E (pid %d, id %d)", callingPid, cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001512
Igor Murashkin44cfcf02013-03-01 16:22:28 -08001513 mRemoteCallback = cameraClient;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001514
Mathias Agopian65ab4712010-07-14 17:59:35 -07001515 cameraService->setCameraBusy(cameraId);
1516 cameraService->loadSound();
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001517
Wu-cheng Li2fd24402012-02-23 19:01:00 -08001518 LOG1("Client::Client X (pid %d, id %d)", callingPid, cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001519}
1520
Mathias Agopian65ab4712010-07-14 17:59:35 -07001521// tear down the client
1522CameraService::Client::~Client() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -07001523 ALOGV("~Client");
Igor Murashkin634a5152013-02-20 17:15:11 -08001524 mDestructionStarted = true;
1525
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001526 mCameraService->releaseSound();
Igor Murashkin036bc3e2012-10-08 15:09:46 -07001527 // unconditionally disconnect. function is idempotent
1528 Client::disconnect();
Mathias Agopian65ab4712010-07-14 17:59:35 -07001529}
1530
Igor Murashkin634a5152013-02-20 17:15:11 -08001531CameraService::BasicClient::BasicClient(const sp<CameraService>& cameraService,
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001532 const sp<IBinder>& remoteCallback,
1533 const String16& clientPackageName,
1534 int cameraId, int cameraFacing,
1535 int clientPid, uid_t clientUid,
1536 int servicePid):
1537 mClientPackageName(clientPackageName)
Igor Murashkin634a5152013-02-20 17:15:11 -08001538{
1539 mCameraService = cameraService;
Igor Murashkin44cfcf02013-03-01 16:22:28 -08001540 mRemoteBinder = remoteCallback;
Igor Murashkin634a5152013-02-20 17:15:11 -08001541 mCameraId = cameraId;
1542 mCameraFacing = cameraFacing;
1543 mClientPid = clientPid;
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001544 mClientUid = clientUid;
Igor Murashkin634a5152013-02-20 17:15:11 -08001545 mServicePid = servicePid;
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001546 mOpsActive = false;
Igor Murashkin634a5152013-02-20 17:15:11 -08001547 mDestructionStarted = false;
1548}
1549
1550CameraService::BasicClient::~BasicClient() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -07001551 ALOGV("~BasicClient");
Igor Murashkin634a5152013-02-20 17:15:11 -08001552 mDestructionStarted = true;
1553}
1554
1555void CameraService::BasicClient::disconnect() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -07001556 ALOGV("BasicClient::disconnect");
Igor Murashkin44cfcf02013-03-01 16:22:28 -08001557 mCameraService->removeClientByRemote(mRemoteBinder);
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001558
1559 finishCameraOps();
Igor Murashkincba2c162013-03-20 15:56:31 -07001560 // client shouldn't be able to call into us anymore
1561 mClientPid = 0;
Igor Murashkin634a5152013-02-20 17:15:11 -08001562}
1563
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001564status_t CameraService::BasicClient::startCameraOps() {
1565 int32_t res;
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001566 // Notify app ops that the camera is not available
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001567 mOpsCallback = new OpsCallback(this);
1568
Igor Murashkine6800ce2013-03-04 17:25:57 -08001569 {
1570 ALOGV("%s: Start camera ops, package name = %s, client UID = %d",
1571 __FUNCTION__, String8(mClientPackageName).string(), mClientUid);
1572 }
1573
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001574 mAppOpsManager.startWatchingMode(AppOpsManager::OP_CAMERA,
1575 mClientPackageName, mOpsCallback);
1576 res = mAppOpsManager.startOp(AppOpsManager::OP_CAMERA,
1577 mClientUid, mClientPackageName);
1578
1579 if (res != AppOpsManager::MODE_ALLOWED) {
1580 ALOGI("Camera %d: Access for \"%s\" has been revoked",
1581 mCameraId, String8(mClientPackageName).string());
1582 return PERMISSION_DENIED;
1583 }
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001584
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001585 mOpsActive = true;
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001586
1587 // Transition device availability listeners from PRESENT -> NOT_AVAILABLE
1588 mCameraService->updateStatus(ICameraServiceListener::STATUS_NOT_AVAILABLE,
1589 mCameraId);
1590
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001591 return OK;
1592}
1593
1594status_t CameraService::BasicClient::finishCameraOps() {
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001595 // Check if startCameraOps succeeded, and if so, finish the camera op
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001596 if (mOpsActive) {
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001597 // Notify app ops that the camera is available again
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001598 mAppOpsManager.finishOp(AppOpsManager::OP_CAMERA, mClientUid,
1599 mClientPackageName);
1600 mOpsActive = false;
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001601
1602 // Notify device availability listeners that this camera is available
1603 // again
1604
1605 StatusVector rejectSourceStates;
1606 rejectSourceStates.push_back(ICameraServiceListener::STATUS_NOT_PRESENT);
1607 rejectSourceStates.push_back(ICameraServiceListener::STATUS_ENUMERATING);
1608
1609 // Transition to PRESENT if the camera is not in either of above 2
1610 // states
1611 mCameraService->updateStatus(ICameraServiceListener::STATUS_PRESENT,
1612 mCameraId,
1613 &rejectSourceStates);
1614
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001615 }
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001616 // Always stop watching, even if no camera op is active
Eino-Ville Talvalae992e752014-11-07 16:17:48 -08001617 if (mOpsCallback != NULL) {
1618 mAppOpsManager.stopWatchingMode(mOpsCallback);
1619 }
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001620 mOpsCallback.clear();
1621
1622 return OK;
1623}
1624
1625void CameraService::BasicClient::opChanged(int32_t op, const String16& packageName) {
1626 String8 name(packageName);
1627 String8 myName(mClientPackageName);
1628
1629 if (op != AppOpsManager::OP_CAMERA) {
1630 ALOGW("Unexpected app ops notification received: %d", op);
1631 return;
1632 }
1633
1634 int32_t res;
1635 res = mAppOpsManager.checkOp(AppOpsManager::OP_CAMERA,
1636 mClientUid, mClientPackageName);
1637 ALOGV("checkOp returns: %d, %s ", res,
1638 res == AppOpsManager::MODE_ALLOWED ? "ALLOWED" :
1639 res == AppOpsManager::MODE_IGNORED ? "IGNORED" :
1640 res == AppOpsManager::MODE_ERRORED ? "ERRORED" :
1641 "UNKNOWN");
1642
1643 if (res != AppOpsManager::MODE_ALLOWED) {
1644 ALOGI("Camera %d: Access for \"%s\" revoked", mCameraId,
1645 myName.string());
1646 // Reset the client PID to allow server-initiated disconnect,
1647 // and to prevent further calls by client.
1648 mClientPid = getCallingPid();
Jianing Weicb0652e2014-03-12 18:29:36 -07001649 CaptureResultExtras resultExtras; // a dummy result (invalid)
1650 notifyError(ICameraDeviceCallbacks::ERROR_CAMERA_SERVICE, resultExtras);
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001651 disconnect();
1652 }
1653}
1654
Mathias Agopian65ab4712010-07-14 17:59:35 -07001655// ----------------------------------------------------------------------------
1656
Keun young Parkd8973a72012-03-28 14:13:09 -07001657Mutex* CameraService::Client::getClientLockFromCookie(void* user) {
Kévin PETIT377b2ec2014-02-03 12:35:36 +00001658 return gCameraService->getClientLockById((int)(intptr_t) user);
Keun young Parkd8973a72012-03-28 14:13:09 -07001659}
1660
1661// Provide client pointer for callbacks. Client lock returned from getClientLockFromCookie should
1662// be acquired for this to be safe
1663CameraService::Client* CameraService::Client::getClientFromCookie(void* user) {
Kévin PETIT377b2ec2014-02-03 12:35:36 +00001664 BasicClient *basicClient = gCameraService->getClientByIdUnsafe((int)(intptr_t) user);
Igor Murashkine7ee7632013-06-11 18:10:18 -07001665 // OK: only CameraClient calls this, and they already cast anyway.
1666 Client* client = static_cast<Client*>(basicClient);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001667
1668 // This could happen if the Client is in the process of shutting down (the
1669 // last strong reference is gone, but the destructor hasn't finished
1670 // stopping the hardware).
Keun young Parkd8973a72012-03-28 14:13:09 -07001671 if (client == NULL) return NULL;
1672
1673 // destruction already started, so should not be accessed
1674 if (client->mDestructionStarted) return NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001675
Mathias Agopian65ab4712010-07-14 17:59:35 -07001676 return client;
1677}
1678
Jianing Weicb0652e2014-03-12 18:29:36 -07001679void CameraService::Client::notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode,
1680 const CaptureResultExtras& resultExtras) {
Igor Murashkin44cfcf02013-03-01 16:22:28 -08001681 mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_RELEASED, 0);
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001682}
1683
Igor Murashkin036bc3e2012-10-08 15:09:46 -07001684// NOTE: function is idempotent
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001685void CameraService::Client::disconnect() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -07001686 ALOGV("Client::disconnect");
Igor Murashkin634a5152013-02-20 17:15:11 -08001687 BasicClient::disconnect();
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001688 mCameraService->setCameraFree(mCameraId);
Wu-cheng Lie09591e2010-10-14 20:17:44 +08001689}
1690
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001691CameraService::Client::OpsCallback::OpsCallback(wp<BasicClient> client):
1692 mClient(client) {
1693}
1694
1695void CameraService::Client::OpsCallback::opChanged(int32_t op,
1696 const String16& packageName) {
1697 sp<BasicClient> client = mClient.promote();
1698 if (client != NULL) {
1699 client->opChanged(op, packageName);
1700 }
1701}
1702
Mathias Agopian65ab4712010-07-14 17:59:35 -07001703// ----------------------------------------------------------------------------
Igor Murashkin634a5152013-02-20 17:15:11 -08001704// IProCamera
1705// ----------------------------------------------------------------------------
1706
1707CameraService::ProClient::ProClient(const sp<CameraService>& cameraService,
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001708 const sp<IProCameraCallbacks>& remoteCallback,
1709 const String16& clientPackageName,
1710 int cameraId,
1711 int cameraFacing,
1712 int clientPid,
1713 uid_t clientUid,
1714 int servicePid)
Marco Nelissenf8880202014-11-14 07:58:25 -08001715 : CameraService::BasicClient(cameraService, IInterface::asBinder(remoteCallback),
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001716 clientPackageName, cameraId, cameraFacing,
1717 clientPid, clientUid, servicePid)
Igor Murashkin634a5152013-02-20 17:15:11 -08001718{
1719 mRemoteCallback = remoteCallback;
1720}
1721
1722CameraService::ProClient::~ProClient() {
Igor Murashkin634a5152013-02-20 17:15:11 -08001723}
1724
Jianing Weicb0652e2014-03-12 18:29:36 -07001725void CameraService::ProClient::notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode,
1726 const CaptureResultExtras& resultExtras) {
Igor Murashkine6800ce2013-03-04 17:25:57 -08001727 mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_RELEASED, 0);
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001728}
1729
Igor Murashkin634a5152013-02-20 17:15:11 -08001730// ----------------------------------------------------------------------------
Mathias Agopian65ab4712010-07-14 17:59:35 -07001731
1732static const int kDumpLockRetries = 50;
1733static const int kDumpLockSleep = 60000;
1734
1735static bool tryLock(Mutex& mutex)
1736{
1737 bool locked = false;
1738 for (int i = 0; i < kDumpLockRetries; ++i) {
1739 if (mutex.tryLock() == NO_ERROR) {
1740 locked = true;
1741 break;
1742 }
1743 usleep(kDumpLockSleep);
1744 }
1745 return locked;
1746}
1747
1748status_t CameraService::dump(int fd, const Vector<String16>& args) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001749 String8 result;
1750 if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -07001751 result.appendFormat("Permission Denial: "
Mathias Agopian65ab4712010-07-14 17:59:35 -07001752 "can't dump CameraService from pid=%d, uid=%d\n",
1753 getCallingPid(),
1754 getCallingUid());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001755 write(fd, result.string(), result.size());
1756 } else {
1757 bool locked = tryLock(mServiceLock);
1758 // failed to lock - CameraService is probably deadlocked
1759 if (!locked) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -07001760 result.append("CameraService may be deadlocked\n");
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001761 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001762 }
1763
1764 bool hasClient = false;
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001765 if (!mModule) {
1766 result = String8::format("No camera module available!\n");
1767 write(fd, result.string(), result.size());
Kalle Lampila6ec3a152013-04-30 15:27:19 +03001768 if (locked) mServiceLock.unlock();
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001769 return NO_ERROR;
1770 }
1771
Yin-Chia Yehe074a932015-01-30 10:29:02 -08001772 const hw_module_t* common = mModule->getRawModule();
1773 result = String8::format("Camera module HAL API version: 0x%x\n", common->hal_api_version);
1774 result.appendFormat("Camera module API version: 0x%x\n", common->module_api_version);
1775 result.appendFormat("Camera module name: %s\n", common->name);
1776 result.appendFormat("Camera module author: %s\n", common->author);
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001777 result.appendFormat("Number of camera devices: %d\n\n", mNumberOfCameras);
Ruben Brunkf81648e2014-04-17 16:14:57 -07001778
1779 sp<VendorTagDescriptor> desc = VendorTagDescriptor::getGlobalVendorTagDescriptor();
1780 if (desc == NULL) {
1781 result.appendFormat("Vendor tags left unimplemented.\n");
1782 } else {
1783 result.appendFormat("Vendor tag definitions:\n");
1784 }
1785
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001786 write(fd, result.string(), result.size());
Ruben Brunkf81648e2014-04-17 16:14:57 -07001787
1788 if (desc != NULL) {
1789 desc->dump(fd, /*verbosity*/2, /*indentation*/4);
1790 }
1791
Mathias Agopian65ab4712010-07-14 17:59:35 -07001792 for (int i = 0; i < mNumberOfCameras; i++) {
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001793 result = String8::format("Camera %d static information:\n", i);
1794 camera_info info;
1795
Yin-Chia Yehe074a932015-01-30 10:29:02 -08001796 status_t rc = mModule->getCameraInfo(i, &info);
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001797 if (rc != OK) {
1798 result.appendFormat(" Error reading static information!\n");
1799 write(fd, result.string(), result.size());
1800 } else {
1801 result.appendFormat(" Facing: %s\n",
1802 info.facing == CAMERA_FACING_BACK ? "BACK" : "FRONT");
1803 result.appendFormat(" Orientation: %d\n", info.orientation);
1804 int deviceVersion;
Yin-Chia Yehe074a932015-01-30 10:29:02 -08001805 if (common->module_api_version < CAMERA_MODULE_API_VERSION_2_0) {
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001806 deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
1807 } else {
1808 deviceVersion = info.device_version;
1809 }
1810 result.appendFormat(" Device version: 0x%x\n", deviceVersion);
1811 if (deviceVersion >= CAMERA_DEVICE_API_VERSION_2_0) {
1812 result.appendFormat(" Device static metadata:\n");
1813 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -07001814 dump_indented_camera_metadata(info.static_camera_characteristics,
Ruben Brunkf81648e2014-04-17 16:14:57 -07001815 fd, /*verbosity*/2, /*indentation*/4);
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001816 } else {
1817 write(fd, result.string(), result.size());
1818 }
1819 }
1820
Igor Murashkine7ee7632013-06-11 18:10:18 -07001821 sp<BasicClient> client = mClient[i].promote();
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001822 if (client == 0) {
1823 result = String8::format(" Device is closed, no client instance\n");
1824 write(fd, result.string(), result.size());
1825 continue;
1826 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001827 hasClient = true;
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001828 result = String8::format(" Device is open. Client instance dump:\n");
1829 write(fd, result.string(), result.size());
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001830 client->dump(fd, args);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001831 }
1832 if (!hasClient) {
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001833 result = String8::format("\nNo active camera clients yet.\n");
1834 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001835 }
1836
1837 if (locked) mServiceLock.unlock();
1838
Igor Murashkinff3e31d2013-10-23 16:40:06 -07001839 // Dump camera traces if there were any
1840 write(fd, "\n", 1);
1841 camera3::CameraTraces::dump(fd, args);
1842
Mathias Agopian65ab4712010-07-14 17:59:35 -07001843 // change logging level
1844 int n = args.size();
1845 for (int i = 0; i + 1 < n; i++) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -07001846 String16 verboseOption("-v");
1847 if (args[i] == verboseOption) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001848 String8 levelStr(args[i+1]);
1849 int level = atoi(levelStr.string());
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001850 result = String8::format("\nSetting log level to %d.\n", level);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001851 setLogLevel(level);
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001852 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001853 }
1854 }
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001855
Mathias Agopian65ab4712010-07-14 17:59:35 -07001856 }
1857 return NO_ERROR;
1858}
1859
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001860void CameraService::handleTorchClientBinderDied(const wp<IBinder> &who) {
1861 Mutex::Autolock al(mTorchStatusMutex);
1862 for (size_t i = 0; i < mTorchClientMap.size(); i++) {
1863 if (mTorchClientMap[i] == who) {
1864 // turn off the torch mode that was turned on by dead client
1865 String16 cameraId = mTorchClientMap.keyAt(i);
1866 mFlashlight->setTorchMode(cameraId, false);
1867 mTorchClientMap.removeItemsAt(i);
1868
1869 // notify torch mode was turned off
1870 onTorchStatusChangedLocked(cameraId,
1871 ICameraServiceListener::TORCH_STATUS_OFF);
1872 break;
1873 }
1874 }
1875}
1876
Igor Murashkinecf17e82012-10-02 16:05:11 -07001877/*virtual*/void CameraService::binderDied(
1878 const wp<IBinder> &who) {
1879
Igor Murashkin294d0ec2012-10-05 10:44:57 -07001880 /**
1881 * While tempting to promote the wp<IBinder> into a sp,
1882 * it's actually not supported by the binder driver
1883 */
1884
Igor Murashkinecf17e82012-10-02 16:05:11 -07001885 ALOGV("java clients' binder died");
1886
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001887 // check torch client
1888 handleTorchClientBinderDied(who);
1889
1890 // check camera device client
Igor Murashkin634a5152013-02-20 17:15:11 -08001891 sp<BasicClient> cameraClient = getClientByRemote(who);
Igor Murashkinecf17e82012-10-02 16:05:11 -07001892
Igor Murashkin294d0ec2012-10-05 10:44:57 -07001893 if (cameraClient == 0) {
Igor Murashkinecf17e82012-10-02 16:05:11 -07001894 ALOGV("java clients' binder death already cleaned up (normal case)");
1895 return;
1896 }
1897
Igor Murashkinecf17e82012-10-02 16:05:11 -07001898 ALOGW("Disconnecting camera client %p since the binder for it "
1899 "died (this pid %d)", cameraClient.get(), getCallingPid());
1900
1901 cameraClient->disconnect();
1902
1903}
1904
Igor Murashkinbfc99152013-02-27 12:55:20 -08001905void CameraService::updateStatus(ICameraServiceListener::Status status,
Igor Murashkin93747b92013-05-01 15:42:20 -07001906 int32_t cameraId,
1907 const StatusVector *rejectSourceStates) {
Igor Murashkinbfc99152013-02-27 12:55:20 -08001908 // do not lock mServiceLock here or can get into a deadlock from
1909 // connect() -> ProClient::disconnect -> updateStatus
1910 Mutex::Autolock lock(mStatusMutex);
Igor Murashkinbfc99152013-02-27 12:55:20 -08001911
1912 ICameraServiceListener::Status oldStatus = mStatusList[cameraId];
1913
1914 mStatusList[cameraId] = status;
1915
1916 if (oldStatus != status) {
1917 ALOGV("%s: Status has changed for camera ID %d from 0x%x to 0x%x",
1918 __FUNCTION__, cameraId, (uint32_t)oldStatus, (uint32_t)status);
1919
Igor Murashkincba2c162013-03-20 15:56:31 -07001920 if (oldStatus == ICameraServiceListener::STATUS_NOT_PRESENT &&
1921 (status != ICameraServiceListener::STATUS_PRESENT &&
1922 status != ICameraServiceListener::STATUS_ENUMERATING)) {
1923
1924 ALOGW("%s: From NOT_PRESENT can only transition into PRESENT"
1925 " or ENUMERATING", __FUNCTION__);
1926 mStatusList[cameraId] = oldStatus;
1927 return;
1928 }
1929
Igor Murashkin93747b92013-05-01 15:42:20 -07001930 if (rejectSourceStates != NULL) {
1931 const StatusVector &rejectList = *rejectSourceStates;
1932 StatusVector::const_iterator it = rejectList.begin();
1933
1934 /**
1935 * Sometimes we want to conditionally do a transition.
1936 * For example if a client disconnects, we want to go to PRESENT
1937 * only if we weren't already in NOT_PRESENT or ENUMERATING.
1938 */
1939 for (; it != rejectList.end(); ++it) {
1940 if (oldStatus == *it) {
1941 ALOGV("%s: Rejecting status transition for Camera ID %d, "
1942 " since the source state was was in one of the bad "
1943 " states.", __FUNCTION__, cameraId);
1944 mStatusList[cameraId] = oldStatus;
1945 return;
1946 }
1947 }
1948 }
1949
Igor Murashkinbfc99152013-02-27 12:55:20 -08001950 /**
1951 * ProClients lose their exclusive lock.
1952 * - Done before the CameraClient can initialize the HAL device,
1953 * since we want to be able to close it before they get to initialize
1954 */
1955 if (status == ICameraServiceListener::STATUS_NOT_AVAILABLE) {
1956 Vector<wp<ProClient> > proClients(mProClientList[cameraId]);
1957 Vector<wp<ProClient> >::const_iterator it;
1958
1959 for (it = proClients.begin(); it != proClients.end(); ++it) {
1960 sp<ProClient> proCl = it->promote();
1961 if (proCl.get() != NULL) {
1962 proCl->onExclusiveLockStolen();
1963 }
1964 }
1965 }
1966
1967 Vector<sp<ICameraServiceListener> >::const_iterator it;
1968 for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
1969 (*it)->onStatusChanged(status, cameraId);
1970 }
1971 }
1972}
1973
Igor Murashkincba2c162013-03-20 15:56:31 -07001974ICameraServiceListener::Status CameraService::getStatus(int cameraId) const {
1975 if (cameraId < 0 || cameraId >= MAX_CAMERAS) {
1976 ALOGE("%s: Invalid camera ID %d", __FUNCTION__, cameraId);
1977 return ICameraServiceListener::STATUS_UNKNOWN;
1978 }
1979
1980 Mutex::Autolock al(mStatusMutex);
1981 return mStatusList[cameraId];
1982}
1983
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001984ICameraServiceListener::TorchStatus CameraService::getTorchStatusLocked(
1985 const String16& cameraId) const {
1986 ssize_t index = mTorchStatusMap.indexOfKey(cameraId);
1987 if (index == NAME_NOT_FOUND) {
1988 return ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE;
1989 }
1990
1991 return mTorchStatusMap.valueAt(index);
1992}
1993
1994status_t CameraService::setTorchStatusLocked(const String16& cameraId,
1995 ICameraServiceListener::TorchStatus status) {
1996 ssize_t index = mTorchStatusMap.indexOfKey(cameraId);
1997 if (index == NAME_NOT_FOUND) {
1998 return BAD_VALUE;
1999 }
2000 ICameraServiceListener::TorchStatus& item =
2001 mTorchStatusMap.editValueAt(index);
2002 item = status;
2003
2004 return OK;
2005}
2006
Mathias Agopian65ab4712010-07-14 17:59:35 -07002007}; // namespace android