CameraService.cpp revision 169e8ebba23f461cdb57f10985e044e235457b0a
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 ATRACE_TAG ATRACE_TAG_CAMERA
19//#define LOG_NDEBUG 0
20
21#include <algorithm>
22#include <climits>
23#include <stdio.h>
24#include <cstring>
25#include <ctime>
26#include <string>
27#include <sys/types.h>
28#include <inttypes.h>
29#include <pthread.h>
30
31#include <binder/AppOpsManager.h>
32#include <binder/IPCThreadState.h>
33#include <binder/IServiceManager.h>
34#include <binder/MemoryBase.h>
35#include <binder/MemoryHeapBase.h>
36#include <binder/ProcessInfoService.h>
37#include <cutils/atomic.h>
38#include <cutils/properties.h>
39#include <gui/Surface.h>
40#include <hardware/hardware.h>
41#include <media/AudioSystem.h>
42#include <media/IMediaHTTPService.h>
43#include <media/mediaplayer.h>
44#include <mediautils/BatteryNotifier.h>
45#include <utils/Errors.h>
46#include <utils/Log.h>
47#include <utils/String16.h>
48#include <utils/Trace.h>
49#include <system/camera_vendor_tags.h>
50#include <system/camera_metadata.h>
51#include <system/camera.h>
52
53#include "CameraService.h"
54#include "api1/CameraClient.h"
55#include "api1/Camera2Client.h"
56#include "api2/CameraDeviceClient.h"
57#include "utils/CameraTraces.h"
58#include "CameraDeviceFactory.h"
59
60namespace android {
61
62// ----------------------------------------------------------------------------
63// Logging support -- this is for debugging only
64// Use "adb shell dumpsys media.camera -v 1" to change it.
65volatile int32_t gLogLevel = 0;
66
67#define LOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__);
68#define LOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__);
69
70static void setLogLevel(int level) {
71    android_atomic_write(level, &gLogLevel);
72}
73
74// ----------------------------------------------------------------------------
75
76extern "C" {
77static void camera_device_status_change(
78        const struct camera_module_callbacks* callbacks,
79        int camera_id,
80        int new_status) {
81    sp<CameraService> cs = const_cast<CameraService*>(
82            static_cast<const CameraService*>(callbacks));
83
84    cs->onDeviceStatusChanged(static_cast<camera_device_status_t>(camera_id),
85            static_cast<camera_device_status_t>(new_status));
86}
87
88static void torch_mode_status_change(
89        const struct camera_module_callbacks* callbacks,
90        const char* camera_id,
91        int new_status) {
92    if (!callbacks || !camera_id) {
93        ALOGE("%s invalid parameters. callbacks %p, camera_id %p", __FUNCTION__,
94                callbacks, camera_id);
95    }
96    sp<CameraService> cs = const_cast<CameraService*>(
97                                static_cast<const CameraService*>(callbacks));
98
99    ICameraServiceListener::TorchStatus status;
100    switch (new_status) {
101        case TORCH_MODE_STATUS_NOT_AVAILABLE:
102            status = ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE;
103            break;
104        case TORCH_MODE_STATUS_AVAILABLE_OFF:
105            status = ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF;
106            break;
107        case TORCH_MODE_STATUS_AVAILABLE_ON:
108            status = ICameraServiceListener::TORCH_STATUS_AVAILABLE_ON;
109            break;
110        default:
111            ALOGE("Unknown torch status %d", new_status);
112            return;
113    }
114
115    cs->onTorchStatusChanged(
116        String8(camera_id),
117        status);
118}
119} // extern "C"
120
121// ----------------------------------------------------------------------------
122
123// This is ugly and only safe if we never re-create the CameraService, but
124// should be ok for now.
125static CameraService *gCameraService;
126
127CameraService::CameraService() : mEventLog(DEFAULT_EVENT_LOG_LENGTH), mAllowedUsers(),
128        mSoundRef(0), mModule(0), mFlashlight(0) {
129    ALOGI("CameraService started (pid=%d)", getpid());
130    gCameraService = this;
131
132    this->camera_device_status_change = android::camera_device_status_change;
133    this->torch_mode_status_change = android::torch_mode_status_change;
134
135    mServiceLockWrapper = std::make_shared<WaitableMutexWrapper>(&mServiceLock);
136}
137
138void CameraService::onFirstRef()
139{
140    ALOGI("CameraService process starting");
141
142    BnCameraService::onFirstRef();
143
144    // Update battery life tracking if service is restarting
145    BatteryNotifier& notifier(BatteryNotifier::getInstance());
146    notifier.noteResetCamera();
147    notifier.noteResetFlashlight();
148
149    camera_module_t *rawModule;
150    int err = hw_get_module(CAMERA_HARDWARE_MODULE_ID,
151            (const hw_module_t **)&rawModule);
152    if (err < 0) {
153        ALOGE("Could not load camera HAL module: %d (%s)", err, strerror(-err));
154        logServiceError("Could not load camera HAL module", err);
155        mNumberOfCameras = 0;
156        mNumberOfNormalCameras = 0;
157        return;
158    }
159
160    mModule = new CameraModule(rawModule);
161    err = mModule->init();
162    if (err != OK) {
163        ALOGE("Could not initialize camera HAL module: %d (%s)", err,
164            strerror(-err));
165        logServiceError("Could not initialize camera HAL module", err);
166
167        mNumberOfCameras = 0;
168        delete mModule;
169        mModule = nullptr;
170        return;
171    }
172    ALOGI("Loaded \"%s\" camera module", mModule->getModuleName());
173
174    mNumberOfCameras = mModule->getNumberOfCameras();
175    mNumberOfNormalCameras = mNumberOfCameras;
176
177    // Setup vendor tags before we call get_camera_info the first time
178    // because HAL might need to setup static vendor keys in get_camera_info
179    VendorTagDescriptor::clearGlobalVendorTagDescriptor();
180    if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_2) {
181        setUpVendorTags();
182    }
183
184    mFlashlight = new CameraFlashlight(*mModule, *this);
185    status_t res = mFlashlight->findFlashUnits();
186    if (res) {
187        // impossible because we haven't open any camera devices.
188        ALOGE("Failed to find flash units.");
189    }
190
191    int latestStrangeCameraId = INT_MAX;
192    for (int i = 0; i < mNumberOfCameras; i++) {
193        String8 cameraId = String8::format("%d", i);
194
195        // Get camera info
196
197        struct camera_info info;
198        bool haveInfo = true;
199        status_t rc = mModule->getCameraInfo(i, &info);
200        if (rc != NO_ERROR) {
201            ALOGE("%s: Received error loading camera info for device %d, cost and"
202                    " conflicting devices fields set to defaults for this device.",
203                    __FUNCTION__, i);
204            haveInfo = false;
205        }
206
207        // Check for backwards-compatibility support
208        if (haveInfo) {
209            if (checkCameraCapabilities(i, info, &latestStrangeCameraId) != OK) {
210                delete mModule;
211                mModule = nullptr;
212                return;
213            }
214        }
215
216        // Defaults to use for cost and conflicting devices
217        int cost = 100;
218        char** conflicting_devices = nullptr;
219        size_t conflicting_devices_length = 0;
220
221        // If using post-2.4 module version, query the cost + conflicting devices from the HAL
222        if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_4 && haveInfo) {
223            cost = info.resource_cost;
224            conflicting_devices = info.conflicting_devices;
225            conflicting_devices_length = info.conflicting_devices_length;
226        }
227
228        std::set<String8> conflicting;
229        for (size_t i = 0; i < conflicting_devices_length; i++) {
230            conflicting.emplace(String8(conflicting_devices[i]));
231        }
232
233        // Initialize state for each camera device
234        {
235            Mutex::Autolock lock(mCameraStatesLock);
236            mCameraStates.emplace(cameraId, std::make_shared<CameraState>(cameraId, cost,
237                    conflicting));
238        }
239
240        if (mFlashlight->hasFlashUnit(cameraId)) {
241            mTorchStatusMap.add(cameraId,
242                    ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF);
243        }
244    }
245
246    if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_1) {
247        mModule->setCallbacks(this);
248    }
249
250    CameraDeviceFactory::registerService(this);
251
252    CameraService::pingCameraServiceProxy();
253}
254
255sp<ICameraServiceProxy> CameraService::getCameraServiceProxy() {
256    sp<IServiceManager> sm = defaultServiceManager();
257    sp<IBinder> binder = sm->getService(String16("media.camera.proxy"));
258    if (binder == nullptr) {
259        return nullptr;
260    }
261    sp<ICameraServiceProxy> proxyBinder = interface_cast<ICameraServiceProxy>(binder);
262    return proxyBinder;
263}
264
265void CameraService::pingCameraServiceProxy() {
266    sp<ICameraServiceProxy> proxyBinder = getCameraServiceProxy();
267    if (proxyBinder == nullptr) return;
268    proxyBinder->pingForUserUpdate();
269}
270
271CameraService::~CameraService() {
272    if (mModule) {
273        delete mModule;
274        mModule = nullptr;
275    }
276    VendorTagDescriptor::clearGlobalVendorTagDescriptor();
277    gCameraService = nullptr;
278}
279
280void CameraService::onDeviceStatusChanged(camera_device_status_t  cameraId,
281        camera_device_status_t newStatus) {
282    ALOGI("%s: Status changed for cameraId=%d, newStatus=%d", __FUNCTION__,
283          cameraId, newStatus);
284
285    String8 id = String8::format("%d", cameraId);
286    std::shared_ptr<CameraState> state = getCameraState(id);
287
288    if (state == nullptr) {
289        ALOGE("%s: Bad camera ID %d", __FUNCTION__, cameraId);
290        return;
291    }
292
293    ICameraServiceListener::Status oldStatus = state->getStatus();
294
295    if (oldStatus == static_cast<ICameraServiceListener::Status>(newStatus)) {
296        ALOGE("%s: State transition to the same status %#x not allowed", __FUNCTION__, newStatus);
297        return;
298    }
299
300    if (newStatus == CAMERA_DEVICE_STATUS_NOT_PRESENT) {
301        logDeviceRemoved(id, String8::format("Device status changed from %d to %d", oldStatus,
302                newStatus));
303        sp<BasicClient> clientToDisconnect;
304        {
305            // Don't do this in updateStatus to avoid deadlock over mServiceLock
306            Mutex::Autolock lock(mServiceLock);
307
308            // Set the device status to NOT_PRESENT, clients will no longer be able to connect
309            // to this device until the status changes
310            updateStatus(ICameraServiceListener::STATUS_NOT_PRESENT, id);
311
312            // Remove cached shim parameters
313            state->setShimParams(CameraParameters());
314
315            // Remove the client from the list of active clients
316            clientToDisconnect = removeClientLocked(id);
317
318            // Notify the client of disconnection
319            clientToDisconnect->notifyError(ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED,
320                    CaptureResultExtras{});
321        }
322
323        ALOGI("%s: Client for camera ID %s evicted due to device status change from HAL",
324                __FUNCTION__, id.string());
325
326        // Disconnect client
327        if (clientToDisconnect.get() != nullptr) {
328            // Ensure not in binder RPC so client disconnect PID checks work correctly
329            LOG_ALWAYS_FATAL_IF(getCallingPid() != getpid(),
330                    "onDeviceStatusChanged must be called from the camera service process!");
331            clientToDisconnect->disconnect();
332        }
333
334    } else {
335        if (oldStatus == ICameraServiceListener::Status::STATUS_NOT_PRESENT) {
336            logDeviceAdded(id, String8::format("Device status changed from %d to %d", oldStatus,
337                    newStatus));
338        }
339        updateStatus(static_cast<ICameraServiceListener::Status>(newStatus), id);
340    }
341
342}
343
344void CameraService::onTorchStatusChanged(const String8& cameraId,
345        ICameraServiceListener::TorchStatus newStatus) {
346    Mutex::Autolock al(mTorchStatusMutex);
347    onTorchStatusChangedLocked(cameraId, newStatus);
348}
349
350void CameraService::onTorchStatusChangedLocked(const String8& cameraId,
351        ICameraServiceListener::TorchStatus newStatus) {
352    ALOGI("%s: Torch status changed for cameraId=%s, newStatus=%d",
353            __FUNCTION__, cameraId.string(), newStatus);
354
355    ICameraServiceListener::TorchStatus status;
356    status_t res = getTorchStatusLocked(cameraId, &status);
357    if (res) {
358        ALOGE("%s: cannot get torch status of camera %s: %s (%d)",
359                __FUNCTION__, cameraId.string(), strerror(-res), res);
360        return;
361    }
362    if (status == newStatus) {
363        return;
364    }
365
366    res = setTorchStatusLocked(cameraId, newStatus);
367    if (res) {
368        ALOGE("%s: Failed to set the torch status", __FUNCTION__, (uint32_t)newStatus);
369        return;
370    }
371
372    {
373        // Update battery life logging for flashlight
374        Mutex::Autolock al(mTorchUidMapMutex);
375        auto iter = mTorchUidMap.find(cameraId);
376        if (iter != mTorchUidMap.end()) {
377            int oldUid = iter->second.second;
378            int newUid = iter->second.first;
379            BatteryNotifier& notifier(BatteryNotifier::getInstance());
380            if (oldUid != newUid) {
381                // If the UID has changed, log the status and update current UID in mTorchUidMap
382                if (status == ICameraServiceListener::TORCH_STATUS_AVAILABLE_ON) {
383                    notifier.noteFlashlightOff(cameraId, oldUid);
384                }
385                if (newStatus == ICameraServiceListener::TORCH_STATUS_AVAILABLE_ON) {
386                    notifier.noteFlashlightOn(cameraId, newUid);
387                }
388                iter->second.second = newUid;
389            } else {
390                // If the UID has not changed, log the status
391                if (newStatus == ICameraServiceListener::TORCH_STATUS_AVAILABLE_ON) {
392                    notifier.noteFlashlightOn(cameraId, oldUid);
393                } else {
394                    notifier.noteFlashlightOff(cameraId, oldUid);
395                }
396            }
397        }
398    }
399
400    {
401        Mutex::Autolock lock(mStatusListenerLock);
402        for (auto& i : mListenerList) {
403            i->onTorchStatusChanged(newStatus, String16{cameraId});
404        }
405    }
406}
407
408int32_t CameraService::getNumberOfCameras() {
409    ATRACE_CALL();
410    return getNumberOfCameras(CAMERA_TYPE_BACKWARD_COMPATIBLE);
411}
412
413int32_t CameraService::getNumberOfCameras(int type) {
414    ATRACE_CALL();
415    switch (type) {
416        case CAMERA_TYPE_BACKWARD_COMPATIBLE:
417            return mNumberOfNormalCameras;
418        case CAMERA_TYPE_ALL:
419            return mNumberOfCameras;
420        default:
421            ALOGW("%s: Unknown camera type %d, returning 0",
422                    __FUNCTION__, type);
423            return 0;
424    }
425}
426
427status_t CameraService::getCameraInfo(int cameraId,
428                                      struct CameraInfo* cameraInfo) {
429    ATRACE_CALL();
430    if (!mModule) {
431        return -ENODEV;
432    }
433
434    if (cameraId < 0 || cameraId >= mNumberOfCameras) {
435        return BAD_VALUE;
436    }
437
438    struct camera_info info;
439    status_t rc = filterGetInfoErrorCode(
440        mModule->getCameraInfo(cameraId, &info));
441    cameraInfo->facing = info.facing;
442    cameraInfo->orientation = info.orientation;
443    return rc;
444}
445
446int CameraService::cameraIdToInt(const String8& cameraId) {
447    errno = 0;
448    size_t pos = 0;
449    int ret = stoi(std::string{cameraId.string()}, &pos);
450    if (errno != 0 || pos != cameraId.size()) {
451        return -1;
452    }
453    return ret;
454}
455
456status_t CameraService::generateShimMetadata(int cameraId, /*out*/CameraMetadata* cameraInfo) {
457    ATRACE_CALL();
458    status_t ret = OK;
459    struct CameraInfo info;
460    if ((ret = getCameraInfo(cameraId, &info)) != OK) {
461        return ret;
462    }
463
464    CameraMetadata shimInfo;
465    int32_t orientation = static_cast<int32_t>(info.orientation);
466    if ((ret = shimInfo.update(ANDROID_SENSOR_ORIENTATION, &orientation, 1)) != OK) {
467        return ret;
468    }
469
470    uint8_t facing = (info.facing == CAMERA_FACING_FRONT) ?
471            ANDROID_LENS_FACING_FRONT : ANDROID_LENS_FACING_BACK;
472    if ((ret = shimInfo.update(ANDROID_LENS_FACING, &facing, 1)) != OK) {
473        return ret;
474    }
475
476    CameraParameters shimParams;
477    if ((ret = getLegacyParametersLazy(cameraId, /*out*/&shimParams)) != OK) {
478        // Error logged by callee
479        return ret;
480    }
481
482    Vector<Size> sizes;
483    Vector<Size> jpegSizes;
484    Vector<int32_t> formats;
485    const char* supportedPreviewFormats;
486    {
487        shimParams.getSupportedPreviewSizes(/*out*/sizes);
488        shimParams.getSupportedPreviewFormats(/*out*/formats);
489        shimParams.getSupportedPictureSizes(/*out*/jpegSizes);
490    }
491
492    // Always include IMPLEMENTATION_DEFINED
493    formats.add(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED);
494
495    const size_t INTS_PER_CONFIG = 4;
496
497    // Build available stream configurations metadata
498    size_t streamConfigSize = (sizes.size() * formats.size() + jpegSizes.size()) * INTS_PER_CONFIG;
499
500    Vector<int32_t> streamConfigs;
501    streamConfigs.setCapacity(streamConfigSize);
502
503    for (size_t i = 0; i < formats.size(); ++i) {
504        for (size_t j = 0; j < sizes.size(); ++j) {
505            streamConfigs.add(formats[i]);
506            streamConfigs.add(sizes[j].width);
507            streamConfigs.add(sizes[j].height);
508            streamConfigs.add(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
509        }
510    }
511
512    for (size_t i = 0; i < jpegSizes.size(); ++i) {
513        streamConfigs.add(HAL_PIXEL_FORMAT_BLOB);
514        streamConfigs.add(jpegSizes[i].width);
515        streamConfigs.add(jpegSizes[i].height);
516        streamConfigs.add(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
517    }
518
519    if ((ret = shimInfo.update(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
520            streamConfigs.array(), streamConfigSize)) != OK) {
521        return ret;
522    }
523
524    int64_t fakeMinFrames[0];
525    // TODO: Fixme, don't fake min frame durations.
526    if ((ret = shimInfo.update(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
527            fakeMinFrames, 0)) != OK) {
528        return ret;
529    }
530
531    int64_t fakeStalls[0];
532    // TODO: Fixme, don't fake stall durations.
533    if ((ret = shimInfo.update(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
534            fakeStalls, 0)) != OK) {
535        return ret;
536    }
537
538    *cameraInfo = shimInfo;
539    return OK;
540}
541
542status_t CameraService::getCameraCharacteristics(int cameraId,
543                                                CameraMetadata* cameraInfo) {
544    ATRACE_CALL();
545    if (!cameraInfo) {
546        ALOGE("%s: cameraInfo is NULL", __FUNCTION__);
547        return BAD_VALUE;
548    }
549
550    if (!mModule) {
551        ALOGE("%s: camera hardware module doesn't exist", __FUNCTION__);
552        return -ENODEV;
553    }
554
555    if (cameraId < 0 || cameraId >= mNumberOfCameras) {
556        ALOGE("%s: Invalid camera id: %d", __FUNCTION__, cameraId);
557        return BAD_VALUE;
558    }
559
560    int facing;
561    status_t ret = OK;
562    if (mModule->getModuleApiVersion() < CAMERA_MODULE_API_VERSION_2_0 ||
563            getDeviceVersion(cameraId, &facing) <= CAMERA_DEVICE_API_VERSION_2_1 ) {
564        /**
565         * Backwards compatibility mode for old HALs:
566         * - Convert CameraInfo into static CameraMetadata properties.
567         * - Retrieve cached CameraParameters for this camera.  If none exist,
568         *   attempt to open CameraClient and retrieve the CameraParameters.
569         * - Convert cached CameraParameters into static CameraMetadata
570         *   properties.
571         */
572        ALOGI("%s: Switching to HAL1 shim implementation...", __FUNCTION__);
573
574        if ((ret = generateShimMetadata(cameraId, cameraInfo)) != OK) {
575            return ret;
576        }
577
578    } else {
579        /**
580         * Normal HAL 2.1+ codepath.
581         */
582        struct camera_info info;
583        ret = filterGetInfoErrorCode(mModule->getCameraInfo(cameraId, &info));
584        *cameraInfo = info.static_camera_characteristics;
585    }
586
587    return ret;
588}
589
590int CameraService::getCallingPid() {
591    return IPCThreadState::self()->getCallingPid();
592}
593
594int CameraService::getCallingUid() {
595    return IPCThreadState::self()->getCallingUid();
596}
597
598String8 CameraService::getFormattedCurrentTime() {
599    time_t now = time(nullptr);
600    char formattedTime[64];
601    strftime(formattedTime, sizeof(formattedTime), "%m-%d %H:%M:%S", localtime(&now));
602    return String8(formattedTime);
603}
604
605int CameraService::getCameraPriorityFromProcState(int procState) {
606    // Find the priority for the camera usage based on the process state.  Higher priority clients
607    // win for evictions.
608    if (procState < 0) {
609        ALOGE("%s: Received invalid process state %d from ActivityManagerService!", __FUNCTION__,
610                procState);
611        return -1;
612    }
613    // Treat sleeping TOP processes the same as regular TOP processes, for
614    // access priority.  This is important for lock-screen camera launch scenarios
615    if (procState == PROCESS_STATE_TOP_SLEEPING) {
616        procState = PROCESS_STATE_TOP;
617    }
618    return INT_MAX - procState;
619}
620
621status_t CameraService::getCameraVendorTagDescriptor(/*out*/sp<VendorTagDescriptor>& desc) {
622    ATRACE_CALL();
623    if (!mModule) {
624        ALOGE("%s: camera hardware module doesn't exist", __FUNCTION__);
625        return -ENODEV;
626    }
627
628    desc = VendorTagDescriptor::getGlobalVendorTagDescriptor();
629    return OK;
630}
631
632int CameraService::getDeviceVersion(int cameraId, int* facing) {
633    ATRACE_CALL();
634    struct camera_info info;
635    if (mModule->getCameraInfo(cameraId, &info) != OK) {
636        return -1;
637    }
638
639    int deviceVersion;
640    if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_0) {
641        deviceVersion = info.device_version;
642    } else {
643        deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
644    }
645
646    if (facing) {
647        *facing = info.facing;
648    }
649
650    return deviceVersion;
651}
652
653status_t CameraService::filterGetInfoErrorCode(status_t err) {
654    switch(err) {
655        case NO_ERROR:
656        case -EINVAL:
657            return err;
658        default:
659            break;
660    }
661    return -ENODEV;
662}
663
664bool CameraService::setUpVendorTags() {
665    ATRACE_CALL();
666    vendor_tag_ops_t vOps = vendor_tag_ops_t();
667
668    // Check if vendor operations have been implemented
669    if (!mModule->isVendorTagDefined()) {
670        ALOGI("%s: No vendor tags defined for this device.", __FUNCTION__);
671        return false;
672    }
673
674    mModule->getVendorTagOps(&vOps);
675
676    // Ensure all vendor operations are present
677    if (vOps.get_tag_count == NULL || vOps.get_all_tags == NULL ||
678            vOps.get_section_name == NULL || vOps.get_tag_name == NULL ||
679            vOps.get_tag_type == NULL) {
680        ALOGE("%s: Vendor tag operations not fully defined. Ignoring definitions."
681               , __FUNCTION__);
682        return false;
683    }
684
685    // Read all vendor tag definitions into a descriptor
686    sp<VendorTagDescriptor> desc;
687    status_t res;
688    if ((res = VendorTagDescriptor::createDescriptorFromOps(&vOps, /*out*/desc))
689            != OK) {
690        ALOGE("%s: Could not generate descriptor from vendor tag operations,"
691              "received error %s (%d). Camera clients will not be able to use"
692              "vendor tags", __FUNCTION__, strerror(res), res);
693        return false;
694    }
695
696    // Set the global descriptor to use with camera metadata
697    VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
698    return true;
699}
700
701status_t CameraService::makeClient(const sp<CameraService>& cameraService,
702        const sp<IInterface>& cameraCb, const String16& packageName, const String8& cameraId,
703        int facing, int clientPid, uid_t clientUid, int servicePid, bool legacyMode,
704        int halVersion, int deviceVersion, apiLevel effectiveApiLevel,
705        /*out*/sp<BasicClient>* client) {
706
707    // TODO: Update CameraClients + HAL interface to use strings for Camera IDs
708    int id = cameraIdToInt(cameraId);
709    if (id == -1) {
710        ALOGE("%s: Invalid camera ID %s, cannot convert to integer.", __FUNCTION__,
711                cameraId.string());
712        return BAD_VALUE;
713    }
714
715    if (halVersion < 0 || halVersion == deviceVersion) {
716        // Default path: HAL version is unspecified by caller, create CameraClient
717        // based on device version reported by the HAL.
718        switch(deviceVersion) {
719          case CAMERA_DEVICE_API_VERSION_1_0:
720            if (effectiveApiLevel == API_1) {  // Camera1 API route
721                sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
722                *client = new CameraClient(cameraService, tmp, packageName, id, facing,
723                        clientPid, clientUid, getpid(), legacyMode);
724            } else { // Camera2 API route
725                ALOGW("Camera using old HAL version: %d", deviceVersion);
726                return -EOPNOTSUPP;
727            }
728            break;
729          case CAMERA_DEVICE_API_VERSION_2_0:
730          case CAMERA_DEVICE_API_VERSION_2_1:
731          case CAMERA_DEVICE_API_VERSION_3_0:
732          case CAMERA_DEVICE_API_VERSION_3_1:
733          case CAMERA_DEVICE_API_VERSION_3_2:
734          case CAMERA_DEVICE_API_VERSION_3_3:
735            if (effectiveApiLevel == API_1) { // Camera1 API route
736                sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
737                *client = new Camera2Client(cameraService, tmp, packageName, id, facing,
738                        clientPid, clientUid, servicePid, legacyMode);
739            } else { // Camera2 API route
740                sp<ICameraDeviceCallbacks> tmp =
741                        static_cast<ICameraDeviceCallbacks*>(cameraCb.get());
742                *client = new CameraDeviceClient(cameraService, tmp, packageName, id,
743                        facing, clientPid, clientUid, servicePid);
744            }
745            break;
746          default:
747            // Should not be reachable
748            ALOGE("Unknown camera device HAL version: %d", deviceVersion);
749            return INVALID_OPERATION;
750        }
751    } else {
752        // A particular HAL version is requested by caller. Create CameraClient
753        // based on the requested HAL version.
754        if (deviceVersion > CAMERA_DEVICE_API_VERSION_1_0 &&
755            halVersion == CAMERA_DEVICE_API_VERSION_1_0) {
756            // Only support higher HAL version device opened as HAL1.0 device.
757            sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
758            *client = new CameraClient(cameraService, tmp, packageName, id, facing,
759                    clientPid, clientUid, servicePid, legacyMode);
760        } else {
761            // Other combinations (e.g. HAL3.x open as HAL2.x) are not supported yet.
762            ALOGE("Invalid camera HAL version %x: HAL %x device can only be"
763                    " opened as HAL %x device", halVersion, deviceVersion,
764                    CAMERA_DEVICE_API_VERSION_1_0);
765            return INVALID_OPERATION;
766        }
767    }
768    return NO_ERROR;
769}
770
771String8 CameraService::toString(std::set<userid_t> intSet) {
772    String8 s("");
773    bool first = true;
774    for (userid_t i : intSet) {
775        if (first) {
776            s.appendFormat("%d", i);
777            first = false;
778        } else {
779            s.appendFormat(", %d", i);
780        }
781    }
782    return s;
783}
784
785status_t CameraService::initializeShimMetadata(int cameraId) {
786    int uid = getCallingUid();
787
788    String16 internalPackageName("media");
789    String8 id = String8::format("%d", cameraId);
790    status_t ret = NO_ERROR;
791    sp<Client> tmp = nullptr;
792    if ((ret = connectHelper<ICameraClient,Client>(sp<ICameraClient>{nullptr}, id,
793            static_cast<int>(CAMERA_HAL_API_VERSION_UNSPECIFIED), internalPackageName, uid, API_1,
794            false, true, tmp)) != NO_ERROR) {
795        ALOGE("%s: Error %d (%s) initializing shim metadata.", __FUNCTION__, ret, strerror(ret));
796        return ret;
797    }
798    return NO_ERROR;
799}
800
801status_t CameraService::getLegacyParametersLazy(int cameraId,
802        /*out*/
803        CameraParameters* parameters) {
804
805    ALOGV("%s: for cameraId: %d", __FUNCTION__, cameraId);
806
807    status_t ret = 0;
808
809    if (parameters == NULL) {
810        ALOGE("%s: parameters must not be null", __FUNCTION__);
811        return BAD_VALUE;
812    }
813
814    String8 id = String8::format("%d", cameraId);
815
816    // Check if we already have parameters
817    {
818        // Scope for service lock
819        Mutex::Autolock lock(mServiceLock);
820        auto cameraState = getCameraState(id);
821        if (cameraState == nullptr) {
822            ALOGE("%s: Invalid camera ID: %s", __FUNCTION__, id.string());
823            return BAD_VALUE;
824        }
825        CameraParameters p = cameraState->getShimParams();
826        if (!p.isEmpty()) {
827            *parameters = p;
828            return NO_ERROR;
829        }
830    }
831
832    int64_t token = IPCThreadState::self()->clearCallingIdentity();
833    ret = initializeShimMetadata(cameraId);
834    IPCThreadState::self()->restoreCallingIdentity(token);
835    if (ret != NO_ERROR) {
836        // Error already logged by callee
837        return ret;
838    }
839
840    // Check for parameters again
841    {
842        // Scope for service lock
843        Mutex::Autolock lock(mServiceLock);
844        auto cameraState = getCameraState(id);
845        if (cameraState == nullptr) {
846            ALOGE("%s: Invalid camera ID: %s", __FUNCTION__, id.string());
847            return BAD_VALUE;
848        }
849        CameraParameters p = cameraState->getShimParams();
850        if (!p.isEmpty()) {
851            *parameters = p;
852            return NO_ERROR;
853        }
854    }
855
856    ALOGE("%s: Parameters were not initialized, or were empty.  Device may not be present.",
857            __FUNCTION__);
858    return INVALID_OPERATION;
859}
860
861status_t CameraService::validateConnectLocked(const String8& cameraId, /*inout*/int& clientUid)
862        const {
863
864    int callingPid = getCallingPid();
865
866    if (clientUid == USE_CALLING_UID) {
867        clientUid = getCallingUid();
868    } else {
869        // We only trust our own process to forward client UIDs
870        if (callingPid != getpid()) {
871            ALOGE("CameraService::connect X (PID %d) rejected (don't trust clientUid %d)",
872                    callingPid, clientUid);
873            return PERMISSION_DENIED;
874        }
875    }
876
877    if (!mModule) {
878        ALOGE("CameraService::connect X (PID %d) rejected (camera HAL module not loaded)",
879                callingPid);
880        return -ENODEV;
881    }
882
883    if (getCameraState(cameraId) == nullptr) {
884        ALOGE("CameraService::connect X (PID %d) rejected (invalid camera ID %s)", callingPid,
885                cameraId.string());
886        return -ENODEV;
887    }
888
889    userid_t clientUserId = multiuser_get_user_id(clientUid);
890
891    // Only allow clients who are being used by the current foreground device user, unless calling
892    // from our own process.
893    if (callingPid != getpid() && (mAllowedUsers.find(clientUserId) == mAllowedUsers.end())) {
894        ALOGE("CameraService::connect X (PID %d) rejected (cannot connect from "
895                "device user %d, currently allowed device users: %s)", callingPid, clientUserId,
896                toString(mAllowedUsers).string());
897        return PERMISSION_DENIED;
898    }
899
900    return checkIfDeviceIsUsable(cameraId);
901}
902
903status_t CameraService::checkIfDeviceIsUsable(const String8& cameraId) const {
904    auto cameraState = getCameraState(cameraId);
905    int callingPid = getCallingPid();
906    if (cameraState == nullptr) {
907        ALOGE("CameraService::connect X (PID %d) rejected (invalid camera ID %s)", callingPid,
908                cameraId.string());
909        return -ENODEV;
910    }
911
912    ICameraServiceListener::Status currentStatus = cameraState->getStatus();
913    if (currentStatus == ICameraServiceListener::STATUS_NOT_PRESENT) {
914        ALOGE("CameraService::connect X (PID %d) rejected (camera %s is not connected)",
915                callingPid, cameraId.string());
916        return -ENODEV;
917    } else if (currentStatus == ICameraServiceListener::STATUS_ENUMERATING) {
918        ALOGE("CameraService::connect X (PID %d) rejected, (camera %s is initializing)",
919                callingPid, cameraId.string());
920        return -EBUSY;
921    }
922
923    return NO_ERROR;
924}
925
926void CameraService::finishConnectLocked(const sp<BasicClient>& client,
927        const CameraService::DescriptorPtr& desc) {
928
929    // Make a descriptor for the incoming client
930    auto clientDescriptor = CameraService::CameraClientManager::makeClientDescriptor(client, desc);
931    auto evicted = mActiveClientManager.addAndEvict(clientDescriptor);
932
933    logConnected(desc->getKey(), static_cast<int>(desc->getOwnerId()),
934            String8(client->getPackageName()));
935
936    if (evicted.size() > 0) {
937        // This should never happen - clients should already have been removed in disconnect
938        for (auto& i : evicted) {
939            ALOGE("%s: Invalid state: Client for camera %s was not removed in disconnect",
940                    __FUNCTION__, i->getKey().string());
941        }
942
943        LOG_ALWAYS_FATAL("%s: Invalid state for CameraService, clients not evicted properly",
944                __FUNCTION__);
945    }
946
947    // And register a death notification for the client callback. Do
948    // this last to avoid Binder policy where a nested Binder
949    // transaction might be pre-empted to service the client death
950    // notification if the client process dies before linkToDeath is
951    // invoked.
952    sp<IBinder> remoteCallback = client->getRemote();
953    if (remoteCallback != nullptr) {
954        remoteCallback->linkToDeath(this);
955    }
956}
957
958status_t CameraService::handleEvictionsLocked(const String8& cameraId, int clientPid,
959        apiLevel effectiveApiLevel, const sp<IBinder>& remoteCallback, const String8& packageName,
960        /*out*/
961        sp<BasicClient>* client,
962        std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>* partial) {
963    ATRACE_CALL();
964    status_t ret = NO_ERROR;
965    std::vector<DescriptorPtr> evictedClients;
966    DescriptorPtr clientDescriptor;
967    {
968        if (effectiveApiLevel == API_1) {
969            // If we are using API1, any existing client for this camera ID with the same remote
970            // should be returned rather than evicted to allow MediaRecorder to work properly.
971
972            auto current = mActiveClientManager.get(cameraId);
973            if (current != nullptr) {
974                auto clientSp = current->getValue();
975                if (clientSp.get() != nullptr) { // should never be needed
976                    if (!clientSp->canCastToApiClient(effectiveApiLevel)) {
977                        ALOGW("CameraService connect called from same client, but with a different"
978                                " API level, evicting prior client...");
979                    } else if (clientSp->getRemote() == remoteCallback) {
980                        ALOGI("CameraService::connect X (PID %d) (second call from same"
981                                " app binder, returning the same client)", clientPid);
982                        *client = clientSp;
983                        return NO_ERROR;
984                    }
985                }
986            }
987        }
988
989        // Return error if the device was unplugged or removed by the HAL for some reason
990        if ((ret = checkIfDeviceIsUsable(cameraId)) != NO_ERROR) {
991            return ret;
992        }
993
994        // Get current active client PIDs
995        std::vector<int> ownerPids(mActiveClientManager.getAllOwners());
996        ownerPids.push_back(clientPid);
997
998        // Use the value +PROCESS_STATE_NONEXISTENT, to avoid taking
999        // address of PROCESS_STATE_NONEXISTENT as a reference argument
1000        // for the vector constructor. PROCESS_STATE_NONEXISTENT does
1001        // not have an out-of-class definition.
1002        std::vector<int> priorities(ownerPids.size(), +PROCESS_STATE_NONEXISTENT);
1003
1004        // Get priorites of all active PIDs
1005        ProcessInfoService::getProcessStatesFromPids(ownerPids.size(), &ownerPids[0],
1006                /*out*/&priorities[0]);
1007
1008        // Update all active clients' priorities
1009        std::map<int,int> pidToPriorityMap;
1010        for (size_t i = 0; i < ownerPids.size() - 1; i++) {
1011            pidToPriorityMap.emplace(ownerPids[i], getCameraPriorityFromProcState(priorities[i]));
1012        }
1013        mActiveClientManager.updatePriorities(pidToPriorityMap);
1014
1015        // Get state for the given cameraId
1016        auto state = getCameraState(cameraId);
1017        if (state == nullptr) {
1018            ALOGE("CameraService::connect X (PID %d) rejected (no camera device with ID %s)",
1019                clientPid, cameraId.string());
1020            return BAD_VALUE;
1021        }
1022
1023        // Make descriptor for incoming client
1024        clientDescriptor = CameraClientManager::makeClientDescriptor(cameraId,
1025                sp<BasicClient>{nullptr}, static_cast<int32_t>(state->getCost()),
1026                state->getConflicting(),
1027                getCameraPriorityFromProcState(priorities[priorities.size() - 1]), clientPid);
1028
1029        // Find clients that would be evicted
1030        auto evicted = mActiveClientManager.wouldEvict(clientDescriptor);
1031
1032        // If the incoming client was 'evicted,' higher priority clients have the camera in the
1033        // background, so we cannot do evictions
1034        if (std::find(evicted.begin(), evicted.end(), clientDescriptor) != evicted.end()) {
1035            ALOGE("CameraService::connect X (PID %d) rejected (existing client(s) with higher"
1036                    " priority).", clientPid);
1037
1038            sp<BasicClient> clientSp = clientDescriptor->getValue();
1039            String8 curTime = getFormattedCurrentTime();
1040            auto incompatibleClients =
1041                    mActiveClientManager.getIncompatibleClients(clientDescriptor);
1042
1043            String8 msg = String8::format("%s : DENIED connect device %s client for package %s "
1044                    "(PID %d, priority %d) due to eviction policy", curTime.string(),
1045                    cameraId.string(), packageName.string(), clientPid,
1046                    getCameraPriorityFromProcState(priorities[priorities.size() - 1]));
1047
1048            for (auto& i : incompatibleClients) {
1049                msg.appendFormat("\n   - Blocked by existing device %s client for package %s"
1050                        "(PID %" PRId32 ", priority %" PRId32 ")", i->getKey().string(),
1051                        String8{i->getValue()->getPackageName()}.string(), i->getOwnerId(),
1052                        i->getPriority());
1053                ALOGE("   Conflicts with: Device %s, client package %s (PID %"
1054                        PRId32 ", priority %" PRId32 ")", i->getKey().string(),
1055                        String8{i->getValue()->getPackageName()}.string(), i->getOwnerId(),
1056                        i->getPriority());
1057            }
1058
1059            // Log the client's attempt
1060            Mutex::Autolock l(mLogLock);
1061            mEventLog.add(msg);
1062
1063            return -EBUSY;
1064        }
1065
1066        for (auto& i : evicted) {
1067            sp<BasicClient> clientSp = i->getValue();
1068            if (clientSp.get() == nullptr) {
1069                ALOGE("%s: Invalid state: Null client in active client list.", __FUNCTION__);
1070
1071                // TODO: Remove this
1072                LOG_ALWAYS_FATAL("%s: Invalid state for CameraService, null client in active list",
1073                        __FUNCTION__);
1074                mActiveClientManager.remove(i);
1075                continue;
1076            }
1077
1078            ALOGE("CameraService::connect evicting conflicting client for camera ID %s",
1079                    i->getKey().string());
1080            evictedClients.push_back(i);
1081
1082            // Log the clients evicted
1083            logEvent(String8::format("EVICT device %s client held by package %s (PID"
1084                    " %" PRId32 ", priority %" PRId32 ")\n   - Evicted by device %s client for"
1085                    " package %s (PID %d, priority %" PRId32 ")",
1086                    i->getKey().string(), String8{clientSp->getPackageName()}.string(),
1087                    i->getOwnerId(), i->getPriority(), cameraId.string(),
1088                    packageName.string(), clientPid,
1089                    getCameraPriorityFromProcState(priorities[priorities.size() - 1])));
1090
1091            // Notify the client of disconnection
1092            clientSp->notifyError(ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED,
1093                    CaptureResultExtras());
1094        }
1095    }
1096
1097    // Do not hold mServiceLock while disconnecting clients, but retain the condition blocking
1098    // other clients from connecting in mServiceLockWrapper if held
1099    mServiceLock.unlock();
1100
1101    // Clear caller identity temporarily so client disconnect PID checks work correctly
1102    int64_t token = IPCThreadState::self()->clearCallingIdentity();
1103
1104    // Destroy evicted clients
1105    for (auto& i : evictedClients) {
1106        // Disconnect is blocking, and should only have returned when HAL has cleaned up
1107        i->getValue()->disconnect(); // Clients will remove themselves from the active client list
1108    }
1109
1110    IPCThreadState::self()->restoreCallingIdentity(token);
1111
1112    for (const auto& i : evictedClients) {
1113        ALOGV("%s: Waiting for disconnect to complete for client for device %s (PID %" PRId32 ")",
1114                __FUNCTION__, i->getKey().string(), i->getOwnerId());
1115        ret = mActiveClientManager.waitUntilRemoved(i, DEFAULT_DISCONNECT_TIMEOUT_NS);
1116        if (ret == TIMED_OUT) {
1117            ALOGE("%s: Timed out waiting for client for device %s to disconnect, "
1118                    "current clients:\n%s", __FUNCTION__, i->getKey().string(),
1119                    mActiveClientManager.toString().string());
1120            return -EBUSY;
1121        }
1122        if (ret != NO_ERROR) {
1123            ALOGE("%s: Received error waiting for client for device %s to disconnect: %s (%d), "
1124                    "current clients:\n%s", __FUNCTION__, i->getKey().string(), strerror(-ret),
1125                    ret, mActiveClientManager.toString().string());
1126            return ret;
1127        }
1128    }
1129
1130    evictedClients.clear();
1131
1132    // Once clients have been disconnected, relock
1133    mServiceLock.lock();
1134
1135    // Check again if the device was unplugged or something while we weren't holding mServiceLock
1136    if ((ret = checkIfDeviceIsUsable(cameraId)) != NO_ERROR) {
1137        return ret;
1138    }
1139
1140    *partial = clientDescriptor;
1141    return NO_ERROR;
1142}
1143
1144status_t CameraService::connect(
1145        const sp<ICameraClient>& cameraClient,
1146        int cameraId,
1147        const String16& clientPackageName,
1148        int clientUid,
1149        /*out*/
1150        sp<ICamera>& device) {
1151
1152    ATRACE_CALL();
1153    status_t ret = NO_ERROR;
1154    String8 id = String8::format("%d", cameraId);
1155    sp<Client> client = nullptr;
1156    ret = connectHelper<ICameraClient,Client>(cameraClient, id, CAMERA_HAL_API_VERSION_UNSPECIFIED,
1157            clientPackageName, clientUid, API_1, false, false, /*out*/client);
1158
1159    if(ret != NO_ERROR) {
1160        logRejected(id, getCallingPid(), String8(clientPackageName),
1161                String8::format("%s (%d)", strerror(-ret), ret));
1162        return ret;
1163    }
1164
1165    device = client;
1166    return NO_ERROR;
1167}
1168
1169status_t CameraService::connectLegacy(
1170        const sp<ICameraClient>& cameraClient,
1171        int cameraId, int halVersion,
1172        const String16& clientPackageName,
1173        int clientUid,
1174        /*out*/
1175        sp<ICamera>& device) {
1176
1177    ATRACE_CALL();
1178    String8 id = String8::format("%d", cameraId);
1179    int apiVersion = mModule->getModuleApiVersion();
1180    if (halVersion != CAMERA_HAL_API_VERSION_UNSPECIFIED &&
1181            apiVersion < CAMERA_MODULE_API_VERSION_2_3) {
1182        /*
1183         * Either the HAL version is unspecified in which case this just creates
1184         * a camera client selected by the latest device version, or
1185         * it's a particular version in which case the HAL must supported
1186         * the open_legacy call
1187         */
1188        ALOGE("%s: camera HAL module version %x doesn't support connecting to legacy HAL devices!",
1189                __FUNCTION__, apiVersion);
1190        logRejected(id, getCallingPid(), String8(clientPackageName),
1191                String8("HAL module version doesn't support legacy HAL connections"));
1192        return INVALID_OPERATION;
1193    }
1194
1195    status_t ret = NO_ERROR;
1196    sp<Client> client = nullptr;
1197    ret = connectHelper<ICameraClient,Client>(cameraClient, id, halVersion, clientPackageName,
1198            clientUid, API_1, true, false, /*out*/client);
1199
1200    if(ret != NO_ERROR) {
1201        logRejected(id, getCallingPid(), String8(clientPackageName),
1202                String8::format("%s (%d)", strerror(-ret), ret));
1203        return ret;
1204    }
1205
1206    device = client;
1207    return NO_ERROR;
1208}
1209
1210status_t CameraService::connectDevice(
1211        const sp<ICameraDeviceCallbacks>& cameraCb,
1212        int cameraId,
1213        const String16& clientPackageName,
1214        int clientUid,
1215        /*out*/
1216        sp<ICameraDeviceUser>& device) {
1217
1218    ATRACE_CALL();
1219    status_t ret = NO_ERROR;
1220    String8 id = String8::format("%d", cameraId);
1221    sp<CameraDeviceClient> client = nullptr;
1222    ret = connectHelper<ICameraDeviceCallbacks,CameraDeviceClient>(cameraCb, id,
1223            CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageName, clientUid, API_2, false, false,
1224            /*out*/client);
1225
1226    if(ret != NO_ERROR) {
1227        logRejected(id, getCallingPid(), String8(clientPackageName),
1228                String8::format("%s (%d)", strerror(-ret), ret));
1229        return ret;
1230    }
1231
1232    device = client;
1233    return NO_ERROR;
1234}
1235
1236status_t CameraService::setTorchMode(const String16& cameraId, bool enabled,
1237        const sp<IBinder>& clientBinder) {
1238
1239    ATRACE_CALL();
1240    if (enabled && clientBinder == nullptr) {
1241        ALOGE("%s: torch client binder is NULL", __FUNCTION__);
1242        return -EINVAL;
1243    }
1244
1245    String8 id = String8(cameraId.string());
1246    int uid = getCallingUid();
1247
1248    // verify id is valid.
1249    auto state = getCameraState(id);
1250    if (state == nullptr) {
1251        ALOGE("%s: camera id is invalid %s", __FUNCTION__, id.string());
1252        return -EINVAL;
1253    }
1254
1255    ICameraServiceListener::Status cameraStatus = state->getStatus();
1256    if (cameraStatus != ICameraServiceListener::STATUS_PRESENT &&
1257            cameraStatus != ICameraServiceListener::STATUS_NOT_AVAILABLE) {
1258        ALOGE("%s: camera id is invalid %s", __FUNCTION__, id.string());
1259        return -EINVAL;
1260    }
1261
1262    {
1263        Mutex::Autolock al(mTorchStatusMutex);
1264        ICameraServiceListener::TorchStatus status;
1265        status_t res = getTorchStatusLocked(id, &status);
1266        if (res) {
1267            ALOGE("%s: getting current torch status failed for camera %s",
1268                    __FUNCTION__, id.string());
1269            return -EINVAL;
1270        }
1271
1272        if (status == ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE) {
1273            if (cameraStatus == ICameraServiceListener::STATUS_NOT_AVAILABLE) {
1274                ALOGE("%s: torch mode of camera %s is not available because "
1275                        "camera is in use", __FUNCTION__, id.string());
1276                return -EBUSY;
1277            } else {
1278                ALOGE("%s: torch mode of camera %s is not available due to "
1279                        "insufficient resources", __FUNCTION__, id.string());
1280                return -EUSERS;
1281            }
1282        }
1283    }
1284
1285    {
1286        // Update UID map - this is used in the torch status changed callbacks, so must be done
1287        // before setTorchMode
1288        Mutex::Autolock al(mTorchUidMapMutex);
1289        if (mTorchUidMap.find(id) == mTorchUidMap.end()) {
1290            mTorchUidMap[id].first = uid;
1291            mTorchUidMap[id].second = uid;
1292        } else {
1293            // Set the pending UID
1294            mTorchUidMap[id].first = uid;
1295        }
1296    }
1297
1298    status_t res = mFlashlight->setTorchMode(id, enabled);
1299
1300    if (res) {
1301        ALOGE("%s: setting torch mode of camera %s to %d failed. %s (%d)",
1302                __FUNCTION__, id.string(), enabled, strerror(-res), res);
1303        return res;
1304    }
1305
1306    {
1307        // update the link to client's death
1308        Mutex::Autolock al(mTorchClientMapMutex);
1309        ssize_t index = mTorchClientMap.indexOfKey(id);
1310        BatteryNotifier& notifier(BatteryNotifier::getInstance());
1311        if (enabled) {
1312            if (index == NAME_NOT_FOUND) {
1313                mTorchClientMap.add(id, clientBinder);
1314            } else {
1315                mTorchClientMap.valueAt(index)->unlinkToDeath(this);
1316                mTorchClientMap.replaceValueAt(index, clientBinder);
1317            }
1318            clientBinder->linkToDeath(this);
1319        } else if (index != NAME_NOT_FOUND) {
1320            mTorchClientMap.valueAt(index)->unlinkToDeath(this);
1321        }
1322    }
1323
1324    return OK;
1325}
1326
1327void CameraService::notifySystemEvent(int32_t eventId, const int32_t* args, size_t length) {
1328    ATRACE_CALL();
1329
1330    switch(eventId) {
1331        case ICameraService::USER_SWITCHED: {
1332            doUserSwitch(/*newUserIds*/args, /*length*/length);
1333            break;
1334        }
1335        case ICameraService::NO_EVENT:
1336        default: {
1337            ALOGW("%s: Received invalid system event from system_server: %d", __FUNCTION__,
1338                    eventId);
1339            break;
1340        }
1341    }
1342}
1343
1344status_t CameraService::addListener(const sp<ICameraServiceListener>& listener) {
1345    ATRACE_CALL();
1346
1347    ALOGV("%s: Add listener %p", __FUNCTION__, listener.get());
1348
1349    if (listener == nullptr) {
1350        ALOGE("%s: Listener must not be null", __FUNCTION__);
1351        return BAD_VALUE;
1352    }
1353
1354    Mutex::Autolock lock(mServiceLock);
1355
1356    {
1357        Mutex::Autolock lock(mStatusListenerLock);
1358        for (auto& it : mListenerList) {
1359            if (IInterface::asBinder(it) == IInterface::asBinder(listener)) {
1360                ALOGW("%s: Tried to add listener %p which was already subscribed",
1361                      __FUNCTION__, listener.get());
1362                return ALREADY_EXISTS;
1363            }
1364        }
1365
1366        mListenerList.push_back(listener);
1367    }
1368
1369
1370    /* Immediately signal current status to this listener only */
1371    {
1372        Mutex::Autolock lock(mCameraStatesLock);
1373        for (auto& i : mCameraStates) {
1374            // TODO: Update binder to use String16 for camera IDs and remove;
1375            int id = cameraIdToInt(i.first);
1376            if (id == -1) continue;
1377
1378            listener->onStatusChanged(i.second->getStatus(), id);
1379        }
1380    }
1381
1382    /* Immediately signal current torch status to this listener only */
1383    {
1384        Mutex::Autolock al(mTorchStatusMutex);
1385        for (size_t i = 0; i < mTorchStatusMap.size(); i++ ) {
1386            String16 id = String16(mTorchStatusMap.keyAt(i).string());
1387            listener->onTorchStatusChanged(mTorchStatusMap.valueAt(i), id);
1388        }
1389    }
1390
1391    return OK;
1392}
1393
1394status_t CameraService::removeListener(const sp<ICameraServiceListener>& listener) {
1395    ATRACE_CALL();
1396
1397    ALOGV("%s: Remove listener %p", __FUNCTION__, listener.get());
1398
1399    if (listener == 0) {
1400        ALOGE("%s: Listener must not be null", __FUNCTION__);
1401        return BAD_VALUE;
1402    }
1403
1404    Mutex::Autolock lock(mServiceLock);
1405
1406    {
1407        Mutex::Autolock lock(mStatusListenerLock);
1408        for (auto it = mListenerList.begin(); it != mListenerList.end(); it++) {
1409            if (IInterface::asBinder(*it) == IInterface::asBinder(listener)) {
1410                mListenerList.erase(it);
1411                return OK;
1412            }
1413        }
1414    }
1415
1416    ALOGW("%s: Tried to remove a listener %p which was not subscribed",
1417          __FUNCTION__, listener.get());
1418
1419    return BAD_VALUE;
1420}
1421
1422status_t CameraService::getLegacyParameters(int cameraId, /*out*/String16* parameters) {
1423
1424    ATRACE_CALL();
1425    ALOGV("%s: for camera ID = %d", __FUNCTION__, cameraId);
1426
1427    if (parameters == NULL) {
1428        ALOGE("%s: parameters must not be null", __FUNCTION__);
1429        return BAD_VALUE;
1430    }
1431
1432    status_t ret = 0;
1433
1434    CameraParameters shimParams;
1435    if ((ret = getLegacyParametersLazy(cameraId, /*out*/&shimParams)) != OK) {
1436        // Error logged by caller
1437        return ret;
1438    }
1439
1440    String8 shimParamsString8 = shimParams.flatten();
1441    String16 shimParamsString16 = String16(shimParamsString8);
1442
1443    *parameters = shimParamsString16;
1444
1445    return OK;
1446}
1447
1448status_t CameraService::supportsCameraApi(int cameraId, int apiVersion) {
1449    ATRACE_CALL();
1450
1451    ALOGV("%s: for camera ID = %d", __FUNCTION__, cameraId);
1452
1453    switch (apiVersion) {
1454        case API_VERSION_1:
1455        case API_VERSION_2:
1456            break;
1457        default:
1458            ALOGE("%s: Bad API version %d", __FUNCTION__, apiVersion);
1459            return BAD_VALUE;
1460    }
1461
1462    int facing = -1;
1463    int deviceVersion = getDeviceVersion(cameraId, &facing);
1464
1465    switch(deviceVersion) {
1466      case CAMERA_DEVICE_API_VERSION_1_0:
1467      case CAMERA_DEVICE_API_VERSION_2_0:
1468      case CAMERA_DEVICE_API_VERSION_2_1:
1469      case CAMERA_DEVICE_API_VERSION_3_0:
1470      case CAMERA_DEVICE_API_VERSION_3_1:
1471        if (apiVersion == API_VERSION_2) {
1472            ALOGV("%s: Camera id %d uses HAL prior to HAL3.2, doesn't support api2 without shim",
1473                    __FUNCTION__, cameraId);
1474            return -EOPNOTSUPP;
1475        } else { // if (apiVersion == API_VERSION_1) {
1476            ALOGV("%s: Camera id %d uses older HAL before 3.2, but api1 is always supported",
1477                    __FUNCTION__, cameraId);
1478            return OK;
1479        }
1480      case CAMERA_DEVICE_API_VERSION_3_2:
1481      case CAMERA_DEVICE_API_VERSION_3_3:
1482        ALOGV("%s: Camera id %d uses HAL3.2 or newer, supports api1/api2 directly",
1483                __FUNCTION__, cameraId);
1484        return OK;
1485      case -1:
1486        ALOGE("%s: Invalid camera id %d", __FUNCTION__, cameraId);
1487        return BAD_VALUE;
1488      default:
1489        ALOGE("%s: Unknown camera device HAL version: %d", __FUNCTION__, deviceVersion);
1490        return INVALID_OPERATION;
1491    }
1492
1493    return OK;
1494}
1495
1496void CameraService::removeByClient(const BasicClient* client) {
1497    Mutex::Autolock lock(mServiceLock);
1498    for (auto& i : mActiveClientManager.getAll()) {
1499        auto clientSp = i->getValue();
1500        if (clientSp.get() == client) {
1501            mActiveClientManager.remove(i);
1502        }
1503    }
1504}
1505
1506bool CameraService::evictClientIdByRemote(const wp<IBinder>& remote) {
1507    const int callingPid = getCallingPid();
1508    const int servicePid = getpid();
1509    bool ret = false;
1510    {
1511        // Acquire mServiceLock and prevent other clients from connecting
1512        std::unique_ptr<AutoConditionLock> lock =
1513                AutoConditionLock::waitAndAcquire(mServiceLockWrapper);
1514
1515
1516        std::vector<sp<BasicClient>> evicted;
1517        for (auto& i : mActiveClientManager.getAll()) {
1518            auto clientSp = i->getValue();
1519            if (clientSp.get() == nullptr) {
1520                ALOGE("%s: Dead client still in mActiveClientManager.", __FUNCTION__);
1521                mActiveClientManager.remove(i);
1522                continue;
1523            }
1524            if (remote == clientSp->getRemote() && (callingPid == servicePid ||
1525                    callingPid == clientSp->getClientPid())) {
1526                mActiveClientManager.remove(i);
1527                evicted.push_back(clientSp);
1528
1529                // Notify the client of disconnection
1530                clientSp->notifyError(ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED,
1531                        CaptureResultExtras());
1532            }
1533        }
1534
1535        // Do not hold mServiceLock while disconnecting clients, but retain the condition blocking
1536        // other clients from connecting in mServiceLockWrapper if held
1537        mServiceLock.unlock();
1538
1539        // Do not clear caller identity, remote caller should be client proccess
1540
1541        for (auto& i : evicted) {
1542            if (i.get() != nullptr) {
1543                i->disconnect();
1544                ret = true;
1545            }
1546        }
1547
1548        // Reacquire mServiceLock
1549        mServiceLock.lock();
1550
1551    } // lock is destroyed, allow further connect calls
1552
1553    return ret;
1554}
1555
1556
1557/**
1558 * Check camera capabilities, such as support for basic color operation
1559 */
1560int CameraService::checkCameraCapabilities(int id, camera_info info, int *latestStrangeCameraId) {
1561
1562    // Assume all devices pre-v3.3 are backward-compatible
1563    bool isBackwardCompatible = true;
1564    if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_0
1565            && info.device_version >= CAMERA_DEVICE_API_VERSION_3_3) {
1566        isBackwardCompatible = false;
1567        status_t res;
1568        camera_metadata_ro_entry_t caps;
1569        res = find_camera_metadata_ro_entry(
1570            info.static_camera_characteristics,
1571            ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
1572            &caps);
1573        if (res != 0) {
1574            ALOGW("%s: Unable to find camera capabilities for camera device %d",
1575                    __FUNCTION__, id);
1576            caps.count = 0;
1577        }
1578        for (size_t i = 0; i < caps.count; i++) {
1579            if (caps.data.u8[i] ==
1580                    ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE) {
1581                isBackwardCompatible = true;
1582                break;
1583            }
1584        }
1585    }
1586
1587    if (!isBackwardCompatible) {
1588        mNumberOfNormalCameras--;
1589        *latestStrangeCameraId = id;
1590    } else {
1591        if (id > *latestStrangeCameraId) {
1592            ALOGE("%s: Normal camera ID %d higher than strange camera ID %d. "
1593                    "This is not allowed due backward-compatibility requirements",
1594                    __FUNCTION__, id, *latestStrangeCameraId);
1595            logServiceError("Invalid order of camera devices", ENODEV);
1596            mNumberOfCameras = 0;
1597            mNumberOfNormalCameras = 0;
1598            return INVALID_OPERATION;
1599        }
1600    }
1601    return OK;
1602}
1603
1604std::shared_ptr<CameraService::CameraState> CameraService::getCameraState(
1605        const String8& cameraId) const {
1606    std::shared_ptr<CameraState> state;
1607    {
1608        Mutex::Autolock lock(mCameraStatesLock);
1609        auto iter = mCameraStates.find(cameraId);
1610        if (iter != mCameraStates.end()) {
1611            state = iter->second;
1612        }
1613    }
1614    return state;
1615}
1616
1617sp<CameraService::BasicClient> CameraService::removeClientLocked(const String8& cameraId) {
1618    // Remove from active clients list
1619    auto clientDescriptorPtr = mActiveClientManager.remove(cameraId);
1620    if (clientDescriptorPtr == nullptr) {
1621        ALOGW("%s: Could not evict client, no client for camera ID %s", __FUNCTION__,
1622                cameraId.string());
1623        return sp<BasicClient>{nullptr};
1624    }
1625
1626    return clientDescriptorPtr->getValue();
1627}
1628
1629void CameraService::doUserSwitch(const int32_t* newUserId, size_t length) {
1630    // Acquire mServiceLock and prevent other clients from connecting
1631    std::unique_ptr<AutoConditionLock> lock =
1632            AutoConditionLock::waitAndAcquire(mServiceLockWrapper);
1633
1634    std::set<userid_t> newAllowedUsers;
1635    for (size_t i = 0; i < length; i++) {
1636        if (newUserId[i] < 0) {
1637            ALOGE("%s: Bad user ID %d given during user switch, ignoring.",
1638                    __FUNCTION__, newUserId[i]);
1639            return;
1640        }
1641        newAllowedUsers.insert(static_cast<userid_t>(newUserId[i]));
1642    }
1643
1644
1645    if (newAllowedUsers == mAllowedUsers) {
1646        ALOGW("%s: Received notification of user switch with no updated user IDs.", __FUNCTION__);
1647        return;
1648    }
1649
1650    logUserSwitch(mAllowedUsers, newAllowedUsers);
1651
1652    mAllowedUsers = std::move(newAllowedUsers);
1653
1654    // Current user has switched, evict all current clients.
1655    std::vector<sp<BasicClient>> evicted;
1656    for (auto& i : mActiveClientManager.getAll()) {
1657        auto clientSp = i->getValue();
1658
1659        if (clientSp.get() == nullptr) {
1660            ALOGE("%s: Dead client still in mActiveClientManager.", __FUNCTION__);
1661            continue;
1662        }
1663
1664        // Don't evict clients that are still allowed.
1665        uid_t clientUid = clientSp->getClientUid();
1666        userid_t clientUserId = multiuser_get_user_id(clientUid);
1667        if (mAllowedUsers.find(clientUserId) != mAllowedUsers.end()) {
1668            continue;
1669        }
1670
1671        evicted.push_back(clientSp);
1672
1673        String8 curTime = getFormattedCurrentTime();
1674
1675        ALOGE("Evicting conflicting client for camera ID %s due to user change",
1676                i->getKey().string());
1677
1678        // Log the clients evicted
1679        logEvent(String8::format("EVICT device %s client held by package %s (PID %"
1680                PRId32 ", priority %" PRId32 ")\n   - Evicted due to user switch.",
1681                i->getKey().string(), String8{clientSp->getPackageName()}.string(),
1682                i->getOwnerId(), i->getPriority()));
1683
1684    }
1685
1686    // Do not hold mServiceLock while disconnecting clients, but retain the condition
1687    // blocking other clients from connecting in mServiceLockWrapper if held.
1688    mServiceLock.unlock();
1689
1690    // Clear caller identity temporarily so client disconnect PID checks work correctly
1691    int64_t token = IPCThreadState::self()->clearCallingIdentity();
1692
1693    for (auto& i : evicted) {
1694        i->disconnect();
1695    }
1696
1697    IPCThreadState::self()->restoreCallingIdentity(token);
1698
1699    // Reacquire mServiceLock
1700    mServiceLock.lock();
1701}
1702
1703void CameraService::logEvent(const char* event) {
1704    String8 curTime = getFormattedCurrentTime();
1705    Mutex::Autolock l(mLogLock);
1706    mEventLog.add(String8::format("%s : %s", curTime.string(), event));
1707}
1708
1709void CameraService::logDisconnected(const char* cameraId, int clientPid,
1710        const char* clientPackage) {
1711    // Log the clients evicted
1712    logEvent(String8::format("DISCONNECT device %s client for package %s (PID %d)", cameraId,
1713            clientPackage, clientPid));
1714}
1715
1716void CameraService::logConnected(const char* cameraId, int clientPid,
1717        const char* clientPackage) {
1718    // Log the clients evicted
1719    logEvent(String8::format("CONNECT device %s client for package %s (PID %d)", cameraId,
1720            clientPackage, clientPid));
1721}
1722
1723void CameraService::logRejected(const char* cameraId, int clientPid,
1724        const char* clientPackage, const char* reason) {
1725    // Log the client rejected
1726    logEvent(String8::format("REJECT device %s client for package %s (PID %d), reason: (%s)",
1727            cameraId, clientPackage, clientPid, reason));
1728}
1729
1730void CameraService::logUserSwitch(const std::set<userid_t>& oldUserIds,
1731        const std::set<userid_t>& newUserIds) {
1732    String8 newUsers = toString(newUserIds);
1733    String8 oldUsers = toString(oldUserIds);
1734    // Log the new and old users
1735    logEvent(String8::format("USER_SWITCH previous allowed users: %s , current allowed users: %s",
1736            oldUsers.string(), newUsers.string()));
1737}
1738
1739void CameraService::logDeviceRemoved(const char* cameraId, const char* reason) {
1740    // Log the device removal
1741    logEvent(String8::format("REMOVE device %s, reason: (%s)", cameraId, reason));
1742}
1743
1744void CameraService::logDeviceAdded(const char* cameraId, const char* reason) {
1745    // Log the device removal
1746    logEvent(String8::format("ADD device %s, reason: (%s)", cameraId, reason));
1747}
1748
1749void CameraService::logClientDied(int clientPid, const char* reason) {
1750    // Log the device removal
1751    logEvent(String8::format("DIED client(s) with PID %d, reason: (%s)", clientPid, reason));
1752}
1753
1754void CameraService::logServiceError(const char* msg, int errorCode) {
1755    String8 curTime = getFormattedCurrentTime();
1756    logEvent(String8::format("SERVICE ERROR: %s : %d (%s)", msg, errorCode, strerror(errorCode)));
1757}
1758
1759status_t CameraService::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
1760        uint32_t flags) {
1761
1762    const int pid = getCallingPid();
1763    const int selfPid = getpid();
1764
1765    // Permission checks
1766    switch (code) {
1767        case BnCameraService::CONNECT:
1768        case BnCameraService::CONNECT_DEVICE:
1769        case BnCameraService::CONNECT_LEGACY: {
1770            if (pid != selfPid) {
1771                // we're called from a different process, do the real check
1772                if (!checkCallingPermission(
1773                        String16("android.permission.CAMERA"))) {
1774                    const int uid = getCallingUid();
1775                    ALOGE("Permission Denial: "
1776                         "can't use the camera pid=%d, uid=%d", pid, uid);
1777                    return PERMISSION_DENIED;
1778                }
1779            }
1780            break;
1781        }
1782        case BnCameraService::NOTIFY_SYSTEM_EVENT: {
1783            if (pid != selfPid) {
1784                // Ensure we're being called by system_server, or similar process with
1785                // permissions to notify the camera service about system events
1786                if (!checkCallingPermission(
1787                        String16("android.permission.CAMERA_SEND_SYSTEM_EVENTS"))) {
1788                    const int uid = getCallingUid();
1789                    ALOGE("Permission Denial: cannot send updates to camera service about system"
1790                            " events from pid=%d, uid=%d", pid, uid);
1791                    return PERMISSION_DENIED;
1792                }
1793            }
1794            break;
1795        }
1796    }
1797
1798    return BnCameraService::onTransact(code, data, reply, flags);
1799}
1800
1801// We share the media players for shutter and recording sound for all clients.
1802// A reference count is kept to determine when we will actually release the
1803// media players.
1804
1805MediaPlayer* CameraService::newMediaPlayer(const char *file) {
1806    MediaPlayer* mp = new MediaPlayer();
1807    if (mp->setDataSource(NULL /* httpService */, file, NULL) == NO_ERROR) {
1808        mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE);
1809        mp->prepare();
1810    } else {
1811        ALOGE("Failed to load CameraService sounds: %s", file);
1812        return NULL;
1813    }
1814    return mp;
1815}
1816
1817void CameraService::loadSound() {
1818    ATRACE_CALL();
1819
1820    Mutex::Autolock lock(mSoundLock);
1821    LOG1("CameraService::loadSound ref=%d", mSoundRef);
1822    if (mSoundRef++) return;
1823
1824    mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
1825    mSoundPlayer[SOUND_RECORDING_START] = newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");
1826    mSoundPlayer[SOUND_RECORDING_STOP] = newMediaPlayer("/system/media/audio/ui/VideoStop.ogg");
1827}
1828
1829void CameraService::releaseSound() {
1830    Mutex::Autolock lock(mSoundLock);
1831    LOG1("CameraService::releaseSound ref=%d", mSoundRef);
1832    if (--mSoundRef) return;
1833
1834    for (int i = 0; i < NUM_SOUNDS; i++) {
1835        if (mSoundPlayer[i] != 0) {
1836            mSoundPlayer[i]->disconnect();
1837            mSoundPlayer[i].clear();
1838        }
1839    }
1840}
1841
1842void CameraService::playSound(sound_kind kind) {
1843    ATRACE_CALL();
1844
1845    LOG1("playSound(%d)", kind);
1846    Mutex::Autolock lock(mSoundLock);
1847    sp<MediaPlayer> player = mSoundPlayer[kind];
1848    if (player != 0) {
1849        player->seekTo(0);
1850        player->start();
1851    }
1852}
1853
1854// ----------------------------------------------------------------------------
1855
1856CameraService::Client::Client(const sp<CameraService>& cameraService,
1857        const sp<ICameraClient>& cameraClient,
1858        const String16& clientPackageName,
1859        int cameraId, int cameraFacing,
1860        int clientPid, uid_t clientUid,
1861        int servicePid) :
1862        CameraService::BasicClient(cameraService,
1863                IInterface::asBinder(cameraClient),
1864                clientPackageName,
1865                cameraId, cameraFacing,
1866                clientPid, clientUid,
1867                servicePid)
1868{
1869    int callingPid = getCallingPid();
1870    LOG1("Client::Client E (pid %d, id %d)", callingPid, cameraId);
1871
1872    mRemoteCallback = cameraClient;
1873
1874    cameraService->loadSound();
1875
1876    LOG1("Client::Client X (pid %d, id %d)", callingPid, cameraId);
1877}
1878
1879// tear down the client
1880CameraService::Client::~Client() {
1881    ALOGV("~Client");
1882    mDestructionStarted = true;
1883
1884    mCameraService->releaseSound();
1885    // unconditionally disconnect. function is idempotent
1886    Client::disconnect();
1887}
1888
1889CameraService::BasicClient::BasicClient(const sp<CameraService>& cameraService,
1890        const sp<IBinder>& remoteCallback,
1891        const String16& clientPackageName,
1892        int cameraId, int cameraFacing,
1893        int clientPid, uid_t clientUid,
1894        int servicePid):
1895        mClientPackageName(clientPackageName), mDisconnected(false)
1896{
1897    mCameraService = cameraService;
1898    mRemoteBinder = remoteCallback;
1899    mCameraId = cameraId;
1900    mCameraFacing = cameraFacing;
1901    mClientPid = clientPid;
1902    mClientUid = clientUid;
1903    mServicePid = servicePid;
1904    mOpsActive = false;
1905    mDestructionStarted = false;
1906}
1907
1908CameraService::BasicClient::~BasicClient() {
1909    ALOGV("~BasicClient");
1910    mDestructionStarted = true;
1911}
1912
1913void CameraService::BasicClient::disconnect() {
1914    if (mDisconnected) {
1915        return;
1916    }
1917    mDisconnected = true;
1918
1919    mCameraService->removeByClient(this);
1920    mCameraService->logDisconnected(String8::format("%d", mCameraId), mClientPid,
1921            String8(mClientPackageName));
1922
1923    sp<IBinder> remote = getRemote();
1924    if (remote != nullptr) {
1925        remote->unlinkToDeath(mCameraService);
1926    }
1927
1928    finishCameraOps();
1929    ALOGI("%s: Disconnected client for camera %d for PID %d", __FUNCTION__, mCameraId, mClientPid);
1930
1931    // client shouldn't be able to call into us anymore
1932    mClientPid = 0;
1933}
1934
1935String16 CameraService::BasicClient::getPackageName() const {
1936    return mClientPackageName;
1937}
1938
1939
1940int CameraService::BasicClient::getClientPid() const {
1941    return mClientPid;
1942}
1943
1944uid_t CameraService::BasicClient::getClientUid() const {
1945    return mClientUid;
1946}
1947
1948bool CameraService::BasicClient::canCastToApiClient(apiLevel level) const {
1949    // Defaults to API2.
1950    return level == API_2;
1951}
1952
1953status_t CameraService::BasicClient::startCameraOps() {
1954    ATRACE_CALL();
1955
1956    int32_t res;
1957    // Notify app ops that the camera is not available
1958    mOpsCallback = new OpsCallback(this);
1959
1960    {
1961        ALOGV("%s: Start camera ops, package name = %s, client UID = %d",
1962              __FUNCTION__, String8(mClientPackageName).string(), mClientUid);
1963    }
1964
1965    mAppOpsManager.startWatchingMode(AppOpsManager::OP_CAMERA,
1966            mClientPackageName, mOpsCallback);
1967    res = mAppOpsManager.startOp(AppOpsManager::OP_CAMERA,
1968            mClientUid, mClientPackageName);
1969
1970    if (res == AppOpsManager::MODE_ERRORED) {
1971        ALOGI("Camera %d: Access for \"%s\" has been revoked",
1972                mCameraId, String8(mClientPackageName).string());
1973        return PERMISSION_DENIED;
1974    }
1975
1976    if (res == AppOpsManager::MODE_IGNORED) {
1977        ALOGI("Camera %d: Access for \"%s\" has been restricted",
1978                mCameraId, String8(mClientPackageName).string());
1979        // Return the same error as for device policy manager rejection
1980        return -EACCES;
1981    }
1982
1983    mOpsActive = true;
1984
1985    // Transition device availability listeners from PRESENT -> NOT_AVAILABLE
1986    mCameraService->updateStatus(ICameraServiceListener::STATUS_NOT_AVAILABLE,
1987            String8::format("%d", mCameraId));
1988
1989    // Transition device state to OPEN
1990    mCameraService->updateProxyDeviceState(ICameraServiceProxy::CAMERA_STATE_OPEN,
1991            String8::format("%d", mCameraId));
1992
1993    return OK;
1994}
1995
1996status_t CameraService::BasicClient::finishCameraOps() {
1997    ATRACE_CALL();
1998
1999    // Check if startCameraOps succeeded, and if so, finish the camera op
2000    if (mOpsActive) {
2001        // Notify app ops that the camera is available again
2002        mAppOpsManager.finishOp(AppOpsManager::OP_CAMERA, mClientUid,
2003                mClientPackageName);
2004        mOpsActive = false;
2005
2006        auto rejected = {ICameraServiceListener::STATUS_NOT_PRESENT,
2007                ICameraServiceListener::STATUS_ENUMERATING};
2008
2009        // Transition to PRESENT if the camera is not in either of the rejected states
2010        mCameraService->updateStatus(ICameraServiceListener::STATUS_PRESENT,
2011                String8::format("%d", mCameraId), rejected);
2012
2013        // Transition device state to CLOSED
2014        mCameraService->updateProxyDeviceState(ICameraServiceProxy::CAMERA_STATE_CLOSED,
2015                String8::format("%d", mCameraId));
2016
2017        // Notify flashlight that a camera device is closed.
2018        mCameraService->mFlashlight->deviceClosed(
2019                String8::format("%d", mCameraId));
2020    }
2021    // Always stop watching, even if no camera op is active
2022    if (mOpsCallback != NULL) {
2023        mAppOpsManager.stopWatchingMode(mOpsCallback);
2024    }
2025    mOpsCallback.clear();
2026
2027    return OK;
2028}
2029
2030void CameraService::BasicClient::opChanged(int32_t op, const String16& packageName) {
2031    ATRACE_CALL();
2032
2033    String8 name(packageName);
2034    String8 myName(mClientPackageName);
2035
2036    if (op != AppOpsManager::OP_CAMERA) {
2037        ALOGW("Unexpected app ops notification received: %d", op);
2038        return;
2039    }
2040
2041    int32_t res;
2042    res = mAppOpsManager.checkOp(AppOpsManager::OP_CAMERA,
2043            mClientUid, mClientPackageName);
2044    ALOGV("checkOp returns: %d, %s ", res,
2045            res == AppOpsManager::MODE_ALLOWED ? "ALLOWED" :
2046            res == AppOpsManager::MODE_IGNORED ? "IGNORED" :
2047            res == AppOpsManager::MODE_ERRORED ? "ERRORED" :
2048            "UNKNOWN");
2049
2050    if (res != AppOpsManager::MODE_ALLOWED) {
2051        ALOGI("Camera %d: Access for \"%s\" revoked", mCameraId,
2052                myName.string());
2053        // Reset the client PID to allow server-initiated disconnect,
2054        // and to prevent further calls by client.
2055        mClientPid = getCallingPid();
2056        CaptureResultExtras resultExtras; // a dummy result (invalid)
2057        notifyError(ICameraDeviceCallbacks::ERROR_CAMERA_SERVICE, resultExtras);
2058        disconnect();
2059    }
2060}
2061
2062// ----------------------------------------------------------------------------
2063
2064// Provide client strong pointer for callbacks.
2065sp<CameraService::Client> CameraService::Client::getClientFromCookie(void* user) {
2066    String8 cameraId = String8::format("%d", (int)(intptr_t) user);
2067    auto clientDescriptor = gCameraService->mActiveClientManager.get(cameraId);
2068    if (clientDescriptor != nullptr) {
2069        return sp<Client>{
2070                static_cast<Client*>(clientDescriptor->getValue().get())};
2071    }
2072    return sp<Client>{nullptr};
2073}
2074
2075void CameraService::Client::notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode,
2076        const CaptureResultExtras& resultExtras) {
2077    if (mRemoteCallback != NULL) {
2078        mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_RELEASED, 0);
2079    } else {
2080        ALOGE("mRemoteCallback is NULL!!");
2081    }
2082}
2083
2084// NOTE: function is idempotent
2085void CameraService::Client::disconnect() {
2086    ALOGV("Client::disconnect");
2087    BasicClient::disconnect();
2088}
2089
2090bool CameraService::Client::canCastToApiClient(apiLevel level) const {
2091    return level == API_1;
2092}
2093
2094CameraService::Client::OpsCallback::OpsCallback(wp<BasicClient> client):
2095        mClient(client) {
2096}
2097
2098void CameraService::Client::OpsCallback::opChanged(int32_t op,
2099        const String16& packageName) {
2100    sp<BasicClient> client = mClient.promote();
2101    if (client != NULL) {
2102        client->opChanged(op, packageName);
2103    }
2104}
2105
2106// ----------------------------------------------------------------------------
2107//                  CameraState
2108// ----------------------------------------------------------------------------
2109
2110CameraService::CameraState::CameraState(const String8& id, int cost,
2111        const std::set<String8>& conflicting) : mId(id),
2112        mStatus(ICameraServiceListener::STATUS_PRESENT), mCost(cost), mConflicting(conflicting) {}
2113
2114CameraService::CameraState::~CameraState() {}
2115
2116ICameraServiceListener::Status CameraService::CameraState::getStatus() const {
2117    Mutex::Autolock lock(mStatusLock);
2118    return mStatus;
2119}
2120
2121CameraParameters CameraService::CameraState::getShimParams() const {
2122    return mShimParams;
2123}
2124
2125void CameraService::CameraState::setShimParams(const CameraParameters& params) {
2126    mShimParams = params;
2127}
2128
2129int CameraService::CameraState::getCost() const {
2130    return mCost;
2131}
2132
2133std::set<String8> CameraService::CameraState::getConflicting() const {
2134    return mConflicting;
2135}
2136
2137String8 CameraService::CameraState::getId() const {
2138    return mId;
2139}
2140
2141// ----------------------------------------------------------------------------
2142//                  ClientEventListener
2143// ----------------------------------------------------------------------------
2144
2145void CameraService::ClientEventListener::onClientAdded(
2146        const resource_policy::ClientDescriptor<String8,
2147        sp<CameraService::BasicClient>>& descriptor) {
2148    auto basicClient = descriptor.getValue();
2149    if (basicClient.get() != nullptr) {
2150        BatteryNotifier& notifier(BatteryNotifier::getInstance());
2151        notifier.noteStartCamera(descriptor.getKey(),
2152                static_cast<int>(basicClient->getClientUid()));
2153    }
2154}
2155
2156void CameraService::ClientEventListener::onClientRemoved(
2157        const resource_policy::ClientDescriptor<String8,
2158        sp<CameraService::BasicClient>>& descriptor) {
2159    auto basicClient = descriptor.getValue();
2160    if (basicClient.get() != nullptr) {
2161        BatteryNotifier& notifier(BatteryNotifier::getInstance());
2162        notifier.noteStopCamera(descriptor.getKey(),
2163                static_cast<int>(basicClient->getClientUid()));
2164    }
2165}
2166
2167
2168// ----------------------------------------------------------------------------
2169//                  CameraClientManager
2170// ----------------------------------------------------------------------------
2171
2172CameraService::CameraClientManager::CameraClientManager() {
2173    setListener(std::make_shared<ClientEventListener>());
2174}
2175
2176CameraService::CameraClientManager::~CameraClientManager() {}
2177
2178sp<CameraService::BasicClient> CameraService::CameraClientManager::getCameraClient(
2179        const String8& id) const {
2180    auto descriptor = get(id);
2181    if (descriptor == nullptr) {
2182        return sp<BasicClient>{nullptr};
2183    }
2184    return descriptor->getValue();
2185}
2186
2187String8 CameraService::CameraClientManager::toString() const {
2188    auto all = getAll();
2189    String8 ret("[");
2190    bool hasAny = false;
2191    for (auto& i : all) {
2192        hasAny = true;
2193        String8 key = i->getKey();
2194        int32_t cost = i->getCost();
2195        int32_t pid = i->getOwnerId();
2196        int32_t priority = i->getPriority();
2197        auto conflicting = i->getConflicting();
2198        auto clientSp = i->getValue();
2199        String8 packageName;
2200        userid_t clientUserId = 0;
2201        if (clientSp.get() != nullptr) {
2202            packageName = String8{clientSp->getPackageName()};
2203            uid_t clientUid = clientSp->getClientUid();
2204            clientUserId = multiuser_get_user_id(clientUid);
2205        }
2206        ret.appendFormat("\n(Camera ID: %s, Cost: %" PRId32 ", PID: %" PRId32 ", Priority: %"
2207                PRId32 ", ", key.string(), cost, pid, priority);
2208
2209        if (clientSp.get() != nullptr) {
2210            ret.appendFormat("User Id: %d, ", clientUserId);
2211        }
2212        if (packageName.size() != 0) {
2213            ret.appendFormat("Client Package Name: %s", packageName.string());
2214        }
2215
2216        ret.append(", Conflicting Client Devices: {");
2217        for (auto& j : conflicting) {
2218            ret.appendFormat("%s, ", j.string());
2219        }
2220        ret.append("})");
2221    }
2222    if (hasAny) ret.append("\n");
2223    ret.append("]\n");
2224    return ret;
2225}
2226
2227CameraService::DescriptorPtr CameraService::CameraClientManager::makeClientDescriptor(
2228        const String8& key, const sp<BasicClient>& value, int32_t cost,
2229        const std::set<String8>& conflictingKeys, int32_t priority, int32_t ownerId) {
2230
2231    return std::make_shared<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>(
2232            key, value, cost, conflictingKeys, priority, ownerId);
2233}
2234
2235CameraService::DescriptorPtr CameraService::CameraClientManager::makeClientDescriptor(
2236        const sp<BasicClient>& value, const CameraService::DescriptorPtr& partial) {
2237    return makeClientDescriptor(partial->getKey(), value, partial->getCost(),
2238            partial->getConflicting(), partial->getPriority(), partial->getOwnerId());
2239}
2240
2241// ----------------------------------------------------------------------------
2242
2243static const int kDumpLockRetries = 50;
2244static const int kDumpLockSleep = 60000;
2245
2246static bool tryLock(Mutex& mutex)
2247{
2248    bool locked = false;
2249    for (int i = 0; i < kDumpLockRetries; ++i) {
2250        if (mutex.tryLock() == NO_ERROR) {
2251            locked = true;
2252            break;
2253        }
2254        usleep(kDumpLockSleep);
2255    }
2256    return locked;
2257}
2258
2259status_t CameraService::dump(int fd, const Vector<String16>& args) {
2260    ATRACE_CALL();
2261
2262    String8 result("Dump of the Camera Service:\n");
2263    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
2264        result = result.format("Permission Denial: "
2265                "can't dump CameraService from pid=%d, uid=%d\n",
2266                getCallingPid(),
2267                getCallingUid());
2268        write(fd, result.string(), result.size());
2269    } else {
2270        bool locked = tryLock(mServiceLock);
2271        // failed to lock - CameraService is probably deadlocked
2272        if (!locked) {
2273            result.append("CameraService may be deadlocked\n");
2274            write(fd, result.string(), result.size());
2275        }
2276
2277        bool hasClient = false;
2278        if (!mModule) {
2279            result = String8::format("No camera module available!\n");
2280            write(fd, result.string(), result.size());
2281
2282            // Dump event log for error information
2283            dumpEventLog(fd);
2284
2285            if (locked) mServiceLock.unlock();
2286            return NO_ERROR;
2287        }
2288
2289        result = String8::format("Camera module HAL API version: 0x%x\n", mModule->getHalApiVersion());
2290        result.appendFormat("Camera module API version: 0x%x\n", mModule->getModuleApiVersion());
2291        result.appendFormat("Camera module name: %s\n", mModule->getModuleName());
2292        result.appendFormat("Camera module author: %s\n", mModule->getModuleAuthor());
2293        result.appendFormat("Number of camera devices: %d\n", mNumberOfCameras);
2294        String8 activeClientString = mActiveClientManager.toString();
2295        result.appendFormat("Active Camera Clients:\n%s", activeClientString.string());
2296        result.appendFormat("Allowed users:\n%s\n", toString(mAllowedUsers).string());
2297
2298        sp<VendorTagDescriptor> desc = VendorTagDescriptor::getGlobalVendorTagDescriptor();
2299        if (desc == NULL) {
2300            result.appendFormat("Vendor tags left unimplemented.\n");
2301        } else {
2302            result.appendFormat("Vendor tag definitions:\n");
2303        }
2304
2305        write(fd, result.string(), result.size());
2306
2307        if (desc != NULL) {
2308            desc->dump(fd, /*verbosity*/2, /*indentation*/4);
2309        }
2310
2311        dumpEventLog(fd);
2312
2313        bool stateLocked = tryLock(mCameraStatesLock);
2314        if (!stateLocked) {
2315            result = String8::format("CameraStates in use, may be deadlocked\n");
2316            write(fd, result.string(), result.size());
2317        }
2318
2319        for (auto& state : mCameraStates) {
2320            String8 cameraId = state.first;
2321            result = String8::format("Camera %s information:\n", cameraId.string());
2322            camera_info info;
2323
2324            // TODO: Change getCameraInfo + HAL to use String cameraIds
2325            status_t rc = mModule->getCameraInfo(cameraIdToInt(cameraId), &info);
2326            if (rc != OK) {
2327                result.appendFormat("  Error reading static information!\n");
2328                write(fd, result.string(), result.size());
2329            } else {
2330                result.appendFormat("  Facing: %s\n",
2331                        info.facing == CAMERA_FACING_BACK ? "BACK" : "FRONT");
2332                result.appendFormat("  Orientation: %d\n", info.orientation);
2333                int deviceVersion;
2334                if (mModule->getModuleApiVersion() < CAMERA_MODULE_API_VERSION_2_0) {
2335                    deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
2336                } else {
2337                    deviceVersion = info.device_version;
2338                }
2339
2340                auto conflicting = state.second->getConflicting();
2341                result.appendFormat("  Resource Cost: %d\n", state.second->getCost());
2342                result.appendFormat("  Conflicting Devices:");
2343                for (auto& id : conflicting) {
2344                    result.appendFormat(" %s", cameraId.string());
2345                }
2346                if (conflicting.size() == 0) {
2347                    result.appendFormat(" NONE");
2348                }
2349                result.appendFormat("\n");
2350
2351                result.appendFormat("  Device version: %#x\n", deviceVersion);
2352                if (deviceVersion >= CAMERA_DEVICE_API_VERSION_2_0) {
2353                    result.appendFormat("  Device static metadata:\n");
2354                    write(fd, result.string(), result.size());
2355                    dump_indented_camera_metadata(info.static_camera_characteristics,
2356                            fd, /*verbosity*/2, /*indentation*/4);
2357                } else {
2358                    write(fd, result.string(), result.size());
2359                }
2360
2361                CameraParameters p = state.second->getShimParams();
2362                if (!p.isEmpty()) {
2363                    result = String8::format("  Camera1 API shim is using parameters:\n        ");
2364                    write(fd, result.string(), result.size());
2365                    p.dump(fd, args);
2366                }
2367            }
2368
2369            auto clientDescriptor = mActiveClientManager.get(cameraId);
2370            if (clientDescriptor == nullptr) {
2371                result = String8::format("  Device %s is closed, no client instance\n",
2372                        cameraId.string());
2373                write(fd, result.string(), result.size());
2374                continue;
2375            }
2376            hasClient = true;
2377            result = String8::format("  Device %s is open. Client instance dump:\n\n",
2378                    cameraId.string());
2379            result.appendFormat("Client priority level: %d\n", clientDescriptor->getPriority());
2380            result.appendFormat("Client PID: %d\n", clientDescriptor->getOwnerId());
2381
2382            auto client = clientDescriptor->getValue();
2383            result.appendFormat("Client package: %s\n",
2384                    String8(client->getPackageName()).string());
2385            write(fd, result.string(), result.size());
2386
2387            client->dump(fd, args);
2388        }
2389
2390        if (stateLocked) mCameraStatesLock.unlock();
2391
2392        if (!hasClient) {
2393            result = String8::format("\nNo active camera clients yet.\n");
2394            write(fd, result.string(), result.size());
2395        }
2396
2397        if (locked) mServiceLock.unlock();
2398
2399        // Dump camera traces if there were any
2400        write(fd, "\n", 1);
2401        camera3::CameraTraces::dump(fd, args);
2402
2403        // change logging level
2404        int n = args.size();
2405        for (int i = 0; i + 1 < n; i++) {
2406            String16 verboseOption("-v");
2407            if (args[i] == verboseOption) {
2408                String8 levelStr(args[i+1]);
2409                int level = atoi(levelStr.string());
2410                result = String8::format("\nSetting log level to %d.\n", level);
2411                setLogLevel(level);
2412                write(fd, result.string(), result.size());
2413            }
2414        }
2415    }
2416    return NO_ERROR;
2417}
2418
2419void CameraService::dumpEventLog(int fd) {
2420    String8 result = String8("\nPrior client events (most recent at top):\n");
2421
2422    Mutex::Autolock l(mLogLock);
2423    for (const auto& msg : mEventLog) {
2424        result.appendFormat("  %s\n", msg.string());
2425    }
2426
2427    if (mEventLog.size() == DEFAULT_EVENT_LOG_LENGTH) {
2428        result.append("  ...\n");
2429    } else if (mEventLog.size() == 0) {
2430        result.append("  [no events yet]\n");
2431    }
2432    result.append("\n");
2433
2434    write(fd, result.string(), result.size());
2435}
2436
2437void CameraService::handleTorchClientBinderDied(const wp<IBinder> &who) {
2438    Mutex::Autolock al(mTorchClientMapMutex);
2439    for (size_t i = 0; i < mTorchClientMap.size(); i++) {
2440        if (mTorchClientMap[i] == who) {
2441            // turn off the torch mode that was turned on by dead client
2442            String8 cameraId = mTorchClientMap.keyAt(i);
2443            status_t res = mFlashlight->setTorchMode(cameraId, false);
2444            if (res) {
2445                ALOGE("%s: torch client died but couldn't turn off torch: "
2446                    "%s (%d)", __FUNCTION__, strerror(-res), res);
2447                return;
2448            }
2449            mTorchClientMap.removeItemsAt(i);
2450            break;
2451        }
2452    }
2453}
2454
2455/*virtual*/void CameraService::binderDied(const wp<IBinder> &who) {
2456
2457    /**
2458      * While tempting to promote the wp<IBinder> into a sp, it's actually not supported by the
2459      * binder driver
2460      */
2461
2462    logClientDied(getCallingPid(), String8("Binder died unexpectedly"));
2463
2464    // check torch client
2465    handleTorchClientBinderDied(who);
2466
2467    // check camera device client
2468    if(!evictClientIdByRemote(who)) {
2469        ALOGV("%s: Java client's binder death already cleaned up (normal case)", __FUNCTION__);
2470        return;
2471    }
2472
2473    ALOGE("%s: Java client's binder died, removing it from the list of active clients",
2474            __FUNCTION__);
2475}
2476
2477void CameraService::updateStatus(ICameraServiceListener::Status status, const String8& cameraId) {
2478    updateStatus(status, cameraId, {});
2479}
2480
2481void CameraService::updateStatus(ICameraServiceListener::Status status, const String8& cameraId,
2482        std::initializer_list<ICameraServiceListener::Status> rejectSourceStates) {
2483    // Do not lock mServiceLock here or can get into a deadlock from
2484    // connect() -> disconnect -> updateStatus
2485
2486    auto state = getCameraState(cameraId);
2487
2488    if (state == nullptr) {
2489        ALOGW("%s: Could not update the status for %s, no such device exists", __FUNCTION__,
2490                cameraId.string());
2491        return;
2492    }
2493
2494    // Update the status for this camera state, then send the onStatusChangedCallbacks to each
2495    // of the listeners with both the mStatusStatus and mStatusListenerLock held
2496    state->updateStatus(status, cameraId, rejectSourceStates, [this]
2497            (const String8& cameraId, ICameraServiceListener::Status status) {
2498
2499            if (status != ICameraServiceListener::STATUS_ENUMERATING) {
2500                // Update torch status if it has a flash unit.
2501                Mutex::Autolock al(mTorchStatusMutex);
2502                ICameraServiceListener::TorchStatus torchStatus;
2503                if (getTorchStatusLocked(cameraId, &torchStatus) !=
2504                        NAME_NOT_FOUND) {
2505                    ICameraServiceListener::TorchStatus newTorchStatus =
2506                            status == ICameraServiceListener::STATUS_PRESENT ?
2507                            ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF :
2508                            ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE;
2509                    if (torchStatus != newTorchStatus) {
2510                        onTorchStatusChangedLocked(cameraId, newTorchStatus);
2511                    }
2512                }
2513            }
2514
2515            Mutex::Autolock lock(mStatusListenerLock);
2516
2517            for (auto& listener : mListenerList) {
2518                // TODO: Refactor status listeners to use strings for Camera IDs and remove this.
2519                int id = cameraIdToInt(cameraId);
2520                if (id != -1) listener->onStatusChanged(status, id);
2521            }
2522        });
2523}
2524
2525void CameraService::updateProxyDeviceState(ICameraServiceProxy::CameraState newState,
2526        const String8& cameraId) {
2527    sp<ICameraServiceProxy> proxyBinder = getCameraServiceProxy();
2528    if (proxyBinder == nullptr) return;
2529    String16 id(cameraId);
2530    proxyBinder->notifyCameraState(id, newState);
2531}
2532
2533status_t CameraService::getTorchStatusLocked(
2534        const String8& cameraId,
2535        ICameraServiceListener::TorchStatus *status) const {
2536    if (!status) {
2537        return BAD_VALUE;
2538    }
2539    ssize_t index = mTorchStatusMap.indexOfKey(cameraId);
2540    if (index == NAME_NOT_FOUND) {
2541        // invalid camera ID or the camera doesn't have a flash unit
2542        return NAME_NOT_FOUND;
2543    }
2544
2545    *status = mTorchStatusMap.valueAt(index);
2546    return OK;
2547}
2548
2549status_t CameraService::setTorchStatusLocked(const String8& cameraId,
2550        ICameraServiceListener::TorchStatus status) {
2551    ssize_t index = mTorchStatusMap.indexOfKey(cameraId);
2552    if (index == NAME_NOT_FOUND) {
2553        return BAD_VALUE;
2554    }
2555    ICameraServiceListener::TorchStatus& item =
2556            mTorchStatusMap.editValueAt(index);
2557    item = status;
2558
2559    return OK;
2560}
2561
2562}; // namespace android
2563