165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian/*
2d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk * Copyright (C) 2008 The Android Open Source Project
3d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk *
4d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk * Licensed under the Apache License, Version 2.0 (the "License");
5d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk * you may not use this file except in compliance with the License.
6d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk * You may obtain a copy of the License at
7d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk *
8d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk *      http://www.apache.org/licenses/LICENSE-2.0
9d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk *
10d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk * Unless required by applicable law or agreed to in writing, software
11d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk * distributed under the License is distributed on an "AS IS" BASIS,
12d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk * See the License for the specific language governing permissions and
14d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk * limitations under the License.
15d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk */
1665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#define LOG_TAG "CameraService"
18a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala#define ATRACE_TAG ATRACE_TAG_CAMERA
198951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev//#define LOG_NDEBUG 0
2065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
21cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk#include <algorithm>
22cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk#include <climits>
2365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <stdio.h>
24cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk#include <cstring>
25cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk#include <ctime>
26cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk#include <string>
2765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <sys/types.h>
28cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk#include <inttypes.h>
2965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <pthread.h>
3065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
31d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala#include <android/hardware/ICamera.h>
32d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala#include <android/hardware/ICameraClient.h>
33d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala
349c2a2c26c0d70de97f51063b06a5efc79b327eedAlex Deymo#include <android-base/macros.h>
352f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala#include <android-base/parseint.h>
36ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala#include <binder/AppOpsManager.h>
3765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <binder/IPCThreadState.h>
3865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <binder/IServiceManager.h>
3965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <binder/MemoryBase.h>
4065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <binder/MemoryHeapBase.h>
41cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk#include <binder/ProcessInfoService.h>
4265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <cutils/atomic.h>
43b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra#include <cutils/properties.h>
44df712ea86e6350f7005a02ab0e1c60c28a343ed0Mathias Agopian#include <gui/Surface.h>
4565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <hardware/hardware.h>
46d89821ec5481e0640d84bfe3e29a1254a52ca683Eino-Ville Talvala#include <memunreachable/memunreachable.h>
4765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <media/AudioSystem.h>
481b86fe063badb5f28c467ade39be0f4008688947Andreas Huber#include <media/IMediaHTTPService.h>
4965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <media/mediaplayer.h>
5099e69716215cd0665379bc90d708f2ea8689831dRuben Brunk#include <mediautils/BatteryNotifier.h>
5165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/Errors.h>
5265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/Log.h>
5365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/String16.h>
54d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk#include <utils/Trace.h>
5598a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen#include <private/android_filesystem_config.h>
56d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk#include <system/camera_vendor_tags.h>
57b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk#include <system/camera_metadata.h>
582f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
59b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk#include <system/camera.h>
6065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
6165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include "CameraService.h"
627b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala#include "api1/CameraClient.h"
637b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala#include "api1/Camera2Client.h"
647b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala#include "api2/CameraDeviceClient.h"
65ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin#include "utils/CameraTraces.h"
6665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
670dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yehnamespace {
680dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    const char* kPermissionServiceName = "permission";
690dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh}; // namespace anonymous
700dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
7165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiannamespace android {
7265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
73d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvalausing binder::Status;
74f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalausing hardware::ICamera;
75f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalausing hardware::ICameraClient;
76f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalausing hardware::ICameraServiceListener;
77f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalausing hardware::camera::common::V1_0::CameraDeviceStatus;
78f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalausing hardware::camera::common::V1_0::TorchModeStatus;
79d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala
8065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
8165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// Logging support -- this is for debugging only
8265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// Use "adb shell dumpsys media.camera -v 1" to change it.
835e08d60617fc63c2e41f9069ff89f5c00db2617dEino-Ville Talvalavolatile int32_t gLogLevel = 0;
8465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
85b8a805261bf0282e992d3608035e47d05a898710Steve Block#define LOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__);
86b8a805261bf0282e992d3608035e47d05a898710Steve Block#define LOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__);
8765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
8865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic void setLogLevel(int level) {
8965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    android_atomic_write(level, &gLogLevel);
9065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
9165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
92d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala// Convenience methods for constructing binder::Status objects for error returns
93d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala
94d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala#define STATUS_ERROR(errorCode, errorString) \
95d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    binder::Status::fromServiceSpecificError(errorCode, \
96d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            String8::format("%s:%d: %s", __FUNCTION__, __LINE__, errorString))
97d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala
98d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala#define STATUS_ERROR_FMT(errorCode, errorString, ...) \
99d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    binder::Status::fromServiceSpecificError(errorCode, \
100d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            String8::format("%s:%d: " errorString, __FUNCTION__, __LINE__, \
101d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    __VA_ARGS__))
102d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala
10365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
10465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
105cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkinextern "C" {
106cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkinstatic void camera_device_status_change(
107cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin        const struct camera_module_callbacks* callbacks,
108cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin        int camera_id,
109cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin        int new_status) {
110cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin    sp<CameraService> cs = const_cast<CameraService*>(
111cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            static_cast<const CameraService*>(callbacks));
112f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    String8 id = String8::format("%d", camera_id);
113cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin
114f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    CameraDeviceStatus newStatus{CameraDeviceStatus::NOT_PRESENT};
115f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    switch (new_status) {
116f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        case CAMERA_DEVICE_STATUS_NOT_PRESENT:
117f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            newStatus = CameraDeviceStatus::NOT_PRESENT;
118f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            break;
119f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        case CAMERA_DEVICE_STATUS_PRESENT:
120f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            newStatus = CameraDeviceStatus::PRESENT;
121f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            break;
122f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        case CAMERA_DEVICE_STATUS_ENUMERATING:
123f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            newStatus = CameraDeviceStatus::ENUMERATING;
124f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            break;
125f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        default:
126f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            ALOGW("Unknown device status change to %d", new_status);
127f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            break;
128f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    }
129f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    cs->onDeviceStatusChanged(id, newStatus);
130cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin}
1313068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
1323068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chenstatic void torch_mode_status_change(
1333068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen        const struct camera_module_callbacks* callbacks,
1343068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen        const char* camera_id,
1353068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen        int new_status) {
1363068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    if (!callbacks || !camera_id) {
1373068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen        ALOGE("%s invalid parameters. callbacks %p, camera_id %p", __FUNCTION__,
1383068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen                callbacks, camera_id);
1393068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    }
1403068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    sp<CameraService> cs = const_cast<CameraService*>(
1413068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen                                static_cast<const CameraService*>(callbacks));
1423068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
143f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    TorchModeStatus status;
1443068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    switch (new_status) {
14588da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen        case TORCH_MODE_STATUS_NOT_AVAILABLE:
146f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            status = TorchModeStatus::NOT_AVAILABLE;
1473068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen            break;
14888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen        case TORCH_MODE_STATUS_AVAILABLE_OFF:
149f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            status = TorchModeStatus::AVAILABLE_OFF;
15088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen            break;
15188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen        case TORCH_MODE_STATUS_AVAILABLE_ON:
152f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            status = TorchModeStatus::AVAILABLE_ON;
1533068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen            break;
1543068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen        default:
1553068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen            ALOGE("Unknown torch status %d", new_status);
1563068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen            return;
1573068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    }
1583068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
1593068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    cs->onTorchStatusChanged(
16088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen        String8(camera_id),
1613068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen        status);
1623068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen}
163cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin} // extern "C"
164cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin
16565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
16665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
16749c9705a7987b94bd53fddd4834f5f534cf946f7Eino-Ville TalvalaCameraService::CameraService() :
16849c9705a7987b94bd53fddd4834f5f534cf946f7Eino-Ville Talvala        mEventLog(DEFAULT_EVENT_LOG_LENGTH),
169d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        mNumberOfCameras(0), mNumberOfNormalCameras(0),
170f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev        mSoundRef(0), mInitialized(false) {
171df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block    ALOGI("CameraService started (pid=%d)", getpid());
172bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
173cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin    this->camera_device_status_change = android::camera_device_status_change;
1743068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    this->torch_mode_status_change = android::torch_mode_status_change;
1753068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
176cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    mServiceLockWrapper = std::make_shared<WaitableMutexWrapper>(&mServiceLock);
1778951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev}
17865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1798951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchevvoid CameraService::onFirstRef()
1808951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev{
181cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    ALOGI("CameraService process starting");
182634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
1838951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    BnCameraService::onFirstRef();
18465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
18599e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    // Update battery life tracking if service is restarting
18699e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    BatteryNotifier& notifier(BatteryNotifier::getInstance());
18799e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    notifier.noteResetCamera();
18899e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    notifier.noteResetFlashlight();
18999e69716215cd0665379bc90d708f2ea8689831dRuben Brunk
1902f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    status_t res = INVALID_OPERATION;
1919cbbc837625cced18adabc57d71479044999155dEino-Ville Talvala
192f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    res = enumerateProviders();
1932f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (res == OK) {
1942f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        mInitialized = true;
1952f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
1962f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
1972f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    CameraService::pingCameraServiceProxy();
1982f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala}
1992f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
2002f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalastatus_t CameraService::enumerateProviders() {
2012f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    status_t res;
202aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev    Mutex::Autolock l(mServiceLock);
203aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev
204aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev    if (nullptr == mCameraProviderManager.get()) {
205aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev        mCameraProviderManager = new CameraProviderManager();
206aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev        res = mCameraProviderManager->initialize(this);
207aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev        if (res != OK) {
208aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev            ALOGE("%s: Unable to initialize camera provider manager: %s (%d)",
209aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev                    __FUNCTION__, strerror(-res), res);
210aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev            return res;
211aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev        }
2122f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
2132f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
2142f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    mNumberOfCameras = mCameraProviderManager->getCameraCount();
215f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    mNumberOfNormalCameras =
216f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev            mCameraProviderManager->getAPI1CompatibleCameraCount();
2172f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
218067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh    // Setup vendor tags before we call get_camera_info the first time
219067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh    // because HAL might need to setup static vendor keys in get_camera_info
220067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh    // TODO: maybe put this into CameraProviderManager::initialize()?
221067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh    mCameraProviderManager->setUpVendorTags();
2222f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
223aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev    if (nullptr == mFlashlight.get()) {
224aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev        mFlashlight = new CameraFlashlight(mCameraProviderManager, this);
225aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev    }
226aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev
2272f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    res = mFlashlight->findFlashUnits();
2282f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (res != OK) {
2292f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        ALOGE("Failed to enumerate flash units: %s (%d)", strerror(-res), res);
2302f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
2312f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
2322f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    for (auto& cameraId : mCameraProviderManager->getCameraDeviceIds()) {
233aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev        String8 id8 = String8(cameraId.c_str());
234aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev        {
235aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev            Mutex::Autolock lock(mCameraStatesLock);
236aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev            auto iter = mCameraStates.find(id8);
237aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev            if (iter != mCameraStates.end()) {
238aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev                continue;
239aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev            }
240aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev        }
241aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev
2422f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        hardware::camera::common::V1_0::CameraResourceCost cost;
2432f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        res = mCameraProviderManager->getResourceCost(cameraId, &cost);
2442f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        if (res != OK) {
2452f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            ALOGE("Failed to query device resource cost: %s (%d)", strerror(-res), res);
2462f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            continue;
2472f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        }
2482f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        std::set<String8> conflicting;
2492f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        for (size_t i = 0; i < cost.conflictingDevices.size(); i++) {
2502f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            conflicting.emplace(String8(cost.conflictingDevices[i].c_str()));
2512f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        }
2522f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
25392e3321e41e10f2e07a71f9512a6cadef7f40b64Yin-Chia Yeh        {
25492e3321e41e10f2e07a71f9512a6cadef7f40b64Yin-Chia Yeh            Mutex::Autolock lock(mCameraStatesLock);
25592e3321e41e10f2e07a71f9512a6cadef7f40b64Yin-Chia Yeh            mCameraStates.emplace(id8,
25692e3321e41e10f2e07a71f9512a6cadef7f40b64Yin-Chia Yeh                std::make_shared<CameraState>(id8, cost.resourceCost, conflicting));
25792e3321e41e10f2e07a71f9512a6cadef7f40b64Yin-Chia Yeh        }
25892e3321e41e10f2e07a71f9512a6cadef7f40b64Yin-Chia Yeh
25992e3321e41e10f2e07a71f9512a6cadef7f40b64Yin-Chia Yeh        onDeviceStatusChanged(id8, CameraDeviceStatus::PRESENT);
2602f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
2612f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        if (mFlashlight->hasFlashUnit(id8)) {
262aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev            mTorchStatusMap.add(id8, TorchModeStatus::AVAILABLE_OFF);
2632f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        }
2642f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
2652f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
2662f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    return OK;
2672823ce0ce6f9d508a07de20912c93cce9165027fRuben Brunk}
2682823ce0ce6f9d508a07de20912c93cce9165027fRuben Brunk
269412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvalasp<ICameraServiceProxy> CameraService::getCameraServiceProxy() {
27092c06fceabfa47906aaa7c747dcdd6376ccec358Christopher Wiley    sp<ICameraServiceProxy> proxyBinder = nullptr;
27192c06fceabfa47906aaa7c747dcdd6376ccec358Christopher Wiley#ifndef __BRILLO__
2722823ce0ce6f9d508a07de20912c93cce9165027fRuben Brunk    sp<IServiceManager> sm = defaultServiceManager();
273f4db13db84c40299de4f9997f08d05259bdb8716Eino-Ville Talvala    // Use checkService because cameraserver normally starts before the
274f4db13db84c40299de4f9997f08d05259bdb8716Eino-Ville Talvala    // system server and the proxy service. So the long timeout that getService
275f4db13db84c40299de4f9997f08d05259bdb8716Eino-Ville Talvala    // has before giving up is inappropriate.
276f4db13db84c40299de4f9997f08d05259bdb8716Eino-Ville Talvala    sp<IBinder> binder = sm->checkService(String16("media.camera.proxy"));
27792c06fceabfa47906aaa7c747dcdd6376ccec358Christopher Wiley    if (binder != nullptr) {
27892c06fceabfa47906aaa7c747dcdd6376ccec358Christopher Wiley        proxyBinder = interface_cast<ICameraServiceProxy>(binder);
2792823ce0ce6f9d508a07de20912c93cce9165027fRuben Brunk    }
28092c06fceabfa47906aaa7c747dcdd6376ccec358Christopher Wiley#endif
281412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala    return proxyBinder;
282412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala}
283412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala
284412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvalavoid CameraService::pingCameraServiceProxy() {
285412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala    sp<ICameraServiceProxy> proxyBinder = getCameraServiceProxy();
286412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala    if (proxyBinder == nullptr) return;
2872823ce0ce6f9d508a07de20912c93cce9165027fRuben Brunk    proxyBinder->pingForUserUpdate();
28865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
28965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
29065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianCameraService::~CameraService() {
291d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk    VendorTagDescriptor::clearGlobalVendorTagDescriptor();
29265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
29365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
294aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peevvoid CameraService::onNewProviderRegistered() {
295aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev    enumerateProviders();
296aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev}
297aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev
298f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalavoid CameraService::onDeviceStatusChanged(const String8& id,
299f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        CameraDeviceStatus newHalStatus) {
300f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    ALOGI("%s: Status changed for cameraId=%s, newStatus=%d", __FUNCTION__,
301f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            id.string(), newHalStatus);
302f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
303f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    StatusInternal newStatus = mapToInternal(newHalStatus);
304cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin
305cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    std::shared_ptr<CameraState> state = getCameraState(id);
306cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
307cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    if (state == nullptr) {
30892e3321e41e10f2e07a71f9512a6cadef7f40b64Yin-Chia Yeh        if (newStatus == StatusInternal::PRESENT) {
30992e3321e41e10f2e07a71f9512a6cadef7f40b64Yin-Chia Yeh            ALOGW("%s: Unknown camera ID %s, probably newly registered?",
31092e3321e41e10f2e07a71f9512a6cadef7f40b64Yin-Chia Yeh                    __FUNCTION__, id.string());
31192e3321e41e10f2e07a71f9512a6cadef7f40b64Yin-Chia Yeh        } else {
31292e3321e41e10f2e07a71f9512a6cadef7f40b64Yin-Chia Yeh            ALOGE("%s: Bad camera ID %s", __FUNCTION__, id.string());
31392e3321e41e10f2e07a71f9512a6cadef7f40b64Yin-Chia Yeh        }
314cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin        return;
315cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin    }
316cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin
317f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    StatusInternal oldStatus = state->getStatus();
318cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
319f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    if (oldStatus == newStatus) {
320cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        ALOGE("%s: State transition to the same status %#x not allowed", __FUNCTION__, newStatus);
321cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin        return;
322cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin    }
323cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin
324f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    if (newStatus == StatusInternal::NOT_PRESENT) {
325a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk        logDeviceRemoved(id, String8::format("Device status changed from %d to %d", oldStatus,
326a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk                newStatus));
327cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        sp<BasicClient> clientToDisconnect;
328cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin        {
329cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            // Don't do this in updateStatus to avoid deadlock over mServiceLock
330cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            Mutex::Autolock lock(mServiceLock);
331cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin
332cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            // Set the device status to NOT_PRESENT, clients will no longer be able to connect
333cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            // to this device until the status changes
334f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            updateStatus(StatusInternal::NOT_PRESENT, id);
335cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin
336cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            // Remove cached shim parameters
337cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            state->setShimParams(CameraParameters());
338cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin
3398d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala            // Remove the client from the list of active clients, if there is one
340cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            clientToDisconnect = removeClientLocked(id);
3418d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        }
342cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
3438d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        // Disconnect client
3448d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        if (clientToDisconnect.get() != nullptr) {
3458d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala            ALOGI("%s: Client for camera ID %s evicted due to device status change from HAL",
3468d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala                    __FUNCTION__, id.string());
347cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            // Notify the client of disconnection
348d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            clientToDisconnect->notifyError(
349d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED,
350cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    CaptureResultExtras{});
351cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            // Ensure not in binder RPC so client disconnect PID checks work correctly
352cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            LOG_ALWAYS_FATAL_IF(getCallingPid() != getpid(),
353cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    "onDeviceStatusChanged must be called from the camera service process!");
354cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            clientToDisconnect->disconnect();
355cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        }
356cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
357cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    } else {
358f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        if (oldStatus == StatusInternal::NOT_PRESENT) {
359a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk            logDeviceAdded(id, String8::format("Device status changed from %d to %d", oldStatus,
360a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk                    newStatus));
361a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk        }
362f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        updateStatus(newStatus, id);
363cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
364cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin
365cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin}
366cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin
36788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chenvoid CameraService::onTorchStatusChanged(const String8& cameraId,
368f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        TorchModeStatus newStatus) {
3693068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    Mutex::Autolock al(mTorchStatusMutex);
3703068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    onTorchStatusChangedLocked(cameraId, newStatus);
3713068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen}
3723068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
37388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chenvoid CameraService::onTorchStatusChangedLocked(const String8& cameraId,
374f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        TorchModeStatus newStatus) {
3753068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    ALOGI("%s: Torch status changed for cameraId=%s, newStatus=%d",
3763068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen            __FUNCTION__, cameraId.string(), newStatus);
3773068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
378f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    TorchModeStatus status;
37988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    status_t res = getTorchStatusLocked(cameraId, &status);
38088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    if (res) {
381f6463fc62a09b8aad8e811a9abbe9f4d9f2688f9Chien-Yu Chen        ALOGE("%s: cannot get torch status of camera %s: %s (%d)",
382f6463fc62a09b8aad8e811a9abbe9f4d9f2688f9Chien-Yu Chen                __FUNCTION__, cameraId.string(), strerror(-res), res);
38388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen        return;
38488da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    }
38588da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    if (status == newStatus) {
3863068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen        return;
3873068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    }
3883068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
38988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    res = setTorchStatusLocked(cameraId, newStatus);
3903068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    if (res) {
391d309fb9c8a2c4564d88fffba19c4e3688e4b862bEino-Ville Talvala        ALOGE("%s: Failed to set the torch status to %d: %s (%d)", __FUNCTION__,
392d309fb9c8a2c4564d88fffba19c4e3688e4b862bEino-Ville Talvala                (uint32_t)newStatus, strerror(-res), res);
3933068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen        return;
3943068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    }
3953068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
396cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    {
39799e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        // Update battery life logging for flashlight
398fe751bea0d3eedd6e817aebf4e457425b82e7117Chien-Yu Chen        Mutex::Autolock al(mTorchUidMapMutex);
39999e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        auto iter = mTorchUidMap.find(cameraId);
40099e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        if (iter != mTorchUidMap.end()) {
40199e69716215cd0665379bc90d708f2ea8689831dRuben Brunk            int oldUid = iter->second.second;
40299e69716215cd0665379bc90d708f2ea8689831dRuben Brunk            int newUid = iter->second.first;
40399e69716215cd0665379bc90d708f2ea8689831dRuben Brunk            BatteryNotifier& notifier(BatteryNotifier::getInstance());
40499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk            if (oldUid != newUid) {
40599e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                // If the UID has changed, log the status and update current UID in mTorchUidMap
406f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                if (status == TorchModeStatus::AVAILABLE_ON) {
40799e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                    notifier.noteFlashlightOff(cameraId, oldUid);
40899e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                }
409f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                if (newStatus == TorchModeStatus::AVAILABLE_ON) {
41099e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                    notifier.noteFlashlightOn(cameraId, newUid);
41199e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                }
41299e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                iter->second.second = newUid;
41399e69716215cd0665379bc90d708f2ea8689831dRuben Brunk            } else {
41499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                // If the UID has not changed, log the status
415f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                if (newStatus == TorchModeStatus::AVAILABLE_ON) {
41699e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                    notifier.noteFlashlightOn(cameraId, oldUid);
41799e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                } else {
41899e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                    notifier.noteFlashlightOff(cameraId, oldUid);
41999e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                }
42099e69716215cd0665379bc90d708f2ea8689831dRuben Brunk            }
42199e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        }
42299e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    }
42399e69716215cd0665379bc90d708f2ea8689831dRuben Brunk
42499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    {
425cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        Mutex::Autolock lock(mStatusListenerLock);
426cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        for (auto& i : mListenerList) {
427f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            i->onTorchStatusChanged(mapToInterface(newStatus), String16{cameraId});
428cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        }
4293068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    }
4303068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen}
4313068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
432d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::getNumberOfCameras(int32_t type, int32_t* numCameras) {
433a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
434aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev    Mutex::Autolock l(mServiceLock);
435bad4358c83c7daaf9eeb8542c15eea4f473c884cEino-Ville Talvala    switch (type) {
436bad4358c83c7daaf9eeb8542c15eea4f473c884cEino-Ville Talvala        case CAMERA_TYPE_BACKWARD_COMPATIBLE:
437d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            *numCameras = mNumberOfNormalCameras;
438d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            break;
439bad4358c83c7daaf9eeb8542c15eea4f473c884cEino-Ville Talvala        case CAMERA_TYPE_ALL:
440d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            *numCameras = mNumberOfCameras;
441d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            break;
442bad4358c83c7daaf9eeb8542c15eea4f473c884cEino-Ville Talvala        default:
443d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            ALOGW("%s: Unknown camera type %d",
444bad4358c83c7daaf9eeb8542c15eea4f473c884cEino-Ville Talvala                    __FUNCTION__, type);
445d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
446d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    "Unknown camera type %d", type);
447bad4358c83c7daaf9eeb8542c15eea4f473c884cEino-Ville Talvala    }
448d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return Status::ok();
44965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
45065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
451d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::getCameraInfo(int cameraId,
452d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        CameraInfo* cameraInfo) {
453a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
454aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev    Mutex::Autolock l(mServiceLock);
455aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev
4562f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (!mInitialized) {
457d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(ERROR_DISCONNECTED,
458d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "Camera subsystem is not available");
4598951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    }
4608951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev
46165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (cameraId < 0 || cameraId >= mNumberOfCameras) {
462d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT,
463d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "CameraId is not valid");
46465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
46565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4662f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    Status ret = Status::ok();
467f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    status_t err = mCameraProviderManager->getCameraInfo(std::to_string(cameraId), cameraInfo);
468f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    if (err != OK) {
469f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev        ret = STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
470f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev                "Error retrieving camera info from device %d: %s (%d)", cameraId,
471f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev                strerror(-err), err);
472d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    }
473f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev
4742f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    return ret;
47565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
47665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
477cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkint CameraService::cameraIdToInt(const String8& cameraId) {
4782f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    int id;
4792f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    bool success = base::ParseInt(cameraId.string(), &id, 0);
4802f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (!success) {
481cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        return -1;
482cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
4832f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    return id;
484cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
485b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk
4862f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville TalvalaStatus CameraService::getCameraCharacteristics(const String16& cameraId,
487f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        CameraMetadata* cameraInfo) {
488a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
4892b59be89dc245b6e2475d9e8b0c5f2392370e71eZhijun He    if (!cameraInfo) {
4902b59be89dc245b6e2475d9e8b0c5f2392370e71eZhijun He        ALOGE("%s: cameraInfo is NULL", __FUNCTION__);
491d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "cameraInfo is NULL");
4922b59be89dc245b6e2475d9e8b0c5f2392370e71eZhijun He    }
4932b59be89dc245b6e2475d9e8b0c5f2392370e71eZhijun He
4942f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (!mInitialized) {
4952f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        ALOGE("%s: Camera HAL couldn't be initialized", __FUNCTION__);
496d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(ERROR_DISCONNECTED,
497d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "Camera subsystem is not available");;
4982b59be89dc245b6e2475d9e8b0c5f2392370e71eZhijun He    }
4992b59be89dc245b6e2475d9e8b0c5f2392370e71eZhijun He
5002f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    Status ret{};
501f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
502f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    status_t res = mCameraProviderManager->getCameraCharacteristics(
503f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev            String8(cameraId).string(), cameraInfo);
504f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    if (res != OK) {
505f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev        return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, "Unable to retrieve camera "
506f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev                "characteristics for device %s: %s (%d)", String8(cameraId).string(),
507f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev                strerror(-res), res);
508f05e50eb06d3f70e50fa7f44c1fd32128033b49dZhijun He    }
509f05e50eb06d3f70e50fa7f44c1fd32128033b49dZhijun He
5102b59be89dc245b6e2475d9e8b0c5f2392370e71eZhijun He    return ret;
5112b59be89dc245b6e2475d9e8b0c5f2392370e71eZhijun He}
5122b59be89dc245b6e2475d9e8b0c5f2392370e71eZhijun He
513cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkint CameraService::getCallingPid() {
514cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return IPCThreadState::self()->getCallingPid();
515cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
516cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
517cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkint CameraService::getCallingUid() {
518cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return IPCThreadState::self()->getCallingUid();
519cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
520cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
521cc776718c0be7c31fe5ab4fc1446d377be60369fRuben BrunkString8 CameraService::getFormattedCurrentTime() {
522cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    time_t now = time(nullptr);
523cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    char formattedTime[64];
524cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    strftime(formattedTime, sizeof(formattedTime), "%m-%d %H:%M:%S", localtime(&now));
525cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return String8(formattedTime);
526cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
527cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
528d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::getCameraVendorTagDescriptor(
529d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        /*out*/
530d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        hardware::camera2::params::VendorTagDescriptor* desc) {
531a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
5322f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (!mInitialized) {
5332f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        ALOGE("%s: Camera HAL couldn't be initialized", __FUNCTION__);
534d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(ERROR_DISCONNECTED, "Camera subsystem not available");
535d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk    }
5361e74e241f5a4e0e763e27c888561405d013c9ca0Eino-Ville Talvala    sp<VendorTagDescriptor> globalDescriptor = VendorTagDescriptor::getGlobalVendorTagDescriptor();
5371e74e241f5a4e0e763e27c888561405d013c9ca0Eino-Ville Talvala    if (globalDescriptor != nullptr) {
5381e74e241f5a4e0e763e27c888561405d013c9ca0Eino-Ville Talvala        *desc = *(globalDescriptor.get());
5391e74e241f5a4e0e763e27c888561405d013c9ca0Eino-Ville Talvala    }
540d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return Status::ok();
541d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk}
542d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk
54371c73a2985a7ac65ee597be3441ab300fa56e22eEmilian PeevStatus CameraService::getCameraVendorTagCache(
54471c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev        /*out*/ hardware::camera2::params::VendorTagDescriptorCache* cache) {
54571c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    ATRACE_CALL();
54671c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    if (!mInitialized) {
54771c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev        ALOGE("%s: Camera HAL couldn't be initialized", __FUNCTION__);
54871c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev        return STATUS_ERROR(ERROR_DISCONNECTED,
54971c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                "Camera subsystem not available");
55071c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    }
55171c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    sp<VendorTagDescriptorCache> globalCache =
55271c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev            VendorTagDescriptorCache::getGlobalVendorTagCache();
55371c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    if (globalCache != nullptr) {
55471c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev        *cache = *(globalCache.get());
55571c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    }
55671c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    return Status::ok();
55771c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev}
55871c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev
5592f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalaint CameraService::getDeviceVersion(const String8& cameraId, int* facing) {
560a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
561634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
5622f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    int deviceVersion = 0;
563634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
564f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    status_t res;
565f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    hardware::hidl_version maxVersion{0,0};
566f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    res = mCameraProviderManager->getHighestSupportedVersion(cameraId.string(),
567f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev            &maxVersion);
568f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    if (res != OK) return -1;
569f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    deviceVersion = HARDWARE_DEVICE_API_VERSION(maxVersion.get_major(), maxVersion.get_minor());
570f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev
571f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    hardware::CameraInfo info;
572f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    if (facing) {
573f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev        res = mCameraProviderManager->getCameraInfo(cameraId.string(), &info);
5746963d0ad7b621dcdaa74cbfed17c776121635146Eino-Ville Talvala        if (res != OK) return -1;
575f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev        *facing = info.facing;
5762f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
577f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev
578634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    return deviceVersion;
579634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
580634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
581d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::filterGetInfoErrorCode(status_t err) {
582f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala    switch(err) {
583f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala        case NO_ERROR:
584d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return Status::ok();
585f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        case BAD_VALUE:
586d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT,
587d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    "CameraId is not valid for HAL module");
588f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        case NO_INIT:
589d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return STATUS_ERROR(ERROR_DISCONNECTED,
590d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    "Camera device not available");
591f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala        default:
592d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
593d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    "Camera HAL encountered error %d: %s",
594d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    err, strerror(-err));
595f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala    }
596bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin}
597bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
598d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::makeClient(const sp<CameraService>& cameraService,
5992f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        const sp<IInterface>& cameraCb, const String16& packageName, const String8& cameraId,
600cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        int facing, int clientPid, uid_t clientUid, int servicePid, bool legacyMode,
601cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        int halVersion, int deviceVersion, apiLevel effectiveApiLevel,
602cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        /*out*/sp<BasicClient>* client) {
603b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk
604cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    if (halVersion < 0 || halVersion == deviceVersion) {
605cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // Default path: HAL version is unspecified by caller, create CameraClient
606cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // based on device version reported by the HAL.
607cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        switch(deviceVersion) {
608cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk          case CAMERA_DEVICE_API_VERSION_1_0:
609cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            if (effectiveApiLevel == API_1) {  // Camera1 API route
610cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
6112f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                *client = new CameraClient(cameraService, tmp, packageName, cameraIdToInt(cameraId),
6122f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                        facing, clientPid, clientUid, getpid(), legacyMode);
613cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            } else { // Camera2 API route
614