CameraService.cpp revision ef49805296eb81cd4ba039fa4d25b9358436992b
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"
70bd8c503398d6b483b7abba594c7838a4c93b6e23Emilian Peev#include "utils/TagMonitor.h"
7165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
720dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yehnamespace {
730dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    const char* kPermissionServiceName = "permission";
740dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh}; // namespace anonymous
750dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
7665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiannamespace android {
7765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
78d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvalausing binder::Status;
79f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalausing hardware::ICamera;
80f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalausing hardware::ICameraClient;
81e8c96c765b95ec7dcd10732621a825fce05960c6Eino-Ville Talvalausing hardware::ICameraServiceProxy;
82f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalausing hardware::ICameraServiceListener;
83f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalausing hardware::camera::common::V1_0::CameraDeviceStatus;
84f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalausing hardware::camera::common::V1_0::TorchModeStatus;
85d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala
8665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
8765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// Logging support -- this is for debugging only
8865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// Use "adb shell dumpsys media.camera -v 1" to change it.
895e08d60617fc63c2e41f9069ff89f5c00db2617dEino-Ville Talvalavolatile int32_t gLogLevel = 0;
9065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
91b8a805261bf0282e992d3608035e47d05a898710Steve Block#define LOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__);
92b8a805261bf0282e992d3608035e47d05a898710Steve Block#define LOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__);
9365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
9465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic void setLogLevel(int level) {
9565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    android_atomic_write(level, &gLogLevel);
9665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
9765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
98d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala// Convenience methods for constructing binder::Status objects for error returns
99d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala
100d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala#define STATUS_ERROR(errorCode, errorString) \
101d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    binder::Status::fromServiceSpecificError(errorCode, \
102d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            String8::format("%s:%d: %s", __FUNCTION__, __LINE__, errorString))
103d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala
104d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala#define STATUS_ERROR_FMT(errorCode, errorString, ...) \
105d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    binder::Status::fromServiceSpecificError(errorCode, \
106d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            String8::format("%s:%d: " errorString, __FUNCTION__, __LINE__, \
107d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    __VA_ARGS__))
108d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala
10965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
11065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
111a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganovstatic const String16 sManageCameraPermission("android.permission.MANAGE_CAMERA");
112a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
11349c9705a7987b94bd53fddd4834f5f534cf946f7Eino-Ville TalvalaCameraService::CameraService() :
11449c9705a7987b94bd53fddd4834f5f534cf946f7Eino-Ville Talvala        mEventLog(DEFAULT_EVENT_LOG_LENGTH),
115c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        mNumberOfCameras(0),
116f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev        mSoundRef(0), mInitialized(false) {
117df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block    ALOGI("CameraService started (pid=%d)", getpid());
118cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    mServiceLockWrapper = std::make_shared<WaitableMutexWrapper>(&mServiceLock);
1198951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev}
12065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1218951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchevvoid CameraService::onFirstRef()
1228951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev{
123cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    ALOGI("CameraService process starting");
124634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
1258951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    BnCameraService::onFirstRef();
12665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
12799e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    // Update battery life tracking if service is restarting
12899e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    BatteryNotifier& notifier(BatteryNotifier::getInstance());
12999e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    notifier.noteResetCamera();
13099e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    notifier.noteResetFlashlight();
13199e69716215cd0665379bc90d708f2ea8689831dRuben Brunk
1322f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    status_t res = INVALID_OPERATION;
1339cbbc837625cced18adabc57d71479044999155dEino-Ville Talvala
134f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    res = enumerateProviders();
1352f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (res == OK) {
1362f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        mInitialized = true;
1372f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
1382f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
1392f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    CameraService::pingCameraServiceProxy();
140a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
141a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    mUidPolicy = new UidPolicy(this);
142a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    mUidPolicy->registerSelf();
1432f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala}
1442f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
1452f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalastatus_t CameraService::enumerateProviders() {
1462f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    status_t res;
147aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev
148c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    std::vector<std::string> deviceIds;
149c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    {
150c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        Mutex::Autolock l(mServiceLock);
151c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh
152c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        if (nullptr == mCameraProviderManager.get()) {
153c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            mCameraProviderManager = new CameraProviderManager();
154c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            res = mCameraProviderManager->initialize(this);
155c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            if (res != OK) {
156c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                ALOGE("%s: Unable to initialize camera provider manager: %s (%d)",
157c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                        __FUNCTION__, strerror(-res), res);
158c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                return res;
159c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            }
160aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev        }
1612f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
1622f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
163c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        // Setup vendor tags before we call get_camera_info the first time
164c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        // because HAL might need to setup static vendor keys in get_camera_info
165c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        // TODO: maybe put this into CameraProviderManager::initialize()?
166c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        mCameraProviderManager->setUpVendorTags();
1672f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
168c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        if (nullptr == mFlashlight.get()) {
169c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            mFlashlight = new CameraFlashlight(mCameraProviderManager, this);
170aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev        }
171aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev
172c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        res = mFlashlight->findFlashUnits();
173c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        if (res != OK) {
174c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            ALOGE("Failed to enumerate flash units: %s (%d)", strerror(-res), res);
17592e3321e41e10f2e07a71f9512a6cadef7f40b64Yin-Chia Yeh        }
17692e3321e41e10f2e07a71f9512a6cadef7f40b64Yin-Chia Yeh
177c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        deviceIds = mCameraProviderManager->getCameraDeviceIds();
178c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    }
179c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh
180c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh
181c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    for (auto& cameraId : deviceIds) {
182c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        String8 id8 = String8(cameraId.c_str());
18392e3321e41e10f2e07a71f9512a6cadef7f40b64Yin-Chia Yeh        onDeviceStatusChanged(id8, CameraDeviceStatus::PRESENT);
1842f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
1852f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
1862f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    return OK;
1872823ce0ce6f9d508a07de20912c93cce9165027fRuben Brunk}
1882823ce0ce6f9d508a07de20912c93cce9165027fRuben Brunk
189412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvalasp<ICameraServiceProxy> CameraService::getCameraServiceProxy() {
19092c06fceabfa47906aaa7c747dcdd6376ccec358Christopher Wiley    sp<ICameraServiceProxy> proxyBinder = nullptr;
19192c06fceabfa47906aaa7c747dcdd6376ccec358Christopher Wiley#ifndef __BRILLO__
1922823ce0ce6f9d508a07de20912c93cce9165027fRuben Brunk    sp<IServiceManager> sm = defaultServiceManager();
193f4db13db84c40299de4f9997f08d05259bdb8716Eino-Ville Talvala    // Use checkService because cameraserver normally starts before the
194f4db13db84c40299de4f9997f08d05259bdb8716Eino-Ville Talvala    // system server and the proxy service. So the long timeout that getService
195f4db13db84c40299de4f9997f08d05259bdb8716Eino-Ville Talvala    // has before giving up is inappropriate.
196f4db13db84c40299de4f9997f08d05259bdb8716Eino-Ville Talvala    sp<IBinder> binder = sm->checkService(String16("media.camera.proxy"));
19792c06fceabfa47906aaa7c747dcdd6376ccec358Christopher Wiley    if (binder != nullptr) {
19892c06fceabfa47906aaa7c747dcdd6376ccec358Christopher Wiley        proxyBinder = interface_cast<ICameraServiceProxy>(binder);
1992823ce0ce6f9d508a07de20912c93cce9165027fRuben Brunk    }
20092c06fceabfa47906aaa7c747dcdd6376ccec358Christopher Wiley#endif
201412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala    return proxyBinder;
202412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala}
203412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala
204412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvalavoid CameraService::pingCameraServiceProxy() {
205412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala    sp<ICameraServiceProxy> proxyBinder = getCameraServiceProxy();
206412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala    if (proxyBinder == nullptr) return;
2072823ce0ce6f9d508a07de20912c93cce9165027fRuben Brunk    proxyBinder->pingForUserUpdate();
20865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
20965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
21065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianCameraService::~CameraService() {
211d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk    VendorTagDescriptor::clearGlobalVendorTagDescriptor();
212a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    mUidPolicy->unregisterSelf();
21365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
21465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
215aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peevvoid CameraService::onNewProviderRegistered() {
216aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev    enumerateProviders();
217aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev}
218aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev
219c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yehvoid CameraService::updateCameraNumAndIds() {
220c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    Mutex::Autolock l(mServiceLock);
221c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    mNumberOfCameras = mCameraProviderManager->getCameraCount();
222c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    mNormalDeviceIds =
223c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            mCameraProviderManager->getAPI1CompatibleCameraDeviceIds();
224c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh}
225c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh
226151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetskivoid CameraService::addStates(const String8 id) {
227151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    std::string cameraId(id.c_str());
228151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    hardware::camera::common::V1_0::CameraResourceCost cost;
229151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    status_t res = mCameraProviderManager->getResourceCost(cameraId, &cost);
230151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    if (res != OK) {
231151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski        ALOGE("Failed to query device resource cost: %s (%d)", strerror(-res), res);
232151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski        return;
233151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    }
234151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    std::set<String8> conflicting;
235151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    for (size_t i = 0; i < cost.conflictingDevices.size(); i++) {
236151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski        conflicting.emplace(String8(cost.conflictingDevices[i].c_str()));
237151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    }
238151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski
239151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    {
240151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski        Mutex::Autolock lock(mCameraStatesLock);
241151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski        mCameraStates.emplace(id, std::make_shared<CameraState>(id, cost.resourceCost,
242151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski                                                                conflicting));
243151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    }
244151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski
245151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    if (mFlashlight->hasFlashUnit(id)) {
246151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski        mTorchStatusMap.add(id, TorchModeStatus::AVAILABLE_OFF);
247151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    }
248c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh
249c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    updateCameraNumAndIds();
250151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    logDeviceAdded(id, "Device added");
251151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski}
252151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski
2536034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetskivoid CameraService::removeStates(const String8 id) {
254c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    updateCameraNumAndIds();
2556034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski    if (mFlashlight->hasFlashUnit(id)) {
2566034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski        mTorchStatusMap.removeItem(id);
2576034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski    }
2586034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski
2596034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski    {
2606034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski        Mutex::Autolock lock(mCameraStatesLock);
2616034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski        mCameraStates.erase(id);
2626034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski    }
2636034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski}
2646034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski
265f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalavoid CameraService::onDeviceStatusChanged(const String8& id,
266f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        CameraDeviceStatus newHalStatus) {
267f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    ALOGI("%s: Status changed for cameraId=%s, newStatus=%d", __FUNCTION__,
268f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            id.string(), newHalStatus);
269f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
270f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    StatusInternal newStatus = mapToInternal(newHalStatus);
271cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin
272cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    std::shared_ptr<CameraState> state = getCameraState(id);
273cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
274cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    if (state == nullptr) {
27592e3321e41e10f2e07a71f9512a6cadef7f40b64Yin-Chia Yeh        if (newStatus == StatusInternal::PRESENT) {
276151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski            ALOGI("%s: Unknown camera ID %s, a new camera is added",
27792e3321e41e10f2e07a71f9512a6cadef7f40b64Yin-Chia Yeh                    __FUNCTION__, id.string());
278151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski
279151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski            // First add as absent to make sure clients are notified below
280151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski            addStates(id);
281151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski
282151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski            updateStatus(newStatus, id);
28392e3321e41e10f2e07a71f9512a6cadef7f40b64Yin-Chia Yeh        } else {
28492e3321e41e10f2e07a71f9512a6cadef7f40b64Yin-Chia Yeh            ALOGE("%s: Bad camera ID %s", __FUNCTION__, id.string());
28592e3321e41e10f2e07a71f9512a6cadef7f40b64Yin-Chia Yeh        }
286cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin        return;
287cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin    }
288cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin
289f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    StatusInternal oldStatus = state->getStatus();
290cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
291f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    if (oldStatus == newStatus) {
292cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        ALOGE("%s: State transition to the same status %#x not allowed", __FUNCTION__, newStatus);
293cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin        return;
294cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin    }
295cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin
296f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    if (newStatus == StatusInternal::NOT_PRESENT) {
297a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk        logDeviceRemoved(id, String8::format("Device status changed from %d to %d", oldStatus,
298a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk                newStatus));
299c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh
300c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        // Set the device status to NOT_PRESENT, clients will no longer be able to connect
301c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        // to this device until the status changes
302c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        updateStatus(StatusInternal::NOT_PRESENT, id);
303c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh
304cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        sp<BasicClient> clientToDisconnect;
305cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin        {
306cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            // Don't do this in updateStatus to avoid deadlock over mServiceLock
307cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            Mutex::Autolock lock(mServiceLock);
308cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin
309cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            // Remove cached shim parameters
310cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            state->setShimParams(CameraParameters());
311cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin
3128d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala            // Remove the client from the list of active clients, if there is one
313cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            clientToDisconnect = removeClientLocked(id);
3148d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        }
315cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
3168d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        // Disconnect client
3178d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        if (clientToDisconnect.get() != nullptr) {
3188d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala            ALOGI("%s: Client for camera ID %s evicted due to device status change from HAL",
3198d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala                    __FUNCTION__, id.string());
320cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            // Notify the client of disconnection
321d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            clientToDisconnect->notifyError(
322d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED,
323cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    CaptureResultExtras{});
324cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            // Ensure not in binder RPC so client disconnect PID checks work correctly
325cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            LOG_ALWAYS_FATAL_IF(getCallingPid() != getpid(),
326cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    "onDeviceStatusChanged must be called from the camera service process!");
327cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            clientToDisconnect->disconnect();
328cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        }
329cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
3306034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski        removeStates(id);
331cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    } else {
332f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        if (oldStatus == StatusInternal::NOT_PRESENT) {
333a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk            logDeviceAdded(id, String8::format("Device status changed from %d to %d", oldStatus,
334a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk                    newStatus));
335a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk        }
336f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        updateStatus(newStatus, id);
337cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
338cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin
339cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin}
340cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin
34188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chenvoid CameraService::onTorchStatusChanged(const String8& cameraId,
342f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        TorchModeStatus newStatus) {
3433068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    Mutex::Autolock al(mTorchStatusMutex);
3443068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    onTorchStatusChangedLocked(cameraId, newStatus);
3453068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen}
3463068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
34788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chenvoid CameraService::onTorchStatusChangedLocked(const String8& cameraId,
348f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        TorchModeStatus newStatus) {
3493068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    ALOGI("%s: Torch status changed for cameraId=%s, newStatus=%d",
3503068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen            __FUNCTION__, cameraId.string(), newStatus);
3513068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
352f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    TorchModeStatus status;
35388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    status_t res = getTorchStatusLocked(cameraId, &status);
35488da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    if (res) {
355f6463fc62a09b8aad8e811a9abbe9f4d9f2688f9Chien-Yu Chen        ALOGE("%s: cannot get torch status of camera %s: %s (%d)",
356f6463fc62a09b8aad8e811a9abbe9f4d9f2688f9Chien-Yu Chen                __FUNCTION__, cameraId.string(), strerror(-res), res);
35788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen        return;
35888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    }
35988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    if (status == newStatus) {
3603068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen        return;
3613068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    }
3623068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
36388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    res = setTorchStatusLocked(cameraId, newStatus);
3643068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    if (res) {
365d309fb9c8a2c4564d88fffba19c4e3688e4b862bEino-Ville Talvala        ALOGE("%s: Failed to set the torch status to %d: %s (%d)", __FUNCTION__,
366d309fb9c8a2c4564d88fffba19c4e3688e4b862bEino-Ville Talvala                (uint32_t)newStatus, strerror(-res), res);
3673068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen        return;
3683068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    }
3693068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
370cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    {
37199e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        // Update battery life logging for flashlight
372fe751bea0d3eedd6e817aebf4e457425b82e7117Chien-Yu Chen        Mutex::Autolock al(mTorchUidMapMutex);
37399e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        auto iter = mTorchUidMap.find(cameraId);
37499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        if (iter != mTorchUidMap.end()) {
37599e69716215cd0665379bc90d708f2ea8689831dRuben Brunk            int oldUid = iter->second.second;
37699e69716215cd0665379bc90d708f2ea8689831dRuben Brunk            int newUid = iter->second.first;
37799e69716215cd0665379bc90d708f2ea8689831dRuben Brunk            BatteryNotifier& notifier(BatteryNotifier::getInstance());
37899e69716215cd0665379bc90d708f2ea8689831dRuben Brunk            if (oldUid != newUid) {
37999e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                // If the UID has changed, log the status and update current UID in mTorchUidMap
380f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                if (status == TorchModeStatus::AVAILABLE_ON) {
38199e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                    notifier.noteFlashlightOff(cameraId, oldUid);
38299e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                }
383f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                if (newStatus == TorchModeStatus::AVAILABLE_ON) {
38499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                    notifier.noteFlashlightOn(cameraId, newUid);
38599e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                }
38699e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                iter->second.second = newUid;
38799e69716215cd0665379bc90d708f2ea8689831dRuben Brunk            } else {
38899e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                // If the UID has not changed, log the status
389f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                if (newStatus == TorchModeStatus::AVAILABLE_ON) {
39099e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                    notifier.noteFlashlightOn(cameraId, oldUid);
39199e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                } else {
39299e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                    notifier.noteFlashlightOff(cameraId, oldUid);
39399e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                }
39499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk            }
39599e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        }
39699e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    }
39799e69716215cd0665379bc90d708f2ea8689831dRuben Brunk
39899e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    {
399cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        Mutex::Autolock lock(mStatusListenerLock);
400cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        for (auto& i : mListenerList) {
401f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            i->onTorchStatusChanged(mapToInterface(newStatus), String16{cameraId});
402cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        }
4033068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    }
4043068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen}
4053068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
406d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::getNumberOfCameras(int32_t type, int32_t* numCameras) {
407a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
408aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev    Mutex::Autolock l(mServiceLock);
409bad4358c83c7daaf9eeb8542c15eea4f473c884cEino-Ville Talvala    switch (type) {
410bad4358c83c7daaf9eeb8542c15eea4f473c884cEino-Ville Talvala        case CAMERA_TYPE_BACKWARD_COMPATIBLE:
411c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            *numCameras = static_cast<int>(mNormalDeviceIds.size());
412d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            break;
413bad4358c83c7daaf9eeb8542c15eea4f473c884cEino-Ville Talvala        case CAMERA_TYPE_ALL:
414d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            *numCameras = mNumberOfCameras;
415d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            break;
416bad4358c83c7daaf9eeb8542c15eea4f473c884cEino-Ville Talvala        default:
417d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            ALOGW("%s: Unknown camera type %d",
418bad4358c83c7daaf9eeb8542c15eea4f473c884cEino-Ville Talvala                    __FUNCTION__, type);
419d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
420d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    "Unknown camera type %d", type);
421bad4358c83c7daaf9eeb8542c15eea4f473c884cEino-Ville Talvala    }
422d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return Status::ok();
42365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
42465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
425d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::getCameraInfo(int cameraId,
426d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        CameraInfo* cameraInfo) {
427a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
428aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev    Mutex::Autolock l(mServiceLock);
429aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev
4302f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (!mInitialized) {
431d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(ERROR_DISCONNECTED,
432d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "Camera subsystem is not available");
4338951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    }
4348951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev
43565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (cameraId < 0 || cameraId >= mNumberOfCameras) {
436d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT,
437d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "CameraId is not valid");
43865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
43965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4402f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    Status ret = Status::ok();
441c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    status_t err = mCameraProviderManager->getCameraInfo(
442c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            cameraIdIntToStrLocked(cameraId), cameraInfo);
443f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    if (err != OK) {
444f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev        ret = STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
445f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev                "Error retrieving camera info from device %d: %s (%d)", cameraId,
446f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev                strerror(-err), err);
447d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    }
448f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev
4492f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    return ret;
45065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
45165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
452c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yehstd::string CameraService::cameraIdIntToStrLocked(int cameraIdInt) {
453c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    if (cameraIdInt < 0 || cameraIdInt >= static_cast<int>(mNormalDeviceIds.size())) {
454c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        ALOGE("%s: input id %d invalid: valid range  (0, %zu)",
455c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                __FUNCTION__, cameraIdInt, mNormalDeviceIds.size());
456c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        return std::string{};
457cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
458c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh
459c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    return mNormalDeviceIds[cameraIdInt];
460c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh}
461c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh
462c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia YehString8 CameraService::cameraIdIntToStr(int cameraIdInt) {
463c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    Mutex::Autolock lock(mServiceLock);
464c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    return String8(cameraIdIntToStrLocked(cameraIdInt).c_str());
465cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
466b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk
4672f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville TalvalaStatus CameraService::getCameraCharacteristics(const String16& cameraId,
468f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        CameraMetadata* cameraInfo) {
469a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
4702b59be89dc245b6e2475d9e8b0c5f2392370e71eZhijun He    if (!cameraInfo) {
4712b59be89dc245b6e2475d9e8b0c5f2392370e71eZhijun He        ALOGE("%s: cameraInfo is NULL", __FUNCTION__);
472d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "cameraInfo is NULL");
4732b59be89dc245b6e2475d9e8b0c5f2392370e71eZhijun He    }
4742b59be89dc245b6e2475d9e8b0c5f2392370e71eZhijun He
4752f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (!mInitialized) {
4762f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        ALOGE("%s: Camera HAL couldn't be initialized", __FUNCTION__);
477d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(ERROR_DISCONNECTED,
478d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "Camera subsystem is not available");;
4792b59be89dc245b6e2475d9e8b0c5f2392370e71eZhijun He    }
4802b59be89dc245b6e2475d9e8b0c5f2392370e71eZhijun He
4812f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    Status ret{};
482f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
483f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    status_t res = mCameraProviderManager->getCameraCharacteristics(
484f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev            String8(cameraId).string(), cameraInfo);
485f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    if (res != OK) {
486f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev        return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, "Unable to retrieve camera "
487f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev                "characteristics for device %s: %s (%d)", String8(cameraId).string(),
488f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev                strerror(-res), res);
489f05e50eb06d3f70e50fa7f44c1fd32128033b49dZhijun He    }
490f05e50eb06d3f70e50fa7f44c1fd32128033b49dZhijun He
4912b59be89dc245b6e2475d9e8b0c5f2392370e71eZhijun He    return ret;
4922b59be89dc245b6e2475d9e8b0c5f2392370e71eZhijun He}
4932b59be89dc245b6e2475d9e8b0c5f2392370e71eZhijun He
494cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkint CameraService::getCallingPid() {
495cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return IPCThreadState::self()->getCallingPid();
496cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
497cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
498cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkint CameraService::getCallingUid() {
499cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return IPCThreadState::self()->getCallingUid();
500cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
501cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
502cc776718c0be7c31fe5ab4fc1446d377be60369fRuben BrunkString8 CameraService::getFormattedCurrentTime() {
503cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    time_t now = time(nullptr);
504cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    char formattedTime[64];
505cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    strftime(formattedTime, sizeof(formattedTime), "%m-%d %H:%M:%S", localtime(&now));
506cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return String8(formattedTime);
507cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
508cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
509d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::getCameraVendorTagDescriptor(
510d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        /*out*/
511d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        hardware::camera2::params::VendorTagDescriptor* desc) {
512a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
5132f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (!mInitialized) {
5142f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        ALOGE("%s: Camera HAL couldn't be initialized", __FUNCTION__);
515d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(ERROR_DISCONNECTED, "Camera subsystem not available");
516d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk    }
5171e74e241f5a4e0e763e27c888561405d013c9ca0Eino-Ville Talvala    sp<VendorTagDescriptor> globalDescriptor = VendorTagDescriptor::getGlobalVendorTagDescriptor();
5181e74e241f5a4e0e763e27c888561405d013c9ca0Eino-Ville Talvala    if (globalDescriptor != nullptr) {
5191e74e241f5a4e0e763e27c888561405d013c9ca0Eino-Ville Talvala        *desc = *(globalDescriptor.get());
5201e74e241f5a4e0e763e27c888561405d013c9ca0Eino-Ville Talvala    }
521d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return Status::ok();
522d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk}
523d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk
52471c73a2985a7ac65ee597be3441ab300fa56e22eEmilian PeevStatus CameraService::getCameraVendorTagCache(
52571c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev        /*out*/ hardware::camera2::params::VendorTagDescriptorCache* cache) {
52671c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    ATRACE_CALL();
52771c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    if (!mInitialized) {
52871c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev        ALOGE("%s: Camera HAL couldn't be initialized", __FUNCTION__);
52971c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev        return STATUS_ERROR(ERROR_DISCONNECTED,
53071c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                "Camera subsystem not available");
53171c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    }
53271c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    sp<VendorTagDescriptorCache> globalCache =
53371c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev            VendorTagDescriptorCache::getGlobalVendorTagCache();
53471c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    if (globalCache != nullptr) {
53571c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev        *cache = *(globalCache.get());
53671c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    }
53771c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    return Status::ok();
53871c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev}
53971c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev
5402f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalaint CameraService::getDeviceVersion(const String8& cameraId, int* facing) {
541a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
542634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
5432f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    int deviceVersion = 0;
544634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
545f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    status_t res;
546f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    hardware::hidl_version maxVersion{0,0};
547f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    res = mCameraProviderManager->getHighestSupportedVersion(cameraId.string(),
548f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev            &maxVersion);
549f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    if (res != OK) return -1;
550f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    deviceVersion = HARDWARE_DEVICE_API_VERSION(maxVersion.get_major(), maxVersion.get_minor());
551f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev
552f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    hardware::CameraInfo info;
553f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    if (facing) {
554f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev        res = mCameraProviderManager->getCameraInfo(cameraId.string(), &info);
5556963d0ad7b621dcdaa74cbfed17c776121635146Eino-Ville Talvala        if (res != OK) return -1;
556f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev        *facing = info.facing;
5572f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
558f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev
559634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    return deviceVersion;
560634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
561634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
562d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::filterGetInfoErrorCode(status_t err) {
563f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala    switch(err) {
564f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala        case NO_ERROR:
565d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return Status::ok();
566f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        case BAD_VALUE:
567d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT,
568d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    "CameraId is not valid for HAL module");
569f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        case NO_INIT:
570d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return STATUS_ERROR(ERROR_DISCONNECTED,
571d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    "Camera device not available");
572f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala        default:
573d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
574d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    "Camera HAL encountered error %d: %s",
575d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    err, strerror(-err));
576f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala    }
577bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin}
578bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
579d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::makeClient(const sp<CameraService>& cameraService,
5802f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        const sp<IInterface>& cameraCb, const String16& packageName, const String8& cameraId,
581c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        int api1CameraId, int facing, int clientPid, uid_t clientUid, int servicePid,
582c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        bool legacyMode, int halVersion, int deviceVersion, apiLevel effectiveApiLevel,
583cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        /*out*/sp<BasicClient>* client) {
584b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk
585cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    if (halVersion < 0 || halVersion == deviceVersion) {
586cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // Default path: HAL version is unspecified by caller, create CameraClient
587cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // based on device version reported by the HAL.
588cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        switch(deviceVersion) {
589cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk          case CAMERA_DEVICE_API_VERSION_1_0:
590cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            if (effectiveApiLevel == API_1) {  // Camera1 API route
591cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
592c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                *client = new CameraClient(cameraService, tmp, packageName,
593c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                        api1CameraId, facing, clientPid, clientUid,
594c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                        getpid(), legacyMode);
595cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            } else { // Camera2 API route
596cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                ALOGW("Camera using old HAL version: %d", deviceVersion);
597d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                return STATUS_ERROR_FMT(ERROR_DEPRECATED_HAL,
5982f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                        "Camera device \"%s\" HAL version %d does not support camera2 API",
5992f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                        cameraId.string(), deviceVersion);
600cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            }
601cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            break;
602cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk          case CAMERA_DEVICE_API_VERSION_3_0:
603cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk          case CAMERA_DEVICE_API_VERSION_3_1:
604cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk          case CAMERA_DEVICE_API_VERSION_3_2:
605cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk          case CAMERA_DEVICE_API_VERSION_3_3:
6064afbdecf8c6dc5ad04f6fa6c8712ce2c56a00c47Zhijun He          case CAMERA_DEVICE_API_VERSION_3_4:
607cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            if (effectiveApiLevel == API_1) { // Camera1 API route
608cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
609c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                *client = new Camera2Client(cameraService, tmp, packageName,
610c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                        cameraId, api1CameraId,
611c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                        facing, clientPid, clientUid,
612c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                        servicePid, legacyMode);
613cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            } else { // Camera2 API route
614d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                sp<hardware::camera2::ICameraDeviceCallbacks> tmp =
615d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                        static_cast<hardware::camera2::ICameraDeviceCallbacks*>(cameraCb.get());
616d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                *client = new CameraDeviceClient(cameraService, tmp, packageName, cameraId,
617cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                        facing, clientPid, clientUid, servicePid);
618b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk            }
619cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            break;
620cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk          default:
621cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            // Should not be reachable
622cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            ALOGE("Unknown camera device HAL version: %d", deviceVersion);
623d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
6242f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                    "Camera device \"%s\" has unknown HAL version %d",
6252f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                    cameraId.string(), deviceVersion);
626b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk        }
627cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    } else {
628cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // A particular HAL version is requested by caller. Create CameraClient
629cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // based on the requested HAL version.
630cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        if (deviceVersion > CAMERA_DEVICE_API_VERSION_1_0 &&
631cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            halVersion == CAMERA_DEVICE_API_VERSION_1_0) {
632cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            // Only support higher HAL version device opened as HAL1.0 device.
633cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
634c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            *client = new CameraClient(cameraService, tmp, packageName,
635c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                    api1CameraId, facing, clientPid, clientUid,
636c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                    servicePid, legacyMode);
637cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        } else {
638cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            // Other combinations (e.g. HAL3.x open as HAL2.x) are not supported yet.
639cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            ALOGE("Invalid camera HAL version %x: HAL %x device can only be"
640cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    " opened as HAL %x device", halVersion, deviceVersion,
641cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    CAMERA_DEVICE_API_VERSION_1_0);
642d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
6432f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                    "Camera device \"%s\" (HAL version %d) cannot be opened as HAL version %d",
6442f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                    cameraId.string(), deviceVersion, halVersion);
645b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk        }
646b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk    }
647d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return Status::ok();
648cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
649cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
6506267b539d0d1ee7118aafd976d75cb8db397bc24Ruben BrunkString8 CameraService::toString(std::set<userid_t> intSet) {
6516267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk    String8 s("");
6526267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk    bool first = true;
6536267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk    for (userid_t i : intSet) {
6546267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        if (first) {
6556267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk            s.appendFormat("%d", i);
6566267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk            first = false;
6576267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        } else {
6586267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk            s.appendFormat(", %d", i);
6596267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        }
6606267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk    }
6616267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk    return s;
6626267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk}
6636267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk
664f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalaint32_t CameraService::mapToInterface(TorchModeStatus status) {
665f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    int32_t serviceStatus = ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE;
666f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    switch (status) {
667f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        case TorchModeStatus::NOT_AVAILABLE:
668f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            serviceStatus = ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE;
669f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            break;
670f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        case TorchModeStatus::AVAILABLE_OFF:
671f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            serviceStatus = ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF;
672f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            break;
673f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        case TorchModeStatus::AVAILABLE_ON:
674f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            serviceStatus = ICameraServiceListener::TORCH_STATUS_AVAILABLE_ON;
675f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            break;
676f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        default:
677f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            ALOGW("Unknown new flash status: %d", status);
678f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    }
679f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    return serviceStatus;
680f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala}
681f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
682f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville TalvalaCameraService::StatusInternal CameraService::mapToInternal(CameraDeviceStatus status) {
683f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    StatusInternal serviceStatus = StatusInternal::NOT_PRESENT;
684f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    switch (status) {
685f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        case CameraDeviceStatus::NOT_PRESENT:
686f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            serviceStatus = StatusInternal::NOT_PRESENT;
687f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            break;
688f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        case CameraDeviceStatus::PRESENT:
689f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            serviceStatus = StatusInternal::PRESENT;
690f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            break;
691f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        case CameraDeviceStatus::ENUMERATING:
692f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            serviceStatus = StatusInternal::ENUMERATING;
693f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            break;
694f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        default:
695f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            ALOGW("Unknown new HAL device status: %d", status);
696f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    }
697f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    return serviceStatus;
698f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala}
699f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
700f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalaint32_t CameraService::mapToInterface(StatusInternal status) {
701f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    int32_t serviceStatus = ICameraServiceListener::STATUS_NOT_PRESENT;
702f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    switch (status) {
703f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        case StatusInternal::NOT_PRESENT:
704f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            serviceStatus = ICameraServiceListener::STATUS_NOT_PRESENT;
705f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            break;
706f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        case StatusInternal::PRESENT:
707f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            serviceStatus = ICameraServiceListener::STATUS_PRESENT;
708f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            break;
709f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        case StatusInternal::ENUMERATING:
710f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            serviceStatus = ICameraServiceListener::STATUS_ENUMERATING;
711f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            break;
712f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        case StatusInternal::NOT_AVAILABLE:
713f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            serviceStatus = ICameraServiceListener::STATUS_NOT_AVAILABLE;
714f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            break;
715f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        case StatusInternal::UNKNOWN:
716f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            serviceStatus = ICameraServiceListener::STATUS_UNKNOWN;
717f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            break;
718f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        default:
719f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            ALOGW("Unknown new internal device status: %d", status);
720f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    }
721f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    return serviceStatus;
722f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala}
723f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
724d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::initializeShimMetadata(int cameraId) {
725cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    int uid = getCallingUid();
726b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk
72798a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen    String16 internalPackageName("cameraserver");
728cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    String8 id = String8::format("%d", cameraId);
729d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    Status ret = Status::ok();
730cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    sp<Client> tmp = nullptr;
731d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (!(ret = connectHelper<ICameraClient,Client>(
732c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            sp<ICameraClient>{nullptr}, id, cameraId,
733c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            static_cast<int>(CAMERA_HAL_API_VERSION_UNSPECIFIED),
734d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            internalPackageName, uid, USE_CALLING_PID,
735d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            API_1, /*legacyMode*/ false, /*shimUpdateOnly*/ true,
736d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            /*out*/ tmp)
737d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            ).isOk()) {
738d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        ALOGE("%s: Error initializing shim metadata: %s", __FUNCTION__, ret.toString8().string());
739b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk    }
740d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return ret;
741b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk}
742b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk
743d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::getLegacyParametersLazy(int cameraId,
74465d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin        /*out*/
74565d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin        CameraParameters* parameters) {
74665d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
74765d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    ALOGV("%s: for cameraId: %d", __FUNCTION__, cameraId);
74865d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
749d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    Status ret = Status::ok();
75065d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
75165d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    if (parameters == NULL) {
75265d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin        ALOGE("%s: parameters must not be null", __FUNCTION__);
753d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Parameters must not be null");
75465d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    }
75565d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
756cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    String8 id = String8::format("%d", cameraId);
75765d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
758cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    // Check if we already have parameters
759cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    {
760cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // Scope for service lock
761cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        Mutex::Autolock lock(mServiceLock);
762cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        auto cameraState = getCameraState(id);
763cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        if (cameraState == nullptr) {
764cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            ALOGE("%s: Invalid camera ID: %s", __FUNCTION__, id.string());
765d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
766d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    "Invalid camera ID: %s", id.string());
76765d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin        }
768cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        CameraParameters p = cameraState->getShimParams();
769cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        if (!p.isEmpty()) {
770cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            *parameters = p;
771d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return ret;
77265d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin        }
773cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
77465d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
775cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    int64_t token = IPCThreadState::self()->clearCallingIdentity();
776cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    ret = initializeShimMetadata(cameraId);
777cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    IPCThreadState::self()->restoreCallingIdentity(token);
778d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (!ret.isOk()) {
779cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // Error already logged by callee
780cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        return ret;
781cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
78265d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
783cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    // Check for parameters again
784cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    {
785cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // Scope for service lock
786cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        Mutex::Autolock lock(mServiceLock);
787cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        auto cameraState = getCameraState(id);
788cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        if (cameraState == nullptr) {
789cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            ALOGE("%s: Invalid camera ID: %s", __FUNCTION__, id.string());
790d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
791d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    "Invalid camera ID: %s", id.string());
792cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        }
793cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        CameraParameters p = cameraState->getShimParams();
794cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        if (!p.isEmpty()) {
795cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            *parameters = p;
796d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return ret;
79765d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin        }
79865d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    }
79965d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
800cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    ALOGE("%s: Parameters were not initialized, or were empty.  Device may not be present.",
801cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            __FUNCTION__);
802d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return STATUS_ERROR(ERROR_INVALID_OPERATION, "Unable to initialize legacy parameters");
80365d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin}
80465d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
80598a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen// Can camera service trust the caller based on the calling UID?
80698a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chenstatic bool isTrustedCallingUid(uid_t uid) {
80798a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen    switch (uid) {
808af9d030e075e659e9f50fdd143aa83459a7795e2Eino-Ville Talvala        case AID_MEDIA:        // mediaserver
80998a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen        case AID_CAMERASERVER: // cameraserver
810af9d030e075e659e9f50fdd143aa83459a7795e2Eino-Ville Talvala        case AID_RADIO:        // telephony
81198a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen            return true;
81298a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen        default:
81398a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen            return false;
81498a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen    }
81598a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen}
81698a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen
817d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::validateConnectLocked(const String8& cameraId,
81818df60e094edbaa08cbecd25b0398643b8a0f29aChien-Yu Chen        const String8& clientName8, /*inout*/int& clientUid, /*inout*/int& clientPid,
81918df60e094edbaa08cbecd25b0398643b8a0f29aChien-Yu Chen        /*out*/int& originalClientPid) const {
8205861a9a98c641261c4807c976c750e4611b3a57dTyler Luu
8219c2a2c26c0d70de97f51063b06a5efc79b327eedAlex Deymo#ifdef __BRILLO__
8229c2a2c26c0d70de97f51063b06a5efc79b327eedAlex Deymo    UNUSED(clientName8);
8239c2a2c26c0d70de97f51063b06a5efc79b327eedAlex Deymo    UNUSED(clientUid);
8249c2a2c26c0d70de97f51063b06a5efc79b327eedAlex Deymo    UNUSED(clientPid);
8259c2a2c26c0d70de97f51063b06a5efc79b327eedAlex Deymo    UNUSED(originalClientPid);
8269c2a2c26c0d70de97f51063b06a5efc79b327eedAlex Deymo#else
8277939aee8c1688bc8647c5bceb0d47a4e790ff27dChien-Yu Chen    Status allowed = validateClientPermissionsLocked(cameraId, clientName8, clientUid, clientPid,
8287939aee8c1688bc8647c5bceb0d47a4e790ff27dChien-Yu Chen            originalClientPid);
8290492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala    if (!allowed.isOk()) {
830ce761d1fef4da2a4dec3eb538d103fcde1971dbaChristopher Wiley        return allowed;
831ce761d1fef4da2a4dec3eb538d103fcde1971dbaChristopher Wiley    }
8329c2a2c26c0d70de97f51063b06a5efc79b327eedAlex Deymo#endif  // __BRILLO__
833ce761d1fef4da2a4dec3eb538d103fcde1971dbaChristopher Wiley
8340492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala    int callingPid = getCallingPid();
8350492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala
8362f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (!mInitialized) {
837cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        ALOGE("CameraService::connect X (PID %d) rejected (camera HAL module not loaded)",
838cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                callingPid);
8390492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala        return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
8400492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala                "No camera HAL module available to open camera device \"%s\"", cameraId.string());
8418951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    }
8428951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev
843cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    if (getCameraState(cameraId) == nullptr) {
844cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        ALOGE("CameraService::connect X (PID %d) rejected (invalid camera ID %s)", callingPid,
845cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                cameraId.string());
8460492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala        return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
8470492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala                "No camera device with ID \"%s\" available", cameraId.string());
84865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
84965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
8500492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala    status_t err = checkIfDeviceIsUsable(cameraId);
8510492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala    if (err != NO_ERROR) {
8520492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala        switch(err) {
8530492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala            case -ENODEV:
8540492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala            case -EBUSY:
8550492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala                return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
8560492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala                        "No camera device with ID \"%s\" currently available", cameraId.string());
8570492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala            default:
8580492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala                return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
8590492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala                        "Unknown error connecting to ID \"%s\"", cameraId.string());
8600492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala        }
8610492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala    }
8620492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala    return Status::ok();
8630039bcf0c4f10b92917c26df70c7847f1ab0b51eChristopher Wiley}
8640039bcf0c4f10b92917c26df70c7847f1ab0b51eChristopher Wiley
8650492686c4703b3ddbff52d047ef226b973a3388aEino-Ville TalvalaStatus CameraService::validateClientPermissionsLocked(const String8& cameraId,
8667939aee8c1688bc8647c5bceb0d47a4e790ff27dChien-Yu Chen        const String8& clientName8, int& clientUid, int& clientPid,
8677939aee8c1688bc8647c5bceb0d47a4e790ff27dChien-Yu Chen        /*out*/int& originalClientPid) const {
8680039bcf0c4f10b92917c26df70c7847f1ab0b51eChristopher Wiley    int callingPid = getCallingPid();
86998a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen    int callingUid = getCallingUid();
8705861a9a98c641261c4807c976c750e4611b3a57dTyler Luu
87198a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen    // Check if we can trust clientUid
872ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    if (clientUid == USE_CALLING_UID) {
87398a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen        clientUid = callingUid;
87498a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen    } else if (!isTrustedCallingUid(callingUid)) {
87598a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen        ALOGE("CameraService::connect X (calling PID %d, calling UID %d) rejected "
87698a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen                "(don't trust clientUid %d)", callingPid, callingUid, clientUid);
877d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
878d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "Untrusted caller (calling PID %d, UID %d) trying to "
879d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "forward camera access to camera %s for client %s (PID %d, UID %d)",
880d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                callingPid, callingUid, cameraId.string(),
881d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                clientName8.string(), clientUid, clientPid);
88298a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen    }
88398a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen
88498a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen    // Check if we can trust clientPid
88598a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen    if (clientPid == USE_CALLING_PID) {
88698a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen        clientPid = callingPid;
88798a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen    } else if (!isTrustedCallingUid(callingUid)) {
88898a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen        ALOGE("CameraService::connect X (calling PID %d, calling UID %d) rejected "
88998a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen                "(don't trust clientPid %d)", callingPid, callingUid, clientPid);
890d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
891d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "Untrusted caller (calling PID %d, UID %d) trying to "
892d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "forward camera access to camera %s for client %s (PID %d, UID %d)",
893d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                callingPid, callingUid, cameraId.string(),
894d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                clientName8.string(), clientUid, clientPid);
895ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    }
89665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
89798a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen    // If it's not calling from cameraserver, check the permission.
89898a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen    if (callingPid != getpid() &&
89998a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen            !checkPermission(String16("android.permission.CAMERA"), clientPid, clientUid)) {
90098a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen        ALOGE("Permission Denial: can't use the camera pid=%d, uid=%d", clientPid, clientUid);
901d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
902d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "Caller \"%s\" (PID %d, UID %d) cannot open camera \"%s\" without camera permission",
903d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                clientName8.string(), clientUid, clientPid, cameraId.string());
904ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    }
90565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
906a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    // Make sure the UID is in an active state to use the camera
907a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    if (!mUidPolicy->isUidActive(callingUid)) {
908a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        ALOGE("Access Denial: can't use the camera from an idle UID pid=%d, uid=%d",
909a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            clientPid, clientUid);
910a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        return STATUS_ERROR_FMT(ERROR_DISABLED,
911a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov                "Caller \"%s\" (PID %d, UID %d) cannot open camera \"%s\" from background",
912a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov                clientName8.string(), clientUid, clientPid, cameraId.string());
913a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
914a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
9154f3d6203c71f9e76fbd2964ad54a81b7036f7e17Chien-Yu Chen    // Only use passed in clientPid to check permission. Use calling PID as the client PID that's
9164f3d6203c71f9e76fbd2964ad54a81b7036f7e17Chien-Yu Chen    // connected to camera service directly.
91718df60e094edbaa08cbecd25b0398643b8a0f29aChien-Yu Chen    originalClientPid = clientPid;
9184f3d6203c71f9e76fbd2964ad54a81b7036f7e17Chien-Yu Chen    clientPid = callingPid;
91965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
9206267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk    userid_t clientUserId = multiuser_get_user_id(clientUid);
921a3355430a36bbfa7b2c0d90eb30834f1c5dac337Wu-cheng Li
922a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    // Only allow clients who are being used by the current foreground device user, unless calling
923a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    // from our own process.
9246267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk    if (callingPid != getpid() && (mAllowedUsers.find(clientUserId) == mAllowedUsers.end())) {
9256267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        ALOGE("CameraService::connect X (PID %d) rejected (cannot connect from "
9266267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk                "device user %d, currently allowed device users: %s)", callingPid, clientUserId,
9276267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk                toString(mAllowedUsers).string());
928d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
929d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "Callers from device user %d are not currently allowed to connect to camera \"%s\"",
930d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                clientUserId, cameraId.string());
93136597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    }
93236597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
933d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return Status::ok();
934cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
935cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
936cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkstatus_t CameraService::checkIfDeviceIsUsable(const String8& cameraId) const {
937cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    auto cameraState = getCameraState(cameraId);
938cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    int callingPid = getCallingPid();
939cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    if (cameraState == nullptr) {
940cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        ALOGE("CameraService::connect X (PID %d) rejected (invalid camera ID %s)", callingPid,
941cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                cameraId.string());
942cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        return -ENODEV;
943cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
944cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
945f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    StatusInternal currentStatus = cameraState->getStatus();
946f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    if (currentStatus == StatusInternal::NOT_PRESENT) {
947cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        ALOGE("CameraService::connect X (PID %d) rejected (camera %s is not connected)",
948cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                callingPid, cameraId.string());
9490f61d8f14aa368c9cd7076528e8096e10ed100a0Ruben Brunk        return -ENODEV;
950f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    } else if (currentStatus == StatusInternal::ENUMERATING) {
951cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        ALOGE("CameraService::connect X (PID %d) rejected, (camera %s is initializing)",
952cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                callingPid, cameraId.string());
9530f61d8f14aa368c9cd7076528e8096e10ed100a0Ruben Brunk        return -EBUSY;
954cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin    }
955cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin
956cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return NO_ERROR;
957e6800cea0678dbc0bf697b44c3e4548b0253085cIgor Murashkin}
958e6800cea0678dbc0bf697b44c3e4548b0253085cIgor Murashkin
959cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkvoid CameraService::finishConnectLocked(const sp<BasicClient>& client,
960cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        const CameraService::DescriptorPtr& desc) {
961e6800cea0678dbc0bf697b44c3e4548b0253085cIgor Murashkin
962cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    // Make a descriptor for the incoming client
963cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    auto clientDescriptor = CameraService::CameraClientManager::makeClientDescriptor(client, desc);
964cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    auto evicted = mActiveClientManager.addAndEvict(clientDescriptor);
965cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
966cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    logConnected(desc->getKey(), static_cast<int>(desc->getOwnerId()),
967cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            String8(client->getPackageName()));
968cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
969cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    if (evicted.size() > 0) {
970cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // This should never happen - clients should already have been removed in disconnect
971cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        for (auto& i : evicted) {
972cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            ALOGE("%s: Invalid state: Client for camera %s was not removed in disconnect",
973cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    __FUNCTION__, i->getKey().string());
9742fd2440d0175ca3e196b01b7541a9e0d4ed9a694Wu-cheng Li        }
975e6800cea0678dbc0bf697b44c3e4548b0253085cIgor Murashkin
976cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        LOG_ALWAYS_FATAL("%s: Invalid state for CameraService, clients not evicted properly",
977cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                __FUNCTION__);
978cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
97924901c86e10a0923fe10f5e9bce5e6dba061a289Eino-Ville Talvala
98024901c86e10a0923fe10f5e9bce5e6dba061a289Eino-Ville Talvala    // And register a death notification for the client callback. Do
98124901c86e10a0923fe10f5e9bce5e6dba061a289Eino-Ville Talvala    // this last to avoid Binder policy where a nested Binder
98224901c86e10a0923fe10f5e9bce5e6dba061a289Eino-Ville Talvala    // transaction might be pre-empted to service the client death
98324901c86e10a0923fe10f5e9bce5e6dba061a289Eino-Ville Talvala    // notification if the client process dies before linkToDeath is
98424901c86e10a0923fe10f5e9bce5e6dba061a289Eino-Ville Talvala    // invoked.
98524901c86e10a0923fe10f5e9bce5e6dba061a289Eino-Ville Talvala    sp<IBinder> remoteCallback = client->getRemote();
98624901c86e10a0923fe10f5e9bce5e6dba061a289Eino-Ville Talvala    if (remoteCallback != nullptr) {
98724901c86e10a0923fe10f5e9bce5e6dba061a289Eino-Ville Talvala        remoteCallback->linkToDeath(this);
98824901c86e10a0923fe10f5e9bce5e6dba061a289Eino-Ville Talvala    }
989e6800cea0678dbc0bf697b44c3e4548b0253085cIgor Murashkin}
990e6800cea0678dbc0bf697b44c3e4548b0253085cIgor Murashkin
991cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkstatus_t CameraService::handleEvictionsLocked(const String8& cameraId, int clientPid,
992cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        apiLevel effectiveApiLevel, const sp<IBinder>& remoteCallback, const String8& packageName,
993a858ea0495c887621a2fd9c0afc13780deccb597Igor Murashkin        /*out*/
994cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        sp<BasicClient>* client,
995cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>* partial) {
996a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
997cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    status_t ret = NO_ERROR;
9984f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk    std::vector<DescriptorPtr> evictedClients;
999cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    DescriptorPtr clientDescriptor;
1000cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    {
1001cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        if (effectiveApiLevel == API_1) {
1002cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            // If we are using API1, any existing client for this camera ID with the same remote
1003cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            // should be returned rather than evicted to allow MediaRecorder to work properly.
1004cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1005cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            auto current = mActiveClientManager.get(cameraId);
1006cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            if (current != nullptr) {
1007cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                auto clientSp = current->getValue();
1008cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                if (clientSp.get() != nullptr) { // should never be needed
10090bbf8b213ad96051357e3ad6d6d2808bfa31a59aRuben Brunk                    if (!clientSp->canCastToApiClient(effectiveApiLevel)) {
10100bbf8b213ad96051357e3ad6d6d2808bfa31a59aRuben Brunk                        ALOGW("CameraService connect called from same client, but with a different"
10110bbf8b213ad96051357e3ad6d6d2808bfa31a59aRuben Brunk                                " API level, evicting prior client...");
10120bbf8b213ad96051357e3ad6d6d2808bfa31a59aRuben Brunk                    } else if (clientSp->getRemote() == remoteCallback) {
1013cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                        ALOGI("CameraService::connect X (PID %d) (second call from same"
10140bbf8b213ad96051357e3ad6d6d2808bfa31a59aRuben Brunk                                " app binder, returning the same client)", clientPid);
1015cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                        *client = clientSp;
1016cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                        return NO_ERROR;
1017cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    }
1018cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                }
1019cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            }
1020cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        }
10213068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
1022cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // Get current active client PIDs
1023cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        std::vector<int> ownerPids(mActiveClientManager.getAllOwners());
1024cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        ownerPids.push_back(clientPid);
1025cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
10268131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev        std::vector<int> priorityScores(ownerPids.size());
10278131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev        std::vector<int> states(ownerPids.size());
1028cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
10298131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev        // Get priority scores of all active PIDs
10308131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev        status_t err = ProcessInfoService::getProcessStatesScoresFromPids(
10318131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                ownerPids.size(), &ownerPids[0], /*out*/&states[0],
10328131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                /*out*/&priorityScores[0]);
10338131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev        if (err != OK) {
10348131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev            ALOGE("%s: Priority score query failed: %d",
10358131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                  __FUNCTION__, err);
10368131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev            return err;
10378131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev        }
1038cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1039cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // Update all active clients' priorities
10408131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev        std::map<int,resource_policy::ClientPriority> pidToPriorityMap;
1041cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        for (size_t i = 0; i < ownerPids.size() - 1; i++) {
10428131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev            pidToPriorityMap.emplace(ownerPids[i],
10438131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                    resource_policy::ClientPriority(priorityScores[i], states[i]));
1044cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        }
1045cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        mActiveClientManager.updatePriorities(pidToPriorityMap);
1046cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1047cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // Get state for the given cameraId
1048cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        auto state = getCameraState(cameraId);
1049cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        if (state == nullptr) {
1050cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            ALOGE("CameraService::connect X (PID %d) rejected (no camera device with ID %s)",
1051cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                clientPid, cameraId.string());
1052d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            // Should never get here because validateConnectLocked should have errored out
1053b10cdadf0fb945e23ca77008d4af76584bd0e39aZhijun He            return BAD_VALUE;
1054b10cdadf0fb945e23ca77008d4af76584bd0e39aZhijun He        }
1055cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1056cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // Make descriptor for incoming client
1057cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        clientDescriptor = CameraClientManager::makeClientDescriptor(cameraId,
1058cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                sp<BasicClient>{nullptr}, static_cast<int32_t>(state->getCost()),
1059cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                state->getConflicting(),
10608131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                priorityScores[priorityScores.size() - 1],
10618131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                clientPid,
10628131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                states[states.size() - 1]);
1063cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1064cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // Find clients that would be evicted
1065cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        auto evicted = mActiveClientManager.wouldEvict(clientDescriptor);
1066cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1067cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // If the incoming client was 'evicted,' higher priority clients have the camera in the
1068cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // background, so we cannot do evictions
1069cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        if (std::find(evicted.begin(), evicted.end(), clientDescriptor) != evicted.end()) {
1070cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            ALOGE("CameraService::connect X (PID %d) rejected (existing client(s) with higher"
1071cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    " priority).", clientPid);
1072cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1073cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            sp<BasicClient> clientSp = clientDescriptor->getValue();
1074cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            String8 curTime = getFormattedCurrentTime();
1075cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            auto incompatibleClients =
1076cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    mActiveClientManager.getIncompatibleClients(clientDescriptor);
1077cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1078cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            String8 msg = String8::format("%s : DENIED connect device %s client for package %s "
10798131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                    "(PID %d, score %d state %d) due to eviction policy", curTime.string(),
1080cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    cameraId.string(), packageName.string(), clientPid,
10818131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                    priorityScores[priorityScores.size() - 1],
10828131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                    states[states.size() - 1]);
1083cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1084cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            for (auto& i : incompatibleClients) {
1085cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                msg.appendFormat("\n   - Blocked by existing device %s client for package %s"
10868131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                        "(PID %" PRId32 ", score %" PRId32 ", state %" PRId32 ")",
10878131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                        i->getKey().string(),
10888131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                        String8{i->getValue()->getPackageName()}.string(),
10898131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                        i->getOwnerId(), i->getPriority().getScore(),
10908131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                        i->getPriority().getState());
1091022f0cb0c6f135edde4ebe84859c685933ee895eEino-Ville Talvala                ALOGE("   Conflicts with: Device %s, client package %s (PID %"
10928131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                        PRId32 ", score %" PRId32 ", state %" PRId32 ")", i->getKey().string(),
1093022f0cb0c6f135edde4ebe84859c685933ee895eEino-Ville Talvala                        String8{i->getValue()->getPackageName()}.string(), i->getOwnerId(),
10948131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                        i->getPriority().getScore(), i->getPriority().getState());
1095cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            }
1096cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1097cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            // Log the client's attempt
1098a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk            Mutex::Autolock l(mLogLock);
1099cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            mEventLog.add(msg);
1100cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1101cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            return -EBUSY;
1102cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        }
1103cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1104cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        for (auto& i : evicted) {
1105cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            sp<BasicClient> clientSp = i->getValue();
1106cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            if (clientSp.get() == nullptr) {
1107cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                ALOGE("%s: Invalid state: Null client in active client list.", __FUNCTION__);
1108cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1109cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                // TODO: Remove this
1110cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                LOG_ALWAYS_FATAL("%s: Invalid state for CameraService, null client in active list",
1111cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                        __FUNCTION__);
1112cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                mActiveClientManager.remove(i);
1113cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                continue;
1114cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            }
1115cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1116cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            ALOGE("CameraService::connect evicting conflicting client for camera ID %s",
1117cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    i->getKey().string());
11184f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk            evictedClients.push_back(i);
1119cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1120cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            // Log the clients evicted
1121a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk            logEvent(String8::format("EVICT device %s client held by package %s (PID"
11228131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                    " %" PRId32 ", score %" PRId32 ", state %" PRId32 ")\n - Evicted by device %s client for"
11238131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                    " package %s (PID %d, score %" PRId32 ", state %" PRId32 ")",
1124cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    i->getKey().string(), String8{clientSp->getPackageName()}.string(),
11258131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                    i->getOwnerId(), i->getPriority().getScore(),
11268131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                    i->getPriority().getState(), cameraId.string(),
1127cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    packageName.string(), clientPid,
11288131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                    priorityScores[priorityScores.size() - 1],
11298131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                    states[states.size() - 1]));
1130cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1131cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            // Notify the client of disconnection
1132d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            clientSp->notifyError(hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED,
1133cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    CaptureResultExtras());
1134b10cdadf0fb945e23ca77008d4af76584bd0e39aZhijun He        }
1135b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk    }
1136b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk
1137cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    // Do not hold mServiceLock while disconnecting clients, but retain the condition blocking
1138cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    // other clients from connecting in mServiceLockWrapper if held
1139cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    mServiceLock.unlock();
1140cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1141cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    // Clear caller identity temporarily so client disconnect PID checks work correctly
1142cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    int64_t token = IPCThreadState::self()->clearCallingIdentity();
1143cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1144cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    // Destroy evicted clients
1145cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    for (auto& i : evictedClients) {
1146cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // Disconnect is blocking, and should only have returned when HAL has cleaned up
11474f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk        i->getValue()->disconnect(); // Clients will remove themselves from the active client list
1148b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk    }
1149b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk
1150cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    IPCThreadState::self()->restoreCallingIdentity(token);
1151b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk
11524f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk    for (const auto& i : evictedClients) {
11534f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk        ALOGV("%s: Waiting for disconnect to complete for client for device %s (PID %" PRId32 ")",
11544f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk                __FUNCTION__, i->getKey().string(), i->getOwnerId());
11554f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk        ret = mActiveClientManager.waitUntilRemoved(i, DEFAULT_DISCONNECT_TIMEOUT_NS);
11564f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk        if (ret == TIMED_OUT) {
11574f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk            ALOGE("%s: Timed out waiting for client for device %s to disconnect, "
11584f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk                    "current clients:\n%s", __FUNCTION__, i->getKey().string(),
11594f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk                    mActiveClientManager.toString().string());
11604f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk            return -EBUSY;
11614f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk        }
11624f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk        if (ret != NO_ERROR) {
11634f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk            ALOGE("%s: Received error waiting for client for device %s to disconnect: %s (%d), "
11644f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk                    "current clients:\n%s", __FUNCTION__, i->getKey().string(), strerror(-ret),
11654f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk                    ret, mActiveClientManager.toString().string());
11664f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk            return ret;
11674f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk        }
11684f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk    }
11694f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk
11704f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk    evictedClients.clear();
11714f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk
1172cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    // Once clients have been disconnected, relock
1173cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    mServiceLock.lock();
1174cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1175cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    // Check again if the device was unplugged or something while we weren't holding mServiceLock
1176cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    if ((ret = checkIfDeviceIsUsable(cameraId)) != NO_ERROR) {
1177cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        return ret;
1178cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
1179cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1180cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    *partial = clientDescriptor;
1181cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return NO_ERROR;
1182b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk}
1183b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk
1184d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::connect(
1185e6800cea0678dbc0bf697b44c3e4548b0253085cIgor Murashkin        const sp<ICameraClient>& cameraClient,
1186c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        int api1CameraId,
1187280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov        const String16& clientPackageName,
11880f61d8f14aa368c9cd7076528e8096e10ed100a0Ruben Brunk        int clientUid,
118998a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen        int clientPid,
11900f61d8f14aa368c9cd7076528e8096e10ed100a0Ruben Brunk        /*out*/
1191d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        sp<ICamera>* device) {
1192e6800cea0678dbc0bf697b44c3e4548b0253085cIgor Murashkin
1193a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
1194d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    Status ret = Status::ok();
1195c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh
1196c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    String8 id = cameraIdIntToStr(api1CameraId);
1197cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    sp<Client> client = nullptr;
1198c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    ret = connectHelper<ICameraClient,Client>(cameraClient, id, api1CameraId,
1199d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageName, clientUid, clientPid, API_1,
1200d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            /*legacyMode*/ false, /*shimUpdateOnly*/ false,
1201d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            /*out*/client);
1202634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
1203d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if(!ret.isOk()) {
1204280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov        logRejected(id, getCallingPid(), String8(clientPackageName),
1205d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                ret.toString8());
1206cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        return ret;
1207acd695c42749f8821b0a0cc27739ddf096c6d4e8Igor Murashkin    }
1208bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
1209d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    *device = client;
1210d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return ret;
1211634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
1212634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
1213d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::connectLegacy(
1214b10cdadf0fb945e23ca77008d4af76584bd0e39aZhijun He        const sp<ICameraClient>& cameraClient,
1215c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        int api1CameraId, int halVersion,
1216280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov        const String16& clientPackageName,
1217b10cdadf0fb945e23ca77008d4af76584bd0e39aZhijun He        int clientUid,
1218b10cdadf0fb945e23ca77008d4af76584bd0e39aZhijun He        /*out*/
1219d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        sp<ICamera>* device) {
1220b10cdadf0fb945e23ca77008d4af76584bd0e39aZhijun He
1221a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
1222c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    String8 id = cameraIdIntToStr(api1CameraId);
1223b10cdadf0fb945e23ca77008d4af76584bd0e39aZhijun He
1224d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    Status ret = Status::ok();
1225cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    sp<Client> client = nullptr;
1226c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    ret = connectHelper<ICameraClient,Client>(cameraClient, id, api1CameraId, halVersion,
1227d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            clientPackageName, clientUid, USE_CALLING_PID, API_1,
1228d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            /*legacyMode*/ true, /*shimUpdateOnly*/ false,
1229d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            /*out*/client);
1230b10cdadf0fb945e23ca77008d4af76584bd0e39aZhijun He
1231d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if(!ret.isOk()) {
1232280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov        logRejected(id, getCallingPid(), String8(clientPackageName),
1233d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                ret.toString8());
1234cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        return ret;
1235b10cdadf0fb945e23ca77008d4af76584bd0e39aZhijun He    }
1236b10cdadf0fb945e23ca77008d4af76584bd0e39aZhijun He
1237d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    *device = client;
1238d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return ret;
1239b10cdadf0fb945e23ca77008d4af76584bd0e39aZhijun He}
1240b10cdadf0fb945e23ca77008d4af76584bd0e39aZhijun He
1241d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::connectDevice(
1242d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb,
1243f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        const String16& cameraId,
1244280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov        const String16& clientPackageName,
1245cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        int clientUid,
1246cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        /*out*/
1247d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        sp<hardware::camera2::ICameraDeviceUser>* device) {
1248cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1249a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
1250d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    Status ret = Status::ok();
1251f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    String8 id = String8(cameraId);
1252cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    sp<CameraDeviceClient> client = nullptr;
1253d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    ret = connectHelper<hardware::camera2::ICameraDeviceCallbacks,CameraDeviceClient>(cameraCb, id,
1254c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            /*api1CameraId*/-1,
1255d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageName,
1256d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            clientUid, USE_CALLING_PID, API_2,
1257d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            /*legacyMode*/ false, /*shimUpdateOnly*/ false,
1258d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            /*out*/client);
1259cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1260d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if(!ret.isOk()) {
1261280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov        logRejected(id, getCallingPid(), String8(clientPackageName),
1262d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                ret.toString8());
1263cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        return ret;
126488da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    }
126588da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen
1266d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    *device = client;
1267d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return ret;
126888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen}
126988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen
1270f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalatemplate<class CALLBACK, class CLIENT>
1271f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville TalvalaStatus CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
1272c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        int api1CameraId, int halVersion, const String16& clientPackageName, int clientUid,
1273c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        int clientPid, apiLevel effectiveApiLevel, bool legacyMode, bool shimUpdateOnly,
1274f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        /*out*/sp<CLIENT>& device) {
1275f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    binder::Status ret = binder::Status::ok();
1276f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1277f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    String8 clientName8(clientPackageName);
1278f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1279f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    int originalClientPid = 0;
1280f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1281f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    ALOGI("CameraService::connect call (PID %d \"%s\", camera ID %s) for HAL version %s and "
1282f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            "Camera API version %d", clientPid, clientName8.string(), cameraId.string(),
1283f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            (halVersion == -1) ? "default" : std::to_string(halVersion).c_str(),
1284f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            static_cast<int>(effectiveApiLevel));
1285f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1286f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    sp<CLIENT> client = nullptr;
1287f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    {
1288f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        // Acquire mServiceLock and prevent other clients from connecting
1289f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        std::unique_ptr<AutoConditionLock> lock =
1290f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                AutoConditionLock::waitAndAcquire(mServiceLockWrapper, DEFAULT_CONNECT_TIMEOUT_NS);
1291f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1292f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        if (lock == nullptr) {
1293f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            ALOGE("CameraService::connect (PID %d) rejected (too many other clients connecting)."
1294f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                    , clientPid);
1295f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE,
1296f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                    "Cannot open camera %s for \"%s\" (PID %d): Too many other clients connecting",
1297f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                    cameraId.string(), clientName8.string(), clientPid);
1298f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        }
1299f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1300f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        // Enforce client permissions and do basic sanity checks
1301f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        if(!(ret = validateConnectLocked(cameraId, clientName8,
1302f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                /*inout*/clientUid, /*inout*/clientPid, /*out*/originalClientPid)).isOk()) {
1303f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            return ret;
1304f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        }
1305f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1306f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        // Check the shim parameters after acquiring lock, if they have already been updated and
1307f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        // we were doing a shim update, return immediately
1308f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        if (shimUpdateOnly) {
1309f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            auto cameraState = getCameraState(cameraId);
1310f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            if (cameraState != nullptr) {
1311f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                if (!cameraState->getShimParams().isEmpty()) return ret;
1312f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            }
1313f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        }
1314f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1315f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        status_t err;
1316f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1317f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        sp<BasicClient> clientTmp = nullptr;
1318f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>> partial;
1319f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        if ((err = handleEvictionsLocked(cameraId, originalClientPid, effectiveApiLevel,
1320f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                IInterface::asBinder(cameraCb), clientName8, /*out*/&clientTmp,
1321f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                /*out*/&partial)) != NO_ERROR) {
1322f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            switch (err) {
1323f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                case -ENODEV:
1324f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                    return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
1325f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            "No camera device with ID \"%s\" currently available",
1326f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            cameraId.string());
1327f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                case -EBUSY:
1328f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                    return STATUS_ERROR_FMT(ERROR_CAMERA_IN_USE,
1329f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            "Higher-priority client using camera, ID \"%s\" currently unavailable",
1330f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            cameraId.string());
1331f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                default:
1332f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                    return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
1333f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            "Unexpected error %s (%d) opening camera \"%s\"",
1334f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            strerror(-err), err, cameraId.string());
1335f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            }
1336f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        }
1337f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1338f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        if (clientTmp.get() != nullptr) {
1339f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            // Handle special case for API1 MediaRecorder where the existing client is returned
1340f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            device = static_cast<CLIENT*>(clientTmp.get());
1341f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            return ret;
1342f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        }
1343f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1344f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        // give flashlight a chance to close devices if necessary.
1345f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        mFlashlight->prepareDeviceOpen(cameraId);
1346f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1347f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        int facing = -1;
13482f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        int deviceVersion = getDeviceVersion(cameraId, /*out*/&facing);
13496963d0ad7b621dcdaa74cbfed17c776121635146Eino-Ville Talvala        if (facing == -1) {
13506963d0ad7b621dcdaa74cbfed17c776121635146Eino-Ville Talvala            ALOGE("%s: Unable to get camera device \"%s\"  facing", __FUNCTION__, cameraId.string());
13516963d0ad7b621dcdaa74cbfed17c776121635146Eino-Ville Talvala            return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
13526963d0ad7b621dcdaa74cbfed17c776121635146Eino-Ville Talvala                    "Unable to get camera device \"%s\" facing", cameraId.string());
13536963d0ad7b621dcdaa74cbfed17c776121635146Eino-Ville Talvala        }
13546963d0ad7b621dcdaa74cbfed17c776121635146Eino-Ville Talvala
1355f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        sp<BasicClient> tmp = nullptr;
1356c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        if(!(ret = makeClient(this, cameraCb, clientPackageName,
1357c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                cameraId, api1CameraId, facing,
1358c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                clientPid, clientUid, getpid(), legacyMode,
1359c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                halVersion, deviceVersion, effectiveApiLevel,
1360f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                /*out*/&tmp)).isOk()) {
1361f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            return ret;
1362f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        }
1363f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        client = static_cast<CLIENT*>(tmp.get());
1364f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1365f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        LOG_ALWAYS_FATAL_IF(client.get() == nullptr, "%s: CameraService in invalid state",
1366f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                __FUNCTION__);
1367f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1368bd8c503398d6b483b7abba594c7838a4c93b6e23Emilian Peev        err = client->initialize(mCameraProviderManager, mMonitorTags);
13692f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        if (err != OK) {
13702f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            ALOGE("%s: Could not initialize client from HAL.", __FUNCTION__);
1371f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            // Errors could be from the HAL module open call or from AppOpsManager
1372f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            switch(err) {
1373f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                case BAD_VALUE:
1374f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                    return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
1375f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            "Illegal argument to HAL module for camera \"%s\"", cameraId.string());
1376f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                case -EBUSY:
1377f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                    return STATUS_ERROR_FMT(ERROR_CAMERA_IN_USE,
1378f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            "Camera \"%s\" is already open", cameraId.string());
1379f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                case -EUSERS:
1380f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                    return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE,
1381f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            "Too many cameras already open, cannot open camera \"%s\"",
1382f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            cameraId.string());
1383f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                case PERMISSION_DENIED:
1384f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                    return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
1385f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            "No permission to open camera \"%s\"", cameraId.string());
1386f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                case -EACCES:
1387f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                    return STATUS_ERROR_FMT(ERROR_DISABLED,
1388f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            "Camera \"%s\" disabled by policy", cameraId.string());
1389f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                case -ENODEV:
1390f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                default:
1391f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                    return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
1392f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            "Failed to initialize camera \"%s\": %s (%d)", cameraId.string(),
1393f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            strerror(-err), err);
1394f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            }
1395f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        }
1396f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1397f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        // Update shim paremeters for legacy clients
1398f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        if (effectiveApiLevel == API_1) {
1399f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            // Assume we have always received a Client subclass for API1
1400f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            sp<Client> shimClient = reinterpret_cast<Client*>(client.get());
1401f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            String8 rawParams = shimClient->getParameters();
1402f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            CameraParameters params(rawParams);
1403f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1404f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            auto cameraState = getCameraState(cameraId);
1405f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            if (cameraState != nullptr) {
1406f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                cameraState->setShimParams(params);
1407f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            } else {
1408f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                ALOGE("%s: Cannot update shim parameters for camera %s, no such device exists.",
1409f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                        __FUNCTION__, cameraId.string());
1410f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            }
1411f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        }
1412f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1413f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        if (shimUpdateOnly) {
1414f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            // If only updating legacy shim parameters, immediately disconnect client
1415f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            mServiceLock.unlock();
1416f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            client->disconnect();
1417f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            mServiceLock.lock();
1418f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        } else {
1419f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            // Otherwise, add client to active clients list
1420f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            finishConnectLocked(client, partial);
1421f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        }
1422f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    } // lock is destroyed, allow further connect calls
1423f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1424f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    // Important: release the mutex here so the client can call back into the service from its
1425f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    // destructor (can be at the end of the call)
1426f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    device = client;
1427f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    return ret;
1428f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala}
1429f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
1430d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::setTorchMode(const String16& cameraId, bool enabled,
14313068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen        const sp<IBinder>& clientBinder) {
14322f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    Mutex::Autolock lock(mServiceLock);
1433a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala
1434a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
143599e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    if (enabled && clientBinder == nullptr) {
14363068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen        ALOGE("%s: torch client binder is NULL", __FUNCTION__);
1437d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT,
1438d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "Torch client Binder is null");
14393068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    }
14403068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
144188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    String8 id = String8(cameraId.string());
144299e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    int uid = getCallingUid();
144388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen
144488da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    // verify id is valid.
1445cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    auto state = getCameraState(id);
1446cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    if (state == nullptr) {
1447f6463fc62a09b8aad8e811a9abbe9f4d9f2688f9Chien-Yu Chen        ALOGE("%s: camera id is invalid %s", __FUNCTION__, id.string());
1448d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
1449d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "Camera ID \"%s\" is a not valid camera ID", id.string());
1450cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
1451cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1452f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    StatusInternal cameraStatus = state->getStatus();
1453f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    if (cameraStatus != StatusInternal::PRESENT &&
145452778d448123c185fd30cd77e84659fab966d740Yin-Chia Yeh            cameraStatus != StatusInternal::NOT_AVAILABLE) {
145552778d448123c185fd30cd77e84659fab966d740Yin-Chia Yeh        ALOGE("%s: camera id is invalid %s, status %d", __FUNCTION__, id.string(), (int)cameraStatus);
1456d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
1457d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "Camera ID \"%s\" is a not valid camera ID", id.string());
145888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    }
145988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen
146088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    {
146188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen        Mutex::Autolock al(mTorchStatusMutex);
1462f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        TorchModeStatus status;
1463d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        status_t err = getTorchStatusLocked(id, &status);
1464d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        if (err != OK) {
1465d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            if (err == NAME_NOT_FOUND) {
1466d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
1467d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                        "Camera \"%s\" does not have a flash unit", id.string());
1468d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            }
146988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen            ALOGE("%s: getting current torch status failed for camera %s",
147088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen                    __FUNCTION__, id.string());
1471d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
1472d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    "Error updating torch status for camera \"%s\": %s (%d)", id.string(),
1473d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    strerror(-err), err);
147488da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen        }
147588da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen
1476f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        if (status == TorchModeStatus::NOT_AVAILABLE) {
147752778d448123c185fd30cd77e84659fab966d740Yin-Chia Yeh            if (cameraStatus == StatusInternal::NOT_AVAILABLE) {
147888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen                ALOGE("%s: torch mode of camera %s is not available because "
147988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen                        "camera is in use", __FUNCTION__, id.string());
1480d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                return STATUS_ERROR_FMT(ERROR_CAMERA_IN_USE,
1481d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                        "Torch for camera \"%s\" is not available due to an existing camera user",
1482d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                        id.string());
148388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen            } else {
148488da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen                ALOGE("%s: torch mode of camera %s is not available due to "
148588da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen                        "insufficient resources", __FUNCTION__, id.string());
1486d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE,
1487d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                        "Torch for camera \"%s\" is not available due to insufficient resources",
1488d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                        id.string());
148988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen            }
149088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen        }
149188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    }
149288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen
149399e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    {
149499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        // Update UID map - this is used in the torch status changed callbacks, so must be done
149599e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        // before setTorchMode
1496fe751bea0d3eedd6e817aebf4e457425b82e7117Chien-Yu Chen        Mutex::Autolock al(mTorchUidMapMutex);
149799e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        if (mTorchUidMap.find(id) == mTorchUidMap.end()) {
149899e69716215cd0665379bc90d708f2ea8689831dRuben Brunk            mTorchUidMap[id].first = uid;
149999e69716215cd0665379bc90d708f2ea8689831dRuben Brunk            mTorchUidMap[id].second = uid;
150099e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        } else {
150199e69716215cd0665379bc90d708f2ea8689831dRuben Brunk            // Set the pending UID
150299e69716215cd0665379bc90d708f2ea8689831dRuben Brunk            mTorchUidMap[id].first = uid;
150399e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        }
150499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    }
150599e69716215cd0665379bc90d708f2ea8689831dRuben Brunk
1506d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    status_t err = mFlashlight->setTorchMode(id, enabled);
150799e69716215cd0665379bc90d708f2ea8689831dRuben Brunk
1508d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (err != OK) {
1509d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        int32_t errorCode;
1510d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        String8 msg;
1511d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        switch (err) {
1512d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            case -ENOSYS:
1513d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                msg = String8::format("Camera \"%s\" has no flashlight",
1514d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    id.string());
1515d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                errorCode = ERROR_ILLEGAL_ARGUMENT;
1516d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                break;
1517d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            default:
1518d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                msg = String8::format(
1519d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    "Setting torch mode of camera \"%s\" to %d failed: %s (%d)",
1520d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    id.string(), enabled, strerror(-err), err);
1521d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                errorCode = ERROR_INVALID_OPERATION;
1522d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        }
1523d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        ALOGE("%s: %s", __FUNCTION__, msg.string());
1524d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(errorCode, msg.string());
15253068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    }
15263068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
152788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    {
152888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen        // update the link to client's death
152988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen        Mutex::Autolock al(mTorchClientMapMutex);
153088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen        ssize_t index = mTorchClientMap.indexOfKey(id);
153188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen        if (enabled) {
153288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen            if (index == NAME_NOT_FOUND) {
153388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen                mTorchClientMap.add(id, clientBinder);
153488da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen            } else {
153599e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                mTorchClientMap.valueAt(index)->unlinkToDeath(this);
153688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen                mTorchClientMap.replaceValueAt(index, clientBinder);
153788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen            }
153888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen            clientBinder->linkToDeath(this);
153988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen        } else if (index != NAME_NOT_FOUND) {
154099e69716215cd0665379bc90d708f2ea8689831dRuben Brunk            mTorchClientMap.valueAt(index)->unlinkToDeath(this);
15413068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen        }
15423068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    }
15433068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
1544d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return Status::ok();
15453068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen}
15463068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
1547d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::notifySystemEvent(int32_t eventId,
1548d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        const std::vector<int32_t>& args) {
1549a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
1550a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala
155136597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    switch(eventId) {
1552d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        case ICameraService::EVENT_USER_SWITCHED: {
15538abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala            // Try to register for UID policy updates, in case we're recovering
15548abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala            // from a system server crash
15558abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala            mUidPolicy->registerSelf();
1556d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            doUserSwitch(/*newUserIds*/ args);
155736597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk            break;
155836597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk        }
1559d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        case ICameraService::EVENT_NONE:
156036597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk        default: {
156136597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk            ALOGW("%s: Received invalid system event from system_server: %d", __FUNCTION__,
156236597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk                    eventId);
156336597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk            break;
156436597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk        }
156536597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    }
1566d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return Status::ok();
156736597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk}
156836597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
1569f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville TalvalaStatus CameraService::addListener(const sp<ICameraServiceListener>& listener,
1570f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        /*out*/
1571f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        std::vector<hardware::CameraStatus> *cameraStatuses) {
1572a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
1573a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala
1574bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin    ALOGV("%s: Add listener %p", __FUNCTION__, listener.get());
1575634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
15763450ba7879be6522ea46a56c5e66e5382f5dd5baRuben Brunk    if (listener == nullptr) {
1577bd3e2e03f3ab686c52982a9e50cae853128172cfIgor Murashkin        ALOGE("%s: Listener must not be null", __FUNCTION__);
1578d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Null listener given to addListener");
1579bd3e2e03f3ab686c52982a9e50cae853128172cfIgor Murashkin    }
1580bd3e2e03f3ab686c52982a9e50cae853128172cfIgor Murashkin
1581bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin    Mutex::Autolock lock(mServiceLock);
1582bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
1583cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    {
1584cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        Mutex::Autolock lock(mStatusListenerLock);
1585cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        for (auto& it : mListenerList) {
1586cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            if (IInterface::asBinder(it) == IInterface::asBinder(listener)) {
1587cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                ALOGW("%s: Tried to add listener %p which was already subscribed",
1588cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                      __FUNCTION__, listener.get());
1589d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                return STATUS_ERROR(ERROR_ALREADY_EXISTS, "Listener already registered");
1590cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            }
1591bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin        }
1592cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1593cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        mListenerList.push_back(listener);
1594bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin    }
1595bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
1596f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    /* Collect current devices and status */
1597cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin    {
1598cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        Mutex::Autolock lock(mCameraStatesLock);
1599cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        for (auto& i : mCameraStates) {
1600f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            cameraStatuses->emplace_back(i.first, mapToInterface(i.second->getStatus()));
1601cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin        }
1602cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin    }
1603cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin
1604f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    /*
1605f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala     * Immediately signal current torch status to this listener only
1606f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala     * This may be a subset of all the devices, so don't include it in the response directly
1607f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala     */
16083068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    {
16093068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen        Mutex::Autolock al(mTorchStatusMutex);
16103068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen        for (size_t i = 0; i < mTorchStatusMap.size(); i++ ) {
161188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen            String16 id = String16(mTorchStatusMap.keyAt(i).string());
1612f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            listener->onTorchStatusChanged(mapToInterface(mTorchStatusMap.valueAt(i)), id);
16133068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen        }
16143068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    }
16153068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
1616d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return Status::ok();
1617bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin}
1618cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1619d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::removeListener(const sp<ICameraServiceListener>& listener) {
1620a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
1621a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala
1622bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin    ALOGV("%s: Remove listener %p", __FUNCTION__, listener.get());
1623bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
1624bd3e2e03f3ab686c52982a9e50cae853128172cfIgor Murashkin    if (listener == 0) {
1625bd3e2e03f3ab686c52982a9e50cae853128172cfIgor Murashkin        ALOGE("%s: Listener must not be null", __FUNCTION__);
1626d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Null listener given to removeListener");
1627bd3e2e03f3ab686c52982a9e50cae853128172cfIgor Murashkin    }
1628bd3e2e03f3ab686c52982a9e50cae853128172cfIgor Murashkin
1629bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin    Mutex::Autolock lock(mServiceLock);
1630bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
1631cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    {
1632cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        Mutex::Autolock lock(mStatusListenerLock);
1633cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        for (auto it = mListenerList.begin(); it != mListenerList.end(); it++) {
1634cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            if (IInterface::asBinder(*it) == IInterface::asBinder(listener)) {
1635cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                mListenerList.erase(it);
1636d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                return Status::ok();
1637cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            }
1638bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin        }
1639bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin    }
1640bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
1641bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin    ALOGW("%s: Tried to remove a listener %p which was not subscribed",
1642bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin          __FUNCTION__, listener.get());
1643bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
1644d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Unregistered listener given to removeListener");
164565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
164665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1647d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville TalvalaStatus CameraService::getLegacyParameters(int cameraId, /*out*/String16* parameters) {
1648a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala
1649a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
165065d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    ALOGV("%s: for camera ID = %d", __FUNCTION__, cameraId);
165165d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
165265d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    if (parameters == NULL) {
165365d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin        ALOGE("%s: parameters must not be null", __FUNCTION__);
1654d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Parameters must not be null");
165565d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    }
165665d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
1657d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    Status ret = Status::ok();
165865d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
165965d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    CameraParameters shimParams;
1660d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (!(ret = getLegacyParametersLazy(cameraId, /*out*/&shimParams)).isOk()) {
166165d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin        // Error logged by caller
166265d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin        return ret;
166365d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    }
166465d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
166565d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    String8 shimParamsString8 = shimParams.flatten();
166665d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    String16 shimParamsString16 = String16(shimParamsString8);
166765d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
166865d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    *parameters = shimParamsString16;
166965d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
1670d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return ret;
167165d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin}
167265d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
1673f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville TalvalaStatus CameraService::supportsCameraApi(const String16& cameraId, int apiVersion,
1674f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        /*out*/ bool *isSupported) {
1675a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
1676a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala
16772f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    const String8 id = String8(cameraId);
16782f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
16792f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    ALOGV("%s: for camera ID = %s", __FUNCTION__, id.string());
168065d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
168165d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    switch (apiVersion) {
168265d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin        case API_VERSION_1:
168365d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin        case API_VERSION_2:
168465d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin            break;
168565d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin        default:
1686d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            String8 msg = String8::format("Unknown API version %d", apiVersion);
1687d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            ALOGE("%s: %s", __FUNCTION__, msg.string());
1688d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.string());
168965d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    }
169065d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
169128ad2eae9ac86df397b27d27fcc92d2c893138afEmilian Peev    int deviceVersion = getDeviceVersion(id);
169265d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    switch(deviceVersion) {
1693d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        case CAMERA_DEVICE_API_VERSION_1_0:
1694d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        case CAMERA_DEVICE_API_VERSION_3_0:
1695d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        case CAMERA_DEVICE_API_VERSION_3_1:
1696d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            if (apiVersion == API_VERSION_2) {
16972f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                ALOGV("%s: Camera id %s uses HAL version %d <3.2, doesn't support api2 without shim",
16982f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                        __FUNCTION__, id.string(), deviceVersion);
1699d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                *isSupported = false;
1700d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            } else { // if (apiVersion == API_VERSION_1) {
17012f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                ALOGV("%s: Camera id %s uses older HAL before 3.2, but api1 is always supported",
17022f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                        __FUNCTION__, id.string());
1703d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                *isSupported = true;
1704d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            }
1705d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            break;
1706d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        case CAMERA_DEVICE_API_VERSION_3_2:
1707d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        case CAMERA_DEVICE_API_VERSION_3_3:
17084afbdecf8c6dc5ad04f6fa6c8712ce2c56a00c47Zhijun He        case CAMERA_DEVICE_API_VERSION_3_4:
17092f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            ALOGV("%s: Camera id %s uses HAL3.2 or newer, supports api1/api2 directly",
17102f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                    __FUNCTION__, id.string());
1711d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            *isSupported = true;
1712d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            break;
1713d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        case -1: {
17142f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            String8 msg = String8::format("Unknown camera ID %s", id.string());
1715d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            ALOGE("%s: %s", __FUNCTION__, msg.string());
1716d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.string());
1717d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        }
1718d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        default: {
17192f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            String8 msg = String8::format("Unknown device version %x for device %s",
17202f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                    deviceVersion, id.string());
1721d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            ALOGE("%s: %s", __FUNCTION__, msg.string());
1722d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return STATUS_ERROR(ERROR_INVALID_OPERATION, msg.string());
1723d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        }
172465d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    }
172565d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
1726d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return Status::ok();
172765d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin}
172865d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
1729cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkvoid CameraService::removeByClient(const BasicClient* client) {
1730ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    Mutex::Autolock lock(mServiceLock);
1731cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    for (auto& i : mActiveClientManager.getAll()) {
1732cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        auto clientSp = i->getValue();
1733cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        if (clientSp.get() == client) {
1734cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            mActiveClientManager.remove(i);
1735634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        }
1736634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    }
1737634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
1738634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
1739cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkbool CameraService::evictClientIdByRemote(const wp<IBinder>& remote) {
1740cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    bool ret = false;
1741cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    {
1742cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // Acquire mServiceLock and prevent other clients from connecting
1743cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        std::unique_ptr<AutoConditionLock> lock =
1744cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                AutoConditionLock::waitAndAcquire(mServiceLockWrapper);
1745634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
1746634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
1747cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        std::vector<sp<BasicClient>> evicted;
1748cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        for (auto& i : mActiveClientManager.getAll()) {
1749cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            auto clientSp = i->getValue();
1750cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            if (clientSp.get() == nullptr) {
1751cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                ALOGE("%s: Dead client still in mActiveClientManager.", __FUNCTION__);
1752cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                mActiveClientManager.remove(i);
1753cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                continue;
1754cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            }
1755dbfcb38f6636931b2e3e6da8e6aa5a7bfce84a82Yin-Chia Yeh            if (remote == clientSp->getRemote()) {
1756cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                mActiveClientManager.remove(i);
1757cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                evicted.push_back(clientSp);
1758cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1759cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                // Notify the client of disconnection
1760d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                clientSp->notifyError(
1761d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                        hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED,
1762cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                        CaptureResultExtras());
1763634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin            }
1764634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        }
1765634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
1766cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // Do not hold mServiceLock while disconnecting clients, but retain the condition blocking
1767cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // other clients from connecting in mServiceLockWrapper if held
1768cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        mServiceLock.unlock();
1769ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
177036597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk        // Do not clear caller identity, remote caller should be client proccess
177136597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
1772cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        for (auto& i : evicted) {
1773cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            if (i.get() != nullptr) {
1774cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                i->disconnect();
1775cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                ret = true;
1776cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            }
1777cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        }
1778ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
1779cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // Reacquire mServiceLock
1780cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        mServiceLock.lock();
178165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1782cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    } // lock is destroyed, allow further connect calls
178365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1784cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return ret;
1785cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
178665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1787cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkstd::shared_ptr<CameraService::CameraState> CameraService::getCameraState(
1788cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        const String8& cameraId) const {
1789cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    std::shared_ptr<CameraState> state;
1790cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    {
1791cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        Mutex::Autolock lock(mCameraStatesLock);
1792cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        auto iter = mCameraStates.find(cameraId);
1793cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        if (iter != mCameraStates.end()) {
1794cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            state = iter->second;
179565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
179665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
1797cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return state;
179865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
179965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1800cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunksp<CameraService::BasicClient> CameraService::removeClientLocked(const String8& cameraId) {
1801cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    // Remove from active clients list
1802cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    auto clientDescriptorPtr = mActiveClientManager.remove(cameraId);
1803cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    if (clientDescriptorPtr == nullptr) {
1804cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        ALOGW("%s: Could not evict client, no client for camera ID %s", __FUNCTION__,
1805cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                cameraId.string());
1806cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        return sp<BasicClient>{nullptr};
1807cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
1808d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park
1809cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return clientDescriptorPtr->getValue();
181065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
181165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1812d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvalavoid CameraService::doUserSwitch(const std::vector<int32_t>& newUserIds) {
181336597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    // Acquire mServiceLock and prevent other clients from connecting
181436597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    std::unique_ptr<AutoConditionLock> lock =
181536597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk            AutoConditionLock::waitAndAcquire(mServiceLockWrapper);
181636597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
18176267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk    std::set<userid_t> newAllowedUsers;
1818d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    for (size_t i = 0; i < newUserIds.size(); i++) {
1819d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        if (newUserIds[i] < 0) {
18206267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk            ALOGE("%s: Bad user ID %d given during user switch, ignoring.",
1821d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    __FUNCTION__, newUserIds[i]);
18226267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk            return;
18236267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        }
1824d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        newAllowedUsers.insert(static_cast<userid_t>(newUserIds[i]));
18256267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk    }
18266267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk
18276267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk
18286267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk    if (newAllowedUsers == mAllowedUsers) {
18296267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        ALOGW("%s: Received notification of user switch with no updated user IDs.", __FUNCTION__);
18306267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        return;
183136597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    }
183236597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
18336267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk    logUserSwitch(mAllowedUsers, newAllowedUsers);
1834a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk
18356267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk    mAllowedUsers = std::move(newAllowedUsers);
183636597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
183736597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    // Current user has switched, evict all current clients.
183836597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    std::vector<sp<BasicClient>> evicted;
183936597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    for (auto& i : mActiveClientManager.getAll()) {
184036597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk        auto clientSp = i->getValue();
184136597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
184236597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk        if (clientSp.get() == nullptr) {
184336597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk            ALOGE("%s: Dead client still in mActiveClientManager.", __FUNCTION__);
184436597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk            continue;
184536597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk        }
184636597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
18476267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        // Don't evict clients that are still allowed.
18486267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        uid_t clientUid = clientSp->getClientUid();
18496267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        userid_t clientUserId = multiuser_get_user_id(clientUid);
18506267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        if (mAllowedUsers.find(clientUserId) != mAllowedUsers.end()) {
18516267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk            continue;
18526267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        }
18536267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk
185436597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk        evicted.push_back(clientSp);
185536597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
185636597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk        String8 curTime = getFormattedCurrentTime();
185736597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
185836597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk        ALOGE("Evicting conflicting client for camera ID %s due to user change",
185936597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk                i->getKey().string());
1860a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk
186136597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk        // Log the clients evicted
1862a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk        logEvent(String8::format("EVICT device %s client held by package %s (PID %"
18638131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                PRId32 ", score %" PRId32 ", state %" PRId32 ")\n   - Evicted due"
18648131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                " to user switch.", i->getKey().string(),
18658131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                String8{clientSp->getPackageName()}.string(),
18668131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                i->getOwnerId(), i->getPriority().getScore(),
18678131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                i->getPriority().getState()));
186836597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
186936597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    }
187036597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
187136597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    // Do not hold mServiceLock while disconnecting clients, but retain the condition
187236597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    // blocking other clients from connecting in mServiceLockWrapper if held.
187336597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    mServiceLock.unlock();
187436597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
187536597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    // Clear caller identity temporarily so client disconnect PID checks work correctly
187636597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    int64_t token = IPCThreadState::self()->clearCallingIdentity();
187736597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
187836597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    for (auto& i : evicted) {
187936597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk        i->disconnect();
188036597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    }
188136597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
188236597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    IPCThreadState::self()->restoreCallingIdentity(token);
188336597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
188436597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    // Reacquire mServiceLock
188536597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    mServiceLock.lock();
188636597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk}
1887ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
1888a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunkvoid CameraService::logEvent(const char* event) {
1889cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    String8 curTime = getFormattedCurrentTime();
1890a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    Mutex::Autolock l(mLogLock);
1891a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    mEventLog.add(String8::format("%s : %s", curTime.string(), event));
1892cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
1893ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
1894a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunkvoid CameraService::logDisconnected(const char* cameraId, int clientPid,
1895280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov        const char* clientPackage) {
1896a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    // Log the clients evicted
1897a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    logEvent(String8::format("DISCONNECT device %s client for package %s (PID %d)", cameraId,
1898280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov            clientPackage, clientPid));
1899a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk}
1900ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
1901a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunkvoid CameraService::logConnected(const char* cameraId, int clientPid,
1902280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov        const char* clientPackage) {
1903cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    // Log the clients evicted
1904a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    logEvent(String8::format("CONNECT device %s client for package %s (PID %d)", cameraId,
1905280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov            clientPackage, clientPid));
1906a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk}
1907a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk
1908a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunkvoid CameraService::logRejected(const char* cameraId, int clientPid,
1909280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov        const char* clientPackage, const char* reason) {
1910a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    // Log the client rejected
1911a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    logEvent(String8::format("REJECT device %s client for package %s (PID %d), reason: (%s)",
1912280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov            cameraId, clientPackage, clientPid, reason));
1913a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk}
1914a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk
19156267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunkvoid CameraService::logUserSwitch(const std::set<userid_t>& oldUserIds,
19166267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        const std::set<userid_t>& newUserIds) {
19176267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk    String8 newUsers = toString(newUserIds);
19186267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk    String8 oldUsers = toString(oldUserIds);
1919d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala    if (oldUsers.size() == 0) {
1920d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        oldUsers = "<None>";
1921d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala    }
1922a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    // Log the new and old users
1923d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala    logEvent(String8::format("USER_SWITCH previous allowed user IDs: %s, current allowed user IDs: %s",
19246267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk            oldUsers.string(), newUsers.string()));
1925a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk}
1926a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk
1927a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunkvoid CameraService::logDeviceRemoved(const char* cameraId, const char* reason) {
1928a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    // Log the device removal
1929a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    logEvent(String8::format("REMOVE device %s, reason: (%s)", cameraId, reason));
1930a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk}
1931a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk
1932a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunkvoid CameraService::logDeviceAdded(const char* cameraId, const char* reason) {
1933a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    // Log the device removal
1934a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    logEvent(String8::format("ADD device %s, reason: (%s)", cameraId, reason));
1935a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk}
1936a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk
1937a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunkvoid CameraService::logClientDied(int clientPid, const char* reason) {
1938a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    // Log the device removal
1939a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    logEvent(String8::format("DIED client(s) with PID %d, reason: (%s)", clientPid, reason));
1940ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin}
1941ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
19421527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvalavoid CameraService::logServiceError(const char* msg, int errorCode) {
19431527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvala    String8 curTime = getFormattedCurrentTime();
1944d309fb9c8a2c4564d88fffba19c4e3688e4b862bEino-Ville Talvala    logEvent(String8::format("SERVICE ERROR: %s : %d (%s)", msg, errorCode, strerror(-errorCode)));
19451527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvala}
19461527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvala
194736597b241c59eba7e55d5150092947a748c5e9cbRuben Brunkstatus_t CameraService::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
194836597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk        uint32_t flags) {
194936597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
195036597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    const int pid = getCallingPid();
195136597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    const int selfPid = getpid();
195236597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk
195365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // Permission checks
195465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    switch (code) {
1955a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        case SHELL_COMMAND_TRANSACTION: {
1956a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            int in = data.readFileDescriptor();
1957a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            int out = data.readFileDescriptor();
1958a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            int err = data.readFileDescriptor();
1959a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            int argc = data.readInt32();
1960a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            Vector<String16> args;
1961a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
1962a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov               args.add(data.readString16());
1963a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            }
1964a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            sp<IBinder> unusedCallback;
1965a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            sp<IResultReceiver> resultReceiver;
1966a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            status_t status;
1967a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            if ((status = data.readNullableStrongBinder(&unusedCallback)) != NO_ERROR) {
1968a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov                return status;
1969a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            }
1970a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            if ((status = data.readNullableStrongBinder(&resultReceiver)) != NO_ERROR) {
1971a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov                return status;
1972a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            }
1973a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            status = shellCommand(in, out, err, args);
1974a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            if (resultReceiver != nullptr) {
1975a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov                resultReceiver->send(status);
1976a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            }
1977a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            return NO_ERROR;
1978a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        }
1979d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        case BnCameraService::NOTIFYSYSTEMEVENT: {
198036597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk            if (pid != selfPid) {
198136597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk                // Ensure we're being called by system_server, or similar process with
198236597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk                // permissions to notify the camera service about system events
198336597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk                if (!checkCallingPermission(
198436597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk                        String16("android.permission.CAMERA_SEND_SYSTEM_EVENTS"))) {
198536597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk                    const int uid = getCallingUid();
198636597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk                    ALOGE("Permission Denial: cannot send updates to camera service about system"
198736597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk                            " events from pid=%d, uid=%d", pid, uid);
198836597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk                    return PERMISSION_DENIED;
198936597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk                }
199036597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk            }
199136597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk            break;
199236597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk        }
199365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
199465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
199565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return BnCameraService::onTransact(code, data, reply, flags);
199665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
199765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
199865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// We share the media players for shutter and recording sound for all clients.
199965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// A reference count is kept to determine when we will actually release the
200065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// media players.
200165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2002ef49805296eb81cd4ba039fa4d25b9358436992bJaekyun Seoksp<MediaPlayer> CameraService::newMediaPlayer(const char *file) {
2003ef49805296eb81cd4ba039fa4d25b9358436992bJaekyun Seok    sp<MediaPlayer> mp = new MediaPlayer();
2004ef49805296eb81cd4ba039fa4d25b9358436992bJaekyun Seok    status_t error;
2005ef49805296eb81cd4ba039fa4d25b9358436992bJaekyun Seok    if ((error = mp->setDataSource(NULL /* httpService */, file, NULL)) == NO_ERROR) {
200660a78ac9535878984b0777788760b9ee7465c5e6Eino-Ville Talvala        mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE);
2007ef49805296eb81cd4ba039fa4d25b9358436992bJaekyun Seok        error = mp->prepare();
2008ef49805296eb81cd4ba039fa4d25b9358436992bJaekyun Seok    }
2009ef49805296eb81cd4ba039fa4d25b9358436992bJaekyun Seok    if (error != NO_ERROR) {
201029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to load CameraService sounds: %s", file);
2011ef49805296eb81cd4ba039fa4d25b9358436992bJaekyun Seok        mp->disconnect();
2012ef49805296eb81cd4ba039fa4d25b9358436992bJaekyun Seok        mp.clear();
201359a8ef0135bab204ed027625011a1f55d99a694dJaekyun Seok        return nullptr;
201465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
201565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return mp;
201665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
201765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
201865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::loadSound() {
2019a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
2020a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala
202165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mSoundLock);
202265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("CameraService::loadSound ref=%d", mSoundRef);
202365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mSoundRef++) return;
202465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
202559a8ef0135bab204ed027625011a1f55d99a694dJaekyun Seok    mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/product/media/audio/ui/camera_click.ogg");
202659a8ef0135bab204ed027625011a1f55d99a694dJaekyun Seok    if (mSoundPlayer[SOUND_SHUTTER] == nullptr) {
202759a8ef0135bab204ed027625011a1f55d99a694dJaekyun Seok        mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
202859a8ef0135bab204ed027625011a1f55d99a694dJaekyun Seok    }
202959a8ef0135bab204ed027625011a1f55d99a694dJaekyun Seok    mSoundPlayer[SOUND_RECORDING_START] = newMediaPlayer("/product/media/audio/ui/VideoRecord.ogg");
203059a8ef0135bab204ed027625011a1f55d99a694dJaekyun Seok    if (mSoundPlayer[SOUND_RECORDING_START] == nullptr) {
203159a8ef0135bab204ed027625011a1f55d99a694dJaekyun Seok        mSoundPlayer[SOUND_RECORDING_START] =
203259a8ef0135bab204ed027625011a1f55d99a694dJaekyun Seok                newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");
203359a8ef0135bab204ed027625011a1f55d99a694dJaekyun Seok    }
203459a8ef0135bab204ed027625011a1f55d99a694dJaekyun Seok    mSoundPlayer[SOUND_RECORDING_STOP] = newMediaPlayer("/product/media/audio/ui/VideoStop.ogg");
203559a8ef0135bab204ed027625011a1f55d99a694dJaekyun Seok    if (mSoundPlayer[SOUND_RECORDING_STOP] == nullptr) {
203659a8ef0135bab204ed027625011a1f55d99a694dJaekyun Seok        mSoundPlayer[SOUND_RECORDING_STOP] = newMediaPlayer("/system/media/audio/ui/VideoStop.ogg");
203759a8ef0135bab204ed027625011a1f55d99a694dJaekyun Seok    }
203865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
203965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
204065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::releaseSound() {
204165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mSoundLock);
204265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("CameraService::releaseSound ref=%d", mSoundRef);
204365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (--mSoundRef) return;
204465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
204565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (int i = 0; i < NUM_SOUNDS; i++) {
204665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mSoundPlayer[i] != 0) {
204765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mSoundPlayer[i]->disconnect();
204865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mSoundPlayer[i].clear();
204965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
205065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
205165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
205265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
205365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::playSound(sound_kind kind) {
2054a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
2055a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala
205665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("playSound(%d)", kind);
205765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mSoundLock);
205865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<MediaPlayer> player = mSoundPlayer[kind];
205965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (player != 0) {
20608888a75f01d904541e409e858d23e4150ace34b6Chih-Chung Chang        player->seekTo(0);
20618888a75f01d904541e409e858d23e4150ace34b6Chih-Chung Chang        player->start();
206265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
206365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
206465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
206565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
206665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
206765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianCameraService::Client::Client(const sp<CameraService>& cameraService,
2068b7a67942823e8339eb298238f117aaa6d7b63111Wu-cheng Li        const sp<ICameraClient>& cameraClient,
2069280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov        const String16& clientPackageName,
2070c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        const String8& cameraIdStr,
2071c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        int api1CameraId, int cameraFacing,
2072ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        int clientPid, uid_t clientUid,
2073ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        int servicePid) :
2074e992e75053e98e3699af6e344c11b787e30411adEino-Ville Talvala        CameraService::BasicClient(cameraService,
2075f888020c6e2735624f2b2a30e72aca24e17b8b4dMarco Nelissen                IInterface::asBinder(cameraClient),
2076280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov                clientPackageName,
20772f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                cameraIdStr, cameraFacing,
2078ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala                clientPid, clientUid,
20792f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                servicePid),
2080c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        mCameraId(api1CameraId)
2081634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin{
208265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int callingPid = getCallingPid();
20832f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    LOG1("Client::Client E (pid %d, id %d)", callingPid, mCameraId);
208465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
208544cfcf00b9008c1c04f4c8277c6c06af039fd976Igor Murashkin    mRemoteCallback = cameraClient;
20865e08d60617fc63c2e41f9069ff89f5c00db2617dEino-Ville Talvala
208765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    cameraService->loadSound();
2088ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
20892f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    LOG1("Client::Client X (pid %d, id %d)", callingPid, mCameraId);
209065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
209165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
209265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// tear down the client
209365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianCameraService::Client::~Client() {
2094d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    ALOGV("~Client");
2095634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    mDestructionStarted = true;
2096634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
20972f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    sCameraService->releaseSound();
2098036bc3e2cfc5a11c3f7ace41088c8936dae2e946Igor Murashkin    // unconditionally disconnect. function is idempotent
2099036bc3e2cfc5a11c3f7ace41088c8936dae2e946Igor Murashkin    Client::disconnect();
210065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
210165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
21022f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalasp<CameraService> CameraService::BasicClient::BasicClient::sCameraService;
21032f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
2104634a51509ee50475f3e9f8ccf897e90fc72ded31Igor MurashkinCameraService::BasicClient::BasicClient(const sp<CameraService>& cameraService,
2105ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        const sp<IBinder>& remoteCallback,
2106280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov        const String16& clientPackageName,
21072f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        const String8& cameraIdStr, int cameraFacing,
2108ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        int clientPid, uid_t clientUid,
2109ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        int servicePid):
21102f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        mCameraIdStr(cameraIdStr), mCameraFacing(cameraFacing),
21112f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        mClientPackageName(clientPackageName), mClientPid(clientPid), mClientUid(clientUid),
21122f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        mServicePid(servicePid),
21132f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        mDisconnected(false),
21142f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        mRemoteBinder(remoteCallback)
2115634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin{
21162f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (sCameraService == nullptr) {
21172f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        sCameraService = cameraService;
21182f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
2119ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    mOpsActive = false;
2120634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    mDestructionStarted = false;
21210dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
21220dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    // In some cases the calling code has no access to the package it runs under.
21230dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    // For example, NDK camera API.
21240dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    // In this case we will get the packages for the calling UID and pick the first one
21250dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    // for attributing the app op. This will work correctly for runtime permissions
21260dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    // as for legacy apps we will toggle the app op for all packages in the UID.
21270dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    // The caveat is that the operation may be attributed to the wrong package and
21280dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    // stats based on app ops may be slightly off.
21290dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    if (mClientPackageName.size() <= 0) {
21300dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        sp<IServiceManager> sm = defaultServiceManager();
21310dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        sp<IBinder> binder = sm->getService(String16(kPermissionServiceName));
21320dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        if (binder == 0) {
21330dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            ALOGE("Cannot get permission service");
21340dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            // Leave mClientPackageName unchanged (empty) and the further interaction
21350dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            // with camera will fail in BasicClient::startCameraOps
21360dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            return;
21370dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        }
21380dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
21390dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        sp<IPermissionController> permCtrl = interface_cast<IPermissionController>(binder);
21400dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        Vector<String16> packages;
21410dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
21420dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        permCtrl->getPackagesForUid(mClientUid, packages);
21430dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
21440dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        if (packages.isEmpty()) {
21450dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            ALOGE("No packages for calling UID");
21460dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            // Leave mClientPackageName unchanged (empty) and the further interaction
21470dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            // with camera will fail in BasicClient::startCameraOps
21480dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            return;
21490dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        }
21500dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        mClientPackageName = packages[0];
21510dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    }
2152634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
2153634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
2154634a51509ee50475f3e9f8ccf897e90fc72ded31Igor MurashkinCameraService::BasicClient::~BasicClient() {
2155d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    ALOGV("~BasicClient");
2156634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    mDestructionStarted = true;
2157634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
2158634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
2159d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvalabinder::Status CameraService::BasicClient::disconnect() {
2160d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    binder::Status res = Status::ok();
216136597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    if (mDisconnected) {
2162d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return res;
216336597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk    }
216424901c86e10a0923fe10f5e9bce5e6dba061a289Eino-Ville Talvala    mDisconnected = true;
2165cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
21662f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    sCameraService->removeByClient(this);
21672f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    sCameraService->logDisconnected(mCameraIdStr, mClientPid,
2168280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov            String8(mClientPackageName));
2169cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2170cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    sp<IBinder> remote = getRemote();
2171cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    if (remote != nullptr) {
21722f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        remote->unlinkToDeath(sCameraService);
2173cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
2174f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala
2175f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala    finishCameraOps();
2176e4fe21bb7cef893cd38bd194ea880333389aea38Chien-Yu Chen    // Notify flashlight that a camera device is closed.
21772f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    sCameraService->mFlashlight->deviceClosed(mCameraIdStr);
21782f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    ALOGI("%s: Disconnected client for camera %s for PID %d", __FUNCTION__, mCameraIdStr.string(),
21792f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            mClientPid);
2180cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2181cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin    // client shouldn't be able to call into us anymore
2182cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin    mClientPid = 0;
2183d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala
2184d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return res;
2185634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
2186634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
2187c4003965258404a19b99280ac0f475e2f290bf27Eino-Ville Talvalastatus_t CameraService::BasicClient::dump(int, const Vector<String16>&) {
2188c4003965258404a19b99280ac0f475e2f290bf27Eino-Ville Talvala    // No dumping of clients directly over Binder,
2189c4003965258404a19b99280ac0f475e2f290bf27Eino-Ville Talvala    // must go through CameraService::dump
2190c4003965258404a19b99280ac0f475e2f290bf27Eino-Ville Talvala    android_errorWriteWithInfoLog(SN_EVENT_LOG_ID, "26265403",
2191c4003965258404a19b99280ac0f475e2f290bf27Eino-Ville Talvala            IPCThreadState::self()->getCallingUid(), NULL, 0);
2192c4003965258404a19b99280ac0f475e2f290bf27Eino-Ville Talvala    return OK;
2193c4003965258404a19b99280ac0f475e2f290bf27Eino-Ville Talvala}
2194c4003965258404a19b99280ac0f475e2f290bf27Eino-Ville Talvala
2195cc776718c0be7c31fe5ab4fc1446d377be60369fRuben BrunkString16 CameraService::BasicClient::getPackageName() const {
2196280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov    return mClientPackageName;
2197cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
2198cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2199cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2200cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkint CameraService::BasicClient::getClientPid() const {
2201cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return mClientPid;
2202cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
2203cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
22046267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunkuid_t CameraService::BasicClient::getClientUid() const {
22056267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk    return mClientUid;
22066267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk}
22076267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk
22080bbf8b213ad96051357e3ad6d6d2808bfa31a59aRuben Brunkbool CameraService::BasicClient::canCastToApiClient(apiLevel level) const {
22090bbf8b213ad96051357e3ad6d6d2808bfa31a59aRuben Brunk    // Defaults to API2.
22100bbf8b213ad96051357e3ad6d6d2808bfa31a59aRuben Brunk    return level == API_2;
22110bbf8b213ad96051357e3ad6d6d2808bfa31a59aRuben Brunk}
22120bbf8b213ad96051357e3ad6d6d2808bfa31a59aRuben Brunk
2213ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvalastatus_t CameraService::BasicClient::startCameraOps() {
2214a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
2215a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala
2216ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    int32_t res;
2217f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala    // Notify app ops that the camera is not available
2218ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    mOpsCallback = new OpsCallback(this);
2219ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
2220e6800cea0678dbc0bf697b44c3e4548b0253085cIgor Murashkin    {
2221e6800cea0678dbc0bf697b44c3e4548b0253085cIgor Murashkin        ALOGV("%s: Start camera ops, package name = %s, client UID = %d",
2222280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov              __FUNCTION__, String8(mClientPackageName).string(), mClientUid);
2223e6800cea0678dbc0bf697b44c3e4548b0253085cIgor Murashkin    }
2224e6800cea0678dbc0bf697b44c3e4548b0253085cIgor Murashkin
2225ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    mAppOpsManager.startWatchingMode(AppOpsManager::OP_CAMERA,
2226280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov            mClientPackageName, mOpsCallback);
22271d519106f7a3d31cc89e3c4a1146106b0478a410Svet Ganov    res = mAppOpsManager.startOpNoThrow(AppOpsManager::OP_CAMERA,
22281d519106f7a3d31cc89e3c4a1146106b0478a410Svet Ganov            mClientUid, mClientPackageName, /*startIfModeDefault*/ false);
2229ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
223028e8ef72dab287af59663b89b12507e43f760701Svetoslav    if (res == AppOpsManager::MODE_ERRORED) {
22312f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        ALOGI("Camera %s: Access for \"%s\" has been revoked",
22322f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                mCameraIdStr.string(), String8(mClientPackageName).string());
2233ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        return PERMISSION_DENIED;
2234ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    }
2235f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala
223628e8ef72dab287af59663b89b12507e43f760701Svetoslav    if (res == AppOpsManager::MODE_IGNORED) {
22372f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        ALOGI("Camera %s: Access for \"%s\" has been restricted",
22382f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                mCameraIdStr.string(), String8(mClientPackageName).string());
2239e3afb2cc438b76ae433c8c40ceabf0457ad7a678Eino-Ville Talvala        // Return the same error as for device policy manager rejection
2240e3afb2cc438b76ae433c8c40ceabf0457ad7a678Eino-Ville Talvala        return -EACCES;
224128e8ef72dab287af59663b89b12507e43f760701Svetoslav    }
224228e8ef72dab287af59663b89b12507e43f760701Svetoslav
2243ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    mOpsActive = true;
2244f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala
2245f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala    // Transition device availability listeners from PRESENT -> NOT_AVAILABLE
22462f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    sCameraService->updateStatus(StatusInternal::NOT_AVAILABLE, mCameraIdStr);
2247f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala
2248573291c251d9e85f51f7c0fa1cb35baa2969ca17Emilian Peev    int apiLevel = hardware::ICameraServiceProxy::CAMERA_API_LEVEL_1;
2249573291c251d9e85f51f7c0fa1cb35baa2969ca17Emilian Peev    if (canCastToApiClient(API_2)) {
2250573291c251d9e85f51f7c0fa1cb35baa2969ca17Emilian Peev        apiLevel = hardware::ICameraServiceProxy::CAMERA_API_LEVEL_2;
2251573291c251d9e85f51f7c0fa1cb35baa2969ca17Emilian Peev    }
2252412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala    // Transition device state to OPEN
22532f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    sCameraService->updateProxyDeviceState(ICameraServiceProxy::CAMERA_STATE_OPEN,
2254573291c251d9e85f51f7c0fa1cb35baa2969ca17Emilian Peev            mCameraIdStr, mCameraFacing, mClientPackageName, apiLevel);
2255412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala
2256ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    return OK;
2257ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala}
2258ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
2259ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvalastatus_t CameraService::BasicClient::finishCameraOps() {
2260a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
2261a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala
2262f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala    // Check if startCameraOps succeeded, and if so, finish the camera op
2263ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    if (mOpsActive) {
2264f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala        // Notify app ops that the camera is available again
2265ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        mAppOpsManager.finishOp(AppOpsManager::OP_CAMERA, mClientUid,
2266280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov                mClientPackageName);
2267ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        mOpsActive = false;
2268f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala
2269151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski        // This function is called when a client disconnects. This should
2270151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski        // release the camera, but actually only if it was in a proper
2271151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski        // functional state, i.e. with status NOT_AVAILABLE
2272f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        std::initializer_list<StatusInternal> rejected = {StatusInternal::PRESENT,
2273151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski                StatusInternal::ENUMERATING, StatusInternal::NOT_PRESENT};
2274f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala
2275cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // Transition to PRESENT if the camera is not in either of the rejected states
22762f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        sCameraService->updateStatus(StatusInternal::PRESENT,
22772f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                mCameraIdStr, rejected);
2278f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala
2279573291c251d9e85f51f7c0fa1cb35baa2969ca17Emilian Peev        int apiLevel = hardware::ICameraServiceProxy::CAMERA_API_LEVEL_1;
2280573291c251d9e85f51f7c0fa1cb35baa2969ca17Emilian Peev        if (canCastToApiClient(API_2)) {
2281573291c251d9e85f51f7c0fa1cb35baa2969ca17Emilian Peev            apiLevel = hardware::ICameraServiceProxy::CAMERA_API_LEVEL_2;
2282573291c251d9e85f51f7c0fa1cb35baa2969ca17Emilian Peev        }
2283412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala        // Transition device state to CLOSED
22842f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        sCameraService->updateProxyDeviceState(ICameraServiceProxy::CAMERA_STATE_CLOSED,
2285573291c251d9e85f51f7c0fa1cb35baa2969ca17Emilian Peev                mCameraIdStr, mCameraFacing, mClientPackageName, apiLevel);
2286ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    }
2287f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala    // Always stop watching, even if no camera op is active
2288e992e75053e98e3699af6e344c11b787e30411adEino-Ville Talvala    if (mOpsCallback != NULL) {
2289e992e75053e98e3699af6e344c11b787e30411adEino-Ville Talvala        mAppOpsManager.stopWatchingMode(mOpsCallback);
2290e992e75053e98e3699af6e344c11b787e30411adEino-Ville Talvala    }
2291ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    mOpsCallback.clear();
2292ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
2293ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    return OK;
2294ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala}
2295ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
2296ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvalavoid CameraService::BasicClient::opChanged(int32_t op, const String16& packageName) {
2297a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
2298a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala
2299ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    String8 name(packageName);
2300280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov    String8 myName(mClientPackageName);
2301ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
2302ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    if (op != AppOpsManager::OP_CAMERA) {
2303ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        ALOGW("Unexpected app ops notification received: %d", op);
2304ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        return;
2305ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    }
2306ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
2307ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    int32_t res;
2308ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    res = mAppOpsManager.checkOp(AppOpsManager::OP_CAMERA,
2309280405a138a0068694f3c39b4290f510173133d9Svetoslav Ganov            mClientUid, mClientPackageName);
2310ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    ALOGV("checkOp returns: %d, %s ", res,
2311ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala            res == AppOpsManager::MODE_ALLOWED ? "ALLOWED" :
2312ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala            res == AppOpsManager::MODE_IGNORED ? "IGNORED" :
2313ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala            res == AppOpsManager::MODE_ERRORED ? "ERRORED" :
2314ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala            "UNKNOWN");
2315ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
2316ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    if (res != AppOpsManager::MODE_ALLOWED) {
23172f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        ALOGI("Camera %s: Access for \"%s\" revoked", mCameraIdStr.string(),
2318ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala                myName.string());
2319a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        block();
2320ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    }
2321ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala}
2322ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
2323a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganovvoid CameraService::BasicClient::block() {
2324a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    ATRACE_CALL();
2325a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
2326a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    // Reset the client PID to allow server-initiated disconnect,
2327a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    // and to prevent further calls by client.
2328a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    mClientPid = getCallingPid();
2329a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    CaptureResultExtras resultExtras; // a dummy result (invalid)
2330a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    notifyError(hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISABLED, resultExtras);
2331a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    disconnect();
2332a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
2333a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
233465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
233565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2336d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvalavoid CameraService::Client::notifyError(int32_t errorCode,
2337cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei        const CaptureResultExtras& resultExtras) {
2338d309fb9c8a2c4564d88fffba19c4e3688e4b862bEino-Ville Talvala    (void) errorCode;
2339d309fb9c8a2c4564d88fffba19c4e3688e4b862bEino-Ville Talvala    (void) resultExtras;
23403e600894685b994849d59307721c6862ae0c45b7Ranjith Kagathi Ananda    if (mRemoteCallback != NULL) {
23413e600894685b994849d59307721c6862ae0c45b7Ranjith Kagathi Ananda        mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_RELEASED, 0);
23423e600894685b994849d59307721c6862ae0c45b7Ranjith Kagathi Ananda    } else {
23433e600894685b994849d59307721c6862ae0c45b7Ranjith Kagathi Ananda        ALOGE("mRemoteCallback is NULL!!");
23443e600894685b994849d59307721c6862ae0c45b7Ranjith Kagathi Ananda    }
2345ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala}
2346ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
2347036bc3e2cfc5a11c3f7ace41088c8936dae2e946Igor Murashkin// NOTE: function is idempotent
2348d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvalabinder::Status CameraService::Client::disconnect() {
2349d09801b99503b57c35e321ad9afa7e861e012813Eino-Ville Talvala    ALOGV("Client::disconnect");
2350d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return BasicClient::disconnect();
2351e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li}
2352e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li
23530bbf8b213ad96051357e3ad6d6d2808bfa31a59aRuben Brunkbool CameraService::Client::canCastToApiClient(apiLevel level) const {
23540bbf8b213ad96051357e3ad6d6d2808bfa31a59aRuben Brunk    return level == API_1;
23550bbf8b213ad96051357e3ad6d6d2808bfa31a59aRuben Brunk}
23560bbf8b213ad96051357e3ad6d6d2808bfa31a59aRuben Brunk
2357ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville TalvalaCameraService::Client::OpsCallback::OpsCallback(wp<BasicClient> client):
2358ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        mClient(client) {
2359ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala}
2360ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
2361ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvalavoid CameraService::Client::OpsCallback::opChanged(int32_t op,
2362ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        const String16& packageName) {
2363ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    sp<BasicClient> client = mClient.promote();
2364ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    if (client != NULL) {
2365ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        client->opChanged(op, packageName);
2366ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    }
2367ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala}
2368ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
236965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
2370a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov//                  UidPolicy
2371a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov// ----------------------------------------------------------------------------
2372a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
2373a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganovvoid CameraService::UidPolicy::registerSelf() {
23748abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala    Mutex::Autolock _l(mUidLock);
23758abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala
2376a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    ActivityManager am;
23778abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala    if (mRegistered) return;
2378a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    am.registerUidObserver(this, ActivityManager::UID_OBSERVER_GONE
2379a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            | ActivityManager::UID_OBSERVER_IDLE
2380a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            | ActivityManager::UID_OBSERVER_ACTIVE,
2381a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            ActivityManager::PROCESS_STATE_UNKNOWN,
2382a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            String16("cameraserver"));
23838abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala    status_t res = am.linkToDeath(this);
23848abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala    if (res == OK) {
23858abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala        mRegistered = true;
23868abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala        ALOGV("UidPolicy: Registered with ActivityManager");
23878abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala    }
2388a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
2389a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
2390a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganovvoid CameraService::UidPolicy::unregisterSelf() {
23918abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala    Mutex::Autolock _l(mUidLock);
23928abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala
2393a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    ActivityManager am;
2394a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    am.unregisterUidObserver(this);
23958abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala    am.unlinkToDeath(this);
23968abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala    mRegistered = false;
23978abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala    mActiveUids.clear();
23988abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala    ALOGV("UidPolicy: Unregistered with ActivityManager");
2399a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
2400a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
2401a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganovvoid CameraService::UidPolicy::onUidGone(uid_t uid, bool disabled) {
2402a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    onUidIdle(uid, disabled);
2403a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
2404a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
2405a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganovvoid CameraService::UidPolicy::onUidActive(uid_t uid) {
2406a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    Mutex::Autolock _l(mUidLock);
2407a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    mActiveUids.insert(uid);
2408a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
2409a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
2410a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganovvoid CameraService::UidPolicy::onUidIdle(uid_t uid, bool /* disabled */) {
2411a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    bool deleted = false;
2412a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    {
2413a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        Mutex::Autolock _l(mUidLock);
2414a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        if (mActiveUids.erase(uid) > 0) {
2415a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            deleted = true;
2416a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        }
2417a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
2418a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    if (deleted) {
2419a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        sp<CameraService> service = mService.promote();
2420a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        if (service != nullptr) {
2421a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            service->blockClientsForUid(uid);
2422a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        }
2423a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
2424a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
2425a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
2426a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganovbool CameraService::UidPolicy::isUidActive(uid_t uid) {
2427a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    Mutex::Autolock _l(mUidLock);
2428a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    return isUidActiveLocked(uid);
2429a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
2430a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
2431a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganovbool CameraService::UidPolicy::isUidActiveLocked(uid_t uid) {
2432a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    // Non-app UIDs are considered always active
24338abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala    // If activity manager is unreachable, assume everything is active
24348abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala    if (uid < FIRST_APPLICATION_UID || !mRegistered) {
2435a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        return true;
2436a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
2437a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    auto it = mOverrideUids.find(uid);
2438a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    if (it != mOverrideUids.end()) {
2439a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        return it->second;
2440a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
2441a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    return mActiveUids.find(uid) != mActiveUids.end();
2442a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
2443a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
2444a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganovvoid CameraService::UidPolicy::UidPolicy::addOverrideUid(uid_t uid, bool active) {
2445a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    updateOverrideUid(uid, active, true);
2446a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
2447a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
2448a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganovvoid CameraService::UidPolicy::removeOverrideUid(uid_t uid) {
2449a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    updateOverrideUid(uid, false, false);
2450a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
2451a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
24528abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvalavoid CameraService::UidPolicy::binderDied(const wp<IBinder>& /*who*/) {
24538abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala    Mutex::Autolock _l(mUidLock);
24548abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala    ALOGV("UidPolicy: ActivityManager has died");
24558abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala    mRegistered = false;
24568abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala    mActiveUids.clear();
24578abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala}
24588abec3f651fa0f862361047fed63fd5b243b9bf8Eino-Ville Talvala
2459a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganovvoid CameraService::UidPolicy::updateOverrideUid(uid_t uid, bool active, bool insert) {
2460a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    bool wasActive = false;
2461a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    bool isActive = false;
2462a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    {
2463a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        Mutex::Autolock _l(mUidLock);
2464a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        wasActive = isUidActiveLocked(uid);
2465a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        mOverrideUids.erase(uid);
2466a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        if (insert) {
2467a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            mOverrideUids.insert(std::pair<uid_t, bool>(uid, active));
2468a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        }
2469a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        isActive = isUidActiveLocked(uid);
2470a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
2471a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    if (wasActive != isActive && !isActive) {
2472a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        sp<CameraService> service = mService.promote();
2473a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        if (service != nullptr) {
2474a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            service->blockClientsForUid(uid);
2475a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        }
2476a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
2477a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
2478a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
2479a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov// ----------------------------------------------------------------------------
2480cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk//                  CameraState
2481cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk// ----------------------------------------------------------------------------
2482cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2483cc776718c0be7c31fe5ab4fc1446d377be60369fRuben BrunkCameraService::CameraState::CameraState(const String8& id, int cost,
2484cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        const std::set<String8>& conflicting) : mId(id),
2485151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski        mStatus(StatusInternal::NOT_PRESENT), mCost(cost), mConflicting(conflicting) {}
2486cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2487cc776718c0be7c31fe5ab4fc1446d377be60369fRuben BrunkCameraService::CameraState::~CameraState() {}
2488cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2489f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville TalvalaCameraService::StatusInternal CameraService::CameraState::getStatus() const {
2490cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    Mutex::Autolock lock(mStatusLock);
2491cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return mStatus;
2492cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
2493cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2494cc776718c0be7c31fe5ab4fc1446d377be60369fRuben BrunkCameraParameters CameraService::CameraState::getShimParams() const {
2495cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return mShimParams;
2496cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
2497cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2498cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkvoid CameraService::CameraState::setShimParams(const CameraParameters& params) {
2499cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    mShimParams = params;
2500cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
2501cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2502cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkint CameraService::CameraState::getCost() const {
2503cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return mCost;
2504cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
2505cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2506cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkstd::set<String8> CameraService::CameraState::getConflicting() const {
2507cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return mConflicting;
2508cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
2509cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2510cc776718c0be7c31fe5ab4fc1446d377be60369fRuben BrunkString8 CameraService::CameraState::getId() const {
2511cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return mId;
2512cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
2513cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2514cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk// ----------------------------------------------------------------------------
251599e69716215cd0665379bc90d708f2ea8689831dRuben Brunk//                  ClientEventListener
251699e69716215cd0665379bc90d708f2ea8689831dRuben Brunk// ----------------------------------------------------------------------------
251799e69716215cd0665379bc90d708f2ea8689831dRuben Brunk
251899e69716215cd0665379bc90d708f2ea8689831dRuben Brunkvoid CameraService::ClientEventListener::onClientAdded(
251999e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        const resource_policy::ClientDescriptor<String8,
252099e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        sp<CameraService::BasicClient>>& descriptor) {
25215404ee174dd6b5e312d3a97bc63c2bc8d142012bChih-Hung Hsieh    const auto& basicClient = descriptor.getValue();
252299e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    if (basicClient.get() != nullptr) {
252399e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        BatteryNotifier& notifier(BatteryNotifier::getInstance());
252499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        notifier.noteStartCamera(descriptor.getKey(),
252599e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                static_cast<int>(basicClient->getClientUid()));
252699e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    }
252799e69716215cd0665379bc90d708f2ea8689831dRuben Brunk}
252899e69716215cd0665379bc90d708f2ea8689831dRuben Brunk
252999e69716215cd0665379bc90d708f2ea8689831dRuben Brunkvoid CameraService::ClientEventListener::onClientRemoved(
253099e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        const resource_policy::ClientDescriptor<String8,
253199e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        sp<CameraService::BasicClient>>& descriptor) {
25325404ee174dd6b5e312d3a97bc63c2bc8d142012bChih-Hung Hsieh    const auto& basicClient = descriptor.getValue();
253399e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    if (basicClient.get() != nullptr) {
253499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        BatteryNotifier& notifier(BatteryNotifier::getInstance());
253599e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        notifier.noteStopCamera(descriptor.getKey(),
253699e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                static_cast<int>(basicClient->getClientUid()));
253799e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    }
253899e69716215cd0665379bc90d708f2ea8689831dRuben Brunk}
253999e69716215cd0665379bc90d708f2ea8689831dRuben Brunk
254099e69716215cd0665379bc90d708f2ea8689831dRuben Brunk
254199e69716215cd0665379bc90d708f2ea8689831dRuben Brunk// ----------------------------------------------------------------------------
2542cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk//                  CameraClientManager
2543cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk// ----------------------------------------------------------------------------
2544cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
254599e69716215cd0665379bc90d708f2ea8689831dRuben BrunkCameraService::CameraClientManager::CameraClientManager() {
254699e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    setListener(std::make_shared<ClientEventListener>());
254799e69716215cd0665379bc90d708f2ea8689831dRuben Brunk}
254899e69716215cd0665379bc90d708f2ea8689831dRuben Brunk
2549cc776718c0be7c31fe5ab4fc1446d377be60369fRuben BrunkCameraService::CameraClientManager::~CameraClientManager() {}
2550cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2551cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunksp<CameraService::BasicClient> CameraService::CameraClientManager::getCameraClient(
2552cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        const String8& id) const {
2553cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    auto descriptor = get(id);
2554cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    if (descriptor == nullptr) {
2555cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        return sp<BasicClient>{nullptr};
2556cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
2557cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return descriptor->getValue();
2558cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
2559cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2560cc776718c0be7c31fe5ab4fc1446d377be60369fRuben BrunkString8 CameraService::CameraClientManager::toString() const {
2561cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    auto all = getAll();
2562cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    String8 ret("[");
2563cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    bool hasAny = false;
2564cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    for (auto& i : all) {
2565cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        hasAny = true;
2566cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        String8 key = i->getKey();
2567cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        int32_t cost = i->getCost();
2568cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        int32_t pid = i->getOwnerId();
25698131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev        int32_t score = i->getPriority().getScore();
25708131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev        int32_t state = i->getPriority().getState();
2571cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        auto conflicting = i->getConflicting();
2572cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        auto clientSp = i->getValue();
2573cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        String8 packageName;
2574022f0cb0c6f135edde4ebe84859c685933ee895eEino-Ville Talvala        userid_t clientUserId = 0;
2575cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        if (clientSp.get() != nullptr) {
2576cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            packageName = String8{clientSp->getPackageName()};
25776267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk            uid_t clientUid = clientSp->getClientUid();
25786267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk            clientUserId = multiuser_get_user_id(clientUid);
2579cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        }
25808131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev        ret.appendFormat("\n(Camera ID: %s, Cost: %" PRId32 ", PID: %" PRId32 ", Score: %"
25818131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                PRId32 ", State: %" PRId32, key.string(), cost, pid, score, state);
2582cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
25836267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        if (clientSp.get() != nullptr) {
25846267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk            ret.appendFormat("User Id: %d, ", clientUserId);
25856267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        }
2586cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        if (packageName.size() != 0) {
2587cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            ret.appendFormat("Client Package Name: %s", packageName.string());
2588cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        }
2589cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2590cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        ret.append(", Conflicting Client Devices: {");
2591cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        for (auto& j : conflicting) {
2592cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            ret.appendFormat("%s, ", j.string());
2593cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        }
2594cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        ret.append("})");
2595cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
2596cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    if (hasAny) ret.append("\n");
2597cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    ret.append("]\n");
2598cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return ret;
2599cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
2600cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2601cc776718c0be7c31fe5ab4fc1446d377be60369fRuben BrunkCameraService::DescriptorPtr CameraService::CameraClientManager::makeClientDescriptor(
2602cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        const String8& key, const sp<BasicClient>& value, int32_t cost,
26038131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev        const std::set<String8>& conflictingKeys, int32_t score, int32_t ownerId,
26048131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev        int32_t state) {
2605cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2606cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return std::make_shared<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>(
26078131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev            key, value, cost, conflictingKeys, score, ownerId, state);
2608cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
2609cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2610cc776718c0be7c31fe5ab4fc1446d377be60369fRuben BrunkCameraService::DescriptorPtr CameraService::CameraClientManager::makeClientDescriptor(
2611cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        const sp<BasicClient>& value, const CameraService::DescriptorPtr& partial) {
2612cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return makeClientDescriptor(partial->getKey(), value, partial->getCost(),
26138131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev            partial->getConflicting(), partial->getPriority().getScore(),
26148131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev            partial->getOwnerId(), partial->getPriority().getState());
2615cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
2616cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2617cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk// ----------------------------------------------------------------------------
261865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
261965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic const int kDumpLockRetries = 50;
262065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic const int kDumpLockSleep = 60000;
262165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
262265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic bool tryLock(Mutex& mutex)
262365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
262465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    bool locked = false;
262565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (int i = 0; i < kDumpLockRetries; ++i) {
262665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mutex.tryLock() == NO_ERROR) {
262765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            locked = true;
262865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
262965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
263065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        usleep(kDumpLockSleep);
263165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
263265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return locked;
263365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
263465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
263565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::dump(int fd, const Vector<String16>& args) {
2636a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    ATRACE_CALL();
2637a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala
263865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
2639d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        dprintf(fd, "Permission Denial: can't dump CameraService from pid=%d, uid=%d\n",
264065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                getCallingPid(),
264165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                getCallingUid());
26428131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala        return NO_ERROR;
26438131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    }
26448131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    bool locked = tryLock(mServiceLock);
26458131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    // failed to lock - CameraService is probably deadlocked
26468131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    if (!locked) {
2647d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        dprintf(fd, "!! CameraService may be deadlocked !!\n");
26488131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    }
26491527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvala
26508131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    if (!mInitialized) {
2651d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        dprintf(fd, "!! No camera HAL available !!\n");
26521527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvala
26538131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala        // Dump event log for error information
26548131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala        dumpEventLog(fd);
26552f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
26568131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala        if (locked) mServiceLock.unlock();
26578131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala        return NO_ERROR;
26588131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    }
2659d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala    dprintf(fd, "\n== Service global info: ==\n\n");
2660d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala    dprintf(fd, "Number of camera devices: %d\n", mNumberOfCameras);
2661c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    dprintf(fd, "Number of normal camera devices: %zu\n", mNormalDeviceIds.size());
2662c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    for (size_t i = 0; i < mNormalDeviceIds.size(); i++) {
2663c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        dprintf(fd, "    Device %zu maps to \"%s\"\n", i, mNormalDeviceIds[i].c_str());
2664c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    }
26658131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    String8 activeClientString = mActiveClientManager.toString();
2666d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala    dprintf(fd, "Active Camera Clients:\n%s", activeClientString.string());
2667d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala    dprintf(fd, "Allowed user IDs: %s\n", toString(mAllowedUsers).string());
2668f81648ec38ff63f1f35516fa27c1c24d846e9ba5Ruben Brunk
26698131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    dumpEventLog(fd);
2670f81648ec38ff63f1f35516fa27c1c24d846e9ba5Ruben Brunk
26718131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    bool stateLocked = tryLock(mCameraStatesLock);
26728131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    if (!stateLocked) {
2673d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        dprintf(fd, "CameraStates in use, may be deadlocked\n");
26748131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    }
26758131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala
2676bd8c503398d6b483b7abba594c7838a4c93b6e23Emilian Peev    int argSize = args.size();
2677bd8c503398d6b483b7abba594c7838a4c93b6e23Emilian Peev    for (int i = 0; i < argSize; i++) {
2678bd8c503398d6b483b7abba594c7838a4c93b6e23Emilian Peev        if (args[i] == TagMonitor::kMonitorOption) {
2679bd8c503398d6b483b7abba594c7838a4c93b6e23Emilian Peev            if (i + 1 < argSize) {
2680bd8c503398d6b483b7abba594c7838a4c93b6e23Emilian Peev                mMonitorTags = String8(args[i + 1]);
2681bd8c503398d6b483b7abba594c7838a4c93b6e23Emilian Peev            }
2682bd8c503398d6b483b7abba594c7838a4c93b6e23Emilian Peev            break;
2683bd8c503398d6b483b7abba594c7838a4c93b6e23Emilian Peev        }
2684bd8c503398d6b483b7abba594c7838a4c93b6e23Emilian Peev    }
2685bd8c503398d6b483b7abba594c7838a4c93b6e23Emilian Peev
26868131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    for (auto& state : mCameraStates) {
26878131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala        String8 cameraId = state.first;
2688cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2689d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        dprintf(fd, "== Camera device %s dynamic info: ==\n", cameraId.string());
2690d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala
2691d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        CameraParameters p = state.second->getShimParams();
2692d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        if (!p.isEmpty()) {
2693d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala            dprintf(fd, "  Camera1 API shim is using parameters:\n        ");
2694d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala            p.dump(fd, args);
2695d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        }
2696d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala
2697d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        auto clientDescriptor = mActiveClientManager.get(cameraId);
26982f140ed90057ca0df3f9da8318241ecfb6dda9ebZhijun He        if (clientDescriptor != nullptr) {
26992f140ed90057ca0df3f9da8318241ecfb6dda9ebZhijun He            dprintf(fd, "  Device %s is open. Client instance dump:\n",
2700d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala                    cameraId.string());
27012f140ed90057ca0df3f9da8318241ecfb6dda9ebZhijun He            dprintf(fd, "    Client priority score: %d state: %d\n",
27022f140ed90057ca0df3f9da8318241ecfb6dda9ebZhijun He                    clientDescriptor->getPriority().getScore(),
27032f140ed90057ca0df3f9da8318241ecfb6dda9ebZhijun He                    clientDescriptor->getPriority().getState());
27042f140ed90057ca0df3f9da8318241ecfb6dda9ebZhijun He            dprintf(fd, "    Client PID: %d\n", clientDescriptor->getOwnerId());
2705d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala
27062f140ed90057ca0df3f9da8318241ecfb6dda9ebZhijun He            auto client = clientDescriptor->getValue();
27072f140ed90057ca0df3f9da8318241ecfb6dda9ebZhijun He            dprintf(fd, "    Client package: %s\n",
27082f140ed90057ca0df3f9da8318241ecfb6dda9ebZhijun He                    String8(client->getPackageName()).string());
2709d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala
27102f140ed90057ca0df3f9da8318241ecfb6dda9ebZhijun He            client->dumpClient(fd, args);
27112f140ed90057ca0df3f9da8318241ecfb6dda9ebZhijun He        } else {
27122f140ed90057ca0df3f9da8318241ecfb6dda9ebZhijun He            dprintf(fd, "  Device %s is closed, no client instance\n",
27132f140ed90057ca0df3f9da8318241ecfb6dda9ebZhijun He                    cameraId.string());
27142f140ed90057ca0df3f9da8318241ecfb6dda9ebZhijun He        }
2715d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala
27168131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    }
271765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
27188131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    if (stateLocked) mCameraStatesLock.unlock();
271965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2720d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala    if (locked) mServiceLock.unlock();
2721d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala
2722f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    mCameraProviderManager->dump(fd, args);
27238131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala
2724d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala    dprintf(fd, "\n== Vendor tags: ==\n\n");
2725d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala
2726d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala    sp<VendorTagDescriptor> desc = VendorTagDescriptor::getGlobalVendorTagDescriptor();
2727d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala    if (desc == NULL) {
272871c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev        sp<VendorTagDescriptorCache> cache =
272971c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                VendorTagDescriptorCache::getGlobalVendorTagCache();
273071c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev        if (cache == NULL) {
273171c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev            dprintf(fd, "No vendor tags.\n");
273271c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev        } else {
273371c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev            cache->dump(fd, /*verbosity*/2, /*indentation*/2);
273471c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev        }
2735d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala    } else {
2736d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        desc->dump(fd, /*verbosity*/2, /*indentation*/2);
2737d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala    }
27388131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala
27398131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    // Dump camera traces if there were any
2740d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala    dprintf(fd, "\n");
27418131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    camera3::CameraTraces::dump(fd, args);
27428131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala
27438131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    // Process dump arguments, if any
27448131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    int n = args.size();
27458131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    String16 verboseOption("-v");
27468131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    String16 unreachableOption("--unreachable");
27478131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala    for (int i = 0; i < n; i++) {
27488131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala        if (args[i] == verboseOption) {
27498131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala            // change logging level
27508131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala            if (i + 1 >= n) continue;
27518131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala            String8 levelStr(args[i+1]);
27528131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala            int level = atoi(levelStr.string());
2753d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala            dprintf(fd, "\nSetting log level to %d.\n", level);
27548131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala            setLogLevel(level);
27558131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala        } else if (args[i] == unreachableOption) {
27568131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala            // Dump memory analysis
27578131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala            // TODO - should limit be an argument parameter?
27588131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala            UnreachableMemoryInfo info;
27598131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala            bool success = GetUnreachableMemory(info, /*limit*/ 10000);
27608131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala            if (!success) {
2761d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala                dprintf(fd, "\n== Unable to dump unreachable memory. "
2762d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala                        "Try disabling SELinux enforcement. ==\n");
27638131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala            } else {
2764d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala                dprintf(fd, "\n== Dumping unreachable memory: ==\n");
27658131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala                std::string s = info.ToString(/*log_contents*/ true);
27668131418cf06d38431aff416f1d38ec011d4259eeEino-Ville Talvala                write(fd, s.c_str(), s.size());
276765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
276865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
276965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
277065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
277165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
277265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
27731527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvalavoid CameraService::dumpEventLog(int fd) {
2774d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala    dprintf(fd, "\n== Camera service events log (most recent at top): ==\n");
27751527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvala
27761527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvala    Mutex::Autolock l(mLogLock);
27771527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvala    for (const auto& msg : mEventLog) {
2778d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        dprintf(fd, "  %s\n", msg.string());
27791527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvala    }
27801527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvala
27811527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvala    if (mEventLog.size() == DEFAULT_EVENT_LOG_LENGTH) {
2782d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        dprintf(fd, "  ...\n");
27831527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvala    } else if (mEventLog.size() == 0) {
2784d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        dprintf(fd, "  [no events yet]\n");
27851527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvala    }
2786d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala    dprintf(fd, "\n");
27871527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvala}
27881527f07eb2b2b40f6b8f53a4644e6a400bddb460Eino-Ville Talvala
27893068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chenvoid CameraService::handleTorchClientBinderDied(const wp<IBinder> &who) {
279088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    Mutex::Autolock al(mTorchClientMapMutex);
27913068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    for (size_t i = 0; i < mTorchClientMap.size(); i++) {
27923068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen        if (mTorchClientMap[i] == who) {
27933068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen            // turn off the torch mode that was turned on by dead client
279488da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen            String8 cameraId = mTorchClientMap.keyAt(i);
279588da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen            status_t res = mFlashlight->setTorchMode(cameraId, false);
279688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen            if (res) {
279788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen                ALOGE("%s: torch client died but couldn't turn off torch: "
279888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen                    "%s (%d)", __FUNCTION__, strerror(-res), res);
279988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen                return;
280088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen            }
28013068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen            mTorchClientMap.removeItemsAt(i);
28023068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen            break;
28033068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen        }
28043068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    }
28053068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen}
28063068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
2807cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk/*virtual*/void CameraService::binderDied(const wp<IBinder> &who) {
2808ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
2809294d0eca9eabfaa3ef0ee8bee7ccf3eaaa925e41Igor Murashkin    /**
2810a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk      * While tempting to promote the wp<IBinder> into a sp, it's actually not supported by the
2811a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk      * binder driver
2812294d0eca9eabfaa3ef0ee8bee7ccf3eaaa925e41Igor Murashkin      */
2813dbfcb38f6636931b2e3e6da8e6aa5a7bfce84a82Yin-Chia Yeh    // PID here is approximate and can be wrong.
2814a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk    logClientDied(getCallingPid(), String8("Binder died unexpectedly"));
2815a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk
28163068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    // check torch client
28173068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    handleTorchClientBinderDied(who);
28183068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
28193068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    // check camera device client
2820cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    if(!evictClientIdByRemote(who)) {
2821cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        ALOGV("%s: Java client's binder death already cleaned up (normal case)", __FUNCTION__);
2822ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin        return;
2823ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    }
2824ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
2825cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    ALOGE("%s: Java client's binder died, removing it from the list of active clients",
2826cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            __FUNCTION__);
2827ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin}
2828ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
2829f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalavoid CameraService::updateStatus(StatusInternal status, const String8& cameraId) {
2830cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    updateStatus(status, cameraId, {});
2831cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
2832bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
2833f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalavoid CameraService::updateStatus(StatusInternal status, const String8& cameraId,
2834f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        std::initializer_list<StatusInternal> rejectSourceStates) {
2835cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    // Do not lock mServiceLock here or can get into a deadlock from
2836cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    // connect() -> disconnect -> updateStatus
2837cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin
2838cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    auto state = getCameraState(cameraId);
2839cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin
2840cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    if (state == nullptr) {
2841cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        ALOGW("%s: Could not update the status for %s, no such device exists", __FUNCTION__,
2842cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                cameraId.string());
2843cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        return;
2844cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
284593747b9c7724f690b3068300514c05629e0b0a3eIgor Murashkin
2846cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    // Update the status for this camera state, then send the onStatusChangedCallbacks to each
2847cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    // of the listeners with both the mStatusStatus and mStatusListenerLock held
2848cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    state->updateStatus(status, cameraId, rejectSourceStates, [this]
2849f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            (const String8& cameraId, StatusInternal status) {
2850cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
2851f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            if (status != StatusInternal::ENUMERATING) {
2852f6463fc62a09b8aad8e811a9abbe9f4d9f2688f9Chien-Yu Chen                // Update torch status if it has a flash unit.
2853f6463fc62a09b8aad8e811a9abbe9f4d9f2688f9Chien-Yu Chen                Mutex::Autolock al(mTorchStatusMutex);
2854f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                TorchModeStatus torchStatus;
2855f6463fc62a09b8aad8e811a9abbe9f4d9f2688f9Chien-Yu Chen                if (getTorchStatusLocked(cameraId, &torchStatus) !=
2856f6463fc62a09b8aad8e811a9abbe9f4d9f2688f9Chien-Yu Chen                        NAME_NOT_FOUND) {
2857f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                    TorchModeStatus newTorchStatus =
2858f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            status == StatusInternal::PRESENT ?
2859f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            TorchModeStatus::AVAILABLE_OFF :
2860f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                            TorchModeStatus::NOT_AVAILABLE;
2861f6463fc62a09b8aad8e811a9abbe9f4d9f2688f9Chien-Yu Chen                    if (torchStatus != newTorchStatus) {
2862f6463fc62a09b8aad8e811a9abbe9f4d9f2688f9Chien-Yu Chen                        onTorchStatusChangedLocked(cameraId, newTorchStatus);
2863f6463fc62a09b8aad8e811a9abbe9f4d9f2688f9Chien-Yu Chen                    }
2864f6463fc62a09b8aad8e811a9abbe9f4d9f2688f9Chien-Yu Chen                }
2865bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin            }
2866bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
2867cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            Mutex::Autolock lock(mStatusListenerLock);
286888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen
2869cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            for (auto& listener : mListenerList) {
2870f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                listener->onStatusChanged(mapToInterface(status), String16(cameraId));
2871cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            }
2872cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        });
2873cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin}
2874cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin
2875f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalatemplate<class Func>
2876f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalavoid CameraService::CameraState::updateStatus(StatusInternal status,
2877f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        const String8& cameraId,
2878f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        std::initializer_list<StatusInternal> rejectSourceStates,
2879f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        Func onStatusUpdatedLocked) {
2880f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    Mutex::Autolock lock(mStatusLock);
2881f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    StatusInternal oldStatus = mStatus;
2882f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    mStatus = status;
2883f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
2884f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    if (oldStatus == status) {
2885f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        return;
2886f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    }
2887f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
2888f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    ALOGV("%s: Status has changed for camera ID %s from %#x to %#x", __FUNCTION__,
2889f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            cameraId.string(), oldStatus, status);
2890f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
2891f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    if (oldStatus == StatusInternal::NOT_PRESENT &&
2892f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            (status != StatusInternal::PRESENT &&
2893f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala             status != StatusInternal::ENUMERATING)) {
2894f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
2895f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        ALOGW("%s: From NOT_PRESENT can only transition into PRESENT or ENUMERATING",
2896f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                __FUNCTION__);
2897f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        mStatus = oldStatus;
2898f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        return;
2899f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    }
2900f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
2901f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    /**
2902f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala     * Sometimes we want to conditionally do a transition.
2903f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala     * For example if a client disconnects, we want to go to PRESENT
2904f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala     * only if we weren't already in NOT_PRESENT or ENUMERATING.
2905f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala     */
2906f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    for (auto& rejectStatus : rejectSourceStates) {
2907f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        if (oldStatus == rejectStatus) {
2908f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            ALOGV("%s: Rejecting status transition for Camera ID %s,  since the source "
2909f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                    "state was was in one of the bad states.", __FUNCTION__, cameraId.string());
2910f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            mStatus = oldStatus;
2911f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            return;
2912f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        }
2913f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    }
2914f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
2915f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    onStatusUpdatedLocked(cameraId, status);
2916f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala}
2917f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
2918e8c96c765b95ec7dcd10732621a825fce05960c6Eino-Ville Talvalavoid CameraService::updateProxyDeviceState(int newState,
2919573291c251d9e85f51f7c0fa1cb35baa2969ca17Emilian Peev        const String8& cameraId, int facing, const String16& clientName, int apiLevel) {
2920412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala    sp<ICameraServiceProxy> proxyBinder = getCameraServiceProxy();
2921412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala    if (proxyBinder == nullptr) return;
2922412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala    String16 id(cameraId);
2923573291c251d9e85f51f7c0fa1cb35baa2969ca17Emilian Peev    proxyBinder->notifyCameraState(id, newState, facing, clientName, apiLevel);
2924412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala}
2925412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala
292688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chenstatus_t CameraService::getTorchStatusLocked(
292788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen        const String8& cameraId,
2928f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        TorchModeStatus *status) const {
292988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    if (!status) {
293088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen        return BAD_VALUE;
293188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    }
29323068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    ssize_t index = mTorchStatusMap.indexOfKey(cameraId);
29333068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    if (index == NAME_NOT_FOUND) {
293488da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen        // invalid camera ID or the camera doesn't have a flash unit
293588da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen        return NAME_NOT_FOUND;
29363068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    }
29373068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
293888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    *status = mTorchStatusMap.valueAt(index);
293988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen    return OK;
29403068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen}
29413068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
294288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chenstatus_t CameraService::setTorchStatusLocked(const String8& cameraId,
2943f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        TorchModeStatus status) {
29443068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    ssize_t index = mTorchStatusMap.indexOfKey(cameraId);
29453068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    if (index == NAME_NOT_FOUND) {
29463068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen        return BAD_VALUE;
29473068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    }
2948f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    mTorchStatusMap.editValueAt(index) = status;
29493068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
29503068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen    return OK;
29513068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen}
29523068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
2953a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganovvoid CameraService::blockClientsForUid(uid_t uid) {
2954a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    const auto clients = mActiveClientManager.getAll();
2955a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    for (auto& current : clients) {
2956a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        if (current != nullptr) {
2957a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            const auto basicClient = current->getValue();
2958a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            if (basicClient.get() != nullptr && basicClient->getClientUid() == uid) {
2959a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov                basicClient->block();
2960a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov            }
2961a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        }
2962a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
2963a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
2964a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
2965a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov// NOTE: This is a remote API - make sure all args are validated
2966a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganovstatus_t CameraService::shellCommand(int in, int out, int err, const Vector<String16>& args) {
2967a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    if (!checkCallingPermission(sManageCameraPermission, nullptr, nullptr)) {
2968a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        return PERMISSION_DENIED;
2969a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
2970a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    if (in == BAD_TYPE || out == BAD_TYPE || err == BAD_TYPE) {
2971a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        return BAD_VALUE;
2972a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
2973a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    if (args.size() == 3 && args[0] == String16("set-uid-state")) {
2974a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        return handleSetUidState(args, err);
2975a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    } else if (args.size() == 2 && args[0] == String16("reset-uid-state")) {
2976a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        return handleResetUidState(args, err);
2977a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    } else if (args.size() == 2 && args[0] == String16("get-uid-state")) {
2978a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        return handleGetUidState(args, out, err);
2979a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    } else if (args.size() == 1 && args[0] == String16("help")) {
2980a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        printHelp(out);
2981a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        return NO_ERROR;
2982a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
2983a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    printHelp(err);
2984a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    return BAD_VALUE;
2985a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
2986a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
2987a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganovstatus_t CameraService::handleSetUidState(const Vector<String16>& args, int err) {
2988a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    PermissionController pc;
2989a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    int uid = pc.getPackageUid(args[1], 0);
2990a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    if (uid <= 0) {
2991a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        ALOGE("Unknown package: '%s'", String8(args[1]).string());
2992a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        dprintf(err, "Unknown package: '%s'\n", String8(args[1]).string());
2993a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        return BAD_VALUE;
2994a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
2995a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    bool active = false;
2996a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    if (args[2] == String16("active")) {
2997a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        active = true;
2998a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    } else if ((args[2] != String16("idle"))) {
2999a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        ALOGE("Expected active or idle but got: '%s'", String8(args[2]).string());
3000a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        return BAD_VALUE;
3001a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
3002a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    mUidPolicy->addOverrideUid(uid, active);
3003a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    return NO_ERROR;
3004a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
3005a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
3006a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganovstatus_t CameraService::handleResetUidState(const Vector<String16>& args, int err) {
3007a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    PermissionController pc;
3008a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    int uid = pc.getPackageUid(args[1], 0);
3009a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    if (uid < 0) {
3010a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        ALOGE("Unknown package: '%s'", String8(args[1]).string());
3011a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        dprintf(err, "Unknown package: '%s'\n", String8(args[1]).string());
3012a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        return BAD_VALUE;
3013a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
3014a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    mUidPolicy->removeOverrideUid(uid);
3015a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    return NO_ERROR;
3016a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
3017a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
3018a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganovstatus_t CameraService::handleGetUidState(const Vector<String16>& args, int out, int err) {
3019a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    PermissionController pc;
3020a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    int uid = pc.getPackageUid(args[1], 0);
3021a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    if (uid <= 0) {
3022a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        ALOGE("Unknown package: '%s'", String8(args[1]).string());
3023a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        dprintf(err, "Unknown package: '%s'\n", String8(args[1]).string());
3024a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        return BAD_VALUE;
3025a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
3026a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    if (mUidPolicy->isUidActive(uid)) {
3027a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        return dprintf(out, "active\n");
3028a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    } else {
3029a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        return dprintf(out, "idle\n");
3030a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
3031a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
3032a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
3033a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganovstatus_t CameraService::printHelp(int out) {
3034a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    return dprintf(out, "Camera service commands:\n"
3035a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        "  get-uid-state <PACKAGE> gets the uid state\n"
3036a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        "  set-uid-state <PACKAGE> <active|idle> overrides the uid state\n"
3037a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        "  reset-uid-state <PACKAGE> clears the uid state override\n"
3038a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov        "  help print this message\n");
3039a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
3040a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
304165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}; // namespace android
3042