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