CameraService.cpp revision 573291c251d9e85f51f7c0fa1cb35baa2969ca17
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>
58d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk#include <utils/Trace.h>
5998a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen#include <private/android_filesystem_config.h>
60d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk#include <system/camera_vendor_tags.h>
61b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk#include <system/camera_metadata.h>
622f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
63b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk#include <system/camera.h>
6465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
6565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include "CameraService.h"
667b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala#include "api1/CameraClient.h"
677b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala#include "api1/Camera2Client.h"
687b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala#include "api2/CameraDeviceClient.h"
69ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin#include "utils/CameraTraces.h"
7065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
710dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yehnamespace {
720dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    const char* kPermissionServiceName = "permission";
730dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh}; // namespace anonymous
740dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
7565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiannamespace android {
7665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
77d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvalausing binder::Status;
78f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalausing hardware::ICamera;
79f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalausing hardware::ICameraClient;
80e8c96c765b95ec7dcd10732621a825fce05960c6Eino-Ville Talvalausing hardware::ICameraServiceProxy;
81f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalausing hardware::ICameraServiceListener;
82f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalausing hardware::camera::common::V1_0::CameraDeviceStatus;
83f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalausing hardware::camera::common::V1_0::TorchModeStatus;
84d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala
8565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
8665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// Logging support -- this is for debugging only
8765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// Use "adb shell dumpsys media.camera -v 1" to change it.
885e08d60617fc63c2e41f9069ff89f5c00db2617dEino-Ville Talvalavolatile int32_t gLogLevel = 0;
8965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
90b8a805261bf0282e992d3608035e47d05a898710Steve Block#define LOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__);
91b8a805261bf0282e992d3608035e47d05a898710Steve Block#define LOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__);
9265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
9365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic void setLogLevel(int level) {
9465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    android_atomic_write(level, &gLogLevel);
9565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
9665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
97d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala// Convenience methods for constructing binder::Status objects for error returns
98d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala
99d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala#define STATUS_ERROR(errorCode, errorString) \
100d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    binder::Status::fromServiceSpecificError(errorCode, \
101d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            String8::format("%s:%d: %s", __FUNCTION__, __LINE__, errorString))
102d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala
103d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala#define STATUS_ERROR_FMT(errorCode, errorString, ...) \
104d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    binder::Status::fromServiceSpecificError(errorCode, \
105d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            String8::format("%s:%d: " errorString, __FUNCTION__, __LINE__, \
106d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    __VA_ARGS__))
107d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala
10865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
10965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
110a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganovstatic const String16 sManageCameraPermission("android.permission.MANAGE_CAMERA");
111a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
11249c9705a7987b94bd53fddd4834f5f534cf946f7Eino-Ville TalvalaCameraService::CameraService() :
11349c9705a7987b94bd53fddd4834f5f534cf946f7Eino-Ville Talvala        mEventLog(DEFAULT_EVENT_LOG_LENGTH),
114c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        mNumberOfCameras(0),
115f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev        mSoundRef(0), mInitialized(false) {
116df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block    ALOGI("CameraService started (pid=%d)", getpid());
117cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    mServiceLockWrapper = std::make_shared<WaitableMutexWrapper>(&mServiceLock);
1188951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev}
11965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1208951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchevvoid CameraService::onFirstRef()
1218951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev{
122cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    ALOGI("CameraService process starting");
123634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
1248951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    BnCameraService::onFirstRef();
12565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
12699e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    // Update battery life tracking if service is restarting
12799e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    BatteryNotifier& notifier(BatteryNotifier::getInstance());
12899e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    notifier.noteResetCamera();
12999e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    notifier.noteResetFlashlight();
13099e69716215cd0665379bc90d708f2ea8689831dRuben Brunk
1312f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    status_t res = INVALID_OPERATION;
1329cbbc837625cced18adabc57d71479044999155dEino-Ville Talvala
133f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    res = enumerateProviders();
1342f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (res == OK) {
1352f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        mInitialized = true;
1362f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
1372f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
1382f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    CameraService::pingCameraServiceProxy();
139a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
140a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    mUidPolicy = new UidPolicy(this);
141a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    mUidPolicy->registerSelf();
1422f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala}
1432f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
1442f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalastatus_t CameraService::enumerateProviders() {
1452f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    status_t res;
146aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev
147c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    std::vector<std::string> deviceIds;
148c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    {
149c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        Mutex::Autolock l(mServiceLock);
150c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh
151c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        if (nullptr == mCameraProviderManager.get()) {
152c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            mCameraProviderManager = new CameraProviderManager();
153c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            res = mCameraProviderManager->initialize(this);
154c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            if (res != OK) {
155c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                ALOGE("%s: Unable to initialize camera provider manager: %s (%d)",
156c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                        __FUNCTION__, strerror(-res), res);
157c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                return res;
158c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            }
159aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev        }
1602f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
1612f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
162c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        // Setup vendor tags before we call get_camera_info the first time
163c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        // because HAL might need to setup static vendor keys in get_camera_info
164c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        // TODO: maybe put this into CameraProviderManager::initialize()?
165c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        mCameraProviderManager->setUpVendorTags();
1662f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
167c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        if (nullptr == mFlashlight.get()) {
168c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            mFlashlight = new CameraFlashlight(mCameraProviderManager, this);
169aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev        }
170aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev
171c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        res = mFlashlight->findFlashUnits();
172c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        if (res != OK) {
173c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            ALOGE("Failed to enumerate flash units: %s (%d)", strerror(-res), res);
17492e3321e41e10f2e07a71f9512a6cadef7f40b64Yin-Chia Yeh        }
17592e3321e41e10f2e07a71f9512a6cadef7f40b64Yin-Chia Yeh
176c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        deviceIds = mCameraProviderManager->getCameraDeviceIds();
177c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    }
178c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh
179c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh
180c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    for (auto& cameraId : deviceIds) {
181c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        String8 id8 = String8(cameraId.c_str());
18292e3321e41e10f2e07a71f9512a6cadef7f40b64Yin-Chia Yeh        onDeviceStatusChanged(id8, CameraDeviceStatus::PRESENT);
1832f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
1842f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
1852f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    return OK;
1862823ce0ce6f9d508a07de20912c93cce9165027fRuben Brunk}
1872823ce0ce6f9d508a07de20912c93cce9165027fRuben Brunk
188412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvalasp<ICameraServiceProxy> CameraService::getCameraServiceProxy() {
18992c06fceabfa47906aaa7c747dcdd6376ccec358Christopher Wiley    sp<ICameraServiceProxy> proxyBinder = nullptr;
19092c06fceabfa47906aaa7c747dcdd6376ccec358Christopher Wiley#ifndef __BRILLO__
1912823ce0ce6f9d508a07de20912c93cce9165027fRuben Brunk    sp<IServiceManager> sm = defaultServiceManager();
192f4db13db84c40299de4f9997f08d05259bdb8716Eino-Ville Talvala    // Use checkService because cameraserver normally starts before the
193f4db13db84c40299de4f9997f08d05259bdb8716Eino-Ville Talvala    // system server and the proxy service. So the long timeout that getService
194f4db13db84c40299de4f9997f08d05259bdb8716Eino-Ville Talvala    // has before giving up is inappropriate.
195f4db13db84c40299de4f9997f08d05259bdb8716Eino-Ville Talvala    sp<IBinder> binder = sm->checkService(String16("media.camera.proxy"));
19692c06fceabfa47906aaa7c747dcdd6376ccec358Christopher Wiley    if (binder != nullptr) {
19792c06fceabfa47906aaa7c747dcdd6376ccec358Christopher Wiley        proxyBinder = interface_cast<ICameraServiceProxy>(binder);
1982823ce0ce6f9d508a07de20912c93cce9165027fRuben Brunk    }
19992c06fceabfa47906aaa7c747dcdd6376ccec358Christopher Wiley#endif
200412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala    return proxyBinder;
201412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala}
202412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala
203412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvalavoid CameraService::pingCameraServiceProxy() {
204412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala    sp<ICameraServiceProxy> proxyBinder = getCameraServiceProxy();
205412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala    if (proxyBinder == nullptr) return;
2062823ce0ce6f9d508a07de20912c93cce9165027fRuben Brunk    proxyBinder->pingForUserUpdate();
20765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
20865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
20965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianCameraService::~CameraService() {
210d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk    VendorTagDescriptor::clearGlobalVendorTagDescriptor();
211a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    mUidPolicy->unregisterSelf();
21265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
21365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
214aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peevvoid CameraService::onNewProviderRegistered() {
215aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev    enumerateProviders();
216aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev}
217aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev
218c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yehvoid CameraService::updateCameraNumAndIds() {
219c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    Mutex::Autolock l(mServiceLock);
220c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    mNumberOfCameras = mCameraProviderManager->getCameraCount();
221c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    mNormalDeviceIds =
222c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            mCameraProviderManager->getAPI1CompatibleCameraDeviceIds();
223c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh}
224c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh
225151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetskivoid CameraService::addStates(const String8 id) {
226151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    std::string cameraId(id.c_str());
227151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    hardware::camera::common::V1_0::CameraResourceCost cost;
228151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    status_t res = mCameraProviderManager->getResourceCost(cameraId, &cost);
229151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    if (res != OK) {
230151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski        ALOGE("Failed to query device resource cost: %s (%d)", strerror(-res), res);
231151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski        return;
232151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    }
233151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    std::set<String8> conflicting;
234151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    for (size_t i = 0; i < cost.conflictingDevices.size(); i++) {
235151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski        conflicting.emplace(String8(cost.conflictingDevices[i].c_str()));
236151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    }
237151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski
238151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    {
239151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski        Mutex::Autolock lock(mCameraStatesLock);
240151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski        mCameraStates.emplace(id, std::make_shared<CameraState>(id, cost.resourceCost,
241151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski                                                                conflicting));
242151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    }
243151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski
244151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    if (mFlashlight->hasFlashUnit(id)) {
245151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski        mTorchStatusMap.add(id, TorchModeStatus::AVAILABLE_OFF);
246151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    }
247c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh
248c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    updateCameraNumAndIds();
249151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    logDeviceAdded(id, "Device added");
250151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski}
251151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski
2526034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetskivoid CameraService::removeStates(const String8 id) {
253c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    updateCameraNumAndIds();
2546034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski    if (mFlashlight->hasFlashUnit(id)) {
2556034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski        mTorchStatusMap.removeItem(id);
2566034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski    }
2576034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski
2586034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski    {
2596034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski        Mutex::Autolock lock(mCameraStatesLock);
2606034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski        mCameraStates.erase(id);
2616034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski    }
2626034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski}
2636034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski
264f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalavoid CameraService::onDeviceStatusChanged(const String8& id,
265f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        CameraDeviceStatus newHalStatus) {
266f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    ALOGI("%s: Status changed for cameraId=%s, newStatus=%d", __FUNCTION__,
267f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            id.string(), newHalStatus);
268f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
269f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    StatusInternal newStatus = mapToInternal(newHalStatus);
270cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin
271cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    std::shared_ptr<CameraState> state = getCameraState(id);
272cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
273cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    if (state == nullptr) {
27492e3321e41e10f2e07a71f9512a6cadef7f40b64Yin-Chia Yeh        if (newStatus == StatusInternal::PRESENT) {
275151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski            ALOGI("%s: Unknown camera ID %s, a new camera is added",
27692e3321e41e10f2e07a71f9512a6cadef7f40b64Yin-Chia Yeh                    __FUNCTION__, id.string());
277151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski
278151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski            // First add as absent to make sure clients are notified below
279151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski            addStates(id);
280151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski
281151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski            updateStatus(newStatus, id);
28292e3321e41e10f2e07a71f9512a6cadef7f40b64Yin-Chia Yeh        } else {
28392e3321e41e10f2e07a71f9512a6cadef7f40b64Yin-Chia Yeh            ALOGE("%s: Bad camera ID %s", __FUNCTION__, id.string());
28492e3321e41e10f2e07a71f9512a6cadef7f40b64Yin-Chia Yeh        }
285cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin        return;
286cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin    }
287cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin
288f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    StatusInternal oldStatus = state->getStatus();
289cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
290f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    if (oldStatus == newStatus) {
291cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        ALOGE("%s: State transition to the same status %#x not allowed", __FUNCTION__, newStatus);
292cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin        return;
293cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin    }
294cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin
295f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    if (newStatus == StatusInternal::NOT_PRESENT) {
296a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk        logDeviceRemoved(id, String8::format("Device status changed from %d to %d", oldStatus,
297a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk                newStatus));
298c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh
299c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        // Set the device status to NOT_PRESENT, clients will no longer be able to connect
300c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        // to this device until the status changes
301c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        updateStatus(StatusInternal::NOT_PRESENT, id);
302c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh
303cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        sp<BasicClient> clientToDisconnect;
304cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin        {
305cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            // Don't do this in updateStatus to avoid deadlock over mServiceLock
306cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            Mutex::Autolock lock(mServiceLock);
307cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin
308cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            // Remove cached shim parameters
309cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            state->setShimParams(CameraParameters());
310cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin
3118d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala            // Remove the client from the list of active clients, if there is one
312cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            clientToDisconnect = removeClientLocked(id);
3138d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        }
314cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
3158d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        // Disconnect client
3168d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        if (clientToDisconnect.get() != nullptr) {
3178d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala            ALOGI("%s: Client for camera ID %s evicted due to device status change from HAL",
3188d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala                    __FUNCTION__, id.string());
319cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            // Notify the client of disconnection
320d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            clientToDisconnect->notifyError(
321d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED,
322cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    CaptureResultExtras{});
323cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            // Ensure not in binder RPC so client disconnect PID checks work correctly
324cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            LOG_ALWAYS_FATAL_IF(getCallingPid() != getpid(),
325cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    "onDeviceStatusChanged must be called from the camera service process!");
326cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            clientToDisconnect->disconnect();
327cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        }
328cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
3296034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski        removeStates(id);
330cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    } else {
331f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        if (oldStatus == StatusInternal::NOT_PRESENT) {
332a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk            logDeviceAdded(id, String8::format("Device status changed from %d to %d", oldStatus,
333a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk                    newStatus));
334a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk        }
335f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        updateStatus(newStatus, id);
336cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
337cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin
338cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin}
339cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin
34088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chenvoid CameraService::onTorchStatusChanged(const String8& cameraId,
341f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        TorchModeStatus newStatus) {
3423068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    Mutex::Autolock al(mTorchStatusMutex);
3433068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    onTorchStatusChangedLocked(cameraId, newStatus);
3443068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen}
3453068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
34688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chenvoid CameraService::onTorchStatusChangedLocked(const String8& cameraId,
347f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        TorchModeStatus newStatus) {
3483068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    ALOGI("%s: Torch status changed for cameraId=%s, newStatus=%d",
3493068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen            __FUNCTION__, cameraId.string(), newStatus);
3503068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
351f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    TorchModeStatus status;
35288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    status_t res = getTorchStatusLocked(cameraId, &status);
35388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    if (res) {
354f6463fc62a09b8aad8e811a9abbe9f4d9f2688f9Chien-Yu Chen        ALOGE("%s: cannot get torch status of camera %s: %s (%d)",
355f6463fc62a09b8aad8e811a9abbe9f4d9f2688f9Chien-Yu Chen                __FUNCTION__, cameraId.string(), strerror(-res), res);
35688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen        return;
35788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    }
35888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    if (status == newStatus) {
3593068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen        return;
3603068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    }
3613068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
36288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    res = setTorchStatusLocked(cameraId, newStatus);
3633068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    if (res) {
364d309fb9c8a2c4564d88fffba19c4e3688e4b862bEino-Ville Talvala        ALOGE("%s: Failed to set the torch status to %d: %s (%d)", __FUNCTION__,
365d309fb9c8a2c4564d88fffba19c4e3688e4b862bEino-Ville Talvala                (uint32_t)newStatus, strerror(-res), res);
3663068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen        return;
3673068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    }
3683068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
369cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    {
37099e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        // Update battery life logging for flashlight
371fe751bea0d3eedd6e817aebf4e457425b82e7117Chien-Yu Chen        Mutex::Autolock al(mTorchUidMapMutex);
37299e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        auto iter = mTorchUidMap.find(cameraId);
37399e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        if (iter != mTorchUidMap.end()) {
37499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk            int oldUid = iter->second.second;
37599e69716215cd0665379bc90d708f2ea8689831dRuben Brunk            int newUid = iter->second.first;
37699e69716215cd0665379bc90d708f2ea8689831dRuben Brunk            BatteryNotifier& notifier(BatteryNotifier::getInstance());
37799e69716215cd0665379bc90d708f2ea8689831dRuben Brunk            if (oldUid != newUid) {
37899e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                // If the UID has changed, log the status and update current UID in mTorchUidMap
379f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                if (status == TorchModeStatus::AVAILABLE_ON) {
38099e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                    notifier.noteFlashlightOff(cameraId, oldUid);
38199e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                }
382f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                if (newStatus == TorchModeStatus::AVAILABLE_ON) {
38399e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                    notifier.noteFlashlightOn(cameraId, newUid);
38499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                }
38599e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                iter->second.second = newUid;
38699e69716215cd0665379bc90d708f2ea8689831dRuben Brunk            } else {
38799e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                // If the UID has not changed, log the status
388f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                if (newStatus == TorchModeStatus::AVAILABLE_ON) {
38999e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                    notifier.noteFlashlightOn(cameraId, oldUid);
39099e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                } else {
39199e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                    notifier.noteFlashlightOff(cameraId, oldUid);
39299e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                }
39399e69716215cd0665379bc90d708f2ea8689831dRuben Brunk            }
39499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        }
39599e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    }
39699e69716215cd0665379bc90d708f2ea8689831dRuben Brunk
39799e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    {
398cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        Mutex::Autolock lock(mStatusListenerLock);
399cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        for (auto& i : mListenerList) {
400f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            i->onTorchStatusChanged(mapToInterface(newStatus), String16{cameraId});
401cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        }
4023068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    }
4033068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen}
4043068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
405d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::getNumberOfCameras(int32_t type, int32_t* numCameras) {
406a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
407aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev    Mutex::Autolock l(mServiceLock);
408bad4358c83c7daaf9eeb8542c15eea4f473c884cEino-Ville Talvala    switch (type) {
409bad4358c83c7daaf9eeb8542c15eea4f473c884cEino-Ville Talvala        case CAMERA_TYPE_BACKWARD_COMPATIBLE:
410c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            *numCameras = static_cast<int>(mNormalDeviceIds.size());
411d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            break;
412bad4358c83c7daaf9eeb8542c15eea4f473c884cEino-Ville Talvala        case CAMERA_TYPE_ALL:
413d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            *numCameras = mNumberOfCameras;
414d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            break;
415bad4358c83c7daaf9eeb8542c15eea4f473c884cEino-Ville Talvala        default:
416d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            ALOGW("%s: Unknown camera type %d",
417bad4358c83c7daaf9eeb8542c15eea4f473c884cEino-Ville Talvala                    __FUNCTION__, type);
418d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
419d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    "Unknown camera type %d", type);
420bad4358c83c7daaf9eeb8542c15eea4f473c884cEino-Ville Talvala    }
421d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return Status::ok();
42265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
42365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
424d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::getCameraInfo(int cameraId,
425d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        CameraInfo* cameraInfo) {
426a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
427aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev    Mutex::Autolock l(mServiceLock);
428aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev
4292f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (!mInitialized) {
430d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(ERROR_DISCONNECTED,
431d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "Camera subsystem is not available");
4328951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    }
4338951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev
43465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (cameraId < 0 || cameraId >= mNumberOfCameras) {
435d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT,
436d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "CameraId is not valid");
43765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
43865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4392f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    Status ret = Status::ok();
440c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    status_t err = mCameraProviderManager->getCameraInfo(
441c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            cameraIdIntToStrLocked(cameraId), cameraInfo);
442f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    if (err != OK) {
443f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev        ret = STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
444f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev                "Error retrieving camera info from device %d: %s (%d)", cameraId,
445f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev                strerror(-err), err);
446d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    }
447f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev
4482f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    return ret;
44965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
45065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
451c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yehstd::string CameraService::cameraIdIntToStrLocked(int cameraIdInt) {
452c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    if (cameraIdInt < 0 || cameraIdInt >= static_cast<int>(mNormalDeviceIds.size())) {
453c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        ALOGE("%s: input id %d invalid: valid range  (0, %zu)",
454c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                __FUNCTION__, cameraIdInt, mNormalDeviceIds.size());
455c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        return std::string{};
456cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
457c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh
458c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    return mNormalDeviceIds[cameraIdInt];
459c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh}
460c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh
461c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia YehString8 CameraService::cameraIdIntToStr(int cameraIdInt) {
462c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    Mutex::Autolock lock(mServiceLock);
463c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    return String8(cameraIdIntToStrLocked(cameraIdInt).c_str());
464cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
465b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk
4662f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville TalvalaStatus CameraService::getCameraCharacteristics(const String16& cameraId,
467f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        CameraMetadata* cameraInfo) {
468a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
4692b59be89dc245b6e2475d9e8b0c5f2392370e71eZhijun He    if (!cameraInfo) {
4702b59be89dc245b6e2475d9e8b0c5f2392370e71eZhijun He        ALOGE("%s: cameraInfo is NULL", __FUNCTION__);
471d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "cameraInfo is NULL");
4722b59be89dc245b6e2475d9e8b0c5f2392370e71eZhijun He    }
4732b59be89dc245b6e2475d9e8b0c5f2392370e71eZhijun He
4742f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (!mInitialized) {
4752f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        ALOGE("%s: Camera HAL couldn't be initialized", __FUNCTION__);
476d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(ERROR_DISCONNECTED,
477d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "Camera subsystem is not available");;
4782b59be89dc245b6e2475d9e8b0c5f2392370e71eZhijun He    }
4792b59be89dc245b6e2475d9e8b0c5f2392370e71eZhijun He
4802f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    Status ret{};
481f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
482f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    status_t res = mCameraProviderManager->getCameraCharacteristics(
483f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev            String8(cameraId).string(), cameraInfo);
484f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    if (res != OK) {
485f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev        return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, "Unable to retrieve camera "
486f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev                "characteristics for device %s: %s (%d)", String8(cameraId).string(),
487f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev                strerror(-res), res);
488f05e50eb06d3f70e50fa7f44c1fd32128033b49dZhijun He    }
489f05e50eb06d3f70e50fa7f44c1fd32128033b49dZhijun He
4902b59be89dc245b6e2475d9e8b0c5f2392370e71eZhijun He    return ret;
4912b59be89dc245b6e2475d9e8b0c5f2392370e71eZhijun He}
4922b59be89dc245b6e2475d9e8b0c5f2392370e71eZhijun He
493cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkint CameraService::getCallingPid() {
494cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return IPCThreadState::self()->getCallingPid();
495cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
496cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
497cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkint CameraService::getCallingUid() {
498cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return IPCThreadState::self()->getCallingUid();
499cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
500cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
501cc776718c0be7c31fe5ab4fc1446d377be60369fRuben BrunkString8 CameraService::getFormattedCurrentTime() {
502cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    time_t now = time(nullptr);
503cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    char formattedTime[64];
504cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    strftime(formattedTime, sizeof(formattedTime), "%m-%d %H:%M:%S", localtime(&now));
505cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return String8(formattedTime);
506cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
507cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
508d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::getCameraVendorTagDescriptor(
509d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        /*out*/
510d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        hardware::camera2::params::VendorTagDescriptor* desc) {
511a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
5122f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (!mInitialized) {
5132f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        ALOGE("%s: Camera HAL couldn't be initialized", __FUNCTION__);
514d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(ERROR_DISCONNECTED, "Camera subsystem not available");
515d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk    }
5161e74e241f5a4e0e763e27c888561405d013c9ca0Eino-Ville Talvala    sp<VendorTagDescriptor> globalDescriptor = VendorTagDescriptor::getGlobalVendorTagDescriptor();
5171e74e241f5a4e0e763e27c888561405d013c9ca0Eino-Ville Talvala    if (globalDescriptor != nullptr) {
5181e74e241f5a4e0e763e27c888561405d013c9ca0Eino-Ville Talvala        *desc = *(globalDescriptor.get());
5191e74e241f5a4e0e763e27c888561405d013c9ca0Eino-Ville Talvala    }
520d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return Status::ok();
521d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk}
522d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk
52371c73a2985a7ac65ee597be3441ab300fa56e22eEmilian PeevStatus CameraService::getCameraVendorTagCache(
52471c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev        /*out*/ hardware::camera2::params::VendorTagDescriptorCache* cache) {
52571c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    ATRACE_CALL();
52671c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    if (!mInitialized) {
52771c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev        ALOGE("%s: Camera HAL couldn't be initialized", __FUNCTION__);
52871c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev        return STATUS_ERROR(ERROR_DISCONNECTED,
52971c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                "Camera subsystem not available");
53071c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    }
53171c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    sp<VendorTagDescriptorCache> globalCache =
53271c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev            VendorTagDescriptorCache::getGlobalVendorTagCache();
53371c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    if (globalCache != nullptr) {
53471c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev        *cache = *(globalCache.get());
53571c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    }
53671c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    return Status::ok();
53771c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev}
53871c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev
5392f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalaint CameraService::getDeviceVersion(const String8& cameraId, int* facing) {
540a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
541634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
5422f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    int deviceVersion = 0;
543634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
544f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    status_t res;
545f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    hardware::hidl_version maxVersion{0,0};
546f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    res = mCameraProviderManager->getHighestSupportedVersion(cameraId.string(),
547f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev            &maxVersion);
548f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    if (res != OK) return -1;
549f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    deviceVersion = HARDWARE_DEVICE_API_VERSION(maxVersion.get_major(), maxVersion.get_minor());
550f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev
551f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    hardware::CameraInfo info;
552f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    if (facing) {
553f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev        res = mCameraProviderManager->getCameraInfo(cameraId.string(), &info);
5546963d0ad7b621dcdaa74cbfed17c776121635146Eino-Ville Talvala        if (res != OK) return -1;
555f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev        *facing = info.facing;
5562f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
557f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev
558634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    return deviceVersion;
559634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
560634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
561d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::filterGetInfoErrorCode(status_t err) {
562f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala    switch(err) {
563f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala        case NO_ERROR:
564d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return Status::ok();
565f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        case BAD_VALUE:
566d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT,
567d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    "CameraId is not valid for HAL module");
568f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        case NO_INIT:
569d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return STATUS_ERROR(ERROR_DISCONNECTED,
570d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    "Camera device not available");
571f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala        default:
572d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
573d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    "Camera HAL encountered error %d: %s",
574d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    err, strerror(-err));
575f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala    }
576bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin}
577bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
578d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::makeClient(const sp<CameraService>& cameraService,
5792f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        const sp<IInterface>& cameraCb, const String16& packageName, const String8& cameraId,
580c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        int api1CameraId, int facing, int clientPid, uid_t clientUid, int servicePid,
581c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        bool legacyMode, int halVersion, int deviceVersion, apiLevel effectiveApiLevel,
582cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        /*out*/sp<BasicClient>* client) {
583b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk
584cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    if (halVersion < 0 || halVersion == deviceVersion) {
585cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // Default path: HAL version is unspecified by caller, create CameraClient
586cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // based on device version reported by the HAL.
587cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        switch(deviceVersion) {
588cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk          case CAMERA_DEVICE_API_VERSION_1_0:
589cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            if (effectiveApiLevel == API_1) {  // Camera1 API route
590cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
591c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                *client = new CameraClient(cameraService, tmp, packageName,
592c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                        api1CameraId, facing, clientPid, clientUid,
593c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                        getpid(), legacyMode);
594cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            } else { // Camera2 API route
595cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                ALOGW("Camera using old HAL version: %d", deviceVersion);
596d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                return STATUS_ERROR_FMT(ERROR_DEPRECATED_HAL,
5972f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                        "Camera device \"%s\" HAL version %d does not support camera2 API",
5982f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                        cameraId.string(), deviceVersion);
599cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            }
600cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            break;
601cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk          case CAMERA_DEVICE_API_VERSION_3_0:
602cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk          case CAMERA_DEVICE_API_VERSION_3_1:
603cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk          case CAMERA_DEVICE_API_VERSION_3_2:
604cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk          case CAMERA_DEVICE_API_VERSION_3_3:
6054afbdecf8c6dc5ad04f6fa6c8712ce2c56a00c47Zhijun He          case CAMERA_DEVICE_API_VERSION_3_4:
606cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            if (effectiveApiLevel == API_1) { // Camera1 API route
607cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
608c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                *client = new Camera2Client(cameraService, tmp, packageName,
609c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                        cameraId, api1CameraId,
610c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                        facing, clientPid, clientUid,
611c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                        servicePid, legacyMode);
612cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            } else { // Camera2 API route
613d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                sp<hardware::camera2::ICameraDeviceCallbacks> tmp =
614d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                        static_cast<hardware::camera2::ICameraDeviceCallbacks*>(cameraCb.get());
615d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                *client = new CameraDeviceClient(cameraService, tmp, packageName, cameraId,
616cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                        facing, clientPid, clientUid, servicePid);
617b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk            }
618cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            break;
619cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk          default:
620cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            // Should not be reachable
621cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            ALOGE("Unknown camera device HAL version: %d", deviceVersion);
622d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
6232f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                    "Camera device \"%s\" has unknown HAL version %d",
6242f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                    cameraId.string(), deviceVersion);
625b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk        }
626cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    } else {
627cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // A particular HAL version is requested by caller. Create CameraClient
628cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // based on the requested HAL version.
629cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        if (deviceVersion > CAMERA_DEVICE_API_VERSION_1_0 &&
630cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            halVersion == CAMERA_DEVICE_API_VERSION_1_0) {
631cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            // Only support higher HAL version device opened as HAL1.0 device.
632cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
633c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            *client = new CameraClient(cameraService, tmp, packageName,
634c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                    api1CameraId, facing, clientPid, clientUid,
635c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                    servicePid, legacyMode);
636cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        } else {
637cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            // Other combinations (e.g. HAL3.x open as HAL2.x) are not supported yet.
638cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            ALOGE("Invalid camera HAL version %x: HAL %x device can only be"
639cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    " opened as HAL %x device", halVersion, deviceVersion,
640cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    CAMERA_DEVICE_API_VERSION_1_0);
641d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
6422f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                    "Camera device \"%s\" (HAL version %d) cannot be opened as HAL version %d",
6432f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                    cameraId.string(), deviceVersion, halVersion);
644b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk        }
645b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk    }
646d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return Status::ok();
647cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
648cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
6496267b539d0d1ee7118aafd976d75cb8db397bc24Ruben BrunkString8 CameraService::toString(std::set<userid_t> intSet) {
6506267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk    String8 s("");
6516267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk    bool first = true;
6526267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk    for (userid_t i : intSet) {
6536267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        if (first) {
6546267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk            s.appendFormat("%d", i);
6556267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk            first = false;
6566267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        } else {
6576267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk            s.appendFormat(", %d", i);
6586267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        }
6596267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk    }
6606267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk    return s;
6616267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk}
6626267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk
663f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalaint32_t CameraService::mapToInterface(TorchModeStatus status) {
664f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    int32_t serviceStatus = ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE;
665f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    switch (status) {
666f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        case TorchModeStatus::NOT_AVAILABLE:
667f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            serviceStatus = ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE;
668f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            break;
669f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        case TorchModeStatus::AVAILABLE_OFF:
670f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            serviceStatus = ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF;
671f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            break;
672f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        case TorchModeStatus::AVAILABLE_ON:
673f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            serviceStatus = ICameraServiceListener::TORCH_STATUS_AVAILABLE_ON;
674f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            break;
675f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        default:
676f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            ALOGW("Unknown new flash status: %d", status);
677f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    }
678f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    return serviceStatus;
679f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala}
680f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
681f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville TalvalaCameraService::StatusInternal CameraService::mapToInternal(CameraDeviceStatus status) {
682f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    StatusInternal serviceStatus = StatusInternal::NOT_PRESENT;
683f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    switch (status) {
684f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        case CameraDeviceStatus::NOT_PRESENT:
685f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            serviceStatus = StatusInternal::NOT_PRESENT;
686f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            break;
687f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        case CameraDeviceStatus::PRESENT:
688f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            serviceStatus = StatusInternal::PRESENT;
689f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            break;
690f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        case CameraDeviceStatus::ENUMERATING:
691f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            serviceStatus = StatusInternal::ENUMERATING;
692f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            break;
693f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        default:
694f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            ALOGW("Unknown new HAL device status: %d", status);
695f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    }
696f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    return serviceStatus;
697f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala}
698f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
699f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalaint32_t CameraService::mapToInterface(StatusInternal status) {
700f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    int32_t serviceStatus = ICameraServiceListener::STATUS_NOT_PRESENT;
701f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    switch (status) {
702f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        case StatusInternal::NOT_PRESENT:
703f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            serviceStatus = ICameraServiceListener::STATUS_NOT_PRESENT;
704f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            break;
705f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        case StatusInternal::PRESENT:
706f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            serviceStatus = ICameraServiceListener::STATUS_PRESENT;
707f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            break;
708f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        case StatusInternal::ENUMERATING:
709f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            serviceStatus = ICameraServiceListener::STATUS_ENUMERATING;
710f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            break;
711f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        case StatusInternal::NOT_AVAILABLE:
712f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            serviceStatus = ICameraServiceListener::STATUS_NOT_AVAILABLE;
713f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            break;
714f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        case StatusInternal::UNKNOWN:
715f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            serviceStatus = ICameraServiceListener::STATUS_UNKNOWN;
716f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            break;
717f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        default:
718f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            ALOGW("Unknown new internal device status: %d", status);
719f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    }
720f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    return serviceStatus;
721f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala}
722f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
723d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::initializeShimMetadata(int cameraId) {
724cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    int uid = getCallingUid();
725b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk
72698a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen    String16 internalPackageName("cameraserver");
727cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    String8 id = String8::format("%d", cameraId);
728d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    Status ret = Status::ok();
729cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    sp<Client> tmp = nullptr;
730d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (!(ret = connectHelper<ICameraClient,Client>(
731c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            sp<ICameraClient>{nullptr}, id, cameraId,
732c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            static_cast<int>(CAMERA_HAL_API_VERSION_UNSPECIFIED),
733d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            internalPackageName, uid, USE_CALLING_PID,
734d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            API_1, /*legacyMode*/ false, /*shimUpdateOnly*/ true,
735d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            /*out*/ tmp)
736d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            ).isOk()) {
737d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        ALOGE("%s: Error initializing shim metadata: %s", __FUNCTION__, ret.toString8().string());
738b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk    }
739d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return ret;
740b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk}
741b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk
742d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::getLegacyParametersLazy(int cameraId,
74365d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin        /*out*/
74465d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin        CameraParameters* parameters) {
74565d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
74665d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    ALOGV("%s: for cameraId: %d", __FUNCTION__, cameraId);
74765d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
748d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    Status ret = Status::ok();
74965d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
75065d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    if (parameters == NULL) {
75165d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin        ALOGE("%s: parameters must not be null", __FUNCTION__);
752d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Parameters must not be null");
75365d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    }
75465d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
755cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    String8 id = String8::format("%d", cameraId);
75665d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
757cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    // Check if we already have parameters
758cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    {
759cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // Scope for service lock
760cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        Mutex::Autolock lock(mServiceLock);
761cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        auto cameraState = getCameraState(id);
762cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        if (cameraState == nullptr) {
763cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            ALOGE("%s: Invalid camera ID: %s", __FUNCTION__, id.string());
764d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
765d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    "Invalid camera ID: %s", id.string());
76665d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin        }
767cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        CameraParameters p = cameraState->getShimParams();
768cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        if (!p.isEmpty()) {
769cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            *parameters = p;
770d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return ret;
77165d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin        }
772cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
77365d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
774cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    int64_t token = IPCThreadState::self()->clearCallingIdentity();
775cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    ret = initializeShimMetadata(cameraId);
776cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    IPCThreadState::self()->restoreCallingIdentity(token);
777d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (!ret.isOk()) {
778cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // Error already logged by callee
779cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        return ret;
780cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
78165d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
782cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    // Check for parameters again
783cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    {
784cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // Scope for service lock
785cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        Mutex::Autolock lock(mServiceLock);
786cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        auto cameraState = getCameraState(id);
787cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        if (cameraState == nullptr) {
788cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            ALOGE("%s: Invalid camera ID: %s", __FUNCTION__, id.string());
789d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
790d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    "Invalid camera ID: %s", id.string());
791cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        }
792cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        CameraParameters p = cameraState->getShimParams();
793cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        if (!p.isEmpty()) {
794cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            *parameters = p;
795d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return ret;
79665d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin        }
79765d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    }
79865d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
799cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    ALOGE("%s: Parameters were not initialized, or were empty.  Device may not be present.",
800cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            __FUNCTION__);
801d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return STATUS_ERROR(ERROR_INVALID_OPERATION, "Unable to initialize legacy parameters");
80265d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin}
80365d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
80498a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen// Can camera service trust the caller based on the calling UID?
80598a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chenstatic bool isTrustedCallingUid(uid_t uid) {
80698a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen    switch (uid) {
807af9d030e075e659e9f50fdd143aa83459a7795e2Eino-Ville Talvala        case AID_MEDIA:        // mediaserver
80898a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen        case AID_CAMERASERVER: // cameraserver
809af9d030e075e659e9f50fdd143aa83459a7795e2Eino-Ville Talvala        case AID_RADIO:        // telephony
81098a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen            return true;
81198a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen        default:
81298a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen            return false;
81398a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen    }
81498a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen}
81598a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen
816d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::validateConnectLocked(const String8& cameraId,
81718df60e094edbaa08cbecd25b0398643b8a0f29aChien-Yu Chen        const String8& clientName8, /*inout*/int& clientUid, /*inout*/int& clientPid,
81818df60e094edbaa08cbecd25b0398643b8a0f29aChien-Yu Chen        /*out*/int& originalClientPid) const {
8195861a9a98c641261c4807c976c750e4611b3a57dTyler Luu
8209c2a2c26c0d70de97f51063b06a5efc79b327eedAlex Deymo#ifdef __BRILLO__
8219c2a2c26c0d70de97f51063b06a5efc79b327eedAlex Deymo    UNUSED(clientName8);
8229c2a2c26c0d70de97f51063b06a5efc79b327eedAlex Deymo    UNUSED(clientUid);
8239c2a2c26c0d70de97f51063b06a5efc79b327eedAlex Deymo    UNUSED(clientPid);
8249c2a2c26c0d70de97f51063b06a5efc79b327eedAlex Deymo    UNUSED(originalClientPid);
8259c2a2c26c0d70de97f51063b06a5efc79b327eedAlex Deymo#else
8267939aee8c1688bc8647c5bceb0d47a4e790ff27dChien-Yu Chen    Status allowed = validateClientPermissionsLocked(cameraId, clientName8, clientUid, clientPid,
8277939aee8c1688bc8647c5bceb0d47a4e790ff27dChien-Yu Chen            originalClientPid);
8280492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala    if (!allowed.isOk()) {
829ce761d1fef4da2a4dec3eb538d103fcde1971dbaChristopher Wiley        return allowed;
830ce761d1fef4da2a4dec3eb538d103fcde1971dbaChristopher Wiley    }
8319c2a2c26c0d70de97f51063b06a5efc79b327eedAlex Deymo#endif  // __BRILLO__
832ce761d1fef4da2a4dec3eb538d103fcde1971dbaChristopher Wiley
8330492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala    int callingPid = getCallingPid();
8340492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala
8352f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (!mInitialized) {
836cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        ALOGE("CameraService::connect X (PID %d) rejected (camera HAL module not loaded)",
837cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                callingPid);
8380492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala        return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
8390492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala                "No camera HAL module available to open camera device \"%s\"", cameraId.string());
8408951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    }
8418951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev
842cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    if (getCameraState(cameraId) == nullptr) {
843cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        ALOGE("CameraService::connect X (PID %d) rejected (invalid camera ID %s)", callingPid,
844cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                cameraId.string());
8450492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala        return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
8460492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala                "No camera device with ID \"%s\" available", cameraId.string());
84765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
84865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
8490492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala    status_t err = checkIfDeviceIsUsable(cameraId);
8500492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala    if (err != NO_ERROR) {
8510492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala        switch(err) {
8520492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala            case -ENODEV:
8530492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala            case -EBUSY:
8540492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala                return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
8550492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala                        "No camera device with ID \"%s\" currently available", cameraId.string());
8560492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala            default:
8570492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala                return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
8580492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala                        "Unknown error connecting to ID \"%s\"", cameraId.string());
8590492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala        }
8600492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala    }
8610492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala    return Status::ok();
8620039bcf0c4f10b92917c26df70c7847f1ab0b51eChristopher Wiley}
8630039bcf0c4f10b92917c26df70c7847f1ab0b51eChristopher Wiley
8640492686c4703b3ddbff52d047ef226b973a3388aEino-Ville TalvalaStatus CameraService::validateClientPermissionsLocked(const String8& cameraId,
8657939aee8c1688bc8647c5bceb0d47a4e790ff27dChien-Yu Chen        const String8& clientName8, int& clientUid, int& clientPid,
8667939aee8c1688bc8647c5bceb0d47a4e790ff27dChien-Yu Chen        /*out*/int& originalClientPid) const {
8670039bcf0c4f10b92917c26df70c7847f1ab0b51eChristopher Wiley    int callingPid = getCallingPid();
86898a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen    int callingUid = getCallingUid();
8695861a9a98c641261c4807c976c750e4611b3a57dTyler Luu
87098a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen    // Check if we can trust clientUid
871ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    if (clientUid == USE_CALLING_UID) {
87298a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen        clientUid = callingUid;
87398a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen    } else if (!isTrustedCallingUid(callingUid)) {
87498a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen        ALOGE("CameraService::connect X (calling PID %d, calling UID %d) rejected "
87598a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen                "(don't trust clientUid %d)", callingPid, callingUid, clientUid);
876d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
877d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "Untrusted caller (calling PID %d, UID %d) trying to "
878d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "forward camera access to camera %s for client %s (PID %d, UID %d)",
879d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                callingPid, callingUid, cameraId.string(),
880d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                clientName8.string(), clientUid, clientPid);
88198a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen    }
88298a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen
88398a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen    // Check if we can trust clientPid
88498a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen    if (clientPid == USE_CALLING_PID) {
88598a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen        clientPid = callingPid;
88698a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen    } else if (!isTrustedCallingUid(callingUid)) {
88798a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen        ALOGE("CameraService::connect X (calling PID %d, calling UID %d) rejected "
88898a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen                "(don't trust clientPid %d)", callingPid, callingUid, clientPid);
889d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
890d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "Untrusted caller (calling PID %d, UID %d) trying to "
891d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "forward camera access to camera %s for client %s (PID %d, UID %d)",
892d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                callingPid, callingUid, cameraId.string(),
893d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                clientName8.string(), clientUid, clientPid);
894ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    }
89565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
89698a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen    // If it's not calling from cameraserver, check the permission.
89798a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen    if (callingPid != getpid() &&
89898a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen            !checkPermission(String16("android.permission.CAMERA"), clientPid, clientUid)) {
89998a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen        ALOGE("Permission Denial: can't use the camera pid=%d, uid=%d", clientPid, clientUid);
900d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
901d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "Caller \"%s\" (PID %d, UID %d) cannot open camera \"%s\" without camera permission",
902d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                clientName8.string(), clientUid, clientPid, cameraId.string());
903ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    }
90465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
905a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    // Make sure the UID is in an active state to use the camera
906a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    if (!mUidPolicy->isUidActive(callingUid)) {
907a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        ALOGE("Access Denial: can't use the camera from an idle UID pid=%d, uid=%d",
908a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            clientPid, clientUid);
909a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        return STATUS_ERROR_FMT(ERROR_DISABLED,
910a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov                "Caller \"%s\" (PID %d, UID %d) cannot open camera \"%s\" from background",
911a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov                clientName8.string(), clientUid, clientPid, cameraId.string());
912a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
913a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
9144f3d6203c71f9e76fbd2964ad54a81b7036f7e17Chien-Yu Chen    // Only use passed in clientPid to check permission. Use calling PID as the client PID that's
9154f3d6203c71f9e76fbd2964ad54a81b7036f7e17Chien-Yu Chen    // connected to camera service directly.
91618df60e094edbaa08cbecd25b0398643b8a0f29aChien-Yu Chen    originalClientPid = clientPid;
9174f3d6203c71f9e76fbd2964ad54a81b7036f7e17Chien-Yu Chen    clientPid = callingPid;
91865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
9196267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk    userid_t clientUserId = multiuser_get_user_id(clientUid);
920a3355430a36bbfa7b2c0d90eb30834f1c5dac337Wu-cheng Li
921a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    // Only allow clients who are being used by the current foreground device user, unless calling
922a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    // from our own process.
9236267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk    if (callingPid != getpid() && (mAllowedUsers.find(clientUserId) == mAllowedUsers.end())) {
9246267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        ALOGE("CameraService::connect X (PID %d) rejected (cannot connect from "
9256267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk                "device user %d, currently allowed device users: %s)", callingPid, clientUserId,
9266267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk                toString(mAllowedUsers).string());
927d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
928d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "Callers from device user %d are not currently allowed to connect to camera \"%s\"",
929d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                clientUserId, cameraId.string());
93036597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    }
93136597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
932d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return Status::ok();
933cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
934cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
935cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkstatus_t CameraService::checkIfDeviceIsUsable(const String8& cameraId) const {
936cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    auto cameraState = getCameraState(cameraId);
937cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    int callingPid = getCallingPid();
938cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    if (cameraState == nullptr) {
939cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        ALOGE("CameraService::connect X (PID %d) rejected (invalid camera ID %s)", callingPid,
940cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                cameraId.string());
941cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        return -ENODEV;
942cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
943cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
944f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    StatusInternal currentStatus = cameraState->getStatus();
945f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    if (currentStatus == StatusInternal::NOT_PRESENT) {
946cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        ALOGE("CameraService::connect X (PID %d) rejected (camera %s is not connected)",
947cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                callingPid, cameraId.string());
9480f61d8f14aa368c9cd7076528e8096e10ed100a0Ruben Brunk        return -ENODEV;
949f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    } else if (currentStatus == StatusInternal::ENUMERATING) {
950cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        ALOGE("CameraService::connect X (PID %d) rejected, (camera %s is initializing)",
951cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                callingPid, cameraId.string());
9520f61d8f14aa368c9cd7076528e8096e10ed100a0Ruben Brunk        return -EBUSY;
953cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin    }
954cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin
955cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return NO_ERROR;
956e6800cea0678dbc0bf697b44c3e4548b0253085cIgor Murashkin}
957e6800cea0678dbc0bf697b44c3e4548b0253085cIgor Murashkin
958cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkvoid CameraService::finishConnectLocked(const sp<BasicClient>& client,
959cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        const CameraService::DescriptorPtr& desc) {
960e6800cea0678dbc0bf697b44c3e4548b0253085cIgor Murashkin
961cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    // Make a descriptor for the incoming client
962cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    auto clientDescriptor = CameraService::CameraClientManager::makeClientDescriptor(client, desc);
963cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    auto evicted = mActiveClientManager.addAndEvict(clientDescriptor);
964cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
965cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    logConnected(desc->getKey(), static_cast<int>(desc->getOwnerId()),
966cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            String8(client->getPackageName()));
967cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
968cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    if (evicted.size() > 0) {
969cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // This should never happen - clients should already have been removed in disconnect
970cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        for (auto& i : evicted) {
971cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            ALOGE("%s: Invalid state: Client for camera %s was not removed in disconnect",
972cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    __FUNCTION__, i->getKey().string());
9732fd2440d0175ca3e196b01b7541a9e0d4ed9a694Wu-cheng Li        }
974e6800cea0678dbc0bf697b44c3e4548b0253085cIgor Murashkin
975cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        LOG_ALWAYS_FATAL("%s: Invalid state for CameraService, clients not evicted properly",
976cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                __FUNCTION__);
977cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
97824901c86e10a0923fe10f5e9bce5e6dba061a289Eino-Ville Talvala
97924901c86e10a0923fe10f5e9bce5e6dba061a289Eino-Ville Talvala    // And register a death notification for the client callback. Do
98024901c86e10a0923fe10f5e9bce5e6dba061a289Eino-Ville Talvala    // this last to avoid Binder policy where a nested Binder
98124901c86e10a0923fe10f5e9bce5e6dba061a289Eino-Ville Talvala    // transaction might be pre-empted to service the client death
98224901c86e10a0923fe10f5e9bce5e6dba061a289Eino-Ville Talvala    // notification if the client process dies before linkToDeath is
98324901c86e10a0923fe10f5e9bce5e6dba061a289Eino-Ville Talvala    // invoked.
98424901c86e10a0923fe10f5e9bce5e6dba061a289Eino-Ville Talvala    sp<IBinder> remoteCallback = client->getRemote();
98524901c86e10a0923fe10f5e9bce5e6dba061a289Eino-Ville Talvala    if (remoteCallback != nullptr) {
98624901c86e10a0923fe10f5e9bce5e6dba061a289Eino-Ville Talvala        remoteCallback->linkToDeath(this);
98724901c86e10a0923fe10f5e9bce5e6dba061a289Eino-Ville Talvala    }
988e6800cea0678dbc0bf697b44c3e4548b0253085cIgor Murashkin}
989e6800cea0678dbc0bf697b44c3e4548b0253085cIgor Murashkin
990cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkstatus_t CameraService::handleEvictionsLocked(const String8& cameraId, int clientPid,
991cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        apiLevel effectiveApiLevel, const sp<IBinder>& remoteCallback, const String8& packageName,
992a858ea0495c887621a2fd9c0afc13780deccb597Igor Murashkin        /*out*/
993cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        sp<BasicClient>* client,
994cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>* partial) {
995a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
996cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    status_t ret = NO_ERROR;
9974f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk    std::vector<DescriptorPtr> evictedClients;
998cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    DescriptorPtr clientDescriptor;
999cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    {
1000cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        if (effectiveApiLevel == API_1) {
1001cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            // If we are using API1, any existing client for this camera ID with the same remote
1002cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            // should be returned rather than evicted to allow MediaRecorder to work properly.
1003cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1004cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            auto current = mActiveClientManager.get(cameraId);
1005cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            if (current != nullptr) {
1006cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                auto clientSp = current->getValue();
1007cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                if (clientSp.get() != nullptr) { // should never be needed
10080bbf8b213ad96051357e3ad6d6d2808bfa31a59aRuben Brunk                    if (!clientSp->canCastToApiClient(effectiveApiLevel)) {
10090bbf8b213ad96051357e3ad6d6d2808bfa31a59aRuben Brunk                        ALOGW("CameraService connect called from same client, but with a different"
10100bbf8b213ad96051357e3ad6d6d2808bfa31a59aRuben Brunk                                " API level, evicting prior client...");
10110bbf8b213ad96051357e3ad6d6d2808bfa31a59aRuben Brunk                    } else if (clientSp->getRemote() == remoteCallback) {
1012cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                        ALOGI("CameraService::connect X (PID %d) (second call from same"
10130bbf8b213ad96051357e3ad6d6d2808bfa31a59aRuben Brunk                                " app binder, returning the same client)", clientPid);
1014cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                        *client = clientSp;
1015cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                        return NO_ERROR;
1016cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    }
1017cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                }
1018cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            }
1019cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        }
10203068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
1021cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // Get current active client PIDs
1022cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        std::vector<int> ownerPids(mActiveClientManager.getAllOwners());
1023cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        ownerPids.push_back(clientPid);
1024cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
10258131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev        std::vector<int> priorityScores(ownerPids.size());
10268131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev        std::vector<int> states(ownerPids.size());
1027cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
10288131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev        // Get priority scores of all active PIDs
10298131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev        status_t err = ProcessInfoService::getProcessStatesScoresFromPids(
10308131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                ownerPids.size(), &ownerPids[0], /*out*/&states[0],
10318131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                /*out*/&priorityScores[0]);
10328131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev        if (err != OK) {
10338131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev            ALOGE("%s: Priority score query failed: %d",
10348131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                  __FUNCTION__, err);
10358131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev            return err;
10368131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev        }
1037cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1038cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // Update all active clients' priorities
10398131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev        std::map<int,resource_policy::ClientPriority> pidToPriorityMap;
1040cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        for (size_t i = 0; i < ownerPids.size() - 1; i++) {
10418131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev            pidToPriorityMap.emplace(ownerPids[i],
10428131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                    resource_policy::ClientPriority(priorityScores[i], states[i]));
1043cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        }
1044cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        mActiveClientManager.updatePriorities(pidToPriorityMap);
1045cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1046cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // Get state for the given cameraId
1047cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        auto state = getCameraState(cameraId);
1048cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        if (state == nullptr) {
1049cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            ALOGE("CameraService::connect X (PID %d) rejected (no camera device with ID %s)",
1050cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                clientPid, cameraId.string());
1051d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            // Should never get here because validateConnectLocked should have errored out
1052b10cdadf0fb945e23ca77008d4af76584bd0e39aZhijun He            return BAD_VALUE;
1053b10cdadf0fb945e23ca77008d4af76584bd0e39aZhijun He        }
1054cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1055cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // Make descriptor for incoming client
1056cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        clientDescriptor = CameraClientManager::makeClientDescriptor(cameraId,
1057cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                sp<BasicClient>{nullptr}, static_cast<int32_t>(state->getCost()),
1058cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                state->getConflicting(),
10598131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                priorityScores[priorityScores.size() - 1],
10608131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                clientPid,
10618131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                states[states.size() - 1]);
1062cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1063cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // Find clients that would be evicted
1064cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        auto evicted = mActiveClientManager.wouldEvict(clientDescriptor);
1065cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1066cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // If the incoming client was 'evicted,' higher priority clients have the camera in the
1067cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // background, so we cannot do evictions
1068cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        if (std::find(evicted.begin(), evicted.end(), clientDescriptor) != evicted.end()) {
1069cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            ALOGE("CameraService::connect X (PID %d) rejected (existing client(s) with higher"
1070cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    " priority).", clientPid);
1071cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1072cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            sp<BasicClient> clientSp = clientDescriptor->getValue();
1073cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            String8 curTime = getFormattedCurrentTime();
1074cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            auto incompatibleClients =
1075cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    mActiveClientManager.getIncompatibleClients(clientDescriptor);
1076cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1077cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            String8 msg = String8::format("%s : DENIED connect device %s client for package %s "
10788131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                    "(PID %d, score %d state %d) due to eviction policy", curTime.string(),
1079cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    cameraId.string(), packageName.string(), clientPid,
10808131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                    priorityScores[priorityScores.size() - 1],
10818131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                    states[states.size() - 1]);
1082cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1083cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            for (auto& i : incompatibleClients) {
1084cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                msg.appendFormat("\n   - Blocked by existing device %s client for package %s"
10858131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                        "(PID %" PRId32 ", score %" PRId32 ", state %" PRId32 ")",
10868131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                        i->getKey().string(),
10878131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                        String8{i->getValue()->getPackageName()}.string(),
10888131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                        i->getOwnerId(), i->getPriority().getScore(),
10898131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                        i->getPriority().getState());
1090022f0cb0c6f135edde4ebe84859c685933ee895eEino-Ville Talvala                ALOGE("   Conflicts with: Device %s, client package %s (PID %"
10918131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                        PRId32 ", score %" PRId32 ", state %" PRId32 ")", i->getKey().string(),
1092022f0cb0c6f135edde4ebe84859c685933ee895eEino-Ville Talvala                        String8{i->getValue()->getPackageName()}.string(), i->getOwnerId(),
10938131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                        i->getPriority().getScore(), i->getPriority().getState());
1094cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            }
1095cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1096cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            // Log the client's attempt
1097a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk            Mutex::Autolock l(mLogLock);
1098cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            mEventLog.add(msg);
1099cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1100cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            return -EBUSY;
1101cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        }
1102cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1103cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        for (auto& i : evicted) {
1104cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            sp<BasicClient> clientSp = i->getValue();
1105cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            if (clientSp.get() == nullptr) {
1106cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                ALOGE("%s: Invalid state: Null client in active client list.", __FUNCTION__);
1107cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1108cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                // TODO: Remove this
1109cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                LOG_ALWAYS_FATAL("%s: Invalid state for CameraService, null client in active list",
1110cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                        __FUNCTION__);
1111cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                mActiveClientManager.remove(i);
1112cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                continue;
1113cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            }
1114cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1115cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            ALOGE("CameraService::connect evicting conflicting client for camera ID %s",
1116cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    i->getKey().string());
11174f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk            evictedClients.push_back(i);
1118cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1119cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            // Log the clients evicted
1120a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk            logEvent(String8::format("EVICT device %s client held by package %s (PID"
11218131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                    " %" PRId32 ", score %" PRId32 ", state %" PRId32 ")\n - Evicted by device %s client for"
11228131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                    " package %s (PID %d, score %" PRId32 ", state %" PRId32 ")",
1123cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    i->getKey().string(), String8{clientSp->getPackageName()}.string(),
11248131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                    i->getOwnerId(), i->getPriority().getScore(),
11258131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                    i->getPriority().getState(), cameraId.string(),
1126cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    packageName.string(), clientPid,
11278131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                    priorityScores[priorityScores.size() - 1],
11288131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                    states[states.size() - 1]));
1129cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1130cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            // Notify the client of disconnection
1131d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            clientSp->notifyError(hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED,
1132cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    CaptureResultExtras());
1133b10cdadf0fb945e23ca77008d4af76584bd0e39aZhijun He        }
1134b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk    }
1135b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk
1136cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    // Do not hold mServiceLock while disconnecting clients, but retain the condition blocking
1137cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    // other clients from connecting in mServiceLockWrapper if held
1138cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    mServiceLock.unlock();
1139cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1140cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    // Clear caller identity temporarily so client disconnect PID checks work correctly
1141cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    int64_t token = IPCThreadState::self()->clearCallingIdentity();
1142cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1143cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    // Destroy evicted clients
1144cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    for (auto& i : evictedClients) {
1145cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // Disconnect is blocking, and should only have returned when HAL has cleaned up
11464f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk        i->getValue()->disconnect(); // Clients will remove themselves from the active client list
1147b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk    }
1148b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk
1149cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    IPCThreadState::self()->restoreCallingIdentity(token);
1150b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk
11514f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk    for (const auto& i : evictedClients) {
11524f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk        ALOGV("%s: Waiting for disconnect to complete for client for device %s (PID %" PRId32 ")",
11534f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk                __FUNCTION__, i->getKey().string(), i->getOwnerId());
11544f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk        ret = mActiveClientManager.waitUntilRemoved(i, DEFAULT_DISCONNECT_TIMEOUT_NS);
11554f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk        if (ret == TIMED_OUT) {
11564f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk            ALOGE("%s: Timed out waiting for client for device %s to disconnect, "
11574f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk                    "current clients:\n%s", __FUNCTION__, i->getKey().string(),
11584f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk                    mActiveClientManager.toString().string());
11594f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk            return -EBUSY;
11604f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk        }
11614f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk        if (ret != NO_ERROR) {
11624f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk            ALOGE("%s: Received error waiting for client for device %s to disconnect: %s (%d), "
11634f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk                    "current clients:\n%s", __FUNCTION__, i->getKey().string(), strerror(-ret),
11644f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk                    ret, mActiveClientManager.toString().string());
11654f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk            return ret;
11664f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk        }
11674f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk    }
11684f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk
11694f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk    evictedClients.clear();
11704f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk
1171cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    // Once clients have been disconnected, relock
1172cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    mServiceLock.lock();
1173cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1174cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    // Check again if the device was unplugged or something while we weren't holding mServiceLock
1175cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    if ((ret = checkIfDeviceIsUsable(cameraId)) != NO_ERROR) {
1176cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        return ret;
1177cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
1178cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1179cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    *partial = clientDescriptor;
1180cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return NO_ERROR;
1181b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk}
1182b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk
1183d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::connect(
1184e6800cea0678dbc0bf697b44c3e4548b0253085cIgor Murashkin        const sp<ICameraClient>& cameraClient,
1185c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        int api1CameraId,
1186280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov        const String16& clientPackageName,
11870f61d8f14aa368c9cd7076528e8096e10ed100a0Ruben Brunk        int clientUid,
118898a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen        int clientPid,
11890f61d8f14aa368c9cd7076528e8096e10ed100a0Ruben Brunk        /*out*/
1190d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        sp<ICamera>* device) {
1191e6800cea0678dbc0bf697b44c3e4548b0253085cIgor Murashkin
1192a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
1193d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    Status ret = Status::ok();
1194c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh
1195c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    String8 id = cameraIdIntToStr(api1CameraId);
1196cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    sp<Client> client = nullptr;
1197c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    ret = connectHelper<ICameraClient,Client>(cameraClient, id, api1CameraId,
1198d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageName, clientUid, clientPid, API_1,
1199d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            /*legacyMode*/ false, /*shimUpdateOnly*/ false,
1200d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            /*out*/client);
1201634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
1202d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if(!ret.isOk()) {
1203280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov        logRejected(id, getCallingPid(), String8(clientPackageName),
1204d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                ret.toString8());
1205cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        return ret;
1206acd695c42749f8821b0a0cc27739ddf096c6d4e8Igor Murashkin    }
1207bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
1208d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    *device = client;
1209d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return ret;
1210634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
1211634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
1212d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::connectLegacy(
1213b10cdadf0fb945e23ca77008d4af76584bd0e39aZhijun He        const sp<ICameraClient>& cameraClient,
1214c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        int api1CameraId, int halVersion,
1215280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov        const String16& clientPackageName,
1216b10cdadf0fb945e23ca77008d4af76584bd0e39aZhijun He        int clientUid,
1217b10cdadf0fb945e23ca77008d4af76584bd0e39aZhijun He        /*out*/
1218d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        sp<ICamera>* device) {
1219b10cdadf0fb945e23ca77008d4af76584bd0e39aZhijun He
1220a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
1221c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    String8 id = cameraIdIntToStr(api1CameraId);
1222b10cdadf0fb945e23ca77008d4af76584bd0e39aZhijun He
1223d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    Status ret = Status::ok();
1224cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    sp<Client> client = nullptr;
1225c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    ret = connectHelper<ICameraClient,Client>(cameraClient, id, api1CameraId, halVersion,
1226d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            clientPackageName, clientUid, USE_CALLING_PID, API_1,
1227d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            /*legacyMode*/ true, /*shimUpdateOnly*/ false,
1228d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            /*out*/client);
1229b10cdadf0fb945e23ca77008d4af76584bd0e39aZhijun He
1230d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if(!ret.isOk()) {
1231280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov        logRejected(id, getCallingPid(), String8(clientPackageName),
1232d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                ret.toString8());
1233cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        return ret;
1234b10cdadf0fb945e23ca77008d4af76584bd0e39aZhijun He    }
1235b10cdadf0fb945e23ca77008d4af76584bd0e39aZhijun He
1236d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    *device = client;
1237d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return ret;
1238b10cdadf0fb945e23ca77008d4af76584bd0e39aZhijun He}
1239b10cdadf0fb945e23ca77008d4af76584bd0e39aZhijun He
1240d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::connectDevice(
1241d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb,
1242f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        const String16& cameraId,
1243280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov        const String16& clientPackageName,
1244cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        int clientUid,
1245cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        /*out*/
1246d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        sp<hardware::camera2::ICameraDeviceUser>* device) {
1247cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1248a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
1249d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    Status ret = Status::ok();
1250f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    String8 id = String8(cameraId);
1251cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    sp<CameraDeviceClient> client = nullptr;
1252d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    ret = connectHelper<hardware::camera2::ICameraDeviceCallbacks,CameraDeviceClient>(cameraCb, id,
1253c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            /*api1CameraId*/-1,
1254d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageName,
1255d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            clientUid, USE_CALLING_PID, API_2,
1256d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            /*legacyMode*/ false, /*shimUpdateOnly*/ false,
1257d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            /*out*/client);
1258cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1259d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if(!ret.isOk()) {
1260280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov        logRejected(id, getCallingPid(), String8(clientPackageName),
1261d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                ret.toString8());
1262cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        return ret;
126388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    }
126488da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen
1265d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    *device = client;
1266d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return ret;
126788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen}
126888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen
1269f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalatemplate<class CALLBACK, class CLIENT>
1270f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville TalvalaStatus CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
1271c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        int api1CameraId, int halVersion, const String16& clientPackageName, int clientUid,
1272c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        int clientPid, apiLevel effectiveApiLevel, bool legacyMode, bool shimUpdateOnly,
1273f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        /*out*/sp<CLIENT>& device) {
1274f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    binder::Status ret = binder::Status::ok();
1275f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1276f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    String8 clientName8(clientPackageName);
1277f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1278f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    int originalClientPid = 0;
1279f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1280f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    ALOGI("CameraService::connect call (PID %d \"%s\", camera ID %s) for HAL version %s and "
1281f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            "Camera API version %d", clientPid, clientName8.string(), cameraId.string(),
1282f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            (halVersion == -1) ? "default" : std::to_string(halVersion).c_str(),
1283f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            static_cast<int>(effectiveApiLevel));
1284f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1285f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    sp<CLIENT> client = nullptr;
1286f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    {
1287f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        // Acquire mServiceLock and prevent other clients from connecting
1288f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        std::unique_ptr<AutoConditionLock> lock =
1289f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                AutoConditionLock::waitAndAcquire(mServiceLockWrapper, DEFAULT_CONNECT_TIMEOUT_NS);
1290f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1291f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        if (lock == nullptr) {
1292f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            ALOGE("CameraService::connect (PID %d) rejected (too many other clients connecting)."
1293f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                    , clientPid);
1294f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE,
1295f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                    "Cannot open camera %s for \"%s\" (PID %d): Too many other clients connecting",
1296f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                    cameraId.string(), clientName8.string(), clientPid);
1297f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        }
1298f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1299f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        // Enforce client permissions and do basic sanity checks
1300f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        if(!(ret = validateConnectLocked(cameraId, clientName8,
1301f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                /*inout*/clientUid, /*inout*/clientPid, /*out*/originalClientPid)).isOk()) {
1302f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            return ret;
1303f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        }
1304f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1305f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        // Check the shim parameters after acquiring lock, if they have already been updated and
1306f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        // we were doing a shim update, return immediately
1307f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        if (shimUpdateOnly) {
1308f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            auto cameraState = getCameraState(cameraId);
1309f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            if (cameraState != nullptr) {
1310f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                if (!cameraState->getShimParams().isEmpty()) return ret;
1311f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            }
1312f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        }
1313f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1314f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        status_t err;
1315f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1316f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        sp<BasicClient> clientTmp = nullptr;
1317f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>> partial;
1318f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        if ((err = handleEvictionsLocked(cameraId, originalClientPid, effectiveApiLevel,
1319f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                IInterface::asBinder(cameraCb), clientName8, /*out*/&clientTmp,
1320f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                /*out*/&partial)) != NO_ERROR) {
1321f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            switch (err) {
1322f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                case -ENODEV:
1323f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                    return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
1324f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            "No camera device with ID \"%s\" currently available",
1325f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            cameraId.string());
1326f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                case -EBUSY:
1327f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                    return STATUS_ERROR_FMT(ERROR_CAMERA_IN_USE,
1328f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            "Higher-priority client using camera, ID \"%s\" currently unavailable",
1329f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            cameraId.string());
1330f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                default:
1331f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                    return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
1332f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            "Unexpected error %s (%d) opening camera \"%s\"",
1333f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            strerror(-err), err, cameraId.string());
1334f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            }
1335f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        }
1336f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1337f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        if (clientTmp.get() != nullptr) {
1338f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            // Handle special case for API1 MediaRecorder where the existing client is returned
1339f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            device = static_cast<CLIENT*>(clientTmp.get());
1340f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            return ret;
1341f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        }
1342f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1343f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        // give flashlight a chance to close devices if necessary.
1344f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        mFlashlight->prepareDeviceOpen(cameraId);
1345f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1346f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        int facing = -1;
13472f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        int deviceVersion = getDeviceVersion(cameraId, /*out*/&facing);
13486963d0ad7b621dcdaa74cbfed17c776121635146Eino-Ville Talvala        if (facing == -1) {
13496963d0ad7b621dcdaa74cbfed17c776121635146Eino-Ville Talvala            ALOGE("%s: Unable to get camera device \"%s\"  facing", __FUNCTION__, cameraId.string());
13506963d0ad7b621dcdaa74cbfed17c776121635146Eino-Ville Talvala            return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
13516963d0ad7b621dcdaa74cbfed17c776121635146Eino-Ville Talvala                    "Unable to get camera device \"%s\" facing", cameraId.string());
13526963d0ad7b621dcdaa74cbfed17c776121635146Eino-Ville Talvala        }
13536963d0ad7b621dcdaa74cbfed17c776121635146Eino-Ville Talvala
1354f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        sp<BasicClient> tmp = nullptr;
1355c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        if(!(ret = makeClient(this, cameraCb, clientPackageName,
1356c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                cameraId, api1CameraId, facing,
1357c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                clientPid, clientUid, getpid(), legacyMode,
1358c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                halVersion, deviceVersion, effectiveApiLevel,
1359f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                /*out*/&tmp)).isOk()) {
1360f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            return ret;
1361f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        }
1362f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        client = static_cast<CLIENT*>(tmp.get());
1363f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1364f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        LOG_ALWAYS_FATAL_IF(client.get() == nullptr, "%s: CameraService in invalid state",
1365f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                __FUNCTION__);
1366f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1367f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev        err = client->initialize(mCameraProviderManager);
13682f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        if (err != OK) {
13692f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            ALOGE("%s: Could not initialize client from HAL.", __FUNCTION__);
1370f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            // Errors could be from the HAL module open call or from AppOpsManager
1371f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            switch(err) {
1372f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                case BAD_VALUE:
1373f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                    return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
1374f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            "Illegal argument to HAL module for camera \"%s\"", cameraId.string());
1375f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                case -EBUSY:
1376f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                    return STATUS_ERROR_FMT(ERROR_CAMERA_IN_USE,
1377f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            "Camera \"%s\" is already open", cameraId.string());
1378f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                case -EUSERS:
1379f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                    return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE,
1380f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            "Too many cameras already open, cannot open camera \"%s\"",
1381f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            cameraId.string());
1382f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                case PERMISSION_DENIED:
1383f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                    return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
1384f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            "No permission to open camera \"%s\"", cameraId.string());
1385f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                case -EACCES:
1386f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                    return STATUS_ERROR_FMT(ERROR_DISABLED,
1387f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            "Camera \"%s\" disabled by policy", cameraId.string());
1388f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                case -ENODEV:
1389f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                default:
1390f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                    return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
1391f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            "Failed to initialize camera \"%s\": %s (%d)", cameraId.string(),
1392f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            strerror(-err), err);
1393f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            }
1394f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        }
1395f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1396f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        // Update shim paremeters for legacy clients
1397f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        if (effectiveApiLevel == API_1) {
1398f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            // Assume we have always received a Client subclass for API1
1399f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            sp<Client> shimClient = reinterpret_cast<Client*>(client.get());
1400f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            String8 rawParams = shimClient->getParameters();
1401f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            CameraParameters params(rawParams);
1402f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1403f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            auto cameraState = getCameraState(cameraId);
1404f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            if (cameraState != nullptr) {
1405f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                cameraState->setShimParams(params);
1406f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            } else {
1407f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                ALOGE("%s: Cannot update shim parameters for camera %s, no such device exists.",
1408f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                        __FUNCTION__, cameraId.string());
1409f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            }
1410f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        }
1411f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1412f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        if (shimUpdateOnly) {
1413f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            // If only updating legacy shim parameters, immediately disconnect client
1414f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            mServiceLock.unlock();
1415f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            client->disconnect();
1416f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            mServiceLock.lock();
1417f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        } else {
1418f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            // Otherwise, add client to active clients list
1419f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            finishConnectLocked(client, partial);
1420f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        }
1421f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    } // lock is destroyed, allow further connect calls
1422f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1423f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    // Important: release the mutex here so the client can call back into the service from its
1424f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    // destructor (can be at the end of the call)
1425f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    device = client;
1426f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    return ret;
1427f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala}
1428f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1429d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::setTorchMode(const String16& cameraId, bool enabled,
14303068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen        const sp<IBinder>& clientBinder) {
14312f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    Mutex::Autolock lock(mServiceLock);
1432a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala
1433a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
143499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    if (enabled && clientBinder == nullptr) {
14353068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen        ALOGE("%s: torch client binder is NULL", __FUNCTION__);
1436d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT,
1437d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "Torch client Binder is null");
14383068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    }
14393068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
144088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    String8 id = String8(cameraId.string());
144199e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    int uid = getCallingUid();
144288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen
144388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    // verify id is valid.
1444cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    auto state = getCameraState(id);
1445cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    if (state == nullptr) {
1446f6463fc62a09b8aad8e811a9abbe9f4d9f2688f9Chien-Yu Chen        ALOGE("%s: camera id is invalid %s", __FUNCTION__, id.string());
1447d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
1448d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "Camera ID \"%s\" is a not valid camera ID", id.string());
1449cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
1450cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1451f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    StatusInternal cameraStatus = state->getStatus();
1452f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    if (cameraStatus != StatusInternal::PRESENT &&
145352778d448123c185fd30cd77e84659fab966d740Yin-Chia Yeh            cameraStatus != StatusInternal::NOT_AVAILABLE) {
145452778d448123c185fd30cd77e84659fab966d740Yin-Chia Yeh        ALOGE("%s: camera id is invalid %s, status %d", __FUNCTION__, id.string(), (int)cameraStatus);
1455d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
1456d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "Camera ID \"%s\" is a not valid camera ID", id.string());
145788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    }
145888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen
145988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    {
146088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen        Mutex::Autolock al(mTorchStatusMutex);
1461f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        TorchModeStatus status;
1462d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        status_t err = getTorchStatusLocked(id, &status);
1463d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        if (err != OK) {
1464d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            if (err == NAME_NOT_FOUND) {
1465d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
1466d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                        "Camera \"%s\" does not have a flash unit", id.string());
1467d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            }
146888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen            ALOGE("%s: getting current torch status failed for camera %s",
146988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen                    __FUNCTION__, id.string());
1470d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
1471d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    "Error updating torch status for camera \"%s\": %s (%d)", id.string(),
1472d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    strerror(-err), err);
147388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen        }
147488da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen
1475f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        if (status == TorchModeStatus::NOT_AVAILABLE) {
147652778d448123c185fd30cd77e84659fab966d740Yin-Chia Yeh            if (cameraStatus == StatusInternal::NOT_AVAILABLE) {
147788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen                ALOGE("%s: torch mode of camera %s is not available because "
147888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen                        "camera is in use", __FUNCTION__, id.string());
1479d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                return STATUS_ERROR_FMT(ERROR_CAMERA_IN_USE,
1480d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                        "Torch for camera \"%s\" is not available due to an existing camera user",
1481d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                        id.string());
148288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen            } else {
148388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen                ALOGE("%s: torch mode of camera %s is not available due to "
148488da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen                        "insufficient resources", __FUNCTION__, id.string());
1485d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE,
1486d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                        "Torch for camera \"%s\" is not available due to insufficient resources",
1487d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                        id.string());
148888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen            }
148988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen        }
149088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    }
149188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen
149299e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    {
149399e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        // Update UID map - this is used in the torch status changed callbacks, so must be done
149499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        // before setTorchMode
1495fe751bea0d3eedd6e817aebf4e457425b82e7117Chien-Yu Chen        Mutex::Autolock al(mTorchUidMapMutex);
149699e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        if (mTorchUidMap.find(id) == mTorchUidMap.end()) {
149799e69716215cd0665379bc90d708f2ea8689831dRuben Brunk            mTorchUidMap[id].first = uid;
149899e69716215cd0665379bc90d708f2ea8689831dRuben Brunk            mTorchUidMap[id].second = uid;
149999e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        } else {
150099e69716215cd0665379bc90d708f2ea8689831dRuben Brunk            // Set the pending UID
150199e69716215cd0665379bc90d708f2ea8689831dRuben Brunk            mTorchUidMap[id].first = uid;
150299e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        }
150399e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    }
150499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk
1505d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    status_t err = mFlashlight->setTorchMode(id, enabled);
150699e69716215cd0665379bc90d708f2ea8689831dRuben Brunk
1507d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (err != OK) {
1508d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        int32_t errorCode;
1509d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        String8 msg;
1510d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        switch (err) {
1511d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            case -ENOSYS:
1512d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                msg = String8::format("Camera \"%s\" has no flashlight",
1513d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    id.string());
1514d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                errorCode = ERROR_ILLEGAL_ARGUMENT;
1515d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                break;
1516d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            default:
1517d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                msg = String8::format(
1518d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    "Setting torch mode of camera \"%s\" to %d failed: %s (%d)",
1519d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    id.string(), enabled, strerror(-err), err);
1520d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                errorCode = ERROR_INVALID_OPERATION;
1521d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        }
1522d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        ALOGE("%s: %s", __FUNCTION__, msg.string());
1523d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(errorCode, msg.string());
15243068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    }
15253068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
152688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    {
152788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen        // update the link to client's death
152888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen        Mutex::Autolock al(mTorchClientMapMutex);
152988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen        ssize_t index = mTorchClientMap.indexOfKey(id);
153088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen        if (enabled) {
153188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen            if (index == NAME_NOT_FOUND) {
153288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen                mTorchClientMap.add(id, clientBinder);
153388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen            } else {
153499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                mTorchClientMap.valueAt(index)->unlinkToDeath(this);
153588da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen                mTorchClientMap.replaceValueAt(index, clientBinder);
153688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen            }
153788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen            clientBinder->linkToDeath(this);
153888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen        } else if (index != NAME_NOT_FOUND) {
153999e69716215cd0665379bc90d708f2ea8689831dRuben Brunk            mTorchClientMap.valueAt(index)->unlinkToDeath(this);
15403068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen        }
15413068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    }
15423068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
1543d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return Status::ok();
15443068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen}
15453068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
1546d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::notifySystemEvent(int32_t eventId,
1547d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        const std::vector<int32_t>& args) {
1548a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
1549a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala
155036597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    switch(eventId) {
1551d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        case ICameraService::EVENT_USER_SWITCHED: {
1552d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            doUserSwitch(/*newUserIds*/ args);
155336597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk            break;
155436597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk        }
1555d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        case ICameraService::EVENT_NONE:
155636597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk        default: {
155736597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk            ALOGW("%s: Received invalid system event from system_server: %d", __FUNCTION__,
155836597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk                    eventId);
155936597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk            break;
156036597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk        }
156136597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    }
1562d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return Status::ok();
156336597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk}
156436597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
1565f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville TalvalaStatus CameraService::addListener(const sp<ICameraServiceListener>& listener,
1566f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        /*out*/
1567f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        std::vector<hardware::CameraStatus> *cameraStatuses) {
1568a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
1569a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala
1570bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin    ALOGV("%s: Add listener %p", __FUNCTION__, listener.get());
1571634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
15723450ba7879be6522ea46a56c5e66e5382f5dd5baRuben Brunk    if (listener == nullptr) {
1573bd3e2e03f3ab686c52982a9e50cae853128172cfIgor Murashkin        ALOGE("%s: Listener must not be null", __FUNCTION__);
1574d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Null listener given to addListener");
1575bd3e2e03f3ab686c52982a9e50cae853128172cfIgor Murashkin    }
1576bd3e2e03f3ab686c52982a9e50cae853128172cfIgor Murashkin
1577bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin    Mutex::Autolock lock(mServiceLock);
1578bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
1579cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    {
1580cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        Mutex::Autolock lock(mStatusListenerLock);
1581cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        for (auto& it : mListenerList) {
1582cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            if (IInterface::asBinder(it) == IInterface::asBinder(listener)) {
1583cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                ALOGW("%s: Tried to add listener %p which was already subscribed",
1584cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                      __FUNCTION__, listener.get());
1585d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                return STATUS_ERROR(ERROR_ALREADY_EXISTS, "Listener already registered");
1586cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            }
1587bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin        }
1588cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1589cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        mListenerList.push_back(listener);
1590bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin    }
1591bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
1592f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    /* Collect current devices and status */
1593cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin    {
1594cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        Mutex::Autolock lock(mCameraStatesLock);
1595cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        for (auto& i : mCameraStates) {
1596f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            cameraStatuses->emplace_back(i.first, mapToInterface(i.second->getStatus()));
1597cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin        }
1598cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin    }
1599cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin
1600f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    /*
1601f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala     * Immediately signal current torch status to this listener only
1602f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala     * This may be a subset of all the devices, so don't include it in the response directly
1603f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala     */
16043068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    {
16053068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen        Mutex::Autolock al(mTorchStatusMutex);
16063068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen        for (size_t i = 0; i < mTorchStatusMap.size(); i++ ) {
160788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen            String16 id = String16(mTorchStatusMap.keyAt(i).string());
1608f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            listener->onTorchStatusChanged(mapToInterface(mTorchStatusMap.valueAt(i)), id);
16093068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen        }
16103068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    }
16113068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
1612d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return Status::ok();
1613bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin}
1614cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1615d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::removeListener(const sp<ICameraServiceListener>& listener) {
1616a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
1617a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala
1618bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin    ALOGV("%s: Remove listener %p", __FUNCTION__, listener.get());
1619bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
1620bd3e2e03f3ab686c52982a9e50cae853128172cfIgor Murashkin    if (listener == 0) {
1621bd3e2e03f3ab686c52982a9e50cae853128172cfIgor Murashkin        ALOGE("%s: Listener must not be null", __FUNCTION__);
1622d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Null listener given to removeListener");
1623bd3e2e03f3ab686c52982a9e50cae853128172cfIgor Murashkin    }
1624bd3e2e03f3ab686c52982a9e50cae853128172cfIgor Murashkin
1625bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin    Mutex::Autolock lock(mServiceLock);
1626bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
1627cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    {
1628cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        Mutex::Autolock lock(mStatusListenerLock);
1629cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        for (auto it = mListenerList.begin(); it != mListenerList.end(); it++) {
1630cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            if (IInterface::asBinder(*it) == IInterface::asBinder(listener)) {
1631cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                mListenerList.erase(it);
1632d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                return Status::ok();
1633cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            }
1634bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin        }
1635bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin    }
1636bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
1637bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin    ALOGW("%s: Tried to remove a listener %p which was not subscribed",
1638bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin          __FUNCTION__, listener.get());
1639bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
1640d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Unregistered listener given to removeListener");
164165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
164265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1643d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::getLegacyParameters(int cameraId, /*out*/String16* parameters) {
1644a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala
1645a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
164665d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    ALOGV("%s: for camera ID = %d", __FUNCTION__, cameraId);
164765d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
164865d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    if (parameters == NULL) {
164965d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin        ALOGE("%s: parameters must not be null", __FUNCTION__);
1650d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Parameters must not be null");
165165d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    }
165265d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
1653d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    Status ret = Status::ok();
165465d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
165565d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    CameraParameters shimParams;
1656d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (!(ret = getLegacyParametersLazy(cameraId, /*out*/&shimParams)).isOk()) {
165765d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin        // Error logged by caller
165865d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin        return ret;
165965d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    }
166065d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
166165d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    String8 shimParamsString8 = shimParams.flatten();
166265d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    String16 shimParamsString16 = String16(shimParamsString8);
166365d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
166465d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    *parameters = shimParamsString16;
166565d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
1666d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return ret;
166765d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin}
166865d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
1669f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville TalvalaStatus CameraService::supportsCameraApi(const String16& cameraId, int apiVersion,
1670f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        /*out*/ bool *isSupported) {
1671a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
1672a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala
16732f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    const String8 id = String8(cameraId);
16742f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
16752f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    ALOGV("%s: for camera ID = %s", __FUNCTION__, id.string());
167665d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
167765d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    switch (apiVersion) {
167865d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin        case API_VERSION_1:
167965d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin        case API_VERSION_2:
168065d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin            break;
168165d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin        default:
1682d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            String8 msg = String8::format("Unknown API version %d", apiVersion);
1683d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            ALOGE("%s: %s", __FUNCTION__, msg.string());
1684d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.string());
168565d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    }
168665d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
168728ad2eae9ac86df397b27d27fcc92d2c893138afEmilian Peev    int deviceVersion = getDeviceVersion(id);
168865d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    switch(deviceVersion) {
1689d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        case CAMERA_DEVICE_API_VERSION_1_0:
1690d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        case CAMERA_DEVICE_API_VERSION_3_0:
1691d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        case CAMERA_DEVICE_API_VERSION_3_1:
1692d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            if (apiVersion == API_VERSION_2) {
16932f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                ALOGV("%s: Camera id %s uses HAL version %d <3.2, doesn't support api2 without shim",
16942f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                        __FUNCTION__, id.string(), deviceVersion);
1695d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                *isSupported = false;
1696d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            } else { // if (apiVersion == API_VERSION_1) {
16972f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                ALOGV("%s: Camera id %s uses older HAL before 3.2, but api1 is always supported",
16982f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                        __FUNCTION__, id.string());
1699d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                *isSupported = true;
1700d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            }
1701d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            break;
1702d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        case CAMERA_DEVICE_API_VERSION_3_2:
1703d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        case CAMERA_DEVICE_API_VERSION_3_3:
17044afbdecf8c6dc5ad04f6fa6c8712ce2c56a00c47Zhijun He        case CAMERA_DEVICE_API_VERSION_3_4:
17052f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            ALOGV("%s: Camera id %s uses HAL3.2 or newer, supports api1/api2 directly",
17062f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                    __FUNCTION__, id.string());
1707d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            *isSupported = true;
1708d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            break;
1709d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        case -1: {
17102f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            String8 msg = String8::format("Unknown camera ID %s", id.string());
1711d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            ALOGE("%s: %s", __FUNCTION__, msg.string());
1712d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.string());
1713d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        }
1714d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        default: {
17152f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            String8 msg = String8::format("Unknown device version %x for device %s",
17162f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                    deviceVersion, id.string());
1717d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            ALOGE("%s: %s", __FUNCTION__, msg.string());
1718d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return STATUS_ERROR(ERROR_INVALID_OPERATION, msg.string());
1719d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        }
172065d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    }
172165d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
1722d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return Status::ok();
172365d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin}
172465d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
1725cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkvoid CameraService::removeByClient(const BasicClient* client) {
1726ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    Mutex::Autolock lock(mServiceLock);
1727cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    for (auto& i : mActiveClientManager.getAll()) {
1728cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        auto clientSp = i->getValue();
1729cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        if (clientSp.get() == client) {
1730cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            mActiveClientManager.remove(i);
1731634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        }
1732634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    }
1733634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
1734634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
1735cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkbool CameraService::evictClientIdByRemote(const wp<IBinder>& remote) {
1736cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    const int callingPid = getCallingPid();
1737cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    const int servicePid = getpid();
1738cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    bool ret = false;
1739cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    {
1740cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // Acquire mServiceLock and prevent other clients from connecting
1741cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        std::unique_ptr<AutoConditionLock> lock =
1742cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                AutoConditionLock::waitAndAcquire(mServiceLockWrapper);
1743634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
1744634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
1745cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        std::vector<sp<BasicClient>> evicted;
1746cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        for (auto& i : mActiveClientManager.getAll()) {
1747cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            auto clientSp = i->getValue();
1748cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            if (clientSp.get() == nullptr) {
1749cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                ALOGE("%s: Dead client still in mActiveClientManager.", __FUNCTION__);
1750cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                mActiveClientManager.remove(i);
1751cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                continue;
1752cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            }
1753cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            if (remote == clientSp->getRemote() && (callingPid == servicePid ||
1754cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    callingPid == clientSp->getClientPid())) {
1755cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                mActiveClientManager.remove(i);
1756cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                evicted.push_back(clientSp);
1757cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1758cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                // Notify the client of disconnection
1759d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                clientSp->notifyError(
1760d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                        hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED,
1761cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                        CaptureResultExtras());
1762634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin            }
1763634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        }
1764634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
1765cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // Do not hold mServiceLock while disconnecting clients, but retain the condition blocking
1766cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // other clients from connecting in mServiceLockWrapper if held
1767cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        mServiceLock.unlock();
1768ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
176936597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk        // Do not clear caller identity, remote caller should be client proccess
177036597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
1771cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        for (auto& i : evicted) {
1772cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            if (i.get() != nullptr) {
1773cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                i->disconnect();
1774cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                ret = true;
1775cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            }
1776cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        }
1777ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
1778cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // Reacquire mServiceLock
1779cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        mServiceLock.lock();
178065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1781cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    } // lock is destroyed, allow further connect calls
178265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1783cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return ret;
1784cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
178565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1786cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkstd::shared_ptr<CameraService::CameraState> CameraService::getCameraState(
1787cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        const String8& cameraId) const {
1788cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    std::shared_ptr<CameraState> state;
1789cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    {
1790cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        Mutex::Autolock lock(mCameraStatesLock);
1791cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        auto iter = mCameraStates.find(cameraId);
1792cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        if (iter != mCameraStates.end()) {
1793cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            state = iter->second;
179465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
179565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
1796cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return state;
179765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
179865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1799cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunksp<CameraService::BasicClient> CameraService::removeClientLocked(const String8& cameraId) {
1800cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    // Remove from active clients list
1801cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    auto clientDescriptorPtr = mActiveClientManager.remove(cameraId);
1802cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    if (clientDescriptorPtr == nullptr) {
1803cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        ALOGW("%s: Could not evict client, no client for camera ID %s", __FUNCTION__,
1804cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                cameraId.string());
1805cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        return sp<BasicClient>{nullptr};
1806cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
1807d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park
1808cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return clientDescriptorPtr->getValue();
180965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
181065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1811d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvalavoid CameraService::doUserSwitch(const std::vector<int32_t>& newUserIds) {
181236597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    // Acquire mServiceLock and prevent other clients from connecting
181336597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    std::unique_ptr<AutoConditionLock> lock =
181436597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk            AutoConditionLock::waitAndAcquire(mServiceLockWrapper);
181536597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
18166267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk    std::set<userid_t> newAllowedUsers;
1817d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    for (size_t i = 0; i < newUserIds.size(); i++) {
1818d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        if (newUserIds[i] < 0) {
18196267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk            ALOGE("%s: Bad user ID %d given during user switch, ignoring.",
1820d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    __FUNCTION__, newUserIds[i]);
18216267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk            return;
18226267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        }
1823d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        newAllowedUsers.insert(static_cast<userid_t>(newUserIds[i]));
18246267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk    }
18256267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk
18266267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk
18276267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk    if (newAllowedUsers == mAllowedUsers) {
18286267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        ALOGW("%s: Received notification of user switch with no updated user IDs.", __FUNCTION__);
18296267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        return;
183036597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    }
183136597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
18326267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk    logUserSwitch(mAllowedUsers, newAllowedUsers);
1833a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk
18346267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk    mAllowedUsers = std::move(newAllowedUsers);
183536597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
183636597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    // Current user has switched, evict all current clients.
183736597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    std::vector<sp<BasicClient>> evicted;
183836597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    for (auto& i : mActiveClientManager.getAll()) {
183936597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk        auto clientSp = i->getValue();
184036597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
184136597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk        if (clientSp.get() == nullptr) {
184236597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk            ALOGE("%s: Dead client still in mActiveClientManager.", __FUNCTION__);
184336597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk            continue;
184436597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk        }
184536597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
18466267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        // Don't evict clients that are still allowed.
18476267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        uid_t clientUid = clientSp->getClientUid();
18486267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        userid_t clientUserId = multiuser_get_user_id(clientUid);
18496267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        if (mAllowedUsers.find(clientUserId) != mAllowedUsers.end()) {
18506267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk            continue;
18516267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        }
18526267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk
185336597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk        evicted.push_back(clientSp);
185436597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
185536597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk        String8 curTime = getFormattedCurrentTime();
185636597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
185736597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk        ALOGE("Evicting conflicting client for camera ID %s due to user change",
185836597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk                i->getKey().string());
1859a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk
186036597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk        // Log the clients evicted
1861a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk        logEvent(String8::format("EVICT device %s client held by package %s (PID %"
18628131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                PRId32 ", score %" PRId32 ", state %" PRId32 ")\n   - Evicted due"
18638131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                " to user switch.", i->getKey().string(),
18648131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                String8{clientSp->getPackageName()}.string(),
18658131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                i->getOwnerId(), i->getPriority().getScore(),
18668131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                i->getPriority().getState()));
186736597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
186836597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    }
186936597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
187036597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    // Do not hold mServiceLock while disconnecting clients, but retain the condition
187136597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    // blocking other clients from connecting in mServiceLockWrapper if held.
187236597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    mServiceLock.unlock();
187336597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
187436597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    // Clear caller identity temporarily so client disconnect PID checks work correctly
187536597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    int64_t token = IPCThreadState::self()->clearCallingIdentity();
187636597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
187736597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    for (auto& i : evicted) {
187836597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk        i->disconnect();
187936597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    }
188036597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
188136597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    IPCThreadState::self()->restoreCallingIdentity(token);
188236597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
188336597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    // Reacquire mServiceLock
188436597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    mServiceLock.lock();
188536597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk}
1886ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
1887a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunkvoid CameraService::logEvent(const char* event) {
1888cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    String8 curTime = getFormattedCurrentTime();
1889a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    Mutex::Autolock l(mLogLock);
1890a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    mEventLog.add(String8::format("%s : %s", curTime.string(), event));
1891cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
1892ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
1893a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunkvoid CameraService::logDisconnected(const char* cameraId, int clientPid,
1894280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov        const char* clientPackage) {
1895a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    // Log the clients evicted
1896a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    logEvent(String8::format("DISCONNECT device %s client for package %s (PID %d)", cameraId,
1897280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov            clientPackage, clientPid));
1898a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk}
1899ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
1900a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunkvoid CameraService::logConnected(const char* cameraId, int clientPid,
1901280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov        const char* clientPackage) {
1902cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    // Log the clients evicted
1903a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    logEvent(String8::format("CONNECT device %s client for package %s (PID %d)", cameraId,
1904280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov            clientPackage, clientPid));
1905a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk}
1906a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk
1907a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunkvoid CameraService::logRejected(const char* cameraId, int clientPid,
1908280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov        const char* clientPackage, const char* reason) {
1909a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    // Log the client rejected
1910a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    logEvent(String8::format("REJECT device %s client for package %s (PID %d), reason: (%s)",
1911280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov            cameraId, clientPackage, clientPid, reason));
1912a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk}
1913a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk
19146267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunkvoid CameraService::logUserSwitch(const std::set<userid_t>& oldUserIds,
19156267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        const std::set<userid_t>& newUserIds) {
19166267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk    String8 newUsers = toString(newUserIds);
19176267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk    String8 oldUsers = toString(oldUserIds);
1918d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala    if (oldUsers.size() == 0) {
1919d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        oldUsers = "<None>";
1920d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala    }
1921a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    // Log the new and old users
1922d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala    logEvent(String8::format("USER_SWITCH previous allowed user IDs: %s, current allowed user IDs: %s",
19236267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk            oldUsers.string(), newUsers.string()));
1924a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk}
1925a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk
1926a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunkvoid CameraService::logDeviceRemoved(const char* cameraId, const char* reason) {
1927a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    // Log the device removal
1928a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    logEvent(String8::format("REMOVE device %s, reason: (%s)", cameraId, reason));
1929a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk}
1930a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk
1931a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunkvoid CameraService::logDeviceAdded(const char* cameraId, const char* reason) {
1932a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    // Log the device removal
1933a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    logEvent(String8::format("ADD device %s, reason: (%s)", cameraId, reason));
1934a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk}
1935a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk
1936a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunkvoid CameraService::logClientDied(int clientPid, const char* reason) {
1937a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    // Log the device removal
1938a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    logEvent(String8::format("DIED client(s) with PID %d, reason: (%s)", clientPid, reason));
1939ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin}
1940ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
19411527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvalavoid CameraService::logServiceError(const char* msg, int errorCode) {
19421527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvala    String8 curTime = getFormattedCurrentTime();
1943d309fb9c8a2c4564d88fffba19c4e3688e4b862bEino-Ville Talvala    logEvent(String8::format("SERVICE ERROR: %s : %d (%s)", msg, errorCode, strerror(-errorCode)));
19441527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvala}
19451527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvala
194636597b241c59eba7e55d5150092947a748c5e9cbRuben Brunkstatus_t CameraService::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
194736597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk        uint32_t flags) {
194836597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
194936597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    const int pid = getCallingPid();
195036597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    const int selfPid = getpid();
195136597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
195265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // Permission checks
195365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    switch (code) {
1954a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        case SHELL_COMMAND_TRANSACTION: {
1955a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            int in = data.readFileDescriptor();
1956a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            int out = data.readFileDescriptor();
1957a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            int err = data.readFileDescriptor();
1958a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            int argc = data.readInt32();
1959a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            Vector<String16> args;
1960a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
1961a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov               args.add(data.readString16());
1962a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            }
1963a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            sp<IBinder> unusedCallback;
1964a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            sp<IResultReceiver> resultReceiver;
1965a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            status_t status;
1966a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            if ((status = data.readNullableStrongBinder(&unusedCallback)) != NO_ERROR) {
1967a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov                return status;
1968a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            }
1969a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            if ((status = data.readNullableStrongBinder(&resultReceiver)) != NO_ERROR) {
1970a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov                return status;
1971a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            }
1972a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            status = shellCommand(in, out, err, args);
1973a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            if (resultReceiver != nullptr) {
1974a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov                resultReceiver->send(status);
1975a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            }
1976a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            return NO_ERROR;
1977a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        }
1978d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        case BnCameraService::NOTIFYSYSTEMEVENT: {
197936597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk            if (pid != selfPid) {
198036597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk                // Ensure we're being called by system_server, or similar process with
198136597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk                // permissions to notify the camera service about system events
198236597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk                if (!checkCallingPermission(
198336597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk                        String16("android.permission.CAMERA_SEND_SYSTEM_EVENTS"))) {
198436597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk                    const int uid = getCallingUid();
198536597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk                    ALOGE("Permission Denial: cannot send updates to camera service about system"
198636597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk                            " events from pid=%d, uid=%d", pid, uid);
198736597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk                    return PERMISSION_DENIED;
198836597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk                }
198936597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk            }
199036597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk            break;
199136597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk        }
199265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
199365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
199465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return BnCameraService::onTransact(code, data, reply, flags);
199565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
199665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
199765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// We share the media players for shutter and recording sound for all clients.
199865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// A reference count is kept to determine when we will actually release the
199965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// media players.
200065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2001ff4f55c8d77e276dbcceedb4e560ca1d91ba38baChih-Chung ChangMediaPlayer* CameraService::newMediaPlayer(const char *file) {
200265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    MediaPlayer* mp = new MediaPlayer();
20031b86fe063badb5f28c467ade39be0f4008688947Andreas Huber    if (mp->setDataSource(NULL /* httpService */, file, NULL) == NO_ERROR) {
200460a78ac9535878984b0777788760b9ee7465c5e6Eino-Ville Talvala        mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE);
200565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mp->prepare();
200665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
200729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to load CameraService sounds: %s", file);
200859a8ef0135bab204ed027625011a1f55d99a694dJaekyun Seok        delete mp;
200959a8ef0135bab204ed027625011a1f55d99a694dJaekyun Seok        return nullptr;
201065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
201165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return mp;
201265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
201365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
201465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::loadSound() {
2015a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
2016a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala
201765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mSoundLock);
201865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("CameraService::loadSound ref=%d", mSoundRef);
201965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mSoundRef++) return;
202065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
202159a8ef0135bab204ed027625011a1f55d99a694dJaekyun Seok    mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/product/media/audio/ui/camera_click.ogg");
202259a8ef0135bab204ed027625011a1f55d99a694dJaekyun Seok    if (mSoundPlayer[SOUND_SHUTTER] == nullptr) {
202359a8ef0135bab204ed027625011a1f55d99a694dJaekyun Seok        mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
202459a8ef0135bab204ed027625011a1f55d99a694dJaekyun Seok    }
202559a8ef0135bab204ed027625011a1f55d99a694dJaekyun Seok    mSoundPlayer[SOUND_RECORDING_START] = newMediaPlayer("/product/media/audio/ui/VideoRecord.ogg");
202659a8ef0135bab204ed027625011a1f55d99a694dJaekyun Seok    if (mSoundPlayer[SOUND_RECORDING_START] == nullptr) {
202759a8ef0135bab204ed027625011a1f55d99a694dJaekyun Seok        mSoundPlayer[SOUND_RECORDING_START] =
202859a8ef0135bab204ed027625011a1f55d99a694dJaekyun Seok                newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");
202959a8ef0135bab204ed027625011a1f55d99a694dJaekyun Seok    }
203059a8ef0135bab204ed027625011a1f55d99a694dJaekyun Seok    mSoundPlayer[SOUND_RECORDING_STOP] = newMediaPlayer("/product/media/audio/ui/VideoStop.ogg");
203159a8ef0135bab204ed027625011a1f55d99a694dJaekyun Seok    if (mSoundPlayer[SOUND_RECORDING_STOP] == nullptr) {
203259a8ef0135bab204ed027625011a1f55d99a694dJaekyun Seok        mSoundPlayer[SOUND_RECORDING_STOP] = newMediaPlayer("/system/media/audio/ui/VideoStop.ogg");
203359a8ef0135bab204ed027625011a1f55d99a694dJaekyun Seok    }
203465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
203565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
203665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::releaseSound() {
203765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mSoundLock);
203865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("CameraService::releaseSound ref=%d", mSoundRef);
203965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (--mSoundRef) return;
204065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
204165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (int i = 0; i < NUM_SOUNDS; i++) {
204265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mSoundPlayer[i] != 0) {
204365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mSoundPlayer[i]->disconnect();
204465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mSoundPlayer[i].clear();
204565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
204665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
204765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
204865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
204965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::playSound(sound_kind kind) {
2050a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
2051a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala
205265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("playSound(%d)", kind);
205365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mSoundLock);
205465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<MediaPlayer> player = mSoundPlayer[kind];
205565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (player != 0) {
20568888a75f01d904541e409e858d23e4150ace34b6Chih-Chung Chang        player->seekTo(0);
20578888a75f01d904541e409e858d23e4150ace34b6Chih-Chung Chang        player->start();
205865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
205965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
206065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
206165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
206265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
206365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianCameraService::Client::Client(const sp<CameraService>& cameraService,
2064b7a67942823e8339eb298238f117aaa6d7b63111Wu-cheng Li        const sp<ICameraClient>& cameraClient,
2065280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov        const String16& clientPackageName,
2066c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        const String8& cameraIdStr,
2067c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        int api1CameraId, int cameraFacing,
2068ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        int clientPid, uid_t clientUid,
2069ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        int servicePid) :
2070e992e75053e98e3699af6e344c11b787e30411adEino-Ville Talvala        CameraService::BasicClient(cameraService,
2071f888020c6e2735624f2b2a30e72aca24e17b8b4dMarco Nelissen                IInterface::asBinder(cameraClient),
2072280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov                clientPackageName,
20732f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                cameraIdStr, cameraFacing,
2074ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala                clientPid, clientUid,
20752f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                servicePid),
2076c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        mCameraId(api1CameraId)
2077634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin{
207865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int callingPid = getCallingPid();
20792f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    LOG1("Client::Client E (pid %d, id %d)", callingPid, mCameraId);
208065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
208144cfcf00b9008c1c04f4c8277c6c06af039fd976Igor Murashkin    mRemoteCallback = cameraClient;
20825e08d60617fc63c2e41f9069ff89f5c00db2617dEino-Ville Talvala
208365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    cameraService->loadSound();
2084ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
20852f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    LOG1("Client::Client X (pid %d, id %d)", callingPid, mCameraId);
208665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
208765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
208865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// tear down the client
208965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianCameraService::Client::~Client() {
2090d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    ALOGV("~Client");
2091634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    mDestructionStarted = true;
2092634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
20932f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    sCameraService->releaseSound();
2094036bc3e2cfc5a11c3f7ace41088c8936dae2e946Igor Murashkin    // unconditionally disconnect. function is idempotent
2095036bc3e2cfc5a11c3f7ace41088c8936dae2e946Igor Murashkin    Client::disconnect();
209665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
209765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
20982f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalasp<CameraService> CameraService::BasicClient::BasicClient::sCameraService;
20992f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
2100634a51509ee50475f3e9f8ccf897e90fc72ded31Igor MurashkinCameraService::BasicClient::BasicClient(const sp<CameraService>& cameraService,
2101ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        const sp<IBinder>& remoteCallback,
2102280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov        const String16& clientPackageName,
21032f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        const String8& cameraIdStr, int cameraFacing,
2104ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        int clientPid, uid_t clientUid,
2105ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        int servicePid):
21062f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        mCameraIdStr(cameraIdStr), mCameraFacing(cameraFacing),
21072f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        mClientPackageName(clientPackageName), mClientPid(clientPid), mClientUid(clientUid),
21082f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        mServicePid(servicePid),
21092f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        mDisconnected(false),
21102f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        mRemoteBinder(remoteCallback)
2111634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin{
21122f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (sCameraService == nullptr) {
21132f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        sCameraService = cameraService;
21142f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
2115ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    mOpsActive = false;
2116634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    mDestructionStarted = false;
21170dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
21180dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    // In some cases the calling code has no access to the package it runs under.
21190dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    // For example, NDK camera API.
21200dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    // In this case we will get the packages for the calling UID and pick the first one
21210dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    // for attributing the app op. This will work correctly for runtime permissions
21220dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    // as for legacy apps we will toggle the app op for all packages in the UID.
21230dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    // The caveat is that the operation may be attributed to the wrong package and
21240dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    // stats based on app ops may be slightly off.
21250dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    if (mClientPackageName.size() <= 0) {
21260dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        sp<IServiceManager> sm = defaultServiceManager();
21270dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        sp<IBinder> binder = sm->getService(String16(kPermissionServiceName));
21280dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        if (binder == 0) {
21290dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            ALOGE("Cannot get permission service");
21300dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            // Leave mClientPackageName unchanged (empty) and the further interaction
21310dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            // with camera will fail in BasicClient::startCameraOps
21320dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            return;
21330dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        }
21340dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
21350dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        sp<IPermissionController> permCtrl = interface_cast<IPermissionController>(binder);
21360dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        Vector<String16> packages;
21370dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
21380dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        permCtrl->getPackagesForUid(mClientUid, packages);
21390dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
21400dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        if (packages.isEmpty()) {
21410dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            ALOGE("No packages for calling UID");
21420dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            // Leave mClientPackageName unchanged (empty) and the further interaction
21430dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            // with camera will fail in BasicClient::startCameraOps
21440dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            return;
21450dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        }
21460dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        mClientPackageName = packages[0];
21470dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    }
2148634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
2149634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
2150634a51509ee50475f3e9f8ccf897e90fc72ded31Igor MurashkinCameraService::BasicClient::~BasicClient() {
2151d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    ALOGV("~BasicClient");
2152634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    mDestructionStarted = true;
2153634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
2154634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
2155d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvalabinder::Status CameraService::BasicClient::disconnect() {
2156d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    binder::Status res = Status::ok();
215736597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    if (mDisconnected) {
2158d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return res;
215936597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    }
216024901c86e10a0923fe10f5e9bce5e6dba061a289Eino-Ville Talvala    mDisconnected = true;
2161cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
21622f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    sCameraService->removeByClient(this);
21632f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    sCameraService->logDisconnected(mCameraIdStr, mClientPid,
2164280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov            String8(mClientPackageName));
2165cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2166cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    sp<IBinder> remote = getRemote();
2167cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    if (remote != nullptr) {
21682f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        remote->unlinkToDeath(sCameraService);
2169cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
2170f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala
2171f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala    finishCameraOps();
2172e4fe21bb7cef893cd38bd194ea880333389aea38Chien-Yu Chen    // Notify flashlight that a camera device is closed.
21732f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    sCameraService->mFlashlight->deviceClosed(mCameraIdStr);
21742f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    ALOGI("%s: Disconnected client for camera %s for PID %d", __FUNCTION__, mCameraIdStr.string(),
21752f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            mClientPid);
2176cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2177cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin    // client shouldn't be able to call into us anymore
2178cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin    mClientPid = 0;
2179d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala
2180d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return res;
2181634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
2182634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
2183c4003965258404a19b99280ac0f475e2f290bf27Eino-Ville Talvalastatus_t CameraService::BasicClient::dump(int, const Vector<String16>&) {
2184c4003965258404a19b99280ac0f475e2f290bf27Eino-Ville Talvala    // No dumping of clients directly over Binder,
2185c4003965258404a19b99280ac0f475e2f290bf27Eino-Ville Talvala    // must go through CameraService::dump
2186c4003965258404a19b99280ac0f475e2f290bf27Eino-Ville Talvala    android_errorWriteWithInfoLog(SN_EVENT_LOG_ID, "26265403",
2187c4003965258404a19b99280ac0f475e2f290bf27Eino-Ville Talvala            IPCThreadState::self()->getCallingUid(), NULL, 0);
2188c4003965258404a19b99280ac0f475e2f290bf27Eino-Ville Talvala    return OK;
2189c4003965258404a19b99280ac0f475e2f290bf27Eino-Ville Talvala}
2190c4003965258404a19b99280ac0f475e2f290bf27Eino-Ville Talvala
2191cc776718c0be7c31fe5ab4fc1446d377be60369fRuben BrunkString16 CameraService::BasicClient::getPackageName() const {
2192280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov    return mClientPackageName;
2193cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
2194cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2195cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2196cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkint CameraService::BasicClient::getClientPid() const {
2197cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return mClientPid;
2198cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
2199cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
22006267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunkuid_t CameraService::BasicClient::getClientUid() const {
22016267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk    return mClientUid;
22026267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk}
22036267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk
22040bbf8b213ad96051357e3ad6d6d2808bfa31a59aRuben Brunkbool CameraService::BasicClient::canCastToApiClient(apiLevel level) const {
22050bbf8b213ad96051357e3ad6d6d2808bfa31a59aRuben Brunk    // Defaults to API2.
22060bbf8b213ad96051357e3ad6d6d2808bfa31a59aRuben Brunk    return level == API_2;
22070bbf8b213ad96051357e3ad6d6d2808bfa31a59aRuben Brunk}
22080bbf8b213ad96051357e3ad6d6d2808bfa31a59aRuben Brunk
2209ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvalastatus_t CameraService::BasicClient::startCameraOps() {
2210a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
2211a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala
2212ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    int32_t res;
2213f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala    // Notify app ops that the camera is not available
2214ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    mOpsCallback = new OpsCallback(this);
2215ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
2216e6800cea0678dbc0bf697b44c3e4548b0253085cIgor Murashkin    {
2217e6800cea0678dbc0bf697b44c3e4548b0253085cIgor Murashkin        ALOGV("%s: Start camera ops, package name = %s, client UID = %d",
2218280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov              __FUNCTION__, String8(mClientPackageName).string(), mClientUid);
2219e6800cea0678dbc0bf697b44c3e4548b0253085cIgor Murashkin    }
2220e6800cea0678dbc0bf697b44c3e4548b0253085cIgor Murashkin
2221ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    mAppOpsManager.startWatchingMode(AppOpsManager::OP_CAMERA,
2222280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov            mClientPackageName, mOpsCallback);
2223ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    res = mAppOpsManager.startOp(AppOpsManager::OP_CAMERA,
2224280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov            mClientUid, mClientPackageName);
2225ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
222628e8ef72dab287af59663b89b12507e43f760701Svetoslav    if (res == AppOpsManager::MODE_ERRORED) {
22272f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        ALOGI("Camera %s: Access for \"%s\" has been revoked",
22282f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                mCameraIdStr.string(), String8(mClientPackageName).string());
2229ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        return PERMISSION_DENIED;
2230ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    }
2231f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala
223228e8ef72dab287af59663b89b12507e43f760701Svetoslav    if (res == AppOpsManager::MODE_IGNORED) {
22332f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        ALOGI("Camera %s: Access for \"%s\" has been restricted",
22342f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                mCameraIdStr.string(), String8(mClientPackageName).string());
2235e3afb2cc438b76ae433c8c40ceabf0457ad7a678Eino-Ville Talvala        // Return the same error as for device policy manager rejection
2236e3afb2cc438b76ae433c8c40ceabf0457ad7a678Eino-Ville Talvala        return -EACCES;
223728e8ef72dab287af59663b89b12507e43f760701Svetoslav    }
223828e8ef72dab287af59663b89b12507e43f760701Svetoslav
2239ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    mOpsActive = true;
2240f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala
2241f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala    // Transition device availability listeners from PRESENT -> NOT_AVAILABLE
22422f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    sCameraService->updateStatus(StatusInternal::NOT_AVAILABLE, mCameraIdStr);
2243f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala
2244573291c251d9e85f51f7c0fa1cb35baa2969ca17Emilian Peev    int apiLevel = hardware::ICameraServiceProxy::CAMERA_API_LEVEL_1;
2245573291c251d9e85f51f7c0fa1cb35baa2969ca17Emilian Peev    if (canCastToApiClient(API_2)) {
2246573291c251d9e85f51f7c0fa1cb35baa2969ca17Emilian Peev        apiLevel = hardware::ICameraServiceProxy::CAMERA_API_LEVEL_2;
2247573291c251d9e85f51f7c0fa1cb35baa2969ca17Emilian Peev    }
2248412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala    // Transition device state to OPEN
22492f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    sCameraService->updateProxyDeviceState(ICameraServiceProxy::CAMERA_STATE_OPEN,
2250573291c251d9e85f51f7c0fa1cb35baa2969ca17Emilian Peev            mCameraIdStr, mCameraFacing, mClientPackageName, apiLevel);
2251412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala
2252ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    return OK;
2253ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala}
2254ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
2255ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvalastatus_t CameraService::BasicClient::finishCameraOps() {
2256a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
2257a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala
2258f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala    // Check if startCameraOps succeeded, and if so, finish the camera op
2259ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    if (mOpsActive) {
2260f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala        // Notify app ops that the camera is available again
2261ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        mAppOpsManager.finishOp(AppOpsManager::OP_CAMERA, mClientUid,
2262280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov                mClientPackageName);
2263ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        mOpsActive = false;
2264f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala
2265151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski        // This function is called when a client disconnects. This should
2266151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski        // release the camera, but actually only if it was in a proper
2267151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski        // functional state, i.e. with status NOT_AVAILABLE
2268f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        std::initializer_list<StatusInternal> rejected = {StatusInternal::PRESENT,
2269151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski                StatusInternal::ENUMERATING, StatusInternal::NOT_PRESENT};
2270f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala
2271cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // Transition to PRESENT if the camera is not in either of the rejected states
22722f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        sCameraService->updateStatus(StatusInternal::PRESENT,
22732f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                mCameraIdStr, rejected);
2274f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala
2275573291c251d9e85f51f7c0fa1cb35baa2969ca17Emilian Peev        int apiLevel = hardware::ICameraServiceProxy::CAMERA_API_LEVEL_1;
2276573291c251d9e85f51f7c0fa1cb35baa2969ca17Emilian Peev        if (canCastToApiClient(API_2)) {
2277573291c251d9e85f51f7c0fa1cb35baa2969ca17Emilian Peev            apiLevel = hardware::ICameraServiceProxy::CAMERA_API_LEVEL_2;
2278573291c251d9e85f51f7c0fa1cb35baa2969ca17Emilian Peev        }
2279412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala        // Transition device state to CLOSED
22802f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        sCameraService->updateProxyDeviceState(ICameraServiceProxy::CAMERA_STATE_CLOSED,
2281573291c251d9e85f51f7c0fa1cb35baa2969ca17Emilian Peev                mCameraIdStr, mCameraFacing, mClientPackageName, apiLevel);
2282ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    }
2283f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala    // Always stop watching, even if no camera op is active
2284e992e75053e98e3699af6e344c11b787e30411adEino-Ville Talvala    if (mOpsCallback != NULL) {
2285e992e75053e98e3699af6e344c11b787e30411adEino-Ville Talvala        mAppOpsManager.stopWatchingMode(mOpsCallback);
2286e992e75053e98e3699af6e344c11b787e30411adEino-Ville Talvala    }
2287ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    mOpsCallback.clear();
2288ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
2289ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    return OK;
2290ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala}
2291ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
2292ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvalavoid CameraService::BasicClient::opChanged(int32_t op, const String16& packageName) {
2293a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
2294a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala
2295ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    String8 name(packageName);
2296280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov    String8 myName(mClientPackageName);
2297ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
2298ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    if (op != AppOpsManager::OP_CAMERA) {
2299ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        ALOGW("Unexpected app ops notification received: %d", op);
2300ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        return;
2301ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    }
2302ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
2303ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    int32_t res;
2304ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    res = mAppOpsManager.checkOp(AppOpsManager::OP_CAMERA,
2305280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov            mClientUid, mClientPackageName);
2306ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    ALOGV("checkOp returns: %d, %s ", res,
2307ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala            res == AppOpsManager::MODE_ALLOWED ? "ALLOWED" :
2308ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala            res == AppOpsManager::MODE_IGNORED ? "IGNORED" :
2309ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala            res == AppOpsManager::MODE_ERRORED ? "ERRORED" :
2310ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala            "UNKNOWN");
2311ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
2312ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    if (res != AppOpsManager::MODE_ALLOWED) {
23132f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        ALOGI("Camera %s: Access for \"%s\" revoked", mCameraIdStr.string(),
2314ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala                myName.string());
2315a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        block();
2316ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    }
2317ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala}
2318ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
2319a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganovvoid CameraService::BasicClient::block() {
2320a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    ATRACE_CALL();
2321a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
2322a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    // Reset the client PID to allow server-initiated disconnect,
2323a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    // and to prevent further calls by client.
2324a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    mClientPid = getCallingPid();
2325a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    CaptureResultExtras resultExtras; // a dummy result (invalid)
2326a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    notifyError(hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISABLED, resultExtras);
2327a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    disconnect();
2328a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
2329a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
233065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
233165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2332d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvalavoid CameraService::Client::notifyError(int32_t errorCode,
2333cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei        const CaptureResultExtras& resultExtras) {
2334d309fb9c8a2c4564d88fffba19c4e3688e4b862bEino-Ville Talvala    (void) errorCode;
2335d309fb9c8a2c4564d88fffba19c4e3688e4b862bEino-Ville Talvala    (void) resultExtras;
23363e600894685b994849d59307721c6862ae0c45b7Ranjith Kagathi Ananda    if (mRemoteCallback != NULL) {
23373e600894685b994849d59307721c6862ae0c45b7Ranjith Kagathi Ananda        mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_RELEASED, 0);
23383e600894685b994849d59307721c6862ae0c45b7Ranjith Kagathi Ananda    } else {
23393e600894685b994849d59307721c6862ae0c45b7Ranjith Kagathi Ananda        ALOGE("mRemoteCallback is NULL!!");
23403e600894685b994849d59307721c6862ae0c45b7Ranjith Kagathi Ananda    }
2341ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala}
2342ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
2343036bc3e2cfc5a11c3f7ace41088c8936dae2e946Igor Murashkin// NOTE: function is idempotent
2344d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvalabinder::Status CameraService::Client::disconnect() {
2345d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    ALOGV("Client::disconnect");
2346d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return BasicClient::disconnect();
2347e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li}
2348e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li
23490bbf8b213ad96051357e3ad6d6d2808bfa31a59aRuben Brunkbool CameraService::Client::canCastToApiClient(apiLevel level) const {
23500bbf8b213ad96051357e3ad6d6d2808bfa31a59aRuben Brunk    return level == API_1;
23510bbf8b213ad96051357e3ad6d6d2808bfa31a59aRuben Brunk}
23520bbf8b213ad96051357e3ad6d6d2808bfa31a59aRuben Brunk
2353ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville TalvalaCameraService::Client::OpsCallback::OpsCallback(wp<BasicClient> client):
2354ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        mClient(client) {
2355ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala}
2356ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
2357ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvalavoid CameraService::Client::OpsCallback::opChanged(int32_t op,
2358ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        const String16& packageName) {
2359ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    sp<BasicClient> client = mClient.promote();
2360ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    if (client != NULL) {
2361ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        client->opChanged(op, packageName);
2362ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    }
2363ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala}
2364ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
236565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
2366a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov//                  UidPolicy
2367a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov// ----------------------------------------------------------------------------
2368a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
2369a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganovvoid CameraService::UidPolicy::registerSelf() {
2370a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    ActivityManager am;
2371a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    am.registerUidObserver(this, ActivityManager::UID_OBSERVER_GONE
2372a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            | ActivityManager::UID_OBSERVER_IDLE
2373a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            | ActivityManager::UID_OBSERVER_ACTIVE,
2374a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            ActivityManager::PROCESS_STATE_UNKNOWN,
2375a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            String16("cameraserver"));
2376a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
2377a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
2378a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganovvoid CameraService::UidPolicy::unregisterSelf() {
2379a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    ActivityManager am;
2380a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    am.unregisterUidObserver(this);
2381a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
2382a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
2383a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganovvoid CameraService::UidPolicy::onUidGone(uid_t uid, bool disabled) {
2384a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    onUidIdle(uid, disabled);
2385a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
2386a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
2387a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganovvoid CameraService::UidPolicy::onUidActive(uid_t uid) {
2388a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    Mutex::Autolock _l(mUidLock);
2389a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    mActiveUids.insert(uid);
2390a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
2391a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
2392a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganovvoid CameraService::UidPolicy::onUidIdle(uid_t uid, bool /* disabled */) {
2393a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    bool deleted = false;
2394a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    {
2395a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        Mutex::Autolock _l(mUidLock);
2396a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        if (mActiveUids.erase(uid) > 0) {
2397a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            deleted = true;
2398a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        }
2399a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
2400a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    if (deleted) {
2401a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        sp<CameraService> service = mService.promote();
2402a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        if (service != nullptr) {
2403a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            service->blockClientsForUid(uid);
2404a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        }
2405a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
2406a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
2407a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
2408a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganovbool CameraService::UidPolicy::isUidActive(uid_t uid) {
2409a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    // Non-app UIDs are considered always active
2410a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    if (uid < FIRST_APPLICATION_UID) {
2411a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        return true;
2412a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
2413a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    Mutex::Autolock _l(mUidLock);
2414a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    return isUidActiveLocked(uid);
2415a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
2416a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
2417a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganovbool CameraService::UidPolicy::isUidActiveLocked(uid_t uid) {
2418a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    // Non-app UIDs are considered always active
2419a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    if (uid < FIRST_APPLICATION_UID) {
2420a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        return true;
2421a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
2422a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    auto it = mOverrideUids.find(uid);
2423a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    if (it != mOverrideUids.end()) {
2424a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        return it->second;
2425a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
2426a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    return mActiveUids.find(uid) != mActiveUids.end();
2427a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
2428a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
2429a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganovvoid CameraService::UidPolicy::UidPolicy::addOverrideUid(uid_t uid, bool active) {
2430a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    updateOverrideUid(uid, active, true);
2431a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
2432a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
2433a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganovvoid CameraService::UidPolicy::removeOverrideUid(uid_t uid) {
2434a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    updateOverrideUid(uid, false, false);
2435a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
2436a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
2437a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganovvoid CameraService::UidPolicy::updateOverrideUid(uid_t uid, bool active, bool insert) {
2438a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    bool wasActive = false;
2439a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    bool isActive = false;
2440a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    {
2441a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        Mutex::Autolock _l(mUidLock);
2442a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        wasActive = isUidActiveLocked(uid);
2443a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        mOverrideUids.erase(uid);
2444a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        if (insert) {
2445a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            mOverrideUids.insert(std::pair<uid_t, bool>(uid, active));
2446a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        }
2447a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        isActive = isUidActiveLocked(uid);
2448a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
2449a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    if (wasActive != isActive && !isActive) {
2450a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        sp<CameraService> service = mService.promote();
2451a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        if (service != nullptr) {
2452a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            service->blockClientsForUid(uid);
2453a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        }
2454a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
2455a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
2456a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
2457a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov// ----------------------------------------------------------------------------
2458cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk//                  CameraState
2459cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk// ----------------------------------------------------------------------------
2460cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2461cc776718c0be7c31fe5ab4fc1446d377be60369fRuben BrunkCameraService::CameraState::CameraState(const String8& id, int cost,
2462cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        const std::set<String8>& conflicting) : mId(id),
2463151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski        mStatus(StatusInternal::NOT_PRESENT), mCost(cost), mConflicting(conflicting) {}
2464cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2465cc776718c0be7c31fe5ab4fc1446d377be60369fRuben BrunkCameraService::CameraState::~CameraState() {}
2466cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2467f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville TalvalaCameraService::StatusInternal CameraService::CameraState::getStatus() const {
2468cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    Mutex::Autolock lock(mStatusLock);
2469cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return mStatus;
2470cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
2471cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2472cc776718c0be7c31fe5ab4fc1446d377be60369fRuben BrunkCameraParameters CameraService::CameraState::getShimParams() const {
2473cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return mShimParams;
2474cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
2475cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2476cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkvoid CameraService::CameraState::setShimParams(const CameraParameters& params) {
2477cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    mShimParams = params;
2478cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
2479cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2480cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkint CameraService::CameraState::getCost() const {
2481cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return mCost;
2482cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
2483cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2484cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkstd::set<String8> CameraService::CameraState::getConflicting() const {
2485cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return mConflicting;
2486cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
2487cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2488cc776718c0be7c31fe5ab4fc1446d377be60369fRuben BrunkString8 CameraService::CameraState::getId() const {
2489cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return mId;
2490cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
2491cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2492cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk// ----------------------------------------------------------------------------
249399e69716215cd0665379bc90d708f2ea8689831dRuben Brunk//                  ClientEventListener
249499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk// ----------------------------------------------------------------------------
249599e69716215cd0665379bc90d708f2ea8689831dRuben Brunk
249699e69716215cd0665379bc90d708f2ea8689831dRuben Brunkvoid CameraService::ClientEventListener::onClientAdded(
249799e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        const resource_policy::ClientDescriptor<String8,
249899e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        sp<CameraService::BasicClient>>& descriptor) {
24995404ee174dd6b5e312d3a97bc63c2bc8d142012bChih-Hung Hsieh    const auto& basicClient = descriptor.getValue();
250099e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    if (basicClient.get() != nullptr) {
250199e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        BatteryNotifier& notifier(BatteryNotifier::getInstance());
250299e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        notifier.noteStartCamera(descriptor.getKey(),
250399e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                static_cast<int>(basicClient->getClientUid()));
250499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    }
250599e69716215cd0665379bc90d708f2ea8689831dRuben Brunk}
250699e69716215cd0665379bc90d708f2ea8689831dRuben Brunk
250799e69716215cd0665379bc90d708f2ea8689831dRuben Brunkvoid CameraService::ClientEventListener::onClientRemoved(
250899e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        const resource_policy::ClientDescriptor<String8,
250999e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        sp<CameraService::BasicClient>>& descriptor) {
25105404ee174dd6b5e312d3a97bc63c2bc8d142012bChih-Hung Hsieh    const auto& basicClient = descriptor.getValue();
251199e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    if (basicClient.get() != nullptr) {
251299e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        BatteryNotifier& notifier(BatteryNotifier::getInstance());
251399e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        notifier.noteStopCamera(descriptor.getKey(),
251499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                static_cast<int>(basicClient->getClientUid()));
251599e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    }
251699e69716215cd0665379bc90d708f2ea8689831dRuben Brunk}
251799e69716215cd0665379bc90d708f2ea8689831dRuben Brunk
251899e69716215cd0665379bc90d708f2ea8689831dRuben Brunk
251999e69716215cd0665379bc90d708f2ea8689831dRuben Brunk// ----------------------------------------------------------------------------
2520cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk//                  CameraClientManager
2521cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk// ----------------------------------------------------------------------------
2522cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
252399e69716215cd0665379bc90d708f2ea8689831dRuben BrunkCameraService::CameraClientManager::CameraClientManager() {
252499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    setListener(std::make_shared<ClientEventListener>());
252599e69716215cd0665379bc90d708f2ea8689831dRuben Brunk}
252699e69716215cd0665379bc90d708f2ea8689831dRuben Brunk
2527cc776718c0be7c31fe5ab4fc1446d377be60369fRuben BrunkCameraService::CameraClientManager::~CameraClientManager() {}
2528cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2529cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunksp<CameraService::BasicClient> CameraService::CameraClientManager::getCameraClient(
2530cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        const String8& id) const {
2531cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    auto descriptor = get(id);
2532cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    if (descriptor == nullptr) {
2533cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        return sp<BasicClient>{nullptr};
2534cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
2535cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return descriptor->getValue();
2536cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
2537cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2538cc776718c0be7c31fe5ab4fc1446d377be60369fRuben BrunkString8 CameraService::CameraClientManager::toString() const {
2539cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    auto all = getAll();
2540cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    String8 ret("[");
2541cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    bool hasAny = false;
2542cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    for (auto& i : all) {
2543cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        hasAny = true;
2544cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        String8 key = i->getKey();
2545cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        int32_t cost = i->getCost();
2546cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        int32_t pid = i->getOwnerId();
25478131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev        int32_t score = i->getPriority().getScore();
25488131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev        int32_t state = i->getPriority().getState();
2549cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        auto conflicting = i->getConflicting();
2550cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        auto clientSp = i->getValue();
2551cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        String8 packageName;
2552022f0cb0c6f135edde4ebe84859c685933ee895eEino-Ville Talvala        userid_t clientUserId = 0;
2553cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        if (clientSp.get() != nullptr) {
2554cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            packageName = String8{clientSp->getPackageName()};
25556267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk            uid_t clientUid = clientSp->getClientUid();
25566267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk            clientUserId = multiuser_get_user_id(clientUid);
2557cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        }
25588131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev        ret.appendFormat("\n(Camera ID: %s, Cost: %" PRId32 ", PID: %" PRId32 ", Score: %"
25598131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                PRId32 ", State: %" PRId32, key.string(), cost, pid, score, state);
2560cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
25616267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        if (clientSp.get() != nullptr) {
25626267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk            ret.appendFormat("User Id: %d, ", clientUserId);
25636267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        }
2564cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        if (packageName.size() != 0) {
2565cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            ret.appendFormat("Client Package Name: %s", packageName.string());
2566cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        }
2567cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2568cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        ret.append(", Conflicting Client Devices: {");
2569cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        for (auto& j : conflicting) {
2570cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            ret.appendFormat("%s, ", j.string());
2571cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        }
2572cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        ret.append("})");
2573cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
2574cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    if (hasAny) ret.append("\n");
2575cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    ret.append("]\n");
2576cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return ret;
2577cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
2578cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2579cc776718c0be7c31fe5ab4fc1446d377be60369fRuben BrunkCameraService::DescriptorPtr CameraService::CameraClientManager::makeClientDescriptor(
2580cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        const String8& key, const sp<BasicClient>& value, int32_t cost,
25818131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev        const std::set<String8>& conflictingKeys, int32_t score, int32_t ownerId,
25828131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev        int32_t state) {
2583cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2584cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return std::make_shared<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>(
25858131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev            key, value, cost, conflictingKeys, score, ownerId, state);
2586cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
2587cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2588cc776718c0be7c31fe5ab4fc1446d377be60369fRuben BrunkCameraService::DescriptorPtr CameraService::CameraClientManager::makeClientDescriptor(
2589cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        const sp<BasicClient>& value, const CameraService::DescriptorPtr& partial) {
2590cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return makeClientDescriptor(partial->getKey(), value, partial->getCost(),
25918131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev            partial->getConflicting(), partial->getPriority().getScore(),
25928131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev            partial->getOwnerId(), partial->getPriority().getState());
2593cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
2594cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2595cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk// ----------------------------------------------------------------------------
259665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
259765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic const int kDumpLockRetries = 50;
259865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic const int kDumpLockSleep = 60000;
259965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
260065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic bool tryLock(Mutex& mutex)
260165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
260265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    bool locked = false;
260365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (int i = 0; i < kDumpLockRetries; ++i) {
260465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mutex.tryLock() == NO_ERROR) {
260565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            locked = true;
260665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
260765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
260865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        usleep(kDumpLockSleep);
260965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
261065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return locked;
261165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
261265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
261365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::dump(int fd, const Vector<String16>& args) {
2614a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
2615a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala
261665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
2617d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        dprintf(fd, "Permission Denial: can't dump CameraService from pid=%d, uid=%d\n",
261865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                getCallingPid(),
261965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                getCallingUid());
26208131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala        return NO_ERROR;
26218131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    }
26228131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    bool locked = tryLock(mServiceLock);
26238131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    // failed to lock - CameraService is probably deadlocked
26248131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    if (!locked) {
2625d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        dprintf(fd, "!! CameraService may be deadlocked !!\n");
26268131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    }
26271527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvala
26288131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    if (!mInitialized) {
2629d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        dprintf(fd, "!! No camera HAL available !!\n");
26301527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvala
26318131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala        // Dump event log for error information
26328131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala        dumpEventLog(fd);
26332f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
26348131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala        if (locked) mServiceLock.unlock();
26358131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala        return NO_ERROR;
26368131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    }
2637d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala    dprintf(fd, "\n== Service global info: ==\n\n");
2638d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala    dprintf(fd, "Number of camera devices: %d\n", mNumberOfCameras);
2639c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    dprintf(fd, "Number of normal camera devices: %zu\n", mNormalDeviceIds.size());
2640c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    for (size_t i = 0; i < mNormalDeviceIds.size(); i++) {
2641c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        dprintf(fd, "    Device %zu maps to \"%s\"\n", i, mNormalDeviceIds[i].c_str());
2642c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    }
26438131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    String8 activeClientString = mActiveClientManager.toString();
2644d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala    dprintf(fd, "Active Camera Clients:\n%s", activeClientString.string());
2645d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala    dprintf(fd, "Allowed user IDs: %s\n", toString(mAllowedUsers).string());
2646f81648ec38ff63f1f35516fa27c1c24d846e9ba5Ruben Brunk
26478131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    dumpEventLog(fd);
2648f81648ec38ff63f1f35516fa27c1c24d846e9ba5Ruben Brunk
26498131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    bool stateLocked = tryLock(mCameraStatesLock);
26508131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    if (!stateLocked) {
2651d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        dprintf(fd, "CameraStates in use, may be deadlocked\n");
26528131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    }
26538131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala
26548131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    for (auto& state : mCameraStates) {
26558131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala        String8 cameraId = state.first;
2656cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2657d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        dprintf(fd, "== Camera device %s dynamic info: ==\n", cameraId.string());
2658d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala
2659d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        CameraParameters p = state.second->getShimParams();
2660d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        if (!p.isEmpty()) {
2661d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala            dprintf(fd, "  Camera1 API shim is using parameters:\n        ");
2662d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala            p.dump(fd, args);
2663d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        }
2664d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala
2665d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        auto clientDescriptor = mActiveClientManager.get(cameraId);
26662f140ed90057ca0df3f9da8318241ecfb6dda9ebZhijun He        if (clientDescriptor != nullptr) {
26672f140ed90057ca0df3f9da8318241ecfb6dda9ebZhijun He            dprintf(fd, "  Device %s is open. Client instance dump:\n",
2668d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala                    cameraId.string());
26692f140ed90057ca0df3f9da8318241ecfb6dda9ebZhijun He            dprintf(fd, "    Client priority score: %d state: %d\n",
26702f140ed90057ca0df3f9da8318241ecfb6dda9ebZhijun He                    clientDescriptor->getPriority().getScore(),
26712f140ed90057ca0df3f9da8318241ecfb6dda9ebZhijun He                    clientDescriptor->getPriority().getState());
26722f140ed90057ca0df3f9da8318241ecfb6dda9ebZhijun He            dprintf(fd, "    Client PID: %d\n", clientDescriptor->getOwnerId());
2673d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala
26742f140ed90057ca0df3f9da8318241ecfb6dda9ebZhijun He            auto client = clientDescriptor->getValue();
26752f140ed90057ca0df3f9da8318241ecfb6dda9ebZhijun He            dprintf(fd, "    Client package: %s\n",
26762f140ed90057ca0df3f9da8318241ecfb6dda9ebZhijun He                    String8(client->getPackageName()).string());
2677d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala
26782f140ed90057ca0df3f9da8318241ecfb6dda9ebZhijun He            client->dumpClient(fd, args);
26792f140ed90057ca0df3f9da8318241ecfb6dda9ebZhijun He        } else {
26802f140ed90057ca0df3f9da8318241ecfb6dda9ebZhijun He            dprintf(fd, "  Device %s is closed, no client instance\n",
26812f140ed90057ca0df3f9da8318241ecfb6dda9ebZhijun He                    cameraId.string());
26822f140ed90057ca0df3f9da8318241ecfb6dda9ebZhijun He        }
2683d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala
26848131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    }
268565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
26868131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    if (stateLocked) mCameraStatesLock.unlock();
268765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2688d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala    if (locked) mServiceLock.unlock();
2689d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala
2690f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    mCameraProviderManager->dump(fd, args);
26918131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala
2692d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala    dprintf(fd, "\n== Vendor tags: ==\n\n");
2693d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala
2694d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala    sp<VendorTagDescriptor> desc = VendorTagDescriptor::getGlobalVendorTagDescriptor();
2695d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala    if (desc == NULL) {
269671c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev        sp<VendorTagDescriptorCache> cache =
269771c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                VendorTagDescriptorCache::getGlobalVendorTagCache();
269871c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev        if (cache == NULL) {
269971c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev            dprintf(fd, "No vendor tags.\n");
270071c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev        } else {
270171c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev            cache->dump(fd, /*verbosity*/2, /*indentation*/2);
270271c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev        }
2703d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala    } else {
2704d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        desc->dump(fd, /*verbosity*/2, /*indentation*/2);
2705d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala    }
27068131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala
27078131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    // Dump camera traces if there were any
2708d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala    dprintf(fd, "\n");
27098131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    camera3::CameraTraces::dump(fd, args);
27108131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala
27118131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    // Process dump arguments, if any
27128131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    int n = args.size();
27138131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    String16 verboseOption("-v");
27148131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    String16 unreachableOption("--unreachable");
27158131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    for (int i = 0; i < n; i++) {
27168131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala        if (args[i] == verboseOption) {
27178131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala            // change logging level
27188131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala            if (i + 1 >= n) continue;
27198131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala            String8 levelStr(args[i+1]);
27208131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala            int level = atoi(levelStr.string());
2721d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala            dprintf(fd, "\nSetting log level to %d.\n", level);
27228131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala            setLogLevel(level);
27238131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala        } else if (args[i] == unreachableOption) {
27248131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala            // Dump memory analysis
27258131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala            // TODO - should limit be an argument parameter?
27268131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala            UnreachableMemoryInfo info;
27278131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala            bool success = GetUnreachableMemory(info, /*limit*/ 10000);
27288131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala            if (!success) {
2729d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala                dprintf(fd, "\n== Unable to dump unreachable memory. "
2730d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala                        "Try disabling SELinux enforcement. ==\n");
27318131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala            } else {
2732d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala                dprintf(fd, "\n== Dumping unreachable memory: ==\n");
27338131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala                std::string s = info.ToString(/*log_contents*/ true);
27348131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala                write(fd, s.c_str(), s.size());
273565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
273665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
273765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
273865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
273965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
274065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
27411527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvalavoid CameraService::dumpEventLog(int fd) {
2742d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala    dprintf(fd, "\n== Camera service events log (most recent at top): ==\n");
27431527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvala
27441527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvala    Mutex::Autolock l(mLogLock);
27451527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvala    for (const auto& msg : mEventLog) {
2746d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        dprintf(fd, "  %s\n", msg.string());
27471527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvala    }
27481527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvala
27491527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvala    if (mEventLog.size() == DEFAULT_EVENT_LOG_LENGTH) {
2750d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        dprintf(fd, "  ...\n");
27511527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvala    } else if (mEventLog.size() == 0) {
2752d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        dprintf(fd, "  [no events yet]\n");
27531527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvala    }
2754d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala    dprintf(fd, "\n");
27551527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvala}
27561527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvala
27573068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chenvoid CameraService::handleTorchClientBinderDied(const wp<IBinder> &who) {
275888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    Mutex::Autolock al(mTorchClientMapMutex);
27593068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    for (size_t i = 0; i < mTorchClientMap.size(); i++) {
27603068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen        if (mTorchClientMap[i] == who) {
27613068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen            // turn off the torch mode that was turned on by dead client
276288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen            String8 cameraId = mTorchClientMap.keyAt(i);
276388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen            status_t res = mFlashlight->setTorchMode(cameraId, false);
276488da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen            if (res) {
276588da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen                ALOGE("%s: torch client died but couldn't turn off torch: "
276688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen                    "%s (%d)", __FUNCTION__, strerror(-res), res);
276788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen                return;
276888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen            }
27693068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen            mTorchClientMap.removeItemsAt(i);
27703068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen            break;
27713068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen        }
27723068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    }
27733068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen}
27743068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
2775cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk/*virtual*/void CameraService::binderDied(const wp<IBinder> &who) {
2776ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
2777294d0eca9eabfaa3ef0ee8bee7ccf3eaaa925e41Igor Murashkin    /**
2778a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk      * While tempting to promote the wp<IBinder> into a sp, it's actually not supported by the
2779a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk      * binder driver
2780294d0eca9eabfaa3ef0ee8bee7ccf3eaaa925e41Igor Murashkin      */
2781294d0eca9eabfaa3ef0ee8bee7ccf3eaaa925e41Igor Murashkin
2782a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    logClientDied(getCallingPid(), String8("Binder died unexpectedly"));
2783a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk
27843068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    // check torch client
27853068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    handleTorchClientBinderDied(who);
27863068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
27873068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    // check camera device client
2788cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    if(!evictClientIdByRemote(who)) {
2789cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        ALOGV("%s: Java client's binder death already cleaned up (normal case)", __FUNCTION__);
2790ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin        return;
2791ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    }
2792ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
2793cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    ALOGE("%s: Java client's binder died, removing it from the list of active clients",
2794cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            __FUNCTION__);
2795ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin}
2796ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
2797f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalavoid CameraService::updateStatus(StatusInternal status, const String8& cameraId) {
2798cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    updateStatus(status, cameraId, {});
2799cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
2800bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
2801f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalavoid CameraService::updateStatus(StatusInternal status, const String8& cameraId,
2802f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        std::initializer_list<StatusInternal> rejectSourceStates) {
2803cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    // Do not lock mServiceLock here or can get into a deadlock from
2804cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    // connect() -> disconnect -> updateStatus
2805cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin
2806cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    auto state = getCameraState(cameraId);
2807cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin
2808cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    if (state == nullptr) {
2809cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        ALOGW("%s: Could not update the status for %s, no such device exists", __FUNCTION__,
2810cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                cameraId.string());
2811cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        return;
2812cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
281393747b9c7724f690b3068300514c05629e0b0a3eIgor Murashkin
2814cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    // Update the status for this camera state, then send the onStatusChangedCallbacks to each
2815cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    // of the listeners with both the mStatusStatus and mStatusListenerLock held
2816cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    state->updateStatus(status, cameraId, rejectSourceStates, [this]
2817f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            (const String8& cameraId, StatusInternal status) {
2818cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2819f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            if (status != StatusInternal::ENUMERATING) {
2820f6463fc62a09b8aad8e811a9abbe9f4d9f2688f9Chien-Yu Chen                // Update torch status if it has a flash unit.
2821f6463fc62a09b8aad8e811a9abbe9f4d9f2688f9Chien-Yu Chen                Mutex::Autolock al(mTorchStatusMutex);
2822f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                TorchModeStatus torchStatus;
2823f6463fc62a09b8aad8e811a9abbe9f4d9f2688f9Chien-Yu Chen                if (getTorchStatusLocked(cameraId, &torchStatus) !=
2824f6463fc62a09b8aad8e811a9abbe9f4d9f2688f9Chien-Yu Chen                        NAME_NOT_FOUND) {
2825f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                    TorchModeStatus newTorchStatus =
2826f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            status == StatusInternal::PRESENT ?
2827f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            TorchModeStatus::AVAILABLE_OFF :
2828f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            TorchModeStatus::NOT_AVAILABLE;
2829f6463fc62a09b8aad8e811a9abbe9f4d9f2688f9Chien-Yu Chen                    if (torchStatus != newTorchStatus) {
2830f6463fc62a09b8aad8e811a9abbe9f4d9f2688f9Chien-Yu Chen                        onTorchStatusChangedLocked(cameraId, newTorchStatus);
2831f6463fc62a09b8aad8e811a9abbe9f4d9f2688f9Chien-Yu Chen                    }
2832f6463fc62a09b8aad8e811a9abbe9f4d9f2688f9Chien-Yu Chen                }
2833bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin            }
2834bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
2835cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            Mutex::Autolock lock(mStatusListenerLock);
283688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen
2837cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            for (auto& listener : mListenerList) {
2838f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                listener->onStatusChanged(mapToInterface(status), String16(cameraId));
2839cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            }
2840cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        });
2841cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin}
2842cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin
2843f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalatemplate<class Func>
2844f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalavoid CameraService::CameraState::updateStatus(StatusInternal status,
2845f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        const String8& cameraId,
2846f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        std::initializer_list<StatusInternal> rejectSourceStates,
2847f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        Func onStatusUpdatedLocked) {
2848f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    Mutex::Autolock lock(mStatusLock);
2849f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    StatusInternal oldStatus = mStatus;
2850f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    mStatus = status;
2851f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
2852f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    if (oldStatus == status) {
2853f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        return;
2854f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    }
2855f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
2856f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    ALOGV("%s: Status has changed for camera ID %s from %#x to %#x", __FUNCTION__,
2857f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            cameraId.string(), oldStatus, status);
2858f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
2859f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    if (oldStatus == StatusInternal::NOT_PRESENT &&
2860f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            (status != StatusInternal::PRESENT &&
2861f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala             status != StatusInternal::ENUMERATING)) {
2862f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
2863f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        ALOGW("%s: From NOT_PRESENT can only transition into PRESENT or ENUMERATING",
2864f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                __FUNCTION__);
2865f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        mStatus = oldStatus;
2866f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        return;
2867f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    }
2868f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
2869f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    /**
2870f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala     * Sometimes we want to conditionally do a transition.
2871f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala     * For example if a client disconnects, we want to go to PRESENT
2872f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala     * only if we weren't already in NOT_PRESENT or ENUMERATING.
2873f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala     */
2874f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    for (auto& rejectStatus : rejectSourceStates) {
2875f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        if (oldStatus == rejectStatus) {
2876f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            ALOGV("%s: Rejecting status transition for Camera ID %s,  since the source "
2877f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                    "state was was in one of the bad states.", __FUNCTION__, cameraId.string());
2878f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            mStatus = oldStatus;
2879f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            return;
2880f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        }
2881f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    }
2882f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
2883f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    onStatusUpdatedLocked(cameraId, status);
2884f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala}
2885f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
2886e8c96c765b95ec7dcd10732621a825fce05960c6Eino-Ville Talvalavoid CameraService::updateProxyDeviceState(int newState,
2887573291c251d9e85f51f7c0fa1cb35baa2969ca17Emilian Peev        const String8& cameraId, int facing, const String16& clientName, int apiLevel) {
2888412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala    sp<ICameraServiceProxy> proxyBinder = getCameraServiceProxy();
2889412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala    if (proxyBinder == nullptr) return;
2890412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala    String16 id(cameraId);
2891573291c251d9e85f51f7c0fa1cb35baa2969ca17Emilian Peev    proxyBinder->notifyCameraState(id, newState, facing, clientName, apiLevel);
2892412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala}
2893412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala
289488da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chenstatus_t CameraService::getTorchStatusLocked(
289588da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen        const String8& cameraId,
2896f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        TorchModeStatus *status) const {
289788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    if (!status) {
289888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen        return BAD_VALUE;
289988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    }
29003068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    ssize_t index = mTorchStatusMap.indexOfKey(cameraId);
29013068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    if (index == NAME_NOT_FOUND) {
290288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen        // invalid camera ID or the camera doesn't have a flash unit
290388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen        return NAME_NOT_FOUND;
29043068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    }
29053068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
290688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    *status = mTorchStatusMap.valueAt(index);
290788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    return OK;
29083068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen}
29093068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
291088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chenstatus_t CameraService::setTorchStatusLocked(const String8& cameraId,
2911f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        TorchModeStatus status) {
29123068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    ssize_t index = mTorchStatusMap.indexOfKey(cameraId);
29133068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    if (index == NAME_NOT_FOUND) {
29143068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen        return BAD_VALUE;
29153068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    }
2916f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    mTorchStatusMap.editValueAt(index) = status;
29173068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
29183068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    return OK;
29193068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen}
29203068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
2921a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganovvoid CameraService::blockClientsForUid(uid_t uid) {
2922a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    const auto clients = mActiveClientManager.getAll();
2923a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    for (auto& current : clients) {
2924a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        if (current != nullptr) {
2925a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            const auto basicClient = current->getValue();
2926a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            if (basicClient.get() != nullptr && basicClient->getClientUid() == uid) {
2927a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov                basicClient->block();
2928a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            }
2929a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        }
2930a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
2931a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
2932a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
2933a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov// NOTE: This is a remote API - make sure all args are validated
2934a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganovstatus_t CameraService::shellCommand(int in, int out, int err, const Vector<String16>& args) {
2935a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    if (!checkCallingPermission(sManageCameraPermission, nullptr, nullptr)) {
2936a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        return PERMISSION_DENIED;
2937a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
2938a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    if (in == BAD_TYPE || out == BAD_TYPE || err == BAD_TYPE) {
2939a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        return BAD_VALUE;
2940a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
2941a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    if (args.size() == 3 && args[0] == String16("set-uid-state")) {
2942a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        return handleSetUidState(args, err);
2943a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    } else if (args.size() == 2 && args[0] == String16("reset-uid-state")) {
2944a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        return handleResetUidState(args, err);
2945a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    } else if (args.size() == 2 && args[0] == String16("get-uid-state")) {
2946a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        return handleGetUidState(args, out, err);
2947a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    } else if (args.size() == 1 && args[0] == String16("help")) {
2948a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        printHelp(out);
2949a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        return NO_ERROR;
2950a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
2951a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    printHelp(err);
2952a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    return BAD_VALUE;
2953a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
2954a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
2955a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganovstatus_t CameraService::handleSetUidState(const Vector<String16>& args, int err) {
2956a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    PermissionController pc;
2957a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    int uid = pc.getPackageUid(args[1], 0);
2958a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    if (uid <= 0) {
2959a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        ALOGE("Unknown package: '%s'", String8(args[1]).string());
2960a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        dprintf(err, "Unknown package: '%s'\n", String8(args[1]).string());
2961a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        return BAD_VALUE;
2962a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
2963a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    bool active = false;
2964a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    if (args[2] == String16("active")) {
2965a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        active = true;
2966a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    } else if ((args[2] != String16("idle"))) {
2967a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        ALOGE("Expected active or idle but got: '%s'", String8(args[2]).string());
2968a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        return BAD_VALUE;
2969a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
2970a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    mUidPolicy->addOverrideUid(uid, active);
2971a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    return NO_ERROR;
2972a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
2973a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
2974a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganovstatus_t CameraService::handleResetUidState(const Vector<String16>& args, int err) {
2975a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    PermissionController pc;
2976a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    int uid = pc.getPackageUid(args[1], 0);
2977a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    if (uid < 0) {
2978a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        ALOGE("Unknown package: '%s'", String8(args[1]).string());
2979a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        dprintf(err, "Unknown package: '%s'\n", String8(args[1]).string());
2980a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        return BAD_VALUE;
2981a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
2982a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    mUidPolicy->removeOverrideUid(uid);
2983a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    return NO_ERROR;
2984a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
2985a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
2986a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganovstatus_t CameraService::handleGetUidState(const Vector<String16>& args, int out, int err) {
2987a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    PermissionController pc;
2988a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    int uid = pc.getPackageUid(args[1], 0);
2989a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    if (uid <= 0) {
2990a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        ALOGE("Unknown package: '%s'", String8(args[1]).string());
2991a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        dprintf(err, "Unknown package: '%s'\n", String8(args[1]).string());
2992a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        return BAD_VALUE;
2993a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
2994a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    if (mUidPolicy->isUidActive(uid)) {
2995a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        return dprintf(out, "active\n");
2996a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    } else {
2997a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        return dprintf(out, "idle\n");
2998a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
2999a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
3000a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
3001a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganovstatus_t CameraService::printHelp(int out) {
3002a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    return dprintf(out, "Camera service commands:\n"
3003a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        "  get-uid-state <PACKAGE> gets the uid state\n"
3004a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        "  set-uid-state <PACKAGE> <active|idle> overrides the uid state\n"
3005a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        "  reset-uid-state <PACKAGE> clears the uid state override\n"
3006a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        "  help print this message\n");
3007a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
3008a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
300965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}; // namespace android
3010