blob: 6fb5a841173b9cf2f1e78af0c70bff1afebfa391 [file] [log] [blame]
Mathias Agopian65ab4712010-07-14 17:59:35 -07001/*
Ruben Brunkd1176ef2014-02-21 10:51:38 -08002 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Mathias Agopian65ab4712010-07-14 17:59:35 -070016
17#define LOG_TAG "CameraService"
Iliyan Malchev8951a972011-04-14 16:55:59 -070018//#define LOG_NDEBUG 0
Mathias Agopian65ab4712010-07-14 17:59:35 -070019
20#include <stdio.h>
Ruben Brunkd1176ef2014-02-21 10:51:38 -080021#include <string.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070022#include <sys/types.h>
23#include <pthread.h>
24
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -080025#include <binder/AppOpsManager.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070026#include <binder/IPCThreadState.h>
27#include <binder/IServiceManager.h>
28#include <binder/MemoryBase.h>
29#include <binder/MemoryHeapBase.h>
30#include <cutils/atomic.h>
Nipun Kwatrab5ca4612010-09-11 19:31:10 -070031#include <cutils/properties.h>
Mathias Agopiandf712ea2012-02-25 18:48:35 -080032#include <gui/Surface.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070033#include <hardware/hardware.h>
34#include <media/AudioSystem.h>
Andreas Huber1b86fe02014-01-29 11:13:26 -080035#include <media/IMediaHTTPService.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070036#include <media/mediaplayer.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070037#include <utils/Errors.h>
38#include <utils/Log.h>
39#include <utils/String16.h>
Ruben Brunkd1176ef2014-02-21 10:51:38 -080040#include <utils/Trace.h>
41#include <system/camera_vendor_tags.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070042
43#include "CameraService.h"
Eino-Ville Talvala7b82efe2013-07-25 17:12:35 -070044#include "api1/CameraClient.h"
45#include "api1/Camera2Client.h"
46#include "api_pro/ProCamera2Client.h"
47#include "api2/CameraDeviceClient.h"
Igor Murashkinff3e31d2013-10-23 16:40:06 -070048#include "utils/CameraTraces.h"
Igor Murashkin98e24722013-06-19 19:51:04 -070049#include "CameraDeviceFactory.h"
Mathias Agopian65ab4712010-07-14 17:59:35 -070050
51namespace android {
52
53// ----------------------------------------------------------------------------
54// Logging support -- this is for debugging only
55// Use "adb shell dumpsys media.camera -v 1" to change it.
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -070056volatile int32_t gLogLevel = 0;
Mathias Agopian65ab4712010-07-14 17:59:35 -070057
Steve Blockb8a80522011-12-20 16:23:08 +000058#define LOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__);
59#define LOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__);
Mathias Agopian65ab4712010-07-14 17:59:35 -070060
61static void setLogLevel(int level) {
62 android_atomic_write(level, &gLogLevel);
63}
64
65// ----------------------------------------------------------------------------
66
67static int getCallingPid() {
68 return IPCThreadState::self()->getCallingPid();
69}
70
71static int getCallingUid() {
72 return IPCThreadState::self()->getCallingUid();
73}
74
Igor Murashkincba2c162013-03-20 15:56:31 -070075extern "C" {
76static void camera_device_status_change(
77 const struct camera_module_callbacks* callbacks,
78 int camera_id,
79 int new_status) {
80 sp<CameraService> cs = const_cast<CameraService*>(
81 static_cast<const CameraService*>(callbacks));
82
83 cs->onDeviceStatusChanged(
84 camera_id,
85 new_status);
86}
87} // extern "C"
88
Mathias Agopian65ab4712010-07-14 17:59:35 -070089// ----------------------------------------------------------------------------
90
91// This is ugly and only safe if we never re-create the CameraService, but
92// should be ok for now.
93static CameraService *gCameraService;
94
95CameraService::CameraService()
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -080096 :mSoundRef(0), mModule(0)
Mathias Agopian65ab4712010-07-14 17:59:35 -070097{
Steve Blockdf64d152012-01-04 20:05:49 +000098 ALOGI("CameraService started (pid=%d)", getpid());
Mathias Agopian65ab4712010-07-14 17:59:35 -070099 gCameraService = this;
Igor Murashkinbfc99152013-02-27 12:55:20 -0800100
101 for (size_t i = 0; i < MAX_CAMERAS; ++i) {
Igor Murashkincba2c162013-03-20 15:56:31 -0700102 mStatusList[i] = ICameraServiceListener::STATUS_PRESENT;
Igor Murashkinbfc99152013-02-27 12:55:20 -0800103 }
Igor Murashkincba2c162013-03-20 15:56:31 -0700104
105 this->camera_device_status_change = android::camera_device_status_change;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700106}
107
Iliyan Malchev8951a972011-04-14 16:55:59 -0700108void CameraService::onFirstRef()
109{
Igor Murashkin634a5152013-02-20 17:15:11 -0800110 LOG1("CameraService::onFirstRef");
111
Iliyan Malchev8951a972011-04-14 16:55:59 -0700112 BnCameraService::onFirstRef();
113
114 if (hw_get_module(CAMERA_HARDWARE_MODULE_ID,
115 (const hw_module_t **)&mModule) < 0) {
Steve Block29357bc2012-01-06 19:20:56 +0000116 ALOGE("Could not load camera HAL module");
Iliyan Malchev8951a972011-04-14 16:55:59 -0700117 mNumberOfCameras = 0;
118 }
119 else {
Alex Rayc0dd54f2013-02-20 13:39:37 -0800120 ALOGI("Loaded \"%s\" camera module", mModule->common.name);
Iliyan Malchev8951a972011-04-14 16:55:59 -0700121 mNumberOfCameras = mModule->get_number_of_cameras();
122 if (mNumberOfCameras > MAX_CAMERAS) {
Steve Block29357bc2012-01-06 19:20:56 +0000123 ALOGE("Number of cameras(%d) > MAX_CAMERAS(%d).",
Iliyan Malchev8951a972011-04-14 16:55:59 -0700124 mNumberOfCameras, MAX_CAMERAS);
125 mNumberOfCameras = MAX_CAMERAS;
126 }
127 for (int i = 0; i < mNumberOfCameras; i++) {
128 setCameraFree(i);
129 }
Igor Murashkincba2c162013-03-20 15:56:31 -0700130
131 if (mModule->common.module_api_version >=
132 CAMERA_MODULE_API_VERSION_2_1) {
133 mModule->set_callbacks(this);
134 }
Igor Murashkin98e24722013-06-19 19:51:04 -0700135
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800136 VendorTagDescriptor::clearGlobalVendorTagDescriptor();
137
138 if (mModule->common.module_api_version >= CAMERA_MODULE_API_VERSION_2_2) {
139 setUpVendorTags();
140 }
141
Igor Murashkin98e24722013-06-19 19:51:04 -0700142 CameraDeviceFactory::registerService(this);
Iliyan Malchev8951a972011-04-14 16:55:59 -0700143 }
144}
145
Mathias Agopian65ab4712010-07-14 17:59:35 -0700146CameraService::~CameraService() {
147 for (int i = 0; i < mNumberOfCameras; i++) {
148 if (mBusy[i]) {
Steve Block29357bc2012-01-06 19:20:56 +0000149 ALOGE("camera %d is still in use in destructor!", i);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700150 }
151 }
152
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800153 VendorTagDescriptor::clearGlobalVendorTagDescriptor();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700154 gCameraService = NULL;
155}
156
Igor Murashkincba2c162013-03-20 15:56:31 -0700157void CameraService::onDeviceStatusChanged(int cameraId,
158 int newStatus)
159{
160 ALOGI("%s: Status changed for cameraId=%d, newStatus=%d", __FUNCTION__,
161 cameraId, newStatus);
162
163 if (cameraId < 0 || cameraId >= MAX_CAMERAS) {
164 ALOGE("%s: Bad camera ID %d", __FUNCTION__, cameraId);
165 return;
166 }
167
168 if ((int)getStatus(cameraId) == newStatus) {
169 ALOGE("%s: State transition to the same status 0x%x not allowed",
170 __FUNCTION__, (uint32_t)newStatus);
171 return;
172 }
173
174 /* don't do this in updateStatus
175 since it is also called from connect and we could get into a deadlock */
176 if (newStatus == CAMERA_DEVICE_STATUS_NOT_PRESENT) {
177 Vector<sp<BasicClient> > clientsToDisconnect;
178 {
179 Mutex::Autolock al(mServiceLock);
180
181 /* Find all clients that we need to disconnect */
Igor Murashkine7ee7632013-06-11 18:10:18 -0700182 sp<BasicClient> client = mClient[cameraId].promote();
Igor Murashkincba2c162013-03-20 15:56:31 -0700183 if (client.get() != NULL) {
184 clientsToDisconnect.push_back(client);
185 }
186
187 int i = cameraId;
188 for (size_t j = 0; j < mProClientList[i].size(); ++j) {
189 sp<ProClient> cl = mProClientList[i][j].promote();
190 if (cl != NULL) {
191 clientsToDisconnect.push_back(cl);
192 }
193 }
194 }
195
196 /* now disconnect them. don't hold the lock
197 or we can get into a deadlock */
198
199 for (size_t i = 0; i < clientsToDisconnect.size(); ++i) {
200 sp<BasicClient> client = clientsToDisconnect[i];
201
202 client->disconnect();
203 /**
204 * The remote app will no longer be able to call methods on the
205 * client since the client PID will be reset to 0
206 */
207 }
208
209 ALOGV("%s: After unplug, disconnected %d clients",
210 __FUNCTION__, clientsToDisconnect.size());
211 }
212
213 updateStatus(
214 static_cast<ICameraServiceListener::Status>(newStatus), cameraId);
215
216}
217
Mathias Agopian65ab4712010-07-14 17:59:35 -0700218int32_t CameraService::getNumberOfCameras() {
219 return mNumberOfCameras;
220}
221
222status_t CameraService::getCameraInfo(int cameraId,
223 struct CameraInfo* cameraInfo) {
Iliyan Malchev8951a972011-04-14 16:55:59 -0700224 if (!mModule) {
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700225 return -ENODEV;
Iliyan Malchev8951a972011-04-14 16:55:59 -0700226 }
227
Mathias Agopian65ab4712010-07-14 17:59:35 -0700228 if (cameraId < 0 || cameraId >= mNumberOfCameras) {
229 return BAD_VALUE;
230 }
231
Iliyan Malchev8951a972011-04-14 16:55:59 -0700232 struct camera_info info;
233 status_t rc = mModule->get_camera_info(cameraId, &info);
234 cameraInfo->facing = info.facing;
235 cameraInfo->orientation = info.orientation;
236 return rc;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700237}
238
Zhijun He2b59be82013-09-25 10:14:30 -0700239status_t CameraService::getCameraCharacteristics(int cameraId,
240 CameraMetadata* cameraInfo) {
241 if (!cameraInfo) {
242 ALOGE("%s: cameraInfo is NULL", __FUNCTION__);
243 return BAD_VALUE;
244 }
245
246 if (!mModule) {
247 ALOGE("%s: camera hardware module doesn't exist", __FUNCTION__);
248 return -ENODEV;
249 }
250
251 if (mModule->common.module_api_version < CAMERA_MODULE_API_VERSION_2_0) {
252 // TODO: Remove this check once HAL1 shim is in place.
253 ALOGE("%s: Only HAL module version V2 or higher supports static metadata", __FUNCTION__);
254 return BAD_VALUE;
255 }
256
257 if (cameraId < 0 || cameraId >= mNumberOfCameras) {
258 ALOGE("%s: Invalid camera id: %d", __FUNCTION__, cameraId);
259 return BAD_VALUE;
260 }
261
262 int facing;
263 if (getDeviceVersion(cameraId, &facing) == CAMERA_DEVICE_API_VERSION_1_0) {
264 // TODO: Remove this check once HAL1 shim is in place.
265 ALOGE("%s: HAL1 doesn't support static metadata yet", __FUNCTION__);
266 return BAD_VALUE;
267 }
268
Zhijun Hef05e50e2013-10-01 11:05:33 -0700269 if (getDeviceVersion(cameraId, &facing) <= CAMERA_DEVICE_API_VERSION_2_1) {
270 // Disable HAL2.x support for camera2 API for now.
271 ALOGW("%s: HAL2.x doesn't support getCameraCharacteristics for now", __FUNCTION__);
272 return BAD_VALUE;
273 }
274
Zhijun He2b59be82013-09-25 10:14:30 -0700275 struct camera_info info;
276 status_t ret = mModule->get_camera_info(cameraId, &info);
277 *cameraInfo = info.static_camera_characteristics;
278
279 return ret;
280}
281
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800282status_t CameraService::getCameraVendorTagDescriptor(/*out*/sp<VendorTagDescriptor>& desc) {
283 if (!mModule) {
284 ALOGE("%s: camera hardware module doesn't exist", __FUNCTION__);
285 return -ENODEV;
286 }
287
288 if (mModule->common.module_api_version < CAMERA_MODULE_API_VERSION_2_2) {
289 // TODO: Remove this check once HAL1 shim is in place.
Igor Murashkine1445da2014-03-17 14:00:29 -0700290 ALOGW("%s: Only HAL module version V2.2 or higher supports vendor tags", __FUNCTION__);
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800291 return -EOPNOTSUPP;
292 }
293
294 desc = VendorTagDescriptor::getGlobalVendorTagDescriptor();
295 return OK;
296}
297
Igor Murashkin634a5152013-02-20 17:15:11 -0800298int CameraService::getDeviceVersion(int cameraId, int* facing) {
299 struct camera_info info;
300 if (mModule->get_camera_info(cameraId, &info) != OK) {
301 return -1;
302 }
303
304 int deviceVersion;
305 if (mModule->common.module_api_version >= CAMERA_MODULE_API_VERSION_2_0) {
306 deviceVersion = info.device_version;
307 } else {
308 deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
309 }
310
311 if (facing) {
312 *facing = info.facing;
313 }
314
315 return deviceVersion;
316}
317
Igor Murashkinbfc99152013-02-27 12:55:20 -0800318bool CameraService::isValidCameraId(int cameraId) {
319 int facing;
320 int deviceVersion = getDeviceVersion(cameraId, &facing);
321
322 switch(deviceVersion) {
323 case CAMERA_DEVICE_API_VERSION_1_0:
324 case CAMERA_DEVICE_API_VERSION_2_0:
325 case CAMERA_DEVICE_API_VERSION_2_1:
326 case CAMERA_DEVICE_API_VERSION_3_0:
327 return true;
328 default:
329 return false;
330 }
331
332 return false;
333}
334
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800335bool CameraService::setUpVendorTags() {
336 vendor_tag_ops_t vOps = vendor_tag_ops_t();
337
338 // Check if vendor operations have been implemented
339 if (mModule->get_vendor_tag_ops == NULL) {
340 ALOGI("%s: No vendor tags defined for this device.", __FUNCTION__);
341 return false;
342 }
343
344 ATRACE_BEGIN("camera3->get_metadata_vendor_tag_ops");
345 mModule->get_vendor_tag_ops(&vOps);
346 ATRACE_END();
347
348 // Ensure all vendor operations are present
349 if (vOps.get_tag_count == NULL || vOps.get_all_tags == NULL ||
350 vOps.get_section_name == NULL || vOps.get_tag_name == NULL ||
351 vOps.get_tag_type == NULL) {
352 ALOGE("%s: Vendor tag operations not fully defined. Ignoring definitions."
353 , __FUNCTION__);
354 return false;
355 }
356
357 // Read all vendor tag definitions into a descriptor
358 sp<VendorTagDescriptor> desc;
359 status_t res;
360 if ((res = VendorTagDescriptor::createDescriptorFromOps(&vOps, /*out*/desc))
361 != OK) {
362 ALOGE("%s: Could not generate descriptor from vendor tag operations,"
363 "received error %s (%d). Camera clients will not be able to use"
364 "vendor tags", __FUNCTION__, strerror(res), res);
365 return false;
366 }
367
368 // Set the global descriptor to use with camera metadata
369 VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
370 return true;
371}
372
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700373status_t CameraService::validateConnect(int cameraId,
Igor Murashkine6800ce2013-03-04 17:25:57 -0800374 /*inout*/
375 int& clientUid) const {
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800376
Mathias Agopian65ab4712010-07-14 17:59:35 -0700377 int callingPid = getCallingPid();
Tyler Luu5861a9a2011-10-06 00:00:03 -0500378
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800379 if (clientUid == USE_CALLING_UID) {
380 clientUid = getCallingUid();
381 } else {
382 // We only trust our own process to forward client UIDs
383 if (callingPid != getpid()) {
384 ALOGE("CameraService::connect X (pid %d) rejected (don't trust clientUid)",
385 callingPid);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700386 return PERMISSION_DENIED;
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800387 }
388 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700389
Iliyan Malchev8951a972011-04-14 16:55:59 -0700390 if (!mModule) {
Steve Block29357bc2012-01-06 19:20:56 +0000391 ALOGE("Camera HAL module not loaded");
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700392 return -ENODEV;
Iliyan Malchev8951a972011-04-14 16:55:59 -0700393 }
394
Mathias Agopian65ab4712010-07-14 17:59:35 -0700395 if (cameraId < 0 || cameraId >= mNumberOfCameras) {
Steve Block29357bc2012-01-06 19:20:56 +0000396 ALOGE("CameraService::connect X (pid %d) rejected (invalid cameraId %d).",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700397 callingPid, cameraId);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700398 return -ENODEV;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700399 }
400
Wu-cheng Lia3355432011-05-20 14:54:25 +0800401 char value[PROPERTY_VALUE_MAX];
402 property_get("sys.secpolicy.camera.disabled", value, "0");
403 if (strcmp(value, "1") == 0) {
404 // Camera is disabled by DevicePolicyManager.
Steve Blockdf64d152012-01-04 20:05:49 +0000405 ALOGI("Camera is disabled. connect X (pid %d) rejected", callingPid);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700406 return -EACCES;
Wu-cheng Lia3355432011-05-20 14:54:25 +0800407 }
408
Igor Murashkincba2c162013-03-20 15:56:31 -0700409 ICameraServiceListener::Status currentStatus = getStatus(cameraId);
410 if (currentStatus == ICameraServiceListener::STATUS_NOT_PRESENT) {
411 ALOGI("Camera is not plugged in,"
412 " connect X (pid %d) rejected", callingPid);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700413 return -ENODEV;
Igor Murashkincba2c162013-03-20 15:56:31 -0700414 } else if (currentStatus == ICameraServiceListener::STATUS_ENUMERATING) {
415 ALOGI("Camera is enumerating,"
416 " connect X (pid %d) rejected", callingPid);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700417 return -EBUSY;
Igor Murashkincba2c162013-03-20 15:56:31 -0700418 }
419 // Else don't check for STATUS_NOT_AVAILABLE.
420 // -- It's done implicitly in canConnectUnsafe /w the mBusy array
421
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700422 return OK;
Igor Murashkine6800ce2013-03-04 17:25:57 -0800423}
424
425bool CameraService::canConnectUnsafe(int cameraId,
426 const String16& clientPackageName,
427 const sp<IBinder>& remoteCallback,
Igor Murashkine7ee7632013-06-11 18:10:18 -0700428 sp<BasicClient> &client) {
Igor Murashkine6800ce2013-03-04 17:25:57 -0800429 String8 clientName8(clientPackageName);
430 int callingPid = getCallingPid();
431
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800432 if (mClient[cameraId] != 0) {
433 client = mClient[cameraId].promote();
434 if (client != 0) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700435 if (remoteCallback == client->getRemote()) {
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800436 LOG1("CameraService::connect X (pid %d) (the same client)",
437 callingPid);
Igor Murashkine6800ce2013-03-04 17:25:57 -0800438 return true;
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800439 } else {
Igor Murashkine6800ce2013-03-04 17:25:57 -0800440 // TODOSC: need to support 1 regular client,
441 // multiple shared clients here
442 ALOGW("CameraService::connect X (pid %d) rejected"
443 " (existing client).", callingPid);
444 return false;
Wu-cheng Li2fd24402012-02-23 19:01:00 -0800445 }
Wu-cheng Li2fd24402012-02-23 19:01:00 -0800446 }
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800447 mClient[cameraId].clear();
448 }
449
Igor Murashkin634a5152013-02-20 17:15:11 -0800450 /*
451 mBusy is set to false as the last step of the Client destructor,
452 after which it is guaranteed that the Client destructor has finished (
453 including any inherited destructors)
454
455 We only need this for a Client subclasses since we don't allow
456 multiple Clents to be opened concurrently, but multiple BasicClient
457 would be fine
458 */
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800459 if (mBusy[cameraId]) {
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800460 ALOGW("CameraService::connect X (pid %d, \"%s\") rejected"
461 " (camera %d is still busy).", callingPid,
462 clientName8.string(), cameraId);
Igor Murashkine6800ce2013-03-04 17:25:57 -0800463 return false;
464 }
465
466 return true;
467}
468
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700469status_t CameraService::connect(
Igor Murashkine6800ce2013-03-04 17:25:57 -0800470 const sp<ICameraClient>& cameraClient,
471 int cameraId,
472 const String16& clientPackageName,
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700473 int clientUid,
474 /*out*/
475 sp<ICamera>& device) {
Igor Murashkine6800ce2013-03-04 17:25:57 -0800476
477 String8 clientName8(clientPackageName);
478 int callingPid = getCallingPid();
479
480 LOG1("CameraService::connect E (pid %d \"%s\", id %d)", callingPid,
481 clientName8.string(), cameraId);
482
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700483 status_t status = validateConnect(cameraId, /*inout*/clientUid);
484 if (status != OK) {
485 return status;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700486 }
487
Igor Murashkine6800ce2013-03-04 17:25:57 -0800488
Igor Murashkine7ee7632013-06-11 18:10:18 -0700489 sp<Client> client;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700490 {
491 Mutex::Autolock lock(mServiceLock);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700492 sp<BasicClient> clientTmp;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700493 if (!canConnectUnsafe(cameraId, clientPackageName,
494 cameraClient->asBinder(),
Igor Murashkine7ee7632013-06-11 18:10:18 -0700495 /*out*/clientTmp)) {
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700496 return -EBUSY;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700497 } else if (client.get() != NULL) {
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700498 device = static_cast<Client*>(clientTmp.get());
499 return OK;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700500 }
501
502 int facing = -1;
503 int deviceVersion = getDeviceVersion(cameraId, &facing);
504
505 // If there are other non-exclusive users of the camera,
506 // this will tear them down before we can reuse the camera
507 if (isValidCameraId(cameraId)) {
Igor Murashkincba2c162013-03-20 15:56:31 -0700508 // transition from PRESENT -> NOT_AVAILABLE
Igor Murashkinacd695c2013-03-13 17:23:00 -0700509 updateStatus(ICameraServiceListener::STATUS_NOT_AVAILABLE,
510 cameraId);
511 }
512
513 switch(deviceVersion) {
514 case CAMERA_DEVICE_API_VERSION_1_0:
515 client = new CameraClient(this, cameraClient,
516 clientPackageName, cameraId,
517 facing, callingPid, clientUid, getpid());
518 break;
519 case CAMERA_DEVICE_API_VERSION_2_0:
520 case CAMERA_DEVICE_API_VERSION_2_1:
521 case CAMERA_DEVICE_API_VERSION_3_0:
522 client = new Camera2Client(this, cameraClient,
523 clientPackageName, cameraId,
524 facing, callingPid, clientUid, getpid(),
525 deviceVersion);
526 break;
527 case -1:
528 ALOGE("Invalid camera id %d", cameraId);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700529 return BAD_VALUE;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700530 default:
531 ALOGE("Unknown camera device HAL version: %d", deviceVersion);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700532 return INVALID_OPERATION;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700533 }
534
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700535 status_t status = connectFinishUnsafe(client, client->getRemote());
536 if (status != OK) {
Igor Murashkinacd695c2013-03-13 17:23:00 -0700537 // this is probably not recoverable.. maybe the client can try again
Igor Murashkincba2c162013-03-20 15:56:31 -0700538 // OK: we can only get here if we were originally in PRESENT state
539 updateStatus(ICameraServiceListener::STATUS_PRESENT, cameraId);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700540 return status;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700541 }
542
543 mClient[cameraId] = client;
544 LOG1("CameraService::connect X (id %d, this pid is %d)", cameraId,
545 getpid());
Igor Murashkine6800ce2013-03-04 17:25:57 -0800546 }
Igor Murashkinacd695c2013-03-13 17:23:00 -0700547 // important: release the mutex here so the client can call back
548 // into the service from its destructor (can be at the end of the call)
Igor Murashkinbfc99152013-02-27 12:55:20 -0800549
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700550 device = client;
551 return OK;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700552}
553
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700554status_t CameraService::connectFinishUnsafe(const sp<BasicClient>& client,
555 const sp<IBinder>& remoteCallback) {
556 status_t status = client->initialize(mModule);
557 if (status != OK) {
558 return status;
Igor Murashkine6800ce2013-03-04 17:25:57 -0800559 }
560
Igor Murashkine7ee7632013-06-11 18:10:18 -0700561 remoteCallback->linkToDeath(this);
Igor Murashkine6800ce2013-03-04 17:25:57 -0800562
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700563 return OK;
Igor Murashkine6800ce2013-03-04 17:25:57 -0800564}
565
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700566status_t CameraService::connectPro(
Igor Murashkin634a5152013-02-20 17:15:11 -0800567 const sp<IProCameraCallbacks>& cameraCb,
Igor Murashkinc073ba52013-02-26 14:32:34 -0800568 int cameraId,
569 const String16& clientPackageName,
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700570 int clientUid,
571 /*out*/
572 sp<IProCameraUser>& device)
Igor Murashkin634a5152013-02-20 17:15:11 -0800573{
Igor Murashkinbfc99152013-02-27 12:55:20 -0800574 String8 clientName8(clientPackageName);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700575 int callingPid = getCallingPid();
Igor Murashkin634a5152013-02-20 17:15:11 -0800576
Igor Murashkine6800ce2013-03-04 17:25:57 -0800577 LOG1("CameraService::connectPro E (pid %d \"%s\", id %d)", callingPid,
578 clientName8.string(), cameraId);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700579 status_t status = validateConnect(cameraId, /*inout*/clientUid);
580 if (status != OK) {
581 return status;
Igor Murashkin634a5152013-02-20 17:15:11 -0800582 }
583
Igor Murashkinacd695c2013-03-13 17:23:00 -0700584 sp<ProClient> client;
Igor Murashkine6800ce2013-03-04 17:25:57 -0800585 {
Igor Murashkinacd695c2013-03-13 17:23:00 -0700586 Mutex::Autolock lock(mServiceLock);
587 {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700588 sp<BasicClient> client;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700589 if (!canConnectUnsafe(cameraId, clientPackageName,
590 cameraCb->asBinder(),
591 /*out*/client)) {
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700592 return -EBUSY;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700593 }
594 }
595
596 int facing = -1;
597 int deviceVersion = getDeviceVersion(cameraId, &facing);
598
599 switch(deviceVersion) {
600 case CAMERA_DEVICE_API_VERSION_1_0:
601 ALOGE("Camera id %d uses HALv1, doesn't support ProCamera",
602 cameraId);
Ruben Brunk17963d12013-08-19 15:21:19 -0700603 return -EOPNOTSUPP;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700604 break;
605 case CAMERA_DEVICE_API_VERSION_2_0:
606 case CAMERA_DEVICE_API_VERSION_2_1:
Zhijun He47110052013-07-22 17:34:34 -0700607 case CAMERA_DEVICE_API_VERSION_3_0:
Igor Murashkinacd695c2013-03-13 17:23:00 -0700608 client = new ProCamera2Client(this, cameraCb, String16(),
609 cameraId, facing, callingPid, USE_CALLING_UID, getpid());
610 break;
611 case -1:
612 ALOGE("Invalid camera id %d", cameraId);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700613 return BAD_VALUE;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700614 default:
615 ALOGE("Unknown camera device HAL version: %d", deviceVersion);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700616 return INVALID_OPERATION;
Igor Murashkine6800ce2013-03-04 17:25:57 -0800617 }
Igor Murashkinacd695c2013-03-13 17:23:00 -0700618
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700619 status_t status = connectFinishUnsafe(client, client->getRemote());
620 if (status != OK) {
621 return status;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700622 }
623
624 mProClientList[cameraId].push(client);
625
626 LOG1("CameraService::connectPro X (id %d, this pid is %d)", cameraId,
627 getpid());
Igor Murashkine6800ce2013-03-04 17:25:57 -0800628 }
Igor Murashkinacd695c2013-03-13 17:23:00 -0700629 // important: release the mutex here so the client can call back
630 // into the service from its destructor (can be at the end of the call)
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700631 device = client;
632 return OK;
Igor Murashkinbfc99152013-02-27 12:55:20 -0800633}
Igor Murashkin634a5152013-02-20 17:15:11 -0800634
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700635status_t CameraService::connectDevice(
Igor Murashkine7ee7632013-06-11 18:10:18 -0700636 const sp<ICameraDeviceCallbacks>& cameraCb,
637 int cameraId,
638 const String16& clientPackageName,
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700639 int clientUid,
640 /*out*/
641 sp<ICameraDeviceUser>& device)
Igor Murashkine7ee7632013-06-11 18:10:18 -0700642{
Igor Murashkine7ee7632013-06-11 18:10:18 -0700643
644 String8 clientName8(clientPackageName);
645 int callingPid = getCallingPid();
646
647 LOG1("CameraService::connectDevice E (pid %d \"%s\", id %d)", callingPid,
648 clientName8.string(), cameraId);
649
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700650 status_t status = validateConnect(cameraId, /*inout*/clientUid);
651 if (status != OK) {
652 return status;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700653 }
654
655 sp<CameraDeviceClient> client;
656 {
657 Mutex::Autolock lock(mServiceLock);
658 {
659 sp<BasicClient> client;
660 if (!canConnectUnsafe(cameraId, clientPackageName,
661 cameraCb->asBinder(),
662 /*out*/client)) {
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700663 return -EBUSY;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700664 }
665 }
666
667 int facing = -1;
668 int deviceVersion = getDeviceVersion(cameraId, &facing);
669
670 // If there are other non-exclusive users of the camera,
671 // this will tear them down before we can reuse the camera
672 if (isValidCameraId(cameraId)) {
673 // transition from PRESENT -> NOT_AVAILABLE
674 updateStatus(ICameraServiceListener::STATUS_NOT_AVAILABLE,
675 cameraId);
676 }
677
678 switch(deviceVersion) {
679 case CAMERA_DEVICE_API_VERSION_1_0:
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700680 ALOGW("Camera using old HAL version: %d", deviceVersion);
Ruben Brunk17963d12013-08-19 15:21:19 -0700681 return -EOPNOTSUPP;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700682 // TODO: don't allow 2.0 Only allow 2.1 and higher
683 case CAMERA_DEVICE_API_VERSION_2_0:
684 case CAMERA_DEVICE_API_VERSION_2_1:
685 case CAMERA_DEVICE_API_VERSION_3_0:
686 client = new CameraDeviceClient(this, cameraCb, String16(),
687 cameraId, facing, callingPid, USE_CALLING_UID, getpid());
688 break;
689 case -1:
690 ALOGE("Invalid camera id %d", cameraId);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700691 return BAD_VALUE;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700692 default:
693 ALOGE("Unknown camera device HAL version: %d", deviceVersion);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700694 return INVALID_OPERATION;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700695 }
696
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700697 status_t status = connectFinishUnsafe(client, client->getRemote());
698 if (status != OK) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700699 // this is probably not recoverable.. maybe the client can try again
700 // OK: we can only get here if we were originally in PRESENT state
701 updateStatus(ICameraServiceListener::STATUS_PRESENT, cameraId);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700702 return status;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700703 }
704
705 LOG1("CameraService::connectDevice X (id %d, this pid is %d)", cameraId,
706 getpid());
707
708 mClient[cameraId] = client;
709 }
710 // important: release the mutex here so the client can call back
711 // into the service from its destructor (can be at the end of the call)
712
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700713 device = client;
714 return OK;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700715}
716
717
Igor Murashkinbfc99152013-02-27 12:55:20 -0800718status_t CameraService::addListener(
719 const sp<ICameraServiceListener>& listener) {
720 ALOGV("%s: Add listener %p", __FUNCTION__, listener.get());
Igor Murashkin634a5152013-02-20 17:15:11 -0800721
Igor Murashkinbfc99152013-02-27 12:55:20 -0800722 Mutex::Autolock lock(mServiceLock);
723
724 Vector<sp<ICameraServiceListener> >::iterator it, end;
725 for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
726 if ((*it)->asBinder() == listener->asBinder()) {
727 ALOGW("%s: Tried to add listener %p which was already subscribed",
728 __FUNCTION__, listener.get());
729 return ALREADY_EXISTS;
730 }
731 }
732
733 mListenerList.push_back(listener);
734
Igor Murashkincba2c162013-03-20 15:56:31 -0700735 /* Immediately signal current status to this listener only */
736 {
737 Mutex::Autolock m(mStatusMutex) ;
738 int numCams = getNumberOfCameras();
739 for (int i = 0; i < numCams; ++i) {
740 listener->onStatusChanged(mStatusList[i], i);
741 }
742 }
743
Igor Murashkinbfc99152013-02-27 12:55:20 -0800744 return OK;
745}
746status_t CameraService::removeListener(
747 const sp<ICameraServiceListener>& listener) {
748 ALOGV("%s: Remove listener %p", __FUNCTION__, listener.get());
749
750 Mutex::Autolock lock(mServiceLock);
751
752 Vector<sp<ICameraServiceListener> >::iterator it;
753 for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
754 if ((*it)->asBinder() == listener->asBinder()) {
755 mListenerList.erase(it);
756 return OK;
757 }
758 }
759
760 ALOGW("%s: Tried to remove a listener %p which was not subscribed",
761 __FUNCTION__, listener.get());
762
763 return BAD_VALUE;
Igor Murashkin634a5152013-02-20 17:15:11 -0800764}
765
766void CameraService::removeClientByRemote(const wp<IBinder>& remoteBinder) {
767 int callingPid = getCallingPid();
768 LOG1("CameraService::removeClientByRemote E (pid %d)", callingPid);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700769
Igor Murashkinecf17e82012-10-02 16:05:11 -0700770 // Declare this before the lock to make absolutely sure the
771 // destructor won't be called with the lock held.
772 Mutex::Autolock lock(mServiceLock);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700773
Igor Murashkinecf17e82012-10-02 16:05:11 -0700774 int outIndex;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700775 sp<BasicClient> client = findClientUnsafe(remoteBinder, outIndex);
Igor Murashkinecf17e82012-10-02 16:05:11 -0700776
777 if (client != 0) {
778 // Found our camera, clear and leave.
779 LOG1("removeClient: clear camera %d", outIndex);
780 mClient[outIndex].clear();
781
Igor Murashkine7ee7632013-06-11 18:10:18 -0700782 client->getRemote()->unlinkToDeath(this);
Igor Murashkin634a5152013-02-20 17:15:11 -0800783 } else {
784
785 sp<ProClient> clientPro = findProClientUnsafe(remoteBinder);
786
787 if (clientPro != NULL) {
788 // Found our camera, clear and leave.
789 LOG1("removeClient: clear pro %p", clientPro.get());
790
791 clientPro->getRemoteCallback()->asBinder()->unlinkToDeath(this);
792 }
Igor Murashkinecf17e82012-10-02 16:05:11 -0700793 }
794
Igor Murashkin634a5152013-02-20 17:15:11 -0800795 LOG1("CameraService::removeClientByRemote X (pid %d)", callingPid);
796}
797
798sp<CameraService::ProClient> CameraService::findProClientUnsafe(
799 const wp<IBinder>& cameraCallbacksRemote)
800{
801 sp<ProClient> clientPro;
802
803 for (int i = 0; i < mNumberOfCameras; ++i) {
804 Vector<size_t> removeIdx;
805
806 for (size_t j = 0; j < mProClientList[i].size(); ++j) {
807 wp<ProClient> cl = mProClientList[i][j];
808
809 sp<ProClient> clStrong = cl.promote();
810 if (clStrong != NULL && clStrong->getRemote() == cameraCallbacksRemote) {
811 clientPro = clStrong;
812 break;
813 } else if (clStrong == NULL) {
814 // mark to clean up dead ptr
815 removeIdx.push(j);
816 }
817 }
818
819 // remove stale ptrs (in reverse so the indices dont change)
820 for (ssize_t j = (ssize_t)removeIdx.size() - 1; j >= 0; --j) {
821 mProClientList[i].removeAt(removeIdx[j]);
822 }
823
824 }
825
826 return clientPro;
Igor Murashkinecf17e82012-10-02 16:05:11 -0700827}
828
Igor Murashkine7ee7632013-06-11 18:10:18 -0700829sp<CameraService::BasicClient> CameraService::findClientUnsafe(
Igor Murashkin294d0ec2012-10-05 10:44:57 -0700830 const wp<IBinder>& cameraClient, int& outIndex) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700831 sp<BasicClient> client;
Igor Murashkinecf17e82012-10-02 16:05:11 -0700832
833 for (int i = 0; i < mNumberOfCameras; i++) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700834
835 // This happens when we have already disconnected (or this is
836 // just another unused camera).
837 if (mClient[i] == 0) continue;
838
839 // Promote mClient. It can fail if we are called from this path:
Igor Murashkin634a5152013-02-20 17:15:11 -0800840 // Client::~Client() -> disconnect() -> removeClientByRemote().
Mathias Agopian65ab4712010-07-14 17:59:35 -0700841 client = mClient[i].promote();
842
Igor Murashkinecf17e82012-10-02 16:05:11 -0700843 // Clean up stale client entry
844 if (client == NULL) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700845 mClient[i].clear();
846 continue;
847 }
848
Igor Murashkine7ee7632013-06-11 18:10:18 -0700849 if (cameraClient == client->getRemote()) {
Igor Murashkinecf17e82012-10-02 16:05:11 -0700850 // Found our camera
851 outIndex = i;
852 return client;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700853 }
854 }
855
Igor Murashkinecf17e82012-10-02 16:05:11 -0700856 outIndex = -1;
857 return NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700858}
859
Igor Murashkine7ee7632013-06-11 18:10:18 -0700860CameraService::BasicClient* CameraService::getClientByIdUnsafe(int cameraId) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700861 if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
Keun young Parkd8973a72012-03-28 14:13:09 -0700862 return mClient[cameraId].unsafe_get();
863}
864
865Mutex* CameraService::getClientLockById(int cameraId) {
866 if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
867 return &mClientLock[cameraId];
Mathias Agopian65ab4712010-07-14 17:59:35 -0700868}
869
Igor Murashkin634a5152013-02-20 17:15:11 -0800870sp<CameraService::BasicClient> CameraService::getClientByRemote(
Igor Murashkin294d0ec2012-10-05 10:44:57 -0700871 const wp<IBinder>& cameraClient) {
Igor Murashkinecf17e82012-10-02 16:05:11 -0700872
873 // Declare this before the lock to make absolutely sure the
874 // destructor won't be called with the lock held.
Igor Murashkin634a5152013-02-20 17:15:11 -0800875 sp<BasicClient> client;
Igor Murashkinecf17e82012-10-02 16:05:11 -0700876
877 Mutex::Autolock lock(mServiceLock);
878
879 int outIndex;
880 client = findClientUnsafe(cameraClient, outIndex);
881
882 return client;
883}
884
Mathias Agopian65ab4712010-07-14 17:59:35 -0700885status_t CameraService::onTransact(
886 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
887 // Permission checks
888 switch (code) {
889 case BnCameraService::CONNECT:
Igor Murashkin634a5152013-02-20 17:15:11 -0800890 case BnCameraService::CONNECT_PRO:
Mathias Agopian65ab4712010-07-14 17:59:35 -0700891 const int pid = getCallingPid();
892 const int self_pid = getpid();
893 if (pid != self_pid) {
894 // we're called from a different process, do the real check
895 if (!checkCallingPermission(
896 String16("android.permission.CAMERA"))) {
897 const int uid = getCallingUid();
Steve Block29357bc2012-01-06 19:20:56 +0000898 ALOGE("Permission Denial: "
Mathias Agopian65ab4712010-07-14 17:59:35 -0700899 "can't use the camera pid=%d, uid=%d", pid, uid);
900 return PERMISSION_DENIED;
901 }
902 }
903 break;
904 }
905
906 return BnCameraService::onTransact(code, data, reply, flags);
907}
908
909// The reason we need this busy bit is a new CameraService::connect() request
910// may come in while the previous Client's destructor has not been run or is
911// still running. If the last strong reference of the previous Client is gone
912// but the destructor has not been finished, we should not allow the new Client
913// to be created because we need to wait for the previous Client to tear down
914// the hardware first.
915void CameraService::setCameraBusy(int cameraId) {
916 android_atomic_write(1, &mBusy[cameraId]);
Igor Murashkinecf17e82012-10-02 16:05:11 -0700917
918 ALOGV("setCameraBusy cameraId=%d", cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700919}
920
921void CameraService::setCameraFree(int cameraId) {
922 android_atomic_write(0, &mBusy[cameraId]);
Igor Murashkinecf17e82012-10-02 16:05:11 -0700923
924 ALOGV("setCameraFree cameraId=%d", cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700925}
926
927// We share the media players for shutter and recording sound for all clients.
928// A reference count is kept to determine when we will actually release the
929// media players.
930
Chih-Chung Changff4f55c2011-10-17 19:03:12 +0800931MediaPlayer* CameraService::newMediaPlayer(const char *file) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700932 MediaPlayer* mp = new MediaPlayer();
Andreas Huber1b86fe02014-01-29 11:13:26 -0800933 if (mp->setDataSource(NULL /* httpService */, file, NULL) == NO_ERROR) {
Eino-Ville Talvala60a78ac2012-01-05 15:34:53 -0800934 mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700935 mp->prepare();
936 } else {
Steve Block29357bc2012-01-06 19:20:56 +0000937 ALOGE("Failed to load CameraService sounds: %s", file);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700938 return NULL;
939 }
940 return mp;
941}
942
943void CameraService::loadSound() {
944 Mutex::Autolock lock(mSoundLock);
945 LOG1("CameraService::loadSound ref=%d", mSoundRef);
946 if (mSoundRef++) return;
947
948 mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
949 mSoundPlayer[SOUND_RECORDING] = newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");
950}
951
952void CameraService::releaseSound() {
953 Mutex::Autolock lock(mSoundLock);
954 LOG1("CameraService::releaseSound ref=%d", mSoundRef);
955 if (--mSoundRef) return;
956
957 for (int i = 0; i < NUM_SOUNDS; i++) {
958 if (mSoundPlayer[i] != 0) {
959 mSoundPlayer[i]->disconnect();
960 mSoundPlayer[i].clear();
961 }
962 }
963}
964
965void CameraService::playSound(sound_kind kind) {
966 LOG1("playSound(%d)", kind);
967 Mutex::Autolock lock(mSoundLock);
968 sp<MediaPlayer> player = mSoundPlayer[kind];
969 if (player != 0) {
Chih-Chung Chang8888a752011-10-20 10:47:26 +0800970 player->seekTo(0);
971 player->start();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700972 }
973}
974
975// ----------------------------------------------------------------------------
976
977CameraService::Client::Client(const sp<CameraService>& cameraService,
Wu-cheng Lib7a67942010-08-17 15:45:37 -0700978 const sp<ICameraClient>& cameraClient,
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800979 const String16& clientPackageName,
980 int cameraId, int cameraFacing,
981 int clientPid, uid_t clientUid,
982 int servicePid) :
Igor Murashkin634a5152013-02-20 17:15:11 -0800983 CameraService::BasicClient(cameraService, cameraClient->asBinder(),
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800984 clientPackageName,
985 cameraId, cameraFacing,
986 clientPid, clientUid,
987 servicePid)
Igor Murashkin634a5152013-02-20 17:15:11 -0800988{
Mathias Agopian65ab4712010-07-14 17:59:35 -0700989 int callingPid = getCallingPid();
Wu-cheng Li2fd24402012-02-23 19:01:00 -0800990 LOG1("Client::Client E (pid %d, id %d)", callingPid, cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700991
Igor Murashkin44cfcf02013-03-01 16:22:28 -0800992 mRemoteCallback = cameraClient;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700993
Mathias Agopian65ab4712010-07-14 17:59:35 -0700994 cameraService->setCameraBusy(cameraId);
995 cameraService->loadSound();
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800996
Wu-cheng Li2fd24402012-02-23 19:01:00 -0800997 LOG1("Client::Client X (pid %d, id %d)", callingPid, cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700998}
999
Mathias Agopian65ab4712010-07-14 17:59:35 -07001000// tear down the client
1001CameraService::Client::~Client() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -07001002 ALOGV("~Client");
Igor Murashkin634a5152013-02-20 17:15:11 -08001003 mDestructionStarted = true;
1004
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001005 mCameraService->releaseSound();
Igor Murashkin036bc3e2012-10-08 15:09:46 -07001006 // unconditionally disconnect. function is idempotent
1007 Client::disconnect();
Mathias Agopian65ab4712010-07-14 17:59:35 -07001008}
1009
Igor Murashkin634a5152013-02-20 17:15:11 -08001010CameraService::BasicClient::BasicClient(const sp<CameraService>& cameraService,
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001011 const sp<IBinder>& remoteCallback,
1012 const String16& clientPackageName,
1013 int cameraId, int cameraFacing,
1014 int clientPid, uid_t clientUid,
1015 int servicePid):
1016 mClientPackageName(clientPackageName)
Igor Murashkin634a5152013-02-20 17:15:11 -08001017{
1018 mCameraService = cameraService;
Igor Murashkin44cfcf02013-03-01 16:22:28 -08001019 mRemoteBinder = remoteCallback;
Igor Murashkin634a5152013-02-20 17:15:11 -08001020 mCameraId = cameraId;
1021 mCameraFacing = cameraFacing;
1022 mClientPid = clientPid;
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001023 mClientUid = clientUid;
Igor Murashkin634a5152013-02-20 17:15:11 -08001024 mServicePid = servicePid;
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001025 mOpsActive = false;
Igor Murashkin634a5152013-02-20 17:15:11 -08001026 mDestructionStarted = false;
1027}
1028
1029CameraService::BasicClient::~BasicClient() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -07001030 ALOGV("~BasicClient");
Igor Murashkin634a5152013-02-20 17:15:11 -08001031 mDestructionStarted = true;
1032}
1033
1034void CameraService::BasicClient::disconnect() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -07001035 ALOGV("BasicClient::disconnect");
Igor Murashkin44cfcf02013-03-01 16:22:28 -08001036 mCameraService->removeClientByRemote(mRemoteBinder);
Igor Murashkincba2c162013-03-20 15:56:31 -07001037 // client shouldn't be able to call into us anymore
1038 mClientPid = 0;
Igor Murashkin634a5152013-02-20 17:15:11 -08001039}
1040
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001041status_t CameraService::BasicClient::startCameraOps() {
1042 int32_t res;
1043
1044 mOpsCallback = new OpsCallback(this);
1045
Igor Murashkine6800ce2013-03-04 17:25:57 -08001046 {
1047 ALOGV("%s: Start camera ops, package name = %s, client UID = %d",
1048 __FUNCTION__, String8(mClientPackageName).string(), mClientUid);
1049 }
1050
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001051 mAppOpsManager.startWatchingMode(AppOpsManager::OP_CAMERA,
1052 mClientPackageName, mOpsCallback);
1053 res = mAppOpsManager.startOp(AppOpsManager::OP_CAMERA,
1054 mClientUid, mClientPackageName);
1055
1056 if (res != AppOpsManager::MODE_ALLOWED) {
1057 ALOGI("Camera %d: Access for \"%s\" has been revoked",
1058 mCameraId, String8(mClientPackageName).string());
1059 return PERMISSION_DENIED;
1060 }
1061 mOpsActive = true;
1062 return OK;
1063}
1064
1065status_t CameraService::BasicClient::finishCameraOps() {
1066 if (mOpsActive) {
1067 mAppOpsManager.finishOp(AppOpsManager::OP_CAMERA, mClientUid,
1068 mClientPackageName);
1069 mOpsActive = false;
1070 }
1071 mAppOpsManager.stopWatchingMode(mOpsCallback);
1072 mOpsCallback.clear();
1073
1074 return OK;
1075}
1076
1077void CameraService::BasicClient::opChanged(int32_t op, const String16& packageName) {
1078 String8 name(packageName);
1079 String8 myName(mClientPackageName);
1080
1081 if (op != AppOpsManager::OP_CAMERA) {
1082 ALOGW("Unexpected app ops notification received: %d", op);
1083 return;
1084 }
1085
1086 int32_t res;
1087 res = mAppOpsManager.checkOp(AppOpsManager::OP_CAMERA,
1088 mClientUid, mClientPackageName);
1089 ALOGV("checkOp returns: %d, %s ", res,
1090 res == AppOpsManager::MODE_ALLOWED ? "ALLOWED" :
1091 res == AppOpsManager::MODE_IGNORED ? "IGNORED" :
1092 res == AppOpsManager::MODE_ERRORED ? "ERRORED" :
1093 "UNKNOWN");
1094
1095 if (res != AppOpsManager::MODE_ALLOWED) {
1096 ALOGI("Camera %d: Access for \"%s\" revoked", mCameraId,
1097 myName.string());
1098 // Reset the client PID to allow server-initiated disconnect,
1099 // and to prevent further calls by client.
1100 mClientPid = getCallingPid();
1101 notifyError();
1102 disconnect();
1103 }
1104}
1105
Mathias Agopian65ab4712010-07-14 17:59:35 -07001106// ----------------------------------------------------------------------------
1107
Keun young Parkd8973a72012-03-28 14:13:09 -07001108Mutex* CameraService::Client::getClientLockFromCookie(void* user) {
Kévin PETIT377b2ec2014-02-03 12:35:36 +00001109 return gCameraService->getClientLockById((int)(intptr_t) user);
Keun young Parkd8973a72012-03-28 14:13:09 -07001110}
1111
1112// Provide client pointer for callbacks. Client lock returned from getClientLockFromCookie should
1113// be acquired for this to be safe
1114CameraService::Client* CameraService::Client::getClientFromCookie(void* user) {
Kévin PETIT377b2ec2014-02-03 12:35:36 +00001115 BasicClient *basicClient = gCameraService->getClientByIdUnsafe((int)(intptr_t) user);
Igor Murashkine7ee7632013-06-11 18:10:18 -07001116 // OK: only CameraClient calls this, and they already cast anyway.
1117 Client* client = static_cast<Client*>(basicClient);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001118
1119 // This could happen if the Client is in the process of shutting down (the
1120 // last strong reference is gone, but the destructor hasn't finished
1121 // stopping the hardware).
Keun young Parkd8973a72012-03-28 14:13:09 -07001122 if (client == NULL) return NULL;
1123
1124 // destruction already started, so should not be accessed
1125 if (client->mDestructionStarted) return NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001126
Mathias Agopian65ab4712010-07-14 17:59:35 -07001127 return client;
1128}
1129
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001130void CameraService::Client::notifyError() {
Igor Murashkin44cfcf02013-03-01 16:22:28 -08001131 mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_RELEASED, 0);
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001132}
1133
Igor Murashkin036bc3e2012-10-08 15:09:46 -07001134// NOTE: function is idempotent
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001135void CameraService::Client::disconnect() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -07001136 ALOGV("Client::disconnect");
Igor Murashkin634a5152013-02-20 17:15:11 -08001137 BasicClient::disconnect();
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001138 mCameraService->setCameraFree(mCameraId);
Igor Murashkin93747b92013-05-01 15:42:20 -07001139
1140 StatusVector rejectSourceStates;
1141 rejectSourceStates.push_back(ICameraServiceListener::STATUS_NOT_PRESENT);
1142 rejectSourceStates.push_back(ICameraServiceListener::STATUS_ENUMERATING);
1143
1144 // Transition to PRESENT if the camera is not in either of above 2 states
Igor Murashkincba2c162013-03-20 15:56:31 -07001145 mCameraService->updateStatus(ICameraServiceListener::STATUS_PRESENT,
Igor Murashkin93747b92013-05-01 15:42:20 -07001146 mCameraId,
1147 &rejectSourceStates);
Wu-cheng Lie09591e2010-10-14 20:17:44 +08001148}
1149
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001150CameraService::Client::OpsCallback::OpsCallback(wp<BasicClient> client):
1151 mClient(client) {
1152}
1153
1154void CameraService::Client::OpsCallback::opChanged(int32_t op,
1155 const String16& packageName) {
1156 sp<BasicClient> client = mClient.promote();
1157 if (client != NULL) {
1158 client->opChanged(op, packageName);
1159 }
1160}
1161
Mathias Agopian65ab4712010-07-14 17:59:35 -07001162// ----------------------------------------------------------------------------
Igor Murashkin634a5152013-02-20 17:15:11 -08001163// IProCamera
1164// ----------------------------------------------------------------------------
1165
1166CameraService::ProClient::ProClient(const sp<CameraService>& cameraService,
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001167 const sp<IProCameraCallbacks>& remoteCallback,
1168 const String16& clientPackageName,
1169 int cameraId,
1170 int cameraFacing,
1171 int clientPid,
1172 uid_t clientUid,
1173 int servicePid)
1174 : CameraService::BasicClient(cameraService, remoteCallback->asBinder(),
1175 clientPackageName, cameraId, cameraFacing,
1176 clientPid, clientUid, servicePid)
Igor Murashkin634a5152013-02-20 17:15:11 -08001177{
1178 mRemoteCallback = remoteCallback;
1179}
1180
1181CameraService::ProClient::~ProClient() {
Igor Murashkin634a5152013-02-20 17:15:11 -08001182}
1183
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001184void CameraService::ProClient::notifyError() {
Igor Murashkine6800ce2013-03-04 17:25:57 -08001185 mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_RELEASED, 0);
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001186}
1187
Igor Murashkin634a5152013-02-20 17:15:11 -08001188// ----------------------------------------------------------------------------
Mathias Agopian65ab4712010-07-14 17:59:35 -07001189
1190static const int kDumpLockRetries = 50;
1191static const int kDumpLockSleep = 60000;
1192
1193static bool tryLock(Mutex& mutex)
1194{
1195 bool locked = false;
1196 for (int i = 0; i < kDumpLockRetries; ++i) {
1197 if (mutex.tryLock() == NO_ERROR) {
1198 locked = true;
1199 break;
1200 }
1201 usleep(kDumpLockSleep);
1202 }
1203 return locked;
1204}
1205
1206status_t CameraService::dump(int fd, const Vector<String16>& args) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001207 String8 result;
1208 if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -07001209 result.appendFormat("Permission Denial: "
Mathias Agopian65ab4712010-07-14 17:59:35 -07001210 "can't dump CameraService from pid=%d, uid=%d\n",
1211 getCallingPid(),
1212 getCallingUid());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001213 write(fd, result.string(), result.size());
1214 } else {
1215 bool locked = tryLock(mServiceLock);
1216 // failed to lock - CameraService is probably deadlocked
1217 if (!locked) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -07001218 result.append("CameraService may be deadlocked\n");
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001219 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001220 }
1221
1222 bool hasClient = false;
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001223 if (!mModule) {
1224 result = String8::format("No camera module available!\n");
1225 write(fd, result.string(), result.size());
1226 return NO_ERROR;
1227 }
1228
1229 result = String8::format("Camera module HAL API version: 0x%x\n",
1230 mModule->common.hal_api_version);
1231 result.appendFormat("Camera module API version: 0x%x\n",
1232 mModule->common.module_api_version);
1233 result.appendFormat("Camera module name: %s\n",
1234 mModule->common.name);
1235 result.appendFormat("Camera module author: %s\n",
1236 mModule->common.author);
1237 result.appendFormat("Number of camera devices: %d\n\n", mNumberOfCameras);
1238 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001239 for (int i = 0; i < mNumberOfCameras; i++) {
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001240 result = String8::format("Camera %d static information:\n", i);
1241 camera_info info;
1242
1243 status_t rc = mModule->get_camera_info(i, &info);
1244 if (rc != OK) {
1245 result.appendFormat(" Error reading static information!\n");
1246 write(fd, result.string(), result.size());
1247 } else {
1248 result.appendFormat(" Facing: %s\n",
1249 info.facing == CAMERA_FACING_BACK ? "BACK" : "FRONT");
1250 result.appendFormat(" Orientation: %d\n", info.orientation);
1251 int deviceVersion;
1252 if (mModule->common.module_api_version <
1253 CAMERA_MODULE_API_VERSION_2_0) {
1254 deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
1255 } else {
1256 deviceVersion = info.device_version;
1257 }
1258 result.appendFormat(" Device version: 0x%x\n", deviceVersion);
1259 if (deviceVersion >= CAMERA_DEVICE_API_VERSION_2_0) {
1260 result.appendFormat(" Device static metadata:\n");
1261 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -07001262 dump_indented_camera_metadata(info.static_camera_characteristics,
1263 fd, 2, 4);
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001264 } else {
1265 write(fd, result.string(), result.size());
1266 }
1267 }
1268
Igor Murashkine7ee7632013-06-11 18:10:18 -07001269 sp<BasicClient> client = mClient[i].promote();
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001270 if (client == 0) {
1271 result = String8::format(" Device is closed, no client instance\n");
1272 write(fd, result.string(), result.size());
1273 continue;
1274 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001275 hasClient = true;
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001276 result = String8::format(" Device is open. Client instance dump:\n");
1277 write(fd, result.string(), result.size());
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001278 client->dump(fd, args);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001279 }
1280 if (!hasClient) {
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001281 result = String8::format("\nNo active camera clients yet.\n");
1282 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001283 }
1284
1285 if (locked) mServiceLock.unlock();
1286
Igor Murashkinff3e31d2013-10-23 16:40:06 -07001287 // Dump camera traces if there were any
1288 write(fd, "\n", 1);
1289 camera3::CameraTraces::dump(fd, args);
1290
Mathias Agopian65ab4712010-07-14 17:59:35 -07001291 // change logging level
1292 int n = args.size();
1293 for (int i = 0; i + 1 < n; i++) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -07001294 String16 verboseOption("-v");
1295 if (args[i] == verboseOption) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001296 String8 levelStr(args[i+1]);
1297 int level = atoi(levelStr.string());
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001298 result = String8::format("\nSetting log level to %d.\n", level);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001299 setLogLevel(level);
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001300 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001301 }
1302 }
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001303
Mathias Agopian65ab4712010-07-14 17:59:35 -07001304 }
1305 return NO_ERROR;
1306}
1307
Igor Murashkinecf17e82012-10-02 16:05:11 -07001308/*virtual*/void CameraService::binderDied(
1309 const wp<IBinder> &who) {
1310
Igor Murashkin294d0ec2012-10-05 10:44:57 -07001311 /**
1312 * While tempting to promote the wp<IBinder> into a sp,
1313 * it's actually not supported by the binder driver
1314 */
1315
Igor Murashkinecf17e82012-10-02 16:05:11 -07001316 ALOGV("java clients' binder died");
1317
Igor Murashkin634a5152013-02-20 17:15:11 -08001318 sp<BasicClient> cameraClient = getClientByRemote(who);
Igor Murashkinecf17e82012-10-02 16:05:11 -07001319
Igor Murashkin294d0ec2012-10-05 10:44:57 -07001320 if (cameraClient == 0) {
Igor Murashkinecf17e82012-10-02 16:05:11 -07001321 ALOGV("java clients' binder death already cleaned up (normal case)");
1322 return;
1323 }
1324
Igor Murashkinecf17e82012-10-02 16:05:11 -07001325 ALOGW("Disconnecting camera client %p since the binder for it "
1326 "died (this pid %d)", cameraClient.get(), getCallingPid());
1327
1328 cameraClient->disconnect();
1329
1330}
1331
Igor Murashkinbfc99152013-02-27 12:55:20 -08001332void CameraService::updateStatus(ICameraServiceListener::Status status,
Igor Murashkin93747b92013-05-01 15:42:20 -07001333 int32_t cameraId,
1334 const StatusVector *rejectSourceStates) {
Igor Murashkinbfc99152013-02-27 12:55:20 -08001335 // do not lock mServiceLock here or can get into a deadlock from
1336 // connect() -> ProClient::disconnect -> updateStatus
1337 Mutex::Autolock lock(mStatusMutex);
Igor Murashkinbfc99152013-02-27 12:55:20 -08001338
1339 ICameraServiceListener::Status oldStatus = mStatusList[cameraId];
1340
1341 mStatusList[cameraId] = status;
1342
1343 if (oldStatus != status) {
1344 ALOGV("%s: Status has changed for camera ID %d from 0x%x to 0x%x",
1345 __FUNCTION__, cameraId, (uint32_t)oldStatus, (uint32_t)status);
1346
Igor Murashkincba2c162013-03-20 15:56:31 -07001347 if (oldStatus == ICameraServiceListener::STATUS_NOT_PRESENT &&
1348 (status != ICameraServiceListener::STATUS_PRESENT &&
1349 status != ICameraServiceListener::STATUS_ENUMERATING)) {
1350
1351 ALOGW("%s: From NOT_PRESENT can only transition into PRESENT"
1352 " or ENUMERATING", __FUNCTION__);
1353 mStatusList[cameraId] = oldStatus;
1354 return;
1355 }
1356
Igor Murashkin93747b92013-05-01 15:42:20 -07001357 if (rejectSourceStates != NULL) {
1358 const StatusVector &rejectList = *rejectSourceStates;
1359 StatusVector::const_iterator it = rejectList.begin();
1360
1361 /**
1362 * Sometimes we want to conditionally do a transition.
1363 * For example if a client disconnects, we want to go to PRESENT
1364 * only if we weren't already in NOT_PRESENT or ENUMERATING.
1365 */
1366 for (; it != rejectList.end(); ++it) {
1367 if (oldStatus == *it) {
1368 ALOGV("%s: Rejecting status transition for Camera ID %d, "
1369 " since the source state was was in one of the bad "
1370 " states.", __FUNCTION__, cameraId);
1371 mStatusList[cameraId] = oldStatus;
1372 return;
1373 }
1374 }
1375 }
1376
Igor Murashkinbfc99152013-02-27 12:55:20 -08001377 /**
1378 * ProClients lose their exclusive lock.
1379 * - Done before the CameraClient can initialize the HAL device,
1380 * since we want to be able to close it before they get to initialize
1381 */
1382 if (status == ICameraServiceListener::STATUS_NOT_AVAILABLE) {
1383 Vector<wp<ProClient> > proClients(mProClientList[cameraId]);
1384 Vector<wp<ProClient> >::const_iterator it;
1385
1386 for (it = proClients.begin(); it != proClients.end(); ++it) {
1387 sp<ProClient> proCl = it->promote();
1388 if (proCl.get() != NULL) {
1389 proCl->onExclusiveLockStolen();
1390 }
1391 }
1392 }
1393
1394 Vector<sp<ICameraServiceListener> >::const_iterator it;
1395 for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
1396 (*it)->onStatusChanged(status, cameraId);
1397 }
1398 }
1399}
1400
Igor Murashkincba2c162013-03-20 15:56:31 -07001401ICameraServiceListener::Status CameraService::getStatus(int cameraId) const {
1402 if (cameraId < 0 || cameraId >= MAX_CAMERAS) {
1403 ALOGE("%s: Invalid camera ID %d", __FUNCTION__, cameraId);
1404 return ICameraServiceListener::STATUS_UNKNOWN;
1405 }
1406
1407 Mutex::Autolock al(mStatusMutex);
1408 return mStatusList[cameraId];
1409}
1410
Mathias Agopian65ab4712010-07-14 17:59:35 -07001411}; // namespace android