CameraService.cpp revision f2776a5692bb4228decbe4ea3c8cc6df1d9c684c
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    if (cameraCb == 0) {
579        ALOGE("%s: Callback must not be null", __FUNCTION__);
580        return BAD_VALUE;
581    }
582
583    String8 clientName8(clientPackageName);
584    int callingPid = getCallingPid();
585
586    LOG1("CameraService::connectPro E (pid %d \"%s\", id %d)", callingPid,
587            clientName8.string(), cameraId);
588    status_t status = validateConnect(cameraId, /*inout*/clientUid);
589    if (status != OK) {
590        return status;
591    }
592
593    sp<ProClient> client;
594    {
595        Mutex::Autolock lock(mServiceLock);
596        {
597            sp<BasicClient> client;
598            if (!canConnectUnsafe(cameraId, clientPackageName,
599                                  cameraCb->asBinder(),
600                                  /*out*/client)) {
601                return -EBUSY;
602            }
603        }
604
605        int facing = -1;
606        int deviceVersion = getDeviceVersion(cameraId, &facing);
607
608        switch(deviceVersion) {
609          case CAMERA_DEVICE_API_VERSION_1_0:
610            ALOGE("Camera id %d uses HALv1, doesn't support ProCamera",
611                  cameraId);
612            return -EOPNOTSUPP;
613            break;
614          case CAMERA_DEVICE_API_VERSION_2_0:
615          case CAMERA_DEVICE_API_VERSION_2_1:
616          case CAMERA_DEVICE_API_VERSION_3_0:
617          case CAMERA_DEVICE_API_VERSION_3_1:
618          case CAMERA_DEVICE_API_VERSION_3_2:
619            client = new ProCamera2Client(this, cameraCb, String16(),
620                    cameraId, facing, callingPid, USE_CALLING_UID, getpid());
621            break;
622          case -1:
623            ALOGE("Invalid camera id %d", cameraId);
624            return BAD_VALUE;
625          default:
626            ALOGE("Unknown camera device HAL version: %d", deviceVersion);
627            return INVALID_OPERATION;
628        }
629
630        status_t status = connectFinishUnsafe(client, client->getRemote());
631        if (status != OK) {
632            return status;
633        }
634
635        mProClientList[cameraId].push(client);
636
637        LOG1("CameraService::connectPro X (id %d, this pid is %d)", cameraId,
638                getpid());
639    }
640    // important: release the mutex here so the client can call back
641    //    into the service from its destructor (can be at the end of the call)
642    device = client;
643    return OK;
644}
645
646status_t CameraService::connectDevice(
647        const sp<ICameraDeviceCallbacks>& cameraCb,
648        int cameraId,
649        const String16& clientPackageName,
650        int clientUid,
651        /*out*/
652        sp<ICameraDeviceUser>& device)
653{
654
655    String8 clientName8(clientPackageName);
656    int callingPid = getCallingPid();
657
658    LOG1("CameraService::connectDevice E (pid %d \"%s\", id %d)", callingPid,
659            clientName8.string(), cameraId);
660
661    status_t status = validateConnect(cameraId, /*inout*/clientUid);
662    if (status != OK) {
663        return status;
664    }
665
666    sp<CameraDeviceClient> client;
667    {
668        Mutex::Autolock lock(mServiceLock);
669        {
670            sp<BasicClient> client;
671            if (!canConnectUnsafe(cameraId, clientPackageName,
672                                  cameraCb->asBinder(),
673                                  /*out*/client)) {
674                return -EBUSY;
675            }
676        }
677
678        int facing = -1;
679        int deviceVersion = getDeviceVersion(cameraId, &facing);
680
681        // If there are other non-exclusive users of the camera,
682        //  this will tear them down before we can reuse the camera
683        if (isValidCameraId(cameraId)) {
684            // transition from PRESENT -> NOT_AVAILABLE
685            updateStatus(ICameraServiceListener::STATUS_NOT_AVAILABLE,
686                         cameraId);
687        }
688
689        switch(deviceVersion) {
690          case CAMERA_DEVICE_API_VERSION_1_0:
691            ALOGW("Camera using old HAL version: %d", deviceVersion);
692            return -EOPNOTSUPP;
693           // TODO: don't allow 2.0  Only allow 2.1 and higher
694          case CAMERA_DEVICE_API_VERSION_2_0:
695          case CAMERA_DEVICE_API_VERSION_2_1:
696          case CAMERA_DEVICE_API_VERSION_3_0:
697          case CAMERA_DEVICE_API_VERSION_3_1:
698          case CAMERA_DEVICE_API_VERSION_3_2:
699            client = new CameraDeviceClient(this, cameraCb, String16(),
700                    cameraId, facing, callingPid, USE_CALLING_UID, getpid());
701            break;
702          case -1:
703            ALOGE("Invalid camera id %d", cameraId);
704            return BAD_VALUE;
705          default:
706            ALOGE("Unknown camera device HAL version: %d", deviceVersion);
707            return INVALID_OPERATION;
708        }
709
710        status_t status = connectFinishUnsafe(client, client->getRemote());
711        if (status != OK) {
712            // this is probably not recoverable.. maybe the client can try again
713            // OK: we can only get here if we were originally in PRESENT state
714            updateStatus(ICameraServiceListener::STATUS_PRESENT, cameraId);
715            return status;
716        }
717
718        LOG1("CameraService::connectDevice X (id %d, this pid is %d)", cameraId,
719                getpid());
720
721        mClient[cameraId] = client;
722    }
723    // important: release the mutex here so the client can call back
724    //    into the service from its destructor (can be at the end of the call)
725
726    device = client;
727    return OK;
728}
729
730
731status_t CameraService::addListener(
732                                const sp<ICameraServiceListener>& listener) {
733    ALOGV("%s: Add listener %p", __FUNCTION__, listener.get());
734
735    if (listener == 0) {
736        ALOGE("%s: Listener must not be null", __FUNCTION__);
737        return BAD_VALUE;
738    }
739
740    Mutex::Autolock lock(mServiceLock);
741
742    Vector<sp<ICameraServiceListener> >::iterator it, end;
743    for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
744        if ((*it)->asBinder() == listener->asBinder()) {
745            ALOGW("%s: Tried to add listener %p which was already subscribed",
746                  __FUNCTION__, listener.get());
747            return ALREADY_EXISTS;
748        }
749    }
750
751    mListenerList.push_back(listener);
752
753    /* Immediately signal current status to this listener only */
754    {
755        Mutex::Autolock m(mStatusMutex) ;
756        int numCams = getNumberOfCameras();
757        for (int i = 0; i < numCams; ++i) {
758            listener->onStatusChanged(mStatusList[i], i);
759        }
760    }
761
762    return OK;
763}
764status_t CameraService::removeListener(
765                                const sp<ICameraServiceListener>& listener) {
766    ALOGV("%s: Remove listener %p", __FUNCTION__, listener.get());
767
768    if (listener == 0) {
769        ALOGE("%s: Listener must not be null", __FUNCTION__);
770        return BAD_VALUE;
771    }
772
773    Mutex::Autolock lock(mServiceLock);
774
775    Vector<sp<ICameraServiceListener> >::iterator it;
776    for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
777        if ((*it)->asBinder() == listener->asBinder()) {
778            mListenerList.erase(it);
779            return OK;
780        }
781    }
782
783    ALOGW("%s: Tried to remove a listener %p which was not subscribed",
784          __FUNCTION__, listener.get());
785
786    return BAD_VALUE;
787}
788
789void CameraService::removeClientByRemote(const wp<IBinder>& remoteBinder) {
790    int callingPid = getCallingPid();
791    LOG1("CameraService::removeClientByRemote E (pid %d)", callingPid);
792
793    // Declare this before the lock to make absolutely sure the
794    // destructor won't be called with the lock held.
795    Mutex::Autolock lock(mServiceLock);
796
797    int outIndex;
798    sp<BasicClient> client = findClientUnsafe(remoteBinder, outIndex);
799
800    if (client != 0) {
801        // Found our camera, clear and leave.
802        LOG1("removeClient: clear camera %d", outIndex);
803        mClient[outIndex].clear();
804
805        client->getRemote()->unlinkToDeath(this);
806    } else {
807
808        sp<ProClient> clientPro = findProClientUnsafe(remoteBinder);
809
810        if (clientPro != NULL) {
811            // Found our camera, clear and leave.
812            LOG1("removeClient: clear pro %p", clientPro.get());
813
814            clientPro->getRemoteCallback()->asBinder()->unlinkToDeath(this);
815        }
816    }
817
818    LOG1("CameraService::removeClientByRemote X (pid %d)", callingPid);
819}
820
821sp<CameraService::ProClient> CameraService::findProClientUnsafe(
822                        const wp<IBinder>& cameraCallbacksRemote)
823{
824    sp<ProClient> clientPro;
825
826    for (int i = 0; i < mNumberOfCameras; ++i) {
827        Vector<size_t> removeIdx;
828
829        for (size_t j = 0; j < mProClientList[i].size(); ++j) {
830            wp<ProClient> cl = mProClientList[i][j];
831
832            sp<ProClient> clStrong = cl.promote();
833            if (clStrong != NULL && clStrong->getRemote() == cameraCallbacksRemote) {
834                clientPro = clStrong;
835                break;
836            } else if (clStrong == NULL) {
837                // mark to clean up dead ptr
838                removeIdx.push(j);
839            }
840        }
841
842        // remove stale ptrs (in reverse so the indices dont change)
843        for (ssize_t j = (ssize_t)removeIdx.size() - 1; j >= 0; --j) {
844            mProClientList[i].removeAt(removeIdx[j]);
845        }
846
847    }
848
849    return clientPro;
850}
851
852sp<CameraService::BasicClient> CameraService::findClientUnsafe(
853                        const wp<IBinder>& cameraClient, int& outIndex) {
854    sp<BasicClient> client;
855
856    for (int i = 0; i < mNumberOfCameras; i++) {
857
858        // This happens when we have already disconnected (or this is
859        // just another unused camera).
860        if (mClient[i] == 0) continue;
861
862        // Promote mClient. It can fail if we are called from this path:
863        // Client::~Client() -> disconnect() -> removeClientByRemote().
864        client = mClient[i].promote();
865
866        // Clean up stale client entry
867        if (client == NULL) {
868            mClient[i].clear();
869            continue;
870        }
871
872        if (cameraClient == client->getRemote()) {
873            // Found our camera
874            outIndex = i;
875            return client;
876        }
877    }
878
879    outIndex = -1;
880    return NULL;
881}
882
883CameraService::BasicClient* CameraService::getClientByIdUnsafe(int cameraId) {
884    if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
885    return mClient[cameraId].unsafe_get();
886}
887
888Mutex* CameraService::getClientLockById(int cameraId) {
889    if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
890    return &mClientLock[cameraId];
891}
892
893sp<CameraService::BasicClient> CameraService::getClientByRemote(
894                                const wp<IBinder>& cameraClient) {
895
896    // Declare this before the lock to make absolutely sure the
897    // destructor won't be called with the lock held.
898    sp<BasicClient> client;
899
900    Mutex::Autolock lock(mServiceLock);
901
902    int outIndex;
903    client = findClientUnsafe(cameraClient, outIndex);
904
905    return client;
906}
907
908status_t CameraService::onTransact(
909    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
910    // Permission checks
911    switch (code) {
912        case BnCameraService::CONNECT:
913        case BnCameraService::CONNECT_PRO:
914            const int pid = getCallingPid();
915            const int self_pid = getpid();
916            if (pid != self_pid) {
917                // we're called from a different process, do the real check
918                if (!checkCallingPermission(
919                        String16("android.permission.CAMERA"))) {
920                    const int uid = getCallingUid();
921                    ALOGE("Permission Denial: "
922                         "can't use the camera pid=%d, uid=%d", pid, uid);
923                    return PERMISSION_DENIED;
924                }
925            }
926            break;
927    }
928
929    return BnCameraService::onTransact(code, data, reply, flags);
930}
931
932// The reason we need this busy bit is a new CameraService::connect() request
933// may come in while the previous Client's destructor has not been run or is
934// still running. If the last strong reference of the previous Client is gone
935// but the destructor has not been finished, we should not allow the new Client
936// to be created because we need to wait for the previous Client to tear down
937// the hardware first.
938void CameraService::setCameraBusy(int cameraId) {
939    android_atomic_write(1, &mBusy[cameraId]);
940
941    ALOGV("setCameraBusy cameraId=%d", cameraId);
942}
943
944void CameraService::setCameraFree(int cameraId) {
945    android_atomic_write(0, &mBusy[cameraId]);
946
947    ALOGV("setCameraFree cameraId=%d", cameraId);
948}
949
950// We share the media players for shutter and recording sound for all clients.
951// A reference count is kept to determine when we will actually release the
952// media players.
953
954MediaPlayer* CameraService::newMediaPlayer(const char *file) {
955    MediaPlayer* mp = new MediaPlayer();
956    if (mp->setDataSource(NULL /* httpService */, file, NULL) == NO_ERROR) {
957        mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE);
958        mp->prepare();
959    } else {
960        ALOGE("Failed to load CameraService sounds: %s", file);
961        return NULL;
962    }
963    return mp;
964}
965
966void CameraService::loadSound() {
967    Mutex::Autolock lock(mSoundLock);
968    LOG1("CameraService::loadSound ref=%d", mSoundRef);
969    if (mSoundRef++) return;
970
971    mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
972    mSoundPlayer[SOUND_RECORDING] = newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");
973}
974
975void CameraService::releaseSound() {
976    Mutex::Autolock lock(mSoundLock);
977    LOG1("CameraService::releaseSound ref=%d", mSoundRef);
978    if (--mSoundRef) return;
979
980    for (int i = 0; i < NUM_SOUNDS; i++) {
981        if (mSoundPlayer[i] != 0) {
982            mSoundPlayer[i]->disconnect();
983            mSoundPlayer[i].clear();
984        }
985    }
986}
987
988void CameraService::playSound(sound_kind kind) {
989    LOG1("playSound(%d)", kind);
990    Mutex::Autolock lock(mSoundLock);
991    sp<MediaPlayer> player = mSoundPlayer[kind];
992    if (player != 0) {
993        player->seekTo(0);
994        player->start();
995    }
996}
997
998// ----------------------------------------------------------------------------
999
1000CameraService::Client::Client(const sp<CameraService>& cameraService,
1001        const sp<ICameraClient>& cameraClient,
1002        const String16& clientPackageName,
1003        int cameraId, int cameraFacing,
1004        int clientPid, uid_t clientUid,
1005        int servicePid) :
1006        CameraService::BasicClient(cameraService, cameraClient->asBinder(),
1007                clientPackageName,
1008                cameraId, cameraFacing,
1009                clientPid, clientUid,
1010                servicePid)
1011{
1012    int callingPid = getCallingPid();
1013    LOG1("Client::Client E (pid %d, id %d)", callingPid, cameraId);
1014
1015    mRemoteCallback = cameraClient;
1016
1017    cameraService->setCameraBusy(cameraId);
1018    cameraService->loadSound();
1019
1020    LOG1("Client::Client X (pid %d, id %d)", callingPid, cameraId);
1021}
1022
1023// tear down the client
1024CameraService::Client::~Client() {
1025    ALOGV("~Client");
1026    mDestructionStarted = true;
1027
1028    mCameraService->releaseSound();
1029    // unconditionally disconnect. function is idempotent
1030    Client::disconnect();
1031}
1032
1033CameraService::BasicClient::BasicClient(const sp<CameraService>& cameraService,
1034        const sp<IBinder>& remoteCallback,
1035        const String16& clientPackageName,
1036        int cameraId, int cameraFacing,
1037        int clientPid, uid_t clientUid,
1038        int servicePid):
1039        mClientPackageName(clientPackageName)
1040{
1041    mCameraService = cameraService;
1042    mRemoteBinder = remoteCallback;
1043    mCameraId = cameraId;
1044    mCameraFacing = cameraFacing;
1045    mClientPid = clientPid;
1046    mClientUid = clientUid;
1047    mServicePid = servicePid;
1048    mOpsActive = false;
1049    mDestructionStarted = false;
1050}
1051
1052CameraService::BasicClient::~BasicClient() {
1053    ALOGV("~BasicClient");
1054    mDestructionStarted = true;
1055}
1056
1057void CameraService::BasicClient::disconnect() {
1058    ALOGV("BasicClient::disconnect");
1059    mCameraService->removeClientByRemote(mRemoteBinder);
1060    // client shouldn't be able to call into us anymore
1061    mClientPid = 0;
1062}
1063
1064status_t CameraService::BasicClient::startCameraOps() {
1065    int32_t res;
1066
1067    mOpsCallback = new OpsCallback(this);
1068
1069    {
1070        ALOGV("%s: Start camera ops, package name = %s, client UID = %d",
1071              __FUNCTION__, String8(mClientPackageName).string(), mClientUid);
1072    }
1073
1074    mAppOpsManager.startWatchingMode(AppOpsManager::OP_CAMERA,
1075            mClientPackageName, mOpsCallback);
1076    res = mAppOpsManager.startOp(AppOpsManager::OP_CAMERA,
1077            mClientUid, mClientPackageName);
1078
1079    if (res != AppOpsManager::MODE_ALLOWED) {
1080        ALOGI("Camera %d: Access for \"%s\" has been revoked",
1081                mCameraId, String8(mClientPackageName).string());
1082        return PERMISSION_DENIED;
1083    }
1084    mOpsActive = true;
1085    return OK;
1086}
1087
1088status_t CameraService::BasicClient::finishCameraOps() {
1089    if (mOpsActive) {
1090        mAppOpsManager.finishOp(AppOpsManager::OP_CAMERA, mClientUid,
1091                mClientPackageName);
1092        mOpsActive = false;
1093    }
1094    mAppOpsManager.stopWatchingMode(mOpsCallback);
1095    mOpsCallback.clear();
1096
1097    return OK;
1098}
1099
1100void CameraService::BasicClient::opChanged(int32_t op, const String16& packageName) {
1101    String8 name(packageName);
1102    String8 myName(mClientPackageName);
1103
1104    if (op != AppOpsManager::OP_CAMERA) {
1105        ALOGW("Unexpected app ops notification received: %d", op);
1106        return;
1107    }
1108
1109    int32_t res;
1110    res = mAppOpsManager.checkOp(AppOpsManager::OP_CAMERA,
1111            mClientUid, mClientPackageName);
1112    ALOGV("checkOp returns: %d, %s ", res,
1113            res == AppOpsManager::MODE_ALLOWED ? "ALLOWED" :
1114            res == AppOpsManager::MODE_IGNORED ? "IGNORED" :
1115            res == AppOpsManager::MODE_ERRORED ? "ERRORED" :
1116            "UNKNOWN");
1117
1118    if (res != AppOpsManager::MODE_ALLOWED) {
1119        ALOGI("Camera %d: Access for \"%s\" revoked", mCameraId,
1120                myName.string());
1121        // Reset the client PID to allow server-initiated disconnect,
1122        // and to prevent further calls by client.
1123        mClientPid = getCallingPid();
1124        CaptureResultExtras resultExtras; // a dummy result (invalid)
1125        notifyError(ICameraDeviceCallbacks::ERROR_CAMERA_SERVICE, resultExtras);
1126        disconnect();
1127    }
1128}
1129
1130// ----------------------------------------------------------------------------
1131
1132Mutex* CameraService::Client::getClientLockFromCookie(void* user) {
1133    return gCameraService->getClientLockById((int)(intptr_t) user);
1134}
1135
1136// Provide client pointer for callbacks. Client lock returned from getClientLockFromCookie should
1137// be acquired for this to be safe
1138CameraService::Client* CameraService::Client::getClientFromCookie(void* user) {
1139    BasicClient *basicClient = gCameraService->getClientByIdUnsafe((int)(intptr_t) user);
1140    // OK: only CameraClient calls this, and they already cast anyway.
1141    Client* client = static_cast<Client*>(basicClient);
1142
1143    // This could happen if the Client is in the process of shutting down (the
1144    // last strong reference is gone, but the destructor hasn't finished
1145    // stopping the hardware).
1146    if (client == NULL) return NULL;
1147
1148    // destruction already started, so should not be accessed
1149    if (client->mDestructionStarted) return NULL;
1150
1151    return client;
1152}
1153
1154void CameraService::Client::notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode,
1155        const CaptureResultExtras& resultExtras) {
1156    mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_RELEASED, 0);
1157}
1158
1159// NOTE: function is idempotent
1160void CameraService::Client::disconnect() {
1161    ALOGV("Client::disconnect");
1162    BasicClient::disconnect();
1163    mCameraService->setCameraFree(mCameraId);
1164
1165    StatusVector rejectSourceStates;
1166    rejectSourceStates.push_back(ICameraServiceListener::STATUS_NOT_PRESENT);
1167    rejectSourceStates.push_back(ICameraServiceListener::STATUS_ENUMERATING);
1168
1169    // Transition to PRESENT if the camera is not in either of above 2 states
1170    mCameraService->updateStatus(ICameraServiceListener::STATUS_PRESENT,
1171                                 mCameraId,
1172                                 &rejectSourceStates);
1173}
1174
1175CameraService::Client::OpsCallback::OpsCallback(wp<BasicClient> client):
1176        mClient(client) {
1177}
1178
1179void CameraService::Client::OpsCallback::opChanged(int32_t op,
1180        const String16& packageName) {
1181    sp<BasicClient> client = mClient.promote();
1182    if (client != NULL) {
1183        client->opChanged(op, packageName);
1184    }
1185}
1186
1187// ----------------------------------------------------------------------------
1188//                  IProCamera
1189// ----------------------------------------------------------------------------
1190
1191CameraService::ProClient::ProClient(const sp<CameraService>& cameraService,
1192        const sp<IProCameraCallbacks>& remoteCallback,
1193        const String16& clientPackageName,
1194        int cameraId,
1195        int cameraFacing,
1196        int clientPid,
1197        uid_t clientUid,
1198        int servicePid)
1199        : CameraService::BasicClient(cameraService, remoteCallback->asBinder(),
1200                clientPackageName, cameraId, cameraFacing,
1201                clientPid,  clientUid, servicePid)
1202{
1203    mRemoteCallback = remoteCallback;
1204}
1205
1206CameraService::ProClient::~ProClient() {
1207}
1208
1209void CameraService::ProClient::notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode,
1210        const CaptureResultExtras& resultExtras) {
1211    mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_RELEASED, 0);
1212}
1213
1214// ----------------------------------------------------------------------------
1215
1216static const int kDumpLockRetries = 50;
1217static const int kDumpLockSleep = 60000;
1218
1219static bool tryLock(Mutex& mutex)
1220{
1221    bool locked = false;
1222    for (int i = 0; i < kDumpLockRetries; ++i) {
1223        if (mutex.tryLock() == NO_ERROR) {
1224            locked = true;
1225            break;
1226        }
1227        usleep(kDumpLockSleep);
1228    }
1229    return locked;
1230}
1231
1232status_t CameraService::dump(int fd, const Vector<String16>& args) {
1233    String8 result;
1234    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
1235        result.appendFormat("Permission Denial: "
1236                "can't dump CameraService from pid=%d, uid=%d\n",
1237                getCallingPid(),
1238                getCallingUid());
1239        write(fd, result.string(), result.size());
1240    } else {
1241        bool locked = tryLock(mServiceLock);
1242        // failed to lock - CameraService is probably deadlocked
1243        if (!locked) {
1244            result.append("CameraService may be deadlocked\n");
1245            write(fd, result.string(), result.size());
1246        }
1247
1248        bool hasClient = false;
1249        if (!mModule) {
1250            result = String8::format("No camera module available!\n");
1251            write(fd, result.string(), result.size());
1252            if (locked) mServiceLock.unlock();
1253            return NO_ERROR;
1254        }
1255
1256        result = String8::format("Camera module HAL API version: 0x%x\n",
1257                mModule->common.hal_api_version);
1258        result.appendFormat("Camera module API version: 0x%x\n",
1259                mModule->common.module_api_version);
1260        result.appendFormat("Camera module name: %s\n",
1261                mModule->common.name);
1262        result.appendFormat("Camera module author: %s\n",
1263                mModule->common.author);
1264        result.appendFormat("Number of camera devices: %d\n\n", mNumberOfCameras);
1265
1266        sp<VendorTagDescriptor> desc = VendorTagDescriptor::getGlobalVendorTagDescriptor();
1267        if (desc == NULL) {
1268            result.appendFormat("Vendor tags left unimplemented.\n");
1269        } else {
1270            result.appendFormat("Vendor tag definitions:\n");
1271        }
1272
1273        write(fd, result.string(), result.size());
1274
1275        if (desc != NULL) {
1276            desc->dump(fd, /*verbosity*/2, /*indentation*/4);
1277        }
1278
1279        for (int i = 0; i < mNumberOfCameras; i++) {
1280            result = String8::format("Camera %d static information:\n", i);
1281            camera_info info;
1282
1283            status_t rc = mModule->get_camera_info(i, &info);
1284            if (rc != OK) {
1285                result.appendFormat("  Error reading static information!\n");
1286                write(fd, result.string(), result.size());
1287            } else {
1288                result.appendFormat("  Facing: %s\n",
1289                        info.facing == CAMERA_FACING_BACK ? "BACK" : "FRONT");
1290                result.appendFormat("  Orientation: %d\n", info.orientation);
1291                int deviceVersion;
1292                if (mModule->common.module_api_version <
1293                        CAMERA_MODULE_API_VERSION_2_0) {
1294                    deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
1295                } else {
1296                    deviceVersion = info.device_version;
1297                }
1298                result.appendFormat("  Device version: 0x%x\n", deviceVersion);
1299                if (deviceVersion >= CAMERA_DEVICE_API_VERSION_2_0) {
1300                    result.appendFormat("  Device static metadata:\n");
1301                    write(fd, result.string(), result.size());
1302                    dump_indented_camera_metadata(info.static_camera_characteristics,
1303                            fd, /*verbosity*/2, /*indentation*/4);
1304                } else {
1305                    write(fd, result.string(), result.size());
1306                }
1307            }
1308
1309            sp<BasicClient> client = mClient[i].promote();
1310            if (client == 0) {
1311                result = String8::format("  Device is closed, no client instance\n");
1312                write(fd, result.string(), result.size());
1313                continue;
1314            }
1315            hasClient = true;
1316            result = String8::format("  Device is open. Client instance dump:\n");
1317            write(fd, result.string(), result.size());
1318            client->dump(fd, args);
1319        }
1320        if (!hasClient) {
1321            result = String8::format("\nNo active camera clients yet.\n");
1322            write(fd, result.string(), result.size());
1323        }
1324
1325        if (locked) mServiceLock.unlock();
1326
1327        // Dump camera traces if there were any
1328        write(fd, "\n", 1);
1329        camera3::CameraTraces::dump(fd, args);
1330
1331        // change logging level
1332        int n = args.size();
1333        for (int i = 0; i + 1 < n; i++) {
1334            String16 verboseOption("-v");
1335            if (args[i] == verboseOption) {
1336                String8 levelStr(args[i+1]);
1337                int level = atoi(levelStr.string());
1338                result = String8::format("\nSetting log level to %d.\n", level);
1339                setLogLevel(level);
1340                write(fd, result.string(), result.size());
1341            }
1342        }
1343
1344    }
1345    return NO_ERROR;
1346}
1347
1348/*virtual*/void CameraService::binderDied(
1349    const wp<IBinder> &who) {
1350
1351    /**
1352      * While tempting to promote the wp<IBinder> into a sp,
1353      * it's actually not supported by the binder driver
1354      */
1355
1356    ALOGV("java clients' binder died");
1357
1358    sp<BasicClient> cameraClient = getClientByRemote(who);
1359
1360    if (cameraClient == 0) {
1361        ALOGV("java clients' binder death already cleaned up (normal case)");
1362        return;
1363    }
1364
1365    ALOGW("Disconnecting camera client %p since the binder for it "
1366          "died (this pid %d)", cameraClient.get(), getCallingPid());
1367
1368    cameraClient->disconnect();
1369
1370}
1371
1372void CameraService::updateStatus(ICameraServiceListener::Status status,
1373                                 int32_t cameraId,
1374                                 const StatusVector *rejectSourceStates) {
1375    // do not lock mServiceLock here or can get into a deadlock from
1376    //  connect() -> ProClient::disconnect -> updateStatus
1377    Mutex::Autolock lock(mStatusMutex);
1378
1379    ICameraServiceListener::Status oldStatus = mStatusList[cameraId];
1380
1381    mStatusList[cameraId] = status;
1382
1383    if (oldStatus != status) {
1384        ALOGV("%s: Status has changed for camera ID %d from 0x%x to 0x%x",
1385              __FUNCTION__, cameraId, (uint32_t)oldStatus, (uint32_t)status);
1386
1387        if (oldStatus == ICameraServiceListener::STATUS_NOT_PRESENT &&
1388            (status != ICameraServiceListener::STATUS_PRESENT &&
1389             status != ICameraServiceListener::STATUS_ENUMERATING)) {
1390
1391            ALOGW("%s: From NOT_PRESENT can only transition into PRESENT"
1392                  " or ENUMERATING", __FUNCTION__);
1393            mStatusList[cameraId] = oldStatus;
1394            return;
1395        }
1396
1397        if (rejectSourceStates != NULL) {
1398            const StatusVector &rejectList = *rejectSourceStates;
1399            StatusVector::const_iterator it = rejectList.begin();
1400
1401            /**
1402             * Sometimes we want to conditionally do a transition.
1403             * For example if a client disconnects, we want to go to PRESENT
1404             * only if we weren't already in NOT_PRESENT or ENUMERATING.
1405             */
1406            for (; it != rejectList.end(); ++it) {
1407                if (oldStatus == *it) {
1408                    ALOGV("%s: Rejecting status transition for Camera ID %d, "
1409                          " since the source state was was in one of the bad "
1410                          " states.", __FUNCTION__, cameraId);
1411                    mStatusList[cameraId] = oldStatus;
1412                    return;
1413                }
1414            }
1415        }
1416
1417        /**
1418          * ProClients lose their exclusive lock.
1419          * - Done before the CameraClient can initialize the HAL device,
1420          *   since we want to be able to close it before they get to initialize
1421          */
1422        if (status == ICameraServiceListener::STATUS_NOT_AVAILABLE) {
1423            Vector<wp<ProClient> > proClients(mProClientList[cameraId]);
1424            Vector<wp<ProClient> >::const_iterator it;
1425
1426            for (it = proClients.begin(); it != proClients.end(); ++it) {
1427                sp<ProClient> proCl = it->promote();
1428                if (proCl.get() != NULL) {
1429                    proCl->onExclusiveLockStolen();
1430                }
1431            }
1432        }
1433
1434        Vector<sp<ICameraServiceListener> >::const_iterator it;
1435        for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
1436            (*it)->onStatusChanged(status, cameraId);
1437        }
1438    }
1439}
1440
1441ICameraServiceListener::Status CameraService::getStatus(int cameraId) const {
1442    if (cameraId < 0 || cameraId >= MAX_CAMERAS) {
1443        ALOGE("%s: Invalid camera ID %d", __FUNCTION__, cameraId);
1444        return ICameraServiceListener::STATUS_UNKNOWN;
1445    }
1446
1447    Mutex::Autolock al(mStatusMutex);
1448    return mStatusList[cameraId];
1449}
1450
1451}; // namespace android
1452