CameraService.cpp revision 88da526d97442c80731e01bfc94c6b47c4b0c3c7
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 <cutils/multiuser.h>
33#include <gui/Surface.h>
34#include <hardware/hardware.h>
35#include <media/AudioSystem.h>
36#include <media/IMediaHTTPService.h>
37#include <media/mediaplayer.h>
38#include <utils/Errors.h>
39#include <utils/Log.h>
40#include <utils/String16.h>
41#include <utils/Trace.h>
42#include <system/camera_vendor_tags.h>
43#include <system/camera_metadata.h>
44#include <system/camera.h>
45
46#include "CameraService.h"
47#include "api1/CameraClient.h"
48#include "api1/Camera2Client.h"
49#include "api_pro/ProCamera2Client.h"
50#include "api2/CameraDeviceClient.h"
51#include "utils/CameraTraces.h"
52#include "CameraDeviceFactory.h"
53
54namespace android {
55
56// ----------------------------------------------------------------------------
57// Logging support -- this is for debugging only
58// Use "adb shell dumpsys media.camera -v 1" to change it.
59volatile int32_t gLogLevel = 0;
60
61#define LOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__);
62#define LOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__);
63
64static void setLogLevel(int level) {
65    android_atomic_write(level, &gLogLevel);
66}
67
68// ----------------------------------------------------------------------------
69
70static int getCallingPid() {
71    return IPCThreadState::self()->getCallingPid();
72}
73
74static int getCallingUid() {
75    return IPCThreadState::self()->getCallingUid();
76}
77
78extern "C" {
79static void camera_device_status_change(
80        const struct camera_module_callbacks* callbacks,
81        int camera_id,
82        int new_status) {
83    sp<CameraService> cs = const_cast<CameraService*>(
84                                static_cast<const CameraService*>(callbacks));
85
86    cs->onDeviceStatusChanged(
87        camera_id,
88        new_status);
89}
90
91static void torch_mode_status_change(
92        const struct camera_module_callbacks* callbacks,
93        const char* camera_id,
94        int new_status) {
95    if (!callbacks || !camera_id) {
96        ALOGE("%s invalid parameters. callbacks %p, camera_id %p", __FUNCTION__,
97                callbacks, camera_id);
98    }
99    sp<CameraService> cs = const_cast<CameraService*>(
100                                static_cast<const CameraService*>(callbacks));
101
102    ICameraServiceListener::TorchStatus status;
103    switch (new_status) {
104        case TORCH_MODE_STATUS_NOT_AVAILABLE:
105            status = ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE;
106            break;
107        case TORCH_MODE_STATUS_AVAILABLE_OFF:
108            status = ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF;
109            break;
110        case TORCH_MODE_STATUS_AVAILABLE_ON:
111            status = ICameraServiceListener::TORCH_STATUS_AVAILABLE_ON;
112            break;
113        default:
114            ALOGE("Unknown torch status %d", new_status);
115            return;
116    }
117
118    cs->onTorchStatusChanged(
119        String8(camera_id),
120        status);
121}
122} // extern "C"
123
124// ----------------------------------------------------------------------------
125
126// This is ugly and only safe if we never re-create the CameraService, but
127// should be ok for now.
128static CameraService *gCameraService;
129
130CameraService::CameraService()
131    :mSoundRef(0), mModule(0), mFlashlight(0)
132{
133    ALOGI("CameraService started (pid=%d)", getpid());
134    gCameraService = this;
135
136    for (size_t i = 0; i < MAX_CAMERAS; ++i) {
137        mStatusList[i] = ICameraServiceListener::STATUS_PRESENT;
138    }
139
140    this->camera_device_status_change = android::camera_device_status_change;
141    this->torch_mode_status_change = android::torch_mode_status_change;
142
143}
144
145void CameraService::onFirstRef()
146{
147    LOG1("CameraService::onFirstRef");
148
149    BnCameraService::onFirstRef();
150
151    camera_module_t *rawModule;
152    if (hw_get_module(CAMERA_HARDWARE_MODULE_ID,
153                (const hw_module_t **)&rawModule) < 0) {
154        ALOGE("Could not load camera HAL module");
155        mNumberOfCameras = 0;
156    }
157    else {
158        mModule = new CameraModule(rawModule);
159        const hw_module_t *common = mModule->getRawModule();
160        ALOGI("Loaded \"%s\" cameraCa module", common->name);
161        mNumberOfCameras = mModule->getNumberOfCameras();
162        if (mNumberOfCameras > MAX_CAMERAS) {
163            ALOGE("Number of cameras(%d) > MAX_CAMERAS(%d).",
164                    mNumberOfCameras, MAX_CAMERAS);
165            mNumberOfCameras = MAX_CAMERAS;
166        }
167
168        mFlashlight = new CameraFlashlight(*mModule, *this);
169        status_t res = mFlashlight->findFlashUnits();
170        if (res) {
171            // impossible because we haven't open any camera devices.
172            ALOGE("failed to find flash units.");
173        }
174
175        for (int i = 0; i < mNumberOfCameras; i++) {
176            setCameraFree(i);
177
178            String8 cameraName = String8::format("%d", i);
179            if (mFlashlight->hasFlashUnit(cameraName)) {
180                mTorchStatusMap.add(cameraName,
181                        ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF);
182            }
183        }
184
185        if (common->module_api_version >= CAMERA_MODULE_API_VERSION_2_1) {
186            mModule->setCallbacks(this);
187        }
188
189        VendorTagDescriptor::clearGlobalVendorTagDescriptor();
190
191        if (common->module_api_version >= CAMERA_MODULE_API_VERSION_2_2) {
192            setUpVendorTags();
193        }
194
195        CameraDeviceFactory::registerService(this);
196    }
197}
198
199CameraService::~CameraService() {
200    for (int i = 0; i < mNumberOfCameras; i++) {
201        if (mBusy[i]) {
202            ALOGE("camera %d is still in use in destructor!", i);
203        }
204    }
205
206    if (mModule) {
207        delete mModule;
208    }
209    VendorTagDescriptor::clearGlobalVendorTagDescriptor();
210    gCameraService = NULL;
211}
212
213void CameraService::onDeviceStatusChanged(int cameraId,
214                                          int newStatus)
215{
216    ALOGV("%s: Status changed for cameraId=%d, newStatus=%d", __FUNCTION__,
217          cameraId, newStatus);
218
219    if (cameraId < 0 || cameraId >= MAX_CAMERAS) {
220        ALOGE("%s: Bad camera ID %d", __FUNCTION__, cameraId);
221        return;
222    }
223
224    if ((int)getStatus(cameraId) == newStatus) {
225        ALOGE("%s: State transition to the same status 0x%x not allowed",
226              __FUNCTION__, (uint32_t)newStatus);
227        return;
228    }
229
230    /* don't do this in updateStatus
231       since it is also called from connect and we could get into a deadlock */
232    if (newStatus == CAMERA_DEVICE_STATUS_NOT_PRESENT) {
233        Vector<sp<BasicClient> > clientsToDisconnect;
234        {
235           Mutex::Autolock al(mServiceLock);
236
237           /* Remove cached parameters from shim cache */
238           mShimParams.removeItem(cameraId);
239
240           /* Find all clients that we need to disconnect */
241           sp<BasicClient> client = mClient[cameraId].promote();
242           if (client.get() != NULL) {
243               clientsToDisconnect.push_back(client);
244           }
245
246           int i = cameraId;
247           for (size_t j = 0; j < mProClientList[i].size(); ++j) {
248               sp<ProClient> cl = mProClientList[i][j].promote();
249               if (cl != NULL) {
250                   clientsToDisconnect.push_back(cl);
251               }
252           }
253        }
254
255        /* now disconnect them. don't hold the lock
256           or we can get into a deadlock */
257
258        for (size_t i = 0; i < clientsToDisconnect.size(); ++i) {
259            sp<BasicClient> client = clientsToDisconnect[i];
260
261            client->disconnect();
262            /**
263             * The remote app will no longer be able to call methods on the
264             * client since the client PID will be reset to 0
265             */
266        }
267
268        ALOGV("%s: After unplug, disconnected %zu clients",
269              __FUNCTION__, clientsToDisconnect.size());
270    }
271
272    updateStatus(
273            static_cast<ICameraServiceListener::Status>(newStatus), cameraId);
274
275}
276
277void CameraService::onTorchStatusChanged(const String8& cameraId,
278        ICameraServiceListener::TorchStatus newStatus) {
279    Mutex::Autolock al(mTorchStatusMutex);
280    onTorchStatusChangedLocked(cameraId, newStatus);
281}
282
283void CameraService::onTorchStatusChangedLocked(const String8& cameraId,
284        ICameraServiceListener::TorchStatus newStatus) {
285    ALOGI("%s: Torch status changed for cameraId=%s, newStatus=%d",
286            __FUNCTION__, cameraId.string(), newStatus);
287
288    ICameraServiceListener::TorchStatus status;
289    status_t res = getTorchStatusLocked(cameraId, &status);
290    if (res) {
291        ALOGE("%s: cannot get torch status of camera %s", cameraId.string());
292        return;
293    }
294    if (status == newStatus) {
295        ALOGE("%s: Torch state transition to the same status 0x%x not allowed",
296              __FUNCTION__, (uint32_t)newStatus);
297        return;
298    }
299
300    res = setTorchStatusLocked(cameraId, newStatus);
301    if (res) {
302        ALOGE("%s: Failed to set the torch status", __FUNCTION__,
303                (uint32_t)newStatus);
304        return;
305    }
306
307    Vector<sp<ICameraServiceListener> >::const_iterator it;
308    for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
309        (*it)->onTorchStatusChanged(newStatus, String16(cameraId.string()));
310    }
311}
312
313
314int32_t CameraService::getNumberOfCameras() {
315    return mNumberOfCameras;
316}
317
318status_t CameraService::getCameraInfo(int cameraId,
319                                      struct CameraInfo* cameraInfo) {
320    if (!mModule) {
321        return -ENODEV;
322    }
323
324    if (cameraId < 0 || cameraId >= mNumberOfCameras) {
325        return BAD_VALUE;
326    }
327
328    struct camera_info info;
329    status_t rc = filterGetInfoErrorCode(
330        mModule->getCameraInfo(cameraId, &info));
331    cameraInfo->facing = info.facing;
332    cameraInfo->orientation = info.orientation;
333    return rc;
334}
335
336
337status_t CameraService::generateShimMetadata(int cameraId, /*out*/CameraMetadata* cameraInfo) {
338    status_t ret = OK;
339    struct CameraInfo info;
340    if ((ret = getCameraInfo(cameraId, &info)) != OK) {
341        return ret;
342    }
343
344    CameraMetadata shimInfo;
345    int32_t orientation = static_cast<int32_t>(info.orientation);
346    if ((ret = shimInfo.update(ANDROID_SENSOR_ORIENTATION, &orientation, 1)) != OK) {
347        return ret;
348    }
349
350    uint8_t facing = (info.facing == CAMERA_FACING_FRONT) ?
351            ANDROID_LENS_FACING_FRONT : ANDROID_LENS_FACING_BACK;
352    if ((ret = shimInfo.update(ANDROID_LENS_FACING, &facing, 1)) != OK) {
353        return ret;
354    }
355
356    CameraParameters shimParams;
357    if ((ret = getLegacyParametersLazy(cameraId, /*out*/&shimParams)) != OK) {
358        // Error logged by callee
359        return ret;
360    }
361
362    Vector<Size> sizes;
363    Vector<Size> jpegSizes;
364    Vector<int32_t> formats;
365    const char* supportedPreviewFormats;
366    {
367        shimParams.getSupportedPreviewSizes(/*out*/sizes);
368        shimParams.getSupportedPreviewFormats(/*out*/formats);
369        shimParams.getSupportedPictureSizes(/*out*/jpegSizes);
370    }
371
372    // Always include IMPLEMENTATION_DEFINED
373    formats.add(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED);
374
375    const size_t INTS_PER_CONFIG = 4;
376
377    // Build available stream configurations metadata
378    size_t streamConfigSize = (sizes.size() * formats.size() + jpegSizes.size()) * INTS_PER_CONFIG;
379
380    Vector<int32_t> streamConfigs;
381    streamConfigs.setCapacity(streamConfigSize);
382
383    for (size_t i = 0; i < formats.size(); ++i) {
384        for (size_t j = 0; j < sizes.size(); ++j) {
385            streamConfigs.add(formats[i]);
386            streamConfigs.add(sizes[j].width);
387            streamConfigs.add(sizes[j].height);
388            streamConfigs.add(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
389        }
390    }
391
392    for (size_t i = 0; i < jpegSizes.size(); ++i) {
393        streamConfigs.add(HAL_PIXEL_FORMAT_BLOB);
394        streamConfigs.add(jpegSizes[i].width);
395        streamConfigs.add(jpegSizes[i].height);
396        streamConfigs.add(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
397    }
398
399    if ((ret = shimInfo.update(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
400            streamConfigs.array(), streamConfigSize)) != OK) {
401        return ret;
402    }
403
404    int64_t fakeMinFrames[0];
405    // TODO: Fixme, don't fake min frame durations.
406    if ((ret = shimInfo.update(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
407            fakeMinFrames, 0)) != OK) {
408        return ret;
409    }
410
411    int64_t fakeStalls[0];
412    // TODO: Fixme, don't fake stall durations.
413    if ((ret = shimInfo.update(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
414            fakeStalls, 0)) != OK) {
415        return ret;
416    }
417
418    *cameraInfo = shimInfo;
419    return OK;
420}
421
422status_t CameraService::getCameraCharacteristics(int cameraId,
423                                                CameraMetadata* cameraInfo) {
424    if (!cameraInfo) {
425        ALOGE("%s: cameraInfo is NULL", __FUNCTION__);
426        return BAD_VALUE;
427    }
428
429    if (!mModule) {
430        ALOGE("%s: camera hardware module doesn't exist", __FUNCTION__);
431        return -ENODEV;
432    }
433
434    if (cameraId < 0 || cameraId >= mNumberOfCameras) {
435        ALOGE("%s: Invalid camera id: %d", __FUNCTION__, cameraId);
436        return BAD_VALUE;
437    }
438
439    int facing;
440    status_t ret = OK;
441    if (mModule->getRawModule()->module_api_version < CAMERA_MODULE_API_VERSION_2_0 ||
442            getDeviceVersion(cameraId, &facing) <= CAMERA_DEVICE_API_VERSION_2_1 ) {
443        /**
444         * Backwards compatibility mode for old HALs:
445         * - Convert CameraInfo into static CameraMetadata properties.
446         * - Retrieve cached CameraParameters for this camera.  If none exist,
447         *   attempt to open CameraClient and retrieve the CameraParameters.
448         * - Convert cached CameraParameters into static CameraMetadata
449         *   properties.
450         */
451        ALOGI("%s: Switching to HAL1 shim implementation...", __FUNCTION__);
452
453        if ((ret = generateShimMetadata(cameraId, cameraInfo)) != OK) {
454            return ret;
455        }
456
457    } else {
458        /**
459         * Normal HAL 2.1+ codepath.
460         */
461        struct camera_info info;
462        ret = filterGetInfoErrorCode(mModule->getCameraInfo(cameraId, &info));
463        *cameraInfo = info.static_camera_characteristics;
464    }
465
466    return ret;
467}
468
469status_t CameraService::getCameraVendorTagDescriptor(/*out*/sp<VendorTagDescriptor>& desc) {
470    if (!mModule) {
471        ALOGE("%s: camera hardware module doesn't exist", __FUNCTION__);
472        return -ENODEV;
473    }
474
475    desc = VendorTagDescriptor::getGlobalVendorTagDescriptor();
476    return OK;
477}
478
479int CameraService::getDeviceVersion(int cameraId, int* facing) {
480    struct camera_info info;
481    if (mModule->getCameraInfo(cameraId, &info) != OK) {
482        return -1;
483    }
484
485    int deviceVersion;
486    if (mModule->getRawModule()->module_api_version >= CAMERA_MODULE_API_VERSION_2_0) {
487        deviceVersion = info.device_version;
488    } else {
489        deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
490    }
491
492    if (facing) {
493        *facing = info.facing;
494    }
495
496    return deviceVersion;
497}
498
499status_t CameraService::filterOpenErrorCode(status_t err) {
500    switch(err) {
501        case NO_ERROR:
502        case -EBUSY:
503        case -EINVAL:
504        case -EUSERS:
505            return err;
506        default:
507            break;
508    }
509    return -ENODEV;
510}
511
512status_t CameraService::filterGetInfoErrorCode(status_t err) {
513    switch(err) {
514        case NO_ERROR:
515        case -EINVAL:
516            return err;
517        default:
518            break;
519    }
520    return -ENODEV;
521}
522
523bool CameraService::setUpVendorTags() {
524    vendor_tag_ops_t vOps = vendor_tag_ops_t();
525
526    // Check if vendor operations have been implemented
527    if (!mModule->isVendorTagDefined()) {
528        ALOGI("%s: No vendor tags defined for this device.", __FUNCTION__);
529        return false;
530    }
531
532    ATRACE_BEGIN("camera3->get_metadata_vendor_tag_ops");
533    mModule->getVendorTagOps(&vOps);
534    ATRACE_END();
535
536    // Ensure all vendor operations are present
537    if (vOps.get_tag_count == NULL || vOps.get_all_tags == NULL ||
538            vOps.get_section_name == NULL || vOps.get_tag_name == NULL ||
539            vOps.get_tag_type == NULL) {
540        ALOGE("%s: Vendor tag operations not fully defined. Ignoring definitions."
541               , __FUNCTION__);
542        return false;
543    }
544
545    // Read all vendor tag definitions into a descriptor
546    sp<VendorTagDescriptor> desc;
547    status_t res;
548    if ((res = VendorTagDescriptor::createDescriptorFromOps(&vOps, /*out*/desc))
549            != OK) {
550        ALOGE("%s: Could not generate descriptor from vendor tag operations,"
551              "received error %s (%d). Camera clients will not be able to use"
552              "vendor tags", __FUNCTION__, strerror(res), res);
553        return false;
554    }
555
556    // Set the global descriptor to use with camera metadata
557    VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
558    return true;
559}
560
561status_t CameraService::initializeShimMetadata(int cameraId) {
562    int pid = getCallingPid();
563    int uid = getCallingUid();
564    status_t ret = validateConnect(cameraId, uid);
565    if (ret != OK) {
566        // Error already logged by callee
567        return ret;
568    }
569
570    bool needsNewClient = false;
571    sp<Client> client;
572
573    String16 internalPackageName("media");
574    {   // Scope for service lock
575        Mutex::Autolock lock(mServiceLock);
576        if (mClient[cameraId] != NULL) {
577            client = static_cast<Client*>(mClient[cameraId].promote().get());
578        }
579        if (client == NULL) {
580            needsNewClient = true;
581            ret = connectHelperLocked(/*out*/client,
582                                      /*cameraClient*/NULL, // Empty binder callbacks
583                                      cameraId,
584                                      internalPackageName,
585                                      uid,
586                                      pid);
587
588            if (ret != OK) {
589                // Error already logged by callee
590                return ret;
591            }
592        }
593
594        if (client == NULL) {
595            ALOGE("%s: Could not connect to client camera device.", __FUNCTION__);
596            return BAD_VALUE;
597        }
598
599        String8 rawParams = client->getParameters();
600        CameraParameters params(rawParams);
601        mShimParams.add(cameraId, params);
602    }
603
604    // Close client if one was opened solely for this call
605    if (needsNewClient) {
606        client->disconnect();
607    }
608    return OK;
609}
610
611status_t CameraService::getLegacyParametersLazy(int cameraId,
612        /*out*/
613        CameraParameters* parameters) {
614
615    ALOGV("%s: for cameraId: %d", __FUNCTION__, cameraId);
616
617    status_t ret = 0;
618
619    if (parameters == NULL) {
620        ALOGE("%s: parameters must not be null", __FUNCTION__);
621        return BAD_VALUE;
622    }
623
624    ssize_t index = -1;
625    {   // Scope for service lock
626        Mutex::Autolock lock(mServiceLock);
627        index = mShimParams.indexOfKey(cameraId);
628        // Release service lock so initializeShimMetadata can be called correctly.
629
630        if (index >= 0) {
631            *parameters = mShimParams[index];
632        }
633    }
634
635    if (index < 0) {
636        int64_t token = IPCThreadState::self()->clearCallingIdentity();
637        ret = initializeShimMetadata(cameraId);
638        IPCThreadState::self()->restoreCallingIdentity(token);
639        if (ret != OK) {
640            // Error already logged by callee
641            return ret;
642        }
643
644        {   // Scope for service lock
645            Mutex::Autolock lock(mServiceLock);
646            index = mShimParams.indexOfKey(cameraId);
647
648            LOG_ALWAYS_FATAL_IF(index < 0, "index should have been initialized");
649
650            *parameters = mShimParams[index];
651        }
652    }
653
654    return OK;
655}
656
657status_t CameraService::validateConnect(int cameraId,
658                                    /*inout*/
659                                    int& clientUid) const {
660
661    int callingPid = getCallingPid();
662
663    if (clientUid == USE_CALLING_UID) {
664        clientUid = getCallingUid();
665    } else {
666        // We only trust our own process to forward client UIDs
667        if (callingPid != getpid()) {
668            ALOGE("CameraService::connect X (pid %d) rejected (don't trust clientUid)",
669                    callingPid);
670            return PERMISSION_DENIED;
671        }
672    }
673
674    if (!mModule) {
675        ALOGE("Camera HAL module not loaded");
676        return -ENODEV;
677    }
678
679    if (cameraId < 0 || cameraId >= mNumberOfCameras) {
680        ALOGE("CameraService::connect X (pid %d) rejected (invalid cameraId %d).",
681            callingPid, cameraId);
682        return -ENODEV;
683    }
684
685    char value[PROPERTY_VALUE_MAX];
686    char key[PROPERTY_KEY_MAX];
687    int clientUserId = multiuser_get_user_id(clientUid);
688    snprintf(key, PROPERTY_KEY_MAX, "sys.secpolicy.camera.off_%d", clientUserId);
689    property_get(key, value, "0");
690    if (strcmp(value, "1") == 0) {
691        // Camera is disabled by DevicePolicyManager.
692        ALOGI("Camera is disabled. connect X (pid %d) rejected", callingPid);
693        return -EACCES;
694    }
695
696    ICameraServiceListener::Status currentStatus = getStatus(cameraId);
697    if (currentStatus == ICameraServiceListener::STATUS_NOT_PRESENT) {
698        ALOGI("Camera is not plugged in,"
699               " connect X (pid %d) rejected", callingPid);
700        return -ENODEV;
701    } else if (currentStatus == ICameraServiceListener::STATUS_ENUMERATING) {
702        ALOGI("Camera is enumerating,"
703               " connect X (pid %d) rejected", callingPid);
704        return -EBUSY;
705    }
706    // Else don't check for STATUS_NOT_AVAILABLE.
707    //  -- It's done implicitly in canConnectUnsafe /w the mBusy array
708
709    return OK;
710}
711
712bool CameraService::canConnectUnsafe(int cameraId,
713                                     const String16& clientPackageName,
714                                     const sp<IBinder>& remoteCallback,
715                                     sp<BasicClient> &client) {
716    String8 clientName8(clientPackageName);
717    int callingPid = getCallingPid();
718
719    if (mClient[cameraId] != 0) {
720        client = mClient[cameraId].promote();
721        if (client != 0) {
722            if (remoteCallback == client->getRemote()) {
723                LOG1("CameraService::connect X (pid %d) (the same client)",
724                     callingPid);
725                return true;
726            } else {
727                // TODOSC: need to support 1 regular client,
728                // multiple shared clients here
729                ALOGW("CameraService::connect X (pid %d) rejected"
730                      " (existing client).", callingPid);
731                return false;
732            }
733        }
734        mClient[cameraId].clear();
735    }
736
737    /*
738    mBusy is set to false as the last step of the Client destructor,
739    after which it is guaranteed that the Client destructor has finished (
740    including any inherited destructors)
741
742    We only need this for a Client subclasses since we don't allow
743    multiple Clents to be opened concurrently, but multiple BasicClient
744    would be fine
745    */
746    if (mBusy[cameraId]) {
747        ALOGW("CameraService::connect X (pid %d, \"%s\") rejected"
748                " (camera %d is still busy).", callingPid,
749                clientName8.string(), cameraId);
750        return false;
751    }
752
753    return true;
754}
755
756status_t CameraService::connectHelperLocked(
757        /*out*/
758        sp<Client>& client,
759        /*in*/
760        const sp<ICameraClient>& cameraClient,
761        int cameraId,
762        const String16& clientPackageName,
763        int clientUid,
764        int callingPid,
765        int halVersion,
766        bool legacyMode) {
767
768    // give flashlight a chance to close devices if necessary.
769    mFlashlight->prepareDeviceOpen(String8::format("%d", cameraId));
770
771    int facing = -1;
772    int deviceVersion = getDeviceVersion(cameraId, &facing);
773
774    if (halVersion < 0 || halVersion == deviceVersion) {
775        // Default path: HAL version is unspecified by caller, create CameraClient
776        // based on device version reported by the HAL.
777        switch(deviceVersion) {
778          case CAMERA_DEVICE_API_VERSION_1_0:
779            client = new CameraClient(this, cameraClient,
780                    clientPackageName, cameraId,
781                    facing, callingPid, clientUid, getpid(), legacyMode);
782            break;
783          case CAMERA_DEVICE_API_VERSION_2_0:
784          case CAMERA_DEVICE_API_VERSION_2_1:
785          case CAMERA_DEVICE_API_VERSION_3_0:
786          case CAMERA_DEVICE_API_VERSION_3_1:
787          case CAMERA_DEVICE_API_VERSION_3_2:
788            client = new Camera2Client(this, cameraClient,
789                    clientPackageName, cameraId,
790                    facing, callingPid, clientUid, getpid(), legacyMode);
791            break;
792          case -1:
793            ALOGE("Invalid camera id %d", cameraId);
794            return BAD_VALUE;
795          default:
796            ALOGE("Unknown camera device HAL version: %d", deviceVersion);
797            return INVALID_OPERATION;
798        }
799    } else {
800        // A particular HAL version is requested by caller. Create CameraClient
801        // based on the requested HAL version.
802        if (deviceVersion > CAMERA_DEVICE_API_VERSION_1_0 &&
803            halVersion == CAMERA_DEVICE_API_VERSION_1_0) {
804            // Only support higher HAL version device opened as HAL1.0 device.
805            client = new CameraClient(this, cameraClient,
806                    clientPackageName, cameraId,
807                    facing, callingPid, clientUid, getpid(), legacyMode);
808        } else {
809            // Other combinations (e.g. HAL3.x open as HAL2.x) are not supported yet.
810            ALOGE("Invalid camera HAL version %x: HAL %x device can only be"
811                    " opened as HAL %x device", halVersion, deviceVersion,
812                    CAMERA_DEVICE_API_VERSION_1_0);
813            return INVALID_OPERATION;
814        }
815    }
816
817    status_t status = connectFinishUnsafe(client, client->getRemote());
818    if (status != OK) {
819        // this is probably not recoverable.. maybe the client can try again
820        return status;
821    }
822
823    mClient[cameraId] = client;
824    LOG1("CameraService::connect X (id %d, this pid is %d)", cameraId,
825         getpid());
826
827    return OK;
828}
829
830status_t CameraService::connect(
831        const sp<ICameraClient>& cameraClient,
832        int cameraId,
833        const String16& clientPackageName,
834        int clientUid,
835        /*out*/
836        sp<ICamera>& device) {
837
838    String8 clientName8(clientPackageName);
839    int callingPid = getCallingPid();
840
841    LOG1("CameraService::connect E (pid %d \"%s\", id %d)", callingPid,
842            clientName8.string(), cameraId);
843
844    status_t status = validateConnect(cameraId, /*inout*/clientUid);
845    if (status != OK) {
846        return status;
847    }
848
849
850    sp<Client> client;
851    {
852        Mutex::Autolock lock(mServiceLock);
853        sp<BasicClient> clientTmp;
854        if (!canConnectUnsafe(cameraId, clientPackageName,
855                              IInterface::asBinder(cameraClient),
856                              /*out*/clientTmp)) {
857            return -EBUSY;
858        } else if (client.get() != NULL) {
859            device = static_cast<Client*>(clientTmp.get());
860            return OK;
861        }
862
863        status = connectHelperLocked(/*out*/client,
864                                     cameraClient,
865                                     cameraId,
866                                     clientPackageName,
867                                     clientUid,
868                                     callingPid);
869        if (status != OK) {
870            return status;
871        }
872
873    }
874    // important: release the mutex here so the client can call back
875    //    into the service from its destructor (can be at the end of the call)
876
877    device = client;
878    return OK;
879}
880
881status_t CameraService::connectLegacy(
882        const sp<ICameraClient>& cameraClient,
883        int cameraId, int halVersion,
884        const String16& clientPackageName,
885        int clientUid,
886        /*out*/
887        sp<ICamera>& device) {
888
889    int apiVersion = mModule->getRawModule()->module_api_version;
890    if (halVersion != CAMERA_HAL_API_VERSION_UNSPECIFIED &&
891            apiVersion < CAMERA_MODULE_API_VERSION_2_3) {
892        /*
893         * Either the HAL version is unspecified in which case this just creates
894         * a camera client selected by the latest device version, or
895         * it's a particular version in which case the HAL must supported
896         * the open_legacy call
897         */
898        ALOGE("%s: camera HAL module version %x doesn't support connecting to legacy HAL devices!",
899                __FUNCTION__, apiVersion);
900        return INVALID_OPERATION;
901    }
902
903    String8 clientName8(clientPackageName);
904    int callingPid = getCallingPid();
905
906    LOG1("CameraService::connect legacy E (pid %d \"%s\", id %d)", callingPid,
907            clientName8.string(), cameraId);
908
909    status_t status = validateConnect(cameraId, /*inout*/clientUid);
910    if (status != OK) {
911        return status;
912    }
913
914    sp<Client> client;
915    {
916        Mutex::Autolock lock(mServiceLock);
917        sp<BasicClient> clientTmp;
918        if (!canConnectUnsafe(cameraId, clientPackageName,
919                              IInterface::asBinder(cameraClient),
920                              /*out*/clientTmp)) {
921            return -EBUSY;
922        } else if (client.get() != NULL) {
923            device = static_cast<Client*>(clientTmp.get());
924            return OK;
925        }
926
927        status = connectHelperLocked(/*out*/client,
928                                     cameraClient,
929                                     cameraId,
930                                     clientPackageName,
931                                     clientUid,
932                                     callingPid,
933                                     halVersion,
934                                     /*legacyMode*/true);
935        if (status != OK) {
936            return status;
937        }
938
939    }
940    // important: release the mutex here so the client can call back
941    //    into the service from its destructor (can be at the end of the call)
942
943    device = client;
944    return OK;
945}
946
947bool CameraService::validCameraIdForSetTorchMode(const String8& cameraId) {
948    // invalid string for int
949    if (cameraId.string() == NULL) {
950        return false;
951    }
952    errno = 0;
953    char *endptr;
954    long id = strtol(cameraId.string(), &endptr, 10); // base 10
955    if (errno || id > INT_MAX || id < INT_MIN || *endptr != 0) {
956        return false;
957    }
958
959    // id matches one of the plugged-in devices?
960    ICameraServiceListener::Status deviceStatus = getStatus(id);
961    if (deviceStatus != ICameraServiceListener::STATUS_PRESENT &&
962            deviceStatus != ICameraServiceListener::STATUS_NOT_AVAILABLE) {
963        return false;
964    }
965
966    return true;
967}
968
969status_t CameraService::setTorchMode(const String16& cameraId, bool enabled,
970        const sp<IBinder>& clientBinder) {
971    if (enabled && clientBinder == NULL) {
972        ALOGE("%s: torch client binder is NULL", __FUNCTION__);
973        return -EINVAL;
974    }
975
976    String8 id = String8(cameraId.string());
977
978    // verify id is valid.
979    if (validCameraIdForSetTorchMode(id) == false) {
980        ALOGE("%s: camera id is invalid %s", id.string());
981        return -EINVAL;
982    }
983
984    {
985        Mutex::Autolock al(mTorchStatusMutex);
986        ICameraServiceListener::TorchStatus status;
987        status_t res = getTorchStatusLocked(id, &status);
988        if (res) {
989            ALOGE("%s: getting current torch status failed for camera %s",
990                    __FUNCTION__, id.string());
991            return -EINVAL;
992        }
993
994        if (status == ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE) {
995            if (getStatus(atoi(id.string())) ==
996                        ICameraServiceListener::STATUS_NOT_AVAILABLE) {
997                ALOGE("%s: torch mode of camera %s is not available because "
998                        "camera is in use", __FUNCTION__, id.string());
999                return -EBUSY;
1000            } else {
1001                ALOGE("%s: torch mode of camera %s is not available due to "
1002                        "insufficient resources", __FUNCTION__, id.string());
1003                return -EUSERS;
1004            }
1005        }
1006    }
1007
1008    status_t res = mFlashlight->setTorchMode(id, enabled);
1009    if (res) {
1010        ALOGE("%s: setting torch mode of camera %s to %d failed. %s (%d)",
1011                __FUNCTION__, id.string(), enabled, strerror(-res), res);
1012        return res;
1013    }
1014
1015    {
1016        // update the link to client's death
1017        Mutex::Autolock al(mTorchClientMapMutex);
1018        ssize_t index = mTorchClientMap.indexOfKey(id);
1019        if (enabled) {
1020            if (index == NAME_NOT_FOUND) {
1021                mTorchClientMap.add(id, clientBinder);
1022            } else {
1023                const sp<IBinder> oldBinder = mTorchClientMap.valueAt(index);
1024                oldBinder->unlinkToDeath(this);
1025
1026                mTorchClientMap.replaceValueAt(index, clientBinder);
1027            }
1028            clientBinder->linkToDeath(this);
1029        } else if (index != NAME_NOT_FOUND) {
1030            sp<IBinder> oldBinder = mTorchClientMap.valueAt(index);
1031            oldBinder->unlinkToDeath(this);
1032        }
1033    }
1034
1035    return OK;
1036}
1037
1038status_t CameraService::connectFinishUnsafe(const sp<BasicClient>& client,
1039                                            const sp<IBinder>& remoteCallback) {
1040    status_t status = client->initialize(mModule);
1041    if (status != OK) {
1042        ALOGE("%s: Could not initialize client from HAL module.", __FUNCTION__);
1043        return status;
1044    }
1045    if (remoteCallback != NULL) {
1046        remoteCallback->linkToDeath(this);
1047    }
1048
1049    return OK;
1050}
1051
1052status_t CameraService::connectPro(
1053                                        const sp<IProCameraCallbacks>& cameraCb,
1054                                        int cameraId,
1055                                        const String16& clientPackageName,
1056                                        int clientUid,
1057                                        /*out*/
1058                                        sp<IProCameraUser>& device)
1059{
1060    if (cameraCb == 0) {
1061        ALOGE("%s: Callback must not be null", __FUNCTION__);
1062        return BAD_VALUE;
1063    }
1064
1065    String8 clientName8(clientPackageName);
1066    int callingPid = getCallingPid();
1067
1068    LOG1("CameraService::connectPro E (pid %d \"%s\", id %d)", callingPid,
1069            clientName8.string(), cameraId);
1070    status_t status = validateConnect(cameraId, /*inout*/clientUid);
1071    if (status != OK) {
1072        return status;
1073    }
1074
1075    sp<ProClient> client;
1076    {
1077        Mutex::Autolock lock(mServiceLock);
1078        {
1079            sp<BasicClient> client;
1080            if (!canConnectUnsafe(cameraId, clientPackageName,
1081                                  IInterface::asBinder(cameraCb),
1082                                  /*out*/client)) {
1083                return -EBUSY;
1084            }
1085        }
1086
1087        int facing = -1;
1088        int deviceVersion = getDeviceVersion(cameraId, &facing);
1089
1090        switch(deviceVersion) {
1091          case CAMERA_DEVICE_API_VERSION_1_0:
1092            ALOGE("Camera id %d uses HALv1, doesn't support ProCamera",
1093                  cameraId);
1094            return -EOPNOTSUPP;
1095            break;
1096          case CAMERA_DEVICE_API_VERSION_2_0:
1097          case CAMERA_DEVICE_API_VERSION_2_1:
1098          case CAMERA_DEVICE_API_VERSION_3_0:
1099          case CAMERA_DEVICE_API_VERSION_3_1:
1100          case CAMERA_DEVICE_API_VERSION_3_2:
1101            client = new ProCamera2Client(this, cameraCb, clientPackageName,
1102                    cameraId, facing, callingPid, clientUid, getpid());
1103            break;
1104          case -1:
1105            ALOGE("Invalid camera id %d", cameraId);
1106            return BAD_VALUE;
1107          default:
1108            ALOGE("Unknown camera device HAL version: %d", deviceVersion);
1109            return INVALID_OPERATION;
1110        }
1111
1112        status_t status = connectFinishUnsafe(client, client->getRemote());
1113        if (status != OK) {
1114            return status;
1115        }
1116
1117        mProClientList[cameraId].push(client);
1118
1119        LOG1("CameraService::connectPro X (id %d, this pid is %d)", cameraId,
1120                getpid());
1121    }
1122    // important: release the mutex here so the client can call back
1123    //    into the service from its destructor (can be at the end of the call)
1124    device = client;
1125    return OK;
1126}
1127
1128status_t CameraService::connectDevice(
1129        const sp<ICameraDeviceCallbacks>& cameraCb,
1130        int cameraId,
1131        const String16& clientPackageName,
1132        int clientUid,
1133        /*out*/
1134        sp<ICameraDeviceUser>& device)
1135{
1136
1137    String8 clientName8(clientPackageName);
1138    int callingPid = getCallingPid();
1139
1140    LOG1("CameraService::connectDevice E (pid %d \"%s\", id %d)", callingPid,
1141            clientName8.string(), cameraId);
1142
1143    status_t status = validateConnect(cameraId, /*inout*/clientUid);
1144    if (status != OK) {
1145        return status;
1146    }
1147
1148    sp<CameraDeviceClient> client;
1149    {
1150        Mutex::Autolock lock(mServiceLock);
1151        {
1152            sp<BasicClient> client;
1153            if (!canConnectUnsafe(cameraId, clientPackageName,
1154                                  IInterface::asBinder(cameraCb),
1155                                  /*out*/client)) {
1156                return -EBUSY;
1157            }
1158        }
1159
1160        int facing = -1;
1161        int deviceVersion = getDeviceVersion(cameraId, &facing);
1162
1163        // give flashlight a chance to close devices if necessary.
1164        mFlashlight->prepareDeviceOpen(String8::format("%d", cameraId));
1165
1166        switch(deviceVersion) {
1167          case CAMERA_DEVICE_API_VERSION_1_0:
1168            ALOGW("Camera using old HAL version: %d", deviceVersion);
1169            return -EOPNOTSUPP;
1170           // TODO: don't allow 2.0  Only allow 2.1 and higher
1171          case CAMERA_DEVICE_API_VERSION_2_0:
1172          case CAMERA_DEVICE_API_VERSION_2_1:
1173          case CAMERA_DEVICE_API_VERSION_3_0:
1174          case CAMERA_DEVICE_API_VERSION_3_1:
1175          case CAMERA_DEVICE_API_VERSION_3_2:
1176            client = new CameraDeviceClient(this, cameraCb, clientPackageName,
1177                    cameraId, facing, callingPid, clientUid, getpid());
1178            break;
1179          case -1:
1180            ALOGE("Invalid camera id %d", cameraId);
1181            return BAD_VALUE;
1182          default:
1183            ALOGE("Unknown camera device HAL version: %d", deviceVersion);
1184            return INVALID_OPERATION;
1185        }
1186
1187        status_t status = connectFinishUnsafe(client, client->getRemote());
1188        if (status != OK) {
1189            // this is probably not recoverable.. maybe the client can try again
1190            return status;
1191        }
1192
1193        LOG1("CameraService::connectDevice X (id %d, this pid is %d)", cameraId,
1194                getpid());
1195
1196        mClient[cameraId] = client;
1197    }
1198    // important: release the mutex here so the client can call back
1199    //    into the service from its destructor (can be at the end of the call)
1200
1201    device = client;
1202    return OK;
1203}
1204
1205
1206status_t CameraService::addListener(
1207                                const sp<ICameraServiceListener>& listener) {
1208    ALOGV("%s: Add listener %p", __FUNCTION__, listener.get());
1209
1210    if (listener == 0) {
1211        ALOGE("%s: Listener must not be null", __FUNCTION__);
1212        return BAD_VALUE;
1213    }
1214
1215    Mutex::Autolock lock(mServiceLock);
1216
1217    Vector<sp<ICameraServiceListener> >::iterator it, end;
1218    for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
1219        if (IInterface::asBinder(*it) == IInterface::asBinder(listener)) {
1220            ALOGW("%s: Tried to add listener %p which was already subscribed",
1221                  __FUNCTION__, listener.get());
1222            return ALREADY_EXISTS;
1223        }
1224    }
1225
1226    mListenerList.push_back(listener);
1227
1228    /* Immediately signal current status to this listener only */
1229    {
1230        Mutex::Autolock m(mStatusMutex) ;
1231        int numCams = getNumberOfCameras();
1232        for (int i = 0; i < numCams; ++i) {
1233            listener->onStatusChanged(mStatusList[i], i);
1234        }
1235    }
1236
1237    /* Immediately signal current torch status to this listener only */
1238    {
1239        Mutex::Autolock al(mTorchStatusMutex);
1240        for (size_t i = 0; i < mTorchStatusMap.size(); i++ ) {
1241            String16 id = String16(mTorchStatusMap.keyAt(i).string());
1242            listener->onTorchStatusChanged(mTorchStatusMap.valueAt(i), id);
1243        }
1244
1245    }
1246
1247    return OK;
1248}
1249status_t CameraService::removeListener(
1250                                const sp<ICameraServiceListener>& listener) {
1251    ALOGV("%s: Remove listener %p", __FUNCTION__, listener.get());
1252
1253    if (listener == 0) {
1254        ALOGE("%s: Listener must not be null", __FUNCTION__);
1255        return BAD_VALUE;
1256    }
1257
1258    Mutex::Autolock lock(mServiceLock);
1259
1260    Vector<sp<ICameraServiceListener> >::iterator it;
1261    for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
1262        if (IInterface::asBinder(*it) == IInterface::asBinder(listener)) {
1263            mListenerList.erase(it);
1264            return OK;
1265        }
1266    }
1267
1268    ALOGW("%s: Tried to remove a listener %p which was not subscribed",
1269          __FUNCTION__, listener.get());
1270
1271    return BAD_VALUE;
1272}
1273
1274status_t CameraService::getLegacyParameters(
1275            int cameraId,
1276            /*out*/
1277            String16* parameters) {
1278    ALOGV("%s: for camera ID = %d", __FUNCTION__, cameraId);
1279
1280    if (parameters == NULL) {
1281        ALOGE("%s: parameters must not be null", __FUNCTION__);
1282        return BAD_VALUE;
1283    }
1284
1285    status_t ret = 0;
1286
1287    CameraParameters shimParams;
1288    if ((ret = getLegacyParametersLazy(cameraId, /*out*/&shimParams)) != OK) {
1289        // Error logged by caller
1290        return ret;
1291    }
1292
1293    String8 shimParamsString8 = shimParams.flatten();
1294    String16 shimParamsString16 = String16(shimParamsString8);
1295
1296    *parameters = shimParamsString16;
1297
1298    return OK;
1299}
1300
1301status_t CameraService::supportsCameraApi(int cameraId, int apiVersion) {
1302    ALOGV("%s: for camera ID = %d", __FUNCTION__, cameraId);
1303
1304    switch (apiVersion) {
1305        case API_VERSION_1:
1306        case API_VERSION_2:
1307            break;
1308        default:
1309            ALOGE("%s: Bad API version %d", __FUNCTION__, apiVersion);
1310            return BAD_VALUE;
1311    }
1312
1313    int facing = -1;
1314    int deviceVersion = getDeviceVersion(cameraId, &facing);
1315
1316    switch(deviceVersion) {
1317      case CAMERA_DEVICE_API_VERSION_1_0:
1318      case CAMERA_DEVICE_API_VERSION_2_0:
1319      case CAMERA_DEVICE_API_VERSION_2_1:
1320      case CAMERA_DEVICE_API_VERSION_3_0:
1321      case CAMERA_DEVICE_API_VERSION_3_1:
1322        if (apiVersion == API_VERSION_2) {
1323            ALOGV("%s: Camera id %d uses HAL prior to HAL3.2, doesn't support api2 without shim",
1324                    __FUNCTION__, cameraId);
1325            return -EOPNOTSUPP;
1326        } else { // if (apiVersion == API_VERSION_1) {
1327            ALOGV("%s: Camera id %d uses older HAL before 3.2, but api1 is always supported",
1328                    __FUNCTION__, cameraId);
1329            return OK;
1330        }
1331      case CAMERA_DEVICE_API_VERSION_3_2:
1332        ALOGV("%s: Camera id %d uses HAL3.2 or newer, supports api1/api2 directly",
1333                __FUNCTION__, cameraId);
1334        return OK;
1335      case -1:
1336        ALOGE("%s: Invalid camera id %d", __FUNCTION__, cameraId);
1337        return BAD_VALUE;
1338      default:
1339        ALOGE("%s: Unknown camera device HAL version: %d", __FUNCTION__, deviceVersion);
1340        return INVALID_OPERATION;
1341    }
1342
1343    return OK;
1344}
1345
1346void CameraService::removeClientByRemote(const wp<IBinder>& remoteBinder) {
1347    int callingPid = getCallingPid();
1348    LOG1("CameraService::removeClientByRemote E (pid %d)", callingPid);
1349
1350    // Declare this before the lock to make absolutely sure the
1351    // destructor won't be called with the lock held.
1352    Mutex::Autolock lock(mServiceLock);
1353
1354    int outIndex;
1355    sp<BasicClient> client = findClientUnsafe(remoteBinder, outIndex);
1356
1357    if (client != 0) {
1358        // Found our camera, clear and leave.
1359        LOG1("removeClient: clear camera %d", outIndex);
1360
1361        sp<IBinder> remote = client->getRemote();
1362        if (remote != NULL) {
1363            remote->unlinkToDeath(this);
1364        }
1365
1366        mClient[outIndex].clear();
1367    } else {
1368
1369        sp<ProClient> clientPro = findProClientUnsafe(remoteBinder);
1370
1371        if (clientPro != NULL) {
1372            // Found our camera, clear and leave.
1373            LOG1("removeClient: clear pro %p", clientPro.get());
1374
1375            IInterface::asBinder(clientPro->getRemoteCallback())->unlinkToDeath(this);
1376        }
1377    }
1378
1379    LOG1("CameraService::removeClientByRemote X (pid %d)", callingPid);
1380}
1381
1382sp<CameraService::ProClient> CameraService::findProClientUnsafe(
1383                        const wp<IBinder>& cameraCallbacksRemote)
1384{
1385    sp<ProClient> clientPro;
1386
1387    for (int i = 0; i < mNumberOfCameras; ++i) {
1388        Vector<size_t> removeIdx;
1389
1390        for (size_t j = 0; j < mProClientList[i].size(); ++j) {
1391            wp<ProClient> cl = mProClientList[i][j];
1392
1393            sp<ProClient> clStrong = cl.promote();
1394            if (clStrong != NULL && clStrong->getRemote() == cameraCallbacksRemote) {
1395                clientPro = clStrong;
1396                break;
1397            } else if (clStrong == NULL) {
1398                // mark to clean up dead ptr
1399                removeIdx.push(j);
1400            }
1401        }
1402
1403        // remove stale ptrs (in reverse so the indices dont change)
1404        for (ssize_t j = (ssize_t)removeIdx.size() - 1; j >= 0; --j) {
1405            mProClientList[i].removeAt(removeIdx[j]);
1406        }
1407
1408    }
1409
1410    return clientPro;
1411}
1412
1413sp<CameraService::BasicClient> CameraService::findClientUnsafe(
1414                        const wp<IBinder>& cameraClient, int& outIndex) {
1415    sp<BasicClient> client;
1416
1417    for (int i = 0; i < mNumberOfCameras; i++) {
1418
1419        // This happens when we have already disconnected (or this is
1420        // just another unused camera).
1421        if (mClient[i] == 0) continue;
1422
1423        // Promote mClient. It can fail if we are called from this path:
1424        // Client::~Client() -> disconnect() -> removeClientByRemote().
1425        client = mClient[i].promote();
1426
1427        // Clean up stale client entry
1428        if (client == NULL) {
1429            mClient[i].clear();
1430            continue;
1431        }
1432
1433        if (cameraClient == client->getRemote()) {
1434            // Found our camera
1435            outIndex = i;
1436            return client;
1437        }
1438    }
1439
1440    outIndex = -1;
1441    return NULL;
1442}
1443
1444CameraService::BasicClient* CameraService::getClientByIdUnsafe(int cameraId) {
1445    if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
1446    return mClient[cameraId].unsafe_get();
1447}
1448
1449Mutex* CameraService::getClientLockById(int cameraId) {
1450    if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
1451    return &mClientLock[cameraId];
1452}
1453
1454sp<CameraService::BasicClient> CameraService::getClientByRemote(
1455                                const wp<IBinder>& cameraClient) {
1456
1457    // Declare this before the lock to make absolutely sure the
1458    // destructor won't be called with the lock held.
1459    sp<BasicClient> client;
1460
1461    Mutex::Autolock lock(mServiceLock);
1462
1463    int outIndex;
1464    client = findClientUnsafe(cameraClient, outIndex);
1465
1466    return client;
1467}
1468
1469status_t CameraService::onTransact(
1470    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
1471    // Permission checks
1472    switch (code) {
1473        case BnCameraService::CONNECT:
1474        case BnCameraService::CONNECT_PRO:
1475        case BnCameraService::CONNECT_DEVICE:
1476        case BnCameraService::CONNECT_LEGACY:
1477            const int pid = getCallingPid();
1478            const int self_pid = getpid();
1479            if (pid != self_pid) {
1480                // we're called from a different process, do the real check
1481                if (!checkCallingPermission(
1482                        String16("android.permission.CAMERA"))) {
1483                    const int uid = getCallingUid();
1484                    ALOGE("Permission Denial: "
1485                         "can't use the camera pid=%d, uid=%d", pid, uid);
1486                    return PERMISSION_DENIED;
1487                }
1488            }
1489            break;
1490    }
1491
1492    return BnCameraService::onTransact(code, data, reply, flags);
1493}
1494
1495// The reason we need this busy bit is a new CameraService::connect() request
1496// may come in while the previous Client's destructor has not been run or is
1497// still running. If the last strong reference of the previous Client is gone
1498// but the destructor has not been finished, we should not allow the new Client
1499// to be created because we need to wait for the previous Client to tear down
1500// the hardware first.
1501void CameraService::setCameraBusy(int cameraId) {
1502    android_atomic_write(1, &mBusy[cameraId]);
1503
1504    ALOGV("setCameraBusy cameraId=%d", cameraId);
1505}
1506
1507void CameraService::setCameraFree(int cameraId) {
1508    android_atomic_write(0, &mBusy[cameraId]);
1509
1510    ALOGV("setCameraFree cameraId=%d", cameraId);
1511}
1512
1513// We share the media players for shutter and recording sound for all clients.
1514// A reference count is kept to determine when we will actually release the
1515// media players.
1516
1517MediaPlayer* CameraService::newMediaPlayer(const char *file) {
1518    MediaPlayer* mp = new MediaPlayer();
1519    if (mp->setDataSource(NULL /* httpService */, file, NULL) == NO_ERROR) {
1520        mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE);
1521        mp->prepare();
1522    } else {
1523        ALOGE("Failed to load CameraService sounds: %s", file);
1524        return NULL;
1525    }
1526    return mp;
1527}
1528
1529void CameraService::loadSound() {
1530    Mutex::Autolock lock(mSoundLock);
1531    LOG1("CameraService::loadSound ref=%d", mSoundRef);
1532    if (mSoundRef++) return;
1533
1534    mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
1535    mSoundPlayer[SOUND_RECORDING] = newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");
1536}
1537
1538void CameraService::releaseSound() {
1539    Mutex::Autolock lock(mSoundLock);
1540    LOG1("CameraService::releaseSound ref=%d", mSoundRef);
1541    if (--mSoundRef) return;
1542
1543    for (int i = 0; i < NUM_SOUNDS; i++) {
1544        if (mSoundPlayer[i] != 0) {
1545            mSoundPlayer[i]->disconnect();
1546            mSoundPlayer[i].clear();
1547        }
1548    }
1549}
1550
1551void CameraService::playSound(sound_kind kind) {
1552    LOG1("playSound(%d)", kind);
1553    Mutex::Autolock lock(mSoundLock);
1554    sp<MediaPlayer> player = mSoundPlayer[kind];
1555    if (player != 0) {
1556        player->seekTo(0);
1557        player->start();
1558    }
1559}
1560
1561// ----------------------------------------------------------------------------
1562
1563CameraService::Client::Client(const sp<CameraService>& cameraService,
1564        const sp<ICameraClient>& cameraClient,
1565        const String16& clientPackageName,
1566        int cameraId, int cameraFacing,
1567        int clientPid, uid_t clientUid,
1568        int servicePid) :
1569        CameraService::BasicClient(cameraService,
1570                IInterface::asBinder(cameraClient),
1571                clientPackageName,
1572                cameraId, cameraFacing,
1573                clientPid, clientUid,
1574                servicePid)
1575{
1576    int callingPid = getCallingPid();
1577    LOG1("Client::Client E (pid %d, id %d)", callingPid, cameraId);
1578
1579    mRemoteCallback = cameraClient;
1580
1581    cameraService->setCameraBusy(cameraId);
1582    cameraService->loadSound();
1583
1584    LOG1("Client::Client X (pid %d, id %d)", callingPid, cameraId);
1585}
1586
1587// tear down the client
1588CameraService::Client::~Client() {
1589    ALOGV("~Client");
1590    mDestructionStarted = true;
1591
1592    mCameraService->releaseSound();
1593    // unconditionally disconnect. function is idempotent
1594    Client::disconnect();
1595}
1596
1597CameraService::BasicClient::BasicClient(const sp<CameraService>& cameraService,
1598        const sp<IBinder>& remoteCallback,
1599        const String16& clientPackageName,
1600        int cameraId, int cameraFacing,
1601        int clientPid, uid_t clientUid,
1602        int servicePid):
1603        mClientPackageName(clientPackageName)
1604{
1605    mCameraService = cameraService;
1606    mRemoteBinder = remoteCallback;
1607    mCameraId = cameraId;
1608    mCameraFacing = cameraFacing;
1609    mClientPid = clientPid;
1610    mClientUid = clientUid;
1611    mServicePid = servicePid;
1612    mOpsActive = false;
1613    mDestructionStarted = false;
1614}
1615
1616CameraService::BasicClient::~BasicClient() {
1617    ALOGV("~BasicClient");
1618    mDestructionStarted = true;
1619}
1620
1621void CameraService::BasicClient::disconnect() {
1622    ALOGV("BasicClient::disconnect");
1623    mCameraService->removeClientByRemote(mRemoteBinder);
1624
1625    finishCameraOps();
1626    // client shouldn't be able to call into us anymore
1627    mClientPid = 0;
1628}
1629
1630status_t CameraService::BasicClient::startCameraOps() {
1631    int32_t res;
1632    // Notify app ops that the camera is not available
1633    mOpsCallback = new OpsCallback(this);
1634
1635    {
1636        ALOGV("%s: Start camera ops, package name = %s, client UID = %d",
1637              __FUNCTION__, String8(mClientPackageName).string(), mClientUid);
1638    }
1639
1640    mAppOpsManager.startWatchingMode(AppOpsManager::OP_CAMERA,
1641            mClientPackageName, mOpsCallback);
1642    res = mAppOpsManager.startOp(AppOpsManager::OP_CAMERA,
1643            mClientUid, mClientPackageName);
1644
1645    if (res != AppOpsManager::MODE_ALLOWED) {
1646        ALOGI("Camera %d: Access for \"%s\" has been revoked",
1647                mCameraId, String8(mClientPackageName).string());
1648        return PERMISSION_DENIED;
1649    }
1650
1651    mOpsActive = true;
1652
1653    // Transition device availability listeners from PRESENT -> NOT_AVAILABLE
1654    mCameraService->updateStatus(ICameraServiceListener::STATUS_NOT_AVAILABLE,
1655            mCameraId);
1656
1657    return OK;
1658}
1659
1660status_t CameraService::BasicClient::finishCameraOps() {
1661    // Check if startCameraOps succeeded, and if so, finish the camera op
1662    if (mOpsActive) {
1663        // Notify app ops that the camera is available again
1664        mAppOpsManager.finishOp(AppOpsManager::OP_CAMERA, mClientUid,
1665                mClientPackageName);
1666        mOpsActive = false;
1667
1668        // Notify device availability listeners that this camera is available
1669        // again
1670
1671        StatusVector rejectSourceStates;
1672        rejectSourceStates.push_back(ICameraServiceListener::STATUS_NOT_PRESENT);
1673        rejectSourceStates.push_back(ICameraServiceListener::STATUS_ENUMERATING);
1674
1675        // Transition to PRESENT if the camera is not in either of above 2
1676        // states
1677        mCameraService->updateStatus(ICameraServiceListener::STATUS_PRESENT,
1678                mCameraId,
1679                &rejectSourceStates);
1680
1681        // Notify flashlight that a camera device is closed.
1682        mCameraService->mFlashlight->deviceClosed(
1683                String8::format("%d", mCameraId));
1684    }
1685    // Always stop watching, even if no camera op is active
1686    if (mOpsCallback != NULL) {
1687        mAppOpsManager.stopWatchingMode(mOpsCallback);
1688    }
1689    mOpsCallback.clear();
1690
1691    return OK;
1692}
1693
1694void CameraService::BasicClient::opChanged(int32_t op, const String16& packageName) {
1695    String8 name(packageName);
1696    String8 myName(mClientPackageName);
1697
1698    if (op != AppOpsManager::OP_CAMERA) {
1699        ALOGW("Unexpected app ops notification received: %d", op);
1700        return;
1701    }
1702
1703    int32_t res;
1704    res = mAppOpsManager.checkOp(AppOpsManager::OP_CAMERA,
1705            mClientUid, mClientPackageName);
1706    ALOGV("checkOp returns: %d, %s ", res,
1707            res == AppOpsManager::MODE_ALLOWED ? "ALLOWED" :
1708            res == AppOpsManager::MODE_IGNORED ? "IGNORED" :
1709            res == AppOpsManager::MODE_ERRORED ? "ERRORED" :
1710            "UNKNOWN");
1711
1712    if (res != AppOpsManager::MODE_ALLOWED) {
1713        ALOGI("Camera %d: Access for \"%s\" revoked", mCameraId,
1714                myName.string());
1715        // Reset the client PID to allow server-initiated disconnect,
1716        // and to prevent further calls by client.
1717        mClientPid = getCallingPid();
1718        CaptureResultExtras resultExtras; // a dummy result (invalid)
1719        notifyError(ICameraDeviceCallbacks::ERROR_CAMERA_SERVICE, resultExtras);
1720        disconnect();
1721    }
1722}
1723
1724// ----------------------------------------------------------------------------
1725
1726Mutex* CameraService::Client::getClientLockFromCookie(void* user) {
1727    return gCameraService->getClientLockById((int)(intptr_t) user);
1728}
1729
1730// Provide client pointer for callbacks. Client lock returned from getClientLockFromCookie should
1731// be acquired for this to be safe
1732CameraService::Client* CameraService::Client::getClientFromCookie(void* user) {
1733    BasicClient *basicClient = gCameraService->getClientByIdUnsafe((int)(intptr_t) user);
1734    // OK: only CameraClient calls this, and they already cast anyway.
1735    Client* client = static_cast<Client*>(basicClient);
1736
1737    // This could happen if the Client is in the process of shutting down (the
1738    // last strong reference is gone, but the destructor hasn't finished
1739    // stopping the hardware).
1740    if (client == NULL) return NULL;
1741
1742    // destruction already started, so should not be accessed
1743    if (client->mDestructionStarted) return NULL;
1744
1745    return client;
1746}
1747
1748void CameraService::Client::notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode,
1749        const CaptureResultExtras& resultExtras) {
1750    mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_RELEASED, 0);
1751}
1752
1753// NOTE: function is idempotent
1754void CameraService::Client::disconnect() {
1755    ALOGV("Client::disconnect");
1756    BasicClient::disconnect();
1757    mCameraService->setCameraFree(mCameraId);
1758}
1759
1760CameraService::Client::OpsCallback::OpsCallback(wp<BasicClient> client):
1761        mClient(client) {
1762}
1763
1764void CameraService::Client::OpsCallback::opChanged(int32_t op,
1765        const String16& packageName) {
1766    sp<BasicClient> client = mClient.promote();
1767    if (client != NULL) {
1768        client->opChanged(op, packageName);
1769    }
1770}
1771
1772// ----------------------------------------------------------------------------
1773//                  IProCamera
1774// ----------------------------------------------------------------------------
1775
1776CameraService::ProClient::ProClient(const sp<CameraService>& cameraService,
1777        const sp<IProCameraCallbacks>& remoteCallback,
1778        const String16& clientPackageName,
1779        int cameraId,
1780        int cameraFacing,
1781        int clientPid,
1782        uid_t clientUid,
1783        int servicePid)
1784        : CameraService::BasicClient(cameraService, IInterface::asBinder(remoteCallback),
1785                clientPackageName, cameraId, cameraFacing,
1786                clientPid,  clientUid, servicePid)
1787{
1788    mRemoteCallback = remoteCallback;
1789}
1790
1791CameraService::ProClient::~ProClient() {
1792}
1793
1794void CameraService::ProClient::notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode,
1795        const CaptureResultExtras& resultExtras) {
1796    mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_RELEASED, 0);
1797}
1798
1799// ----------------------------------------------------------------------------
1800
1801static const int kDumpLockRetries = 50;
1802static const int kDumpLockSleep = 60000;
1803
1804static bool tryLock(Mutex& mutex)
1805{
1806    bool locked = false;
1807    for (int i = 0; i < kDumpLockRetries; ++i) {
1808        if (mutex.tryLock() == NO_ERROR) {
1809            locked = true;
1810            break;
1811        }
1812        usleep(kDumpLockSleep);
1813    }
1814    return locked;
1815}
1816
1817status_t CameraService::dump(int fd, const Vector<String16>& args) {
1818    String8 result;
1819    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
1820        result.appendFormat("Permission Denial: "
1821                "can't dump CameraService from pid=%d, uid=%d\n",
1822                getCallingPid(),
1823                getCallingUid());
1824        write(fd, result.string(), result.size());
1825    } else {
1826        bool locked = tryLock(mServiceLock);
1827        // failed to lock - CameraService is probably deadlocked
1828        if (!locked) {
1829            result.append("CameraService may be deadlocked\n");
1830            write(fd, result.string(), result.size());
1831        }
1832
1833        bool hasClient = false;
1834        if (!mModule) {
1835            result = String8::format("No camera module available!\n");
1836            write(fd, result.string(), result.size());
1837            if (locked) mServiceLock.unlock();
1838            return NO_ERROR;
1839        }
1840
1841        const hw_module_t* common = mModule->getRawModule();
1842        result = String8::format("Camera module HAL API version: 0x%x\n", common->hal_api_version);
1843        result.appendFormat("Camera module API version: 0x%x\n", common->module_api_version);
1844        result.appendFormat("Camera module name: %s\n", common->name);
1845        result.appendFormat("Camera module author: %s\n", common->author);
1846        result.appendFormat("Number of camera devices: %d\n\n", mNumberOfCameras);
1847
1848        sp<VendorTagDescriptor> desc = VendorTagDescriptor::getGlobalVendorTagDescriptor();
1849        if (desc == NULL) {
1850            result.appendFormat("Vendor tags left unimplemented.\n");
1851        } else {
1852            result.appendFormat("Vendor tag definitions:\n");
1853        }
1854
1855        write(fd, result.string(), result.size());
1856
1857        if (desc != NULL) {
1858            desc->dump(fd, /*verbosity*/2, /*indentation*/4);
1859        }
1860
1861        for (int i = 0; i < mNumberOfCameras; i++) {
1862            result = String8::format("Camera %d static information:\n", i);
1863            camera_info info;
1864
1865            status_t rc = mModule->getCameraInfo(i, &info);
1866            if (rc != OK) {
1867                result.appendFormat("  Error reading static information!\n");
1868                write(fd, result.string(), result.size());
1869            } else {
1870                result.appendFormat("  Facing: %s\n",
1871                        info.facing == CAMERA_FACING_BACK ? "BACK" : "FRONT");
1872                result.appendFormat("  Orientation: %d\n", info.orientation);
1873                int deviceVersion;
1874                if (common->module_api_version < CAMERA_MODULE_API_VERSION_2_0) {
1875                    deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
1876                } else {
1877                    deviceVersion = info.device_version;
1878                }
1879                result.appendFormat("  Device version: 0x%x\n", deviceVersion);
1880                if (deviceVersion >= CAMERA_DEVICE_API_VERSION_2_0) {
1881                    result.appendFormat("  Device static metadata:\n");
1882                    write(fd, result.string(), result.size());
1883                    dump_indented_camera_metadata(info.static_camera_characteristics,
1884                            fd, /*verbosity*/2, /*indentation*/4);
1885                } else {
1886                    write(fd, result.string(), result.size());
1887                }
1888            }
1889
1890            sp<BasicClient> client = mClient[i].promote();
1891            if (client == 0) {
1892                result = String8::format("  Device is closed, no client instance\n");
1893                write(fd, result.string(), result.size());
1894                continue;
1895            }
1896            hasClient = true;
1897            result = String8::format("  Device is open. Client instance dump:\n");
1898            write(fd, result.string(), result.size());
1899            client->dump(fd, args);
1900        }
1901        if (!hasClient) {
1902            result = String8::format("\nNo active camera clients yet.\n");
1903            write(fd, result.string(), result.size());
1904        }
1905
1906        if (locked) mServiceLock.unlock();
1907
1908        // Dump camera traces if there were any
1909        write(fd, "\n", 1);
1910        camera3::CameraTraces::dump(fd, args);
1911
1912        // change logging level
1913        int n = args.size();
1914        for (int i = 0; i + 1 < n; i++) {
1915            String16 verboseOption("-v");
1916            if (args[i] == verboseOption) {
1917                String8 levelStr(args[i+1]);
1918                int level = atoi(levelStr.string());
1919                result = String8::format("\nSetting log level to %d.\n", level);
1920                setLogLevel(level);
1921                write(fd, result.string(), result.size());
1922            }
1923        }
1924
1925    }
1926    return NO_ERROR;
1927}
1928
1929void CameraService::handleTorchClientBinderDied(const wp<IBinder> &who) {
1930    Mutex::Autolock al(mTorchClientMapMutex);
1931    for (size_t i = 0; i < mTorchClientMap.size(); i++) {
1932        if (mTorchClientMap[i] == who) {
1933            // turn off the torch mode that was turned on by dead client
1934            String8 cameraId = mTorchClientMap.keyAt(i);
1935            status_t res = mFlashlight->setTorchMode(cameraId, false);
1936            if (res) {
1937                ALOGE("%s: torch client died but couldn't turn off torch: "
1938                    "%s (%d)", __FUNCTION__, strerror(-res), res);
1939                return;
1940            }
1941            mTorchClientMap.removeItemsAt(i);
1942            break;
1943        }
1944    }
1945}
1946
1947/*virtual*/void CameraService::binderDied(
1948    const wp<IBinder> &who) {
1949
1950    /**
1951      * While tempting to promote the wp<IBinder> into a sp,
1952      * it's actually not supported by the binder driver
1953      */
1954
1955    ALOGV("java clients' binder died");
1956
1957    // check torch client
1958    handleTorchClientBinderDied(who);
1959
1960    // check camera device client
1961    sp<BasicClient> cameraClient = getClientByRemote(who);
1962
1963    if (cameraClient == 0) {
1964        ALOGV("java clients' binder death already cleaned up (normal case)");
1965        return;
1966    }
1967
1968    ALOGW("Disconnecting camera client %p since the binder for it "
1969          "died (this pid %d)", cameraClient.get(), getCallingPid());
1970
1971    cameraClient->disconnect();
1972
1973}
1974
1975void CameraService::updateStatus(ICameraServiceListener::Status status,
1976                                 int32_t cameraId,
1977                                 const StatusVector *rejectSourceStates) {
1978    // do not lock mServiceLock here or can get into a deadlock from
1979    //  connect() -> ProClient::disconnect -> updateStatus
1980    Mutex::Autolock lock(mStatusMutex);
1981
1982    ICameraServiceListener::Status oldStatus = mStatusList[cameraId];
1983
1984    mStatusList[cameraId] = status;
1985
1986    if (oldStatus != status) {
1987        ALOGV("%s: Status has changed for camera ID %d from 0x%x to 0x%x",
1988              __FUNCTION__, cameraId, (uint32_t)oldStatus, (uint32_t)status);
1989
1990        if (oldStatus == ICameraServiceListener::STATUS_NOT_PRESENT &&
1991            (status != ICameraServiceListener::STATUS_PRESENT &&
1992             status != ICameraServiceListener::STATUS_ENUMERATING)) {
1993
1994            ALOGW("%s: From NOT_PRESENT can only transition into PRESENT"
1995                  " or ENUMERATING", __FUNCTION__);
1996            mStatusList[cameraId] = oldStatus;
1997            return;
1998        }
1999
2000        if (rejectSourceStates != NULL) {
2001            const StatusVector &rejectList = *rejectSourceStates;
2002            StatusVector::const_iterator it = rejectList.begin();
2003
2004            /**
2005             * Sometimes we want to conditionally do a transition.
2006             * For example if a client disconnects, we want to go to PRESENT
2007             * only if we weren't already in NOT_PRESENT or ENUMERATING.
2008             */
2009            for (; it != rejectList.end(); ++it) {
2010                if (oldStatus == *it) {
2011                    ALOGV("%s: Rejecting status transition for Camera ID %d, "
2012                          " since the source state was was in one of the bad "
2013                          " states.", __FUNCTION__, cameraId);
2014                    mStatusList[cameraId] = oldStatus;
2015                    return;
2016                }
2017            }
2018        }
2019
2020        /**
2021          * ProClients lose their exclusive lock.
2022          * - Done before the CameraClient can initialize the HAL device,
2023          *   since we want to be able to close it before they get to initialize
2024          */
2025        if (status == ICameraServiceListener::STATUS_NOT_AVAILABLE) {
2026            Vector<wp<ProClient> > proClients(mProClientList[cameraId]);
2027            Vector<wp<ProClient> >::const_iterator it;
2028
2029            for (it = proClients.begin(); it != proClients.end(); ++it) {
2030                sp<ProClient> proCl = it->promote();
2031                if (proCl.get() != NULL) {
2032                    proCl->onExclusiveLockStolen();
2033                }
2034            }
2035        }
2036
2037        if (status == ICameraServiceListener::STATUS_NOT_PRESENT ||
2038            status == ICameraServiceListener::STATUS_NOT_AVAILABLE) {
2039            // update torch status to not available when the camera device
2040            // becomes not present or not available.
2041            onTorchStatusChanged(String8::format("%d", cameraId),
2042                    ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE);
2043        } else if (status == ICameraServiceListener::STATUS_PRESENT) {
2044            // update torch status to available when the camera device becomes
2045            // present or available
2046            onTorchStatusChanged(String8::format("%d", cameraId),
2047                    ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF);
2048        }
2049
2050        Vector<sp<ICameraServiceListener> >::const_iterator it;
2051        for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
2052            (*it)->onStatusChanged(status, cameraId);
2053        }
2054    }
2055}
2056
2057ICameraServiceListener::Status CameraService::getStatus(int cameraId) const {
2058    if (cameraId < 0 || cameraId >= MAX_CAMERAS) {
2059        ALOGE("%s: Invalid camera ID %d", __FUNCTION__, cameraId);
2060        return ICameraServiceListener::STATUS_UNKNOWN;
2061    }
2062
2063    Mutex::Autolock al(mStatusMutex);
2064    return mStatusList[cameraId];
2065}
2066
2067status_t CameraService::getTorchStatusLocked(
2068        const String8& cameraId,
2069        ICameraServiceListener::TorchStatus *status) const {
2070    if (!status) {
2071        return BAD_VALUE;
2072    }
2073    ssize_t index = mTorchStatusMap.indexOfKey(cameraId);
2074    if (index == NAME_NOT_FOUND) {
2075        // invalid camera ID or the camera doesn't have a flash unit
2076        return NAME_NOT_FOUND;
2077    }
2078
2079    *status = mTorchStatusMap.valueAt(index);
2080    return OK;
2081}
2082
2083status_t CameraService::setTorchStatusLocked(const String8& cameraId,
2084        ICameraServiceListener::TorchStatus status) {
2085    ssize_t index = mTorchStatusMap.indexOfKey(cameraId);
2086    if (index == NAME_NOT_FOUND) {
2087        return BAD_VALUE;
2088    }
2089    ICameraServiceListener::TorchStatus& item =
2090            mTorchStatusMap.editValueAt(index);
2091    item = status;
2092
2093    return OK;
2094}
2095
2096}; // namespace android
2097