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