• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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