blob: 6f37f163fcde5fc4864840f03f4d1647f983d302 [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) {
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800104 case TORCH_MODE_STATUS_NOT_AVAILABLE:
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800105 status = ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE;
106 break;
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800107 case TORCH_MODE_STATUS_AVAILABLE_OFF:
108 status = ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF;
109 break;
110 case TORCH_MODE_STATUS_AVAILABLE_ON:
111 status = ICameraServiceListener::TORCH_STATUS_AVAILABLE_ON;
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800112 break;
113 default:
114 ALOGE("Unknown torch status %d", new_status);
115 return;
116 }
117
118 cs->onTorchStatusChanged(
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800119 String8(camera_id),
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800120 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);
159 const hw_module_t *common = mModule->getRawModule();
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800160 ALOGI("Loaded \"%s\" cameraCa module", common->name);
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800161 mNumberOfCameras = mModule->getNumberOfCameras();
Iliyan Malchev8951a972011-04-14 16:55:59 -0700162 if (mNumberOfCameras > MAX_CAMERAS) {
Steve Block29357bc2012-01-06 19:20:56 +0000163 ALOGE("Number of cameras(%d) > MAX_CAMERAS(%d).",
Iliyan Malchev8951a972011-04-14 16:55:59 -0700164 mNumberOfCameras, MAX_CAMERAS);
165 mNumberOfCameras = MAX_CAMERAS;
166 }
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800167
168 mFlashlight = new CameraFlashlight(*mModule, *this);
169 status_t res = mFlashlight->findFlashUnits();
170 if (res) {
171 // impossible because we haven't open any camera devices.
172 ALOGE("failed to find flash units.");
173 }
174
Iliyan Malchev8951a972011-04-14 16:55:59 -0700175 for (int i = 0; i < mNumberOfCameras; i++) {
176 setCameraFree(i);
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800177
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800178 String8 cameraName = String8::format("%d", i);
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800179 if (mFlashlight->hasFlashUnit(cameraName)) {
180 mTorchStatusMap.add(cameraName,
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800181 ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF);
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800182 }
Iliyan Malchev8951a972011-04-14 16:55:59 -0700183 }
Igor Murashkincba2c162013-03-20 15:56:31 -0700184
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800185 if (common->module_api_version >= CAMERA_MODULE_API_VERSION_2_1) {
186 mModule->setCallbacks(this);
Igor Murashkincba2c162013-03-20 15:56:31 -0700187 }
Igor Murashkin98e24722013-06-19 19:51:04 -0700188
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800189 VendorTagDescriptor::clearGlobalVendorTagDescriptor();
190
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800191 if (common->module_api_version >= CAMERA_MODULE_API_VERSION_2_2) {
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800192 setUpVendorTags();
193 }
194
Igor Murashkin98e24722013-06-19 19:51:04 -0700195 CameraDeviceFactory::registerService(this);
Iliyan Malchev8951a972011-04-14 16:55:59 -0700196 }
197}
198
Mathias Agopian65ab4712010-07-14 17:59:35 -0700199CameraService::~CameraService() {
200 for (int i = 0; i < mNumberOfCameras; i++) {
201 if (mBusy[i]) {
Steve Block29357bc2012-01-06 19:20:56 +0000202 ALOGE("camera %d is still in use in destructor!", i);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700203 }
204 }
205
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800206 if (mModule) {
207 delete mModule;
208 }
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800209 VendorTagDescriptor::clearGlobalVendorTagDescriptor();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700210 gCameraService = NULL;
211}
212
Igor Murashkincba2c162013-03-20 15:56:31 -0700213void CameraService::onDeviceStatusChanged(int cameraId,
214 int newStatus)
215{
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800216 ALOGV("%s: Status changed for cameraId=%d, newStatus=%d", __FUNCTION__,
Igor Murashkincba2c162013-03-20 15:56:31 -0700217 cameraId, newStatus);
218
219 if (cameraId < 0 || cameraId >= MAX_CAMERAS) {
220 ALOGE("%s: Bad camera ID %d", __FUNCTION__, cameraId);
221 return;
222 }
223
224 if ((int)getStatus(cameraId) == newStatus) {
225 ALOGE("%s: State transition to the same status 0x%x not allowed",
226 __FUNCTION__, (uint32_t)newStatus);
227 return;
228 }
229
230 /* don't do this in updateStatus
231 since it is also called from connect and we could get into a deadlock */
232 if (newStatus == CAMERA_DEVICE_STATUS_NOT_PRESENT) {
233 Vector<sp<BasicClient> > clientsToDisconnect;
234 {
235 Mutex::Autolock al(mServiceLock);
236
Ruben Brunkb2119af2014-05-09 19:57:56 -0700237 /* Remove cached parameters from shim cache */
238 mShimParams.removeItem(cameraId);
239
Igor Murashkincba2c162013-03-20 15:56:31 -0700240 /* Find all clients that we need to disconnect */
Igor Murashkine7ee7632013-06-11 18:10:18 -0700241 sp<BasicClient> client = mClient[cameraId].promote();
Igor Murashkincba2c162013-03-20 15:56:31 -0700242 if (client.get() != NULL) {
243 clientsToDisconnect.push_back(client);
244 }
245
246 int i = cameraId;
247 for (size_t j = 0; j < mProClientList[i].size(); ++j) {
248 sp<ProClient> cl = mProClientList[i][j].promote();
249 if (cl != NULL) {
250 clientsToDisconnect.push_back(cl);
251 }
252 }
253 }
254
255 /* now disconnect them. don't hold the lock
256 or we can get into a deadlock */
257
258 for (size_t i = 0; i < clientsToDisconnect.size(); ++i) {
259 sp<BasicClient> client = clientsToDisconnect[i];
260
261 client->disconnect();
262 /**
263 * The remote app will no longer be able to call methods on the
264 * client since the client PID will be reset to 0
265 */
266 }
267
Colin Crosse5729fa2014-03-21 15:04:25 -0700268 ALOGV("%s: After unplug, disconnected %zu clients",
Igor Murashkincba2c162013-03-20 15:56:31 -0700269 __FUNCTION__, clientsToDisconnect.size());
270 }
271
272 updateStatus(
273 static_cast<ICameraServiceListener::Status>(newStatus), cameraId);
274
275}
276
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800277void CameraService::onTorchStatusChanged(const String8& cameraId,
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800278 ICameraServiceListener::TorchStatus newStatus) {
279 Mutex::Autolock al(mTorchStatusMutex);
280 onTorchStatusChangedLocked(cameraId, newStatus);
281}
282
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800283void CameraService::onTorchStatusChangedLocked(const String8& cameraId,
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800284 ICameraServiceListener::TorchStatus newStatus) {
285 ALOGI("%s: Torch status changed for cameraId=%s, newStatus=%d",
286 __FUNCTION__, cameraId.string(), newStatus);
287
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800288 ICameraServiceListener::TorchStatus status;
289 status_t res = getTorchStatusLocked(cameraId, &status);
290 if (res) {
291 ALOGE("%s: cannot get torch status of camera %s", cameraId.string());
292 return;
293 }
294 if (status == newStatus) {
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800295 ALOGE("%s: Torch state transition to the same status 0x%x not allowed",
296 __FUNCTION__, (uint32_t)newStatus);
297 return;
298 }
299
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800300 res = setTorchStatusLocked(cameraId, newStatus);
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800301 if (res) {
302 ALOGE("%s: Failed to set the torch status", __FUNCTION__,
303 (uint32_t)newStatus);
304 return;
305 }
306
307 Vector<sp<ICameraServiceListener> >::const_iterator it;
308 for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800309 (*it)->onTorchStatusChanged(newStatus, String16(cameraId.string()));
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800310 }
311}
312
313
Mathias Agopian65ab4712010-07-14 17:59:35 -0700314int32_t CameraService::getNumberOfCameras() {
315 return mNumberOfCameras;
316}
317
318status_t CameraService::getCameraInfo(int cameraId,
319 struct CameraInfo* cameraInfo) {
Iliyan Malchev8951a972011-04-14 16:55:59 -0700320 if (!mModule) {
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700321 return -ENODEV;
Iliyan Malchev8951a972011-04-14 16:55:59 -0700322 }
323
Mathias Agopian65ab4712010-07-14 17:59:35 -0700324 if (cameraId < 0 || cameraId >= mNumberOfCameras) {
325 return BAD_VALUE;
326 }
327
Iliyan Malchev8951a972011-04-14 16:55:59 -0700328 struct camera_info info;
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -0700329 status_t rc = filterGetInfoErrorCode(
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800330 mModule->getCameraInfo(cameraId, &info));
Iliyan Malchev8951a972011-04-14 16:55:59 -0700331 cameraInfo->facing = info.facing;
332 cameraInfo->orientation = info.orientation;
333 return rc;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700334}
335
Ruben Brunkb2119af2014-05-09 19:57:56 -0700336
337status_t CameraService::generateShimMetadata(int cameraId, /*out*/CameraMetadata* cameraInfo) {
338 status_t ret = OK;
339 struct CameraInfo info;
340 if ((ret = getCameraInfo(cameraId, &info)) != OK) {
341 return ret;
342 }
343
344 CameraMetadata shimInfo;
345 int32_t orientation = static_cast<int32_t>(info.orientation);
346 if ((ret = shimInfo.update(ANDROID_SENSOR_ORIENTATION, &orientation, 1)) != OK) {
347 return ret;
348 }
349
350 uint8_t facing = (info.facing == CAMERA_FACING_FRONT) ?
351 ANDROID_LENS_FACING_FRONT : ANDROID_LENS_FACING_BACK;
352 if ((ret = shimInfo.update(ANDROID_LENS_FACING, &facing, 1)) != OK) {
353 return ret;
354 }
355
Igor Murashkin65d14b92014-06-17 12:03:20 -0700356 CameraParameters shimParams;
357 if ((ret = getLegacyParametersLazy(cameraId, /*out*/&shimParams)) != OK) {
358 // Error logged by callee
359 return ret;
Ruben Brunkb2119af2014-05-09 19:57:56 -0700360 }
361
362 Vector<Size> sizes;
Ruben Brunk152dbcf2014-06-12 19:11:45 -0700363 Vector<Size> jpegSizes;
Ruben Brunkb2119af2014-05-09 19:57:56 -0700364 Vector<int32_t> formats;
365 const char* supportedPreviewFormats;
Igor Murashkin65d14b92014-06-17 12:03:20 -0700366 {
367 shimParams.getSupportedPreviewSizes(/*out*/sizes);
368 shimParams.getSupportedPreviewFormats(/*out*/formats);
369 shimParams.getSupportedPictureSizes(/*out*/jpegSizes);
Ruben Brunkb2119af2014-05-09 19:57:56 -0700370 }
371
372 // Always include IMPLEMENTATION_DEFINED
373 formats.add(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED);
374
375 const size_t INTS_PER_CONFIG = 4;
376
377 // Build available stream configurations metadata
Ruben Brunk152dbcf2014-06-12 19:11:45 -0700378 size_t streamConfigSize = (sizes.size() * formats.size() + jpegSizes.size()) * INTS_PER_CONFIG;
379
380 Vector<int32_t> streamConfigs;
381 streamConfigs.setCapacity(streamConfigSize);
382
Ruben Brunkb2119af2014-05-09 19:57:56 -0700383 for (size_t i = 0; i < formats.size(); ++i) {
384 for (size_t j = 0; j < sizes.size(); ++j) {
Ruben Brunk152dbcf2014-06-12 19:11:45 -0700385 streamConfigs.add(formats[i]);
386 streamConfigs.add(sizes[j].width);
387 streamConfigs.add(sizes[j].height);
388 streamConfigs.add(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
Ruben Brunkb2119af2014-05-09 19:57:56 -0700389 }
390 }
391
Ruben Brunk152dbcf2014-06-12 19:11:45 -0700392 for (size_t i = 0; i < jpegSizes.size(); ++i) {
393 streamConfigs.add(HAL_PIXEL_FORMAT_BLOB);
394 streamConfigs.add(jpegSizes[i].width);
395 streamConfigs.add(jpegSizes[i].height);
396 streamConfigs.add(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
397 }
398
Ruben Brunkb2119af2014-05-09 19:57:56 -0700399 if ((ret = shimInfo.update(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
Ruben Brunk152dbcf2014-06-12 19:11:45 -0700400 streamConfigs.array(), streamConfigSize)) != OK) {
Ruben Brunkb2119af2014-05-09 19:57:56 -0700401 return ret;
402 }
403
404 int64_t fakeMinFrames[0];
405 // TODO: Fixme, don't fake min frame durations.
406 if ((ret = shimInfo.update(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
407 fakeMinFrames, 0)) != OK) {
408 return ret;
409 }
410
411 int64_t fakeStalls[0];
412 // TODO: Fixme, don't fake stall durations.
413 if ((ret = shimInfo.update(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
414 fakeStalls, 0)) != OK) {
415 return ret;
416 }
417
418 *cameraInfo = shimInfo;
419 return OK;
420}
421
Zhijun He2b59be82013-09-25 10:14:30 -0700422status_t CameraService::getCameraCharacteristics(int cameraId,
423 CameraMetadata* cameraInfo) {
424 if (!cameraInfo) {
425 ALOGE("%s: cameraInfo is NULL", __FUNCTION__);
426 return BAD_VALUE;
427 }
428
429 if (!mModule) {
430 ALOGE("%s: camera hardware module doesn't exist", __FUNCTION__);
431 return -ENODEV;
432 }
433
Zhijun He2b59be82013-09-25 10:14:30 -0700434 if (cameraId < 0 || cameraId >= mNumberOfCameras) {
435 ALOGE("%s: Invalid camera id: %d", __FUNCTION__, cameraId);
436 return BAD_VALUE;
437 }
438
439 int facing;
Ruben Brunkb2119af2014-05-09 19:57:56 -0700440 status_t ret = OK;
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800441 if (mModule->getRawModule()->module_api_version < CAMERA_MODULE_API_VERSION_2_0 ||
Ruben Brunkb2119af2014-05-09 19:57:56 -0700442 getDeviceVersion(cameraId, &facing) <= CAMERA_DEVICE_API_VERSION_2_1 ) {
443 /**
444 * Backwards compatibility mode for old HALs:
445 * - Convert CameraInfo into static CameraMetadata properties.
446 * - Retrieve cached CameraParameters for this camera. If none exist,
447 * attempt to open CameraClient and retrieve the CameraParameters.
448 * - Convert cached CameraParameters into static CameraMetadata
449 * properties.
450 */
451 ALOGI("%s: Switching to HAL1 shim implementation...", __FUNCTION__);
Zhijun He2b59be82013-09-25 10:14:30 -0700452
Ruben Brunkb2119af2014-05-09 19:57:56 -0700453 if ((ret = generateShimMetadata(cameraId, cameraInfo)) != OK) {
454 return ret;
455 }
Zhijun Hef05e50e2013-10-01 11:05:33 -0700456
Ruben Brunkb2119af2014-05-09 19:57:56 -0700457 } else {
458 /**
459 * Normal HAL 2.1+ codepath.
460 */
461 struct camera_info info;
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800462 ret = filterGetInfoErrorCode(mModule->getCameraInfo(cameraId, &info));
Ruben Brunkb2119af2014-05-09 19:57:56 -0700463 *cameraInfo = info.static_camera_characteristics;
464 }
Zhijun He2b59be82013-09-25 10:14:30 -0700465
466 return ret;
467}
468
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800469status_t CameraService::getCameraVendorTagDescriptor(/*out*/sp<VendorTagDescriptor>& desc) {
470 if (!mModule) {
471 ALOGE("%s: camera hardware module doesn't exist", __FUNCTION__);
472 return -ENODEV;
473 }
474
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800475 desc = VendorTagDescriptor::getGlobalVendorTagDescriptor();
476 return OK;
477}
478
Igor Murashkin634a5152013-02-20 17:15:11 -0800479int CameraService::getDeviceVersion(int cameraId, int* facing) {
480 struct camera_info info;
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800481 if (mModule->getCameraInfo(cameraId, &info) != OK) {
Igor Murashkin634a5152013-02-20 17:15:11 -0800482 return -1;
483 }
484
485 int deviceVersion;
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800486 if (mModule->getRawModule()->module_api_version >= CAMERA_MODULE_API_VERSION_2_0) {
Igor Murashkin634a5152013-02-20 17:15:11 -0800487 deviceVersion = info.device_version;
488 } else {
489 deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
490 }
491
492 if (facing) {
493 *facing = info.facing;
494 }
495
496 return deviceVersion;
497}
498
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];
Amith Yamasani228711d2015-02-13 13:25:39 -0800673 char key[PROPERTY_KEY_MAX];
674 int clientUserId = multiuser_get_user_id(clientUid);
675 snprintf(key, PROPERTY_KEY_MAX, "sys.secpolicy.camera.off_%d", clientUserId);
676 property_get(key, value, "0");
Wu-cheng Lia3355432011-05-20 14:54:25 +0800677 if (strcmp(value, "1") == 0) {
678 // Camera is disabled by DevicePolicyManager.
Steve Blockdf64d152012-01-04 20:05:49 +0000679 ALOGI("Camera is disabled. connect X (pid %d) rejected", callingPid);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700680 return -EACCES;
Wu-cheng Lia3355432011-05-20 14:54:25 +0800681 }
682
Igor Murashkincba2c162013-03-20 15:56:31 -0700683 ICameraServiceListener::Status currentStatus = getStatus(cameraId);
684 if (currentStatus == ICameraServiceListener::STATUS_NOT_PRESENT) {
685 ALOGI("Camera is not plugged in,"
686 " connect X (pid %d) rejected", callingPid);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700687 return -ENODEV;
Igor Murashkincba2c162013-03-20 15:56:31 -0700688 } else if (currentStatus == ICameraServiceListener::STATUS_ENUMERATING) {
689 ALOGI("Camera is enumerating,"
690 " connect X (pid %d) rejected", callingPid);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700691 return -EBUSY;
Igor Murashkincba2c162013-03-20 15:56:31 -0700692 }
693 // Else don't check for STATUS_NOT_AVAILABLE.
694 // -- It's done implicitly in canConnectUnsafe /w the mBusy array
695
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700696 return OK;
Igor Murashkine6800ce2013-03-04 17:25:57 -0800697}
698
699bool CameraService::canConnectUnsafe(int cameraId,
700 const String16& clientPackageName,
701 const sp<IBinder>& remoteCallback,
Igor Murashkine7ee7632013-06-11 18:10:18 -0700702 sp<BasicClient> &client) {
Igor Murashkine6800ce2013-03-04 17:25:57 -0800703 String8 clientName8(clientPackageName);
704 int callingPid = getCallingPid();
705
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800706 if (mClient[cameraId] != 0) {
707 client = mClient[cameraId].promote();
708 if (client != 0) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700709 if (remoteCallback == client->getRemote()) {
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800710 LOG1("CameraService::connect X (pid %d) (the same client)",
711 callingPid);
Igor Murashkine6800ce2013-03-04 17:25:57 -0800712 return true;
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800713 } else {
Igor Murashkine6800ce2013-03-04 17:25:57 -0800714 // TODOSC: need to support 1 regular client,
715 // multiple shared clients here
716 ALOGW("CameraService::connect X (pid %d) rejected"
717 " (existing client).", callingPid);
718 return false;
Wu-cheng Li2fd24402012-02-23 19:01:00 -0800719 }
Wu-cheng Li2fd24402012-02-23 19:01:00 -0800720 }
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800721 mClient[cameraId].clear();
722 }
723
Igor Murashkin634a5152013-02-20 17:15:11 -0800724 /*
725 mBusy is set to false as the last step of the Client destructor,
726 after which it is guaranteed that the Client destructor has finished (
727 including any inherited destructors)
728
729 We only need this for a Client subclasses since we don't allow
730 multiple Clents to be opened concurrently, but multiple BasicClient
731 would be fine
732 */
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800733 if (mBusy[cameraId]) {
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800734 ALOGW("CameraService::connect X (pid %d, \"%s\") rejected"
735 " (camera %d is still busy).", callingPid,
736 clientName8.string(), cameraId);
Igor Murashkine6800ce2013-03-04 17:25:57 -0800737 return false;
738 }
739
740 return true;
741}
742
Igor Murashkina858ea02014-08-19 14:53:08 -0700743status_t CameraService::connectHelperLocked(
744 /*out*/
745 sp<Client>& client,
746 /*in*/
747 const sp<ICameraClient>& cameraClient,
748 int cameraId,
749 const String16& clientPackageName,
750 int clientUid,
751 int callingPid,
752 int halVersion,
753 bool legacyMode) {
Ruben Brunkb2119af2014-05-09 19:57:56 -0700754
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800755 // give flashlight a chance to close devices if necessary.
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800756 mFlashlight->prepareDeviceOpen(String8::format("%d", cameraId));
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800757
Ruben Brunkb2119af2014-05-09 19:57:56 -0700758 int facing = -1;
759 int deviceVersion = getDeviceVersion(cameraId, &facing);
760
Zhijun Heb10cdad2014-06-16 16:38:35 -0700761 if (halVersion < 0 || halVersion == deviceVersion) {
762 // Default path: HAL version is unspecified by caller, create CameraClient
763 // based on device version reported by the HAL.
764 switch(deviceVersion) {
765 case CAMERA_DEVICE_API_VERSION_1_0:
766 client = new CameraClient(this, cameraClient,
767 clientPackageName, cameraId,
Igor Murashkina858ea02014-08-19 14:53:08 -0700768 facing, callingPid, clientUid, getpid(), legacyMode);
Zhijun Heb10cdad2014-06-16 16:38:35 -0700769 break;
770 case CAMERA_DEVICE_API_VERSION_2_0:
771 case CAMERA_DEVICE_API_VERSION_2_1:
772 case CAMERA_DEVICE_API_VERSION_3_0:
773 case CAMERA_DEVICE_API_VERSION_3_1:
774 case CAMERA_DEVICE_API_VERSION_3_2:
775 client = new Camera2Client(this, cameraClient,
776 clientPackageName, cameraId,
Igor Murashkina858ea02014-08-19 14:53:08 -0700777 facing, callingPid, clientUid, getpid(), legacyMode);
Zhijun Heb10cdad2014-06-16 16:38:35 -0700778 break;
779 case -1:
780 ALOGE("Invalid camera id %d", cameraId);
781 return BAD_VALUE;
782 default:
783 ALOGE("Unknown camera device HAL version: %d", deviceVersion);
784 return INVALID_OPERATION;
785 }
786 } else {
787 // A particular HAL version is requested by caller. Create CameraClient
788 // based on the requested HAL version.
789 if (deviceVersion > CAMERA_DEVICE_API_VERSION_1_0 &&
790 halVersion == CAMERA_DEVICE_API_VERSION_1_0) {
791 // Only support higher HAL version device opened as HAL1.0 device.
792 client = new CameraClient(this, cameraClient,
793 clientPackageName, cameraId,
Igor Murashkina858ea02014-08-19 14:53:08 -0700794 facing, callingPid, clientUid, getpid(), legacyMode);
Zhijun Heb10cdad2014-06-16 16:38:35 -0700795 } else {
796 // Other combinations (e.g. HAL3.x open as HAL2.x) are not supported yet.
797 ALOGE("Invalid camera HAL version %x: HAL %x device can only be"
798 " opened as HAL %x device", halVersion, deviceVersion,
799 CAMERA_DEVICE_API_VERSION_1_0);
800 return INVALID_OPERATION;
801 }
Ruben Brunkb2119af2014-05-09 19:57:56 -0700802 }
803
804 status_t status = connectFinishUnsafe(client, client->getRemote());
805 if (status != OK) {
806 // this is probably not recoverable.. maybe the client can try again
Ruben Brunkb2119af2014-05-09 19:57:56 -0700807 return status;
808 }
809
810 mClient[cameraId] = client;
811 LOG1("CameraService::connect X (id %d, this pid is %d)", cameraId,
812 getpid());
813
814 return OK;
815}
816
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700817status_t CameraService::connect(
Igor Murashkine6800ce2013-03-04 17:25:57 -0800818 const sp<ICameraClient>& cameraClient,
819 int cameraId,
820 const String16& clientPackageName,
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700821 int clientUid,
822 /*out*/
823 sp<ICamera>& device) {
Igor Murashkine6800ce2013-03-04 17:25:57 -0800824
825 String8 clientName8(clientPackageName);
826 int callingPid = getCallingPid();
827
828 LOG1("CameraService::connect E (pid %d \"%s\", id %d)", callingPid,
829 clientName8.string(), cameraId);
830
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700831 status_t status = validateConnect(cameraId, /*inout*/clientUid);
832 if (status != OK) {
833 return status;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700834 }
835
Igor Murashkine6800ce2013-03-04 17:25:57 -0800836
Igor Murashkine7ee7632013-06-11 18:10:18 -0700837 sp<Client> client;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700838 {
839 Mutex::Autolock lock(mServiceLock);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700840 sp<BasicClient> clientTmp;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700841 if (!canConnectUnsafe(cameraId, clientPackageName,
Marco Nelissenf8880202014-11-14 07:58:25 -0800842 IInterface::asBinder(cameraClient),
Igor Murashkine7ee7632013-06-11 18:10:18 -0700843 /*out*/clientTmp)) {
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700844 return -EBUSY;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700845 } else if (client.get() != NULL) {
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700846 device = static_cast<Client*>(clientTmp.get());
847 return OK;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700848 }
849
Igor Murashkina858ea02014-08-19 14:53:08 -0700850 status = connectHelperLocked(/*out*/client,
851 cameraClient,
Ruben Brunkb2119af2014-05-09 19:57:56 -0700852 cameraId,
853 clientPackageName,
854 clientUid,
Igor Murashkina858ea02014-08-19 14:53:08 -0700855 callingPid);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700856 if (status != OK) {
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700857 return status;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700858 }
859
Igor Murashkine6800ce2013-03-04 17:25:57 -0800860 }
Igor Murashkinacd695c2013-03-13 17:23:00 -0700861 // important: release the mutex here so the client can call back
862 // into the service from its destructor (can be at the end of the call)
Igor Murashkinbfc99152013-02-27 12:55:20 -0800863
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700864 device = client;
865 return OK;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700866}
867
Zhijun Heb10cdad2014-06-16 16:38:35 -0700868status_t CameraService::connectLegacy(
869 const sp<ICameraClient>& cameraClient,
870 int cameraId, int halVersion,
871 const String16& clientPackageName,
872 int clientUid,
873 /*out*/
874 sp<ICamera>& device) {
875
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800876 int apiVersion = mModule->getRawModule()->module_api_version;
Igor Murashkin3d07d1a2014-06-20 11:27:03 -0700877 if (halVersion != CAMERA_HAL_API_VERSION_UNSPECIFIED &&
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800878 apiVersion < CAMERA_MODULE_API_VERSION_2_3) {
Igor Murashkin3d07d1a2014-06-20 11:27:03 -0700879 /*
880 * Either the HAL version is unspecified in which case this just creates
881 * a camera client selected by the latest device version, or
882 * it's a particular version in which case the HAL must supported
883 * the open_legacy call
884 */
Zhijun Heb10cdad2014-06-16 16:38:35 -0700885 ALOGE("%s: camera HAL module version %x doesn't support connecting to legacy HAL devices!",
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800886 __FUNCTION__, apiVersion);
Zhijun Heb10cdad2014-06-16 16:38:35 -0700887 return INVALID_OPERATION;
888 }
889
890 String8 clientName8(clientPackageName);
891 int callingPid = getCallingPid();
892
893 LOG1("CameraService::connect legacy E (pid %d \"%s\", id %d)", callingPid,
894 clientName8.string(), cameraId);
895
896 status_t status = validateConnect(cameraId, /*inout*/clientUid);
897 if (status != OK) {
898 return status;
899 }
900
901 sp<Client> client;
902 {
903 Mutex::Autolock lock(mServiceLock);
904 sp<BasicClient> clientTmp;
905 if (!canConnectUnsafe(cameraId, clientPackageName,
Marco Nelissenf8880202014-11-14 07:58:25 -0800906 IInterface::asBinder(cameraClient),
Zhijun Heb10cdad2014-06-16 16:38:35 -0700907 /*out*/clientTmp)) {
908 return -EBUSY;
909 } else if (client.get() != NULL) {
910 device = static_cast<Client*>(clientTmp.get());
911 return OK;
912 }
913
Igor Murashkina858ea02014-08-19 14:53:08 -0700914 status = connectHelperLocked(/*out*/client,
915 cameraClient,
Zhijun Heb10cdad2014-06-16 16:38:35 -0700916 cameraId,
917 clientPackageName,
918 clientUid,
919 callingPid,
Igor Murashkina858ea02014-08-19 14:53:08 -0700920 halVersion,
921 /*legacyMode*/true);
Zhijun Heb10cdad2014-06-16 16:38:35 -0700922 if (status != OK) {
923 return status;
924 }
925
926 }
927 // important: release the mutex here so the client can call back
928 // into the service from its destructor (can be at the end of the call)
929
930 device = client;
931 return OK;
932}
933
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800934bool CameraService::validCameraIdForSetTorchMode(const String8& cameraId) {
935 // invalid string for int
936 if (cameraId.string() == NULL) {
937 return false;
938 }
939 errno = 0;
940 char *endptr;
941 long id = strtol(cameraId.string(), &endptr, 10); // base 10
942 if (errno || id > INT_MAX || id < INT_MIN || *endptr != 0) {
943 return false;
944 }
945
946 // id matches one of the plugged-in devices?
947 ICameraServiceListener::Status deviceStatus = getStatus(id);
948 if (deviceStatus != ICameraServiceListener::STATUS_PRESENT &&
949 deviceStatus != ICameraServiceListener::STATUS_NOT_AVAILABLE) {
950 return false;
951 }
952
953 return true;
954}
955
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800956status_t CameraService::setTorchMode(const String16& cameraId, bool enabled,
957 const sp<IBinder>& clientBinder) {
958 if (enabled && clientBinder == NULL) {
959 ALOGE("%s: torch client binder is NULL", __FUNCTION__);
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800960 return -EINVAL;
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800961 }
962
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800963 String8 id = String8(cameraId.string());
964
965 // verify id is valid.
966 if (validCameraIdForSetTorchMode(id) == false) {
967 ALOGE("%s: camera id is invalid %s", id.string());
968 return -EINVAL;
969 }
970
971 {
972 Mutex::Autolock al(mTorchStatusMutex);
973 ICameraServiceListener::TorchStatus status;
974 status_t res = getTorchStatusLocked(id, &status);
975 if (res) {
976 ALOGE("%s: getting current torch status failed for camera %s",
977 __FUNCTION__, id.string());
978 return -EINVAL;
979 }
980
981 if (status == ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE) {
982 if (getStatus(atoi(id.string())) ==
983 ICameraServiceListener::STATUS_NOT_AVAILABLE) {
984 ALOGE("%s: torch mode of camera %s is not available because "
985 "camera is in use", __FUNCTION__, id.string());
986 return -EBUSY;
987 } else {
988 ALOGE("%s: torch mode of camera %s is not available due to "
989 "insufficient resources", __FUNCTION__, id.string());
990 return -EUSERS;
991 }
992 }
993 }
994
995 status_t res = mFlashlight->setTorchMode(id, enabled);
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800996 if (res) {
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800997 ALOGE("%s: setting torch mode of camera %s to %d failed. %s (%d)",
998 __FUNCTION__, id.string(), enabled, strerror(-res), res);
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800999 return res;
1000 }
1001
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001002 {
1003 // update the link to client's death
1004 Mutex::Autolock al(mTorchClientMapMutex);
1005 ssize_t index = mTorchClientMap.indexOfKey(id);
1006 if (enabled) {
1007 if (index == NAME_NOT_FOUND) {
1008 mTorchClientMap.add(id, clientBinder);
1009 } else {
1010 const sp<IBinder> oldBinder = mTorchClientMap.valueAt(index);
1011 oldBinder->unlinkToDeath(this);
1012
1013 mTorchClientMap.replaceValueAt(index, clientBinder);
1014 }
1015 clientBinder->linkToDeath(this);
1016 } else if (index != NAME_NOT_FOUND) {
1017 sp<IBinder> oldBinder = mTorchClientMap.valueAt(index);
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001018 oldBinder->unlinkToDeath(this);
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001019 }
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001020 }
1021
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001022 return OK;
1023}
1024
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001025status_t CameraService::connectFinishUnsafe(const sp<BasicClient>& client,
1026 const sp<IBinder>& remoteCallback) {
1027 status_t status = client->initialize(mModule);
1028 if (status != OK) {
Ruben Brunk5fc9d902014-11-20 13:34:36 -08001029 ALOGE("%s: Could not initialize client from HAL module.", __FUNCTION__);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001030 return status;
Igor Murashkine6800ce2013-03-04 17:25:57 -08001031 }
Ruben Brunkb2119af2014-05-09 19:57:56 -07001032 if (remoteCallback != NULL) {
1033 remoteCallback->linkToDeath(this);
1034 }
Igor Murashkine6800ce2013-03-04 17:25:57 -08001035
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001036 return OK;
Igor Murashkine6800ce2013-03-04 17:25:57 -08001037}
1038
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001039status_t CameraService::connectPro(
Igor Murashkin634a5152013-02-20 17:15:11 -08001040 const sp<IProCameraCallbacks>& cameraCb,
Igor Murashkinc073ba52013-02-26 14:32:34 -08001041 int cameraId,
1042 const String16& clientPackageName,
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001043 int clientUid,
1044 /*out*/
1045 sp<IProCameraUser>& device)
Igor Murashkin634a5152013-02-20 17:15:11 -08001046{
Natalie Silvanoviche1b55da2014-05-01 14:44:52 -07001047 if (cameraCb == 0) {
1048 ALOGE("%s: Callback must not be null", __FUNCTION__);
1049 return BAD_VALUE;
1050 }
1051
Igor Murashkinbfc99152013-02-27 12:55:20 -08001052 String8 clientName8(clientPackageName);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001053 int callingPid = getCallingPid();
Igor Murashkin634a5152013-02-20 17:15:11 -08001054
Igor Murashkine6800ce2013-03-04 17:25:57 -08001055 LOG1("CameraService::connectPro E (pid %d \"%s\", id %d)", callingPid,
1056 clientName8.string(), cameraId);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001057 status_t status = validateConnect(cameraId, /*inout*/clientUid);
1058 if (status != OK) {
1059 return status;
Igor Murashkin634a5152013-02-20 17:15:11 -08001060 }
1061
Igor Murashkinacd695c2013-03-13 17:23:00 -07001062 sp<ProClient> client;
Igor Murashkine6800ce2013-03-04 17:25:57 -08001063 {
Igor Murashkinacd695c2013-03-13 17:23:00 -07001064 Mutex::Autolock lock(mServiceLock);
1065 {
Igor Murashkine7ee7632013-06-11 18:10:18 -07001066 sp<BasicClient> client;
Igor Murashkinacd695c2013-03-13 17:23:00 -07001067 if (!canConnectUnsafe(cameraId, clientPackageName,
Marco Nelissenf8880202014-11-14 07:58:25 -08001068 IInterface::asBinder(cameraCb),
Igor Murashkinacd695c2013-03-13 17:23:00 -07001069 /*out*/client)) {
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001070 return -EBUSY;
Igor Murashkinacd695c2013-03-13 17:23:00 -07001071 }
1072 }
1073
1074 int facing = -1;
1075 int deviceVersion = getDeviceVersion(cameraId, &facing);
1076
1077 switch(deviceVersion) {
1078 case CAMERA_DEVICE_API_VERSION_1_0:
1079 ALOGE("Camera id %d uses HALv1, doesn't support ProCamera",
1080 cameraId);
Ruben Brunk17963d12013-08-19 15:21:19 -07001081 return -EOPNOTSUPP;
Igor Murashkinacd695c2013-03-13 17:23:00 -07001082 break;
1083 case CAMERA_DEVICE_API_VERSION_2_0:
1084 case CAMERA_DEVICE_API_VERSION_2_1:
Zhijun He47110052013-07-22 17:34:34 -07001085 case CAMERA_DEVICE_API_VERSION_3_0:
Zhijun He95dd5ba2014-03-26 18:18:00 -07001086 case CAMERA_DEVICE_API_VERSION_3_1:
1087 case CAMERA_DEVICE_API_VERSION_3_2:
Eino-Ville Talvala63d877f2014-06-16 19:21:12 -07001088 client = new ProCamera2Client(this, cameraCb, clientPackageName,
1089 cameraId, facing, callingPid, clientUid, getpid());
Igor Murashkinacd695c2013-03-13 17:23:00 -07001090 break;
1091 case -1:
1092 ALOGE("Invalid camera id %d", cameraId);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001093 return BAD_VALUE;
Igor Murashkinacd695c2013-03-13 17:23:00 -07001094 default:
1095 ALOGE("Unknown camera device HAL version: %d", deviceVersion);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001096 return INVALID_OPERATION;
Igor Murashkine6800ce2013-03-04 17:25:57 -08001097 }
Igor Murashkinacd695c2013-03-13 17:23:00 -07001098
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001099 status_t status = connectFinishUnsafe(client, client->getRemote());
1100 if (status != OK) {
1101 return status;
Igor Murashkinacd695c2013-03-13 17:23:00 -07001102 }
1103
1104 mProClientList[cameraId].push(client);
1105
1106 LOG1("CameraService::connectPro X (id %d, this pid is %d)", cameraId,
1107 getpid());
Igor Murashkine6800ce2013-03-04 17:25:57 -08001108 }
Igor Murashkinacd695c2013-03-13 17:23:00 -07001109 // important: release the mutex here so the client can call back
1110 // into the service from its destructor (can be at the end of the call)
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001111 device = client;
1112 return OK;
Igor Murashkinbfc99152013-02-27 12:55:20 -08001113}
Igor Murashkin634a5152013-02-20 17:15:11 -08001114
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001115status_t CameraService::connectDevice(
Igor Murashkine7ee7632013-06-11 18:10:18 -07001116 const sp<ICameraDeviceCallbacks>& cameraCb,
1117 int cameraId,
1118 const String16& clientPackageName,
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001119 int clientUid,
1120 /*out*/
1121 sp<ICameraDeviceUser>& device)
Igor Murashkine7ee7632013-06-11 18:10:18 -07001122{
Igor Murashkine7ee7632013-06-11 18:10:18 -07001123
1124 String8 clientName8(clientPackageName);
1125 int callingPid = getCallingPid();
1126
1127 LOG1("CameraService::connectDevice E (pid %d \"%s\", id %d)", callingPid,
1128 clientName8.string(), cameraId);
1129
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001130 status_t status = validateConnect(cameraId, /*inout*/clientUid);
1131 if (status != OK) {
1132 return status;
Igor Murashkine7ee7632013-06-11 18:10:18 -07001133 }
1134
1135 sp<CameraDeviceClient> client;
1136 {
1137 Mutex::Autolock lock(mServiceLock);
1138 {
1139 sp<BasicClient> client;
1140 if (!canConnectUnsafe(cameraId, clientPackageName,
Marco Nelissenf8880202014-11-14 07:58:25 -08001141 IInterface::asBinder(cameraCb),
Igor Murashkine7ee7632013-06-11 18:10:18 -07001142 /*out*/client)) {
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001143 return -EBUSY;
Igor Murashkine7ee7632013-06-11 18:10:18 -07001144 }
1145 }
1146
1147 int facing = -1;
1148 int deviceVersion = getDeviceVersion(cameraId, &facing);
1149
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001150 // give flashlight a chance to close devices if necessary.
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001151 mFlashlight->prepareDeviceOpen(String8::format("%d", cameraId));
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001152
Igor Murashkine7ee7632013-06-11 18:10:18 -07001153 switch(deviceVersion) {
1154 case CAMERA_DEVICE_API_VERSION_1_0:
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001155 ALOGW("Camera using old HAL version: %d", deviceVersion);
Ruben Brunk17963d12013-08-19 15:21:19 -07001156 return -EOPNOTSUPP;
Igor Murashkine7ee7632013-06-11 18:10:18 -07001157 // TODO: don't allow 2.0 Only allow 2.1 and higher
1158 case CAMERA_DEVICE_API_VERSION_2_0:
1159 case CAMERA_DEVICE_API_VERSION_2_1:
1160 case CAMERA_DEVICE_API_VERSION_3_0:
Zhijun He95dd5ba2014-03-26 18:18:00 -07001161 case CAMERA_DEVICE_API_VERSION_3_1:
1162 case CAMERA_DEVICE_API_VERSION_3_2:
Eino-Ville Talvala63d877f2014-06-16 19:21:12 -07001163 client = new CameraDeviceClient(this, cameraCb, clientPackageName,
1164 cameraId, facing, callingPid, clientUid, getpid());
Igor Murashkine7ee7632013-06-11 18:10:18 -07001165 break;
1166 case -1:
1167 ALOGE("Invalid camera id %d", cameraId);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001168 return BAD_VALUE;
Igor Murashkine7ee7632013-06-11 18:10:18 -07001169 default:
1170 ALOGE("Unknown camera device HAL version: %d", deviceVersion);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001171 return INVALID_OPERATION;
Igor Murashkine7ee7632013-06-11 18:10:18 -07001172 }
1173
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001174 status_t status = connectFinishUnsafe(client, client->getRemote());
1175 if (status != OK) {
Igor Murashkine7ee7632013-06-11 18:10:18 -07001176 // this is probably not recoverable.. maybe the client can try again
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001177 return status;
Igor Murashkine7ee7632013-06-11 18:10:18 -07001178 }
1179
1180 LOG1("CameraService::connectDevice X (id %d, this pid is %d)", cameraId,
1181 getpid());
1182
1183 mClient[cameraId] = client;
1184 }
1185 // important: release the mutex here so the client can call back
1186 // into the service from its destructor (can be at the end of the call)
1187
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001188 device = client;
1189 return OK;
Igor Murashkine7ee7632013-06-11 18:10:18 -07001190}
1191
1192
Igor Murashkinbfc99152013-02-27 12:55:20 -08001193status_t CameraService::addListener(
1194 const sp<ICameraServiceListener>& listener) {
1195 ALOGV("%s: Add listener %p", __FUNCTION__, listener.get());
Igor Murashkin634a5152013-02-20 17:15:11 -08001196
Igor Murashkinbd3e2e02014-03-17 13:01:41 -07001197 if (listener == 0) {
1198 ALOGE("%s: Listener must not be null", __FUNCTION__);
1199 return BAD_VALUE;
1200 }
1201
Igor Murashkinbfc99152013-02-27 12:55:20 -08001202 Mutex::Autolock lock(mServiceLock);
1203
1204 Vector<sp<ICameraServiceListener> >::iterator it, end;
1205 for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
Marco Nelissenf8880202014-11-14 07:58:25 -08001206 if (IInterface::asBinder(*it) == IInterface::asBinder(listener)) {
Igor Murashkinbfc99152013-02-27 12:55:20 -08001207 ALOGW("%s: Tried to add listener %p which was already subscribed",
1208 __FUNCTION__, listener.get());
1209 return ALREADY_EXISTS;
1210 }
1211 }
1212
1213 mListenerList.push_back(listener);
1214
Igor Murashkincba2c162013-03-20 15:56:31 -07001215 /* Immediately signal current status to this listener only */
1216 {
1217 Mutex::Autolock m(mStatusMutex) ;
1218 int numCams = getNumberOfCameras();
1219 for (int i = 0; i < numCams; ++i) {
1220 listener->onStatusChanged(mStatusList[i], i);
1221 }
1222 }
1223
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001224 /* Immediately signal current torch status to this listener only */
1225 {
1226 Mutex::Autolock al(mTorchStatusMutex);
1227 for (size_t i = 0; i < mTorchStatusMap.size(); i++ ) {
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001228 String16 id = String16(mTorchStatusMap.keyAt(i).string());
1229 listener->onTorchStatusChanged(mTorchStatusMap.valueAt(i), id);
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001230 }
1231
1232 }
1233
Igor Murashkinbfc99152013-02-27 12:55:20 -08001234 return OK;
1235}
1236status_t CameraService::removeListener(
1237 const sp<ICameraServiceListener>& listener) {
1238 ALOGV("%s: Remove listener %p", __FUNCTION__, listener.get());
1239
Igor Murashkinbd3e2e02014-03-17 13:01:41 -07001240 if (listener == 0) {
1241 ALOGE("%s: Listener must not be null", __FUNCTION__);
1242 return BAD_VALUE;
1243 }
1244
Igor Murashkinbfc99152013-02-27 12:55:20 -08001245 Mutex::Autolock lock(mServiceLock);
1246
1247 Vector<sp<ICameraServiceListener> >::iterator it;
1248 for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
Marco Nelissenf8880202014-11-14 07:58:25 -08001249 if (IInterface::asBinder(*it) == IInterface::asBinder(listener)) {
Igor Murashkinbfc99152013-02-27 12:55:20 -08001250 mListenerList.erase(it);
1251 return OK;
1252 }
1253 }
1254
1255 ALOGW("%s: Tried to remove a listener %p which was not subscribed",
1256 __FUNCTION__, listener.get());
1257
1258 return BAD_VALUE;
Igor Murashkin634a5152013-02-20 17:15:11 -08001259}
1260
Igor Murashkin65d14b92014-06-17 12:03:20 -07001261status_t CameraService::getLegacyParameters(
1262 int cameraId,
1263 /*out*/
1264 String16* parameters) {
1265 ALOGV("%s: for camera ID = %d", __FUNCTION__, cameraId);
1266
1267 if (parameters == NULL) {
1268 ALOGE("%s: parameters must not be null", __FUNCTION__);
1269 return BAD_VALUE;
1270 }
1271
1272 status_t ret = 0;
1273
1274 CameraParameters shimParams;
1275 if ((ret = getLegacyParametersLazy(cameraId, /*out*/&shimParams)) != OK) {
1276 // Error logged by caller
1277 return ret;
1278 }
1279
1280 String8 shimParamsString8 = shimParams.flatten();
1281 String16 shimParamsString16 = String16(shimParamsString8);
1282
1283 *parameters = shimParamsString16;
1284
1285 return OK;
1286}
1287
1288status_t CameraService::supportsCameraApi(int cameraId, int apiVersion) {
1289 ALOGV("%s: for camera ID = %d", __FUNCTION__, cameraId);
1290
1291 switch (apiVersion) {
1292 case API_VERSION_1:
1293 case API_VERSION_2:
1294 break;
1295 default:
1296 ALOGE("%s: Bad API version %d", __FUNCTION__, apiVersion);
1297 return BAD_VALUE;
1298 }
1299
1300 int facing = -1;
1301 int deviceVersion = getDeviceVersion(cameraId, &facing);
1302
1303 switch(deviceVersion) {
1304 case CAMERA_DEVICE_API_VERSION_1_0:
1305 case CAMERA_DEVICE_API_VERSION_2_0:
1306 case CAMERA_DEVICE_API_VERSION_2_1:
1307 case CAMERA_DEVICE_API_VERSION_3_0:
1308 case CAMERA_DEVICE_API_VERSION_3_1:
1309 if (apiVersion == API_VERSION_2) {
1310 ALOGV("%s: Camera id %d uses HAL prior to HAL3.2, doesn't support api2 without shim",
1311 __FUNCTION__, cameraId);
1312 return -EOPNOTSUPP;
1313 } else { // if (apiVersion == API_VERSION_1) {
1314 ALOGV("%s: Camera id %d uses older HAL before 3.2, but api1 is always supported",
1315 __FUNCTION__, cameraId);
1316 return OK;
1317 }
1318 case CAMERA_DEVICE_API_VERSION_3_2:
1319 ALOGV("%s: Camera id %d uses HAL3.2 or newer, supports api1/api2 directly",
1320 __FUNCTION__, cameraId);
1321 return OK;
1322 case -1:
1323 ALOGE("%s: Invalid camera id %d", __FUNCTION__, cameraId);
1324 return BAD_VALUE;
1325 default:
1326 ALOGE("%s: Unknown camera device HAL version: %d", __FUNCTION__, deviceVersion);
1327 return INVALID_OPERATION;
1328 }
1329
1330 return OK;
1331}
1332
Igor Murashkin634a5152013-02-20 17:15:11 -08001333void CameraService::removeClientByRemote(const wp<IBinder>& remoteBinder) {
1334 int callingPid = getCallingPid();
1335 LOG1("CameraService::removeClientByRemote E (pid %d)", callingPid);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001336
Igor Murashkinecf17e82012-10-02 16:05:11 -07001337 // Declare this before the lock to make absolutely sure the
1338 // destructor won't be called with the lock held.
1339 Mutex::Autolock lock(mServiceLock);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001340
Igor Murashkinecf17e82012-10-02 16:05:11 -07001341 int outIndex;
Igor Murashkine7ee7632013-06-11 18:10:18 -07001342 sp<BasicClient> client = findClientUnsafe(remoteBinder, outIndex);
Igor Murashkinecf17e82012-10-02 16:05:11 -07001343
1344 if (client != 0) {
1345 // Found our camera, clear and leave.
1346 LOG1("removeClient: clear camera %d", outIndex);
Igor Murashkinecf17e82012-10-02 16:05:11 -07001347
Ruben Brunkb2119af2014-05-09 19:57:56 -07001348 sp<IBinder> remote = client->getRemote();
1349 if (remote != NULL) {
1350 remote->unlinkToDeath(this);
1351 }
1352
1353 mClient[outIndex].clear();
Igor Murashkin634a5152013-02-20 17:15:11 -08001354 } else {
1355
1356 sp<ProClient> clientPro = findProClientUnsafe(remoteBinder);
1357
1358 if (clientPro != NULL) {
1359 // Found our camera, clear and leave.
1360 LOG1("removeClient: clear pro %p", clientPro.get());
1361
Marco Nelissenf8880202014-11-14 07:58:25 -08001362 IInterface::asBinder(clientPro->getRemoteCallback())->unlinkToDeath(this);
Igor Murashkin634a5152013-02-20 17:15:11 -08001363 }
Igor Murashkinecf17e82012-10-02 16:05:11 -07001364 }
1365
Igor Murashkin634a5152013-02-20 17:15:11 -08001366 LOG1("CameraService::removeClientByRemote X (pid %d)", callingPid);
1367}
1368
1369sp<CameraService::ProClient> CameraService::findProClientUnsafe(
1370 const wp<IBinder>& cameraCallbacksRemote)
1371{
1372 sp<ProClient> clientPro;
1373
1374 for (int i = 0; i < mNumberOfCameras; ++i) {
1375 Vector<size_t> removeIdx;
1376
1377 for (size_t j = 0; j < mProClientList[i].size(); ++j) {
1378 wp<ProClient> cl = mProClientList[i][j];
1379
1380 sp<ProClient> clStrong = cl.promote();
1381 if (clStrong != NULL && clStrong->getRemote() == cameraCallbacksRemote) {
1382 clientPro = clStrong;
1383 break;
1384 } else if (clStrong == NULL) {
1385 // mark to clean up dead ptr
1386 removeIdx.push(j);
1387 }
1388 }
1389
1390 // remove stale ptrs (in reverse so the indices dont change)
1391 for (ssize_t j = (ssize_t)removeIdx.size() - 1; j >= 0; --j) {
1392 mProClientList[i].removeAt(removeIdx[j]);
1393 }
1394
1395 }
1396
1397 return clientPro;
Igor Murashkinecf17e82012-10-02 16:05:11 -07001398}
1399
Igor Murashkine7ee7632013-06-11 18:10:18 -07001400sp<CameraService::BasicClient> CameraService::findClientUnsafe(
Igor Murashkin294d0ec2012-10-05 10:44:57 -07001401 const wp<IBinder>& cameraClient, int& outIndex) {
Igor Murashkine7ee7632013-06-11 18:10:18 -07001402 sp<BasicClient> client;
Igor Murashkinecf17e82012-10-02 16:05:11 -07001403
1404 for (int i = 0; i < mNumberOfCameras; i++) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001405
1406 // This happens when we have already disconnected (or this is
1407 // just another unused camera).
1408 if (mClient[i] == 0) continue;
1409
1410 // Promote mClient. It can fail if we are called from this path:
Igor Murashkin634a5152013-02-20 17:15:11 -08001411 // Client::~Client() -> disconnect() -> removeClientByRemote().
Mathias Agopian65ab4712010-07-14 17:59:35 -07001412 client = mClient[i].promote();
1413
Igor Murashkinecf17e82012-10-02 16:05:11 -07001414 // Clean up stale client entry
1415 if (client == NULL) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001416 mClient[i].clear();
1417 continue;
1418 }
1419
Igor Murashkine7ee7632013-06-11 18:10:18 -07001420 if (cameraClient == client->getRemote()) {
Igor Murashkinecf17e82012-10-02 16:05:11 -07001421 // Found our camera
1422 outIndex = i;
1423 return client;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001424 }
1425 }
1426
Igor Murashkinecf17e82012-10-02 16:05:11 -07001427 outIndex = -1;
1428 return NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001429}
1430
Igor Murashkine7ee7632013-06-11 18:10:18 -07001431CameraService::BasicClient* CameraService::getClientByIdUnsafe(int cameraId) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001432 if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
Keun young Parkd8973a72012-03-28 14:13:09 -07001433 return mClient[cameraId].unsafe_get();
1434}
1435
1436Mutex* CameraService::getClientLockById(int cameraId) {
1437 if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
1438 return &mClientLock[cameraId];
Mathias Agopian65ab4712010-07-14 17:59:35 -07001439}
1440
Igor Murashkin634a5152013-02-20 17:15:11 -08001441sp<CameraService::BasicClient> CameraService::getClientByRemote(
Igor Murashkin294d0ec2012-10-05 10:44:57 -07001442 const wp<IBinder>& cameraClient) {
Igor Murashkinecf17e82012-10-02 16:05:11 -07001443
1444 // Declare this before the lock to make absolutely sure the
1445 // destructor won't be called with the lock held.
Igor Murashkin634a5152013-02-20 17:15:11 -08001446 sp<BasicClient> client;
Igor Murashkinecf17e82012-10-02 16:05:11 -07001447
1448 Mutex::Autolock lock(mServiceLock);
1449
1450 int outIndex;
1451 client = findClientUnsafe(cameraClient, outIndex);
1452
1453 return client;
1454}
1455
Mathias Agopian65ab4712010-07-14 17:59:35 -07001456status_t CameraService::onTransact(
1457 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
1458 // Permission checks
1459 switch (code) {
1460 case BnCameraService::CONNECT:
Igor Murashkin634a5152013-02-20 17:15:11 -08001461 case BnCameraService::CONNECT_PRO:
Eino-Ville Talvala63d877f2014-06-16 19:21:12 -07001462 case BnCameraService::CONNECT_DEVICE:
Zhijun Heb10cdad2014-06-16 16:38:35 -07001463 case BnCameraService::CONNECT_LEGACY:
Mathias Agopian65ab4712010-07-14 17:59:35 -07001464 const int pid = getCallingPid();
1465 const int self_pid = getpid();
1466 if (pid != self_pid) {
1467 // we're called from a different process, do the real check
1468 if (!checkCallingPermission(
1469 String16("android.permission.CAMERA"))) {
1470 const int uid = getCallingUid();
Steve Block29357bc2012-01-06 19:20:56 +00001471 ALOGE("Permission Denial: "
Mathias Agopian65ab4712010-07-14 17:59:35 -07001472 "can't use the camera pid=%d, uid=%d", pid, uid);
1473 return PERMISSION_DENIED;
1474 }
1475 }
1476 break;
1477 }
1478
1479 return BnCameraService::onTransact(code, data, reply, flags);
1480}
1481
1482// The reason we need this busy bit is a new CameraService::connect() request
1483// may come in while the previous Client's destructor has not been run or is
1484// still running. If the last strong reference of the previous Client is gone
1485// but the destructor has not been finished, we should not allow the new Client
1486// to be created because we need to wait for the previous Client to tear down
1487// the hardware first.
1488void CameraService::setCameraBusy(int cameraId) {
1489 android_atomic_write(1, &mBusy[cameraId]);
Igor Murashkinecf17e82012-10-02 16:05:11 -07001490
1491 ALOGV("setCameraBusy cameraId=%d", cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001492}
1493
1494void CameraService::setCameraFree(int cameraId) {
1495 android_atomic_write(0, &mBusy[cameraId]);
Igor Murashkinecf17e82012-10-02 16:05:11 -07001496
1497 ALOGV("setCameraFree cameraId=%d", cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001498}
1499
1500// We share the media players for shutter and recording sound for all clients.
1501// A reference count is kept to determine when we will actually release the
1502// media players.
1503
Chih-Chung Changff4f55c2011-10-17 19:03:12 +08001504MediaPlayer* CameraService::newMediaPlayer(const char *file) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001505 MediaPlayer* mp = new MediaPlayer();
Andreas Huber1b86fe02014-01-29 11:13:26 -08001506 if (mp->setDataSource(NULL /* httpService */, file, NULL) == NO_ERROR) {
Eino-Ville Talvala60a78ac2012-01-05 15:34:53 -08001507 mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001508 mp->prepare();
1509 } else {
Steve Block29357bc2012-01-06 19:20:56 +00001510 ALOGE("Failed to load CameraService sounds: %s", file);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001511 return NULL;
1512 }
1513 return mp;
1514}
1515
1516void CameraService::loadSound() {
1517 Mutex::Autolock lock(mSoundLock);
1518 LOG1("CameraService::loadSound ref=%d", mSoundRef);
1519 if (mSoundRef++) return;
1520
1521 mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
1522 mSoundPlayer[SOUND_RECORDING] = newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");
1523}
1524
1525void CameraService::releaseSound() {
1526 Mutex::Autolock lock(mSoundLock);
1527 LOG1("CameraService::releaseSound ref=%d", mSoundRef);
1528 if (--mSoundRef) return;
1529
1530 for (int i = 0; i < NUM_SOUNDS; i++) {
1531 if (mSoundPlayer[i] != 0) {
1532 mSoundPlayer[i]->disconnect();
1533 mSoundPlayer[i].clear();
1534 }
1535 }
1536}
1537
1538void CameraService::playSound(sound_kind kind) {
1539 LOG1("playSound(%d)", kind);
1540 Mutex::Autolock lock(mSoundLock);
1541 sp<MediaPlayer> player = mSoundPlayer[kind];
1542 if (player != 0) {
Chih-Chung Chang8888a752011-10-20 10:47:26 +08001543 player->seekTo(0);
1544 player->start();
Mathias Agopian65ab4712010-07-14 17:59:35 -07001545 }
1546}
1547
1548// ----------------------------------------------------------------------------
1549
1550CameraService::Client::Client(const sp<CameraService>& cameraService,
Wu-cheng Lib7a67942010-08-17 15:45:37 -07001551 const sp<ICameraClient>& cameraClient,
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001552 const String16& clientPackageName,
1553 int cameraId, int cameraFacing,
1554 int clientPid, uid_t clientUid,
1555 int servicePid) :
Eino-Ville Talvalae992e752014-11-07 16:17:48 -08001556 CameraService::BasicClient(cameraService,
Marco Nelissenf8880202014-11-14 07:58:25 -08001557 IInterface::asBinder(cameraClient),
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001558 clientPackageName,
1559 cameraId, cameraFacing,
1560 clientPid, clientUid,
1561 servicePid)
Igor Murashkin634a5152013-02-20 17:15:11 -08001562{
Mathias Agopian65ab4712010-07-14 17:59:35 -07001563 int callingPid = getCallingPid();
Wu-cheng Li2fd24402012-02-23 19:01:00 -08001564 LOG1("Client::Client E (pid %d, id %d)", callingPid, cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001565
Igor Murashkin44cfcf02013-03-01 16:22:28 -08001566 mRemoteCallback = cameraClient;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001567
Mathias Agopian65ab4712010-07-14 17:59:35 -07001568 cameraService->setCameraBusy(cameraId);
1569 cameraService->loadSound();
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001570
Wu-cheng Li2fd24402012-02-23 19:01:00 -08001571 LOG1("Client::Client X (pid %d, id %d)", callingPid, cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001572}
1573
Mathias Agopian65ab4712010-07-14 17:59:35 -07001574// tear down the client
1575CameraService::Client::~Client() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -07001576 ALOGV("~Client");
Igor Murashkin634a5152013-02-20 17:15:11 -08001577 mDestructionStarted = true;
1578
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001579 mCameraService->releaseSound();
Igor Murashkin036bc3e2012-10-08 15:09:46 -07001580 // unconditionally disconnect. function is idempotent
1581 Client::disconnect();
Mathias Agopian65ab4712010-07-14 17:59:35 -07001582}
1583
Igor Murashkin634a5152013-02-20 17:15:11 -08001584CameraService::BasicClient::BasicClient(const sp<CameraService>& cameraService,
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001585 const sp<IBinder>& remoteCallback,
1586 const String16& clientPackageName,
1587 int cameraId, int cameraFacing,
1588 int clientPid, uid_t clientUid,
1589 int servicePid):
1590 mClientPackageName(clientPackageName)
Igor Murashkin634a5152013-02-20 17:15:11 -08001591{
1592 mCameraService = cameraService;
Igor Murashkin44cfcf02013-03-01 16:22:28 -08001593 mRemoteBinder = remoteCallback;
Igor Murashkin634a5152013-02-20 17:15:11 -08001594 mCameraId = cameraId;
1595 mCameraFacing = cameraFacing;
1596 mClientPid = clientPid;
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001597 mClientUid = clientUid;
Igor Murashkin634a5152013-02-20 17:15:11 -08001598 mServicePid = servicePid;
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001599 mOpsActive = false;
Igor Murashkin634a5152013-02-20 17:15:11 -08001600 mDestructionStarted = false;
1601}
1602
1603CameraService::BasicClient::~BasicClient() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -07001604 ALOGV("~BasicClient");
Igor Murashkin634a5152013-02-20 17:15:11 -08001605 mDestructionStarted = true;
1606}
1607
1608void CameraService::BasicClient::disconnect() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -07001609 ALOGV("BasicClient::disconnect");
Igor Murashkin44cfcf02013-03-01 16:22:28 -08001610 mCameraService->removeClientByRemote(mRemoteBinder);
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001611
1612 finishCameraOps();
Igor Murashkincba2c162013-03-20 15:56:31 -07001613 // client shouldn't be able to call into us anymore
1614 mClientPid = 0;
Igor Murashkin634a5152013-02-20 17:15:11 -08001615}
1616
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001617status_t CameraService::BasicClient::startCameraOps() {
1618 int32_t res;
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001619 // Notify app ops that the camera is not available
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001620 mOpsCallback = new OpsCallback(this);
1621
Igor Murashkine6800ce2013-03-04 17:25:57 -08001622 {
1623 ALOGV("%s: Start camera ops, package name = %s, client UID = %d",
1624 __FUNCTION__, String8(mClientPackageName).string(), mClientUid);
1625 }
1626
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001627 mAppOpsManager.startWatchingMode(AppOpsManager::OP_CAMERA,
1628 mClientPackageName, mOpsCallback);
1629 res = mAppOpsManager.startOp(AppOpsManager::OP_CAMERA,
1630 mClientUid, mClientPackageName);
1631
1632 if (res != AppOpsManager::MODE_ALLOWED) {
1633 ALOGI("Camera %d: Access for \"%s\" has been revoked",
1634 mCameraId, String8(mClientPackageName).string());
1635 return PERMISSION_DENIED;
1636 }
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001637
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001638 mOpsActive = true;
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001639
1640 // Transition device availability listeners from PRESENT -> NOT_AVAILABLE
1641 mCameraService->updateStatus(ICameraServiceListener::STATUS_NOT_AVAILABLE,
1642 mCameraId);
1643
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001644 return OK;
1645}
1646
1647status_t CameraService::BasicClient::finishCameraOps() {
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001648 // Check if startCameraOps succeeded, and if so, finish the camera op
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001649 if (mOpsActive) {
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001650 // Notify app ops that the camera is available again
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001651 mAppOpsManager.finishOp(AppOpsManager::OP_CAMERA, mClientUid,
1652 mClientPackageName);
1653 mOpsActive = false;
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001654
1655 // Notify device availability listeners that this camera is available
1656 // again
1657
1658 StatusVector rejectSourceStates;
1659 rejectSourceStates.push_back(ICameraServiceListener::STATUS_NOT_PRESENT);
1660 rejectSourceStates.push_back(ICameraServiceListener::STATUS_ENUMERATING);
1661
1662 // Transition to PRESENT if the camera is not in either of above 2
1663 // states
1664 mCameraService->updateStatus(ICameraServiceListener::STATUS_PRESENT,
1665 mCameraId,
1666 &rejectSourceStates);
1667
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001668 // Notify flashlight that a camera device is closed.
1669 mCameraService->mFlashlight->deviceClosed(
1670 String8::format("%d", mCameraId));
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001671 }
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001672 // Always stop watching, even if no camera op is active
Eino-Ville Talvalae992e752014-11-07 16:17:48 -08001673 if (mOpsCallback != NULL) {
1674 mAppOpsManager.stopWatchingMode(mOpsCallback);
1675 }
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001676 mOpsCallback.clear();
1677
1678 return OK;
1679}
1680
1681void CameraService::BasicClient::opChanged(int32_t op, const String16& packageName) {
1682 String8 name(packageName);
1683 String8 myName(mClientPackageName);
1684
1685 if (op != AppOpsManager::OP_CAMERA) {
1686 ALOGW("Unexpected app ops notification received: %d", op);
1687 return;
1688 }
1689
1690 int32_t res;
1691 res = mAppOpsManager.checkOp(AppOpsManager::OP_CAMERA,
1692 mClientUid, mClientPackageName);
1693 ALOGV("checkOp returns: %d, %s ", res,
1694 res == AppOpsManager::MODE_ALLOWED ? "ALLOWED" :
1695 res == AppOpsManager::MODE_IGNORED ? "IGNORED" :
1696 res == AppOpsManager::MODE_ERRORED ? "ERRORED" :
1697 "UNKNOWN");
1698
1699 if (res != AppOpsManager::MODE_ALLOWED) {
1700 ALOGI("Camera %d: Access for \"%s\" revoked", mCameraId,
1701 myName.string());
1702 // Reset the client PID to allow server-initiated disconnect,
1703 // and to prevent further calls by client.
1704 mClientPid = getCallingPid();
Jianing Weicb0652e2014-03-12 18:29:36 -07001705 CaptureResultExtras resultExtras; // a dummy result (invalid)
1706 notifyError(ICameraDeviceCallbacks::ERROR_CAMERA_SERVICE, resultExtras);
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001707 disconnect();
1708 }
1709}
1710
Mathias Agopian65ab4712010-07-14 17:59:35 -07001711// ----------------------------------------------------------------------------
1712
Keun young Parkd8973a72012-03-28 14:13:09 -07001713Mutex* CameraService::Client::getClientLockFromCookie(void* user) {
Kévin PETIT377b2ec2014-02-03 12:35:36 +00001714 return gCameraService->getClientLockById((int)(intptr_t) user);
Keun young Parkd8973a72012-03-28 14:13:09 -07001715}
1716
1717// Provide client pointer for callbacks. Client lock returned from getClientLockFromCookie should
1718// be acquired for this to be safe
1719CameraService::Client* CameraService::Client::getClientFromCookie(void* user) {
Kévin PETIT377b2ec2014-02-03 12:35:36 +00001720 BasicClient *basicClient = gCameraService->getClientByIdUnsafe((int)(intptr_t) user);
Igor Murashkine7ee7632013-06-11 18:10:18 -07001721 // OK: only CameraClient calls this, and they already cast anyway.
1722 Client* client = static_cast<Client*>(basicClient);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001723
1724 // This could happen if the Client is in the process of shutting down (the
1725 // last strong reference is gone, but the destructor hasn't finished
1726 // stopping the hardware).
Keun young Parkd8973a72012-03-28 14:13:09 -07001727 if (client == NULL) return NULL;
1728
1729 // destruction already started, so should not be accessed
1730 if (client->mDestructionStarted) return NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001731
Mathias Agopian65ab4712010-07-14 17:59:35 -07001732 return client;
1733}
1734
Jianing Weicb0652e2014-03-12 18:29:36 -07001735void CameraService::Client::notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode,
1736 const CaptureResultExtras& resultExtras) {
Igor Murashkin44cfcf02013-03-01 16:22:28 -08001737 mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_RELEASED, 0);
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001738}
1739
Igor Murashkin036bc3e2012-10-08 15:09:46 -07001740// NOTE: function is idempotent
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001741void CameraService::Client::disconnect() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -07001742 ALOGV("Client::disconnect");
Igor Murashkin634a5152013-02-20 17:15:11 -08001743 BasicClient::disconnect();
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001744 mCameraService->setCameraFree(mCameraId);
Wu-cheng Lie09591e2010-10-14 20:17:44 +08001745}
1746
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001747CameraService::Client::OpsCallback::OpsCallback(wp<BasicClient> client):
1748 mClient(client) {
1749}
1750
1751void CameraService::Client::OpsCallback::opChanged(int32_t op,
1752 const String16& packageName) {
1753 sp<BasicClient> client = mClient.promote();
1754 if (client != NULL) {
1755 client->opChanged(op, packageName);
1756 }
1757}
1758
Mathias Agopian65ab4712010-07-14 17:59:35 -07001759// ----------------------------------------------------------------------------
Igor Murashkin634a5152013-02-20 17:15:11 -08001760// IProCamera
1761// ----------------------------------------------------------------------------
1762
1763CameraService::ProClient::ProClient(const sp<CameraService>& cameraService,
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001764 const sp<IProCameraCallbacks>& remoteCallback,
1765 const String16& clientPackageName,
1766 int cameraId,
1767 int cameraFacing,
1768 int clientPid,
1769 uid_t clientUid,
1770 int servicePid)
Marco Nelissenf8880202014-11-14 07:58:25 -08001771 : CameraService::BasicClient(cameraService, IInterface::asBinder(remoteCallback),
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001772 clientPackageName, cameraId, cameraFacing,
1773 clientPid, clientUid, servicePid)
Igor Murashkin634a5152013-02-20 17:15:11 -08001774{
1775 mRemoteCallback = remoteCallback;
1776}
1777
1778CameraService::ProClient::~ProClient() {
Igor Murashkin634a5152013-02-20 17:15:11 -08001779}
1780
Jianing Weicb0652e2014-03-12 18:29:36 -07001781void CameraService::ProClient::notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode,
1782 const CaptureResultExtras& resultExtras) {
Igor Murashkine6800ce2013-03-04 17:25:57 -08001783 mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_RELEASED, 0);
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001784}
1785
Igor Murashkin634a5152013-02-20 17:15:11 -08001786// ----------------------------------------------------------------------------
Mathias Agopian65ab4712010-07-14 17:59:35 -07001787
1788static const int kDumpLockRetries = 50;
1789static const int kDumpLockSleep = 60000;
1790
1791static bool tryLock(Mutex& mutex)
1792{
1793 bool locked = false;
1794 for (int i = 0; i < kDumpLockRetries; ++i) {
1795 if (mutex.tryLock() == NO_ERROR) {
1796 locked = true;
1797 break;
1798 }
1799 usleep(kDumpLockSleep);
1800 }
1801 return locked;
1802}
1803
1804status_t CameraService::dump(int fd, const Vector<String16>& args) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001805 String8 result;
1806 if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -07001807 result.appendFormat("Permission Denial: "
Mathias Agopian65ab4712010-07-14 17:59:35 -07001808 "can't dump CameraService from pid=%d, uid=%d\n",
1809 getCallingPid(),
1810 getCallingUid());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001811 write(fd, result.string(), result.size());
1812 } else {
1813 bool locked = tryLock(mServiceLock);
1814 // failed to lock - CameraService is probably deadlocked
1815 if (!locked) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -07001816 result.append("CameraService may be deadlocked\n");
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001817 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001818 }
1819
1820 bool hasClient = false;
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001821 if (!mModule) {
1822 result = String8::format("No camera module available!\n");
1823 write(fd, result.string(), result.size());
Kalle Lampila6ec3a152013-04-30 15:27:19 +03001824 if (locked) mServiceLock.unlock();
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001825 return NO_ERROR;
1826 }
1827
Yin-Chia Yehe074a932015-01-30 10:29:02 -08001828 const hw_module_t* common = mModule->getRawModule();
1829 result = String8::format("Camera module HAL API version: 0x%x\n", common->hal_api_version);
1830 result.appendFormat("Camera module API version: 0x%x\n", common->module_api_version);
1831 result.appendFormat("Camera module name: %s\n", common->name);
1832 result.appendFormat("Camera module author: %s\n", common->author);
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001833 result.appendFormat("Number of camera devices: %d\n\n", mNumberOfCameras);
Ruben Brunkf81648e2014-04-17 16:14:57 -07001834
1835 sp<VendorTagDescriptor> desc = VendorTagDescriptor::getGlobalVendorTagDescriptor();
1836 if (desc == NULL) {
1837 result.appendFormat("Vendor tags left unimplemented.\n");
1838 } else {
1839 result.appendFormat("Vendor tag definitions:\n");
1840 }
1841
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001842 write(fd, result.string(), result.size());
Ruben Brunkf81648e2014-04-17 16:14:57 -07001843
1844 if (desc != NULL) {
1845 desc->dump(fd, /*verbosity*/2, /*indentation*/4);
1846 }
1847
Mathias Agopian65ab4712010-07-14 17:59:35 -07001848 for (int i = 0; i < mNumberOfCameras; i++) {
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001849 result = String8::format("Camera %d static information:\n", i);
1850 camera_info info;
1851
Yin-Chia Yehe074a932015-01-30 10:29:02 -08001852 status_t rc = mModule->getCameraInfo(i, &info);
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001853 if (rc != OK) {
1854 result.appendFormat(" Error reading static information!\n");
1855 write(fd, result.string(), result.size());
1856 } else {
1857 result.appendFormat(" Facing: %s\n",
1858 info.facing == CAMERA_FACING_BACK ? "BACK" : "FRONT");
1859 result.appendFormat(" Orientation: %d\n", info.orientation);
1860 int deviceVersion;
Yin-Chia Yehe074a932015-01-30 10:29:02 -08001861 if (common->module_api_version < CAMERA_MODULE_API_VERSION_2_0) {
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001862 deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
1863 } else {
1864 deviceVersion = info.device_version;
1865 }
1866 result.appendFormat(" Device version: 0x%x\n", deviceVersion);
1867 if (deviceVersion >= CAMERA_DEVICE_API_VERSION_2_0) {
1868 result.appendFormat(" Device static metadata:\n");
1869 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -07001870 dump_indented_camera_metadata(info.static_camera_characteristics,
Ruben Brunkf81648e2014-04-17 16:14:57 -07001871 fd, /*verbosity*/2, /*indentation*/4);
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001872 } else {
1873 write(fd, result.string(), result.size());
1874 }
1875 }
1876
Igor Murashkine7ee7632013-06-11 18:10:18 -07001877 sp<BasicClient> client = mClient[i].promote();
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001878 if (client == 0) {
1879 result = String8::format(" Device is closed, no client instance\n");
1880 write(fd, result.string(), result.size());
1881 continue;
1882 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001883 hasClient = true;
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001884 result = String8::format(" Device is open. Client instance dump:\n");
1885 write(fd, result.string(), result.size());
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001886 client->dump(fd, args);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001887 }
1888 if (!hasClient) {
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001889 result = String8::format("\nNo active camera clients yet.\n");
1890 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001891 }
1892
1893 if (locked) mServiceLock.unlock();
1894
Igor Murashkinff3e31d2013-10-23 16:40:06 -07001895 // Dump camera traces if there were any
1896 write(fd, "\n", 1);
1897 camera3::CameraTraces::dump(fd, args);
1898
Mathias Agopian65ab4712010-07-14 17:59:35 -07001899 // change logging level
1900 int n = args.size();
1901 for (int i = 0; i + 1 < n; i++) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -07001902 String16 verboseOption("-v");
1903 if (args[i] == verboseOption) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001904 String8 levelStr(args[i+1]);
1905 int level = atoi(levelStr.string());
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001906 result = String8::format("\nSetting log level to %d.\n", level);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001907 setLogLevel(level);
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001908 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001909 }
1910 }
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001911
Mathias Agopian65ab4712010-07-14 17:59:35 -07001912 }
1913 return NO_ERROR;
1914}
1915
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001916void CameraService::handleTorchClientBinderDied(const wp<IBinder> &who) {
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001917 Mutex::Autolock al(mTorchClientMapMutex);
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001918 for (size_t i = 0; i < mTorchClientMap.size(); i++) {
1919 if (mTorchClientMap[i] == who) {
1920 // turn off the torch mode that was turned on by dead client
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001921 String8 cameraId = mTorchClientMap.keyAt(i);
1922 status_t res = mFlashlight->setTorchMode(cameraId, false);
1923 if (res) {
1924 ALOGE("%s: torch client died but couldn't turn off torch: "
1925 "%s (%d)", __FUNCTION__, strerror(-res), res);
1926 return;
1927 }
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001928 mTorchClientMap.removeItemsAt(i);
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001929 break;
1930 }
1931 }
1932}
1933
Igor Murashkinecf17e82012-10-02 16:05:11 -07001934/*virtual*/void CameraService::binderDied(
1935 const wp<IBinder> &who) {
1936
Igor Murashkin294d0ec2012-10-05 10:44:57 -07001937 /**
1938 * While tempting to promote the wp<IBinder> into a sp,
1939 * it's actually not supported by the binder driver
1940 */
1941
Igor Murashkinecf17e82012-10-02 16:05:11 -07001942 ALOGV("java clients' binder died");
1943
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001944 // check torch client
1945 handleTorchClientBinderDied(who);
1946
1947 // check camera device client
Igor Murashkin634a5152013-02-20 17:15:11 -08001948 sp<BasicClient> cameraClient = getClientByRemote(who);
Igor Murashkinecf17e82012-10-02 16:05:11 -07001949
Igor Murashkin294d0ec2012-10-05 10:44:57 -07001950 if (cameraClient == 0) {
Igor Murashkinecf17e82012-10-02 16:05:11 -07001951 ALOGV("java clients' binder death already cleaned up (normal case)");
1952 return;
1953 }
1954
Igor Murashkinecf17e82012-10-02 16:05:11 -07001955 ALOGW("Disconnecting camera client %p since the binder for it "
1956 "died (this pid %d)", cameraClient.get(), getCallingPid());
1957
1958 cameraClient->disconnect();
1959
1960}
1961
Igor Murashkinbfc99152013-02-27 12:55:20 -08001962void CameraService::updateStatus(ICameraServiceListener::Status status,
Igor Murashkin93747b92013-05-01 15:42:20 -07001963 int32_t cameraId,
1964 const StatusVector *rejectSourceStates) {
Igor Murashkinbfc99152013-02-27 12:55:20 -08001965 // do not lock mServiceLock here or can get into a deadlock from
1966 // connect() -> ProClient::disconnect -> updateStatus
1967 Mutex::Autolock lock(mStatusMutex);
Igor Murashkinbfc99152013-02-27 12:55:20 -08001968
1969 ICameraServiceListener::Status oldStatus = mStatusList[cameraId];
1970
1971 mStatusList[cameraId] = status;
1972
1973 if (oldStatus != status) {
1974 ALOGV("%s: Status has changed for camera ID %d from 0x%x to 0x%x",
1975 __FUNCTION__, cameraId, (uint32_t)oldStatus, (uint32_t)status);
1976
Igor Murashkincba2c162013-03-20 15:56:31 -07001977 if (oldStatus == ICameraServiceListener::STATUS_NOT_PRESENT &&
1978 (status != ICameraServiceListener::STATUS_PRESENT &&
1979 status != ICameraServiceListener::STATUS_ENUMERATING)) {
1980
1981 ALOGW("%s: From NOT_PRESENT can only transition into PRESENT"
1982 " or ENUMERATING", __FUNCTION__);
1983 mStatusList[cameraId] = oldStatus;
1984 return;
1985 }
1986
Igor Murashkin93747b92013-05-01 15:42:20 -07001987 if (rejectSourceStates != NULL) {
1988 const StatusVector &rejectList = *rejectSourceStates;
1989 StatusVector::const_iterator it = rejectList.begin();
1990
1991 /**
1992 * Sometimes we want to conditionally do a transition.
1993 * For example if a client disconnects, we want to go to PRESENT
1994 * only if we weren't already in NOT_PRESENT or ENUMERATING.
1995 */
1996 for (; it != rejectList.end(); ++it) {
1997 if (oldStatus == *it) {
1998 ALOGV("%s: Rejecting status transition for Camera ID %d, "
1999 " since the source state was was in one of the bad "
2000 " states.", __FUNCTION__, cameraId);
2001 mStatusList[cameraId] = oldStatus;
2002 return;
2003 }
2004 }
2005 }
2006
Igor Murashkinbfc99152013-02-27 12:55:20 -08002007 /**
2008 * ProClients lose their exclusive lock.
2009 * - Done before the CameraClient can initialize the HAL device,
2010 * since we want to be able to close it before they get to initialize
2011 */
2012 if (status == ICameraServiceListener::STATUS_NOT_AVAILABLE) {
2013 Vector<wp<ProClient> > proClients(mProClientList[cameraId]);
2014 Vector<wp<ProClient> >::const_iterator it;
2015
2016 for (it = proClients.begin(); it != proClients.end(); ++it) {
2017 sp<ProClient> proCl = it->promote();
2018 if (proCl.get() != NULL) {
2019 proCl->onExclusiveLockStolen();
2020 }
2021 }
2022 }
2023
Chien-Yu Chen88da5262015-02-17 13:56:46 -08002024 if (status == ICameraServiceListener::STATUS_NOT_PRESENT ||
2025 status == ICameraServiceListener::STATUS_NOT_AVAILABLE) {
2026 // update torch status to not available when the camera device
2027 // becomes not present or not available.
2028 onTorchStatusChanged(String8::format("%d", cameraId),
2029 ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE);
2030 } else if (status == ICameraServiceListener::STATUS_PRESENT) {
2031 // update torch status to available when the camera device becomes
2032 // present or available
2033 onTorchStatusChanged(String8::format("%d", cameraId),
2034 ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF);
2035 }
2036
Igor Murashkinbfc99152013-02-27 12:55:20 -08002037 Vector<sp<ICameraServiceListener> >::const_iterator it;
2038 for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
2039 (*it)->onStatusChanged(status, cameraId);
2040 }
2041 }
2042}
2043
Igor Murashkincba2c162013-03-20 15:56:31 -07002044ICameraServiceListener::Status CameraService::getStatus(int cameraId) const {
2045 if (cameraId < 0 || cameraId >= MAX_CAMERAS) {
2046 ALOGE("%s: Invalid camera ID %d", __FUNCTION__, cameraId);
2047 return ICameraServiceListener::STATUS_UNKNOWN;
2048 }
2049
2050 Mutex::Autolock al(mStatusMutex);
2051 return mStatusList[cameraId];
2052}
2053
Chien-Yu Chen88da5262015-02-17 13:56:46 -08002054status_t CameraService::getTorchStatusLocked(
2055 const String8& cameraId,
2056 ICameraServiceListener::TorchStatus *status) const {
2057 if (!status) {
2058 return BAD_VALUE;
2059 }
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002060 ssize_t index = mTorchStatusMap.indexOfKey(cameraId);
2061 if (index == NAME_NOT_FOUND) {
Chien-Yu Chen88da5262015-02-17 13:56:46 -08002062 // invalid camera ID or the camera doesn't have a flash unit
2063 return NAME_NOT_FOUND;
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002064 }
2065
Chien-Yu Chen88da5262015-02-17 13:56:46 -08002066 *status = mTorchStatusMap.valueAt(index);
2067 return OK;
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002068}
2069
Chien-Yu Chen88da5262015-02-17 13:56:46 -08002070status_t CameraService::setTorchStatusLocked(const String8& cameraId,
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002071 ICameraServiceListener::TorchStatus status) {
2072 ssize_t index = mTorchStatusMap.indexOfKey(cameraId);
2073 if (index == NAME_NOT_FOUND) {
2074 return BAD_VALUE;
2075 }
2076 ICameraServiceListener::TorchStatus& item =
2077 mTorchStatusMap.editValueAt(index);
2078 item = status;
2079
2080 return OK;
2081}
2082
Mathias Agopian65ab4712010-07-14 17:59:35 -07002083}; // namespace android