CameraService.cpp revision d231fd61ca94441183abda9766ce6906a5b4c3cf
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::filterGetInfoErrorCode(status_t err) {
500    switch(err) {
501        case NO_ERROR:
502        case -EINVAL:
503            return err;
504        default:
505            break;
506    }
507    return -ENODEV;
508}
509
510bool CameraService::setUpVendorTags() {
511    vendor_tag_ops_t vOps = vendor_tag_ops_t();
512
513    // Check if vendor operations have been implemented
514    if (!mModule->isVendorTagDefined()) {
515        ALOGI("%s: No vendor tags defined for this device.", __FUNCTION__);
516        return false;
517    }
518
519    ATRACE_BEGIN("camera3->get_metadata_vendor_tag_ops");
520    mModule->getVendorTagOps(&vOps);
521    ATRACE_END();
522
523    // Ensure all vendor operations are present
524    if (vOps.get_tag_count == NULL || vOps.get_all_tags == NULL ||
525            vOps.get_section_name == NULL || vOps.get_tag_name == NULL ||
526            vOps.get_tag_type == NULL) {
527        ALOGE("%s: Vendor tag operations not fully defined. Ignoring definitions."
528               , __FUNCTION__);
529        return false;
530    }
531
532    // Read all vendor tag definitions into a descriptor
533    sp<VendorTagDescriptor> desc;
534    status_t res;
535    if ((res = VendorTagDescriptor::createDescriptorFromOps(&vOps, /*out*/desc))
536            != OK) {
537        ALOGE("%s: Could not generate descriptor from vendor tag operations,"
538              "received error %s (%d). Camera clients will not be able to use"
539              "vendor tags", __FUNCTION__, strerror(res), res);
540        return false;
541    }
542
543    // Set the global descriptor to use with camera metadata
544    VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
545    return true;
546}
547
548status_t CameraService::initializeShimMetadata(int cameraId) {
549    int pid = getCallingPid();
550    int uid = getCallingUid();
551    status_t ret = validateConnect(cameraId, uid);
552    if (ret != OK) {
553        // Error already logged by callee
554        return ret;
555    }
556
557    bool needsNewClient = false;
558    sp<Client> client;
559
560    String16 internalPackageName("media");
561    {   // Scope for service lock
562        Mutex::Autolock lock(mServiceLock);
563        if (mClient[cameraId] != NULL) {
564            client = static_cast<Client*>(mClient[cameraId].promote().get());
565        }
566        if (client == NULL) {
567            needsNewClient = true;
568            ret = connectHelperLocked(/*out*/client,
569                                      /*cameraClient*/NULL, // Empty binder callbacks
570                                      cameraId,
571                                      internalPackageName,
572                                      uid,
573                                      pid);
574
575            if (ret != OK) {
576                // Error already logged by callee
577                return ret;
578            }
579        }
580
581        if (client == NULL) {
582            ALOGE("%s: Could not connect to client camera device.", __FUNCTION__);
583            return BAD_VALUE;
584        }
585
586        String8 rawParams = client->getParameters();
587        CameraParameters params(rawParams);
588        mShimParams.add(cameraId, params);
589    }
590
591    // Close client if one was opened solely for this call
592    if (needsNewClient) {
593        client->disconnect();
594    }
595    return OK;
596}
597
598status_t CameraService::getLegacyParametersLazy(int cameraId,
599        /*out*/
600        CameraParameters* parameters) {
601
602    ALOGV("%s: for cameraId: %d", __FUNCTION__, cameraId);
603
604    status_t ret = 0;
605
606    if (parameters == NULL) {
607        ALOGE("%s: parameters must not be null", __FUNCTION__);
608        return BAD_VALUE;
609    }
610
611    ssize_t index = -1;
612    {   // Scope for service lock
613        Mutex::Autolock lock(mServiceLock);
614        index = mShimParams.indexOfKey(cameraId);
615        // Release service lock so initializeShimMetadata can be called correctly.
616
617        if (index >= 0) {
618            *parameters = mShimParams[index];
619        }
620    }
621
622    if (index < 0) {
623        int64_t token = IPCThreadState::self()->clearCallingIdentity();
624        ret = initializeShimMetadata(cameraId);
625        IPCThreadState::self()->restoreCallingIdentity(token);
626        if (ret != OK) {
627            // Error already logged by callee
628            return ret;
629        }
630
631        {   // Scope for service lock
632            Mutex::Autolock lock(mServiceLock);
633            index = mShimParams.indexOfKey(cameraId);
634
635            LOG_ALWAYS_FATAL_IF(index < 0, "index should have been initialized");
636
637            *parameters = mShimParams[index];
638        }
639    }
640
641    return OK;
642}
643
644status_t CameraService::validateConnect(int cameraId,
645                                    /*inout*/
646                                    int& clientUid) const {
647
648    int callingPid = getCallingPid();
649
650    if (clientUid == USE_CALLING_UID) {
651        clientUid = getCallingUid();
652    } else {
653        // We only trust our own process to forward client UIDs
654        if (callingPid != getpid()) {
655            ALOGE("CameraService::connect X (pid %d) rejected (don't trust clientUid)",
656                    callingPid);
657            return PERMISSION_DENIED;
658        }
659    }
660
661    if (!mModule) {
662        ALOGE("Camera HAL module not loaded");
663        return -ENODEV;
664    }
665
666    if (cameraId < 0 || cameraId >= mNumberOfCameras) {
667        ALOGE("CameraService::connect X (pid %d) rejected (invalid cameraId %d).",
668            callingPid, cameraId);
669        return -ENODEV;
670    }
671
672    char value[PROPERTY_VALUE_MAX];
673    char key[PROPERTY_KEY_MAX];
674    int clientUserId = multiuser_get_user_id(clientUid);
675    snprintf(key, PROPERTY_KEY_MAX, "sys.secpolicy.camera.off_%d", clientUserId);
676    property_get(key, value, "0");
677    if (strcmp(value, "1") == 0) {
678        // Camera is disabled by DevicePolicyManager.
679        ALOGI("Camera is disabled. connect X (pid %d) rejected", callingPid);
680        return -EACCES;
681    }
682
683    ICameraServiceListener::Status currentStatus = getStatus(cameraId);
684    if (currentStatus == ICameraServiceListener::STATUS_NOT_PRESENT) {
685        ALOGI("Camera is not plugged in,"
686               " connect X (pid %d) rejected", callingPid);
687        return -ENODEV;
688    } else if (currentStatus == ICameraServiceListener::STATUS_ENUMERATING) {
689        ALOGI("Camera is enumerating,"
690               " connect X (pid %d) rejected", callingPid);
691        return -EBUSY;
692    }
693    // Else don't check for STATUS_NOT_AVAILABLE.
694    //  -- It's done implicitly in canConnectUnsafe /w the mBusy array
695
696    return OK;
697}
698
699bool CameraService::canConnectUnsafe(int cameraId,
700                                     const String16& clientPackageName,
701                                     const sp<IBinder>& remoteCallback,
702                                     sp<BasicClient> &client) {
703    String8 clientName8(clientPackageName);
704    int callingPid = getCallingPid();
705
706    if (mClient[cameraId] != 0) {
707        client = mClient[cameraId].promote();
708        if (client != 0) {
709            if (remoteCallback == client->getRemote()) {
710                LOG1("CameraService::connect X (pid %d) (the same client)",
711                     callingPid);
712                return true;
713            } else {
714                // TODOSC: need to support 1 regular client,
715                // multiple shared clients here
716                ALOGW("CameraService::connect X (pid %d) rejected"
717                      " (existing client).", callingPid);
718                return false;
719            }
720        }
721        mClient[cameraId].clear();
722    }
723
724    /*
725    mBusy is set to false as the last step of the Client destructor,
726    after which it is guaranteed that the Client destructor has finished (
727    including any inherited destructors)
728
729    We only need this for a Client subclasses since we don't allow
730    multiple Clents to be opened concurrently, but multiple BasicClient
731    would be fine
732    */
733    if (mBusy[cameraId]) {
734        ALOGW("CameraService::connect X (pid %d, \"%s\") rejected"
735                " (camera %d is still busy).", callingPid,
736                clientName8.string(), cameraId);
737        return false;
738    }
739
740    return true;
741}
742
743status_t CameraService::connectHelperLocked(
744        /*out*/
745        sp<Client>& client,
746        /*in*/
747        const sp<ICameraClient>& cameraClient,
748        int cameraId,
749        const String16& clientPackageName,
750        int clientUid,
751        int callingPid,
752        int halVersion,
753        bool legacyMode) {
754
755    // give flashlight a chance to close devices if necessary.
756    mFlashlight->prepareDeviceOpen(String8::format("%d", cameraId));
757
758    int facing = -1;
759    int deviceVersion = getDeviceVersion(cameraId, &facing);
760
761    if (halVersion < 0 || halVersion == deviceVersion) {
762        // Default path: HAL version is unspecified by caller, create CameraClient
763        // based on device version reported by the HAL.
764        switch(deviceVersion) {
765          case CAMERA_DEVICE_API_VERSION_1_0:
766            client = new CameraClient(this, cameraClient,
767                    clientPackageName, cameraId,
768                    facing, callingPid, clientUid, getpid(), legacyMode);
769            break;
770          case CAMERA_DEVICE_API_VERSION_2_0:
771          case CAMERA_DEVICE_API_VERSION_2_1:
772          case CAMERA_DEVICE_API_VERSION_3_0:
773          case CAMERA_DEVICE_API_VERSION_3_1:
774          case CAMERA_DEVICE_API_VERSION_3_2:
775            client = new Camera2Client(this, cameraClient,
776                    clientPackageName, cameraId,
777                    facing, callingPid, clientUid, getpid(), legacyMode);
778            break;
779          case -1:
780            ALOGE("Invalid camera id %d", cameraId);
781            return BAD_VALUE;
782          default:
783            ALOGE("Unknown camera device HAL version: %d", deviceVersion);
784            return INVALID_OPERATION;
785        }
786    } else {
787        // A particular HAL version is requested by caller. Create CameraClient
788        // based on the requested HAL version.
789        if (deviceVersion > CAMERA_DEVICE_API_VERSION_1_0 &&
790            halVersion == CAMERA_DEVICE_API_VERSION_1_0) {
791            // Only support higher HAL version device opened as HAL1.0 device.
792            client = new CameraClient(this, cameraClient,
793                    clientPackageName, cameraId,
794                    facing, callingPid, clientUid, getpid(), legacyMode);
795        } else {
796            // Other combinations (e.g. HAL3.x open as HAL2.x) are not supported yet.
797            ALOGE("Invalid camera HAL version %x: HAL %x device can only be"
798                    " opened as HAL %x device", halVersion, deviceVersion,
799                    CAMERA_DEVICE_API_VERSION_1_0);
800            return INVALID_OPERATION;
801        }
802    }
803
804    status_t status = connectFinishUnsafe(client, client->getRemote());
805    if (status != OK) {
806        // this is probably not recoverable.. maybe the client can try again
807        return status;
808    }
809
810    mClient[cameraId] = client;
811    LOG1("CameraService::connect X (id %d, this pid is %d)", cameraId,
812         getpid());
813
814    return OK;
815}
816
817status_t CameraService::connect(
818        const sp<ICameraClient>& cameraClient,
819        int cameraId,
820        const String16& clientPackageName,
821        int clientUid,
822        /*out*/
823        sp<ICamera>& device) {
824
825    String8 clientName8(clientPackageName);
826    int callingPid = getCallingPid();
827
828    LOG1("CameraService::connect E (pid %d \"%s\", id %d)", callingPid,
829            clientName8.string(), cameraId);
830
831    status_t status = validateConnect(cameraId, /*inout*/clientUid);
832    if (status != OK) {
833        return status;
834    }
835
836
837    sp<Client> client;
838    {
839        Mutex::Autolock lock(mServiceLock);
840        sp<BasicClient> clientTmp;
841        if (!canConnectUnsafe(cameraId, clientPackageName,
842                              IInterface::asBinder(cameraClient),
843                              /*out*/clientTmp)) {
844            return -EBUSY;
845        } else if (client.get() != NULL) {
846            device = static_cast<Client*>(clientTmp.get());
847            return OK;
848        }
849
850        status = connectHelperLocked(/*out*/client,
851                                     cameraClient,
852                                     cameraId,
853                                     clientPackageName,
854                                     clientUid,
855                                     callingPid);
856        if (status != OK) {
857            return status;
858        }
859
860    }
861    // important: release the mutex here so the client can call back
862    //    into the service from its destructor (can be at the end of the call)
863
864    device = client;
865    return OK;
866}
867
868status_t CameraService::connectLegacy(
869        const sp<ICameraClient>& cameraClient,
870        int cameraId, int halVersion,
871        const String16& clientPackageName,
872        int clientUid,
873        /*out*/
874        sp<ICamera>& device) {
875
876    int apiVersion = mModule->getRawModule()->module_api_version;
877    if (halVersion != CAMERA_HAL_API_VERSION_UNSPECIFIED &&
878            apiVersion < CAMERA_MODULE_API_VERSION_2_3) {
879        /*
880         * Either the HAL version is unspecified in which case this just creates
881         * a camera client selected by the latest device version, or
882         * it's a particular version in which case the HAL must supported
883         * the open_legacy call
884         */
885        ALOGE("%s: camera HAL module version %x doesn't support connecting to legacy HAL devices!",
886                __FUNCTION__, apiVersion);
887        return INVALID_OPERATION;
888    }
889
890    String8 clientName8(clientPackageName);
891    int callingPid = getCallingPid();
892
893    LOG1("CameraService::connect legacy E (pid %d \"%s\", id %d)", callingPid,
894            clientName8.string(), cameraId);
895
896    status_t status = validateConnect(cameraId, /*inout*/clientUid);
897    if (status != OK) {
898        return status;
899    }
900
901    sp<Client> client;
902    {
903        Mutex::Autolock lock(mServiceLock);
904        sp<BasicClient> clientTmp;
905        if (!canConnectUnsafe(cameraId, clientPackageName,
906                              IInterface::asBinder(cameraClient),
907                              /*out*/clientTmp)) {
908            return -EBUSY;
909        } else if (client.get() != NULL) {
910            device = static_cast<Client*>(clientTmp.get());
911            return OK;
912        }
913
914        status = connectHelperLocked(/*out*/client,
915                                     cameraClient,
916                                     cameraId,
917                                     clientPackageName,
918                                     clientUid,
919                                     callingPid,
920                                     halVersion,
921                                     /*legacyMode*/true);
922        if (status != OK) {
923            return status;
924        }
925
926    }
927    // important: release the mutex here so the client can call back
928    //    into the service from its destructor (can be at the end of the call)
929
930    device = client;
931    return OK;
932}
933
934bool CameraService::validCameraIdForSetTorchMode(const String8& cameraId) {
935    // invalid string for int
936    if (cameraId.string() == NULL) {
937        return false;
938    }
939    errno = 0;
940    char *endptr;
941    long id = strtol(cameraId.string(), &endptr, 10); // base 10
942    if (errno || id > INT_MAX || id < INT_MIN || *endptr != 0) {
943        return false;
944    }
945
946    // id matches one of the plugged-in devices?
947    ICameraServiceListener::Status deviceStatus = getStatus(id);
948    if (deviceStatus != ICameraServiceListener::STATUS_PRESENT &&
949            deviceStatus != ICameraServiceListener::STATUS_NOT_AVAILABLE) {
950        return false;
951    }
952
953    return true;
954}
955
956status_t CameraService::setTorchMode(const String16& cameraId, bool enabled,
957        const sp<IBinder>& clientBinder) {
958    if (enabled && clientBinder == NULL) {
959        ALOGE("%s: torch client binder is NULL", __FUNCTION__);
960        return -EINVAL;
961    }
962
963    String8 id = String8(cameraId.string());
964
965    // verify id is valid.
966    if (validCameraIdForSetTorchMode(id) == false) {
967        ALOGE("%s: camera id is invalid %s", id.string());
968        return -EINVAL;
969    }
970
971    {
972        Mutex::Autolock al(mTorchStatusMutex);
973        ICameraServiceListener::TorchStatus status;
974        status_t res = getTorchStatusLocked(id, &status);
975        if (res) {
976            ALOGE("%s: getting current torch status failed for camera %s",
977                    __FUNCTION__, id.string());
978            return -EINVAL;
979        }
980
981        if (status == ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE) {
982            if (getStatus(atoi(id.string())) ==
983                        ICameraServiceListener::STATUS_NOT_AVAILABLE) {
984                ALOGE("%s: torch mode of camera %s is not available because "
985                        "camera is in use", __FUNCTION__, id.string());
986                return -EBUSY;
987            } else {
988                ALOGE("%s: torch mode of camera %s is not available due to "
989                        "insufficient resources", __FUNCTION__, id.string());
990                return -EUSERS;
991            }
992        }
993    }
994
995    status_t res = mFlashlight->setTorchMode(id, enabled);
996    if (res) {
997        ALOGE("%s: setting torch mode of camera %s to %d failed. %s (%d)",
998                __FUNCTION__, id.string(), enabled, strerror(-res), res);
999        return res;
1000    }
1001
1002    {
1003        // update the link to client's death
1004        Mutex::Autolock al(mTorchClientMapMutex);
1005        ssize_t index = mTorchClientMap.indexOfKey(id);
1006        if (enabled) {
1007            if (index == NAME_NOT_FOUND) {
1008                mTorchClientMap.add(id, clientBinder);
1009            } else {
1010                const sp<IBinder> oldBinder = mTorchClientMap.valueAt(index);
1011                oldBinder->unlinkToDeath(this);
1012
1013                mTorchClientMap.replaceValueAt(index, clientBinder);
1014            }
1015            clientBinder->linkToDeath(this);
1016        } else if (index != NAME_NOT_FOUND) {
1017            sp<IBinder> oldBinder = mTorchClientMap.valueAt(index);
1018            oldBinder->unlinkToDeath(this);
1019        }
1020    }
1021
1022    return OK;
1023}
1024
1025status_t CameraService::connectFinishUnsafe(const sp<BasicClient>& client,
1026                                            const sp<IBinder>& remoteCallback) {
1027    status_t status = client->initialize(mModule);
1028    if (status != OK) {
1029        ALOGE("%s: Could not initialize client from HAL module.", __FUNCTION__);
1030        return status;
1031    }
1032    if (remoteCallback != NULL) {
1033        remoteCallback->linkToDeath(this);
1034    }
1035
1036    return OK;
1037}
1038
1039status_t CameraService::connectPro(
1040                                        const sp<IProCameraCallbacks>& cameraCb,
1041                                        int cameraId,
1042                                        const String16& clientPackageName,
1043                                        int clientUid,
1044                                        /*out*/
1045                                        sp<IProCameraUser>& device)
1046{
1047    if (cameraCb == 0) {
1048        ALOGE("%s: Callback must not be null", __FUNCTION__);
1049        return BAD_VALUE;
1050    }
1051
1052    String8 clientName8(clientPackageName);
1053    int callingPid = getCallingPid();
1054
1055    LOG1("CameraService::connectPro E (pid %d \"%s\", id %d)", callingPid,
1056            clientName8.string(), cameraId);
1057    status_t status = validateConnect(cameraId, /*inout*/clientUid);
1058    if (status != OK) {
1059        return status;
1060    }
1061
1062    sp<ProClient> client;
1063    {
1064        Mutex::Autolock lock(mServiceLock);
1065        {
1066            sp<BasicClient> client;
1067            if (!canConnectUnsafe(cameraId, clientPackageName,
1068                                  IInterface::asBinder(cameraCb),
1069                                  /*out*/client)) {
1070                return -EBUSY;
1071            }
1072        }
1073
1074        int facing = -1;
1075        int deviceVersion = getDeviceVersion(cameraId, &facing);
1076
1077        switch(deviceVersion) {
1078          case CAMERA_DEVICE_API_VERSION_1_0:
1079            ALOGE("Camera id %d uses HALv1, doesn't support ProCamera",
1080                  cameraId);
1081            return -EOPNOTSUPP;
1082            break;
1083          case CAMERA_DEVICE_API_VERSION_2_0:
1084          case CAMERA_DEVICE_API_VERSION_2_1:
1085          case CAMERA_DEVICE_API_VERSION_3_0:
1086          case CAMERA_DEVICE_API_VERSION_3_1:
1087          case CAMERA_DEVICE_API_VERSION_3_2:
1088            client = new ProCamera2Client(this, cameraCb, clientPackageName,
1089                    cameraId, facing, callingPid, clientUid, getpid());
1090            break;
1091          case -1:
1092            ALOGE("Invalid camera id %d", cameraId);
1093            return BAD_VALUE;
1094          default:
1095            ALOGE("Unknown camera device HAL version: %d", deviceVersion);
1096            return INVALID_OPERATION;
1097        }
1098
1099        status_t status = connectFinishUnsafe(client, client->getRemote());
1100        if (status != OK) {
1101            return status;
1102        }
1103
1104        mProClientList[cameraId].push(client);
1105
1106        LOG1("CameraService::connectPro X (id %d, this pid is %d)", cameraId,
1107                getpid());
1108    }
1109    // important: release the mutex here so the client can call back
1110    //    into the service from its destructor (can be at the end of the call)
1111    device = client;
1112    return OK;
1113}
1114
1115status_t CameraService::connectDevice(
1116        const sp<ICameraDeviceCallbacks>& cameraCb,
1117        int cameraId,
1118        const String16& clientPackageName,
1119        int clientUid,
1120        /*out*/
1121        sp<ICameraDeviceUser>& device)
1122{
1123
1124    String8 clientName8(clientPackageName);
1125    int callingPid = getCallingPid();
1126
1127    LOG1("CameraService::connectDevice E (pid %d \"%s\", id %d)", callingPid,
1128            clientName8.string(), cameraId);
1129
1130    status_t status = validateConnect(cameraId, /*inout*/clientUid);
1131    if (status != OK) {
1132        return status;
1133    }
1134
1135    sp<CameraDeviceClient> client;
1136    {
1137        Mutex::Autolock lock(mServiceLock);
1138        {
1139            sp<BasicClient> client;
1140            if (!canConnectUnsafe(cameraId, clientPackageName,
1141                                  IInterface::asBinder(cameraCb),
1142                                  /*out*/client)) {
1143                return -EBUSY;
1144            }
1145        }
1146
1147        int facing = -1;
1148        int deviceVersion = getDeviceVersion(cameraId, &facing);
1149
1150        // give flashlight a chance to close devices if necessary.
1151        mFlashlight->prepareDeviceOpen(String8::format("%d", cameraId));
1152
1153        switch(deviceVersion) {
1154          case CAMERA_DEVICE_API_VERSION_1_0:
1155            ALOGW("Camera using old HAL version: %d", deviceVersion);
1156            return -EOPNOTSUPP;
1157           // TODO: don't allow 2.0  Only allow 2.1 and higher
1158          case CAMERA_DEVICE_API_VERSION_2_0:
1159          case CAMERA_DEVICE_API_VERSION_2_1:
1160          case CAMERA_DEVICE_API_VERSION_3_0:
1161          case CAMERA_DEVICE_API_VERSION_3_1:
1162          case CAMERA_DEVICE_API_VERSION_3_2:
1163            client = new CameraDeviceClient(this, cameraCb, clientPackageName,
1164                    cameraId, facing, callingPid, clientUid, getpid());
1165            break;
1166          case -1:
1167            ALOGE("Invalid camera id %d", cameraId);
1168            return BAD_VALUE;
1169          default:
1170            ALOGE("Unknown camera device HAL version: %d", deviceVersion);
1171            return INVALID_OPERATION;
1172        }
1173
1174        status_t status = connectFinishUnsafe(client, client->getRemote());
1175        if (status != OK) {
1176            // this is probably not recoverable.. maybe the client can try again
1177            return status;
1178        }
1179
1180        LOG1("CameraService::connectDevice X (id %d, this pid is %d)", cameraId,
1181                getpid());
1182
1183        mClient[cameraId] = client;
1184    }
1185    // important: release the mutex here so the client can call back
1186    //    into the service from its destructor (can be at the end of the call)
1187
1188    device = client;
1189    return OK;
1190}
1191
1192
1193status_t CameraService::addListener(
1194                                const sp<ICameraServiceListener>& listener) {
1195    ALOGV("%s: Add listener %p", __FUNCTION__, listener.get());
1196
1197    if (listener == 0) {
1198        ALOGE("%s: Listener must not be null", __FUNCTION__);
1199        return BAD_VALUE;
1200    }
1201
1202    Mutex::Autolock lock(mServiceLock);
1203
1204    Vector<sp<ICameraServiceListener> >::iterator it, end;
1205    for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
1206        if (IInterface::asBinder(*it) == IInterface::asBinder(listener)) {
1207            ALOGW("%s: Tried to add listener %p which was already subscribed",
1208                  __FUNCTION__, listener.get());
1209            return ALREADY_EXISTS;
1210        }
1211    }
1212
1213    mListenerList.push_back(listener);
1214
1215    /* Immediately signal current status to this listener only */
1216    {
1217        Mutex::Autolock m(mStatusMutex) ;
1218        int numCams = getNumberOfCameras();
1219        for (int i = 0; i < numCams; ++i) {
1220            listener->onStatusChanged(mStatusList[i], i);
1221        }
1222    }
1223
1224    /* Immediately signal current torch status to this listener only */
1225    {
1226        Mutex::Autolock al(mTorchStatusMutex);
1227        for (size_t i = 0; i < mTorchStatusMap.size(); i++ ) {
1228            String16 id = String16(mTorchStatusMap.keyAt(i).string());
1229            listener->onTorchStatusChanged(mTorchStatusMap.valueAt(i), id);
1230        }
1231
1232    }
1233
1234    return OK;
1235}
1236status_t CameraService::removeListener(
1237                                const sp<ICameraServiceListener>& listener) {
1238    ALOGV("%s: Remove listener %p", __FUNCTION__, listener.get());
1239
1240    if (listener == 0) {
1241        ALOGE("%s: Listener must not be null", __FUNCTION__);
1242        return BAD_VALUE;
1243    }
1244
1245    Mutex::Autolock lock(mServiceLock);
1246
1247    Vector<sp<ICameraServiceListener> >::iterator it;
1248    for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
1249        if (IInterface::asBinder(*it) == IInterface::asBinder(listener)) {
1250            mListenerList.erase(it);
1251            return OK;
1252        }
1253    }
1254
1255    ALOGW("%s: Tried to remove a listener %p which was not subscribed",
1256          __FUNCTION__, listener.get());
1257
1258    return BAD_VALUE;
1259}
1260
1261status_t CameraService::getLegacyParameters(
1262            int cameraId,
1263            /*out*/
1264            String16* parameters) {
1265    ALOGV("%s: for camera ID = %d", __FUNCTION__, cameraId);
1266
1267    if (parameters == NULL) {
1268        ALOGE("%s: parameters must not be null", __FUNCTION__);
1269        return BAD_VALUE;
1270    }
1271
1272    status_t ret = 0;
1273
1274    CameraParameters shimParams;
1275    if ((ret = getLegacyParametersLazy(cameraId, /*out*/&shimParams)) != OK) {
1276        // Error logged by caller
1277        return ret;
1278    }
1279
1280    String8 shimParamsString8 = shimParams.flatten();
1281    String16 shimParamsString16 = String16(shimParamsString8);
1282
1283    *parameters = shimParamsString16;
1284
1285    return OK;
1286}
1287
1288status_t CameraService::supportsCameraApi(int cameraId, int apiVersion) {
1289    ALOGV("%s: for camera ID = %d", __FUNCTION__, cameraId);
1290
1291    switch (apiVersion) {
1292        case API_VERSION_1:
1293        case API_VERSION_2:
1294            break;
1295        default:
1296            ALOGE("%s: Bad API version %d", __FUNCTION__, apiVersion);
1297            return BAD_VALUE;
1298    }
1299
1300    int facing = -1;
1301    int deviceVersion = getDeviceVersion(cameraId, &facing);
1302
1303    switch(deviceVersion) {
1304      case CAMERA_DEVICE_API_VERSION_1_0:
1305      case CAMERA_DEVICE_API_VERSION_2_0:
1306      case CAMERA_DEVICE_API_VERSION_2_1:
1307      case CAMERA_DEVICE_API_VERSION_3_0:
1308      case CAMERA_DEVICE_API_VERSION_3_1:
1309        if (apiVersion == API_VERSION_2) {
1310            ALOGV("%s: Camera id %d uses HAL prior to HAL3.2, doesn't support api2 without shim",
1311                    __FUNCTION__, cameraId);
1312            return -EOPNOTSUPP;
1313        } else { // if (apiVersion == API_VERSION_1) {
1314            ALOGV("%s: Camera id %d uses older HAL before 3.2, but api1 is always supported",
1315                    __FUNCTION__, cameraId);
1316            return OK;
1317        }
1318      case CAMERA_DEVICE_API_VERSION_3_2:
1319        ALOGV("%s: Camera id %d uses HAL3.2 or newer, supports api1/api2 directly",
1320                __FUNCTION__, cameraId);
1321        return OK;
1322      case -1:
1323        ALOGE("%s: Invalid camera id %d", __FUNCTION__, cameraId);
1324        return BAD_VALUE;
1325      default:
1326        ALOGE("%s: Unknown camera device HAL version: %d", __FUNCTION__, deviceVersion);
1327        return INVALID_OPERATION;
1328    }
1329
1330    return OK;
1331}
1332
1333void CameraService::removeClientByRemote(const wp<IBinder>& remoteBinder) {
1334    int callingPid = getCallingPid();
1335    LOG1("CameraService::removeClientByRemote E (pid %d)", callingPid);
1336
1337    // Declare this before the lock to make absolutely sure the
1338    // destructor won't be called with the lock held.
1339    Mutex::Autolock lock(mServiceLock);
1340
1341    int outIndex;
1342    sp<BasicClient> client = findClientUnsafe(remoteBinder, outIndex);
1343
1344    if (client != 0) {
1345        // Found our camera, clear and leave.
1346        LOG1("removeClient: clear camera %d", outIndex);
1347
1348        sp<IBinder> remote = client->getRemote();
1349        if (remote != NULL) {
1350            remote->unlinkToDeath(this);
1351        }
1352
1353        mClient[outIndex].clear();
1354    } else {
1355
1356        sp<ProClient> clientPro = findProClientUnsafe(remoteBinder);
1357
1358        if (clientPro != NULL) {
1359            // Found our camera, clear and leave.
1360            LOG1("removeClient: clear pro %p", clientPro.get());
1361
1362            IInterface::asBinder(clientPro->getRemoteCallback())->unlinkToDeath(this);
1363        }
1364    }
1365
1366    LOG1("CameraService::removeClientByRemote X (pid %d)", callingPid);
1367}
1368
1369sp<CameraService::ProClient> CameraService::findProClientUnsafe(
1370                        const wp<IBinder>& cameraCallbacksRemote)
1371{
1372    sp<ProClient> clientPro;
1373
1374    for (int i = 0; i < mNumberOfCameras; ++i) {
1375        Vector<size_t> removeIdx;
1376
1377        for (size_t j = 0; j < mProClientList[i].size(); ++j) {
1378            wp<ProClient> cl = mProClientList[i][j];
1379
1380            sp<ProClient> clStrong = cl.promote();
1381            if (clStrong != NULL && clStrong->getRemote() == cameraCallbacksRemote) {
1382                clientPro = clStrong;
1383                break;
1384            } else if (clStrong == NULL) {
1385                // mark to clean up dead ptr
1386                removeIdx.push(j);
1387            }
1388        }
1389
1390        // remove stale ptrs (in reverse so the indices dont change)
1391        for (ssize_t j = (ssize_t)removeIdx.size() - 1; j >= 0; --j) {
1392            mProClientList[i].removeAt(removeIdx[j]);
1393        }
1394
1395    }
1396
1397    return clientPro;
1398}
1399
1400sp<CameraService::BasicClient> CameraService::findClientUnsafe(
1401                        const wp<IBinder>& cameraClient, int& outIndex) {
1402    sp<BasicClient> client;
1403
1404    for (int i = 0; i < mNumberOfCameras; i++) {
1405
1406        // This happens when we have already disconnected (or this is
1407        // just another unused camera).
1408        if (mClient[i] == 0) continue;
1409
1410        // Promote mClient. It can fail if we are called from this path:
1411        // Client::~Client() -> disconnect() -> removeClientByRemote().
1412        client = mClient[i].promote();
1413
1414        // Clean up stale client entry
1415        if (client == NULL) {
1416            mClient[i].clear();
1417            continue;
1418        }
1419
1420        if (cameraClient == client->getRemote()) {
1421            // Found our camera
1422            outIndex = i;
1423            return client;
1424        }
1425    }
1426
1427    outIndex = -1;
1428    return NULL;
1429}
1430
1431CameraService::BasicClient* CameraService::getClientByIdUnsafe(int cameraId) {
1432    if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
1433    return mClient[cameraId].unsafe_get();
1434}
1435
1436Mutex* CameraService::getClientLockById(int cameraId) {
1437    if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
1438    return &mClientLock[cameraId];
1439}
1440
1441sp<CameraService::BasicClient> CameraService::getClientByRemote(
1442                                const wp<IBinder>& cameraClient) {
1443
1444    // Declare this before the lock to make absolutely sure the
1445    // destructor won't be called with the lock held.
1446    sp<BasicClient> client;
1447
1448    Mutex::Autolock lock(mServiceLock);
1449
1450    int outIndex;
1451    client = findClientUnsafe(cameraClient, outIndex);
1452
1453    return client;
1454}
1455
1456status_t CameraService::onTransact(
1457    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
1458    // Permission checks
1459    switch (code) {
1460        case BnCameraService::CONNECT:
1461        case BnCameraService::CONNECT_PRO:
1462        case BnCameraService::CONNECT_DEVICE:
1463        case BnCameraService::CONNECT_LEGACY:
1464            const int pid = getCallingPid();
1465            const int self_pid = getpid();
1466            if (pid != self_pid) {
1467                // we're called from a different process, do the real check
1468                if (!checkCallingPermission(
1469                        String16("android.permission.CAMERA"))) {
1470                    const int uid = getCallingUid();
1471                    ALOGE("Permission Denial: "
1472                         "can't use the camera pid=%d, uid=%d", pid, uid);
1473                    return PERMISSION_DENIED;
1474                }
1475            }
1476            break;
1477    }
1478
1479    return BnCameraService::onTransact(code, data, reply, flags);
1480}
1481
1482// The reason we need this busy bit is a new CameraService::connect() request
1483// may come in while the previous Client's destructor has not been run or is
1484// still running. If the last strong reference of the previous Client is gone
1485// but the destructor has not been finished, we should not allow the new Client
1486// to be created because we need to wait for the previous Client to tear down
1487// the hardware first.
1488void CameraService::setCameraBusy(int cameraId) {
1489    android_atomic_write(1, &mBusy[cameraId]);
1490
1491    ALOGV("setCameraBusy cameraId=%d", cameraId);
1492}
1493
1494void CameraService::setCameraFree(int cameraId) {
1495    android_atomic_write(0, &mBusy[cameraId]);
1496
1497    ALOGV("setCameraFree cameraId=%d", cameraId);
1498}
1499
1500// We share the media players for shutter and recording sound for all clients.
1501// A reference count is kept to determine when we will actually release the
1502// media players.
1503
1504MediaPlayer* CameraService::newMediaPlayer(const char *file) {
1505    MediaPlayer* mp = new MediaPlayer();
1506    if (mp->setDataSource(NULL /* httpService */, file, NULL) == NO_ERROR) {
1507        mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE);
1508        mp->prepare();
1509    } else {
1510        ALOGE("Failed to load CameraService sounds: %s", file);
1511        return NULL;
1512    }
1513    return mp;
1514}
1515
1516void CameraService::loadSound() {
1517    Mutex::Autolock lock(mSoundLock);
1518    LOG1("CameraService::loadSound ref=%d", mSoundRef);
1519    if (mSoundRef++) return;
1520
1521    mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
1522    mSoundPlayer[SOUND_RECORDING] = newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");
1523}
1524
1525void CameraService::releaseSound() {
1526    Mutex::Autolock lock(mSoundLock);
1527    LOG1("CameraService::releaseSound ref=%d", mSoundRef);
1528    if (--mSoundRef) return;
1529
1530    for (int i = 0; i < NUM_SOUNDS; i++) {
1531        if (mSoundPlayer[i] != 0) {
1532            mSoundPlayer[i]->disconnect();
1533            mSoundPlayer[i].clear();
1534        }
1535    }
1536}
1537
1538void CameraService::playSound(sound_kind kind) {
1539    LOG1("playSound(%d)", kind);
1540    Mutex::Autolock lock(mSoundLock);
1541    sp<MediaPlayer> player = mSoundPlayer[kind];
1542    if (player != 0) {
1543        player->seekTo(0);
1544        player->start();
1545    }
1546}
1547
1548// ----------------------------------------------------------------------------
1549
1550CameraService::Client::Client(const sp<CameraService>& cameraService,
1551        const sp<ICameraClient>& cameraClient,
1552        const String16& clientPackageName,
1553        int cameraId, int cameraFacing,
1554        int clientPid, uid_t clientUid,
1555        int servicePid) :
1556        CameraService::BasicClient(cameraService,
1557                IInterface::asBinder(cameraClient),
1558                clientPackageName,
1559                cameraId, cameraFacing,
1560                clientPid, clientUid,
1561                servicePid)
1562{
1563    int callingPid = getCallingPid();
1564    LOG1("Client::Client E (pid %d, id %d)", callingPid, cameraId);
1565
1566    mRemoteCallback = cameraClient;
1567
1568    cameraService->setCameraBusy(cameraId);
1569    cameraService->loadSound();
1570
1571    LOG1("Client::Client X (pid %d, id %d)", callingPid, cameraId);
1572}
1573
1574// tear down the client
1575CameraService::Client::~Client() {
1576    ALOGV("~Client");
1577    mDestructionStarted = true;
1578
1579    mCameraService->releaseSound();
1580    // unconditionally disconnect. function is idempotent
1581    Client::disconnect();
1582}
1583
1584CameraService::BasicClient::BasicClient(const sp<CameraService>& cameraService,
1585        const sp<IBinder>& remoteCallback,
1586        const String16& clientPackageName,
1587        int cameraId, int cameraFacing,
1588        int clientPid, uid_t clientUid,
1589        int servicePid):
1590        mClientPackageName(clientPackageName)
1591{
1592    mCameraService = cameraService;
1593    mRemoteBinder = remoteCallback;
1594    mCameraId = cameraId;
1595    mCameraFacing = cameraFacing;
1596    mClientPid = clientPid;
1597    mClientUid = clientUid;
1598    mServicePid = servicePid;
1599    mOpsActive = false;
1600    mDestructionStarted = false;
1601}
1602
1603CameraService::BasicClient::~BasicClient() {
1604    ALOGV("~BasicClient");
1605    mDestructionStarted = true;
1606}
1607
1608void CameraService::BasicClient::disconnect() {
1609    ALOGV("BasicClient::disconnect");
1610    mCameraService->removeClientByRemote(mRemoteBinder);
1611
1612    finishCameraOps();
1613    // client shouldn't be able to call into us anymore
1614    mClientPid = 0;
1615}
1616
1617status_t CameraService::BasicClient::startCameraOps() {
1618    int32_t res;
1619    // Notify app ops that the camera is not available
1620    mOpsCallback = new OpsCallback(this);
1621
1622    {
1623        ALOGV("%s: Start camera ops, package name = %s, client UID = %d",
1624              __FUNCTION__, String8(mClientPackageName).string(), mClientUid);
1625    }
1626
1627    mAppOpsManager.startWatchingMode(AppOpsManager::OP_CAMERA,
1628            mClientPackageName, mOpsCallback);
1629    res = mAppOpsManager.startOp(AppOpsManager::OP_CAMERA,
1630            mClientUid, mClientPackageName);
1631
1632    if (res != AppOpsManager::MODE_ALLOWED) {
1633        ALOGI("Camera %d: Access for \"%s\" has been revoked",
1634                mCameraId, String8(mClientPackageName).string());
1635        return PERMISSION_DENIED;
1636    }
1637
1638    mOpsActive = true;
1639
1640    // Transition device availability listeners from PRESENT -> NOT_AVAILABLE
1641    mCameraService->updateStatus(ICameraServiceListener::STATUS_NOT_AVAILABLE,
1642            mCameraId);
1643
1644    return OK;
1645}
1646
1647status_t CameraService::BasicClient::finishCameraOps() {
1648    // Check if startCameraOps succeeded, and if so, finish the camera op
1649    if (mOpsActive) {
1650        // Notify app ops that the camera is available again
1651        mAppOpsManager.finishOp(AppOpsManager::OP_CAMERA, mClientUid,
1652                mClientPackageName);
1653        mOpsActive = false;
1654
1655        // Notify device availability listeners that this camera is available
1656        // again
1657
1658        StatusVector rejectSourceStates;
1659        rejectSourceStates.push_back(ICameraServiceListener::STATUS_NOT_PRESENT);
1660        rejectSourceStates.push_back(ICameraServiceListener::STATUS_ENUMERATING);
1661
1662        // Transition to PRESENT if the camera is not in either of above 2
1663        // states
1664        mCameraService->updateStatus(ICameraServiceListener::STATUS_PRESENT,
1665                mCameraId,
1666                &rejectSourceStates);
1667
1668        // Notify flashlight that a camera device is closed.
1669        mCameraService->mFlashlight->deviceClosed(
1670                String8::format("%d", mCameraId));
1671    }
1672    // Always stop watching, even if no camera op is active
1673    if (mOpsCallback != NULL) {
1674        mAppOpsManager.stopWatchingMode(mOpsCallback);
1675    }
1676    mOpsCallback.clear();
1677
1678    return OK;
1679}
1680
1681void CameraService::BasicClient::opChanged(int32_t op, const String16& packageName) {
1682    String8 name(packageName);
1683    String8 myName(mClientPackageName);
1684
1685    if (op != AppOpsManager::OP_CAMERA) {
1686        ALOGW("Unexpected app ops notification received: %d", op);
1687        return;
1688    }
1689
1690    int32_t res;
1691    res = mAppOpsManager.checkOp(AppOpsManager::OP_CAMERA,
1692            mClientUid, mClientPackageName);
1693    ALOGV("checkOp returns: %d, %s ", res,
1694            res == AppOpsManager::MODE_ALLOWED ? "ALLOWED" :
1695            res == AppOpsManager::MODE_IGNORED ? "IGNORED" :
1696            res == AppOpsManager::MODE_ERRORED ? "ERRORED" :
1697            "UNKNOWN");
1698
1699    if (res != AppOpsManager::MODE_ALLOWED) {
1700        ALOGI("Camera %d: Access for \"%s\" revoked", mCameraId,
1701                myName.string());
1702        // Reset the client PID to allow server-initiated disconnect,
1703        // and to prevent further calls by client.
1704        mClientPid = getCallingPid();
1705        CaptureResultExtras resultExtras; // a dummy result (invalid)
1706        notifyError(ICameraDeviceCallbacks::ERROR_CAMERA_SERVICE, resultExtras);
1707        disconnect();
1708    }
1709}
1710
1711// ----------------------------------------------------------------------------
1712
1713Mutex* CameraService::Client::getClientLockFromCookie(void* user) {
1714    return gCameraService->getClientLockById((int)(intptr_t) user);
1715}
1716
1717// Provide client pointer for callbacks. Client lock returned from getClientLockFromCookie should
1718// be acquired for this to be safe
1719CameraService::Client* CameraService::Client::getClientFromCookie(void* user) {
1720    BasicClient *basicClient = gCameraService->getClientByIdUnsafe((int)(intptr_t) user);
1721    // OK: only CameraClient calls this, and they already cast anyway.
1722    Client* client = static_cast<Client*>(basicClient);
1723
1724    // This could happen if the Client is in the process of shutting down (the
1725    // last strong reference is gone, but the destructor hasn't finished
1726    // stopping the hardware).
1727    if (client == NULL) return NULL;
1728
1729    // destruction already started, so should not be accessed
1730    if (client->mDestructionStarted) return NULL;
1731
1732    return client;
1733}
1734
1735void CameraService::Client::notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode,
1736        const CaptureResultExtras& resultExtras) {
1737    mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_RELEASED, 0);
1738}
1739
1740// NOTE: function is idempotent
1741void CameraService::Client::disconnect() {
1742    ALOGV("Client::disconnect");
1743    BasicClient::disconnect();
1744    mCameraService->setCameraFree(mCameraId);
1745}
1746
1747CameraService::Client::OpsCallback::OpsCallback(wp<BasicClient> client):
1748        mClient(client) {
1749}
1750
1751void CameraService::Client::OpsCallback::opChanged(int32_t op,
1752        const String16& packageName) {
1753    sp<BasicClient> client = mClient.promote();
1754    if (client != NULL) {
1755        client->opChanged(op, packageName);
1756    }
1757}
1758
1759// ----------------------------------------------------------------------------
1760//                  IProCamera
1761// ----------------------------------------------------------------------------
1762
1763CameraService::ProClient::ProClient(const sp<CameraService>& cameraService,
1764        const sp<IProCameraCallbacks>& remoteCallback,
1765        const String16& clientPackageName,
1766        int cameraId,
1767        int cameraFacing,
1768        int clientPid,
1769        uid_t clientUid,
1770        int servicePid)
1771        : CameraService::BasicClient(cameraService, IInterface::asBinder(remoteCallback),
1772                clientPackageName, cameraId, cameraFacing,
1773                clientPid,  clientUid, servicePid)
1774{
1775    mRemoteCallback = remoteCallback;
1776}
1777
1778CameraService::ProClient::~ProClient() {
1779}
1780
1781void CameraService::ProClient::notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode,
1782        const CaptureResultExtras& resultExtras) {
1783    mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_RELEASED, 0);
1784}
1785
1786// ----------------------------------------------------------------------------
1787
1788static const int kDumpLockRetries = 50;
1789static const int kDumpLockSleep = 60000;
1790
1791static bool tryLock(Mutex& mutex)
1792{
1793    bool locked = false;
1794    for (int i = 0; i < kDumpLockRetries; ++i) {
1795        if (mutex.tryLock() == NO_ERROR) {
1796            locked = true;
1797            break;
1798        }
1799        usleep(kDumpLockSleep);
1800    }
1801    return locked;
1802}
1803
1804status_t CameraService::dump(int fd, const Vector<String16>& args) {
1805    String8 result;
1806    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
1807        result.appendFormat("Permission Denial: "
1808                "can't dump CameraService from pid=%d, uid=%d\n",
1809                getCallingPid(),
1810                getCallingUid());
1811        write(fd, result.string(), result.size());
1812    } else {
1813        bool locked = tryLock(mServiceLock);
1814        // failed to lock - CameraService is probably deadlocked
1815        if (!locked) {
1816            result.append("CameraService may be deadlocked\n");
1817            write(fd, result.string(), result.size());
1818        }
1819
1820        bool hasClient = false;
1821        if (!mModule) {
1822            result = String8::format("No camera module available!\n");
1823            write(fd, result.string(), result.size());
1824            if (locked) mServiceLock.unlock();
1825            return NO_ERROR;
1826        }
1827
1828        const hw_module_t* common = mModule->getRawModule();
1829        result = String8::format("Camera module HAL API version: 0x%x\n", common->hal_api_version);
1830        result.appendFormat("Camera module API version: 0x%x\n", common->module_api_version);
1831        result.appendFormat("Camera module name: %s\n", common->name);
1832        result.appendFormat("Camera module author: %s\n", common->author);
1833        result.appendFormat("Number of camera devices: %d\n\n", mNumberOfCameras);
1834
1835        sp<VendorTagDescriptor> desc = VendorTagDescriptor::getGlobalVendorTagDescriptor();
1836        if (desc == NULL) {
1837            result.appendFormat("Vendor tags left unimplemented.\n");
1838        } else {
1839            result.appendFormat("Vendor tag definitions:\n");
1840        }
1841
1842        write(fd, result.string(), result.size());
1843
1844        if (desc != NULL) {
1845            desc->dump(fd, /*verbosity*/2, /*indentation*/4);
1846        }
1847
1848        for (int i = 0; i < mNumberOfCameras; i++) {
1849            result = String8::format("Camera %d static information:\n", i);
1850            camera_info info;
1851
1852            status_t rc = mModule->getCameraInfo(i, &info);
1853            if (rc != OK) {
1854                result.appendFormat("  Error reading static information!\n");
1855                write(fd, result.string(), result.size());
1856            } else {
1857                result.appendFormat("  Facing: %s\n",
1858                        info.facing == CAMERA_FACING_BACK ? "BACK" : "FRONT");
1859                result.appendFormat("  Orientation: %d\n", info.orientation);
1860                int deviceVersion;
1861                if (common->module_api_version < CAMERA_MODULE_API_VERSION_2_0) {
1862                    deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
1863                } else {
1864                    deviceVersion = info.device_version;
1865                }
1866                result.appendFormat("  Device version: 0x%x\n", deviceVersion);
1867                if (deviceVersion >= CAMERA_DEVICE_API_VERSION_2_0) {
1868                    result.appendFormat("  Device static metadata:\n");
1869                    write(fd, result.string(), result.size());
1870                    dump_indented_camera_metadata(info.static_camera_characteristics,
1871                            fd, /*verbosity*/2, /*indentation*/4);
1872                } else {
1873                    write(fd, result.string(), result.size());
1874                }
1875            }
1876
1877            sp<BasicClient> client = mClient[i].promote();
1878            if (client == 0) {
1879                result = String8::format("  Device is closed, no client instance\n");
1880                write(fd, result.string(), result.size());
1881                continue;
1882            }
1883            hasClient = true;
1884            result = String8::format("  Device is open. Client instance dump:\n");
1885            write(fd, result.string(), result.size());
1886            client->dump(fd, args);
1887        }
1888        if (!hasClient) {
1889            result = String8::format("\nNo active camera clients yet.\n");
1890            write(fd, result.string(), result.size());
1891        }
1892
1893        if (locked) mServiceLock.unlock();
1894
1895        // Dump camera traces if there were any
1896        write(fd, "\n", 1);
1897        camera3::CameraTraces::dump(fd, args);
1898
1899        // change logging level
1900        int n = args.size();
1901        for (int i = 0; i + 1 < n; i++) {
1902            String16 verboseOption("-v");
1903            if (args[i] == verboseOption) {
1904                String8 levelStr(args[i+1]);
1905                int level = atoi(levelStr.string());
1906                result = String8::format("\nSetting log level to %d.\n", level);
1907                setLogLevel(level);
1908                write(fd, result.string(), result.size());
1909            }
1910        }
1911
1912    }
1913    return NO_ERROR;
1914}
1915
1916void CameraService::handleTorchClientBinderDied(const wp<IBinder> &who) {
1917    Mutex::Autolock al(mTorchClientMapMutex);
1918    for (size_t i = 0; i < mTorchClientMap.size(); i++) {
1919        if (mTorchClientMap[i] == who) {
1920            // turn off the torch mode that was turned on by dead client
1921            String8 cameraId = mTorchClientMap.keyAt(i);
1922            status_t res = mFlashlight->setTorchMode(cameraId, false);
1923            if (res) {
1924                ALOGE("%s: torch client died but couldn't turn off torch: "
1925                    "%s (%d)", __FUNCTION__, strerror(-res), res);
1926                return;
1927            }
1928            mTorchClientMap.removeItemsAt(i);
1929            break;
1930        }
1931    }
1932}
1933
1934/*virtual*/void CameraService::binderDied(
1935    const wp<IBinder> &who) {
1936
1937    /**
1938      * While tempting to promote the wp<IBinder> into a sp,
1939      * it's actually not supported by the binder driver
1940      */
1941
1942    ALOGV("java clients' binder died");
1943
1944    // check torch client
1945    handleTorchClientBinderDied(who);
1946
1947    // check camera device client
1948    sp<BasicClient> cameraClient = getClientByRemote(who);
1949
1950    if (cameraClient == 0) {
1951        ALOGV("java clients' binder death already cleaned up (normal case)");
1952        return;
1953    }
1954
1955    ALOGW("Disconnecting camera client %p since the binder for it "
1956          "died (this pid %d)", cameraClient.get(), getCallingPid());
1957
1958    cameraClient->disconnect();
1959
1960}
1961
1962void CameraService::updateStatus(ICameraServiceListener::Status status,
1963                                 int32_t cameraId,
1964                                 const StatusVector *rejectSourceStates) {
1965    // do not lock mServiceLock here or can get into a deadlock from
1966    //  connect() -> ProClient::disconnect -> updateStatus
1967    Mutex::Autolock lock(mStatusMutex);
1968
1969    ICameraServiceListener::Status oldStatus = mStatusList[cameraId];
1970
1971    mStatusList[cameraId] = status;
1972
1973    if (oldStatus != status) {
1974        ALOGV("%s: Status has changed for camera ID %d from 0x%x to 0x%x",
1975              __FUNCTION__, cameraId, (uint32_t)oldStatus, (uint32_t)status);
1976
1977        if (oldStatus == ICameraServiceListener::STATUS_NOT_PRESENT &&
1978            (status != ICameraServiceListener::STATUS_PRESENT &&
1979             status != ICameraServiceListener::STATUS_ENUMERATING)) {
1980
1981            ALOGW("%s: From NOT_PRESENT can only transition into PRESENT"
1982                  " or ENUMERATING", __FUNCTION__);
1983            mStatusList[cameraId] = oldStatus;
1984            return;
1985        }
1986
1987        if (rejectSourceStates != NULL) {
1988            const StatusVector &rejectList = *rejectSourceStates;
1989            StatusVector::const_iterator it = rejectList.begin();
1990
1991            /**
1992             * Sometimes we want to conditionally do a transition.
1993             * For example if a client disconnects, we want to go to PRESENT
1994             * only if we weren't already in NOT_PRESENT or ENUMERATING.
1995             */
1996            for (; it != rejectList.end(); ++it) {
1997                if (oldStatus == *it) {
1998                    ALOGV("%s: Rejecting status transition for Camera ID %d, "
1999                          " since the source state was was in one of the bad "
2000                          " states.", __FUNCTION__, cameraId);
2001                    mStatusList[cameraId] = oldStatus;
2002                    return;
2003                }
2004            }
2005        }
2006
2007        /**
2008          * ProClients lose their exclusive lock.
2009          * - Done before the CameraClient can initialize the HAL device,
2010          *   since we want to be able to close it before they get to initialize
2011          */
2012        if (status == ICameraServiceListener::STATUS_NOT_AVAILABLE) {
2013            Vector<wp<ProClient> > proClients(mProClientList[cameraId]);
2014            Vector<wp<ProClient> >::const_iterator it;
2015
2016            for (it = proClients.begin(); it != proClients.end(); ++it) {
2017                sp<ProClient> proCl = it->promote();
2018                if (proCl.get() != NULL) {
2019                    proCl->onExclusiveLockStolen();
2020                }
2021            }
2022        }
2023
2024        if (status == ICameraServiceListener::STATUS_NOT_PRESENT ||
2025            status == ICameraServiceListener::STATUS_NOT_AVAILABLE) {
2026            // update torch status to not available when the camera device
2027            // becomes not present or not available.
2028            onTorchStatusChanged(String8::format("%d", cameraId),
2029                    ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE);
2030        } else if (status == ICameraServiceListener::STATUS_PRESENT) {
2031            // update torch status to available when the camera device becomes
2032            // present or available
2033            onTorchStatusChanged(String8::format("%d", cameraId),
2034                    ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF);
2035        }
2036
2037        Vector<sp<ICameraServiceListener> >::const_iterator it;
2038        for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
2039            (*it)->onStatusChanged(status, cameraId);
2040        }
2041    }
2042}
2043
2044ICameraServiceListener::Status CameraService::getStatus(int cameraId) const {
2045    if (cameraId < 0 || cameraId >= MAX_CAMERAS) {
2046        ALOGE("%s: Invalid camera ID %d", __FUNCTION__, cameraId);
2047        return ICameraServiceListener::STATUS_UNKNOWN;
2048    }
2049
2050    Mutex::Autolock al(mStatusMutex);
2051    return mStatusList[cameraId];
2052}
2053
2054status_t CameraService::getTorchStatusLocked(
2055        const String8& cameraId,
2056        ICameraServiceListener::TorchStatus *status) const {
2057    if (!status) {
2058        return BAD_VALUE;
2059    }
2060    ssize_t index = mTorchStatusMap.indexOfKey(cameraId);
2061    if (index == NAME_NOT_FOUND) {
2062        // invalid camera ID or the camera doesn't have a flash unit
2063        return NAME_NOT_FOUND;
2064    }
2065
2066    *status = mTorchStatusMap.valueAt(index);
2067    return OK;
2068}
2069
2070status_t CameraService::setTorchStatusLocked(const String8& cameraId,
2071        ICameraServiceListener::TorchStatus status) {
2072    ssize_t index = mTorchStatusMap.indexOfKey(cameraId);
2073    if (index == NAME_NOT_FOUND) {
2074        return BAD_VALUE;
2075    }
2076    ICameraServiceListener::TorchStatus& item =
2077            mTorchStatusMap.editValueAt(index);
2078    item = status;
2079
2080    return OK;
2081}
2082
2083}; // namespace android
2084