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>
36a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov#include <binder/ActivityManager.h>
37ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala#include <binder/AppOpsManager.h>
3865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <binder/IPCThreadState.h>
3965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <binder/IServiceManager.h>
4065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <binder/MemoryBase.h>
4165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <binder/MemoryHeapBase.h>
42a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov#include <binder/PermissionController.h>
43cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk#include <binder/ProcessInfoService.h>
44a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov#include <binder/IResultReceiver.h>
4565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <cutils/atomic.h>
46b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra#include <cutils/properties.h>
47a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov#include <cutils/misc.h>
48df712ea86e6350f7005a02ab0e1c60c28a343ed0Mathias Agopian#include <gui/Surface.h>
4965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <hardware/hardware.h>
50d89821ec5481e0640d84bfe3e29a1254a52ca683Eino-Ville Talvala#include <memunreachable/memunreachable.h>
5165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <media/AudioSystem.h>
521b86fe063badb5f28c467ade39be0f4008688947Andreas Huber#include <media/IMediaHTTPService.h>
5365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <media/mediaplayer.h>
5499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk#include <mediautils/BatteryNotifier.h>
5565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/Errors.h>
5665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/Log.h>
5765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/String16.h>
5894ec46f82f5813fd5bcdf6c2f562e009dd4eec03Svet Ganov#include <utils/SystemClock.h>
59d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk#include <utils/Trace.h>
6098a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen#include <private/android_filesystem_config.h>
61d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk#include <system/camera_vendor_tags.h>
62b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk#include <system/camera_metadata.h>
632f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
64b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk#include <system/camera.h>
6565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
6665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include "CameraService.h"
677b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala#include "api1/CameraClient.h"
687b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala#include "api1/Camera2Client.h"
697b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala#include "api2/CameraDeviceClient.h"
70ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin#include "utils/CameraTraces.h"
71bd8c503398d6b483b7abba594c7838a4c93b6e23Emilian Peev#include "utils/TagMonitor.h"
7265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
730dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yehnamespace {
740dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    const char* kPermissionServiceName = "permission";
750dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh}; // namespace anonymous
760dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
7765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiannamespace android {
7865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
79d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvalausing binder::Status;
80f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalausing hardware::ICamera;
81f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalausing hardware::ICameraClient;
82e8c96c765b95ec7dcd10732621a825fce05960c6Eino-Ville Talvalausing hardware::ICameraServiceProxy;
83f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalausing hardware::ICameraServiceListener;
84f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalausing hardware::camera::common::V1_0::CameraDeviceStatus;
85f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalausing hardware::camera::common::V1_0::TorchModeStatus;
86d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala
8765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
8865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// Logging support -- this is for debugging only
8965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// Use "adb shell dumpsys media.camera -v 1" to change it.
905e08d60617fc63c2e41f9069ff89f5c00db2617dEino-Ville Talvalavolatile int32_t gLogLevel = 0;
9165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
92b8a805261bf0282e992d3608035e47d05a898710Steve Block#define LOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__);
93b8a805261bf0282e992d3608035e47d05a898710Steve Block#define LOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__);
9465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
9565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic void setLogLevel(int level) {
9665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    android_atomic_write(level, &gLogLevel);
9765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
9865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
99d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala// Convenience methods for constructing binder::Status objects for error returns
100d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala
101d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala#define STATUS_ERROR(errorCode, errorString) \
102d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    binder::Status::fromServiceSpecificError(errorCode, \
103d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            String8::format("%s:%d: %s", __FUNCTION__, __LINE__, errorString))
104d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala
105d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala#define STATUS_ERROR_FMT(errorCode, errorString, ...) \
106d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    binder::Status::fromServiceSpecificError(errorCode, \
107d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            String8::format("%s:%d: " errorString, __FUNCTION__, __LINE__, \
108d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    __VA_ARGS__))
109d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala
11065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
11165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
112a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganovstatic const String16 sManageCameraPermission("android.permission.MANAGE_CAMERA");
113a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
11449c9705a7987b94bd53fddd4834f5f534cf946f7Eino-Ville TalvalaCameraService::CameraService() :
11549c9705a7987b94bd53fddd4834f5f534cf946f7Eino-Ville Talvala        mEventLog(DEFAULT_EVENT_LOG_LENGTH),
116c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        mNumberOfCameras(0),
117f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev        mSoundRef(0), mInitialized(false) {
118df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block    ALOGI("CameraService started (pid=%d)", getpid());
119cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    mServiceLockWrapper = std::make_shared<WaitableMutexWrapper>(&mServiceLock);
1208951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev}
12165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1228951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchevvoid CameraService::onFirstRef()
1238951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev{
124cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    ALOGI("CameraService process starting");
125634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
1268951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    BnCameraService::onFirstRef();
12765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
12899e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    // Update battery life tracking if service is restarting
12999e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    BatteryNotifier& notifier(BatteryNotifier::getInstance());
13099e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    notifier.noteResetCamera();
13199e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    notifier.noteResetFlashlight();
13299e69716215cd0665379bc90d708f2ea8689831dRuben Brunk
1332f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    status_t res = INVALID_OPERATION;
1349cbbc837625cced18adabc57d71479044999155dEino-Ville Talvala
135f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    res = enumerateProviders();
1362f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (res == OK) {
1372f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        mInitialized = true;
1382f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
1392f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
1402f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    CameraService::pingCameraServiceProxy();
141a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
142a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    mUidPolicy = new UidPolicy(this);
143a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    mUidPolicy->registerSelf();
1442f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala}
1452f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
1462f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalastatus_t CameraService::enumerateProviders() {
1472f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    status_t res;
148aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev
149c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    std::vector<std::string> deviceIds;
150c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    {
151c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        Mutex::Autolock l(mServiceLock);
152c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh
153c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        if (nullptr == mCameraProviderManager.get()) {
154c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            mCameraProviderManager = new CameraProviderManager();
155c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            res = mCameraProviderManager->initialize(this);
156c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            if (res != OK) {
157c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                ALOGE("%s: Unable to initialize camera provider manager: %s (%d)",
158c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                        __FUNCTION__, strerror(-res), res);
159c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                return res;
160c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            }
161aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev        }
1622f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
1632f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
164c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        // Setup vendor tags before we call get_camera_info the first time
165c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        // because HAL might need to setup static vendor keys in get_camera_info
166c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        // TODO: maybe put this into CameraProviderManager::initialize()?
167c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        mCameraProviderManager->setUpVendorTags();
1682f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
169c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        if (nullptr == mFlashlight.get()) {
170c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            mFlashlight = new CameraFlashlight(mCameraProviderManager, this);
171aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev        }
172aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev
173c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        res = mFlashlight->findFlashUnits();
174c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        if (res != OK) {
175c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            ALOGE("Failed to enumerate flash units: %s (%d)", strerror(-res), res);
17692e3321e41e10f2e07a71f9512a6cadef7f40b64Yin-Chia Yeh        }
17792e3321e41e10f2e07a71f9512a6cadef7f40b64Yin-Chia Yeh
178c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        deviceIds = mCameraProviderManager->getCameraDeviceIds();
179c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    }
180c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh
181c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh
182c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    for (auto& cameraId : deviceIds) {
183c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        String8 id8 = String8(cameraId.c_str());
18492e3321e41e10f2e07a71f9512a6cadef7f40b64Yin-Chia Yeh        onDeviceStatusChanged(id8, CameraDeviceStatus::PRESENT);
1852f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
1862f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
1872f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    return OK;
1882823ce0ce6f9d508a07de20912c93cce9165027fRuben Brunk}
1892823ce0ce6f9d508a07de20912c93cce9165027fRuben Brunk
190412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvalasp<ICameraServiceProxy> CameraService::getCameraServiceProxy() {
19192c06fceabfa47906aaa7c747dcdd6376ccec358Christopher Wiley    sp<ICameraServiceProxy> proxyBinder = nullptr;
19292c06fceabfa47906aaa7c747dcdd6376ccec358Christopher Wiley#ifndef __BRILLO__
1932823ce0ce6f9d508a07de20912c93cce9165027fRuben Brunk    sp<IServiceManager> sm = defaultServiceManager();
194f4db13db84c40299de4f9997f08d05259bdb8716Eino-Ville Talvala    // Use checkService because cameraserver normally starts before the
195f4db13db84c40299de4f9997f08d05259bdb8716Eino-Ville Talvala    // system server and the proxy service. So the long timeout that getService
196f4db13db84c40299de4f9997f08d05259bdb8716Eino-Ville Talvala    // has before giving up is inappropriate.
197f4db13db84c40299de4f9997f08d05259bdb8716Eino-Ville Talvala    sp<IBinder> binder = sm->checkService(String16("media.camera.proxy"));
19892c06fceabfa47906aaa7c747dcdd6376ccec358Christopher Wiley    if (binder != nullptr) {
19992c06fceabfa47906aaa7c747dcdd6376ccec358Christopher Wiley        proxyBinder = interface_cast<ICameraServiceProxy>(binder);
2002823ce0ce6f9d508a07de20912c93cce9165027fRuben Brunk    }
20192c06fceabfa47906aaa7c747dcdd6376ccec358Christopher Wiley#endif
202412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala    return proxyBinder;
203412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala}
204412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala
205412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvalavoid CameraService::pingCameraServiceProxy() {
206412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala    sp<ICameraServiceProxy> proxyBinder = getCameraServiceProxy();
207412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala    if (proxyBinder == nullptr) return;
2082823ce0ce6f9d508a07de20912c93cce9165027fRuben Brunk    proxyBinder->pingForUserUpdate();
20965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
21065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
21165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianCameraService::~CameraService() {
212d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk    VendorTagDescriptor::clearGlobalVendorTagDescriptor();
213a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    mUidPolicy->unregisterSelf();
21465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
21565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
216aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peevvoid CameraService::onNewProviderRegistered() {
217aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev    enumerateProviders();
218aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev}
219aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev
220c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yehvoid CameraService::updateCameraNumAndIds() {
221c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    Mutex::Autolock l(mServiceLock);
222c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    mNumberOfCameras = mCameraProviderManager->getCameraCount();
223c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    mNormalDeviceIds =
224c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            mCameraProviderManager->getAPI1CompatibleCameraDeviceIds();
225c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh}
226c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh
227151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetskivoid CameraService::addStates(const String8 id) {
228151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    std::string cameraId(id.c_str());
229151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    hardware::camera::common::V1_0::CameraResourceCost cost;
230151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    status_t res = mCameraProviderManager->getResourceCost(cameraId, &cost);
231151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    if (res != OK) {
232151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski        ALOGE("Failed to query device resource cost: %s (%d)", strerror(-res), res);
233151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski        return;
234151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    }
235151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    std::set<String8> conflicting;
236151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    for (size_t i = 0; i < cost.conflictingDevices.size(); i++) {
237151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski        conflicting.emplace(String8(cost.conflictingDevices[i].c_str()));
238151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    }
239151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski
240151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    {
241151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski        Mutex::Autolock lock(mCameraStatesLock);
242151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski        mCameraStates.emplace(id, std::make_shared<CameraState>(id, cost.resourceCost,
243151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski                                                                conflicting));
244151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    }
245151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski
246151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    if (mFlashlight->hasFlashUnit(id)) {
2477f25e5f57f25ec798edc781423d7a29234e67f1bEmilian Peev        Mutex::Autolock al(mTorchStatusMutex);
248151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski        mTorchStatusMap.add(id, TorchModeStatus::AVAILABLE_OFF);
249151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    }
250c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh
251c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    updateCameraNumAndIds();
252151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    logDeviceAdded(id, "Device added");
253151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski}
254151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski
2556034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetskivoid CameraService::removeStates(const String8 id) {
256c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    updateCameraNumAndIds();
2576034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski    if (mFlashlight->hasFlashUnit(id)) {
2587f25e5f57f25ec798edc781423d7a29234e67f1bEmilian Peev        Mutex::Autolock al(mTorchStatusMutex);
2596034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski        mTorchStatusMap.removeItem(id);
2606034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski    }
2616034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski
2626034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski    {
2636034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski        Mutex::Autolock lock(mCameraStatesLock);
2646034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski        mCameraStates.erase(id);
2656034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski    }
2666034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski}
2676034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski
268f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalavoid CameraService::onDeviceStatusChanged(const String8& id,
269f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        CameraDeviceStatus newHalStatus) {
270f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    ALOGI("%s: Status changed for cameraId=%s, newStatus=%d", __FUNCTION__,
271f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            id.string(), newHalStatus);
272f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
273f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    StatusInternal newStatus = mapToInternal(newHalStatus);
274cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin
275cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    std::shared_ptr<CameraState> state = getCameraState(id);
276cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
277cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    if (state == nullptr) {
27892e3321e41e10f2e07a71f9512a6cadef7f40b64Yin-Chia Yeh        if (newStatus == StatusInternal::PRESENT) {
279151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski            ALOGI("%s: Unknown camera ID %s, a new camera is added",
28092e3321e41e10f2e07a71f9512a6cadef7f40b64Yin-Chia Yeh                    __FUNCTION__, id.string());
281151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski
282151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski            // First add as absent to make sure clients are notified below
283151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski            addStates(id);
284151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski
285151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski            updateStatus(newStatus, id);
28692e3321e41e10f2e07a71f9512a6cadef7f40b64Yin-Chia Yeh        } else {
28792e3321e41e10f2e07a71f9512a6cadef7f40b64Yin-Chia Yeh            ALOGE("%s: Bad camera ID %s", __FUNCTION__, id.string());
28892e3321e41e10f2e07a71f9512a6cadef7f40b64Yin-Chia Yeh        }
289cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin        return;
290cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin    }
291cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin
292f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    StatusInternal oldStatus = state->getStatus();
293cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
294f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    if (oldStatus == newStatus) {
295cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        ALOGE("%s: State transition to the same status %#x not allowed", __FUNCTION__, newStatus);
296cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin        return;
297cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin    }
298cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin
299f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    if (newStatus == StatusInternal::NOT_PRESENT) {
300a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk        logDeviceRemoved(id, String8::format("Device status changed from %d to %d", oldStatus,
301a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk                newStatus));
302c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh
303c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        // Set the device status to NOT_PRESENT, clients will no longer be able to connect
304c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        // to this device until the status changes
305c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        updateStatus(StatusInternal::NOT_PRESENT, id);
306c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh
307cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        sp<BasicClient> clientToDisconnect;
308cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin        {
309cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            // Don't do this in updateStatus to avoid deadlock over mServiceLock
310cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            Mutex::Autolock lock(mServiceLock);
311cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin
312cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            // Remove cached shim parameters
313cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            state->setShimParams(CameraParameters());
314cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin
3158d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala            // Remove the client from the list of active clients, if there is one
316cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            clientToDisconnect = removeClientLocked(id);
3178d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        }
318cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
3198d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        // Disconnect client
3208d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        if (clientToDisconnect.get() != nullptr) {
3218d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala            ALOGI("%s: Client for camera ID %s evicted due to device status change from HAL",
3228d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala                    __FUNCTION__, id.string());
323cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            // Notify the client of disconnection
324d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            clientToDisconnect->notifyError(
325d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED,
326cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    CaptureResultExtras{});
327cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            // Ensure not in binder RPC so client disconnect PID checks work correctly
328cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            LOG_ALWAYS_FATAL_IF(getCallingPid() != getpid(),
329cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    "onDeviceStatusChanged must be called from the camera service process!");
330cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            clientToDisconnect->disconnect();
331cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        }
332cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
3336034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski        removeStates(id);
334cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    } else {
335f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        if (oldStatus == StatusInternal::NOT_PRESENT) {
336a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk            logDeviceAdded(id, String8::format("Device status changed from %d to %d", oldStatus,
337a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk                    newStatus));
338a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk        }
339f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        updateStatus(newStatus, id);
340cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
341cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin
342cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin}
343cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin
34488da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chenvoid CameraService::onTorchStatusChanged(const String8& cameraId,
345f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        TorchModeStatus newStatus) {
3463068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    Mutex::Autolock al(mTorchStatusMutex);
3473068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    onTorchStatusChangedLocked(cameraId, newStatus);
3483068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen}
3493068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
35088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chenvoid CameraService::onTorchStatusChangedLocked(const String8& cameraId,
351f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        TorchModeStatus newStatus) {
3523068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    ALOGI("%s: Torch status changed for cameraId=%s, newStatus=%d",
3533068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen            __FUNCTION__, cameraId.string(), newStatus);
3543068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
355f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    TorchModeStatus status;
35688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    status_t res = getTorchStatusLocked(cameraId, &status);
35788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    if (res) {
358f6463fc62a09b8aad8e811a9abbe9f4d9f2688f9Chien-Yu Chen        ALOGE("%s: cannot get torch status of camera %s: %s (%d)",
359f6463fc62a09b8aad8e811a9abbe9f4d9f2688f9Chien-Yu Chen                __FUNCTION__, cameraId.string(), strerror(-res), res);
36088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen        return;
36188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    }
36288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    if (status == newStatus) {
3633068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen        return;
3643068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    }
3653068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
36688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    res = setTorchStatusLocked(cameraId, newStatus);
3673068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    if (res) {
368d309fb9c8a2c4564d88fffba19c4e3688e4b862bEino-Ville Talvala        ALOGE("%s: Failed to set the torch status to %d: %s (%d)", __FUNCTION__,
369d309fb9c8a2c4564d88fffba19c4e3688e4b862bEino-Ville Talvala                (uint32_t)newStatus, strerror(-res), res);
3703068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen        return;
3713068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    }
3723068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
373cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    {
37499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        // Update battery life logging for flashlight
375fe751bea0d3eedd6e817aebf4e457425b82e7117Chien-Yu Chen        Mutex::Autolock al(mTorchUidMapMutex);
37699e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        auto iter = mTorchUidMap.find(cameraId);
37799e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        if (iter != mTorchUidMap.end()) {
37899e69716215cd0665379bc90d708f2ea8689831dRuben Brunk            int oldUid = iter->second.second;
37999e69716215cd0665379bc90d708f2ea8689831dRuben Brunk            int newUid = iter->second.first;
38099e69716215cd0665379bc90d708f2ea8689831dRuben Brunk            BatteryNotifier& notifier(BatteryNotifier::getInstance());
38199e69716215cd0665379bc90d708f2ea8689831dRuben Brunk            if (oldUid != newUid) {
38299e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                // If the UID has changed, log the status and update current UID in mTorchUidMap
383f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                if (status == TorchModeStatus::AVAILABLE_ON) {
38499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                    notifier.noteFlashlightOff(cameraId, oldUid);
38599e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                }
386f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                if (newStatus == TorchModeStatus::AVAILABLE_ON) {
38799e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                    notifier.noteFlashlightOn(cameraId, newUid);
38899e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                }
38999e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                iter->second.second = newUid;
39099e69716215cd0665379bc90d708f2ea8689831dRuben Brunk            } else {
39199e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                // If the UID has not changed, log the status
392f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                if (newStatus == TorchModeStatus::AVAILABLE_ON) {
39399e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                    notifier.noteFlashlightOn(cameraId, oldUid);
39499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                } else {
39599e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                    notifier.noteFlashlightOff(cameraId, oldUid);
39699e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                }
39799e69716215cd0665379bc90d708f2ea8689831dRuben Brunk            }
39899e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        }
39999e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    }
40099e69716215cd0665379bc90d708f2ea8689831dRuben Brunk
40199e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    {
402cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        Mutex::Autolock lock(mStatusListenerLock);
403cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        for (auto& i : mListenerList) {
404f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            i->onTorchStatusChanged(mapToInterface(newStatus), String16{cameraId});
405cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        }
4063068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    }
4073068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen}
4083068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
409d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::getNumberOfCameras(int32_t type, int32_t* numCameras) {
410a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
411aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev    Mutex::Autolock l(mServiceLock);
412bad4358c83c7daaf9eeb8542c15eea4f473c884cEino-Ville Talvala    switch (type) {
413bad4358c83c7daaf9eeb8542c15eea4f473c884cEino-Ville Talvala        case CAMERA_TYPE_BACKWARD_COMPATIBLE:
414c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            *numCameras = static_cast<int>(mNormalDeviceIds.size());
415d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            break;
416bad4358c83c7daaf9eeb8542c15eea4f473c884cEino-Ville Talvala        case CAMERA_TYPE_ALL:
417d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            *numCameras = mNumberOfCameras;
418d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            break;
419bad4358c83c7daaf9eeb8542c15eea4f473c884cEino-Ville Talvala        default:
420d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            ALOGW("%s: Unknown camera type %d",
421bad4358c83c7daaf9eeb8542c15eea4f473c884cEino-Ville Talvala                    __FUNCTION__, type);
422d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
423d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    "Unknown camera type %d", type);
424bad4358c83c7daaf9eeb8542c15eea4f473c884cEino-Ville Talvala    }
425d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return Status::ok();
42665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
42765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
428d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::getCameraInfo(int cameraId,
429d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        CameraInfo* cameraInfo) {
430a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
431aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev    Mutex::Autolock l(mServiceLock);
432aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev
4332f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (!mInitialized) {
434d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(ERROR_DISCONNECTED,
435d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "Camera subsystem is not available");
4368951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    }
4378951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev
43865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (cameraId < 0 || cameraId >= mNumberOfCameras) {
439d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT,
440d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "CameraId is not valid");
44165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
44265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4432f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    Status ret = Status::ok();
444c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    status_t err = mCameraProviderManager->getCameraInfo(
445c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            cameraIdIntToStrLocked(cameraId), cameraInfo);
446f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    if (err != OK) {
447f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev        ret = STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
448f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev                "Error retrieving camera info from device %d: %s (%d)", cameraId,
449f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev                strerror(-err), err);
450d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    }
451f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev
4522f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    return ret;
45365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
45465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
455c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yehstd::string CameraService::cameraIdIntToStrLocked(int cameraIdInt) {
456c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    if (cameraIdInt < 0 || cameraIdInt >= static_cast<int>(mNormalDeviceIds.size())) {
457c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        ALOGE("%s: input id %d invalid: valid range  (0, %zu)",
458c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                __FUNCTION__, cameraIdInt, mNormalDeviceIds.size());
459c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        return std::string{};
460cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
461c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh
462c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    return mNormalDeviceIds[cameraIdInt];
463c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh}
464c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh
465c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia YehString8 CameraService::cameraIdIntToStr(int cameraIdInt) {
466c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    Mutex::Autolock lock(mServiceLock);
467c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    return String8(cameraIdIntToStrLocked(cameraIdInt).c_str());
468cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
469b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk
4702f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville TalvalaStatus CameraService::getCameraCharacteristics(const String16& cameraId,
471f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        CameraMetadata* cameraInfo) {
472a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
4732b59be89dc245b6e2475d9e8b0c5f2392370e71eZhijun He    if (!cameraInfo) {
4742b59be89dc245b6e2475d9e8b0c5f2392370e71eZhijun He        ALOGE("%s: cameraInfo is NULL", __FUNCTION__);
475d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "cameraInfo is NULL");
4762b59be89dc245b6e2475d9e8b0c5f2392370e71eZhijun He    }
4772b59be89dc245b6e2475d9e8b0c5f2392370e71eZhijun He
4782f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (!mInitialized) {
4792f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        ALOGE("%s: Camera HAL couldn't be initialized", __FUNCTION__);
480d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(ERROR_DISCONNECTED,
481d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "Camera subsystem is not available");;
4822b59be89dc245b6e2475d9e8b0c5f2392370e71eZhijun He    }
4832b59be89dc245b6e2475d9e8b0c5f2392370e71eZhijun He
4842f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    Status ret{};
485f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
486f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    status_t res = mCameraProviderManager->getCameraCharacteristics(
487f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev            String8(cameraId).string(), cameraInfo);
488f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    if (res != OK) {
489f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev        return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, "Unable to retrieve camera "
490f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev                "characteristics for device %s: %s (%d)", String8(cameraId).string(),
491f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev                strerror(-res), res);
492f05e50eb06d3f70e50fa7f44c1fd32128033b49dZhijun He    }
493f05e50eb06d3f70e50fa7f44c1fd32128033b49dZhijun He
4942b59be89dc245b6e2475d9e8b0c5f2392370e71eZhijun He    return ret;
4952b59be89dc245b6e2475d9e8b0c5f2392370e71eZhijun He}
4962b59be89dc245b6e2475d9e8b0c5f2392370e71eZhijun He
497cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkint CameraService::getCallingPid() {
498cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return IPCThreadState::self()->getCallingPid();
499cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
500cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
501cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkint CameraService::getCallingUid() {
502cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return IPCThreadState::self()->getCallingUid();
503cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
504cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
505cc776718c0be7c31fe5ab4fc1446d377be60369fRuben BrunkString8 CameraService::getFormattedCurrentTime() {
506cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    time_t now = time(nullptr);
507cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    char formattedTime[64];
508cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    strftime(formattedTime, sizeof(formattedTime), "%m-%d %H:%M:%S", localtime(&now));
509cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return String8(formattedTime);
510cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
511cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
512d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::getCameraVendorTagDescriptor(
513d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        /*out*/
514d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        hardware::camera2::params::VendorTagDescriptor* desc) {
515a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
5162f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (!mInitialized) {
5172f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        ALOGE("%s: Camera HAL couldn't be initialized", __FUNCTION__);
518d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(ERROR_DISCONNECTED, "Camera subsystem not available");
519d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk    }
5201e74e241f5a4e0e763e27c888561405d013c9ca0Eino-Ville Talvala    sp<VendorTagDescriptor> globalDescriptor = VendorTagDescriptor::getGlobalVendorTagDescriptor();
5211e74e241f5a4e0e763e27c888561405d013c9ca0Eino-Ville Talvala    if (globalDescriptor != nullptr) {
5221e74e241f5a4e0e763e27c888561405d013c9ca0Eino-Ville Talvala        *desc = *(globalDescriptor.get());
5231e74e241f5a4e0e763e27c888561405d013c9ca0Eino-Ville Talvala    }
524d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return Status::ok();
525d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk}
526d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk
52771c73a2985a7ac65ee597be3441ab300fa56e22eEmilian PeevStatus CameraService::getCameraVendorTagCache(
52871c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev        /*out*/ hardware::camera2::params::VendorTagDescriptorCache* cache) {
52971c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    ATRACE_CALL();
53071c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    if (!mInitialized) {
53171c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev        ALOGE("%s: Camera HAL couldn't be initialized", __FUNCTION__);
53271c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev        return STATUS_ERROR(ERROR_DISCONNECTED,
53371c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                "Camera subsystem not available");
53471c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    }
53571c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    sp<VendorTagDescriptorCache> globalCache =
53671c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev            VendorTagDescriptorCache::getGlobalVendorTagCache();
53771c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    if (globalCache != nullptr) {
53871c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev        *cache = *(globalCache.get());
53971c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    }
54071c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    return Status::ok();
54171c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev}
54271c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev
5432f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalaint CameraService::getDeviceVersion(const String8& cameraId, int* facing) {
544a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
545634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
5462f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    int deviceVersion = 0;
547634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
548f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    status_t res;
549f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    hardware::hidl_version maxVersion{0,0};
550f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    res = mCameraProviderManager->getHighestSupportedVersion(cameraId.string(),
551f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev            &maxVersion);
552f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    if (res != OK) return -1;
553f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    deviceVersion = HARDWARE_DEVICE_API_VERSION(maxVersion.get_major(), maxVersion.get_minor());
554f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev
555f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    hardware::CameraInfo info;
556f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    if (facing) {
557f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev        res = mCameraProviderManager->getCameraInfo(cameraId.string(), &info);
5586963d0ad7b621dcdaa74cbfed17c776121635146Eino-Ville Talvala        if (res != OK) return -1;
559f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev        *facing = info.facing;
5602f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
561f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev
562634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    return deviceVersion;
563634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
564634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
565d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::filterGetInfoErrorCode(status_t err) {
566f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala    switch(err) {
567f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala        case NO_ERROR:
568d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return Status::ok();
569f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        case BAD_VALUE:
570d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT,
571d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    "CameraId is not valid for HAL module");
572f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        case NO_INIT:
573d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return STATUS_ERROR(ERROR_DISCONNECTED,
574d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    "Camera device not available");
575f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala        default:
576d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
577d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    "Camera HAL encountered error %d: %s",
578d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    err, strerror(-err));
579f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala    }
580bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin}
581bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
582d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::makeClient(const sp<CameraService>& cameraService,
5832f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        const sp<IInterface>& cameraCb, const String16& packageName, const String8& cameraId,
584c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        int api1CameraId, int facing, int clientPid, uid_t clientUid, int servicePid,
585c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        bool legacyMode, int halVersion, int deviceVersion, apiLevel effectiveApiLevel,
586cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        /*out*/sp<BasicClient>* client) {
587b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk
588cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    if (halVersion < 0 || halVersion == deviceVersion) {
589cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // Default path: HAL version is unspecified by caller, create CameraClient
590cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // based on device version reported by the HAL.
591cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        switch(deviceVersion) {
592cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk          case CAMERA_DEVICE_API_VERSION_1_0:
593cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            if (effectiveApiLevel == API_1) {  // Camera1 API route
594cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
595c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                *client = new CameraClient(cameraService, tmp, packageName,
596c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                        api1CameraId, facing, clientPid, clientUid,
597c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                        getpid(), legacyMode);
598cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            } else { // Camera2 API route
599cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                ALOGW("Camera using old HAL version: %d", deviceVersion);
600d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                return STATUS_ERROR_FMT(ERROR_DEPRECATED_HAL,
6012f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                        "Camera device \"%s\" HAL version %d does not support camera2 API",
6022f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                        cameraId.string(), deviceVersion);
603cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            }
604cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            break;
605cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk          case CAMERA_DEVICE_API_VERSION_3_0:
606cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk          case CAMERA_DEVICE_API_VERSION_3_1:
607cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk          case CAMERA_DEVICE_API_VERSION_3_2:
608cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk          case CAMERA_DEVICE_API_VERSION_3_3:
6094afbdecf8c6dc5ad04f6fa6c8712ce2c56a00c47Zhijun He          case CAMERA_DEVICE_API_VERSION_3_4:
610cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            if (effectiveApiLevel == API_1) { // Camera1 API route
611cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
612c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                *client = new Camera2Client(cameraService, tmp, packageName,
613c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                        cameraId, api1CameraId,
614c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                        facing, clientPid, clientUid,
615c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                        servicePid, legacyMode);
616cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            } else { // Camera2 API route
617d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                sp<hardware::camera2::ICameraDeviceCallbacks> tmp =
618d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                        static_cast<hardware::camera2::ICameraDeviceCallbacks*>(cameraCb.get());
619d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                *client = new CameraDeviceClient(cameraService, tmp, packageName, cameraId,
620cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                        facing, clientPid, clientUid, servicePid);
621b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk            }
622cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            break;
623cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk          default:
624cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            // Should not be reachable
625cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            ALOGE("Unknown camera device HAL version: %d", deviceVersion);
626d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
6272f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                    "Camera device \"%s\" has unknown HAL version %d",
6282f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                    cameraId.string(), deviceVersion);
629b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk        }
630cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    } else {
631cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // A particular HAL version is requested by caller. Create CameraClient
632cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // based on the requested HAL version.
633cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        if (deviceVersion > CAMERA_DEVICE_API_VERSION_1_0 &&
634cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            halVersion == CAMERA_DEVICE_API_VERSION_1_0) {
635cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            // Only support higher HAL version device opened as HAL1.0 device.
636cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
637c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            *client = new CameraClient(cameraService, tmp, packageName,
638c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                    api1CameraId, facing, clientPid, clientUid,
639c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                    servicePid, legacyMode);
640cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        } else {
641cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            // Other combinations (e.g. HAL3.x open as HAL2.x) are not supported yet.
642cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            ALOGE("Invalid camera HAL version %x: HAL %x device can only be"
643cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    " opened as HAL %x device", halVersion, deviceVersion,
644cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    CAMERA_DEVICE_API_VERSION_1_0);
645d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
6462f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                    "Camera device \"%s\" (HAL version %d) cannot be opened as HAL version %d",
6472f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                    cameraId.string(), deviceVersion, halVersion);
648b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk        }
649b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk    }
650d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return Status::ok();
651cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
652cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
6536267b539d0d1ee7118aafd976d75cb8db397bc24Ruben BrunkString8 CameraService::toString(std::set<userid_t> intSet) {
6546267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk    String8 s("");
6556267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk    bool first = true;
6566267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk    for (userid_t i : intSet) {
6576267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        if (first) {
6586267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk            s.appendFormat("%d", i);
6596267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk            first = false;
6606267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        } else {
6616267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk            s.appendFormat(", %d", i);
6626267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        }
6636267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk    }
6646267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk    return s;
6656267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk}
6666267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk
667f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalaint32_t CameraService::mapToInterface(TorchModeStatus status) {
668f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    int32_t serviceStatus = ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE;
669f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    switch (status) {
670f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        case TorchModeStatus::NOT_AVAILABLE:
671f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            serviceStatus = ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE;
672f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            break;
673f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        case TorchModeStatus::AVAILABLE_OFF:
674f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            serviceStatus = ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF;
675f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            break;
676f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        case TorchModeStatus::AVAILABLE_ON:
677f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            serviceStatus = ICameraServiceListener::TORCH_STATUS_AVAILABLE_ON;
678f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            break;
679f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        default:
680f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            ALOGW("Unknown new flash status: %d", status);
681f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    }
682f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    return serviceStatus;
683f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala}
684f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
685f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville TalvalaCameraService::StatusInternal CameraService::mapToInternal(CameraDeviceStatus status) {
686f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    StatusInternal serviceStatus = StatusInternal::NOT_PRESENT;
687f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    switch (status) {
688f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        case CameraDeviceStatus::NOT_PRESENT:
689f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            serviceStatus = StatusInternal::NOT_PRESENT;
690f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            break;
691f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        case CameraDeviceStatus::PRESENT:
692f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            serviceStatus = StatusInternal::PRESENT;
693f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            break;
694f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        case CameraDeviceStatus::ENUMERATING:
695f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            serviceStatus = StatusInternal::ENUMERATING;
696f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            break;
697f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        default:
698f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            ALOGW("Unknown new HAL device status: %d", status);
699f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    }
700f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    return serviceStatus;
701f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala}
702f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
703f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalaint32_t CameraService::mapToInterface(StatusInternal status) {
704f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    int32_t serviceStatus = ICameraServiceListener::STATUS_NOT_PRESENT;
705f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    switch (status) {
706f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        case StatusInternal::NOT_PRESENT:
707f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            serviceStatus = ICameraServiceListener::STATUS_NOT_PRESENT;
708f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            break;
709f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        case StatusInternal::PRESENT:
710f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            serviceStatus = ICameraServiceListener::STATUS_PRESENT;
711f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            break;
712f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        case StatusInternal::ENUMERATING:
713f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            serviceStatus = ICameraServiceListener::STATUS_ENUMERATING;
714f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            break;
715f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        case StatusInternal::NOT_AVAILABLE:
716f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            serviceStatus = ICameraServiceListener::STATUS_NOT_AVAILABLE;
717f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            break;
718f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        case StatusInternal::UNKNOWN:
719f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            serviceStatus = ICameraServiceListener::STATUS_UNKNOWN;
720f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            break;
721f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        default:
722f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            ALOGW("Unknown new internal device status: %d", status);
723f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    }
724f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    return serviceStatus;
725f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala}
726f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
727d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::initializeShimMetadata(int cameraId) {
728cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    int uid = getCallingUid();
729b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk
73098a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen    String16 internalPackageName("cameraserver");
731cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    String8 id = String8::format("%d", cameraId);
732d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    Status ret = Status::ok();
733cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    sp<Client> tmp = nullptr;
734d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (!(ret = connectHelper<ICameraClient,Client>(
735c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            sp<ICameraClient>{nullptr}, id, cameraId,
736c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            static_cast<int>(CAMERA_HAL_API_VERSION_UNSPECIFIED),
737d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            internalPackageName, uid, USE_CALLING_PID,
738d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            API_1, /*legacyMode*/ false, /*shimUpdateOnly*/ true,
739d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            /*out*/ tmp)
740d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            ).isOk()) {
741d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        ALOGE("%s: Error initializing shim metadata: %s", __FUNCTION__, ret.toString8().string());
742b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk    }
743d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return ret;
744b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk}
745b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk
746d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::getLegacyParametersLazy(int cameraId,
74765d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin        /*out*/
74865d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin        CameraParameters* parameters) {
74965d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
75065d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    ALOGV("%s: for cameraId: %d", __FUNCTION__, cameraId);
75165d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
752d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    Status ret = Status::ok();
75365d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
75465d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    if (parameters == NULL) {
75565d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin        ALOGE("%s: parameters must not be null", __FUNCTION__);
756d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Parameters must not be null");
75765d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    }
75865d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
759cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    String8 id = String8::format("%d", cameraId);
76065d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
761cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    // Check if we already have parameters
762cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    {
763cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // Scope for service lock
764cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        Mutex::Autolock lock(mServiceLock);
765cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        auto cameraState = getCameraState(id);
766cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        if (cameraState == nullptr) {
767cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            ALOGE("%s: Invalid camera ID: %s", __FUNCTION__, id.string());
768d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
769d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    "Invalid camera ID: %s", id.string());
77065d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin        }
771cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        CameraParameters p = cameraState->getShimParams();
772cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        if (!p.isEmpty()) {
773cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            *parameters = p;
774d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return ret;
77565d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin        }
776cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
77765d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
778cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    int64_t token = IPCThreadState::self()->clearCallingIdentity();
779cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    ret = initializeShimMetadata(cameraId);
780cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    IPCThreadState::self()->restoreCallingIdentity(token);
781d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (!ret.isOk()) {
782cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // Error already logged by callee
783cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        return ret;
784cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
78565d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
786cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    // Check for parameters again
787cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    {
788cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // Scope for service lock
789cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        Mutex::Autolock lock(mServiceLock);
790cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        auto cameraState = getCameraState(id);
791cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        if (cameraState == nullptr) {
792cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            ALOGE("%s: Invalid camera ID: %s", __FUNCTION__, id.string());
793d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
794d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    "Invalid camera ID: %s", id.string());
795cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        }
796cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        CameraParameters p = cameraState->getShimParams();
797cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        if (!p.isEmpty()) {
798cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            *parameters = p;
799d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return ret;
80065d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin        }
80165d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    }
80265d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
803cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    ALOGE("%s: Parameters were not initialized, or were empty.  Device may not be present.",
804cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            __FUNCTION__);
805d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return STATUS_ERROR(ERROR_INVALID_OPERATION, "Unable to initialize legacy parameters");
80665d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin}
80765d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
80898a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen// Can camera service trust the caller based on the calling UID?
80998a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chenstatic bool isTrustedCallingUid(uid_t uid) {
81098a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen    switch (uid) {
811af9d030e075e659e9f50fdd143aa83459a7795e2Eino-Ville Talvala        case AID_MEDIA:        // mediaserver
81298a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen        case AID_CAMERASERVER: // cameraserver
813af9d030e075e659e9f50fdd143aa83459a7795e2Eino-Ville Talvala        case AID_RADIO:        // telephony
81498a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen            return true;
81598a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen        default:
81698a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen            return false;
81798a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen    }
81898a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen}
81998a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen
820d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::validateConnectLocked(const String8& cameraId,
82118df60e094edbaa08cbecd25b0398643b8a0f29aChien-Yu Chen        const String8& clientName8, /*inout*/int& clientUid, /*inout*/int& clientPid,
82218df60e094edbaa08cbecd25b0398643b8a0f29aChien-Yu Chen        /*out*/int& originalClientPid) const {
8235861a9a98c641261c4807c976c750e4611b3a57dTyler Luu
8249c2a2c26c0d70de97f51063b06a5efc79b327eedAlex Deymo#ifdef __BRILLO__
8259c2a2c26c0d70de97f51063b06a5efc79b327eedAlex Deymo    UNUSED(clientName8);
8269c2a2c26c0d70de97f51063b06a5efc79b327eedAlex Deymo    UNUSED(clientUid);
8279c2a2c26c0d70de97f51063b06a5efc79b327eedAlex Deymo    UNUSED(clientPid);
8289c2a2c26c0d70de97f51063b06a5efc79b327eedAlex Deymo    UNUSED(originalClientPid);
8299c2a2c26c0d70de97f51063b06a5efc79b327eedAlex Deymo#else
8307939aee8c1688bc8647c5bceb0d47a4e790ff27dChien-Yu Chen    Status allowed = validateClientPermissionsLocked(cameraId, clientName8, clientUid, clientPid,
8317939aee8c1688bc8647c5bceb0d47a4e790ff27dChien-Yu Chen            originalClientPid);
8320492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala    if (!allowed.isOk()) {
833ce761d1fef4da2a4dec3eb538d103fcde1971dbaChristopher Wiley        return allowed;
834ce761d1fef4da2a4dec3eb538d103fcde1971dbaChristopher Wiley    }
8359c2a2c26c0d70de97f51063b06a5efc79b327eedAlex Deymo#endif  // __BRILLO__
836ce761d1fef4da2a4dec3eb538d103fcde1971dbaChristopher Wiley
8370492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala    int callingPid = getCallingPid();
8380492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala
8392f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (!mInitialized) {
840cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        ALOGE("CameraService::connect X (PID %d) rejected (camera HAL module not loaded)",
841cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                callingPid);
8420492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala        return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
8430492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala                "No camera HAL module available to open camera device \"%s\"", cameraId.string());
8448951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    }
8458951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev
846cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    if (getCameraState(cameraId) == nullptr) {
847cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        ALOGE("CameraService::connect X (PID %d) rejected (invalid camera ID %s)", callingPid,
848cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                cameraId.string());
8490492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala        return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
8500492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala                "No camera device with ID \"%s\" available", cameraId.string());
85165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
85265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
8530492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala    status_t err = checkIfDeviceIsUsable(cameraId);
8540492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala    if (err != NO_ERROR) {
8550492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala        switch(err) {
8560492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala            case -ENODEV:
8570492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala            case -EBUSY:
8580492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala                return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
8590492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala                        "No camera device with ID \"%s\" currently available", cameraId.string());
8600492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala            default:
8610492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala                return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
8620492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala                        "Unknown error connecting to ID \"%s\"", cameraId.string());
8630492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala        }
8640492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala    }
8650492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala    return Status::ok();
8660039bcf0c4f10b92917c26df70c7847f1ab0b51eChristopher Wiley}
8670039bcf0c4f10b92917c26df70c7847f1ab0b51eChristopher Wiley
8680492686c4703b3ddbff52d047ef226b973a3388aEino-Ville TalvalaStatus CameraService::validateClientPermissionsLocked(const String8& cameraId,
8697939aee8c1688bc8647c5bceb0d47a4e790ff27dChien-Yu Chen        const String8& clientName8, int& clientUid, int& clientPid,
8707939aee8c1688bc8647c5bceb0d47a4e790ff27dChien-Yu Chen        /*out*/int& originalClientPid) const {
8710039bcf0c4f10b92917c26df70c7847f1ab0b51eChristopher Wiley    int callingPid = getCallingPid();
87298a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen    int callingUid = getCallingUid();
8735861a9a98c641261c4807c976c750e4611b3a57dTyler Luu
87498a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen    // Check if we can trust clientUid
875ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    if (clientUid == USE_CALLING_UID) {
87698a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen        clientUid = callingUid;
87798a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen    } else if (!isTrustedCallingUid(callingUid)) {
87898a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen        ALOGE("CameraService::connect X (calling PID %d, calling UID %d) rejected "
87998a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen                "(don't trust clientUid %d)", callingPid, callingUid, clientUid);
880d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
881d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "Untrusted caller (calling PID %d, UID %d) trying to "
882d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "forward camera access to camera %s for client %s (PID %d, UID %d)",
883d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                callingPid, callingUid, cameraId.string(),
884d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                clientName8.string(), clientUid, clientPid);
88598a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen    }
88698a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen
88798a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen    // Check if we can trust clientPid
88898a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen    if (clientPid == USE_CALLING_PID) {
88998a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen        clientPid = callingPid;
89098a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen    } else if (!isTrustedCallingUid(callingUid)) {
89198a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen        ALOGE("CameraService::connect X (calling PID %d, calling UID %d) rejected "
89298a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen                "(don't trust clientPid %d)", callingPid, callingUid, clientPid);
893d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
894d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "Untrusted caller (calling PID %d, UID %d) trying to "
895d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "forward camera access to camera %s for client %s (PID %d, UID %d)",
896d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                callingPid, callingUid, cameraId.string(),
897d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                clientName8.string(), clientUid, clientPid);
898ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    }
89965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
90098a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen    // If it's not calling from cameraserver, check the permission.
90198a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen    if (callingPid != getpid() &&
90298a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen            !checkPermission(String16("android.permission.CAMERA"), clientPid, clientUid)) {
90398a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen        ALOGE("Permission Denial: can't use the camera pid=%d, uid=%d", clientPid, clientUid);
904d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
905d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "Caller \"%s\" (PID %d, UID %d) cannot open camera \"%s\" without camera permission",
906d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                clientName8.string(), clientUid, clientPid, cameraId.string());
907ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    }
90865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
909a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    // Make sure the UID is in an active state to use the camera
9107b4ab78876db058155bc075385c4db9e33e42a25Svet Ganov    if (!mUidPolicy->isUidActive(callingUid, String16(clientName8))) {
911a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        ALOGE("Access Denial: can't use the camera from an idle UID pid=%d, uid=%d",
912a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            clientPid, clientUid);
913a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        return STATUS_ERROR_FMT(ERROR_DISABLED,
914a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov                "Caller \"%s\" (PID %d, UID %d) cannot open camera \"%s\" from background",
915a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov                clientName8.string(), clientUid, clientPid, cameraId.string());
916a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
917a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
9184f3d6203c71f9e76fbd2964ad54a81b7036f7e17Chien-Yu Chen    // Only use passed in clientPid to check permission. Use calling PID as the client PID that's
9194f3d6203c71f9e76fbd2964ad54a81b7036f7e17Chien-Yu Chen    // connected to camera service directly.
92018df60e094edbaa08cbecd25b0398643b8a0f29aChien-Yu Chen    originalClientPid = clientPid;
9214f3d6203c71f9e76fbd2964ad54a81b7036f7e17Chien-Yu Chen    clientPid = callingPid;
92265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
9236267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk    userid_t clientUserId = multiuser_get_user_id(clientUid);
924a3355430a36bbfa7b2c0d90eb30834f1c5dac337Wu-cheng Li
925a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    // Only allow clients who are being used by the current foreground device user, unless calling
926a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    // from our own process.
9276267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk    if (callingPid != getpid() && (mAllowedUsers.find(clientUserId) == mAllowedUsers.end())) {
9286267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        ALOGE("CameraService::connect X (PID %d) rejected (cannot connect from "
9296267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk                "device user %d, currently allowed device users: %s)", callingPid, clientUserId,
9306267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk                toString(mAllowedUsers).string());
931d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
932d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "Callers from device user %d are not currently allowed to connect to camera \"%s\"",
933d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                clientUserId, cameraId.string());
93436597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    }
93536597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
936d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return Status::ok();
937cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
938cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
939cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkstatus_t CameraService::checkIfDeviceIsUsable(const String8& cameraId) const {
940cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    auto cameraState = getCameraState(cameraId);
941cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    int callingPid = getCallingPid();
942cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    if (cameraState == nullptr) {
943cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        ALOGE("CameraService::connect X (PID %d) rejected (invalid camera ID %s)", callingPid,
944cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                cameraId.string());
945cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        return -ENODEV;
946cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
947cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
948f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    StatusInternal currentStatus = cameraState->getStatus();
949f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    if (currentStatus == StatusInternal::NOT_PRESENT) {
950cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        ALOGE("CameraService::connect X (PID %d) rejected (camera %s is not connected)",
951cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                callingPid, cameraId.string());
9520f61d8f14aa368c9cd7076528e8096e10ed100a0Ruben Brunk        return -ENODEV;
953f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    } else if (currentStatus == StatusInternal::ENUMERATING) {
954cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        ALOGE("CameraService::connect X (PID %d) rejected, (camera %s is initializing)",
955cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                callingPid, cameraId.string());
9560f61d8f14aa368c9cd7076528e8096e10ed100a0Ruben Brunk        return -EBUSY;
957cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin    }
958cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin
959cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return NO_ERROR;
960e6800cea0678dbc0bf697b44c3e4548b0253085cIgor Murashkin}
961e6800cea0678dbc0bf697b44c3e4548b0253085cIgor Murashkin
962cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkvoid CameraService::finishConnectLocked(const sp<BasicClient>& client,
963cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        const CameraService::DescriptorPtr& desc) {
964e6800cea0678dbc0bf697b44c3e4548b0253085cIgor Murashkin
965cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    // Make a descriptor for the incoming client
966cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    auto clientDescriptor = CameraService::CameraClientManager::makeClientDescriptor(client, desc);
967cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    auto evicted = mActiveClientManager.addAndEvict(clientDescriptor);
968cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
969cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    logConnected(desc->getKey(), static_cast<int>(desc->getOwnerId()),
970cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            String8(client->getPackageName()));
971cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
972cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    if (evicted.size() > 0) {
973cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // This should never happen - clients should already have been removed in disconnect
974cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        for (auto& i : evicted) {
975cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            ALOGE("%s: Invalid state: Client for camera %s was not removed in disconnect",
976cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    __FUNCTION__, i->getKey().string());
9772fd2440d0175ca3e196b01b7541a9e0d4ed9a694Wu-cheng Li        }
978e6800cea0678dbc0bf697b44c3e4548b0253085cIgor Murashkin
979cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        LOG_ALWAYS_FATAL("%s: Invalid state for CameraService, clients not evicted properly",
980cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                __FUNCTION__);
981cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
98224901c86e10a0923fe10f5e9bce5e6dba061a289Eino-Ville Talvala
98324901c86e10a0923fe10f5e9bce5e6dba061a289Eino-Ville Talvala    // And register a death notification for the client callback. Do
98424901c86e10a0923fe10f5e9bce5e6dba061a289Eino-Ville Talvala    // this last to avoid Binder policy where a nested Binder
98524901c86e10a0923fe10f5e9bce5e6dba061a289Eino-Ville Talvala    // transaction might be pre-empted to service the client death
98624901c86e10a0923fe10f5e9bce5e6dba061a289Eino-Ville Talvala    // notification if the client process dies before linkToDeath is
98724901c86e10a0923fe10f5e9bce5e6dba061a289Eino-Ville Talvala    // invoked.
98824901c86e10a0923fe10f5e9bce5e6dba061a289Eino-Ville Talvala    sp<IBinder> remoteCallback = client->getRemote();
98924901c86e10a0923fe10f5e9bce5e6dba061a289Eino-Ville Talvala    if (remoteCallback != nullptr) {
99024901c86e10a0923fe10f5e9bce5e6dba061a289Eino-Ville Talvala        remoteCallback->linkToDeath(this);
99124901c86e10a0923fe10f5e9bce5e6dba061a289Eino-Ville Talvala    }
992e6800cea0678dbc0bf697b44c3e4548b0253085cIgor Murashkin}
993e6800cea0678dbc0bf697b44c3e4548b0253085cIgor Murashkin
994cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkstatus_t CameraService::handleEvictionsLocked(const String8& cameraId, int clientPid,
995cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        apiLevel effectiveApiLevel, const sp<IBinder>& remoteCallback, const String8& packageName,
996a858ea0495c887621a2fd9c0afc13780deccb597Igor Murashkin        /*out*/
997cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        sp<BasicClient>* client,
998cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>* partial) {
999a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
1000cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    status_t ret = NO_ERROR;
10014f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk    std::vector<DescriptorPtr> evictedClients;
1002cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    DescriptorPtr clientDescriptor;
1003cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    {
1004cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        if (effectiveApiLevel == API_1) {
1005cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            // If we are using API1, any existing client for this camera ID with the same remote
1006cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            // should be returned rather than evicted to allow MediaRecorder to work properly.
1007cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1008cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            auto current = mActiveClientManager.get(cameraId);
1009cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            if (current != nullptr) {
1010cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                auto clientSp = current->getValue();
1011cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                if (clientSp.get() != nullptr) { // should never be needed
10120bbf8b213ad96051357e3ad6d6d2808bfa31a59aRuben Brunk                    if (!clientSp->canCastToApiClient(effectiveApiLevel)) {
10130bbf8b213ad96051357e3ad6d6d2808bfa31a59aRuben Brunk                        ALOGW("CameraService connect called from same client, but with a different"
10140bbf8b213ad96051357e3ad6d6d2808bfa31a59aRuben Brunk                                " API level, evicting prior client...");
10150bbf8b213ad96051357e3ad6d6d2808bfa31a59aRuben Brunk                    } else if (clientSp->getRemote() == remoteCallback) {
1016cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                        ALOGI("CameraService::connect X (PID %d) (second call from same"
10170bbf8b213ad96051357e3ad6d6d2808bfa31a59aRuben Brunk                                " app binder, returning the same client)", clientPid);
1018cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                        *client = clientSp;
1019cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                        return NO_ERROR;
1020cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    }
1021cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                }
1022cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            }
1023cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        }
10243068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
1025cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // Get current active client PIDs
1026cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        std::vector<int> ownerPids(mActiveClientManager.getAllOwners());
1027cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        ownerPids.push_back(clientPid);
1028cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
10298131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev        std::vector<int> priorityScores(ownerPids.size());
10308131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev        std::vector<int> states(ownerPids.size());
1031cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
10328131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev        // Get priority scores of all active PIDs
10338131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev        status_t err = ProcessInfoService::getProcessStatesScoresFromPids(
10348131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                ownerPids.size(), &ownerPids[0], /*out*/&states[0],
10358131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                /*out*/&priorityScores[0]);
10368131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev        if (err != OK) {
10378131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev            ALOGE("%s: Priority score query failed: %d",
10388131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                  __FUNCTION__, err);
10398131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev            return err;
10408131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev        }
1041cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1042cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // Update all active clients' priorities
10438131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev        std::map<int,resource_policy::ClientPriority> pidToPriorityMap;
1044cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        for (size_t i = 0; i < ownerPids.size() - 1; i++) {
10458131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev            pidToPriorityMap.emplace(ownerPids[i],
10468131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                    resource_policy::ClientPriority(priorityScores[i], states[i]));
1047cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        }
1048cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        mActiveClientManager.updatePriorities(pidToPriorityMap);
1049cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1050cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // Get state for the given cameraId
1051cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        auto state = getCameraState(cameraId);
1052cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        if (state == nullptr) {
1053cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            ALOGE("CameraService::connect X (PID %d) rejected (no camera device with ID %s)",
1054cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                clientPid, cameraId.string());
1055d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            // Should never get here because validateConnectLocked should have errored out
1056b10cdadf0fb945e23ca77008d4af76584bd0e39aZhijun He            return BAD_VALUE;
1057b10cdadf0fb945e23ca77008d4af76584bd0e39aZhijun He        }
1058cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1059cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // Make descriptor for incoming client
10602db86ffaebed02c67a08c8c3bd8e265509cd8c05Shuzhen Wang        clientDescriptor = CameraClientManager::makeClientDescriptor(cameraId,
1061cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                sp<BasicClient>{nullptr}, static_cast<int32_t>(state->getCost()),
1062cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                state->getConflicting(),
10638131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                priorityScores[priorityScores.size() - 1],
10648131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                clientPid,
10658131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                states[states.size() - 1]);
1066cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1067cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // Find clients that would be evicted
1068cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        auto evicted = mActiveClientManager.wouldEvict(clientDescriptor);
1069cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1070cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // If the incoming client was 'evicted,' higher priority clients have the camera in the
1071cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // background, so we cannot do evictions
1072cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        if (std::find(evicted.begin(), evicted.end(), clientDescriptor) != evicted.end()) {
1073cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            ALOGE("CameraService::connect X (PID %d) rejected (existing client(s) with higher"
1074cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    " priority).", clientPid);
1075cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1076cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            sp<BasicClient> clientSp = clientDescriptor->getValue();
1077cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            String8 curTime = getFormattedCurrentTime();
1078cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            auto incompatibleClients =
1079cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    mActiveClientManager.getIncompatibleClients(clientDescriptor);
1080cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1081cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            String8 msg = String8::format("%s : DENIED connect device %s client for package %s "
10828131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                    "(PID %d, score %d state %d) due to eviction policy", curTime.string(),
1083cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    cameraId.string(), packageName.string(), clientPid,
10848131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                    priorityScores[priorityScores.size() - 1],
10858131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                    states[states.size() - 1]);
1086cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1087cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            for (auto& i : incompatibleClients) {
1088cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                msg.appendFormat("\n   - Blocked by existing device %s client for package %s"
10898131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                        "(PID %" PRId32 ", score %" PRId32 ", state %" PRId32 ")",
10908131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                        i->getKey().string(),
10918131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                        String8{i->getValue()->getPackageName()}.string(),
10928131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                        i->getOwnerId(), i->getPriority().getScore(),
10938131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                        i->getPriority().getState());
1094022f0cb0c6f135edde4ebe84859c685933ee895eEino-Ville Talvala                ALOGE("   Conflicts with: Device %s, client package %s (PID %"
10958131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                        PRId32 ", score %" PRId32 ", state %" PRId32 ")", i->getKey().string(),
1096022f0cb0c6f135edde4ebe84859c685933ee895eEino-Ville Talvala                        String8{i->getValue()->getPackageName()}.string(), i->getOwnerId(),
10978131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                        i->getPriority().getScore(), i->getPriority().getState());
1098cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            }
1099cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1100cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            // Log the client's attempt
1101a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk            Mutex::Autolock l(mLogLock);
1102cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            mEventLog.add(msg);
1103cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1104cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            return -EBUSY;
1105cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        }
1106cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1107cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        for (auto& i : evicted) {
1108cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            sp<BasicClient> clientSp = i->getValue();
1109cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            if (clientSp.get() == nullptr) {
1110cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                ALOGE("%s: Invalid state: Null client in active client list.", __FUNCTION__);
1111cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1112cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                // TODO: Remove this
1113cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                LOG_ALWAYS_FATAL("%s: Invalid state for CameraService, null client in active list",
1114cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                        __FUNCTION__);
1115cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                mActiveClientManager.remove(i);
1116cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                continue;
1117cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            }
1118cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1119cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            ALOGE("CameraService::connect evicting conflicting client for camera ID %s",
1120cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    i->getKey().string());
11214f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk            evictedClients.push_back(i);
1122cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1123cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            // Log the clients evicted
1124a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk            logEvent(String8::format("EVICT device %s client held by package %s (PID"
11258131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                    " %" PRId32 ", score %" PRId32 ", state %" PRId32 ")\n - Evicted by device %s client for"
11268131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                    " package %s (PID %d, score %" PRId32 ", state %" PRId32 ")",
1127cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    i->getKey().string(), String8{clientSp->getPackageName()}.string(),
11288131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                    i->getOwnerId(), i->getPriority().getScore(),
11298131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                    i->getPriority().getState(), cameraId.string(),
1130cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    packageName.string(), clientPid,
11318131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                    priorityScores[priorityScores.size() - 1],
11328131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                    states[states.size() - 1]));
1133cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1134cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            // Notify the client of disconnection
1135d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            clientSp->notifyError(hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED,
1136cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    CaptureResultExtras());
1137b10cdadf0fb945e23ca77008d4af76584bd0e39aZhijun He        }
1138b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk    }
1139b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk
1140cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    // Do not hold mServiceLock while disconnecting clients, but retain the condition blocking
1141cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    // other clients from connecting in mServiceLockWrapper if held
1142cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    mServiceLock.unlock();
1143cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1144cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    // Clear caller identity temporarily so client disconnect PID checks work correctly
1145cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    int64_t token = IPCThreadState::self()->clearCallingIdentity();
1146cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1147cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    // Destroy evicted clients
1148cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    for (auto& i : evictedClients) {
1149cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // Disconnect is blocking, and should only have returned when HAL has cleaned up
11504f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk        i->getValue()->disconnect(); // Clients will remove themselves from the active client list
1151b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk    }
1152b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk
1153cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    IPCThreadState::self()->restoreCallingIdentity(token);
1154b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk
11554f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk    for (const auto& i : evictedClients) {
11564f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk        ALOGV("%s: Waiting for disconnect to complete for client for device %s (PID %" PRId32 ")",
11574f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk                __FUNCTION__, i->getKey().string(), i->getOwnerId());
11584f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk        ret = mActiveClientManager.waitUntilRemoved(i, DEFAULT_DISCONNECT_TIMEOUT_NS);
11594f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk        if (ret == TIMED_OUT) {
11604f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk            ALOGE("%s: Timed out waiting for client for device %s to disconnect, "
11614f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk                    "current clients:\n%s", __FUNCTION__, i->getKey().string(),
11624f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk                    mActiveClientManager.toString().string());
11634f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk            return -EBUSY;
11644f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk        }
11654f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk        if (ret != NO_ERROR) {
11664f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk            ALOGE("%s: Received error waiting for client for device %s to disconnect: %s (%d), "
11674f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk                    "current clients:\n%s", __FUNCTION__, i->getKey().string(), strerror(-ret),
11684f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk                    ret, mActiveClientManager.toString().string());
11694f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk            return ret;
11704f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk        }
11714f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk    }
11724f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk
11734f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk    evictedClients.clear();
11744f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk
1175cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    // Once clients have been disconnected, relock
1176cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    mServiceLock.lock();
1177cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1178cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    // Check again if the device was unplugged or something while we weren't holding mServiceLock
1179cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    if ((ret = checkIfDeviceIsUsable(cameraId)) != NO_ERROR) {
1180cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        return ret;
1181cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
1182cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1183cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    *partial = clientDescriptor;
1184cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return NO_ERROR;
1185b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk}
1186b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk
1187d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::connect(
1188e6800cea0678dbc0bf697b44c3e4548b0253085cIgor Murashkin        const sp<ICameraClient>& cameraClient,
1189c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        int api1CameraId,
1190280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov        const String16& clientPackageName,
11910f61d8f14aa368c9cd7076528e8096e10ed100a0Ruben Brunk        int clientUid,
119298a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen        int clientPid,
11930f61d8f14aa368c9cd7076528e8096e10ed100a0Ruben Brunk        /*out*/
1194d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        sp<ICamera>* device) {
1195e6800cea0678dbc0bf697b44c3e4548b0253085cIgor Murashkin
1196a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
1197d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    Status ret = Status::ok();
1198c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh
1199c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    String8 id = cameraIdIntToStr(api1CameraId);
1200cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    sp<Client> client = nullptr;
1201c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    ret = connectHelper<ICameraClient,Client>(cameraClient, id, api1CameraId,
1202d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageName, clientUid, clientPid, API_1,
1203d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            /*legacyMode*/ false, /*shimUpdateOnly*/ false,
1204d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            /*out*/client);
1205634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
1206d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if(!ret.isOk()) {
1207280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov        logRejected(id, getCallingPid(), String8(clientPackageName),
1208d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                ret.toString8());
1209cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        return ret;
1210acd695c42749f8821b0a0cc27739ddf096c6d4e8Igor Murashkin    }
1211bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
1212d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    *device = client;
1213d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return ret;
1214634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
1215634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
1216d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::connectLegacy(
1217b10cdadf0fb945e23ca77008d4af76584bd0e39aZhijun He        const sp<ICameraClient>& cameraClient,
1218c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        int api1CameraId, int halVersion,
1219280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov        const String16& clientPackageName,
1220b10cdadf0fb945e23ca77008d4af76584bd0e39aZhijun He        int clientUid,
1221b10cdadf0fb945e23ca77008d4af76584bd0e39aZhijun He        /*out*/
1222d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        sp<ICamera>* device) {
1223b10cdadf0fb945e23ca77008d4af76584bd0e39aZhijun He
1224a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
1225c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    String8 id = cameraIdIntToStr(api1CameraId);
1226b10cdadf0fb945e23ca77008d4af76584bd0e39aZhijun He
1227d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    Status ret = Status::ok();
1228cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    sp<Client> client = nullptr;
1229c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    ret = connectHelper<ICameraClient,Client>(cameraClient, id, api1CameraId, halVersion,
1230d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            clientPackageName, clientUid, USE_CALLING_PID, API_1,
1231d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            /*legacyMode*/ true, /*shimUpdateOnly*/ false,
1232d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            /*out*/client);
1233b10cdadf0fb945e23ca77008d4af76584bd0e39aZhijun He
1234d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if(!ret.isOk()) {
1235280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov        logRejected(id, getCallingPid(), String8(clientPackageName),
1236d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                ret.toString8());
1237cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        return ret;
1238b10cdadf0fb945e23ca77008d4af76584bd0e39aZhijun He    }
1239b10cdadf0fb945e23ca77008d4af76584bd0e39aZhijun He
1240d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    *device = client;
1241d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return ret;
1242b10cdadf0fb945e23ca77008d4af76584bd0e39aZhijun He}
1243b10cdadf0fb945e23ca77008d4af76584bd0e39aZhijun He
1244d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::connectDevice(
1245d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb,
1246f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        const String16& cameraId,
1247280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov        const String16& clientPackageName,
1248cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        int clientUid,
1249cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        /*out*/
1250d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        sp<hardware::camera2::ICameraDeviceUser>* device) {
1251cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1252a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
1253d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    Status ret = Status::ok();
1254f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    String8 id = String8(cameraId);
1255cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    sp<CameraDeviceClient> client = nullptr;
1256d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    ret = connectHelper<hardware::camera2::ICameraDeviceCallbacks,CameraDeviceClient>(cameraCb, id,
1257c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            /*api1CameraId*/-1,
1258d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageName,
1259d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            clientUid, USE_CALLING_PID, API_2,
1260d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            /*legacyMode*/ false, /*shimUpdateOnly*/ false,
1261d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            /*out*/client);
1262cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1263d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if(!ret.isOk()) {
1264280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov        logRejected(id, getCallingPid(), String8(clientPackageName),
1265d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                ret.toString8());
1266cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        return ret;
126788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    }
126888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen
1269d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    *device = client;
1270d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return ret;
127188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen}
127288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen
1273f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalatemplate<class CALLBACK, class CLIENT>
1274f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville TalvalaStatus CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
1275c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        int api1CameraId, int halVersion, const String16& clientPackageName, int clientUid,
1276c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        int clientPid, apiLevel effectiveApiLevel, bool legacyMode, bool shimUpdateOnly,
1277f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        /*out*/sp<CLIENT>& device) {
1278f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    binder::Status ret = binder::Status::ok();
1279f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1280f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    String8 clientName8(clientPackageName);
1281f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1282f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    int originalClientPid = 0;
1283f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1284f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    ALOGI("CameraService::connect call (PID %d \"%s\", camera ID %s) for HAL version %s and "
1285f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            "Camera API version %d", clientPid, clientName8.string(), cameraId.string(),
1286f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            (halVersion == -1) ? "default" : std::to_string(halVersion).c_str(),
1287f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            static_cast<int>(effectiveApiLevel));
1288f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1289f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    sp<CLIENT> client = nullptr;
1290f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    {
1291f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        // Acquire mServiceLock and prevent other clients from connecting
1292f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        std::unique_ptr<AutoConditionLock> lock =
1293f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                AutoConditionLock::waitAndAcquire(mServiceLockWrapper, DEFAULT_CONNECT_TIMEOUT_NS);
1294f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1295f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        if (lock == nullptr) {
1296f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            ALOGE("CameraService::connect (PID %d) rejected (too many other clients connecting)."
1297f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                    , clientPid);
1298f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE,
1299f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                    "Cannot open camera %s for \"%s\" (PID %d): Too many other clients connecting",
1300f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                    cameraId.string(), clientName8.string(), clientPid);
1301f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        }
1302f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1303f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        // Enforce client permissions and do basic sanity checks
1304f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        if(!(ret = validateConnectLocked(cameraId, clientName8,
1305f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                /*inout*/clientUid, /*inout*/clientPid, /*out*/originalClientPid)).isOk()) {
1306f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            return ret;
1307f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        }
1308f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1309f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        // Check the shim parameters after acquiring lock, if they have already been updated and
1310f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        // we were doing a shim update, return immediately
1311f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        if (shimUpdateOnly) {
1312f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            auto cameraState = getCameraState(cameraId);
1313f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            if (cameraState != nullptr) {
1314f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                if (!cameraState->getShimParams().isEmpty()) return ret;
1315f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            }
1316f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        }
1317f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1318f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        status_t err;
1319f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1320f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        sp<BasicClient> clientTmp = nullptr;
1321f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>> partial;
1322f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        if ((err = handleEvictionsLocked(cameraId, originalClientPid, effectiveApiLevel,
1323f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                IInterface::asBinder(cameraCb), clientName8, /*out*/&clientTmp,
1324f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                /*out*/&partial)) != NO_ERROR) {
1325f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            switch (err) {
1326f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                case -ENODEV:
1327f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                    return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
1328f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            "No camera device with ID \"%s\" currently available",
1329f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            cameraId.string());
1330f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                case -EBUSY:
1331f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                    return STATUS_ERROR_FMT(ERROR_CAMERA_IN_USE,
1332f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            "Higher-priority client using camera, ID \"%s\" currently unavailable",
1333f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            cameraId.string());
1334f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                default:
1335f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                    return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
1336f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            "Unexpected error %s (%d) opening camera \"%s\"",
1337f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            strerror(-err), err, cameraId.string());
1338f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            }
1339f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        }
1340f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1341f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        if (clientTmp.get() != nullptr) {
1342f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            // Handle special case for API1 MediaRecorder where the existing client is returned
1343f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            device = static_cast<CLIENT*>(clientTmp.get());
1344f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            return ret;
1345f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        }
1346f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1347f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        // give flashlight a chance to close devices if necessary.
1348f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        mFlashlight->prepareDeviceOpen(cameraId);
1349f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1350f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        int facing = -1;
13512f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        int deviceVersion = getDeviceVersion(cameraId, /*out*/&facing);
13526963d0ad7b621dcdaa74cbfed17c776121635146Eino-Ville Talvala        if (facing == -1) {
13536963d0ad7b621dcdaa74cbfed17c776121635146Eino-Ville Talvala            ALOGE("%s: Unable to get camera device \"%s\"  facing", __FUNCTION__, cameraId.string());
13546963d0ad7b621dcdaa74cbfed17c776121635146Eino-Ville Talvala            return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
13556963d0ad7b621dcdaa74cbfed17c776121635146Eino-Ville Talvala                    "Unable to get camera device \"%s\" facing", cameraId.string());
13566963d0ad7b621dcdaa74cbfed17c776121635146Eino-Ville Talvala        }
13576963d0ad7b621dcdaa74cbfed17c776121635146Eino-Ville Talvala
1358f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        sp<BasicClient> tmp = nullptr;
1359c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        if(!(ret = makeClient(this, cameraCb, clientPackageName,
1360c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                cameraId, api1CameraId, facing,
1361c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                clientPid, clientUid, getpid(), legacyMode,
1362c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                halVersion, deviceVersion, effectiveApiLevel,
1363f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                /*out*/&tmp)).isOk()) {
1364f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            return ret;
1365f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        }
1366f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        client = static_cast<CLIENT*>(tmp.get());
1367f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1368f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        LOG_ALWAYS_FATAL_IF(client.get() == nullptr, "%s: CameraService in invalid state",
1369f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                __FUNCTION__);
1370f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1371bd8c503398d6b483b7abba594c7838a4c93b6e23Emilian Peev        err = client->initialize(mCameraProviderManager, mMonitorTags);
13722f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        if (err != OK) {
13732f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            ALOGE("%s: Could not initialize client from HAL.", __FUNCTION__);
1374f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            // Errors could be from the HAL module open call or from AppOpsManager
1375f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            switch(err) {
1376f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                case BAD_VALUE:
1377f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                    return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
1378f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            "Illegal argument to HAL module for camera \"%s\"", cameraId.string());
1379f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                case -EBUSY:
1380f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                    return STATUS_ERROR_FMT(ERROR_CAMERA_IN_USE,
1381f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            "Camera \"%s\" is already open", cameraId.string());
1382f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                case -EUSERS:
1383f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                    return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE,
1384f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            "Too many cameras already open, cannot open camera \"%s\"",
1385f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            cameraId.string());
1386f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                case PERMISSION_DENIED:
1387f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                    return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
1388f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            "No permission to open camera \"%s\"", cameraId.string());
1389f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                case -EACCES:
1390f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                    return STATUS_ERROR_FMT(ERROR_DISABLED,
1391f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            "Camera \"%s\" disabled by policy", cameraId.string());
1392f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                case -ENODEV:
1393f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                default:
1394f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                    return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
1395f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            "Failed to initialize camera \"%s\": %s (%d)", cameraId.string(),
1396f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            strerror(-err), err);
1397f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            }
1398f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        }
1399f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1400f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        // Update shim paremeters for legacy clients
1401f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        if (effectiveApiLevel == API_1) {
1402f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            // Assume we have always received a Client subclass for API1
1403f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            sp<Client> shimClient = reinterpret_cast<Client*>(client.get());
1404f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            String8 rawParams = shimClient->getParameters();
1405f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            CameraParameters params(rawParams);
1406f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1407f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            auto cameraState = getCameraState(cameraId);
1408f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            if (cameraState != nullptr) {
1409f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                cameraState->setShimParams(params);
1410f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            } else {
1411f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                ALOGE("%s: Cannot update shim parameters for camera %s, no such device exists.",
1412f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                        __FUNCTION__, cameraId.string());
1413f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            }
1414f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        }
1415f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1416f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        if (shimUpdateOnly) {
1417f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            // If only updating legacy shim parameters, immediately disconnect client
1418f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            mServiceLock.unlock();
1419f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            client->disconnect();
1420f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            mServiceLock.lock();
1421f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        } else {
1422f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            // Otherwise, add client to active clients list
1423f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            finishConnectLocked(client, partial);
1424f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        }
1425f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    } // lock is destroyed, allow further connect calls
1426f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1427f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    // Important: release the mutex here so the client can call back into the service from its
1428f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    // destructor (can be at the end of the call)
1429f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    device = client;
1430f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    return ret;
1431f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala}
1432f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1433d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::setTorchMode(const String16& cameraId, bool enabled,
14343068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen        const sp<IBinder>& clientBinder) {
14352f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    Mutex::Autolock lock(mServiceLock);
1436a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala
1437a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
143899e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    if (enabled && clientBinder == nullptr) {
14393068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen        ALOGE("%s: torch client binder is NULL", __FUNCTION__);
1440d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT,
1441d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "Torch client Binder is null");
14423068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    }
14433068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
144488da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    String8 id = String8(cameraId.string());
144599e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    int uid = getCallingUid();
144688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen
144788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    // verify id is valid.
1448cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    auto state = getCameraState(id);
1449cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    if (state == nullptr) {
1450f6463fc62a09b8aad8e811a9abbe9f4d9f2688f9Chien-Yu Chen        ALOGE("%s: camera id is invalid %s", __FUNCTION__, id.string());
1451d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
1452d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "Camera ID \"%s\" is a not valid camera ID", id.string());
1453cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
1454cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1455f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    StatusInternal cameraStatus = state->getStatus();
1456f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    if (cameraStatus != StatusInternal::PRESENT &&
145752778d448123c185fd30cd77e84659fab966d740Yin-Chia Yeh            cameraStatus != StatusInternal::NOT_AVAILABLE) {
145852778d448123c185fd30cd77e84659fab966d740Yin-Chia Yeh        ALOGE("%s: camera id is invalid %s, status %d", __FUNCTION__, id.string(), (int)cameraStatus);
1459d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
1460d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "Camera ID \"%s\" is a not valid camera ID", id.string());
146188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    }
146288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen
146388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    {
146488da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen        Mutex::Autolock al(mTorchStatusMutex);
1465f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        TorchModeStatus status;
1466d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        status_t err = getTorchStatusLocked(id, &status);
1467d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        if (err != OK) {
1468d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            if (err == NAME_NOT_FOUND) {
1469d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
1470d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                        "Camera \"%s\" does not have a flash unit", id.string());
1471d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            }
147288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen            ALOGE("%s: getting current torch status failed for camera %s",
147388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen                    __FUNCTION__, id.string());
1474d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
1475d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    "Error updating torch status for camera \"%s\": %s (%d)", id.string(),
1476d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    strerror(-err), err);
147788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen        }
147888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen
1479f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        if (status == TorchModeStatus::NOT_AVAILABLE) {
148052778d448123c185fd30cd77e84659fab966d740Yin-Chia Yeh            if (cameraStatus == StatusInternal::NOT_AVAILABLE) {
148188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen                ALOGE("%s: torch mode of camera %s is not available because "
148288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen                        "camera is in use", __FUNCTION__, id.string());
1483d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                return STATUS_ERROR_FMT(ERROR_CAMERA_IN_USE,
1484d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                        "Torch for camera \"%s\" is not available due to an existing camera user",
1485d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                        id.string());
148688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen            } else {
148788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen                ALOGE("%s: torch mode of camera %s is not available due to "
148888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen                        "insufficient resources", __FUNCTION__, id.string());
1489d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE,
1490d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                        "Torch for camera \"%s\" is not available due to insufficient resources",
1491d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                        id.string());
149288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen            }
149388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen        }
149488da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    }
149588da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen
149699e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    {
149799e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        // Update UID map - this is used in the torch status changed callbacks, so must be done
149899e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        // before setTorchMode
1499fe751bea0d3eedd6e817aebf4e457425b82e7117Chien-Yu Chen        Mutex::Autolock al(mTorchUidMapMutex);
150099e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        if (mTorchUidMap.find(id) == mTorchUidMap.end()) {
150199e69716215cd0665379bc90d708f2ea8689831dRuben Brunk            mTorchUidMap[id].first = uid;
150299e69716215cd0665379bc90d708f2ea8689831dRuben Brunk            mTorchUidMap[id].second = uid;
150399e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        } else {
150499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk            // Set the pending UID
150599e69716215cd0665379bc90d708f2ea8689831dRuben Brunk            mTorchUidMap[id].first = uid;
150699e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        }
150799e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    }
150899e69716215cd0665379bc90d708f2ea8689831dRuben Brunk
1509d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    status_t err = mFlashlight->setTorchMode(id, enabled);
151099e69716215cd0665379bc90d708f2ea8689831dRuben Brunk
1511d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (err != OK) {
1512d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        int32_t errorCode;
1513d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        String8 msg;
1514d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        switch (err) {
1515d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            case -ENOSYS:
1516d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                msg = String8::format("Camera \"%s\" has no flashlight",
1517d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    id.string());
1518d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                errorCode = ERROR_ILLEGAL_ARGUMENT;
1519d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                break;
1520d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            default:
1521d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                msg = String8::format(
1522d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    "Setting torch mode of camera \"%s\" to %d failed: %s (%d)",
1523d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    id.string(), enabled, strerror(-err), err);
1524d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                errorCode = ERROR_INVALID_OPERATION;
1525d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        }
1526d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        ALOGE("%s: %s", __FUNCTION__, msg.string());
1527d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(errorCode, msg.string());
15283068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    }
15293068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
153088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    {
153188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen        // update the link to client's death
153288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen        Mutex::Autolock al(mTorchClientMapMutex);
153388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen        ssize_t index = mTorchClientMap.indexOfKey(id);
153488da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen        if (enabled) {
153588da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen            if (index == NAME_NOT_FOUND) {
153688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen                mTorchClientMap.add(id, clientBinder);
153788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen            } else {
153899e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                mTorchClientMap.valueAt(index)->unlinkToDeath(this);
153988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen                mTorchClientMap.replaceValueAt(index, clientBinder);
154088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen            }
154188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen            clientBinder->linkToDeath(this);
154288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen        } else if (index != NAME_NOT_FOUND) {
154399e69716215cd0665379bc90d708f2ea8689831dRuben Brunk            mTorchClientMap.valueAt(index)->unlinkToDeath(this);
15443068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen        }
15453068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    }
15463068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
1547d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return Status::ok();
15483068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen}
15493068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
1550d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::notifySystemEvent(int32_t eventId,
1551d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        const std::vector<int32_t>& args) {
1552a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
1553a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala
155436597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    switch(eventId) {
1555d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        case ICameraService::EVENT_USER_SWITCHED: {
15568abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala            // Try to register for UID policy updates, in case we're recovering
15578abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala            // from a system server crash
15588abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala            mUidPolicy->registerSelf();
1559d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            doUserSwitch(/*newUserIds*/ args);
156036597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk            break;
156136597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk        }
1562d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        case ICameraService::EVENT_NONE:
156336597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk        default: {
156436597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk            ALOGW("%s: Received invalid system event from system_server: %d", __FUNCTION__,
156536597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk                    eventId);
156636597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk            break;
156736597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk        }
156836597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    }
1569d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return Status::ok();
157036597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk}
157136597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
1572f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville TalvalaStatus CameraService::addListener(const sp<ICameraServiceListener>& listener,
1573f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        /*out*/
1574f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        std::vector<hardware::CameraStatus> *cameraStatuses) {
1575a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
1576a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala
1577bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin    ALOGV("%s: Add listener %p", __FUNCTION__, listener.get());
1578634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
15793450ba7879be6522ea46a56c5e66e5382f5dd5baRuben Brunk    if (listener == nullptr) {
1580bd3e2e03f3ab686c52982a9e50cae853128172cfIgor Murashkin        ALOGE("%s: Listener must not be null", __FUNCTION__);
1581d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Null listener given to addListener");
1582bd3e2e03f3ab686c52982a9e50cae853128172cfIgor Murashkin    }
1583bd3e2e03f3ab686c52982a9e50cae853128172cfIgor Murashkin
1584bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin    Mutex::Autolock lock(mServiceLock);
1585bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
1586cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    {
1587cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        Mutex::Autolock lock(mStatusListenerLock);
1588cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        for (auto& it : mListenerList) {
1589cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            if (IInterface::asBinder(it) == IInterface::asBinder(listener)) {
1590cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                ALOGW("%s: Tried to add listener %p which was already subscribed",
1591cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                      __FUNCTION__, listener.get());
1592d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                return STATUS_ERROR(ERROR_ALREADY_EXISTS, "Listener already registered");
1593cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            }
1594bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin        }
1595cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1596cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        mListenerList.push_back(listener);
1597bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin    }
1598bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
1599f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    /* Collect current devices and status */
1600cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin    {
1601cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        Mutex::Autolock lock(mCameraStatesLock);
1602cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        for (auto& i : mCameraStates) {
1603f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            cameraStatuses->emplace_back(i.first, mapToInterface(i.second->getStatus()));
1604cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin        }
1605cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin    }
1606cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin
1607f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    /*
1608f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala     * Immediately signal current torch status to this listener only
1609f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala     * This may be a subset of all the devices, so don't include it in the response directly
1610f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala     */
16113068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    {
16123068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen        Mutex::Autolock al(mTorchStatusMutex);
16133068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen        for (size_t i = 0; i < mTorchStatusMap.size(); i++ ) {
161488da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen            String16 id = String16(mTorchStatusMap.keyAt(i).string());
1615f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            listener->onTorchStatusChanged(mapToInterface(mTorchStatusMap.valueAt(i)), id);
16163068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen        }
16173068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    }
16183068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
1619d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return Status::ok();
1620bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin}
1621cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1622d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::removeListener(const sp<ICameraServiceListener>& listener) {
1623a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
1624a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala
1625bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin    ALOGV("%s: Remove listener %p", __FUNCTION__, listener.get());
1626bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
1627bd3e2e03f3ab686c52982a9e50cae853128172cfIgor Murashkin    if (listener == 0) {
1628bd3e2e03f3ab686c52982a9e50cae853128172cfIgor Murashkin        ALOGE("%s: Listener must not be null", __FUNCTION__);
1629d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Null listener given to removeListener");
1630bd3e2e03f3ab686c52982a9e50cae853128172cfIgor Murashkin    }
1631bd3e2e03f3ab686c52982a9e50cae853128172cfIgor Murashkin
1632bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin    Mutex::Autolock lock(mServiceLock);
1633bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
1634cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    {
1635cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        Mutex::Autolock lock(mStatusListenerLock);
1636cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        for (auto it = mListenerList.begin(); it != mListenerList.end(); it++) {
1637cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            if (IInterface::asBinder(*it) == IInterface::asBinder(listener)) {
1638cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                mListenerList.erase(it);
1639d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                return Status::ok();
1640cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            }
1641bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin        }
1642bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin    }
1643bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
1644bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin    ALOGW("%s: Tried to remove a listener %p which was not subscribed",
1645bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin          __FUNCTION__, listener.get());
1646bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
1647d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Unregistered listener given to removeListener");
164865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
164965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1650d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::getLegacyParameters(int cameraId, /*out*/String16* parameters) {
1651a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala
1652a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
165365d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    ALOGV("%s: for camera ID = %d", __FUNCTION__, cameraId);
165465d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
165565d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    if (parameters == NULL) {
165665d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin        ALOGE("%s: parameters must not be null", __FUNCTION__);
1657d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Parameters must not be null");
165865d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    }
165965d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
1660d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    Status ret = Status::ok();
166165d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
166265d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    CameraParameters shimParams;
1663d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (!(ret = getLegacyParametersLazy(cameraId, /*out*/&shimParams)).isOk()) {
166465d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin        // Error logged by caller
166565d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin        return ret;
166665d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    }
166765d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
166865d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    String8 shimParamsString8 = shimParams.flatten();
166965d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    String16 shimParamsString16 = String16(shimParamsString8);
167065d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
167165d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    *parameters = shimParamsString16;
167265d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
1673d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return ret;
167465d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin}
167565d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
1676f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville TalvalaStatus CameraService::supportsCameraApi(const String16& cameraId, int apiVersion,
1677f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        /*out*/ bool *isSupported) {
1678a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
1679a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala
16802f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    const String8 id = String8(cameraId);
16812f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
16822f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    ALOGV("%s: for camera ID = %s", __FUNCTION__, id.string());
168365d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
168465d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    switch (apiVersion) {
168565d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin        case API_VERSION_1:
168665d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin        case API_VERSION_2:
168765d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin            break;
168865d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin        default:
1689d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            String8 msg = String8::format("Unknown API version %d", apiVersion);
1690d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            ALOGE("%s: %s", __FUNCTION__, msg.string());
1691d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.string());
169265d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    }
169365d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
169428ad2eae9ac86df397b27d27fcc92d2c893138afEmilian Peev    int deviceVersion = getDeviceVersion(id);
169565d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    switch(deviceVersion) {
1696d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        case CAMERA_DEVICE_API_VERSION_1_0:
1697d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        case CAMERA_DEVICE_API_VERSION_3_0:
1698d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        case CAMERA_DEVICE_API_VERSION_3_1:
1699d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            if (apiVersion == API_VERSION_2) {
17002f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                ALOGV("%s: Camera id %s uses HAL version %d <3.2, doesn't support api2 without shim",
17012f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                        __FUNCTION__, id.string(), deviceVersion);
1702d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                *isSupported = false;
1703d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            } else { // if (apiVersion == API_VERSION_1) {
17042f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                ALOGV("%s: Camera id %s uses older HAL before 3.2, but api1 is always supported",
17052f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                        __FUNCTION__, id.string());
1706d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                *isSupported = true;
1707d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            }
1708d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            break;
1709d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        case CAMERA_DEVICE_API_VERSION_3_2:
1710d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        case CAMERA_DEVICE_API_VERSION_3_3:
17114afbdecf8c6dc5ad04f6fa6c8712ce2c56a00c47Zhijun He        case CAMERA_DEVICE_API_VERSION_3_4:
17122f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            ALOGV("%s: Camera id %s uses HAL3.2 or newer, supports api1/api2 directly",
17132f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                    __FUNCTION__, id.string());
1714d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            *isSupported = true;
1715d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            break;
1716d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        case -1: {
17172f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            String8 msg = String8::format("Unknown camera ID %s", id.string());
1718d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            ALOGE("%s: %s", __FUNCTION__, msg.string());
1719d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.string());
1720d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        }
1721d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        default: {
17222f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            String8 msg = String8::format("Unknown device version %x for device %s",
17232f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                    deviceVersion, id.string());
1724d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            ALOGE("%s: %s", __FUNCTION__, msg.string());
1725d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return STATUS_ERROR(ERROR_INVALID_OPERATION, msg.string());
1726d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        }
172765d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    }
172865d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
1729d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return Status::ok();
173065d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin}
173165d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
1732cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkvoid CameraService::removeByClient(const BasicClient* client) {
1733ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    Mutex::Autolock lock(mServiceLock);
1734cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    for (auto& i : mActiveClientManager.getAll()) {
1735cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        auto clientSp = i->getValue();
1736cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        if (clientSp.get() == client) {
1737cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            mActiveClientManager.remove(i);
1738634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        }
1739634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    }
1740634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
1741634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
1742cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkbool CameraService::evictClientIdByRemote(const wp<IBinder>& remote) {
1743cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    bool ret = false;
1744cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    {
1745cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // Acquire mServiceLock and prevent other clients from connecting
1746cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        std::unique_ptr<AutoConditionLock> lock =
1747cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                AutoConditionLock::waitAndAcquire(mServiceLockWrapper);
1748634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
1749634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
1750cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        std::vector<sp<BasicClient>> evicted;
1751cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        for (auto& i : mActiveClientManager.getAll()) {
1752cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            auto clientSp = i->getValue();
1753cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            if (clientSp.get() == nullptr) {
1754cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                ALOGE("%s: Dead client still in mActiveClientManager.", __FUNCTION__);
1755cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                mActiveClientManager.remove(i);
1756cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                continue;
1757cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            }
1758dbfcb38f6636931b2e3e6da8e6aa5a7bfce84a82Yin-Chia Yeh            if (remote == clientSp->getRemote()) {
1759cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                mActiveClientManager.remove(i);
1760cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                evicted.push_back(clientSp);
1761cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1762cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                // Notify the client of disconnection
1763d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                clientSp->notifyError(
1764d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                        hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED,
1765cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                        CaptureResultExtras());
1766634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin            }
1767634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        }
1768634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
1769cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // Do not hold mServiceLock while disconnecting clients, but retain the condition blocking
1770cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // other clients from connecting in mServiceLockWrapper if held
1771cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        mServiceLock.unlock();
1772ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
177336597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk        // Do not clear caller identity, remote caller should be client proccess
177436597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
1775cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        for (auto& i : evicted) {
1776cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            if (i.get() != nullptr) {
1777cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                i->disconnect();
1778cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                ret = true;
1779cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            }
1780cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        }
1781ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
1782cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // Reacquire mServiceLock
1783cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        mServiceLock.lock();
178465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1785cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    } // lock is destroyed, allow further connect calls
178665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1787cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return ret;
1788cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
178965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1790cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkstd::shared_ptr<CameraService::CameraState> CameraService::getCameraState(
1791cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        const String8& cameraId) const {
1792cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    std::shared_ptr<CameraState> state;
1793cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    {
1794cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        Mutex::Autolock lock(mCameraStatesLock);
1795cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        auto iter = mCameraStates.find(cameraId);
1796cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        if (iter != mCameraStates.end()) {
1797cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            state = iter->second;
179865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
179965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
1800cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return state;
180165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
180265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1803cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunksp<CameraService::BasicClient> CameraService::removeClientLocked(const String8& cameraId) {
1804cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    // Remove from active clients list
1805cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    auto clientDescriptorPtr = mActiveClientManager.remove(cameraId);
1806cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    if (clientDescriptorPtr == nullptr) {
1807cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        ALOGW("%s: Could not evict client, no client for camera ID %s", __FUNCTION__,
1808cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                cameraId.string());
1809cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        return sp<BasicClient>{nullptr};
1810cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
1811d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park
1812cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return clientDescriptorPtr->getValue();
181365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
181465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1815d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvalavoid CameraService::doUserSwitch(const std::vector<int32_t>& newUserIds) {
181636597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    // Acquire mServiceLock and prevent other clients from connecting
181736597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    std::unique_ptr<AutoConditionLock> lock =
181836597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk            AutoConditionLock::waitAndAcquire(mServiceLockWrapper);
181936597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
18206267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk    std::set<userid_t> newAllowedUsers;
1821d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    for (size_t i = 0; i < newUserIds.size(); i++) {
1822d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        if (newUserIds[i] < 0) {
18236267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk            ALOGE("%s: Bad user ID %d given during user switch, ignoring.",
1824d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    __FUNCTION__, newUserIds[i]);
18256267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk            return;
18266267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        }
1827d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        newAllowedUsers.insert(static_cast<userid_t>(newUserIds[i]));
18286267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk    }
18296267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk
18306267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk
18316267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk    if (newAllowedUsers == mAllowedUsers) {
18326267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        ALOGW("%s: Received notification of user switch with no updated user IDs.", __FUNCTION__);
18336267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        return;
183436597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    }
183536597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
18366267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk    logUserSwitch(mAllowedUsers, newAllowedUsers);
1837a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk
18386267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk    mAllowedUsers = std::move(newAllowedUsers);
183936597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
184036597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    // Current user has switched, evict all current clients.
184136597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    std::vector<sp<BasicClient>> evicted;
184236597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    for (auto& i : mActiveClientManager.getAll()) {
184336597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk        auto clientSp = i->getValue();
184436597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
184536597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk        if (clientSp.get() == nullptr) {
184636597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk            ALOGE("%s: Dead client still in mActiveClientManager.", __FUNCTION__);
184736597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk            continue;
184836597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk        }
184936597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
18506267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        // Don't evict clients that are still allowed.
18516267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        uid_t clientUid = clientSp->getClientUid();
18526267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        userid_t clientUserId = multiuser_get_user_id(clientUid);
18536267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        if (mAllowedUsers.find(clientUserId) != mAllowedUsers.end()) {
18546267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk            continue;
18556267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        }
18566267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk
185736597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk        evicted.push_back(clientSp);
185836597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
185936597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk        String8 curTime = getFormattedCurrentTime();
186036597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
186136597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk        ALOGE("Evicting conflicting client for camera ID %s due to user change",
186236597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk                i->getKey().string());
1863a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk
186436597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk        // Log the clients evicted
1865a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk        logEvent(String8::format("EVICT device %s client held by package %s (PID %"
18668131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                PRId32 ", score %" PRId32 ", state %" PRId32 ")\n   - Evicted due"
18678131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                " to user switch.", i->getKey().string(),
18688131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                String8{clientSp->getPackageName()}.string(),
18698131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                i->getOwnerId(), i->getPriority().getScore(),
18708131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                i->getPriority().getState()));
187136597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
187236597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    }
187336597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
187436597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    // Do not hold mServiceLock while disconnecting clients, but retain the condition
187536597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    // blocking other clients from connecting in mServiceLockWrapper if held.
187636597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    mServiceLock.unlock();
187736597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
187836597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    // Clear caller identity temporarily so client disconnect PID checks work correctly
187936597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    int64_t token = IPCThreadState::self()->clearCallingIdentity();
188036597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
188136597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    for (auto& i : evicted) {
188236597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk        i->disconnect();
188336597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    }
188436597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
188536597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    IPCThreadState::self()->restoreCallingIdentity(token);
188636597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
188736597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    // Reacquire mServiceLock
188836597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    mServiceLock.lock();
188936597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk}
1890ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
1891a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunkvoid CameraService::logEvent(const char* event) {
1892cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    String8 curTime = getFormattedCurrentTime();
1893a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    Mutex::Autolock l(mLogLock);
1894a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    mEventLog.add(String8::format("%s : %s", curTime.string(), event));
1895cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
1896ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
1897a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunkvoid CameraService::logDisconnected(const char* cameraId, int clientPid,
1898280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov        const char* clientPackage) {
1899a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    // Log the clients evicted
1900a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    logEvent(String8::format("DISCONNECT device %s client for package %s (PID %d)", cameraId,
1901280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov            clientPackage, clientPid));
1902a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk}
1903ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
1904a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunkvoid CameraService::logConnected(const char* cameraId, int clientPid,
1905280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov        const char* clientPackage) {
1906cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    // Log the clients evicted
1907a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    logEvent(String8::format("CONNECT device %s client for package %s (PID %d)", cameraId,
1908280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov            clientPackage, clientPid));
1909a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk}
1910a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk
1911a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunkvoid CameraService::logRejected(const char* cameraId, int clientPid,
1912280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov        const char* clientPackage, const char* reason) {
1913a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    // Log the client rejected
1914a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    logEvent(String8::format("REJECT device %s client for package %s (PID %d), reason: (%s)",
1915280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov            cameraId, clientPackage, clientPid, reason));
1916a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk}
1917a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk
19186267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunkvoid CameraService::logUserSwitch(const std::set<userid_t>& oldUserIds,
19196267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        const std::set<userid_t>& newUserIds) {
19206267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk    String8 newUsers = toString(newUserIds);
19216267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk    String8 oldUsers = toString(oldUserIds);
1922d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala    if (oldUsers.size() == 0) {
1923d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        oldUsers = "<None>";
1924d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala    }
1925a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    // Log the new and old users
1926d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala    logEvent(String8::format("USER_SWITCH previous allowed user IDs: %s, current allowed user IDs: %s",
19276267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk            oldUsers.string(), newUsers.string()));
1928a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk}
1929a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk
1930a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunkvoid CameraService::logDeviceRemoved(const char* cameraId, const char* reason) {
1931a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    // Log the device removal
1932a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    logEvent(String8::format("REMOVE device %s, reason: (%s)", cameraId, reason));
1933a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk}
1934a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk
1935a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunkvoid CameraService::logDeviceAdded(const char* cameraId, const char* reason) {
1936a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    // Log the device removal
1937a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    logEvent(String8::format("ADD device %s, reason: (%s)", cameraId, reason));
1938a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk}
1939a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk
1940a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunkvoid CameraService::logClientDied(int clientPid, const char* reason) {
1941a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    // Log the device removal
1942a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    logEvent(String8::format("DIED client(s) with PID %d, reason: (%s)", clientPid, reason));
1943ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin}
1944ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
19451527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvalavoid CameraService::logServiceError(const char* msg, int errorCode) {
19461527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvala    String8 curTime = getFormattedCurrentTime();
1947d309fb9c8a2c4564d88fffba19c4e3688e4b862bEino-Ville Talvala    logEvent(String8::format("SERVICE ERROR: %s : %d (%s)", msg, errorCode, strerror(-errorCode)));
19481527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvala}
19491527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvala
195036597b241c59eba7e55d5150092947a748c5e9cbRuben Brunkstatus_t CameraService::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
195136597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk        uint32_t flags) {
195236597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
195336597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    const int pid = getCallingPid();
195436597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    const int selfPid = getpid();
195536597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
195665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // Permission checks
195765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    switch (code) {
1958a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        case SHELL_COMMAND_TRANSACTION: {
1959a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            int in = data.readFileDescriptor();
1960a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            int out = data.readFileDescriptor();
1961a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            int err = data.readFileDescriptor();
1962a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            int argc = data.readInt32();
1963a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            Vector<String16> args;
1964a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
1965a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov               args.add(data.readString16());
1966a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            }
1967a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            sp<IBinder> unusedCallback;
1968a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            sp<IResultReceiver> resultReceiver;
1969a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            status_t status;
1970a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            if ((status = data.readNullableStrongBinder(&unusedCallback)) != NO_ERROR) {
1971a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov                return status;
1972a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            }
1973a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            if ((status = data.readNullableStrongBinder(&resultReceiver)) != NO_ERROR) {
1974a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov                return status;
1975a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            }
1976a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            status = shellCommand(in, out, err, args);
1977a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            if (resultReceiver != nullptr) {
1978a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov                resultReceiver->send(status);
1979a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            }
1980a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            return NO_ERROR;
1981a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        }
1982d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        case BnCameraService::NOTIFYSYSTEMEVENT: {
198336597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk            if (pid != selfPid) {
198436597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk                // Ensure we're being called by system_server, or similar process with
198536597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk                // permissions to notify the camera service about system events
198636597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk                if (!checkCallingPermission(
198736597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk                        String16("android.permission.CAMERA_SEND_SYSTEM_EVENTS"))) {
198836597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk                    const int uid = getCallingUid();
198936597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk                    ALOGE("Permission Denial: cannot send updates to camera service about system"
199036597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk                            " events from pid=%d, uid=%d", pid, uid);
199136597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk                    return PERMISSION_DENIED;
199236597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk                }
199336597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk            }
199436597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk            break;
199536597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk        }
199665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
199765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
199865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return BnCameraService::onTransact(code, data, reply, flags);
199965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
200065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
200165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// We share the media players for shutter and recording sound for all clients.
200265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// A reference count is kept to determine when we will actually release the
200365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// media players.
200465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2005ef49805296eb81cd4ba039fa4d25b9358436992bJaekyun Seoksp<MediaPlayer> CameraService::newMediaPlayer(const char *file) {
2006ef49805296eb81cd4ba039fa4d25b9358436992bJaekyun Seok    sp<MediaPlayer> mp = new MediaPlayer();
2007ef49805296eb81cd4ba039fa4d25b9358436992bJaekyun Seok    status_t error;
2008ef49805296eb81cd4ba039fa4d25b9358436992bJaekyun Seok    if ((error = mp->setDataSource(NULL /* httpService */, file, NULL)) == NO_ERROR) {
200960a78ac9535878984b0777788760b9ee7465c5e6Eino-Ville Talvala        mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE);
2010ef49805296eb81cd4ba039fa4d25b9358436992bJaekyun Seok        error = mp->prepare();
2011ef49805296eb81cd4ba039fa4d25b9358436992bJaekyun Seok    }
2012ef49805296eb81cd4ba039fa4d25b9358436992bJaekyun Seok    if (error != NO_ERROR) {
201329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to load CameraService sounds: %s", file);
2014ef49805296eb81cd4ba039fa4d25b9358436992bJaekyun Seok        mp->disconnect();
2015ef49805296eb81cd4ba039fa4d25b9358436992bJaekyun Seok        mp.clear();
201659a8ef0135bab204ed027625011a1f55d99a694dJaekyun Seok        return nullptr;
201765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
201865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return mp;
201965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
202065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
202165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::loadSound() {
2022a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
2023a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala
202465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mSoundLock);
202565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("CameraService::loadSound ref=%d", mSoundRef);
202665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mSoundRef++) return;
202765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
202859a8ef0135bab204ed027625011a1f55d99a694dJaekyun Seok    mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/product/media/audio/ui/camera_click.ogg");
202959a8ef0135bab204ed027625011a1f55d99a694dJaekyun Seok    if (mSoundPlayer[SOUND_SHUTTER] == nullptr) {
203059a8ef0135bab204ed027625011a1f55d99a694dJaekyun Seok        mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
203159a8ef0135bab204ed027625011a1f55d99a694dJaekyun Seok    }
203259a8ef0135bab204ed027625011a1f55d99a694dJaekyun Seok    mSoundPlayer[SOUND_RECORDING_START] = newMediaPlayer("/product/media/audio/ui/VideoRecord.ogg");
203359a8ef0135bab204ed027625011a1f55d99a694dJaekyun Seok    if (mSoundPlayer[SOUND_RECORDING_START] == nullptr) {
203459a8ef0135bab204ed027625011a1f55d99a694dJaekyun Seok        mSoundPlayer[SOUND_RECORDING_START] =
203559a8ef0135bab204ed027625011a1f55d99a694dJaekyun Seok                newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");
203659a8ef0135bab204ed027625011a1f55d99a694dJaekyun Seok    }
203759a8ef0135bab204ed027625011a1f55d99a694dJaekyun Seok    mSoundPlayer[SOUND_RECORDING_STOP] = newMediaPlayer("/product/media/audio/ui/VideoStop.ogg");
203859a8ef0135bab204ed027625011a1f55d99a694dJaekyun Seok    if (mSoundPlayer[SOUND_RECORDING_STOP] == nullptr) {
203959a8ef0135bab204ed027625011a1f55d99a694dJaekyun Seok        mSoundPlayer[SOUND_RECORDING_STOP] = newMediaPlayer("/system/media/audio/ui/VideoStop.ogg");
204059a8ef0135bab204ed027625011a1f55d99a694dJaekyun Seok    }
204165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
204265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
204365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::releaseSound() {
204465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mSoundLock);
204565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("CameraService::releaseSound ref=%d", mSoundRef);
204665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (--mSoundRef) return;
204765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
204865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (int i = 0; i < NUM_SOUNDS; i++) {
204965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mSoundPlayer[i] != 0) {
205065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mSoundPlayer[i]->disconnect();
205165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mSoundPlayer[i].clear();
205265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
205365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
205465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
205565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
205665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::playSound(sound_kind kind) {
2057a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
2058a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala
205965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("playSound(%d)", kind);
206065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mSoundLock);
206165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<MediaPlayer> player = mSoundPlayer[kind];
206265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (player != 0) {
20638888a75f01d904541e409e858d23e4150ace34b6Chih-Chung Chang        player->seekTo(0);
20648888a75f01d904541e409e858d23e4150ace34b6Chih-Chung Chang        player->start();
206565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
206665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
206765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
206865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
206965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
207065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianCameraService::Client::Client(const sp<CameraService>& cameraService,
2071b7a67942823e8339eb298238f117aaa6d7b63111Wu-cheng Li        const sp<ICameraClient>& cameraClient,
2072280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov        const String16& clientPackageName,
2073c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        const String8& cameraIdStr,
2074c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        int api1CameraId, int cameraFacing,
2075ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        int clientPid, uid_t clientUid,
2076ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        int servicePid) :
2077e992e75053e98e3699af6e344c11b787e30411adEino-Ville Talvala        CameraService::BasicClient(cameraService,
2078f888020c6e2735624f2b2a30e72aca24e17b8b4dMarco Nelissen                IInterface::asBinder(cameraClient),
2079280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov                clientPackageName,
20802f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                cameraIdStr, cameraFacing,
2081ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala                clientPid, clientUid,
20822f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                servicePid),
2083c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        mCameraId(api1CameraId)
2084634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin{
208565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int callingPid = getCallingPid();
20862f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    LOG1("Client::Client E (pid %d, id %d)", callingPid, mCameraId);
208765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
208844cfcf00b9008c1c04f4c8277c6c06af039fd976Igor Murashkin    mRemoteCallback = cameraClient;
20895e08d60617fc63c2e41f9069ff89f5c00db2617dEino-Ville Talvala
209065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    cameraService->loadSound();
2091ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
20922f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    LOG1("Client::Client X (pid %d, id %d)", callingPid, mCameraId);
209365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
209465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
209565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// tear down the client
209665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianCameraService::Client::~Client() {
2097d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    ALOGV("~Client");
2098634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    mDestructionStarted = true;
2099634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
21002f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    sCameraService->releaseSound();
2101036bc3e2cfc5a11c3f7ace41088c8936dae2e946Igor Murashkin    // unconditionally disconnect. function is idempotent
2102036bc3e2cfc5a11c3f7ace41088c8936dae2e946Igor Murashkin    Client::disconnect();
210365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
210465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
21052f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalasp<CameraService> CameraService::BasicClient::BasicClient::sCameraService;
21062f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
2107634a51509ee50475f3e9f8ccf897e90fc72ded31Igor MurashkinCameraService::BasicClient::BasicClient(const sp<CameraService>& cameraService,
2108ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        const sp<IBinder>& remoteCallback,
2109280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov        const String16& clientPackageName,
21102f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        const String8& cameraIdStr, int cameraFacing,
2111ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        int clientPid, uid_t clientUid,
2112ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        int servicePid):
21132f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        mCameraIdStr(cameraIdStr), mCameraFacing(cameraFacing),
21142f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        mClientPackageName(clientPackageName), mClientPid(clientPid), mClientUid(clientUid),
21152f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        mServicePid(servicePid),
21162f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        mDisconnected(false),
21172f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        mRemoteBinder(remoteCallback)
2118634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin{
21192f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (sCameraService == nullptr) {
21202f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        sCameraService = cameraService;
21212f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
2122ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    mOpsActive = false;
2123634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    mDestructionStarted = false;
21240dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
21250dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    // In some cases the calling code has no access to the package it runs under.
21260dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    // For example, NDK camera API.
21270dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    // In this case we will get the packages for the calling UID and pick the first one
21280dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    // for attributing the app op. This will work correctly for runtime permissions
21290dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    // as for legacy apps we will toggle the app op for all packages in the UID.
21300dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    // The caveat is that the operation may be attributed to the wrong package and
21310dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    // stats based on app ops may be slightly off.
21320dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    if (mClientPackageName.size() <= 0) {
21330dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        sp<IServiceManager> sm = defaultServiceManager();
21340dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        sp<IBinder> binder = sm->getService(String16(kPermissionServiceName));
21350dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        if (binder == 0) {
21360dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            ALOGE("Cannot get permission service");
21370dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            // Leave mClientPackageName unchanged (empty) and the further interaction
21380dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            // with camera will fail in BasicClient::startCameraOps
21390dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            return;
21400dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        }
21410dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
21420dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        sp<IPermissionController> permCtrl = interface_cast<IPermissionController>(binder);
21430dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        Vector<String16> packages;
21440dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
21450dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        permCtrl->getPackagesForUid(mClientUid, packages);
21460dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
21470dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        if (packages.isEmpty()) {
21480dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            ALOGE("No packages for calling UID");
21490dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            // Leave mClientPackageName unchanged (empty) and the further interaction
21500dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            // with camera will fail in BasicClient::startCameraOps
21510dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            return;
21520dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        }
21530dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        mClientPackageName = packages[0];
21540dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    }
2155634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
2156634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
2157634a51509ee50475f3e9f8ccf897e90fc72ded31Igor MurashkinCameraService::BasicClient::~BasicClient() {
2158d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    ALOGV("~BasicClient");
2159634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    mDestructionStarted = true;
2160634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
2161634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
2162d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvalabinder::Status CameraService::BasicClient::disconnect() {
2163d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    binder::Status res = Status::ok();
216436597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    if (mDisconnected) {
2165d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return res;
216636597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    }
216724901c86e10a0923fe10f5e9bce5e6dba061a289Eino-Ville Talvala    mDisconnected = true;
2168cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
21692f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    sCameraService->removeByClient(this);
21702f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    sCameraService->logDisconnected(mCameraIdStr, mClientPid,
2171280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov            String8(mClientPackageName));
2172cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2173cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    sp<IBinder> remote = getRemote();
2174cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    if (remote != nullptr) {
21752f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        remote->unlinkToDeath(sCameraService);
2176cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
2177f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala
2178f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala    finishCameraOps();
2179e4fe21bb7cef893cd38bd194ea880333389aea38Chien-Yu Chen    // Notify flashlight that a camera device is closed.
21802f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    sCameraService->mFlashlight->deviceClosed(mCameraIdStr);
21812f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    ALOGI("%s: Disconnected client for camera %s for PID %d", __FUNCTION__, mCameraIdStr.string(),
21822f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            mClientPid);
2183cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2184cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin    // client shouldn't be able to call into us anymore
2185cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin    mClientPid = 0;
2186d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala
2187d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return res;
2188634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
2189634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
2190c4003965258404a19b99280ac0f475e2f290bf27Eino-Ville Talvalastatus_t CameraService::BasicClient::dump(int, const Vector<String16>&) {
2191c4003965258404a19b99280ac0f475e2f290bf27Eino-Ville Talvala    // No dumping of clients directly over Binder,
2192c4003965258404a19b99280ac0f475e2f290bf27Eino-Ville Talvala    // must go through CameraService::dump
2193c4003965258404a19b99280ac0f475e2f290bf27Eino-Ville Talvala    android_errorWriteWithInfoLog(SN_EVENT_LOG_ID, "26265403",
2194c4003965258404a19b99280ac0f475e2f290bf27Eino-Ville Talvala            IPCThreadState::self()->getCallingUid(), NULL, 0);
2195c4003965258404a19b99280ac0f475e2f290bf27Eino-Ville Talvala    return OK;
2196c4003965258404a19b99280ac0f475e2f290bf27Eino-Ville Talvala}
2197c4003965258404a19b99280ac0f475e2f290bf27Eino-Ville Talvala
2198cc776718c0be7c31fe5ab4fc1446d377be60369fRuben BrunkString16 CameraService::BasicClient::getPackageName() const {
2199280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov    return mClientPackageName;
2200cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
2201cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2202cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2203cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkint CameraService::BasicClient::getClientPid() const {
2204cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return mClientPid;
2205cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
2206cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
22076267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunkuid_t CameraService::BasicClient::getClientUid() const {
22086267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk    return mClientUid;
22096267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk}
22106267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk
22110bbf8b213ad96051357e3ad6d6d2808bfa31a59aRuben Brunkbool CameraService::BasicClient::canCastToApiClient(apiLevel level) const {
22120bbf8b213ad96051357e3ad6d6d2808bfa31a59aRuben Brunk    // Defaults to API2.
22130bbf8b213ad96051357e3ad6d6d2808bfa31a59aRuben Brunk    return level == API_2;
22140bbf8b213ad96051357e3ad6d6d2808bfa31a59aRuben Brunk}
22150bbf8b213ad96051357e3ad6d6d2808bfa31a59aRuben Brunk
2216ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvalastatus_t CameraService::BasicClient::startCameraOps() {
2217a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
2218a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala
2219ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    int32_t res;
2220f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala    // Notify app ops that the camera is not available
2221ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    mOpsCallback = new OpsCallback(this);
2222ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
2223e6800cea0678dbc0bf697b44c3e4548b0253085cIgor Murashkin    {
2224e6800cea0678dbc0bf697b44c3e4548b0253085cIgor Murashkin        ALOGV("%s: Start camera ops, package name = %s, client UID = %d",
2225280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov              __FUNCTION__, String8(mClientPackageName).string(), mClientUid);
2226e6800cea0678dbc0bf697b44c3e4548b0253085cIgor Murashkin    }
2227e6800cea0678dbc0bf697b44c3e4548b0253085cIgor Murashkin
2228ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    mAppOpsManager.startWatchingMode(AppOpsManager::OP_CAMERA,
2229280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov            mClientPackageName, mOpsCallback);
22301d519106f7a3d31cc89e3c4a1146106b0478a410Svet Ganov    res = mAppOpsManager.startOpNoThrow(AppOpsManager::OP_CAMERA,
22311d519106f7a3d31cc89e3c4a1146106b0478a410Svet Ganov            mClientUid, mClientPackageName, /*startIfModeDefault*/ false);
2232ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
223328e8ef72dab287af59663b89b12507e43f760701Svetoslav    if (res == AppOpsManager::MODE_ERRORED) {
22342f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        ALOGI("Camera %s: Access for \"%s\" has been revoked",
22352f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                mCameraIdStr.string(), String8(mClientPackageName).string());
2236ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        return PERMISSION_DENIED;
2237ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    }
2238f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala
223928e8ef72dab287af59663b89b12507e43f760701Svetoslav    if (res == AppOpsManager::MODE_IGNORED) {
22402f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        ALOGI("Camera %s: Access for \"%s\" has been restricted",
22412f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                mCameraIdStr.string(), String8(mClientPackageName).string());
2242e3afb2cc438b76ae433c8c40ceabf0457ad7a678Eino-Ville Talvala        // Return the same error as for device policy manager rejection
2243e3afb2cc438b76ae433c8c40ceabf0457ad7a678Eino-Ville Talvala        return -EACCES;
224428e8ef72dab287af59663b89b12507e43f760701Svetoslav    }
224528e8ef72dab287af59663b89b12507e43f760701Svetoslav
2246ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    mOpsActive = true;
2247f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala
2248f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala    // Transition device availability listeners from PRESENT -> NOT_AVAILABLE
22492f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    sCameraService->updateStatus(StatusInternal::NOT_AVAILABLE, mCameraIdStr);
2250f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala
2251573291c251d9e85f51f7c0fa1cb35baa2969ca17Emilian Peev    int apiLevel = hardware::ICameraServiceProxy::CAMERA_API_LEVEL_1;
2252573291c251d9e85f51f7c0fa1cb35baa2969ca17Emilian Peev    if (canCastToApiClient(API_2)) {
2253573291c251d9e85f51f7c0fa1cb35baa2969ca17Emilian Peev        apiLevel = hardware::ICameraServiceProxy::CAMERA_API_LEVEL_2;
2254573291c251d9e85f51f7c0fa1cb35baa2969ca17Emilian Peev    }
2255412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala    // Transition device state to OPEN
22562f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    sCameraService->updateProxyDeviceState(ICameraServiceProxy::CAMERA_STATE_OPEN,
2257573291c251d9e85f51f7c0fa1cb35baa2969ca17Emilian Peev            mCameraIdStr, mCameraFacing, mClientPackageName, apiLevel);
2258412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala
2259ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    return OK;
2260ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala}
2261ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
2262ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvalastatus_t CameraService::BasicClient::finishCameraOps() {
2263a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
2264a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala
2265f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala    // Check if startCameraOps succeeded, and if so, finish the camera op
2266ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    if (mOpsActive) {
2267f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala        // Notify app ops that the camera is available again
2268ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        mAppOpsManager.finishOp(AppOpsManager::OP_CAMERA, mClientUid,
2269280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov                mClientPackageName);
2270ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        mOpsActive = false;
2271f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala
2272151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski        // This function is called when a client disconnects. This should
2273151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski        // release the camera, but actually only if it was in a proper
2274151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski        // functional state, i.e. with status NOT_AVAILABLE
2275f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        std::initializer_list<StatusInternal> rejected = {StatusInternal::PRESENT,
2276151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski                StatusInternal::ENUMERATING, StatusInternal::NOT_PRESENT};
2277f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala
2278cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // Transition to PRESENT if the camera is not in either of the rejected states
22792f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        sCameraService->updateStatus(StatusInternal::PRESENT,
22802f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                mCameraIdStr, rejected);
2281f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala
2282573291c251d9e85f51f7c0fa1cb35baa2969ca17Emilian Peev        int apiLevel = hardware::ICameraServiceProxy::CAMERA_API_LEVEL_1;
2283573291c251d9e85f51f7c0fa1cb35baa2969ca17Emilian Peev        if (canCastToApiClient(API_2)) {
2284573291c251d9e85f51f7c0fa1cb35baa2969ca17Emilian Peev            apiLevel = hardware::ICameraServiceProxy::CAMERA_API_LEVEL_2;
2285573291c251d9e85f51f7c0fa1cb35baa2969ca17Emilian Peev        }
2286412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala        // Transition device state to CLOSED
22872f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        sCameraService->updateProxyDeviceState(ICameraServiceProxy::CAMERA_STATE_CLOSED,
2288573291c251d9e85f51f7c0fa1cb35baa2969ca17Emilian Peev                mCameraIdStr, mCameraFacing, mClientPackageName, apiLevel);
2289ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    }
2290f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala    // Always stop watching, even if no camera op is active
2291e992e75053e98e3699af6e344c11b787e30411adEino-Ville Talvala    if (mOpsCallback != NULL) {
2292e992e75053e98e3699af6e344c11b787e30411adEino-Ville Talvala        mAppOpsManager.stopWatchingMode(mOpsCallback);
2293e992e75053e98e3699af6e344c11b787e30411adEino-Ville Talvala    }
2294ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    mOpsCallback.clear();
2295ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
2296ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    return OK;
2297ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala}
2298ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
2299ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvalavoid CameraService::BasicClient::opChanged(int32_t op, const String16& packageName) {
2300a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
2301a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala
2302ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    String8 name(packageName);
2303280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov    String8 myName(mClientPackageName);
2304ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
2305ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    if (op != AppOpsManager::OP_CAMERA) {
2306ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        ALOGW("Unexpected app ops notification received: %d", op);
2307ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        return;
2308ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    }
2309ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
2310ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    int32_t res;
2311ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    res = mAppOpsManager.checkOp(AppOpsManager::OP_CAMERA,
2312280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov            mClientUid, mClientPackageName);
2313ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    ALOGV("checkOp returns: %d, %s ", res,
2314ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala            res == AppOpsManager::MODE_ALLOWED ? "ALLOWED" :
2315ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala            res == AppOpsManager::MODE_IGNORED ? "IGNORED" :
2316ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala            res == AppOpsManager::MODE_ERRORED ? "ERRORED" :
2317ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala            "UNKNOWN");
2318ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
2319ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    if (res != AppOpsManager::MODE_ALLOWED) {
23202f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        ALOGI("Camera %s: Access for \"%s\" revoked", mCameraIdStr.string(),
2321ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala                myName.string());
2322a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        block();
2323ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    }
2324ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala}
2325ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
2326a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganovvoid CameraService::BasicClient::block() {
2327a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    ATRACE_CALL();
2328a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
2329a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    // Reset the client PID to allow server-initiated disconnect,
2330a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    // and to prevent further calls by client.
2331a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    mClientPid = getCallingPid();
2332a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    CaptureResultExtras resultExtras; // a dummy result (invalid)
2333a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    notifyError(hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISABLED, resultExtras);
2334a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    disconnect();
2335a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
2336a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
233765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
233865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2339d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvalavoid CameraService::Client::notifyError(int32_t errorCode,
2340cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei        const CaptureResultExtras& resultExtras) {
2341d309fb9c8a2c4564d88fffba19c4e3688e4b862bEino-Ville Talvala    (void) resultExtras;
23423e600894685b994849d59307721c6862ae0c45b7Ranjith Kagathi Ananda    if (mRemoteCallback != NULL) {
2343f13bda54c62c0d6c6a35dfc6047c5992b652652fYin-Chia Yeh        int32_t api1ErrorCode = CAMERA_ERROR_RELEASED;
2344f13bda54c62c0d6c6a35dfc6047c5992b652652fYin-Chia Yeh        if (errorCode == hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISABLED) {
2345f13bda54c62c0d6c6a35dfc6047c5992b652652fYin-Chia Yeh            api1ErrorCode = CAMERA_ERROR_DISABLED;
2346f13bda54c62c0d6c6a35dfc6047c5992b652652fYin-Chia Yeh        }
2347f13bda54c62c0d6c6a35dfc6047c5992b652652fYin-Chia Yeh        mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, api1ErrorCode, 0);
23483e600894685b994849d59307721c6862ae0c45b7Ranjith Kagathi Ananda    } else {
23493e600894685b994849d59307721c6862ae0c45b7Ranjith Kagathi Ananda        ALOGE("mRemoteCallback is NULL!!");
23503e600894685b994849d59307721c6862ae0c45b7Ranjith Kagathi Ananda    }
2351ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala}
2352ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
2353036bc3e2cfc5a11c3f7ace41088c8936dae2e946Igor Murashkin// NOTE: function is idempotent
2354d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvalabinder::Status CameraService::Client::disconnect() {
2355d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    ALOGV("Client::disconnect");
2356d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return BasicClient::disconnect();
2357e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li}
2358e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li
23590bbf8b213ad96051357e3ad6d6d2808bfa31a59aRuben Brunkbool CameraService::Client::canCastToApiClient(apiLevel level) const {
23600bbf8b213ad96051357e3ad6d6d2808bfa31a59aRuben Brunk    return level == API_1;
23610bbf8b213ad96051357e3ad6d6d2808bfa31a59aRuben Brunk}
23620bbf8b213ad96051357e3ad6d6d2808bfa31a59aRuben Brunk
2363ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville TalvalaCameraService::Client::OpsCallback::OpsCallback(wp<BasicClient> client):
2364ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        mClient(client) {
2365ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala}
2366ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
2367ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvalavoid CameraService::Client::OpsCallback::opChanged(int32_t op,
2368ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        const String16& packageName) {
2369ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    sp<BasicClient> client = mClient.promote();
2370ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    if (client != NULL) {
2371ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        client->opChanged(op, packageName);
2372ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    }
2373ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala}
2374ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
237565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
2376a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov//                  UidPolicy
2377a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov// ----------------------------------------------------------------------------
2378a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
2379a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganovvoid CameraService::UidPolicy::registerSelf() {
23808abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala    Mutex::Autolock _l(mUidLock);
23818abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala
2382a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    ActivityManager am;
23838abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala    if (mRegistered) return;
2384a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    am.registerUidObserver(this, ActivityManager::UID_OBSERVER_GONE
2385a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            | ActivityManager::UID_OBSERVER_IDLE
2386a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            | ActivityManager::UID_OBSERVER_ACTIVE,
2387a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            ActivityManager::PROCESS_STATE_UNKNOWN,
2388a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            String16("cameraserver"));
23898abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala    status_t res = am.linkToDeath(this);
23908abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala    if (res == OK) {
23918abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala        mRegistered = true;
23928abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala        ALOGV("UidPolicy: Registered with ActivityManager");
23938abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala    }
2394a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
2395a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
2396a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganovvoid CameraService::UidPolicy::unregisterSelf() {
23978abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala    Mutex::Autolock _l(mUidLock);
23988abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala
2399a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    ActivityManager am;
2400a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    am.unregisterUidObserver(this);
24018abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala    am.unlinkToDeath(this);
24028abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala    mRegistered = false;
24038abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala    mActiveUids.clear();
24048abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala    ALOGV("UidPolicy: Unregistered with ActivityManager");
2405a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
2406a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
2407a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganovvoid CameraService::UidPolicy::onUidGone(uid_t uid, bool disabled) {
2408a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    onUidIdle(uid, disabled);
2409a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
2410a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
2411a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganovvoid CameraService::UidPolicy::onUidActive(uid_t uid) {
2412a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    Mutex::Autolock _l(mUidLock);
2413a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    mActiveUids.insert(uid);
2414a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
2415a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
2416a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganovvoid CameraService::UidPolicy::onUidIdle(uid_t uid, bool /* disabled */) {
2417a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    bool deleted = false;
2418a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    {
2419a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        Mutex::Autolock _l(mUidLock);
2420a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        if (mActiveUids.erase(uid) > 0) {
2421a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            deleted = true;
2422a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        }
2423a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
2424a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    if (deleted) {
2425a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        sp<CameraService> service = mService.promote();
2426a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        if (service != nullptr) {
2427a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            service->blockClientsForUid(uid);
2428a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        }
2429a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
2430a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
2431a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
24327b4ab78876db058155bc075385c4db9e33e42a25Svet Ganovbool CameraService::UidPolicy::isUidActive(uid_t uid, String16 callingPackage) {
2433a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    Mutex::Autolock _l(mUidLock);
24347b4ab78876db058155bc075385c4db9e33e42a25Svet Ganov    return isUidActiveLocked(uid, callingPackage);
2435a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
2436a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
243794ec46f82f5813fd5bcdf6c2f562e009dd4eec03Svet Ganovstatic const int kPollUidActiveTimeoutMillis = 50;
243894ec46f82f5813fd5bcdf6c2f562e009dd4eec03Svet Ganov
24397b4ab78876db058155bc075385c4db9e33e42a25Svet Ganovbool CameraService::UidPolicy::isUidActiveLocked(uid_t uid, String16 callingPackage) {
2440a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    // Non-app UIDs are considered always active
24418abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala    // If activity manager is unreachable, assume everything is active
24428abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala    if (uid < FIRST_APPLICATION_UID || !mRegistered) {
2443a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        return true;
2444a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
2445a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    auto it = mOverrideUids.find(uid);
2446a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    if (it != mOverrideUids.end()) {
2447a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        return it->second;
2448a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
24497b4ab78876db058155bc075385c4db9e33e42a25Svet Ganov    bool active = mActiveUids.find(uid) != mActiveUids.end();
24507b4ab78876db058155bc075385c4db9e33e42a25Svet Ganov    if (!active) {
24517b4ab78876db058155bc075385c4db9e33e42a25Svet Ganov        // We want active UIDs to always access camera with their first attempt since
24527b4ab78876db058155bc075385c4db9e33e42a25Svet Ganov        // there is no guarantee the app is robustly written and would retry getting
24537b4ab78876db058155bc075385c4db9e33e42a25Svet Ganov        // the camera on failure. The inverse case is not a problem as we would take
24547b4ab78876db058155bc075385c4db9e33e42a25Svet Ganov        // camera away soon once we get the callback that the uid is no longer active.
24557b4ab78876db058155bc075385c4db9e33e42a25Svet Ganov        ActivityManager am;
24567b4ab78876db058155bc075385c4db9e33e42a25Svet Ganov        // Okay to access with a lock held as UID changes are dispatched without
24577b4ab78876db058155bc075385c4db9e33e42a25Svet Ganov        // a lock and we are a higher level component.
245894ec46f82f5813fd5bcdf6c2f562e009dd4eec03Svet Ganov        int64_t startTimeMillis = 0;
245994ec46f82f5813fd5bcdf6c2f562e009dd4eec03Svet Ganov        do {
246094ec46f82f5813fd5bcdf6c2f562e009dd4eec03Svet Ganov            // TODO: Fix this b/109950150!
246194ec46f82f5813fd5bcdf6c2f562e009dd4eec03Svet Ganov            // Okay this is a hack. There is a race between the UID turning active and
246294ec46f82f5813fd5bcdf6c2f562e009dd4eec03Svet Ganov            // activity being resumed. The proper fix is very risky, so we temporary add
246394ec46f82f5813fd5bcdf6c2f562e009dd4eec03Svet Ganov            // some polling which should happen pretty rarely anyway as the race is hard
246494ec46f82f5813fd5bcdf6c2f562e009dd4eec03Svet Ganov            // to hit.
246594ec46f82f5813fd5bcdf6c2f562e009dd4eec03Svet Ganov            active = am.isUidActive(uid, callingPackage);
246694ec46f82f5813fd5bcdf6c2f562e009dd4eec03Svet Ganov            if (active) {
246794ec46f82f5813fd5bcdf6c2f562e009dd4eec03Svet Ganov                break;
246894ec46f82f5813fd5bcdf6c2f562e009dd4eec03Svet Ganov            }
246994ec46f82f5813fd5bcdf6c2f562e009dd4eec03Svet Ganov            if (startTimeMillis <= 0) {
247094ec46f82f5813fd5bcdf6c2f562e009dd4eec03Svet Ganov                startTimeMillis = uptimeMillis();
247194ec46f82f5813fd5bcdf6c2f562e009dd4eec03Svet Ganov            }
247294ec46f82f5813fd5bcdf6c2f562e009dd4eec03Svet Ganov            int64_t ellapsedTimeMillis = uptimeMillis() - startTimeMillis;
247394ec46f82f5813fd5bcdf6c2f562e009dd4eec03Svet Ganov            int64_t remainingTimeMillis = kPollUidActiveTimeoutMillis - ellapsedTimeMillis;
247494ec46f82f5813fd5bcdf6c2f562e009dd4eec03Svet Ganov            if (remainingTimeMillis <= 0) {
247594ec46f82f5813fd5bcdf6c2f562e009dd4eec03Svet Ganov                break;
247694ec46f82f5813fd5bcdf6c2f562e009dd4eec03Svet Ganov            }
247794ec46f82f5813fd5bcdf6c2f562e009dd4eec03Svet Ganov            usleep(remainingTimeMillis * 1000);
247894ec46f82f5813fd5bcdf6c2f562e009dd4eec03Svet Ganov        } while (true);
247994ec46f82f5813fd5bcdf6c2f562e009dd4eec03Svet Ganov
24807b4ab78876db058155bc075385c4db9e33e42a25Svet Ganov        if (active) {
24817b4ab78876db058155bc075385c4db9e33e42a25Svet Ganov            // Now that we found out the UID is actually active, cache that
24827b4ab78876db058155bc075385c4db9e33e42a25Svet Ganov            mActiveUids.insert(uid);
24837b4ab78876db058155bc075385c4db9e33e42a25Svet Ganov        }
24847b4ab78876db058155bc075385c4db9e33e42a25Svet Ganov    }
24857b4ab78876db058155bc075385c4db9e33e42a25Svet Ganov    return active;
2486a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
2487a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
24887b4ab78876db058155bc075385c4db9e33e42a25Svet Ganovvoid CameraService::UidPolicy::UidPolicy::addOverrideUid(uid_t uid,
24897b4ab78876db058155bc075385c4db9e33e42a25Svet Ganov        String16 callingPackage, bool active) {
24907b4ab78876db058155bc075385c4db9e33e42a25Svet Ganov    updateOverrideUid(uid, callingPackage, active, true);
2491a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
2492a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
24937b4ab78876db058155bc075385c4db9e33e42a25Svet Ganovvoid CameraService::UidPolicy::removeOverrideUid(uid_t uid, String16 callingPackage) {
24947b4ab78876db058155bc075385c4db9e33e42a25Svet Ganov    updateOverrideUid(uid, callingPackage, false, false);
2495a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
2496a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
24978abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvalavoid CameraService::UidPolicy::binderDied(const wp<IBinder>& /*who*/) {
24988abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala    Mutex::Autolock _l(mUidLock);
24998abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala    ALOGV("UidPolicy: ActivityManager has died");
25008abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala    mRegistered = false;
25018abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala    mActiveUids.clear();
25028abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala}
25038abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala
25047b4ab78876db058155bc075385c4db9e33e42a25Svet Ganovvoid CameraService::UidPolicy::updateOverrideUid(uid_t uid, String16 callingPackage,
25057b4ab78876db058155bc075385c4db9e33e42a25Svet Ganov        bool active, bool insert) {
2506a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    bool wasActive = false;
2507a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    bool isActive = false;
2508a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    {
2509a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        Mutex::Autolock _l(mUidLock);
25107b4ab78876db058155bc075385c4db9e33e42a25Svet Ganov        wasActive = isUidActiveLocked(uid, callingPackage);
2511a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        mOverrideUids.erase(uid);
2512a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        if (insert) {
2513a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            mOverrideUids.insert(std::pair<uid_t, bool>(uid, active));
2514a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        }
25157b4ab78876db058155bc075385c4db9e33e42a25Svet Ganov        isActive = isUidActiveLocked(uid, callingPackage);
2516a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
2517a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    if (wasActive != isActive && !isActive) {
2518a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        sp<CameraService> service = mService.promote();
2519a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        if (service != nullptr) {
2520a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            service->blockClientsForUid(uid);
2521a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        }
2522a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
2523a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
2524a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
2525a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov// ----------------------------------------------------------------------------
2526cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk//                  CameraState
2527cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk// ----------------------------------------------------------------------------
2528cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2529cc776718c0be7c31fe5ab4fc1446d377be60369fRuben BrunkCameraService::CameraState::CameraState(const String8& id, int cost,
2530cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        const std::set<String8>& conflicting) : mId(id),
2531151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski        mStatus(StatusInternal::NOT_PRESENT), mCost(cost), mConflicting(conflicting) {}
2532cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2533cc776718c0be7c31fe5ab4fc1446d377be60369fRuben BrunkCameraService::CameraState::~CameraState() {}
2534cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2535f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville TalvalaCameraService::StatusInternal CameraService::CameraState::getStatus() const {
2536cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    Mutex::Autolock lock(mStatusLock);
2537cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return mStatus;
2538cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
2539cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2540cc776718c0be7c31fe5ab4fc1446d377be60369fRuben BrunkCameraParameters CameraService::CameraState::getShimParams() const {
2541cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return mShimParams;
2542cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
2543cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2544cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkvoid CameraService::CameraState::setShimParams(const CameraParameters& params) {
2545cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    mShimParams = params;
2546cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
2547cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2548cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkint CameraService::CameraState::getCost() const {
2549cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return mCost;
2550cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
2551cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2552cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkstd::set<String8> CameraService::CameraState::getConflicting() const {
2553cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return mConflicting;
2554cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
2555cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2556cc776718c0be7c31fe5ab4fc1446d377be60369fRuben BrunkString8 CameraService::CameraState::getId() const {
2557cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return mId;
2558cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
2559cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2560cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk// ----------------------------------------------------------------------------
256199e69716215cd0665379bc90d708f2ea8689831dRuben Brunk//                  ClientEventListener
256299e69716215cd0665379bc90d708f2ea8689831dRuben Brunk// ----------------------------------------------------------------------------
256399e69716215cd0665379bc90d708f2ea8689831dRuben Brunk
256499e69716215cd0665379bc90d708f2ea8689831dRuben Brunkvoid CameraService::ClientEventListener::onClientAdded(
256599e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        const resource_policy::ClientDescriptor<String8,
256699e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        sp<CameraService::BasicClient>>& descriptor) {
25675404ee174dd6b5e312d3a97bc63c2bc8d142012bChih-Hung Hsieh    const auto& basicClient = descriptor.getValue();
256899e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    if (basicClient.get() != nullptr) {
256999e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        BatteryNotifier& notifier(BatteryNotifier::getInstance());
257099e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        notifier.noteStartCamera(descriptor.getKey(),
257199e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                static_cast<int>(basicClient->getClientUid()));
257299e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    }
257399e69716215cd0665379bc90d708f2ea8689831dRuben Brunk}
257499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk
257599e69716215cd0665379bc90d708f2ea8689831dRuben Brunkvoid CameraService::ClientEventListener::onClientRemoved(
257699e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        const resource_policy::ClientDescriptor<String8,
257799e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        sp<CameraService::BasicClient>>& descriptor) {
25785404ee174dd6b5e312d3a97bc63c2bc8d142012bChih-Hung Hsieh    const auto& basicClient = descriptor.getValue();
257999e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    if (basicClient.get() != nullptr) {
258099e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        BatteryNotifier& notifier(BatteryNotifier::getInstance());
258199e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        notifier.noteStopCamera(descriptor.getKey(),
258299e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                static_cast<int>(basicClient->getClientUid()));
258399e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    }
258499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk}
258599e69716215cd0665379bc90d708f2ea8689831dRuben Brunk
258699e69716215cd0665379bc90d708f2ea8689831dRuben Brunk
258799e69716215cd0665379bc90d708f2ea8689831dRuben Brunk// ----------------------------------------------------------------------------
2588cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk//                  CameraClientManager
2589cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk// ----------------------------------------------------------------------------
2590cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
259199e69716215cd0665379bc90d708f2ea8689831dRuben BrunkCameraService::CameraClientManager::CameraClientManager() {
259299e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    setListener(std::make_shared<ClientEventListener>());
259399e69716215cd0665379bc90d708f2ea8689831dRuben Brunk}
259499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk
2595cc776718c0be7c31fe5ab4fc1446d377be60369fRuben BrunkCameraService::CameraClientManager::~CameraClientManager() {}
2596cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2597cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunksp<CameraService::BasicClient> CameraService::CameraClientManager::getCameraClient(
2598cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        const String8& id) const {
2599cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    auto descriptor = get(id);
2600cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    if (descriptor == nullptr) {
2601cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        return sp<BasicClient>{nullptr};
2602cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
2603cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return descriptor->getValue();
2604cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
2605cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2606cc776718c0be7c31fe5ab4fc1446d377be60369fRuben BrunkString8 CameraService::CameraClientManager::toString() const {
2607cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    auto all = getAll();
2608cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    String8 ret("[");
2609cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    bool hasAny = false;
2610cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    for (auto& i : all) {
2611cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        hasAny = true;
2612cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        String8 key = i->getKey();
2613cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        int32_t cost = i->getCost();
2614cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        int32_t pid = i->getOwnerId();
26158131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev        int32_t score = i->getPriority().getScore();
26168131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev        int32_t state = i->getPriority().getState();
2617cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        auto conflicting = i->getConflicting();
2618cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        auto clientSp = i->getValue();
2619cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        String8 packageName;
2620022f0cb0c6f135edde4ebe84859c685933ee895eEino-Ville Talvala        userid_t clientUserId = 0;
2621cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        if (clientSp.get() != nullptr) {
2622cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            packageName = String8{clientSp->getPackageName()};
26236267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk            uid_t clientUid = clientSp->getClientUid();
26246267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk            clientUserId = multiuser_get_user_id(clientUid);
2625cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        }
26268131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev        ret.appendFormat("\n(Camera ID: %s, Cost: %" PRId32 ", PID: %" PRId32 ", Score: %"
26278131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                PRId32 ", State: %" PRId32, key.string(), cost, pid, score, state);
2628cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
26296267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        if (clientSp.get() != nullptr) {
26306267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk            ret.appendFormat("User Id: %d, ", clientUserId);
26316267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        }
2632cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        if (packageName.size() != 0) {
2633cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            ret.appendFormat("Client Package Name: %s", packageName.string());
2634cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        }
2635cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2636cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        ret.append(", Conflicting Client Devices: {");
2637cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        for (auto& j : conflicting) {
2638cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            ret.appendFormat("%s, ", j.string());
2639cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        }
2640cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        ret.append("})");
2641cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
2642cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    if (hasAny) ret.append("\n");
2643cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    ret.append("]\n");
2644cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return ret;
2645cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
2646cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2647cc776718c0be7c31fe5ab4fc1446d377be60369fRuben BrunkCameraService::DescriptorPtr CameraService::CameraClientManager::makeClientDescriptor(
2648cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        const String8& key, const sp<BasicClient>& value, int32_t cost,
26498131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev        const std::set<String8>& conflictingKeys, int32_t score, int32_t ownerId,
26508131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev        int32_t state) {
2651cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2652cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return std::make_shared<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>(
26538131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev            key, value, cost, conflictingKeys, score, ownerId, state);
2654cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
2655cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2656cc776718c0be7c31fe5ab4fc1446d377be60369fRuben BrunkCameraService::DescriptorPtr CameraService::CameraClientManager::makeClientDescriptor(
2657cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        const sp<BasicClient>& value, const CameraService::DescriptorPtr& partial) {
2658cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return makeClientDescriptor(partial->getKey(), value, partial->getCost(),
26598131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev            partial->getConflicting(), partial->getPriority().getScore(),
26608131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev            partial->getOwnerId(), partial->getPriority().getState());
2661cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
2662cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2663cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk// ----------------------------------------------------------------------------
266465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
266565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic const int kDumpLockRetries = 50;
266665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic const int kDumpLockSleep = 60000;
266765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
266865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic bool tryLock(Mutex& mutex)
266965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
267065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    bool locked = false;
267165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (int i = 0; i < kDumpLockRetries; ++i) {
267265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mutex.tryLock() == NO_ERROR) {
267365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            locked = true;
267465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
267565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
267665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        usleep(kDumpLockSleep);
267765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
267865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return locked;
267965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
268065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
268165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::dump(int fd, const Vector<String16>& args) {
2682a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
2683a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala
268465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
2685d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        dprintf(fd, "Permission Denial: can't dump CameraService from pid=%d, uid=%d\n",
268665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                getCallingPid(),
268765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                getCallingUid());
26888131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala        return NO_ERROR;
26898131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    }
26908131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    bool locked = tryLock(mServiceLock);
26918131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    // failed to lock - CameraService is probably deadlocked
26928131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    if (!locked) {
2693d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        dprintf(fd, "!! CameraService may be deadlocked !!\n");
26948131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    }
26951527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvala
26968131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    if (!mInitialized) {
2697d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        dprintf(fd, "!! No camera HAL available !!\n");
26981527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvala
26998131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala        // Dump event log for error information
27008131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala        dumpEventLog(fd);
27012f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
27028131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala        if (locked) mServiceLock.unlock();
27038131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala        return NO_ERROR;
27048131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    }
2705d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala    dprintf(fd, "\n== Service global info: ==\n\n");
2706d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala    dprintf(fd, "Number of camera devices: %d\n", mNumberOfCameras);
2707c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    dprintf(fd, "Number of normal camera devices: %zu\n", mNormalDeviceIds.size());
2708c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    for (size_t i = 0; i < mNormalDeviceIds.size(); i++) {
2709c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        dprintf(fd, "    Device %zu maps to \"%s\"\n", i, mNormalDeviceIds[i].c_str());
2710c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    }
27118131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    String8 activeClientString = mActiveClientManager.toString();
2712d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala    dprintf(fd, "Active Camera Clients:\n%s", activeClientString.string());
2713d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala    dprintf(fd, "Allowed user IDs: %s\n", toString(mAllowedUsers).string());
2714f81648ec38ff63f1f35516fa27c1c24d846e9ba5Ruben Brunk
27158131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    dumpEventLog(fd);
2716f81648ec38ff63f1f35516fa27c1c24d846e9ba5Ruben Brunk
27178131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    bool stateLocked = tryLock(mCameraStatesLock);
27188131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    if (!stateLocked) {
2719d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        dprintf(fd, "CameraStates in use, may be deadlocked\n");
27208131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    }
27218131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala
2722bd8c503398d6b483b7abba594c7838a4c93b6e23Emilian Peev    int argSize = args.size();
2723bd8c503398d6b483b7abba594c7838a4c93b6e23Emilian Peev    for (int i = 0; i < argSize; i++) {
2724bd8c503398d6b483b7abba594c7838a4c93b6e23Emilian Peev        if (args[i] == TagMonitor::kMonitorOption) {
2725bd8c503398d6b483b7abba594c7838a4c93b6e23Emilian Peev            if (i + 1 < argSize) {
2726bd8c503398d6b483b7abba594c7838a4c93b6e23Emilian Peev                mMonitorTags = String8(args[i + 1]);
2727bd8c503398d6b483b7abba594c7838a4c93b6e23Emilian Peev            }
2728bd8c503398d6b483b7abba594c7838a4c93b6e23Emilian Peev            break;
2729bd8c503398d6b483b7abba594c7838a4c93b6e23Emilian Peev        }
2730bd8c503398d6b483b7abba594c7838a4c93b6e23Emilian Peev    }
2731bd8c503398d6b483b7abba594c7838a4c93b6e23Emilian Peev
27328131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    for (auto& state : mCameraStates) {
27338131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala        String8 cameraId = state.first;
2734cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2735d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        dprintf(fd, "== Camera device %s dynamic info: ==\n", cameraId.string());
2736d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala
2737d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        CameraParameters p = state.second->getShimParams();
2738d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        if (!p.isEmpty()) {
2739d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala            dprintf(fd, "  Camera1 API shim is using parameters:\n        ");
2740d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala            p.dump(fd, args);
2741d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        }
2742d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala
2743d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        auto clientDescriptor = mActiveClientManager.get(cameraId);
27442f140ed90057ca0df3f9da8318241ecfb6dda9ebZhijun He        if (clientDescriptor != nullptr) {
27452f140ed90057ca0df3f9da8318241ecfb6dda9ebZhijun He            dprintf(fd, "  Device %s is open. Client instance dump:\n",
2746d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala                    cameraId.string());
27472f140ed90057ca0df3f9da8318241ecfb6dda9ebZhijun He            dprintf(fd, "    Client priority score: %d state: %d\n",
27482f140ed90057ca0df3f9da8318241ecfb6dda9ebZhijun He                    clientDescriptor->getPriority().getScore(),
27492f140ed90057ca0df3f9da8318241ecfb6dda9ebZhijun He                    clientDescriptor->getPriority().getState());
27502f140ed90057ca0df3f9da8318241ecfb6dda9ebZhijun He            dprintf(fd, "    Client PID: %d\n", clientDescriptor->getOwnerId());
2751d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala
27522f140ed90057ca0df3f9da8318241ecfb6dda9ebZhijun He            auto client = clientDescriptor->getValue();
27532f140ed90057ca0df3f9da8318241ecfb6dda9ebZhijun He            dprintf(fd, "    Client package: %s\n",
27542f140ed90057ca0df3f9da8318241ecfb6dda9ebZhijun He                    String8(client->getPackageName()).string());
2755d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala
27562f140ed90057ca0df3f9da8318241ecfb6dda9ebZhijun He            client->dumpClient(fd, args);
27572f140ed90057ca0df3f9da8318241ecfb6dda9ebZhijun He        } else {
27582f140ed90057ca0df3f9da8318241ecfb6dda9ebZhijun He            dprintf(fd, "  Device %s is closed, no client instance\n",
27592f140ed90057ca0df3f9da8318241ecfb6dda9ebZhijun He                    cameraId.string());
27602f140ed90057ca0df3f9da8318241ecfb6dda9ebZhijun He        }
2761d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala
27628131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    }
276365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
27648131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    if (stateLocked) mCameraStatesLock.unlock();
276565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2766d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala    if (locked) mServiceLock.unlock();
2767d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala
2768f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    mCameraProviderManager->dump(fd, args);
27698131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala
2770d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala    dprintf(fd, "\n== Vendor tags: ==\n\n");
2771d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala
2772d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala    sp<VendorTagDescriptor> desc = VendorTagDescriptor::getGlobalVendorTagDescriptor();
2773d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala    if (desc == NULL) {
277471c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev        sp<VendorTagDescriptorCache> cache =
277571c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                VendorTagDescriptorCache::getGlobalVendorTagCache();
277671c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev        if (cache == NULL) {
277771c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev            dprintf(fd, "No vendor tags.\n");
277871c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev        } else {
277971c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev            cache->dump(fd, /*verbosity*/2, /*indentation*/2);
278071c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev        }
2781d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala    } else {
2782d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        desc->dump(fd, /*verbosity*/2, /*indentation*/2);
2783d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala    }
27848131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala
27858131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    // Dump camera traces if there were any
2786d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala    dprintf(fd, "\n");
27878131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    camera3::CameraTraces::dump(fd, args);
27888131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala
27898131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    // Process dump arguments, if any
27908131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    int n = args.size();
27918131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    String16 verboseOption("-v");
27928131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    String16 unreachableOption("--unreachable");
27938131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    for (int i = 0; i < n; i++) {
27948131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala        if (args[i] == verboseOption) {
27958131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala            // change logging level
27968131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala            if (i + 1 >= n) continue;
27978131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala            String8 levelStr(args[i+1]);
27988131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala            int level = atoi(levelStr.string());
2799d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala            dprintf(fd, "\nSetting log level to %d.\n", level);
28008131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala            setLogLevel(level);
28018131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala        } else if (args[i] == unreachableOption) {
28028131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala            // Dump memory analysis
28038131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala            // TODO - should limit be an argument parameter?
28048131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala            UnreachableMemoryInfo info;
28058131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala            bool success = GetUnreachableMemory(info, /*limit*/ 10000);
28068131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala            if (!success) {
2807d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala                dprintf(fd, "\n== Unable to dump unreachable memory. "
2808d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala                        "Try disabling SELinux enforcement. ==\n");
28098131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala            } else {
2810d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala                dprintf(fd, "\n== Dumping unreachable memory: ==\n");
28118131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala                std::string s = info.ToString(/*log_contents*/ true);
28128131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala                write(fd, s.c_str(), s.size());
281365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
281465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
281565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
281665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
281765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
281865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
28191527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvalavoid CameraService::dumpEventLog(int fd) {
2820d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala    dprintf(fd, "\n== Camera service events log (most recent at top): ==\n");
28211527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvala
28221527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvala    Mutex::Autolock l(mLogLock);
28231527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvala    for (const auto& msg : mEventLog) {
2824d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        dprintf(fd, "  %s\n", msg.string());
28251527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvala    }
28261527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvala
28271527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvala    if (mEventLog.size() == DEFAULT_EVENT_LOG_LENGTH) {
2828d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        dprintf(fd, "  ...\n");
28291527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvala    } else if (mEventLog.size() == 0) {
2830d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        dprintf(fd, "  [no events yet]\n");
28311527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvala    }
2832d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala    dprintf(fd, "\n");
28331527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvala}
28341527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvala
28353068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chenvoid CameraService::handleTorchClientBinderDied(const wp<IBinder> &who) {
283688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    Mutex::Autolock al(mTorchClientMapMutex);
28373068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    for (size_t i = 0; i < mTorchClientMap.size(); i++) {
28383068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen        if (mTorchClientMap[i] == who) {
28393068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen            // turn off the torch mode that was turned on by dead client
284088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen            String8 cameraId = mTorchClientMap.keyAt(i);
284188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen            status_t res = mFlashlight->setTorchMode(cameraId, false);
284288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen            if (res) {
284388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen                ALOGE("%s: torch client died but couldn't turn off torch: "
284488da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen                    "%s (%d)", __FUNCTION__, strerror(-res), res);
284588da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen                return;
284688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen            }
28473068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen            mTorchClientMap.removeItemsAt(i);
28483068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen            break;
28493068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen        }
28503068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    }
28513068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen}
28523068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
2853cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk/*virtual*/void CameraService::binderDied(const wp<IBinder> &who) {
2854ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
2855294d0eca9eabfaa3ef0ee8bee7ccf3eaaa925e41Igor Murashkin    /**
2856a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk      * While tempting to promote the wp<IBinder> into a sp, it's actually not supported by the
2857a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk      * binder driver
2858294d0eca9eabfaa3ef0ee8bee7ccf3eaaa925e41Igor Murashkin      */
2859dbfcb38f6636931b2e3e6da8e6aa5a7bfce84a82Yin-Chia Yeh    // PID here is approximate and can be wrong.
2860a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    logClientDied(getCallingPid(), String8("Binder died unexpectedly"));
2861a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk
28623068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    // check torch client
28633068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    handleTorchClientBinderDied(who);
28643068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
28653068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    // check camera device client
2866cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    if(!evictClientIdByRemote(who)) {
2867cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        ALOGV("%s: Java client's binder death already cleaned up (normal case)", __FUNCTION__);
2868ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin        return;
2869ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    }
2870ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
2871cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    ALOGE("%s: Java client's binder died, removing it from the list of active clients",
2872cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            __FUNCTION__);
2873ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin}
2874ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
2875f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalavoid CameraService::updateStatus(StatusInternal status, const String8& cameraId) {
2876cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    updateStatus(status, cameraId, {});
2877cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
2878bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
2879f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalavoid CameraService::updateStatus(StatusInternal status, const String8& cameraId,
2880f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        std::initializer_list<StatusInternal> rejectSourceStates) {
2881cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    // Do not lock mServiceLock here or can get into a deadlock from
2882cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    // connect() -> disconnect -> updateStatus
2883cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin
2884cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    auto state = getCameraState(cameraId);
2885cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin
2886cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    if (state == nullptr) {
2887cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        ALOGW("%s: Could not update the status for %s, no such device exists", __FUNCTION__,
2888cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                cameraId.string());
2889cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        return;
2890cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
289193747b9c7724f690b3068300514c05629e0b0a3eIgor Murashkin
2892cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    // Update the status for this camera state, then send the onStatusChangedCallbacks to each
2893cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    // of the listeners with both the mStatusStatus and mStatusListenerLock held
2894cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    state->updateStatus(status, cameraId, rejectSourceStates, [this]
2895f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            (const String8& cameraId, StatusInternal status) {
2896cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2897f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            if (status != StatusInternal::ENUMERATING) {
2898f6463fc62a09b8aad8e811a9abbe9f4d9f2688f9Chien-Yu Chen                // Update torch status if it has a flash unit.
2899f6463fc62a09b8aad8e811a9abbe9f4d9f2688f9Chien-Yu Chen                Mutex::Autolock al(mTorchStatusMutex);
2900f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                TorchModeStatus torchStatus;
2901f6463fc62a09b8aad8e811a9abbe9f4d9f2688f9Chien-Yu Chen                if (getTorchStatusLocked(cameraId, &torchStatus) !=
2902f6463fc62a09b8aad8e811a9abbe9f4d9f2688f9Chien-Yu Chen                        NAME_NOT_FOUND) {
2903f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                    TorchModeStatus newTorchStatus =
2904f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            status == StatusInternal::PRESENT ?
2905f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            TorchModeStatus::AVAILABLE_OFF :
2906f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            TorchModeStatus::NOT_AVAILABLE;
2907f6463fc62a09b8aad8e811a9abbe9f4d9f2688f9Chien-Yu Chen                    if (torchStatus != newTorchStatus) {
2908f6463fc62a09b8aad8e811a9abbe9f4d9f2688f9Chien-Yu Chen                        onTorchStatusChangedLocked(cameraId, newTorchStatus);
2909f6463fc62a09b8aad8e811a9abbe9f4d9f2688f9Chien-Yu Chen                    }
2910f6463fc62a09b8aad8e811a9abbe9f4d9f2688f9Chien-Yu Chen                }
2911bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin            }
2912bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
2913cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            Mutex::Autolock lock(mStatusListenerLock);
291488da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen
2915cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            for (auto& listener : mListenerList) {
2916f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                listener->onStatusChanged(mapToInterface(status), String16(cameraId));
2917cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            }
2918cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        });
2919cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin}
2920cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin
2921f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalatemplate<class Func>
2922f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalavoid CameraService::CameraState::updateStatus(StatusInternal status,
2923f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        const String8& cameraId,
2924f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        std::initializer_list<StatusInternal> rejectSourceStates,
2925f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        Func onStatusUpdatedLocked) {
2926f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    Mutex::Autolock lock(mStatusLock);
2927f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    StatusInternal oldStatus = mStatus;
2928f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    mStatus = status;
2929f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
2930f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    if (oldStatus == status) {
2931f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        return;
2932f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    }
2933f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
2934f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    ALOGV("%s: Status has changed for camera ID %s from %#x to %#x", __FUNCTION__,
2935f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            cameraId.string(), oldStatus, status);
2936f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
2937f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    if (oldStatus == StatusInternal::NOT_PRESENT &&
2938f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            (status != StatusInternal::PRESENT &&
2939f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala             status != StatusInternal::ENUMERATING)) {
2940f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
2941f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        ALOGW("%s: From NOT_PRESENT can only transition into PRESENT or ENUMERATING",
2942f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                __FUNCTION__);
2943f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        mStatus = oldStatus;
2944f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        return;
2945f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    }
2946f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
2947f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    /**
2948f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala     * Sometimes we want to conditionally do a transition.
2949f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala     * For example if a client disconnects, we want to go to PRESENT
2950f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala     * only if we weren't already in NOT_PRESENT or ENUMERATING.
2951f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala     */
2952f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    for (auto& rejectStatus : rejectSourceStates) {
2953f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        if (oldStatus == rejectStatus) {
2954f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            ALOGV("%s: Rejecting status transition for Camera ID %s,  since the source "
2955f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                    "state was was in one of the bad states.", __FUNCTION__, cameraId.string());
2956f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            mStatus = oldStatus;
2957f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            return;
2958f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        }
2959f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    }
2960f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
2961f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    onStatusUpdatedLocked(cameraId, status);
2962f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala}
2963f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
2964e8c96c765b95ec7dcd10732621a825fce05960c6Eino-Ville Talvalavoid CameraService::updateProxyDeviceState(int newState,
2965573291c251d9e85f51f7c0fa1cb35baa2969ca17Emilian Peev        const String8& cameraId, int facing, const String16& clientName, int apiLevel) {
2966412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala    sp<ICameraServiceProxy> proxyBinder = getCameraServiceProxy();
2967412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala    if (proxyBinder == nullptr) return;
2968412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala    String16 id(cameraId);
2969573291c251d9e85f51f7c0fa1cb35baa2969ca17Emilian Peev    proxyBinder->notifyCameraState(id, newState, facing, clientName, apiLevel);
2970412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala}
2971412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala
297288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chenstatus_t CameraService::getTorchStatusLocked(
297388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen        const String8& cameraId,
2974f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        TorchModeStatus *status) const {
297588da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    if (!status) {
297688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen        return BAD_VALUE;
297788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    }
29783068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    ssize_t index = mTorchStatusMap.indexOfKey(cameraId);
29793068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    if (index == NAME_NOT_FOUND) {
298088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen        // invalid camera ID or the camera doesn't have a flash unit
298188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen        return NAME_NOT_FOUND;
29823068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    }
29833068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
298488da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    *status = mTorchStatusMap.valueAt(index);
298588da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    return OK;
29863068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen}
29873068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
298888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chenstatus_t CameraService::setTorchStatusLocked(const String8& cameraId,
2989f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        TorchModeStatus status) {
29903068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    ssize_t index = mTorchStatusMap.indexOfKey(cameraId);
29913068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    if (index == NAME_NOT_FOUND) {
29923068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen        return BAD_VALUE;
29933068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    }
2994f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    mTorchStatusMap.editValueAt(index) = status;
29953068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
29963068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    return OK;
29973068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen}
29983068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
2999a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganovvoid CameraService::blockClientsForUid(uid_t uid) {
3000a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    const auto clients = mActiveClientManager.getAll();
3001a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    for (auto& current : clients) {
3002a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        if (current != nullptr) {
3003a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            const auto basicClient = current->getValue();
3004a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            if (basicClient.get() != nullptr && basicClient->getClientUid() == uid) {
3005a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov                basicClient->block();
3006a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            }
3007a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        }
3008a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
3009a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
3010a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
3011a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov// NOTE: This is a remote API - make sure all args are validated
3012a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganovstatus_t CameraService::shellCommand(int in, int out, int err, const Vector<String16>& args) {
3013a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    if (!checkCallingPermission(sManageCameraPermission, nullptr, nullptr)) {
3014a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        return PERMISSION_DENIED;
3015a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
3016a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    if (in == BAD_TYPE || out == BAD_TYPE || err == BAD_TYPE) {
3017a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        return BAD_VALUE;
3018a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
3019a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    if (args.size() == 3 && args[0] == String16("set-uid-state")) {
3020a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        return handleSetUidState(args, err);
3021a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    } else if (args.size() == 2 && args[0] == String16("reset-uid-state")) {
3022a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        return handleResetUidState(args, err);
3023a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    } else if (args.size() == 2 && args[0] == String16("get-uid-state")) {
3024a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        return handleGetUidState(args, out, err);
3025a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    } else if (args.size() == 1 && args[0] == String16("help")) {
3026a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        printHelp(out);
3027a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        return NO_ERROR;
3028a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
3029a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    printHelp(err);
3030a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    return BAD_VALUE;
3031a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
3032a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
3033a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganovstatus_t CameraService::handleSetUidState(const Vector<String16>& args, int err) {
3034a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    PermissionController pc;
3035a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    int uid = pc.getPackageUid(args[1], 0);
3036a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    if (uid <= 0) {
3037a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        ALOGE("Unknown package: '%s'", String8(args[1]).string());
3038a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        dprintf(err, "Unknown package: '%s'\n", String8(args[1]).string());
3039a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        return BAD_VALUE;
3040a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
3041a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    bool active = false;
3042a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    if (args[2] == String16("active")) {
3043a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        active = true;
3044a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    } else if ((args[2] != String16("idle"))) {
3045a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        ALOGE("Expected active or idle but got: '%s'", String8(args[2]).string());
3046a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        return BAD_VALUE;
3047a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
30487b4ab78876db058155bc075385c4db9e33e42a25Svet Ganov    mUidPolicy->addOverrideUid(uid, args[1], active);
3049a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    return NO_ERROR;
3050a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
3051a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
3052a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganovstatus_t CameraService::handleResetUidState(const Vector<String16>& args, int err) {
3053a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    PermissionController pc;
3054a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    int uid = pc.getPackageUid(args[1], 0);
3055a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    if (uid < 0) {
3056a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        ALOGE("Unknown package: '%s'", String8(args[1]).string());
3057a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        dprintf(err, "Unknown package: '%s'\n", String8(args[1]).string());
3058a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        return BAD_VALUE;
3059a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
30607b4ab78876db058155bc075385c4db9e33e42a25Svet Ganov    mUidPolicy->removeOverrideUid(uid, args[1]);
3061a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    return NO_ERROR;
3062a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
3063a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
3064a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganovstatus_t CameraService::handleGetUidState(const Vector<String16>& args, int out, int err) {
3065a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    PermissionController pc;
3066a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    int uid = pc.getPackageUid(args[1], 0);
3067a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    if (uid <= 0) {
3068a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        ALOGE("Unknown package: '%s'", String8(args[1]).string());
3069a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        dprintf(err, "Unknown package: '%s'\n", String8(args[1]).string());
3070a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        return BAD_VALUE;
3071a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
30727b4ab78876db058155bc075385c4db9e33e42a25Svet Ganov    if (mUidPolicy->isUidActive(uid, args[1])) {
3073a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        return dprintf(out, "active\n");
3074a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    } else {
3075a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        return dprintf(out, "idle\n");
3076a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
3077a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
3078a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
3079a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganovstatus_t CameraService::printHelp(int out) {
3080a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    return dprintf(out, "Camera service commands:\n"
3081a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        "  get-uid-state <PACKAGE> gets the uid state\n"
3082a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        "  set-uid-state <PACKAGE> <active|idle> overrides the uid state\n"
3083a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        "  reset-uid-state <PACKAGE> clears the uid state override\n"
3084a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        "  help print this message\n");
3085a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
3086a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
308765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}; // namespace android
3088