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