1 /*
2 **
3 ** Copyright (C) 2008, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 ** http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17
18 #define LOG_TAG "CameraService"
19 //#define LOG_NDEBUG 0
20
21 #include <stdio.h>
22 #include <sys/types.h>
23 #include <pthread.h>
24
25 #include <binder/AppOpsManager.h>
26 #include <binder/IPCThreadState.h>
27 #include <binder/IServiceManager.h>
28 #include <binder/MemoryBase.h>
29 #include <binder/MemoryHeapBase.h>
30 #include <cutils/atomic.h>
31 #include <cutils/properties.h>
32 #include <gui/Surface.h>
33 #include <hardware/hardware.h>
34 #include <media/AudioSystem.h>
35 #include <media/mediaplayer.h>
36 #include <utils/Errors.h>
37 #include <utils/Log.h>
38 #include <utils/String16.h>
39
40 #include "CameraService.h"
41 #include "api1/CameraClient.h"
42 #include "api1/Camera2Client.h"
43 #include "api_pro/ProCamera2Client.h"
44 #include "api2/CameraDeviceClient.h"
45 #include "utils/CameraTraces.h"
46 #include "CameraDeviceFactory.h"
47
48 namespace android {
49
50 // ----------------------------------------------------------------------------
51 // Logging support -- this is for debugging only
52 // Use "adb shell dumpsys media.camera -v 1" to change it.
53 volatile int32_t gLogLevel = 0;
54
55 #define LOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__);
56 #define LOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__);
57
setLogLevel(int level)58 static void setLogLevel(int level) {
59 android_atomic_write(level, &gLogLevel);
60 }
61
62 // ----------------------------------------------------------------------------
63
getCallingPid()64 static int getCallingPid() {
65 return IPCThreadState::self()->getCallingPid();
66 }
67
getCallingUid()68 static int getCallingUid() {
69 return IPCThreadState::self()->getCallingUid();
70 }
71
72 extern "C" {
camera_device_status_change(const struct camera_module_callbacks * callbacks,int camera_id,int new_status)73 static void camera_device_status_change(
74 const struct camera_module_callbacks* callbacks,
75 int camera_id,
76 int new_status) {
77 sp<CameraService> cs = const_cast<CameraService*>(
78 static_cast<const CameraService*>(callbacks));
79
80 cs->onDeviceStatusChanged(
81 camera_id,
82 new_status);
83 }
84 } // extern "C"
85
86 // ----------------------------------------------------------------------------
87
88 // This is ugly and only safe if we never re-create the CameraService, but
89 // should be ok for now.
90 static CameraService *gCameraService;
91
CameraService()92 CameraService::CameraService()
93 :mSoundRef(0), mModule(0)
94 {
95 ALOGI("CameraService started (pid=%d)", getpid());
96 gCameraService = this;
97
98 for (size_t i = 0; i < MAX_CAMERAS; ++i) {
99 mStatusList[i] = ICameraServiceListener::STATUS_PRESENT;
100 }
101
102 this->camera_device_status_change = android::camera_device_status_change;
103 }
104
onFirstRef()105 void CameraService::onFirstRef()
106 {
107 LOG1("CameraService::onFirstRef");
108
109 BnCameraService::onFirstRef();
110
111 if (hw_get_module(CAMERA_HARDWARE_MODULE_ID,
112 (const hw_module_t **)&mModule) < 0) {
113 ALOGE("Could not load camera HAL module");
114 mNumberOfCameras = 0;
115 }
116 else {
117 ALOGI("Loaded \"%s\" camera module", mModule->common.name);
118 mNumberOfCameras = mModule->get_number_of_cameras();
119 if (mNumberOfCameras > MAX_CAMERAS) {
120 ALOGE("Number of cameras(%d) > MAX_CAMERAS(%d).",
121 mNumberOfCameras, MAX_CAMERAS);
122 mNumberOfCameras = MAX_CAMERAS;
123 }
124 for (int i = 0; i < mNumberOfCameras; i++) {
125 setCameraFree(i);
126 }
127
128 if (mModule->common.module_api_version >=
129 CAMERA_MODULE_API_VERSION_2_1) {
130 mModule->set_callbacks(this);
131 }
132
133 CameraDeviceFactory::registerService(this);
134 }
135 }
136
~CameraService()137 CameraService::~CameraService() {
138 for (int i = 0; i < mNumberOfCameras; i++) {
139 if (mBusy[i]) {
140 ALOGE("camera %d is still in use in destructor!", i);
141 }
142 }
143
144 gCameraService = NULL;
145 }
146
onDeviceStatusChanged(int cameraId,int newStatus)147 void CameraService::onDeviceStatusChanged(int cameraId,
148 int newStatus)
149 {
150 ALOGI("%s: Status changed for cameraId=%d, newStatus=%d", __FUNCTION__,
151 cameraId, newStatus);
152
153 if (cameraId < 0 || cameraId >= MAX_CAMERAS) {
154 ALOGE("%s: Bad camera ID %d", __FUNCTION__, cameraId);
155 return;
156 }
157
158 if ((int)getStatus(cameraId) == newStatus) {
159 ALOGE("%s: State transition to the same status 0x%x not allowed",
160 __FUNCTION__, (uint32_t)newStatus);
161 return;
162 }
163
164 /* don't do this in updateStatus
165 since it is also called from connect and we could get into a deadlock */
166 if (newStatus == CAMERA_DEVICE_STATUS_NOT_PRESENT) {
167 Vector<sp<BasicClient> > clientsToDisconnect;
168 {
169 Mutex::Autolock al(mServiceLock);
170
171 /* Find all clients that we need to disconnect */
172 sp<BasicClient> client = mClient[cameraId].promote();
173 if (client.get() != NULL) {
174 clientsToDisconnect.push_back(client);
175 }
176
177 int i = cameraId;
178 for (size_t j = 0; j < mProClientList[i].size(); ++j) {
179 sp<ProClient> cl = mProClientList[i][j].promote();
180 if (cl != NULL) {
181 clientsToDisconnect.push_back(cl);
182 }
183 }
184 }
185
186 /* now disconnect them. don't hold the lock
187 or we can get into a deadlock */
188
189 for (size_t i = 0; i < clientsToDisconnect.size(); ++i) {
190 sp<BasicClient> client = clientsToDisconnect[i];
191
192 client->disconnect();
193 /**
194 * The remote app will no longer be able to call methods on the
195 * client since the client PID will be reset to 0
196 */
197 }
198
199 ALOGV("%s: After unplug, disconnected %d clients",
200 __FUNCTION__, clientsToDisconnect.size());
201 }
202
203 updateStatus(
204 static_cast<ICameraServiceListener::Status>(newStatus), cameraId);
205
206 }
207
getNumberOfCameras()208 int32_t CameraService::getNumberOfCameras() {
209 return mNumberOfCameras;
210 }
211
getCameraInfo(int cameraId,struct CameraInfo * cameraInfo)212 status_t CameraService::getCameraInfo(int cameraId,
213 struct CameraInfo* cameraInfo) {
214 if (!mModule) {
215 return -ENODEV;
216 }
217
218 if (cameraId < 0 || cameraId >= mNumberOfCameras) {
219 return BAD_VALUE;
220 }
221
222 struct camera_info info;
223 status_t rc = mModule->get_camera_info(cameraId, &info);
224 cameraInfo->facing = info.facing;
225 cameraInfo->orientation = info.orientation;
226 return rc;
227 }
228
getCameraCharacteristics(int cameraId,CameraMetadata * cameraInfo)229 status_t CameraService::getCameraCharacteristics(int cameraId,
230 CameraMetadata* cameraInfo) {
231 if (!cameraInfo) {
232 ALOGE("%s: cameraInfo is NULL", __FUNCTION__);
233 return BAD_VALUE;
234 }
235
236 if (!mModule) {
237 ALOGE("%s: camera hardware module doesn't exist", __FUNCTION__);
238 return -ENODEV;
239 }
240
241 if (mModule->common.module_api_version < CAMERA_MODULE_API_VERSION_2_0) {
242 // TODO: Remove this check once HAL1 shim is in place.
243 ALOGE("%s: Only HAL module version V2 or higher supports static metadata", __FUNCTION__);
244 return BAD_VALUE;
245 }
246
247 if (cameraId < 0 || cameraId >= mNumberOfCameras) {
248 ALOGE("%s: Invalid camera id: %d", __FUNCTION__, cameraId);
249 return BAD_VALUE;
250 }
251
252 int facing;
253 if (getDeviceVersion(cameraId, &facing) == CAMERA_DEVICE_API_VERSION_1_0) {
254 // TODO: Remove this check once HAL1 shim is in place.
255 ALOGE("%s: HAL1 doesn't support static metadata yet", __FUNCTION__);
256 return BAD_VALUE;
257 }
258
259 if (getDeviceVersion(cameraId, &facing) <= CAMERA_DEVICE_API_VERSION_2_1) {
260 // Disable HAL2.x support for camera2 API for now.
261 ALOGW("%s: HAL2.x doesn't support getCameraCharacteristics for now", __FUNCTION__);
262 return BAD_VALUE;
263 }
264
265 struct camera_info info;
266 status_t ret = mModule->get_camera_info(cameraId, &info);
267 *cameraInfo = info.static_camera_characteristics;
268
269 return ret;
270 }
271
getDeviceVersion(int cameraId,int * facing)272 int CameraService::getDeviceVersion(int cameraId, int* facing) {
273 struct camera_info info;
274 if (mModule->get_camera_info(cameraId, &info) != OK) {
275 return -1;
276 }
277
278 int deviceVersion;
279 if (mModule->common.module_api_version >= CAMERA_MODULE_API_VERSION_2_0) {
280 deviceVersion = info.device_version;
281 } else {
282 deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
283 }
284
285 if (facing) {
286 *facing = info.facing;
287 }
288
289 return deviceVersion;
290 }
291
isValidCameraId(int cameraId)292 bool CameraService::isValidCameraId(int cameraId) {
293 int facing;
294 int deviceVersion = getDeviceVersion(cameraId, &facing);
295
296 switch(deviceVersion) {
297 case CAMERA_DEVICE_API_VERSION_1_0:
298 case CAMERA_DEVICE_API_VERSION_2_0:
299 case CAMERA_DEVICE_API_VERSION_2_1:
300 case CAMERA_DEVICE_API_VERSION_3_0:
301 return true;
302 default:
303 return false;
304 }
305
306 return false;
307 }
308
validateConnect(int cameraId,int & clientUid) const309 status_t CameraService::validateConnect(int cameraId,
310 /*inout*/
311 int& clientUid) const {
312
313 int callingPid = getCallingPid();
314
315 if (clientUid == USE_CALLING_UID) {
316 clientUid = getCallingUid();
317 } else {
318 // We only trust our own process to forward client UIDs
319 if (callingPid != getpid()) {
320 ALOGE("CameraService::connect X (pid %d) rejected (don't trust clientUid)",
321 callingPid);
322 return PERMISSION_DENIED;
323 }
324 }
325
326 if (!mModule) {
327 ALOGE("Camera HAL module not loaded");
328 return -ENODEV;
329 }
330
331 if (cameraId < 0 || cameraId >= mNumberOfCameras) {
332 ALOGE("CameraService::connect X (pid %d) rejected (invalid cameraId %d).",
333 callingPid, cameraId);
334 return -ENODEV;
335 }
336
337 char value[PROPERTY_VALUE_MAX];
338 property_get("sys.secpolicy.camera.disabled", value, "0");
339 if (strcmp(value, "1") == 0) {
340 // Camera is disabled by DevicePolicyManager.
341 ALOGI("Camera is disabled. connect X (pid %d) rejected", callingPid);
342 return -EACCES;
343 }
344
345 ICameraServiceListener::Status currentStatus = getStatus(cameraId);
346 if (currentStatus == ICameraServiceListener::STATUS_NOT_PRESENT) {
347 ALOGI("Camera is not plugged in,"
348 " connect X (pid %d) rejected", callingPid);
349 return -ENODEV;
350 } else if (currentStatus == ICameraServiceListener::STATUS_ENUMERATING) {
351 ALOGI("Camera is enumerating,"
352 " connect X (pid %d) rejected", callingPid);
353 return -EBUSY;
354 }
355 // Else don't check for STATUS_NOT_AVAILABLE.
356 // -- It's done implicitly in canConnectUnsafe /w the mBusy array
357
358 return OK;
359 }
360
canConnectUnsafe(int cameraId,const String16 & clientPackageName,const sp<IBinder> & remoteCallback,sp<BasicClient> & client)361 bool CameraService::canConnectUnsafe(int cameraId,
362 const String16& clientPackageName,
363 const sp<IBinder>& remoteCallback,
364 sp<BasicClient> &client) {
365 String8 clientName8(clientPackageName);
366 int callingPid = getCallingPid();
367
368 if (mClient[cameraId] != 0) {
369 client = mClient[cameraId].promote();
370 if (client != 0) {
371 if (remoteCallback == client->getRemote()) {
372 LOG1("CameraService::connect X (pid %d) (the same client)",
373 callingPid);
374 return true;
375 } else {
376 // TODOSC: need to support 1 regular client,
377 // multiple shared clients here
378 ALOGW("CameraService::connect X (pid %d) rejected"
379 " (existing client).", callingPid);
380 return false;
381 }
382 }
383 mClient[cameraId].clear();
384 }
385
386 /*
387 mBusy is set to false as the last step of the Client destructor,
388 after which it is guaranteed that the Client destructor has finished (
389 including any inherited destructors)
390
391 We only need this for a Client subclasses since we don't allow
392 multiple Clents to be opened concurrently, but multiple BasicClient
393 would be fine
394 */
395 if (mBusy[cameraId]) {
396 ALOGW("CameraService::connect X (pid %d, \"%s\") rejected"
397 " (camera %d is still busy).", callingPid,
398 clientName8.string(), cameraId);
399 return false;
400 }
401
402 return true;
403 }
404
connect(const sp<ICameraClient> & cameraClient,int cameraId,const String16 & clientPackageName,int clientUid,sp<ICamera> & device)405 status_t CameraService::connect(
406 const sp<ICameraClient>& cameraClient,
407 int cameraId,
408 const String16& clientPackageName,
409 int clientUid,
410 /*out*/
411 sp<ICamera>& device) {
412
413 String8 clientName8(clientPackageName);
414 int callingPid = getCallingPid();
415
416 LOG1("CameraService::connect E (pid %d \"%s\", id %d)", callingPid,
417 clientName8.string(), cameraId);
418
419 status_t status = validateConnect(cameraId, /*inout*/clientUid);
420 if (status != OK) {
421 return status;
422 }
423
424
425 sp<Client> client;
426 {
427 Mutex::Autolock lock(mServiceLock);
428 sp<BasicClient> clientTmp;
429 if (!canConnectUnsafe(cameraId, clientPackageName,
430 cameraClient->asBinder(),
431 /*out*/clientTmp)) {
432 return -EBUSY;
433 } else if (client.get() != NULL) {
434 device = static_cast<Client*>(clientTmp.get());
435 return OK;
436 }
437
438 int facing = -1;
439 int deviceVersion = getDeviceVersion(cameraId, &facing);
440
441 // If there are other non-exclusive users of the camera,
442 // this will tear them down before we can reuse the camera
443 if (isValidCameraId(cameraId)) {
444 // transition from PRESENT -> NOT_AVAILABLE
445 updateStatus(ICameraServiceListener::STATUS_NOT_AVAILABLE,
446 cameraId);
447 }
448
449 switch(deviceVersion) {
450 case CAMERA_DEVICE_API_VERSION_1_0:
451 client = new CameraClient(this, cameraClient,
452 clientPackageName, cameraId,
453 facing, callingPid, clientUid, getpid());
454 break;
455 case CAMERA_DEVICE_API_VERSION_2_0:
456 case CAMERA_DEVICE_API_VERSION_2_1:
457 case CAMERA_DEVICE_API_VERSION_3_0:
458 client = new Camera2Client(this, cameraClient,
459 clientPackageName, cameraId,
460 facing, callingPid, clientUid, getpid(),
461 deviceVersion);
462 break;
463 case -1:
464 ALOGE("Invalid camera id %d", cameraId);
465 return BAD_VALUE;
466 default:
467 ALOGE("Unknown camera device HAL version: %d", deviceVersion);
468 return INVALID_OPERATION;
469 }
470
471 status_t status = connectFinishUnsafe(client, client->getRemote());
472 if (status != OK) {
473 // this is probably not recoverable.. maybe the client can try again
474 // OK: we can only get here if we were originally in PRESENT state
475 updateStatus(ICameraServiceListener::STATUS_PRESENT, cameraId);
476 return status;
477 }
478
479 mClient[cameraId] = client;
480 LOG1("CameraService::connect X (id %d, this pid is %d)", cameraId,
481 getpid());
482 }
483 // important: release the mutex here so the client can call back
484 // into the service from its destructor (can be at the end of the call)
485
486 device = client;
487 return OK;
488 }
489
connectFinishUnsafe(const sp<BasicClient> & client,const sp<IBinder> & remoteCallback)490 status_t CameraService::connectFinishUnsafe(const sp<BasicClient>& client,
491 const sp<IBinder>& remoteCallback) {
492 status_t status = client->initialize(mModule);
493 if (status != OK) {
494 return status;
495 }
496
497 remoteCallback->linkToDeath(this);
498
499 return OK;
500 }
501
connectPro(const sp<IProCameraCallbacks> & cameraCb,int cameraId,const String16 & clientPackageName,int clientUid,sp<IProCameraUser> & device)502 status_t CameraService::connectPro(
503 const sp<IProCameraCallbacks>& cameraCb,
504 int cameraId,
505 const String16& clientPackageName,
506 int clientUid,
507 /*out*/
508 sp<IProCameraUser>& device)
509 {
510 String8 clientName8(clientPackageName);
511 int callingPid = getCallingPid();
512
513 LOG1("CameraService::connectPro E (pid %d \"%s\", id %d)", callingPid,
514 clientName8.string(), cameraId);
515 status_t status = validateConnect(cameraId, /*inout*/clientUid);
516 if (status != OK) {
517 return status;
518 }
519
520 sp<ProClient> client;
521 {
522 Mutex::Autolock lock(mServiceLock);
523 {
524 sp<BasicClient> client;
525 if (!canConnectUnsafe(cameraId, clientPackageName,
526 cameraCb->asBinder(),
527 /*out*/client)) {
528 return -EBUSY;
529 }
530 }
531
532 int facing = -1;
533 int deviceVersion = getDeviceVersion(cameraId, &facing);
534
535 switch(deviceVersion) {
536 case CAMERA_DEVICE_API_VERSION_1_0:
537 ALOGE("Camera id %d uses HALv1, doesn't support ProCamera",
538 cameraId);
539 return -EOPNOTSUPP;
540 break;
541 case CAMERA_DEVICE_API_VERSION_2_0:
542 case CAMERA_DEVICE_API_VERSION_2_1:
543 case CAMERA_DEVICE_API_VERSION_3_0:
544 client = new ProCamera2Client(this, cameraCb, String16(),
545 cameraId, facing, callingPid, USE_CALLING_UID, getpid());
546 break;
547 case -1:
548 ALOGE("Invalid camera id %d", cameraId);
549 return BAD_VALUE;
550 default:
551 ALOGE("Unknown camera device HAL version: %d", deviceVersion);
552 return INVALID_OPERATION;
553 }
554
555 status_t status = connectFinishUnsafe(client, client->getRemote());
556 if (status != OK) {
557 return status;
558 }
559
560 mProClientList[cameraId].push(client);
561
562 LOG1("CameraService::connectPro X (id %d, this pid is %d)", cameraId,
563 getpid());
564 }
565 // important: release the mutex here so the client can call back
566 // into the service from its destructor (can be at the end of the call)
567 device = client;
568 return OK;
569 }
570
connectDevice(const sp<ICameraDeviceCallbacks> & cameraCb,int cameraId,const String16 & clientPackageName,int clientUid,sp<ICameraDeviceUser> & device)571 status_t CameraService::connectDevice(
572 const sp<ICameraDeviceCallbacks>& cameraCb,
573 int cameraId,
574 const String16& clientPackageName,
575 int clientUid,
576 /*out*/
577 sp<ICameraDeviceUser>& device)
578 {
579
580 String8 clientName8(clientPackageName);
581 int callingPid = getCallingPid();
582
583 LOG1("CameraService::connectDevice E (pid %d \"%s\", id %d)", callingPid,
584 clientName8.string(), cameraId);
585
586 status_t status = validateConnect(cameraId, /*inout*/clientUid);
587 if (status != OK) {
588 return status;
589 }
590
591 sp<CameraDeviceClient> client;
592 {
593 Mutex::Autolock lock(mServiceLock);
594 {
595 sp<BasicClient> client;
596 if (!canConnectUnsafe(cameraId, clientPackageName,
597 cameraCb->asBinder(),
598 /*out*/client)) {
599 return -EBUSY;
600 }
601 }
602
603 int facing = -1;
604 int deviceVersion = getDeviceVersion(cameraId, &facing);
605
606 // If there are other non-exclusive users of the camera,
607 // this will tear them down before we can reuse the camera
608 if (isValidCameraId(cameraId)) {
609 // transition from PRESENT -> NOT_AVAILABLE
610 updateStatus(ICameraServiceListener::STATUS_NOT_AVAILABLE,
611 cameraId);
612 }
613
614 switch(deviceVersion) {
615 case CAMERA_DEVICE_API_VERSION_1_0:
616 ALOGW("Camera using old HAL version: %d", deviceVersion);
617 return -EOPNOTSUPP;
618 // TODO: don't allow 2.0 Only allow 2.1 and higher
619 case CAMERA_DEVICE_API_VERSION_2_0:
620 case CAMERA_DEVICE_API_VERSION_2_1:
621 case CAMERA_DEVICE_API_VERSION_3_0:
622 client = new CameraDeviceClient(this, cameraCb, String16(),
623 cameraId, facing, callingPid, USE_CALLING_UID, getpid());
624 break;
625 case -1:
626 ALOGE("Invalid camera id %d", cameraId);
627 return BAD_VALUE;
628 default:
629 ALOGE("Unknown camera device HAL version: %d", deviceVersion);
630 return INVALID_OPERATION;
631 }
632
633 status_t status = connectFinishUnsafe(client, client->getRemote());
634 if (status != OK) {
635 // this is probably not recoverable.. maybe the client can try again
636 // OK: we can only get here if we were originally in PRESENT state
637 updateStatus(ICameraServiceListener::STATUS_PRESENT, cameraId);
638 return status;
639 }
640
641 LOG1("CameraService::connectDevice X (id %d, this pid is %d)", cameraId,
642 getpid());
643
644 mClient[cameraId] = client;
645 }
646 // important: release the mutex here so the client can call back
647 // into the service from its destructor (can be at the end of the call)
648
649 device = client;
650 return OK;
651 }
652
653
addListener(const sp<ICameraServiceListener> & listener)654 status_t CameraService::addListener(
655 const sp<ICameraServiceListener>& listener) {
656 ALOGV("%s: Add listener %p", __FUNCTION__, listener.get());
657
658 if (listener == 0) {
659 ALOGE("%s: Listener must not be null", __FUNCTION__);
660 return BAD_VALUE;
661 }
662
663 Mutex::Autolock lock(mServiceLock);
664
665 Vector<sp<ICameraServiceListener> >::iterator it, end;
666 for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
667 if ((*it)->asBinder() == listener->asBinder()) {
668 ALOGW("%s: Tried to add listener %p which was already subscribed",
669 __FUNCTION__, listener.get());
670 return ALREADY_EXISTS;
671 }
672 }
673
674 mListenerList.push_back(listener);
675
676 /* Immediately signal current status to this listener only */
677 {
678 Mutex::Autolock m(mStatusMutex) ;
679 int numCams = getNumberOfCameras();
680 for (int i = 0; i < numCams; ++i) {
681 listener->onStatusChanged(mStatusList[i], i);
682 }
683 }
684
685 return OK;
686 }
removeListener(const sp<ICameraServiceListener> & listener)687 status_t CameraService::removeListener(
688 const sp<ICameraServiceListener>& listener) {
689 ALOGV("%s: Remove listener %p", __FUNCTION__, listener.get());
690
691 if (listener == 0) {
692 ALOGE("%s: Listener must not be null", __FUNCTION__);
693 return BAD_VALUE;
694 }
695
696 Mutex::Autolock lock(mServiceLock);
697
698 Vector<sp<ICameraServiceListener> >::iterator it;
699 for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
700 if ((*it)->asBinder() == listener->asBinder()) {
701 mListenerList.erase(it);
702 return OK;
703 }
704 }
705
706 ALOGW("%s: Tried to remove a listener %p which was not subscribed",
707 __FUNCTION__, listener.get());
708
709 return BAD_VALUE;
710 }
711
removeClientByRemote(const wp<IBinder> & remoteBinder)712 void CameraService::removeClientByRemote(const wp<IBinder>& remoteBinder) {
713 int callingPid = getCallingPid();
714 LOG1("CameraService::removeClientByRemote E (pid %d)", callingPid);
715
716 // Declare this before the lock to make absolutely sure the
717 // destructor won't be called with the lock held.
718 Mutex::Autolock lock(mServiceLock);
719
720 int outIndex;
721 sp<BasicClient> client = findClientUnsafe(remoteBinder, outIndex);
722
723 if (client != 0) {
724 // Found our camera, clear and leave.
725 LOG1("removeClient: clear camera %d", outIndex);
726 mClient[outIndex].clear();
727
728 client->getRemote()->unlinkToDeath(this);
729 } else {
730
731 sp<ProClient> clientPro = findProClientUnsafe(remoteBinder);
732
733 if (clientPro != NULL) {
734 // Found our camera, clear and leave.
735 LOG1("removeClient: clear pro %p", clientPro.get());
736
737 clientPro->getRemoteCallback()->asBinder()->unlinkToDeath(this);
738 }
739 }
740
741 LOG1("CameraService::removeClientByRemote X (pid %d)", callingPid);
742 }
743
findProClientUnsafe(const wp<IBinder> & cameraCallbacksRemote)744 sp<CameraService::ProClient> CameraService::findProClientUnsafe(
745 const wp<IBinder>& cameraCallbacksRemote)
746 {
747 sp<ProClient> clientPro;
748
749 for (int i = 0; i < mNumberOfCameras; ++i) {
750 Vector<size_t> removeIdx;
751
752 for (size_t j = 0; j < mProClientList[i].size(); ++j) {
753 wp<ProClient> cl = mProClientList[i][j];
754
755 sp<ProClient> clStrong = cl.promote();
756 if (clStrong != NULL && clStrong->getRemote() == cameraCallbacksRemote) {
757 clientPro = clStrong;
758 break;
759 } else if (clStrong == NULL) {
760 // mark to clean up dead ptr
761 removeIdx.push(j);
762 }
763 }
764
765 // remove stale ptrs (in reverse so the indices dont change)
766 for (ssize_t j = (ssize_t)removeIdx.size() - 1; j >= 0; --j) {
767 mProClientList[i].removeAt(removeIdx[j]);
768 }
769
770 }
771
772 return clientPro;
773 }
774
findClientUnsafe(const wp<IBinder> & cameraClient,int & outIndex)775 sp<CameraService::BasicClient> CameraService::findClientUnsafe(
776 const wp<IBinder>& cameraClient, int& outIndex) {
777 sp<BasicClient> client;
778
779 for (int i = 0; i < mNumberOfCameras; i++) {
780
781 // This happens when we have already disconnected (or this is
782 // just another unused camera).
783 if (mClient[i] == 0) continue;
784
785 // Promote mClient. It can fail if we are called from this path:
786 // Client::~Client() -> disconnect() -> removeClientByRemote().
787 client = mClient[i].promote();
788
789 // Clean up stale client entry
790 if (client == NULL) {
791 mClient[i].clear();
792 continue;
793 }
794
795 if (cameraClient == client->getRemote()) {
796 // Found our camera
797 outIndex = i;
798 return client;
799 }
800 }
801
802 outIndex = -1;
803 return NULL;
804 }
805
getClientByIdUnsafe(int cameraId)806 CameraService::BasicClient* CameraService::getClientByIdUnsafe(int cameraId) {
807 if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
808 return mClient[cameraId].unsafe_get();
809 }
810
getClientLockById(int cameraId)811 Mutex* CameraService::getClientLockById(int cameraId) {
812 if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
813 return &mClientLock[cameraId];
814 }
815
getClientByRemote(const wp<IBinder> & cameraClient)816 sp<CameraService::BasicClient> CameraService::getClientByRemote(
817 const wp<IBinder>& cameraClient) {
818
819 // Declare this before the lock to make absolutely sure the
820 // destructor won't be called with the lock held.
821 sp<BasicClient> client;
822
823 Mutex::Autolock lock(mServiceLock);
824
825 int outIndex;
826 client = findClientUnsafe(cameraClient, outIndex);
827
828 return client;
829 }
830
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)831 status_t CameraService::onTransact(
832 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
833 // Permission checks
834 switch (code) {
835 case BnCameraService::CONNECT:
836 case BnCameraService::CONNECT_PRO:
837 const int pid = getCallingPid();
838 const int self_pid = getpid();
839 if (pid != self_pid) {
840 // we're called from a different process, do the real check
841 if (!checkCallingPermission(
842 String16("android.permission.CAMERA"))) {
843 const int uid = getCallingUid();
844 ALOGE("Permission Denial: "
845 "can't use the camera pid=%d, uid=%d", pid, uid);
846 return PERMISSION_DENIED;
847 }
848 }
849 break;
850 }
851
852 return BnCameraService::onTransact(code, data, reply, flags);
853 }
854
855 // The reason we need this busy bit is a new CameraService::connect() request
856 // may come in while the previous Client's destructor has not been run or is
857 // still running. If the last strong reference of the previous Client is gone
858 // but the destructor has not been finished, we should not allow the new Client
859 // to be created because we need to wait for the previous Client to tear down
860 // the hardware first.
setCameraBusy(int cameraId)861 void CameraService::setCameraBusy(int cameraId) {
862 android_atomic_write(1, &mBusy[cameraId]);
863
864 ALOGV("setCameraBusy cameraId=%d", cameraId);
865 }
866
setCameraFree(int cameraId)867 void CameraService::setCameraFree(int cameraId) {
868 android_atomic_write(0, &mBusy[cameraId]);
869
870 ALOGV("setCameraFree cameraId=%d", cameraId);
871 }
872
873 // We share the media players for shutter and recording sound for all clients.
874 // A reference count is kept to determine when we will actually release the
875 // media players.
876
newMediaPlayer(const char * file)877 MediaPlayer* CameraService::newMediaPlayer(const char *file) {
878 MediaPlayer* mp = new MediaPlayer();
879 if (mp->setDataSource(file, NULL) == NO_ERROR) {
880 mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE);
881 mp->prepare();
882 } else {
883 ALOGE("Failed to load CameraService sounds: %s", file);
884 return NULL;
885 }
886 return mp;
887 }
888
loadSound()889 void CameraService::loadSound() {
890 Mutex::Autolock lock(mSoundLock);
891 LOG1("CameraService::loadSound ref=%d", mSoundRef);
892 if (mSoundRef++) return;
893
894 mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
895 mSoundPlayer[SOUND_RECORDING] = newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");
896 }
897
releaseSound()898 void CameraService::releaseSound() {
899 Mutex::Autolock lock(mSoundLock);
900 LOG1("CameraService::releaseSound ref=%d", mSoundRef);
901 if (--mSoundRef) return;
902
903 for (int i = 0; i < NUM_SOUNDS; i++) {
904 if (mSoundPlayer[i] != 0) {
905 mSoundPlayer[i]->disconnect();
906 mSoundPlayer[i].clear();
907 }
908 }
909 }
910
playSound(sound_kind kind)911 void CameraService::playSound(sound_kind kind) {
912 LOG1("playSound(%d)", kind);
913 Mutex::Autolock lock(mSoundLock);
914 sp<MediaPlayer> player = mSoundPlayer[kind];
915 if (player != 0) {
916 player->seekTo(0);
917 player->start();
918 }
919 }
920
921 // ----------------------------------------------------------------------------
922
Client(const sp<CameraService> & cameraService,const sp<ICameraClient> & cameraClient,const String16 & clientPackageName,int cameraId,int cameraFacing,int clientPid,uid_t clientUid,int servicePid)923 CameraService::Client::Client(const sp<CameraService>& cameraService,
924 const sp<ICameraClient>& cameraClient,
925 const String16& clientPackageName,
926 int cameraId, int cameraFacing,
927 int clientPid, uid_t clientUid,
928 int servicePid) :
929 CameraService::BasicClient(cameraService, cameraClient->asBinder(),
930 clientPackageName,
931 cameraId, cameraFacing,
932 clientPid, clientUid,
933 servicePid)
934 {
935 int callingPid = getCallingPid();
936 LOG1("Client::Client E (pid %d, id %d)", callingPid, cameraId);
937
938 mRemoteCallback = cameraClient;
939
940 cameraService->setCameraBusy(cameraId);
941 cameraService->loadSound();
942
943 LOG1("Client::Client X (pid %d, id %d)", callingPid, cameraId);
944 }
945
946 // tear down the client
~Client()947 CameraService::Client::~Client() {
948 ALOGV("~Client");
949 mDestructionStarted = true;
950
951 mCameraService->releaseSound();
952 // unconditionally disconnect. function is idempotent
953 Client::disconnect();
954 }
955
BasicClient(const sp<CameraService> & cameraService,const sp<IBinder> & remoteCallback,const String16 & clientPackageName,int cameraId,int cameraFacing,int clientPid,uid_t clientUid,int servicePid)956 CameraService::BasicClient::BasicClient(const sp<CameraService>& cameraService,
957 const sp<IBinder>& remoteCallback,
958 const String16& clientPackageName,
959 int cameraId, int cameraFacing,
960 int clientPid, uid_t clientUid,
961 int servicePid):
962 mClientPackageName(clientPackageName)
963 {
964 mCameraService = cameraService;
965 mRemoteBinder = remoteCallback;
966 mCameraId = cameraId;
967 mCameraFacing = cameraFacing;
968 mClientPid = clientPid;
969 mClientUid = clientUid;
970 mServicePid = servicePid;
971 mOpsActive = false;
972 mDestructionStarted = false;
973 }
974
~BasicClient()975 CameraService::BasicClient::~BasicClient() {
976 ALOGV("~BasicClient");
977 mDestructionStarted = true;
978 }
979
disconnect()980 void CameraService::BasicClient::disconnect() {
981 ALOGV("BasicClient::disconnect");
982 mCameraService->removeClientByRemote(mRemoteBinder);
983 // client shouldn't be able to call into us anymore
984 mClientPid = 0;
985 }
986
startCameraOps()987 status_t CameraService::BasicClient::startCameraOps() {
988 int32_t res;
989
990 mOpsCallback = new OpsCallback(this);
991
992 {
993 ALOGV("%s: Start camera ops, package name = %s, client UID = %d",
994 __FUNCTION__, String8(mClientPackageName).string(), mClientUid);
995 }
996
997 mAppOpsManager.startWatchingMode(AppOpsManager::OP_CAMERA,
998 mClientPackageName, mOpsCallback);
999 res = mAppOpsManager.startOp(AppOpsManager::OP_CAMERA,
1000 mClientUid, mClientPackageName);
1001
1002 if (res != AppOpsManager::MODE_ALLOWED) {
1003 ALOGI("Camera %d: Access for \"%s\" has been revoked",
1004 mCameraId, String8(mClientPackageName).string());
1005 return PERMISSION_DENIED;
1006 }
1007 mOpsActive = true;
1008 return OK;
1009 }
1010
finishCameraOps()1011 status_t CameraService::BasicClient::finishCameraOps() {
1012 if (mOpsActive) {
1013 mAppOpsManager.finishOp(AppOpsManager::OP_CAMERA, mClientUid,
1014 mClientPackageName);
1015 mOpsActive = false;
1016 }
1017 mAppOpsManager.stopWatchingMode(mOpsCallback);
1018 mOpsCallback.clear();
1019
1020 return OK;
1021 }
1022
opChanged(int32_t op,const String16 & packageName)1023 void CameraService::BasicClient::opChanged(int32_t op, const String16& packageName) {
1024 String8 name(packageName);
1025 String8 myName(mClientPackageName);
1026
1027 if (op != AppOpsManager::OP_CAMERA) {
1028 ALOGW("Unexpected app ops notification received: %d", op);
1029 return;
1030 }
1031
1032 int32_t res;
1033 res = mAppOpsManager.checkOp(AppOpsManager::OP_CAMERA,
1034 mClientUid, mClientPackageName);
1035 ALOGV("checkOp returns: %d, %s ", res,
1036 res == AppOpsManager::MODE_ALLOWED ? "ALLOWED" :
1037 res == AppOpsManager::MODE_IGNORED ? "IGNORED" :
1038 res == AppOpsManager::MODE_ERRORED ? "ERRORED" :
1039 "UNKNOWN");
1040
1041 if (res != AppOpsManager::MODE_ALLOWED) {
1042 ALOGI("Camera %d: Access for \"%s\" revoked", mCameraId,
1043 myName.string());
1044 // Reset the client PID to allow server-initiated disconnect,
1045 // and to prevent further calls by client.
1046 mClientPid = getCallingPid();
1047 notifyError();
1048 disconnect();
1049 }
1050 }
1051
1052 // ----------------------------------------------------------------------------
1053
getClientLockFromCookie(void * user)1054 Mutex* CameraService::Client::getClientLockFromCookie(void* user) {
1055 return gCameraService->getClientLockById((int) user);
1056 }
1057
1058 // Provide client pointer for callbacks. Client lock returned from getClientLockFromCookie should
1059 // be acquired for this to be safe
getClientFromCookie(void * user)1060 CameraService::Client* CameraService::Client::getClientFromCookie(void* user) {
1061 BasicClient *basicClient = gCameraService->getClientByIdUnsafe((int) user);
1062 // OK: only CameraClient calls this, and they already cast anyway.
1063 Client* client = static_cast<Client*>(basicClient);
1064
1065 // This could happen if the Client is in the process of shutting down (the
1066 // last strong reference is gone, but the destructor hasn't finished
1067 // stopping the hardware).
1068 if (client == NULL) return NULL;
1069
1070 // destruction already started, so should not be accessed
1071 if (client->mDestructionStarted) return NULL;
1072
1073 return client;
1074 }
1075
notifyError()1076 void CameraService::Client::notifyError() {
1077 mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_RELEASED, 0);
1078 }
1079
1080 // NOTE: function is idempotent
disconnect()1081 void CameraService::Client::disconnect() {
1082 ALOGV("Client::disconnect");
1083 BasicClient::disconnect();
1084 mCameraService->setCameraFree(mCameraId);
1085
1086 StatusVector rejectSourceStates;
1087 rejectSourceStates.push_back(ICameraServiceListener::STATUS_NOT_PRESENT);
1088 rejectSourceStates.push_back(ICameraServiceListener::STATUS_ENUMERATING);
1089
1090 // Transition to PRESENT if the camera is not in either of above 2 states
1091 mCameraService->updateStatus(ICameraServiceListener::STATUS_PRESENT,
1092 mCameraId,
1093 &rejectSourceStates);
1094 }
1095
OpsCallback(wp<BasicClient> client)1096 CameraService::Client::OpsCallback::OpsCallback(wp<BasicClient> client):
1097 mClient(client) {
1098 }
1099
opChanged(int32_t op,const String16 & packageName)1100 void CameraService::Client::OpsCallback::opChanged(int32_t op,
1101 const String16& packageName) {
1102 sp<BasicClient> client = mClient.promote();
1103 if (client != NULL) {
1104 client->opChanged(op, packageName);
1105 }
1106 }
1107
1108 // ----------------------------------------------------------------------------
1109 // IProCamera
1110 // ----------------------------------------------------------------------------
1111
ProClient(const sp<CameraService> & cameraService,const sp<IProCameraCallbacks> & remoteCallback,const String16 & clientPackageName,int cameraId,int cameraFacing,int clientPid,uid_t clientUid,int servicePid)1112 CameraService::ProClient::ProClient(const sp<CameraService>& cameraService,
1113 const sp<IProCameraCallbacks>& remoteCallback,
1114 const String16& clientPackageName,
1115 int cameraId,
1116 int cameraFacing,
1117 int clientPid,
1118 uid_t clientUid,
1119 int servicePid)
1120 : CameraService::BasicClient(cameraService, remoteCallback->asBinder(),
1121 clientPackageName, cameraId, cameraFacing,
1122 clientPid, clientUid, servicePid)
1123 {
1124 mRemoteCallback = remoteCallback;
1125 }
1126
~ProClient()1127 CameraService::ProClient::~ProClient() {
1128 }
1129
notifyError()1130 void CameraService::ProClient::notifyError() {
1131 mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_RELEASED, 0);
1132 }
1133
1134 // ----------------------------------------------------------------------------
1135
1136 static const int kDumpLockRetries = 50;
1137 static const int kDumpLockSleep = 60000;
1138
tryLock(Mutex & mutex)1139 static bool tryLock(Mutex& mutex)
1140 {
1141 bool locked = false;
1142 for (int i = 0; i < kDumpLockRetries; ++i) {
1143 if (mutex.tryLock() == NO_ERROR) {
1144 locked = true;
1145 break;
1146 }
1147 usleep(kDumpLockSleep);
1148 }
1149 return locked;
1150 }
1151
dump(int fd,const Vector<String16> & args)1152 status_t CameraService::dump(int fd, const Vector<String16>& args) {
1153 String8 result;
1154 if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
1155 result.appendFormat("Permission Denial: "
1156 "can't dump CameraService from pid=%d, uid=%d\n",
1157 getCallingPid(),
1158 getCallingUid());
1159 write(fd, result.string(), result.size());
1160 } else {
1161 bool locked = tryLock(mServiceLock);
1162 // failed to lock - CameraService is probably deadlocked
1163 if (!locked) {
1164 result.append("CameraService may be deadlocked\n");
1165 write(fd, result.string(), result.size());
1166 }
1167
1168 bool hasClient = false;
1169 if (!mModule) {
1170 result = String8::format("No camera module available!\n");
1171 write(fd, result.string(), result.size());
1172 return NO_ERROR;
1173 }
1174
1175 result = String8::format("Camera module HAL API version: 0x%x\n",
1176 mModule->common.hal_api_version);
1177 result.appendFormat("Camera module API version: 0x%x\n",
1178 mModule->common.module_api_version);
1179 result.appendFormat("Camera module name: %s\n",
1180 mModule->common.name);
1181 result.appendFormat("Camera module author: %s\n",
1182 mModule->common.author);
1183 result.appendFormat("Number of camera devices: %d\n\n", mNumberOfCameras);
1184 write(fd, result.string(), result.size());
1185 for (int i = 0; i < mNumberOfCameras; i++) {
1186 result = String8::format("Camera %d static information:\n", i);
1187 camera_info info;
1188
1189 status_t rc = mModule->get_camera_info(i, &info);
1190 if (rc != OK) {
1191 result.appendFormat(" Error reading static information!\n");
1192 write(fd, result.string(), result.size());
1193 } else {
1194 result.appendFormat(" Facing: %s\n",
1195 info.facing == CAMERA_FACING_BACK ? "BACK" : "FRONT");
1196 result.appendFormat(" Orientation: %d\n", info.orientation);
1197 int deviceVersion;
1198 if (mModule->common.module_api_version <
1199 CAMERA_MODULE_API_VERSION_2_0) {
1200 deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
1201 } else {
1202 deviceVersion = info.device_version;
1203 }
1204 result.appendFormat(" Device version: 0x%x\n", deviceVersion);
1205 if (deviceVersion >= CAMERA_DEVICE_API_VERSION_2_0) {
1206 result.appendFormat(" Device static metadata:\n");
1207 write(fd, result.string(), result.size());
1208 dump_indented_camera_metadata(info.static_camera_characteristics,
1209 fd, 2, 4);
1210 } else {
1211 write(fd, result.string(), result.size());
1212 }
1213 }
1214
1215 sp<BasicClient> client = mClient[i].promote();
1216 if (client == 0) {
1217 result = String8::format(" Device is closed, no client instance\n");
1218 write(fd, result.string(), result.size());
1219 continue;
1220 }
1221 hasClient = true;
1222 result = String8::format(" Device is open. Client instance dump:\n");
1223 write(fd, result.string(), result.size());
1224 client->dump(fd, args);
1225 }
1226 if (!hasClient) {
1227 result = String8::format("\nNo active camera clients yet.\n");
1228 write(fd, result.string(), result.size());
1229 }
1230
1231 if (locked) mServiceLock.unlock();
1232
1233 // Dump camera traces if there were any
1234 write(fd, "\n", 1);
1235 camera3::CameraTraces::dump(fd, args);
1236
1237 // change logging level
1238 int n = args.size();
1239 for (int i = 0; i + 1 < n; i++) {
1240 String16 verboseOption("-v");
1241 if (args[i] == verboseOption) {
1242 String8 levelStr(args[i+1]);
1243 int level = atoi(levelStr.string());
1244 result = String8::format("\nSetting log level to %d.\n", level);
1245 setLogLevel(level);
1246 write(fd, result.string(), result.size());
1247 }
1248 }
1249
1250 }
1251 return NO_ERROR;
1252 }
1253
binderDied(const wp<IBinder> & who)1254 /*virtual*/void CameraService::binderDied(
1255 const wp<IBinder> &who) {
1256
1257 /**
1258 * While tempting to promote the wp<IBinder> into a sp,
1259 * it's actually not supported by the binder driver
1260 */
1261
1262 ALOGV("java clients' binder died");
1263
1264 sp<BasicClient> cameraClient = getClientByRemote(who);
1265
1266 if (cameraClient == 0) {
1267 ALOGV("java clients' binder death already cleaned up (normal case)");
1268 return;
1269 }
1270
1271 ALOGW("Disconnecting camera client %p since the binder for it "
1272 "died (this pid %d)", cameraClient.get(), getCallingPid());
1273
1274 cameraClient->disconnect();
1275
1276 }
1277
updateStatus(ICameraServiceListener::Status status,int32_t cameraId,const StatusVector * rejectSourceStates)1278 void CameraService::updateStatus(ICameraServiceListener::Status status,
1279 int32_t cameraId,
1280 const StatusVector *rejectSourceStates) {
1281 // do not lock mServiceLock here or can get into a deadlock from
1282 // connect() -> ProClient::disconnect -> updateStatus
1283 Mutex::Autolock lock(mStatusMutex);
1284
1285 ICameraServiceListener::Status oldStatus = mStatusList[cameraId];
1286
1287 mStatusList[cameraId] = status;
1288
1289 if (oldStatus != status) {
1290 ALOGV("%s: Status has changed for camera ID %d from 0x%x to 0x%x",
1291 __FUNCTION__, cameraId, (uint32_t)oldStatus, (uint32_t)status);
1292
1293 if (oldStatus == ICameraServiceListener::STATUS_NOT_PRESENT &&
1294 (status != ICameraServiceListener::STATUS_PRESENT &&
1295 status != ICameraServiceListener::STATUS_ENUMERATING)) {
1296
1297 ALOGW("%s: From NOT_PRESENT can only transition into PRESENT"
1298 " or ENUMERATING", __FUNCTION__);
1299 mStatusList[cameraId] = oldStatus;
1300 return;
1301 }
1302
1303 if (rejectSourceStates != NULL) {
1304 const StatusVector &rejectList = *rejectSourceStates;
1305 StatusVector::const_iterator it = rejectList.begin();
1306
1307 /**
1308 * Sometimes we want to conditionally do a transition.
1309 * For example if a client disconnects, we want to go to PRESENT
1310 * only if we weren't already in NOT_PRESENT or ENUMERATING.
1311 */
1312 for (; it != rejectList.end(); ++it) {
1313 if (oldStatus == *it) {
1314 ALOGV("%s: Rejecting status transition for Camera ID %d, "
1315 " since the source state was was in one of the bad "
1316 " states.", __FUNCTION__, cameraId);
1317 mStatusList[cameraId] = oldStatus;
1318 return;
1319 }
1320 }
1321 }
1322
1323 /**
1324 * ProClients lose their exclusive lock.
1325 * - Done before the CameraClient can initialize the HAL device,
1326 * since we want to be able to close it before they get to initialize
1327 */
1328 if (status == ICameraServiceListener::STATUS_NOT_AVAILABLE) {
1329 Vector<wp<ProClient> > proClients(mProClientList[cameraId]);
1330 Vector<wp<ProClient> >::const_iterator it;
1331
1332 for (it = proClients.begin(); it != proClients.end(); ++it) {
1333 sp<ProClient> proCl = it->promote();
1334 if (proCl.get() != NULL) {
1335 proCl->onExclusiveLockStolen();
1336 }
1337 }
1338 }
1339
1340 Vector<sp<ICameraServiceListener> >::const_iterator it;
1341 for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
1342 (*it)->onStatusChanged(status, cameraId);
1343 }
1344 }
1345 }
1346
getStatus(int cameraId) const1347 ICameraServiceListener::Status CameraService::getStatus(int cameraId) const {
1348 if (cameraId < 0 || cameraId >= MAX_CAMERAS) {
1349 ALOGE("%s: Invalid camera ID %d", __FUNCTION__, cameraId);
1350 return ICameraServiceListener::STATUS_UNKNOWN;
1351 }
1352
1353 Mutex::Autolock al(mStatusMutex);
1354 return mStatusList[cameraId];
1355 }
1356
1357 }; // namespace android
1358