blob: d45be62edf85242478dff00217b3310245299834 [file] [log] [blame]
Mathias Agopian65ab4712010-07-14 17:59:35 -07001/*
Ruben Brunkd1176ef2014-02-21 10:51:38 -08002 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Mathias Agopian65ab4712010-07-14 17:59:35 -070016
17#define LOG_TAG "CameraService"
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -070018#define ATRACE_TAG ATRACE_TAG_CAMERA
Iliyan Malchev8951a972011-04-14 16:55:59 -070019//#define LOG_NDEBUG 0
Mathias Agopian65ab4712010-07-14 17:59:35 -070020
Ruben Brunkcc776712015-02-17 20:18:47 -080021#include <algorithm>
22#include <climits>
Mathias Agopian65ab4712010-07-14 17:59:35 -070023#include <stdio.h>
Ruben Brunkcc776712015-02-17 20:18:47 -080024#include <cstring>
25#include <ctime>
26#include <string>
Mathias Agopian65ab4712010-07-14 17:59:35 -070027#include <sys/types.h>
Ruben Brunkcc776712015-02-17 20:18:47 -080028#include <inttypes.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070029#include <pthread.h>
30
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080031#include <android/hardware/ICamera.h>
32#include <android/hardware/ICameraClient.h>
33
Alex Deymo9c2a2c22016-08-25 11:59:14 -070034#include <android-base/macros.h>
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -080035#include <android-base/parseint.h>
Svet Ganova453d0d2018-01-11 15:37:58 -080036#include <binder/ActivityManager.h>
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -080037#include <binder/AppOpsManager.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070038#include <binder/IPCThreadState.h>
39#include <binder/IServiceManager.h>
40#include <binder/MemoryBase.h>
41#include <binder/MemoryHeapBase.h>
Svet Ganova453d0d2018-01-11 15:37:58 -080042#include <binder/PermissionController.h>
Ruben Brunkcc776712015-02-17 20:18:47 -080043#include <binder/ProcessInfoService.h>
Svet Ganova453d0d2018-01-11 15:37:58 -080044#include <binder/IResultReceiver.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070045#include <cutils/atomic.h>
Nipun Kwatrab5ca4612010-09-11 19:31:10 -070046#include <cutils/properties.h>
Svet Ganova453d0d2018-01-11 15:37:58 -080047#include <cutils/misc.h>
Mathias Agopiandf712ea2012-02-25 18:48:35 -080048#include <gui/Surface.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070049#include <hardware/hardware.h>
Eino-Ville Talvalad89821e2016-04-20 11:23:50 -070050#include <memunreachable/memunreachable.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070051#include <media/AudioSystem.h>
Andreas Huber1b86fe02014-01-29 11:13:26 -080052#include <media/IMediaHTTPService.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070053#include <media/mediaplayer.h>
Ruben Brunk99e69712015-05-26 17:25:07 -070054#include <mediautils/BatteryNotifier.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070055#include <utils/Errors.h>
56#include <utils/Log.h>
57#include <utils/String16.h>
Svet Ganov94ec46f2018-06-08 15:03:46 -070058#include <utils/SystemClock.h>
Ruben Brunkd1176ef2014-02-21 10:51:38 -080059#include <utils/Trace.h>
Chien-Yu Chen98a668f2015-12-18 14:10:33 -080060#include <private/android_filesystem_config.h>
Ruben Brunkd1176ef2014-02-21 10:51:38 -080061#include <system/camera_vendor_tags.h>
Ruben Brunkb2119af2014-05-09 19:57:56 -070062#include <system/camera_metadata.h>
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -080063
Ruben Brunkb2119af2014-05-09 19:57:56 -070064#include <system/camera.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070065
66#include "CameraService.h"
Eino-Ville Talvala7b82efe2013-07-25 17:12:35 -070067#include "api1/CameraClient.h"
68#include "api1/Camera2Client.h"
Eino-Ville Talvala7b82efe2013-07-25 17:12:35 -070069#include "api2/CameraDeviceClient.h"
Igor Murashkinff3e31d2013-10-23 16:40:06 -070070#include "utils/CameraTraces.h"
Emilian Peevbd8c5032018-02-14 23:05:40 +000071#include "utils/TagMonitor.h"
Jayant Chowdhary12361932018-08-27 14:46:13 -070072#include "utils/CameraThreadState.h"
Mathias Agopian65ab4712010-07-14 17:59:35 -070073
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080074namespace {
75 const char* kPermissionServiceName = "permission";
76}; // namespace anonymous
77
Mathias Agopian65ab4712010-07-14 17:59:35 -070078namespace android {
79
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080080using binder::Status;
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -080081using hardware::ICamera;
82using hardware::ICameraClient;
Eino-Ville Talvalae8c96c72017-06-27 12:24:07 -070083using hardware::ICameraServiceProxy;
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -080084using hardware::ICameraServiceListener;
85using hardware::camera::common::V1_0::CameraDeviceStatus;
86using hardware::camera::common::V1_0::TorchModeStatus;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080087
Mathias Agopian65ab4712010-07-14 17:59:35 -070088// ----------------------------------------------------------------------------
89// Logging support -- this is for debugging only
90// Use "adb shell dumpsys media.camera -v 1" to change it.
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -070091volatile int32_t gLogLevel = 0;
Mathias Agopian65ab4712010-07-14 17:59:35 -070092
Steve Blockb8a80522011-12-20 16:23:08 +000093#define LOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__);
94#define LOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__);
Mathias Agopian65ab4712010-07-14 17:59:35 -070095
96static void setLogLevel(int level) {
97 android_atomic_write(level, &gLogLevel);
98}
99
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800100// Convenience methods for constructing binder::Status objects for error returns
101
102#define STATUS_ERROR(errorCode, errorString) \
103 binder::Status::fromServiceSpecificError(errorCode, \
104 String8::format("%s:%d: %s", __FUNCTION__, __LINE__, errorString))
105
106#define STATUS_ERROR_FMT(errorCode, errorString, ...) \
107 binder::Status::fromServiceSpecificError(errorCode, \
108 String8::format("%s:%d: " errorString, __FUNCTION__, __LINE__, \
109 __VA_ARGS__))
110
Mathias Agopian65ab4712010-07-14 17:59:35 -0700111// ----------------------------------------------------------------------------
112
Svet Ganova453d0d2018-01-11 15:37:58 -0800113static const String16 sManageCameraPermission("android.permission.MANAGE_CAMERA");
114
Eino-Ville Talvala49c97052016-01-12 14:29:40 -0800115CameraService::CameraService() :
116 mEventLog(DEFAULT_EVENT_LOG_LENGTH),
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -0800117 mNumberOfCameras(0),
Emilian Peevf53f66e2017-04-11 14:29:43 +0100118 mSoundRef(0), mInitialized(false) {
Steve Blockdf64d152012-01-04 20:05:49 +0000119 ALOGI("CameraService started (pid=%d)", getpid());
Ruben Brunkcc776712015-02-17 20:18:47 -0800120 mServiceLockWrapper = std::make_shared<WaitableMutexWrapper>(&mServiceLock);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700121}
122
Iliyan Malchev8951a972011-04-14 16:55:59 -0700123void CameraService::onFirstRef()
124{
Ruben Brunkcc776712015-02-17 20:18:47 -0800125 ALOGI("CameraService process starting");
Igor Murashkin634a5152013-02-20 17:15:11 -0800126
Iliyan Malchev8951a972011-04-14 16:55:59 -0700127 BnCameraService::onFirstRef();
128
Ruben Brunk99e69712015-05-26 17:25:07 -0700129 // Update battery life tracking if service is restarting
130 BatteryNotifier& notifier(BatteryNotifier::getInstance());
131 notifier.noteResetCamera();
132 notifier.noteResetFlashlight();
133
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800134 status_t res = INVALID_OPERATION;
Eino-Ville Talvala9cbbc832017-01-23 15:39:53 -0800135
Emilian Peevf53f66e2017-04-11 14:29:43 +0100136 res = enumerateProviders();
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800137 if (res == OK) {
138 mInitialized = true;
139 }
140
141 CameraService::pingCameraServiceProxy();
Svet Ganova453d0d2018-01-11 15:37:58 -0800142
143 mUidPolicy = new UidPolicy(this);
144 mUidPolicy->registerSelf();
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800145}
146
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800147status_t CameraService::enumerateProviders() {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800148 status_t res;
Emilian Peevaee727d2017-05-04 16:35:48 +0100149
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -0800150 std::vector<std::string> deviceIds;
151 {
152 Mutex::Autolock l(mServiceLock);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800153
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -0800154 if (nullptr == mCameraProviderManager.get()) {
155 mCameraProviderManager = new CameraProviderManager();
156 res = mCameraProviderManager->initialize(this);
157 if (res != OK) {
158 ALOGE("%s: Unable to initialize camera provider manager: %s (%d)",
159 __FUNCTION__, strerror(-res), res);
160 return res;
Emilian Peevaee727d2017-05-04 16:35:48 +0100161 }
162 }
163
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -0800164
165 // Setup vendor tags before we call get_camera_info the first time
166 // because HAL might need to setup static vendor keys in get_camera_info
167 // TODO: maybe put this into CameraProviderManager::initialize()?
168 mCameraProviderManager->setUpVendorTags();
169
170 if (nullptr == mFlashlight.get()) {
171 mFlashlight = new CameraFlashlight(mCameraProviderManager, this);
Yin-Chia Yeh92e33212017-05-24 15:54:15 -0700172 }
173
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -0800174 res = mFlashlight->findFlashUnits();
175 if (res != OK) {
176 ALOGE("Failed to enumerate flash units: %s (%d)", strerror(-res), res);
177 }
178
179 deviceIds = mCameraProviderManager->getCameraDeviceIds();
180 }
181
182
183 for (auto& cameraId : deviceIds) {
184 String8 id8 = String8(cameraId.c_str());
Yin-Chia Yeh92e33212017-05-24 15:54:15 -0700185 onDeviceStatusChanged(id8, CameraDeviceStatus::PRESENT);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800186 }
187
188 return OK;
189}
190
Eino-Ville Talvala412fe562015-08-20 17:08:32 -0700191sp<ICameraServiceProxy> CameraService::getCameraServiceProxy() {
Christopher Wiley92c06fc2016-02-11 15:40:05 -0800192 sp<ICameraServiceProxy> proxyBinder = nullptr;
193#ifndef __BRILLO__
Ruben Brunk2823ce02015-05-19 17:25:13 -0700194 sp<IServiceManager> sm = defaultServiceManager();
Eino-Ville Talvalaf4db13d2016-12-08 11:20:51 -0800195 // Use checkService because cameraserver normally starts before the
196 // system server and the proxy service. So the long timeout that getService
197 // has before giving up is inappropriate.
198 sp<IBinder> binder = sm->checkService(String16("media.camera.proxy"));
Christopher Wiley92c06fc2016-02-11 15:40:05 -0800199 if (binder != nullptr) {
200 proxyBinder = interface_cast<ICameraServiceProxy>(binder);
Ruben Brunk2823ce02015-05-19 17:25:13 -0700201 }
Christopher Wiley92c06fc2016-02-11 15:40:05 -0800202#endif
Eino-Ville Talvala412fe562015-08-20 17:08:32 -0700203 return proxyBinder;
204}
205
206void CameraService::pingCameraServiceProxy() {
207 sp<ICameraServiceProxy> proxyBinder = getCameraServiceProxy();
208 if (proxyBinder == nullptr) return;
Ruben Brunk2823ce02015-05-19 17:25:13 -0700209 proxyBinder->pingForUserUpdate();
Iliyan Malchev8951a972011-04-14 16:55:59 -0700210}
211
Shuzhen Wang7d859d42018-11-06 15:33:23 -0800212void CameraService::broadcastTorchModeStatus(const String8& cameraId, TorchModeStatus status) {
213 Mutex::Autolock lock(mStatusListenerLock);
214
215 for (auto& i : mListenerList) {
216 i->onTorchStatusChanged(mapToInterface(status), String16{cameraId});
217 }
218}
219
Mathias Agopian65ab4712010-07-14 17:59:35 -0700220CameraService::~CameraService() {
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800221 VendorTagDescriptor::clearGlobalVendorTagDescriptor();
Svet Ganova453d0d2018-01-11 15:37:58 -0800222 mUidPolicy->unregisterSelf();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700223}
224
Emilian Peevaee727d2017-05-04 16:35:48 +0100225void CameraService::onNewProviderRegistered() {
226 enumerateProviders();
227}
228
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -0800229void CameraService::updateCameraNumAndIds() {
230 Mutex::Autolock l(mServiceLock);
231 mNumberOfCameras = mCameraProviderManager->getCameraCount();
232 mNormalDeviceIds =
233 mCameraProviderManager->getAPI1CompatibleCameraDeviceIds();
234}
235
Guennadi Liakhovetski151e3be2017-11-28 16:34:18 +0100236void CameraService::addStates(const String8 id) {
237 std::string cameraId(id.c_str());
238 hardware::camera::common::V1_0::CameraResourceCost cost;
239 status_t res = mCameraProviderManager->getResourceCost(cameraId, &cost);
240 if (res != OK) {
241 ALOGE("Failed to query device resource cost: %s (%d)", strerror(-res), res);
242 return;
243 }
244 std::set<String8> conflicting;
245 for (size_t i = 0; i < cost.conflictingDevices.size(); i++) {
246 conflicting.emplace(String8(cost.conflictingDevices[i].c_str()));
247 }
248
249 {
250 Mutex::Autolock lock(mCameraStatesLock);
251 mCameraStates.emplace(id, std::make_shared<CameraState>(id, cost.resourceCost,
252 conflicting));
253 }
254
255 if (mFlashlight->hasFlashUnit(id)) {
Emilian Peev7f25e5f2018-04-11 16:50:34 +0100256 Mutex::Autolock al(mTorchStatusMutex);
Guennadi Liakhovetski151e3be2017-11-28 16:34:18 +0100257 mTorchStatusMap.add(id, TorchModeStatus::AVAILABLE_OFF);
Shuzhen Wang7d859d42018-11-06 15:33:23 -0800258
259 broadcastTorchModeStatus(id, TorchModeStatus::AVAILABLE_OFF);
Guennadi Liakhovetski151e3be2017-11-28 16:34:18 +0100260 }
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -0800261
262 updateCameraNumAndIds();
Guennadi Liakhovetski151e3be2017-11-28 16:34:18 +0100263 logDeviceAdded(id, "Device added");
264}
265
Guennadi Liakhovetski6034bf52017-12-07 10:28:29 +0100266void CameraService::removeStates(const String8 id) {
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -0800267 updateCameraNumAndIds();
Guennadi Liakhovetski6034bf52017-12-07 10:28:29 +0100268 if (mFlashlight->hasFlashUnit(id)) {
Emilian Peev7f25e5f2018-04-11 16:50:34 +0100269 Mutex::Autolock al(mTorchStatusMutex);
Guennadi Liakhovetski6034bf52017-12-07 10:28:29 +0100270 mTorchStatusMap.removeItem(id);
271 }
272
273 {
274 Mutex::Autolock lock(mCameraStatesLock);
275 mCameraStates.erase(id);
276 }
277}
278
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800279void CameraService::onDeviceStatusChanged(const String8& id,
280 CameraDeviceStatus newHalStatus) {
281 ALOGI("%s: Status changed for cameraId=%s, newStatus=%d", __FUNCTION__,
282 id.string(), newHalStatus);
Igor Murashkincba2c162013-03-20 15:56:31 -0700283
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800284 StatusInternal newStatus = mapToInternal(newHalStatus);
285
Ruben Brunkcc776712015-02-17 20:18:47 -0800286 std::shared_ptr<CameraState> state = getCameraState(id);
287
288 if (state == nullptr) {
Yin-Chia Yeh92e33212017-05-24 15:54:15 -0700289 if (newStatus == StatusInternal::PRESENT) {
Guennadi Liakhovetski151e3be2017-11-28 16:34:18 +0100290 ALOGI("%s: Unknown camera ID %s, a new camera is added",
Yin-Chia Yeh92e33212017-05-24 15:54:15 -0700291 __FUNCTION__, id.string());
Guennadi Liakhovetski151e3be2017-11-28 16:34:18 +0100292
293 // First add as absent to make sure clients are notified below
294 addStates(id);
295
296 updateStatus(newStatus, id);
Yin-Chia Yeh92e33212017-05-24 15:54:15 -0700297 } else {
298 ALOGE("%s: Bad camera ID %s", __FUNCTION__, id.string());
299 }
Igor Murashkincba2c162013-03-20 15:56:31 -0700300 return;
301 }
302
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800303 StatusInternal oldStatus = state->getStatus();
Ruben Brunkcc776712015-02-17 20:18:47 -0800304
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800305 if (oldStatus == newStatus) {
Ruben Brunkcc776712015-02-17 20:18:47 -0800306 ALOGE("%s: State transition to the same status %#x not allowed", __FUNCTION__, newStatus);
Igor Murashkincba2c162013-03-20 15:56:31 -0700307 return;
308 }
309
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800310 if (newStatus == StatusInternal::NOT_PRESENT) {
Ruben Brunka8ca9152015-04-07 14:23:40 -0700311 logDeviceRemoved(id, String8::format("Device status changed from %d to %d", oldStatus,
312 newStatus));
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -0800313
314 // Set the device status to NOT_PRESENT, clients will no longer be able to connect
315 // to this device until the status changes
316 updateStatus(StatusInternal::NOT_PRESENT, id);
317
Ruben Brunkcc776712015-02-17 20:18:47 -0800318 sp<BasicClient> clientToDisconnect;
Igor Murashkincba2c162013-03-20 15:56:31 -0700319 {
Ruben Brunkcc776712015-02-17 20:18:47 -0800320 // Don't do this in updateStatus to avoid deadlock over mServiceLock
321 Mutex::Autolock lock(mServiceLock);
Igor Murashkincba2c162013-03-20 15:56:31 -0700322
Ruben Brunkcc776712015-02-17 20:18:47 -0800323 // Remove cached shim parameters
324 state->setShimParams(CameraParameters());
Igor Murashkincba2c162013-03-20 15:56:31 -0700325
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700326 // Remove the client from the list of active clients, if there is one
Ruben Brunkcc776712015-02-17 20:18:47 -0800327 clientToDisconnect = removeClientLocked(id);
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700328 }
Ruben Brunkcc776712015-02-17 20:18:47 -0800329
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700330 // Disconnect client
331 if (clientToDisconnect.get() != nullptr) {
332 ALOGI("%s: Client for camera ID %s evicted due to device status change from HAL",
333 __FUNCTION__, id.string());
Ruben Brunkcc776712015-02-17 20:18:47 -0800334 // Notify the client of disconnection
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800335 clientToDisconnect->notifyError(
336 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED,
Ruben Brunkcc776712015-02-17 20:18:47 -0800337 CaptureResultExtras{});
Ruben Brunkcc776712015-02-17 20:18:47 -0800338 // Ensure not in binder RPC so client disconnect PID checks work correctly
Jayant Chowdhary12361932018-08-27 14:46:13 -0700339 LOG_ALWAYS_FATAL_IF(CameraThreadState::getCallingPid() != getpid(),
Ruben Brunkcc776712015-02-17 20:18:47 -0800340 "onDeviceStatusChanged must be called from the camera service process!");
341 clientToDisconnect->disconnect();
Igor Murashkincba2c162013-03-20 15:56:31 -0700342 }
343
Guennadi Liakhovetski6034bf52017-12-07 10:28:29 +0100344 removeStates(id);
Ruben Brunkcc776712015-02-17 20:18:47 -0800345 } else {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800346 if (oldStatus == StatusInternal::NOT_PRESENT) {
Ruben Brunka8ca9152015-04-07 14:23:40 -0700347 logDeviceAdded(id, String8::format("Device status changed from %d to %d", oldStatus,
348 newStatus));
349 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800350 updateStatus(newStatus, id);
Igor Murashkincba2c162013-03-20 15:56:31 -0700351 }
352
Igor Murashkincba2c162013-03-20 15:56:31 -0700353}
354
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800355void CameraService::onTorchStatusChanged(const String8& cameraId,
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800356 TorchModeStatus newStatus) {
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800357 Mutex::Autolock al(mTorchStatusMutex);
358 onTorchStatusChangedLocked(cameraId, newStatus);
359}
360
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800361void CameraService::onTorchStatusChangedLocked(const String8& cameraId,
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800362 TorchModeStatus newStatus) {
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800363 ALOGI("%s: Torch status changed for cameraId=%s, newStatus=%d",
364 __FUNCTION__, cameraId.string(), newStatus);
365
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800366 TorchModeStatus status;
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800367 status_t res = getTorchStatusLocked(cameraId, &status);
368 if (res) {
Chien-Yu Chenf6463fc2015-04-07 15:11:31 -0700369 ALOGE("%s: cannot get torch status of camera %s: %s (%d)",
370 __FUNCTION__, cameraId.string(), strerror(-res), res);
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800371 return;
372 }
373 if (status == newStatus) {
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800374 return;
375 }
376
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800377 res = setTorchStatusLocked(cameraId, newStatus);
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800378 if (res) {
Eino-Ville Talvalad309fb92015-11-25 12:12:45 -0800379 ALOGE("%s: Failed to set the torch status to %d: %s (%d)", __FUNCTION__,
380 (uint32_t)newStatus, strerror(-res), res);
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800381 return;
382 }
383
Ruben Brunkcc776712015-02-17 20:18:47 -0800384 {
Ruben Brunk99e69712015-05-26 17:25:07 -0700385 // Update battery life logging for flashlight
Chien-Yu Chenfe751be2015-09-01 14:16:44 -0700386 Mutex::Autolock al(mTorchUidMapMutex);
Ruben Brunk99e69712015-05-26 17:25:07 -0700387 auto iter = mTorchUidMap.find(cameraId);
388 if (iter != mTorchUidMap.end()) {
389 int oldUid = iter->second.second;
390 int newUid = iter->second.first;
391 BatteryNotifier& notifier(BatteryNotifier::getInstance());
392 if (oldUid != newUid) {
393 // If the UID has changed, log the status and update current UID in mTorchUidMap
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800394 if (status == TorchModeStatus::AVAILABLE_ON) {
Ruben Brunk99e69712015-05-26 17:25:07 -0700395 notifier.noteFlashlightOff(cameraId, oldUid);
396 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800397 if (newStatus == TorchModeStatus::AVAILABLE_ON) {
Ruben Brunk99e69712015-05-26 17:25:07 -0700398 notifier.noteFlashlightOn(cameraId, newUid);
399 }
400 iter->second.second = newUid;
401 } else {
402 // If the UID has not changed, log the status
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800403 if (newStatus == TorchModeStatus::AVAILABLE_ON) {
Ruben Brunk99e69712015-05-26 17:25:07 -0700404 notifier.noteFlashlightOn(cameraId, oldUid);
405 } else {
406 notifier.noteFlashlightOff(cameraId, oldUid);
407 }
408 }
409 }
410 }
411
Shuzhen Wang7d859d42018-11-06 15:33:23 -0800412 broadcastTorchModeStatus(cameraId, newStatus);
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800413}
414
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800415Status CameraService::getNumberOfCameras(int32_t type, int32_t* numCameras) {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -0700416 ATRACE_CALL();
Emilian Peevaee727d2017-05-04 16:35:48 +0100417 Mutex::Autolock l(mServiceLock);
Eino-Ville Talvalabad43582015-08-14 13:12:32 -0700418 switch (type) {
419 case CAMERA_TYPE_BACKWARD_COMPATIBLE:
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -0800420 *numCameras = static_cast<int>(mNormalDeviceIds.size());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800421 break;
Eino-Ville Talvalabad43582015-08-14 13:12:32 -0700422 case CAMERA_TYPE_ALL:
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800423 *numCameras = mNumberOfCameras;
424 break;
Eino-Ville Talvalabad43582015-08-14 13:12:32 -0700425 default:
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800426 ALOGW("%s: Unknown camera type %d",
Eino-Ville Talvalabad43582015-08-14 13:12:32 -0700427 __FUNCTION__, type);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800428 return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
429 "Unknown camera type %d", type);
Eino-Ville Talvalabad43582015-08-14 13:12:32 -0700430 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800431 return Status::ok();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700432}
433
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800434Status CameraService::getCameraInfo(int cameraId,
435 CameraInfo* cameraInfo) {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -0700436 ATRACE_CALL();
Emilian Peevaee727d2017-05-04 16:35:48 +0100437 Mutex::Autolock l(mServiceLock);
438
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800439 if (!mInitialized) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800440 return STATUS_ERROR(ERROR_DISCONNECTED,
441 "Camera subsystem is not available");
Iliyan Malchev8951a972011-04-14 16:55:59 -0700442 }
443
Mathias Agopian65ab4712010-07-14 17:59:35 -0700444 if (cameraId < 0 || cameraId >= mNumberOfCameras) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800445 return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT,
446 "CameraId is not valid");
Mathias Agopian65ab4712010-07-14 17:59:35 -0700447 }
448
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800449 Status ret = Status::ok();
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -0800450 status_t err = mCameraProviderManager->getCameraInfo(
451 cameraIdIntToStrLocked(cameraId), cameraInfo);
Emilian Peevf53f66e2017-04-11 14:29:43 +0100452 if (err != OK) {
453 ret = STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
454 "Error retrieving camera info from device %d: %s (%d)", cameraId,
455 strerror(-err), err);
Ruben Brunkcc776712015-02-17 20:18:47 -0800456 }
Emilian Peevf53f66e2017-04-11 14:29:43 +0100457
Ruben Brunkcc776712015-02-17 20:18:47 -0800458 return ret;
459}
Ruben Brunkb2119af2014-05-09 19:57:56 -0700460
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -0800461std::string CameraService::cameraIdIntToStrLocked(int cameraIdInt) {
462 if (cameraIdInt < 0 || cameraIdInt >= static_cast<int>(mNormalDeviceIds.size())) {
463 ALOGE("%s: input id %d invalid: valid range (0, %zu)",
464 __FUNCTION__, cameraIdInt, mNormalDeviceIds.size());
465 return std::string{};
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800466 }
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -0800467
468 return mNormalDeviceIds[cameraIdInt];
469}
470
471String8 CameraService::cameraIdIntToStr(int cameraIdInt) {
472 Mutex::Autolock lock(mServiceLock);
473 return String8(cameraIdIntToStrLocked(cameraIdInt).c_str());
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800474}
475
476Status CameraService::getCameraCharacteristics(const String16& cameraId,
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800477 CameraMetadata* cameraInfo) {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -0700478 ATRACE_CALL();
Zhijun He2b59be82013-09-25 10:14:30 -0700479 if (!cameraInfo) {
480 ALOGE("%s: cameraInfo is NULL", __FUNCTION__);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800481 return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "cameraInfo is NULL");
Zhijun He2b59be82013-09-25 10:14:30 -0700482 }
483
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800484 if (!mInitialized) {
485 ALOGE("%s: Camera HAL couldn't be initialized", __FUNCTION__);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800486 return STATUS_ERROR(ERROR_DISCONNECTED,
487 "Camera subsystem is not available");;
Zhijun He2b59be82013-09-25 10:14:30 -0700488 }
489
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800490 Status ret{};
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800491
Emilian Peevf53f66e2017-04-11 14:29:43 +0100492 status_t res = mCameraProviderManager->getCameraCharacteristics(
493 String8(cameraId).string(), cameraInfo);
494 if (res != OK) {
495 return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, "Unable to retrieve camera "
496 "characteristics for device %s: %s (%d)", String8(cameraId).string(),
497 strerror(-res), res);
Ruben Brunkb2119af2014-05-09 19:57:56 -0700498 }
Zhijun He2b59be82013-09-25 10:14:30 -0700499
Jayant Chowdhary12361932018-08-27 14:46:13 -0700500 int callingPid = CameraThreadState::getCallingPid();
501 int callingUid = CameraThreadState::getCallingUid();
Emilian Peeve20c6372018-08-14 18:45:53 +0100502 std::vector<int32_t> tagsRemoved;
503 // If it's not calling from cameraserver, check the permission.
504 if ((callingPid != getpid()) &&
505 !checkPermission(String16("android.permission.CAMERA"), callingPid, callingUid)) {
506 res = cameraInfo->removePermissionEntries(
507 mCameraProviderManager->getProviderTagIdLocked(String8(cameraId).string()),
508 &tagsRemoved);
509 if (res != OK) {
510 cameraInfo->clear();
511 return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, "Failed to remove camera"
512 " characteristics needing camera permission for device %s: %s (%d)",
513 String8(cameraId).string(), strerror(-res), res);
514 }
515 }
516
517 if (!tagsRemoved.empty()) {
518 res = cameraInfo->update(ANDROID_REQUEST_CHARACTERISTIC_KEYS_NEEDING_PERMISSION,
519 tagsRemoved.data(), tagsRemoved.size());
520 if (res != OK) {
521 cameraInfo->clear();
522 return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, "Failed to insert camera "
523 "keys needing permission for device %s: %s (%d)", String8(cameraId).string(),
524 strerror(-res), res);
525 }
526 }
527
Zhijun He2b59be82013-09-25 10:14:30 -0700528 return ret;
529}
530
Ruben Brunkcc776712015-02-17 20:18:47 -0800531String8 CameraService::getFormattedCurrentTime() {
532 time_t now = time(nullptr);
533 char formattedTime[64];
534 strftime(formattedTime, sizeof(formattedTime), "%m-%d %H:%M:%S", localtime(&now));
535 return String8(formattedTime);
536}
537
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800538Status CameraService::getCameraVendorTagDescriptor(
539 /*out*/
540 hardware::camera2::params::VendorTagDescriptor* desc) {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -0700541 ATRACE_CALL();
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800542 if (!mInitialized) {
543 ALOGE("%s: Camera HAL couldn't be initialized", __FUNCTION__);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800544 return STATUS_ERROR(ERROR_DISCONNECTED, "Camera subsystem not available");
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800545 }
Eino-Ville Talvala1e74e242016-03-03 11:24:28 -0800546 sp<VendorTagDescriptor> globalDescriptor = VendorTagDescriptor::getGlobalVendorTagDescriptor();
547 if (globalDescriptor != nullptr) {
548 *desc = *(globalDescriptor.get());
549 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800550 return Status::ok();
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800551}
552
Emilian Peev71c73a22017-03-21 16:35:51 +0000553Status CameraService::getCameraVendorTagCache(
554 /*out*/ hardware::camera2::params::VendorTagDescriptorCache* cache) {
555 ATRACE_CALL();
556 if (!mInitialized) {
557 ALOGE("%s: Camera HAL couldn't be initialized", __FUNCTION__);
558 return STATUS_ERROR(ERROR_DISCONNECTED,
559 "Camera subsystem not available");
560 }
561 sp<VendorTagDescriptorCache> globalCache =
562 VendorTagDescriptorCache::getGlobalVendorTagCache();
563 if (globalCache != nullptr) {
564 *cache = *(globalCache.get());
565 }
566 return Status::ok();
567}
568
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800569int CameraService::getDeviceVersion(const String8& cameraId, int* facing) {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -0700570 ATRACE_CALL();
Igor Murashkin634a5152013-02-20 17:15:11 -0800571
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800572 int deviceVersion = 0;
573
Emilian Peevf53f66e2017-04-11 14:29:43 +0100574 status_t res;
575 hardware::hidl_version maxVersion{0,0};
576 res = mCameraProviderManager->getHighestSupportedVersion(cameraId.string(),
577 &maxVersion);
578 if (res != OK) return -1;
579 deviceVersion = HARDWARE_DEVICE_API_VERSION(maxVersion.get_major(), maxVersion.get_minor());
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800580
Emilian Peevf53f66e2017-04-11 14:29:43 +0100581 hardware::CameraInfo info;
582 if (facing) {
583 res = mCameraProviderManager->getCameraInfo(cameraId.string(), &info);
Eino-Ville Talvala6963d0a2017-01-31 13:00:34 -0800584 if (res != OK) return -1;
Emilian Peevf53f66e2017-04-11 14:29:43 +0100585 *facing = info.facing;
Igor Murashkin634a5152013-02-20 17:15:11 -0800586 }
Emilian Peevf53f66e2017-04-11 14:29:43 +0100587
Igor Murashkin634a5152013-02-20 17:15:11 -0800588 return deviceVersion;
589}
590
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800591Status CameraService::filterGetInfoErrorCode(status_t err) {
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -0700592 switch(err) {
593 case NO_ERROR:
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800594 return Status::ok();
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800595 case BAD_VALUE:
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800596 return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT,
597 "CameraId is not valid for HAL module");
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800598 case NO_INIT:
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800599 return STATUS_ERROR(ERROR_DISCONNECTED,
600 "Camera device not available");
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -0700601 default:
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800602 return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
603 "Camera HAL encountered error %d: %s",
604 err, strerror(-err));
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -0700605 }
Igor Murashkinbfc99152013-02-27 12:55:20 -0800606}
607
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800608Status CameraService::makeClient(const sp<CameraService>& cameraService,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800609 const sp<IInterface>& cameraCb, const String16& packageName, const String8& cameraId,
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -0800610 int api1CameraId, int facing, int clientPid, uid_t clientUid, int servicePid,
Shuzhen Wang06fcfb02018-07-30 18:23:31 -0700611 int halVersion, int deviceVersion, apiLevel effectiveApiLevel,
Ruben Brunkcc776712015-02-17 20:18:47 -0800612 /*out*/sp<BasicClient>* client) {
613
Ruben Brunkcc776712015-02-17 20:18:47 -0800614 if (halVersion < 0 || halVersion == deviceVersion) {
615 // Default path: HAL version is unspecified by caller, create CameraClient
616 // based on device version reported by the HAL.
617 switch(deviceVersion) {
618 case CAMERA_DEVICE_API_VERSION_1_0:
619 if (effectiveApiLevel == API_1) { // Camera1 API route
620 sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -0800621 *client = new CameraClient(cameraService, tmp, packageName,
622 api1CameraId, facing, clientPid, clientUid,
Shuzhen Wang06fcfb02018-07-30 18:23:31 -0700623 getpid());
Ruben Brunkcc776712015-02-17 20:18:47 -0800624 } else { // Camera2 API route
625 ALOGW("Camera using old HAL version: %d", deviceVersion);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800626 return STATUS_ERROR_FMT(ERROR_DEPRECATED_HAL,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800627 "Camera device \"%s\" HAL version %d does not support camera2 API",
628 cameraId.string(), deviceVersion);
Ruben Brunkcc776712015-02-17 20:18:47 -0800629 }
630 break;
Ruben Brunkcc776712015-02-17 20:18:47 -0800631 case CAMERA_DEVICE_API_VERSION_3_0:
632 case CAMERA_DEVICE_API_VERSION_3_1:
633 case CAMERA_DEVICE_API_VERSION_3_2:
634 case CAMERA_DEVICE_API_VERSION_3_3:
Zhijun He4afbdec2016-05-04 15:42:51 -0700635 case CAMERA_DEVICE_API_VERSION_3_4:
Shuzhen Wangf9d2c022018-08-21 12:07:35 -0700636 case CAMERA_DEVICE_API_VERSION_3_5:
Ruben Brunkcc776712015-02-17 20:18:47 -0800637 if (effectiveApiLevel == API_1) { // Camera1 API route
638 sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -0800639 *client = new Camera2Client(cameraService, tmp, packageName,
640 cameraId, api1CameraId,
641 facing, clientPid, clientUid,
Shuzhen Wang06fcfb02018-07-30 18:23:31 -0700642 servicePid);
Ruben Brunkcc776712015-02-17 20:18:47 -0800643 } else { // Camera2 API route
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800644 sp<hardware::camera2::ICameraDeviceCallbacks> tmp =
645 static_cast<hardware::camera2::ICameraDeviceCallbacks*>(cameraCb.get());
646 *client = new CameraDeviceClient(cameraService, tmp, packageName, cameraId,
Ruben Brunkcc776712015-02-17 20:18:47 -0800647 facing, clientPid, clientUid, servicePid);
648 }
649 break;
650 default:
651 // Should not be reachable
652 ALOGE("Unknown camera device HAL version: %d", deviceVersion);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800653 return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800654 "Camera device \"%s\" has unknown HAL version %d",
655 cameraId.string(), deviceVersion);
Ruben Brunkcc776712015-02-17 20:18:47 -0800656 }
657 } else {
658 // A particular HAL version is requested by caller. Create CameraClient
659 // based on the requested HAL version.
660 if (deviceVersion > CAMERA_DEVICE_API_VERSION_1_0 &&
661 halVersion == CAMERA_DEVICE_API_VERSION_1_0) {
662 // Only support higher HAL version device opened as HAL1.0 device.
663 sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -0800664 *client = new CameraClient(cameraService, tmp, packageName,
665 api1CameraId, facing, clientPid, clientUid,
Shuzhen Wang06fcfb02018-07-30 18:23:31 -0700666 servicePid);
Ruben Brunkcc776712015-02-17 20:18:47 -0800667 } else {
668 // Other combinations (e.g. HAL3.x open as HAL2.x) are not supported yet.
669 ALOGE("Invalid camera HAL version %x: HAL %x device can only be"
670 " opened as HAL %x device", halVersion, deviceVersion,
671 CAMERA_DEVICE_API_VERSION_1_0);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800672 return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800673 "Camera device \"%s\" (HAL version %d) cannot be opened as HAL version %d",
674 cameraId.string(), deviceVersion, halVersion);
Ruben Brunkcc776712015-02-17 20:18:47 -0800675 }
676 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800677 return Status::ok();
Ruben Brunkcc776712015-02-17 20:18:47 -0800678}
679
Ruben Brunk6267b532015-04-30 17:44:07 -0700680String8 CameraService::toString(std::set<userid_t> intSet) {
681 String8 s("");
682 bool first = true;
683 for (userid_t i : intSet) {
684 if (first) {
685 s.appendFormat("%d", i);
686 first = false;
687 } else {
688 s.appendFormat(", %d", i);
689 }
690 }
691 return s;
692}
693
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800694int32_t CameraService::mapToInterface(TorchModeStatus status) {
695 int32_t serviceStatus = ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE;
696 switch (status) {
697 case TorchModeStatus::NOT_AVAILABLE:
698 serviceStatus = ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE;
699 break;
700 case TorchModeStatus::AVAILABLE_OFF:
701 serviceStatus = ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF;
702 break;
703 case TorchModeStatus::AVAILABLE_ON:
704 serviceStatus = ICameraServiceListener::TORCH_STATUS_AVAILABLE_ON;
705 break;
706 default:
707 ALOGW("Unknown new flash status: %d", status);
708 }
709 return serviceStatus;
710}
711
712CameraService::StatusInternal CameraService::mapToInternal(CameraDeviceStatus status) {
713 StatusInternal serviceStatus = StatusInternal::NOT_PRESENT;
714 switch (status) {
715 case CameraDeviceStatus::NOT_PRESENT:
716 serviceStatus = StatusInternal::NOT_PRESENT;
717 break;
718 case CameraDeviceStatus::PRESENT:
719 serviceStatus = StatusInternal::PRESENT;
720 break;
721 case CameraDeviceStatus::ENUMERATING:
722 serviceStatus = StatusInternal::ENUMERATING;
723 break;
724 default:
725 ALOGW("Unknown new HAL device status: %d", status);
726 }
727 return serviceStatus;
728}
729
730int32_t CameraService::mapToInterface(StatusInternal status) {
731 int32_t serviceStatus = ICameraServiceListener::STATUS_NOT_PRESENT;
732 switch (status) {
733 case StatusInternal::NOT_PRESENT:
734 serviceStatus = ICameraServiceListener::STATUS_NOT_PRESENT;
735 break;
736 case StatusInternal::PRESENT:
737 serviceStatus = ICameraServiceListener::STATUS_PRESENT;
738 break;
739 case StatusInternal::ENUMERATING:
740 serviceStatus = ICameraServiceListener::STATUS_ENUMERATING;
741 break;
742 case StatusInternal::NOT_AVAILABLE:
743 serviceStatus = ICameraServiceListener::STATUS_NOT_AVAILABLE;
744 break;
745 case StatusInternal::UNKNOWN:
746 serviceStatus = ICameraServiceListener::STATUS_UNKNOWN;
747 break;
748 default:
749 ALOGW("Unknown new internal device status: %d", status);
750 }
751 return serviceStatus;
752}
753
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800754Status CameraService::initializeShimMetadata(int cameraId) {
Jayant Chowdhary12361932018-08-27 14:46:13 -0700755 int uid = CameraThreadState::getCallingUid();
Ruben Brunkb2119af2014-05-09 19:57:56 -0700756
Chien-Yu Chen98a668f2015-12-18 14:10:33 -0800757 String16 internalPackageName("cameraserver");
Ruben Brunkcc776712015-02-17 20:18:47 -0800758 String8 id = String8::format("%d", cameraId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800759 Status ret = Status::ok();
Ruben Brunkcc776712015-02-17 20:18:47 -0800760 sp<Client> tmp = nullptr;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800761 if (!(ret = connectHelper<ICameraClient,Client>(
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -0800762 sp<ICameraClient>{nullptr}, id, cameraId,
763 static_cast<int>(CAMERA_HAL_API_VERSION_UNSPECIFIED),
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800764 internalPackageName, uid, USE_CALLING_PID,
Shuzhen Wang06fcfb02018-07-30 18:23:31 -0700765 API_1, /*shimUpdateOnly*/ true, /*out*/ tmp)
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800766 ).isOk()) {
767 ALOGE("%s: Error initializing shim metadata: %s", __FUNCTION__, ret.toString8().string());
Ruben Brunkb2119af2014-05-09 19:57:56 -0700768 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800769 return ret;
Ruben Brunkb2119af2014-05-09 19:57:56 -0700770}
771
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800772Status CameraService::getLegacyParametersLazy(int cameraId,
Igor Murashkin65d14b92014-06-17 12:03:20 -0700773 /*out*/
774 CameraParameters* parameters) {
775
776 ALOGV("%s: for cameraId: %d", __FUNCTION__, cameraId);
777
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800778 Status ret = Status::ok();
Igor Murashkin65d14b92014-06-17 12:03:20 -0700779
780 if (parameters == NULL) {
781 ALOGE("%s: parameters must not be null", __FUNCTION__);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800782 return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Parameters must not be null");
Igor Murashkin65d14b92014-06-17 12:03:20 -0700783 }
784
Ruben Brunkcc776712015-02-17 20:18:47 -0800785 String8 id = String8::format("%d", cameraId);
786
787 // Check if we already have parameters
788 {
789 // Scope for service lock
Igor Murashkin65d14b92014-06-17 12:03:20 -0700790 Mutex::Autolock lock(mServiceLock);
Ruben Brunkcc776712015-02-17 20:18:47 -0800791 auto cameraState = getCameraState(id);
792 if (cameraState == nullptr) {
793 ALOGE("%s: Invalid camera ID: %s", __FUNCTION__, id.string());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800794 return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
795 "Invalid camera ID: %s", id.string());
Ruben Brunkcc776712015-02-17 20:18:47 -0800796 }
797 CameraParameters p = cameraState->getShimParams();
798 if (!p.isEmpty()) {
799 *parameters = p;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800800 return ret;
Igor Murashkin65d14b92014-06-17 12:03:20 -0700801 }
802 }
803
Jayant Chowdhary12361932018-08-27 14:46:13 -0700804 int64_t token = CameraThreadState::clearCallingIdentity();
Ruben Brunkcc776712015-02-17 20:18:47 -0800805 ret = initializeShimMetadata(cameraId);
Jayant Chowdhary12361932018-08-27 14:46:13 -0700806 CameraThreadState::restoreCallingIdentity(token);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800807 if (!ret.isOk()) {
Ruben Brunkcc776712015-02-17 20:18:47 -0800808 // Error already logged by callee
809 return ret;
810 }
811
812 // Check for parameters again
813 {
814 // Scope for service lock
815 Mutex::Autolock lock(mServiceLock);
816 auto cameraState = getCameraState(id);
817 if (cameraState == nullptr) {
818 ALOGE("%s: Invalid camera ID: %s", __FUNCTION__, id.string());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800819 return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
820 "Invalid camera ID: %s", id.string());
Igor Murashkin65d14b92014-06-17 12:03:20 -0700821 }
Ruben Brunkcc776712015-02-17 20:18:47 -0800822 CameraParameters p = cameraState->getShimParams();
823 if (!p.isEmpty()) {
824 *parameters = p;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800825 return ret;
Igor Murashkin65d14b92014-06-17 12:03:20 -0700826 }
827 }
828
Ruben Brunkcc776712015-02-17 20:18:47 -0800829 ALOGE("%s: Parameters were not initialized, or were empty. Device may not be present.",
830 __FUNCTION__);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800831 return STATUS_ERROR(ERROR_INVALID_OPERATION, "Unable to initialize legacy parameters");
Igor Murashkin65d14b92014-06-17 12:03:20 -0700832}
833
Chien-Yu Chen98a668f2015-12-18 14:10:33 -0800834// Can camera service trust the caller based on the calling UID?
835static bool isTrustedCallingUid(uid_t uid) {
836 switch (uid) {
Eino-Ville Talvalaaf9d0302016-06-29 14:40:10 -0700837 case AID_MEDIA: // mediaserver
Chien-Yu Chen98a668f2015-12-18 14:10:33 -0800838 case AID_CAMERASERVER: // cameraserver
Eino-Ville Talvalaaf9d0302016-06-29 14:40:10 -0700839 case AID_RADIO: // telephony
Chien-Yu Chen98a668f2015-12-18 14:10:33 -0800840 return true;
841 default:
842 return false;
843 }
844}
845
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800846Status CameraService::validateConnectLocked(const String8& cameraId,
Chien-Yu Chen18df60e2016-03-18 18:18:09 -0700847 const String8& clientName8, /*inout*/int& clientUid, /*inout*/int& clientPid,
848 /*out*/int& originalClientPid) const {
Tyler Luu5861a9a2011-10-06 00:00:03 -0500849
Alex Deymo9c2a2c22016-08-25 11:59:14 -0700850#ifdef __BRILLO__
851 UNUSED(clientName8);
852 UNUSED(clientUid);
853 UNUSED(clientPid);
854 UNUSED(originalClientPid);
855#else
Chien-Yu Chen7939aee2016-03-21 18:19:33 -0700856 Status allowed = validateClientPermissionsLocked(cameraId, clientName8, clientUid, clientPid,
857 originalClientPid);
Eino-Ville Talvala04926862016-03-02 15:42:53 -0800858 if (!allowed.isOk()) {
Christopher Wileyce761d12016-02-16 10:15:00 -0800859 return allowed;
860 }
Alex Deymo9c2a2c22016-08-25 11:59:14 -0700861#endif // __BRILLO__
Christopher Wileyce761d12016-02-16 10:15:00 -0800862
Jayant Chowdhary12361932018-08-27 14:46:13 -0700863 int callingPid = CameraThreadState::getCallingPid();
Eino-Ville Talvala04926862016-03-02 15:42:53 -0800864
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800865 if (!mInitialized) {
Ruben Brunkcc776712015-02-17 20:18:47 -0800866 ALOGE("CameraService::connect X (PID %d) rejected (camera HAL module not loaded)",
867 callingPid);
Eino-Ville Talvala04926862016-03-02 15:42:53 -0800868 return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
869 "No camera HAL module available to open camera device \"%s\"", cameraId.string());
Iliyan Malchev8951a972011-04-14 16:55:59 -0700870 }
871
Ruben Brunkcc776712015-02-17 20:18:47 -0800872 if (getCameraState(cameraId) == nullptr) {
873 ALOGE("CameraService::connect X (PID %d) rejected (invalid camera ID %s)", callingPid,
874 cameraId.string());
Eino-Ville Talvala04926862016-03-02 15:42:53 -0800875 return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
876 "No camera device with ID \"%s\" available", cameraId.string());
Mathias Agopian65ab4712010-07-14 17:59:35 -0700877 }
878
Eino-Ville Talvala04926862016-03-02 15:42:53 -0800879 status_t err = checkIfDeviceIsUsable(cameraId);
880 if (err != NO_ERROR) {
881 switch(err) {
882 case -ENODEV:
883 case -EBUSY:
884 return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
885 "No camera device with ID \"%s\" currently available", cameraId.string());
886 default:
887 return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
888 "Unknown error connecting to ID \"%s\"", cameraId.string());
889 }
890 }
891 return Status::ok();
Christopher Wiley0039bcf2016-02-05 10:29:50 -0800892}
893
Eino-Ville Talvala04926862016-03-02 15:42:53 -0800894Status CameraService::validateClientPermissionsLocked(const String8& cameraId,
Chien-Yu Chen7939aee2016-03-21 18:19:33 -0700895 const String8& clientName8, int& clientUid, int& clientPid,
896 /*out*/int& originalClientPid) const {
Jayant Chowdhary12361932018-08-27 14:46:13 -0700897 int callingPid = CameraThreadState::getCallingPid();
898 int callingUid = CameraThreadState::getCallingUid();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700899
Chien-Yu Chen98a668f2015-12-18 14:10:33 -0800900 // Check if we can trust clientUid
Mathias Agopian65ab4712010-07-14 17:59:35 -0700901 if (clientUid == USE_CALLING_UID) {
Chien-Yu Chen98a668f2015-12-18 14:10:33 -0800902 clientUid = callingUid;
903 } else if (!isTrustedCallingUid(callingUid)) {
904 ALOGE("CameraService::connect X (calling PID %d, calling UID %d) rejected "
905 "(don't trust clientUid %d)", callingPid, callingUid, clientUid);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800906 return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
907 "Untrusted caller (calling PID %d, UID %d) trying to "
908 "forward camera access to camera %s for client %s (PID %d, UID %d)",
909 callingPid, callingUid, cameraId.string(),
910 clientName8.string(), clientUid, clientPid);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700911 }
912
Chien-Yu Chen98a668f2015-12-18 14:10:33 -0800913 // Check if we can trust clientPid
914 if (clientPid == USE_CALLING_PID) {
915 clientPid = callingPid;
916 } else if (!isTrustedCallingUid(callingUid)) {
917 ALOGE("CameraService::connect X (calling PID %d, calling UID %d) rejected "
918 "(don't trust clientPid %d)", callingPid, callingUid, clientPid);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800919 return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
920 "Untrusted caller (calling PID %d, UID %d) trying to "
921 "forward camera access to camera %s for client %s (PID %d, UID %d)",
922 callingPid, callingUid, cameraId.string(),
923 clientName8.string(), clientUid, clientPid);
Chien-Yu Chen98a668f2015-12-18 14:10:33 -0800924 }
925
926 // If it's not calling from cameraserver, check the permission.
927 if (callingPid != getpid() &&
928 !checkPermission(String16("android.permission.CAMERA"), clientPid, clientUid)) {
929 ALOGE("Permission Denial: can't use the camera pid=%d, uid=%d", clientPid, clientUid);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800930 return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
931 "Caller \"%s\" (PID %d, UID %d) cannot open camera \"%s\" without camera permission",
932 clientName8.string(), clientUid, clientPid, cameraId.string());
Chien-Yu Chen98a668f2015-12-18 14:10:33 -0800933 }
934
Svet Ganova453d0d2018-01-11 15:37:58 -0800935 // Make sure the UID is in an active state to use the camera
Svet Ganov7b4ab782018-03-25 12:48:10 -0700936 if (!mUidPolicy->isUidActive(callingUid, String16(clientName8))) {
Svet Ganova453d0d2018-01-11 15:37:58 -0800937 ALOGE("Access Denial: can't use the camera from an idle UID pid=%d, uid=%d",
938 clientPid, clientUid);
939 return STATUS_ERROR_FMT(ERROR_DISABLED,
940 "Caller \"%s\" (PID %d, UID %d) cannot open camera \"%s\" from background",
941 clientName8.string(), clientUid, clientPid, cameraId.string());
942 }
943
Chien-Yu Chen4f3d6202016-03-22 10:50:23 -0700944 // Only use passed in clientPid to check permission. Use calling PID as the client PID that's
945 // connected to camera service directly.
Chien-Yu Chen18df60e2016-03-18 18:18:09 -0700946 originalClientPid = clientPid;
Chien-Yu Chen4f3d6202016-03-22 10:50:23 -0700947 clientPid = callingPid;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700948
Ruben Brunk6267b532015-04-30 17:44:07 -0700949 userid_t clientUserId = multiuser_get_user_id(clientUid);
Wu-cheng Lia3355432011-05-20 14:54:25 +0800950
Ruben Brunka8ca9152015-04-07 14:23:40 -0700951 // Only allow clients who are being used by the current foreground device user, unless calling
952 // from our own process.
Ruben Brunk6267b532015-04-30 17:44:07 -0700953 if (callingPid != getpid() && (mAllowedUsers.find(clientUserId) == mAllowedUsers.end())) {
954 ALOGE("CameraService::connect X (PID %d) rejected (cannot connect from "
955 "device user %d, currently allowed device users: %s)", callingPid, clientUserId,
956 toString(mAllowedUsers).string());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800957 return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
958 "Callers from device user %d are not currently allowed to connect to camera \"%s\"",
959 clientUserId, cameraId.string());
Ruben Brunk36597b22015-03-20 22:15:57 -0700960 }
961
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800962 return Status::ok();
Ruben Brunkcc776712015-02-17 20:18:47 -0800963}
964
965status_t CameraService::checkIfDeviceIsUsable(const String8& cameraId) const {
966 auto cameraState = getCameraState(cameraId);
Jayant Chowdhary12361932018-08-27 14:46:13 -0700967 int callingPid = CameraThreadState::getCallingPid();
Ruben Brunkcc776712015-02-17 20:18:47 -0800968 if (cameraState == nullptr) {
969 ALOGE("CameraService::connect X (PID %d) rejected (invalid camera ID %s)", callingPid,
970 cameraId.string());
971 return -ENODEV;
972 }
973
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800974 StatusInternal currentStatus = cameraState->getStatus();
975 if (currentStatus == StatusInternal::NOT_PRESENT) {
Ruben Brunkcc776712015-02-17 20:18:47 -0800976 ALOGE("CameraService::connect X (PID %d) rejected (camera %s is not connected)",
977 callingPid, cameraId.string());
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700978 return -ENODEV;
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800979 } else if (currentStatus == StatusInternal::ENUMERATING) {
Ruben Brunkcc776712015-02-17 20:18:47 -0800980 ALOGE("CameraService::connect X (PID %d) rejected, (camera %s is initializing)",
981 callingPid, cameraId.string());
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700982 return -EBUSY;
Igor Murashkincba2c162013-03-20 15:56:31 -0700983 }
Igor Murashkincba2c162013-03-20 15:56:31 -0700984
Ruben Brunkcc776712015-02-17 20:18:47 -0800985 return NO_ERROR;
Igor Murashkine6800ce2013-03-04 17:25:57 -0800986}
987
Ruben Brunkcc776712015-02-17 20:18:47 -0800988void CameraService::finishConnectLocked(const sp<BasicClient>& client,
989 const CameraService::DescriptorPtr& desc) {
Igor Murashkine6800ce2013-03-04 17:25:57 -0800990
Ruben Brunkcc776712015-02-17 20:18:47 -0800991 // Make a descriptor for the incoming client
992 auto clientDescriptor = CameraService::CameraClientManager::makeClientDescriptor(client, desc);
993 auto evicted = mActiveClientManager.addAndEvict(clientDescriptor);
994
995 logConnected(desc->getKey(), static_cast<int>(desc->getOwnerId()),
996 String8(client->getPackageName()));
997
998 if (evicted.size() > 0) {
999 // This should never happen - clients should already have been removed in disconnect
1000 for (auto& i : evicted) {
1001 ALOGE("%s: Invalid state: Client for camera %s was not removed in disconnect",
1002 __FUNCTION__, i->getKey().string());
1003 }
1004
1005 LOG_ALWAYS_FATAL("%s: Invalid state for CameraService, clients not evicted properly",
1006 __FUNCTION__);
1007 }
Eino-Ville Talvala24901c82015-09-04 14:15:58 -07001008
1009 // And register a death notification for the client callback. Do
1010 // this last to avoid Binder policy where a nested Binder
1011 // transaction might be pre-empted to service the client death
1012 // notification if the client process dies before linkToDeath is
1013 // invoked.
1014 sp<IBinder> remoteCallback = client->getRemote();
1015 if (remoteCallback != nullptr) {
1016 remoteCallback->linkToDeath(this);
1017 }
Ruben Brunkcc776712015-02-17 20:18:47 -08001018}
1019
1020status_t CameraService::handleEvictionsLocked(const String8& cameraId, int clientPid,
1021 apiLevel effectiveApiLevel, const sp<IBinder>& remoteCallback, const String8& packageName,
1022 /*out*/
1023 sp<BasicClient>* client,
1024 std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>* partial) {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -07001025 ATRACE_CALL();
Ruben Brunkcc776712015-02-17 20:18:47 -08001026 status_t ret = NO_ERROR;
Ruben Brunk4f9576b2015-04-10 17:26:56 -07001027 std::vector<DescriptorPtr> evictedClients;
Ruben Brunkcc776712015-02-17 20:18:47 -08001028 DescriptorPtr clientDescriptor;
1029 {
1030 if (effectiveApiLevel == API_1) {
1031 // If we are using API1, any existing client for this camera ID with the same remote
1032 // should be returned rather than evicted to allow MediaRecorder to work properly.
1033
1034 auto current = mActiveClientManager.get(cameraId);
1035 if (current != nullptr) {
1036 auto clientSp = current->getValue();
1037 if (clientSp.get() != nullptr) { // should never be needed
Ruben Brunk0bbf8b22015-04-30 14:35:42 -07001038 if (!clientSp->canCastToApiClient(effectiveApiLevel)) {
1039 ALOGW("CameraService connect called from same client, but with a different"
1040 " API level, evicting prior client...");
1041 } else if (clientSp->getRemote() == remoteCallback) {
Ruben Brunkcc776712015-02-17 20:18:47 -08001042 ALOGI("CameraService::connect X (PID %d) (second call from same"
Ruben Brunk0bbf8b22015-04-30 14:35:42 -07001043 " app binder, returning the same client)", clientPid);
Ruben Brunkcc776712015-02-17 20:18:47 -08001044 *client = clientSp;
1045 return NO_ERROR;
1046 }
1047 }
Wu-cheng Li2fd24402012-02-23 19:01:00 -08001048 }
Wu-cheng Li2fd24402012-02-23 19:01:00 -08001049 }
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +08001050
Ruben Brunkcc776712015-02-17 20:18:47 -08001051 // Get current active client PIDs
1052 std::vector<int> ownerPids(mActiveClientManager.getAllOwners());
1053 ownerPids.push_back(clientPid);
Igor Murashkine6800ce2013-03-04 17:25:57 -08001054
Emilian Peev8131a262017-02-01 12:33:43 +00001055 std::vector<int> priorityScores(ownerPids.size());
1056 std::vector<int> states(ownerPids.size());
Igor Murashkine6800ce2013-03-04 17:25:57 -08001057
Emilian Peev8131a262017-02-01 12:33:43 +00001058 // Get priority scores of all active PIDs
1059 status_t err = ProcessInfoService::getProcessStatesScoresFromPids(
1060 ownerPids.size(), &ownerPids[0], /*out*/&states[0],
1061 /*out*/&priorityScores[0]);
1062 if (err != OK) {
1063 ALOGE("%s: Priority score query failed: %d",
1064 __FUNCTION__, err);
1065 return err;
1066 }
Ruben Brunkb2119af2014-05-09 19:57:56 -07001067
Ruben Brunkcc776712015-02-17 20:18:47 -08001068 // Update all active clients' priorities
Emilian Peev8131a262017-02-01 12:33:43 +00001069 std::map<int,resource_policy::ClientPriority> pidToPriorityMap;
Ruben Brunkcc776712015-02-17 20:18:47 -08001070 for (size_t i = 0; i < ownerPids.size() - 1; i++) {
Emilian Peev8131a262017-02-01 12:33:43 +00001071 pidToPriorityMap.emplace(ownerPids[i],
1072 resource_policy::ClientPriority(priorityScores[i], states[i]));
Ruben Brunkcc776712015-02-17 20:18:47 -08001073 }
1074 mActiveClientManager.updatePriorities(pidToPriorityMap);
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001075
Ruben Brunkcc776712015-02-17 20:18:47 -08001076 // Get state for the given cameraId
1077 auto state = getCameraState(cameraId);
1078 if (state == nullptr) {
1079 ALOGE("CameraService::connect X (PID %d) rejected (no camera device with ID %s)",
1080 clientPid, cameraId.string());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001081 // Should never get here because validateConnectLocked should have errored out
Zhijun Heb10cdad2014-06-16 16:38:35 -07001082 return BAD_VALUE;
Zhijun Heb10cdad2014-06-16 16:38:35 -07001083 }
Ruben Brunkcc776712015-02-17 20:18:47 -08001084
1085 // Make descriptor for incoming client
Shuzhen Wang2db86ff2018-04-25 01:11:17 +00001086 clientDescriptor = CameraClientManager::makeClientDescriptor(cameraId,
Ruben Brunkcc776712015-02-17 20:18:47 -08001087 sp<BasicClient>{nullptr}, static_cast<int32_t>(state->getCost()),
1088 state->getConflicting(),
Emilian Peev8131a262017-02-01 12:33:43 +00001089 priorityScores[priorityScores.size() - 1],
1090 clientPid,
1091 states[states.size() - 1]);
Ruben Brunkcc776712015-02-17 20:18:47 -08001092
1093 // Find clients that would be evicted
1094 auto evicted = mActiveClientManager.wouldEvict(clientDescriptor);
1095
1096 // If the incoming client was 'evicted,' higher priority clients have the camera in the
1097 // background, so we cannot do evictions
1098 if (std::find(evicted.begin(), evicted.end(), clientDescriptor) != evicted.end()) {
1099 ALOGE("CameraService::connect X (PID %d) rejected (existing client(s) with higher"
1100 " priority).", clientPid);
1101
1102 sp<BasicClient> clientSp = clientDescriptor->getValue();
1103 String8 curTime = getFormattedCurrentTime();
1104 auto incompatibleClients =
1105 mActiveClientManager.getIncompatibleClients(clientDescriptor);
1106
1107 String8 msg = String8::format("%s : DENIED connect device %s client for package %s "
Emilian Peev8131a262017-02-01 12:33:43 +00001108 "(PID %d, score %d state %d) due to eviction policy", curTime.string(),
Ruben Brunkcc776712015-02-17 20:18:47 -08001109 cameraId.string(), packageName.string(), clientPid,
Emilian Peev8131a262017-02-01 12:33:43 +00001110 priorityScores[priorityScores.size() - 1],
1111 states[states.size() - 1]);
Ruben Brunkcc776712015-02-17 20:18:47 -08001112
1113 for (auto& i : incompatibleClients) {
1114 msg.appendFormat("\n - Blocked by existing device %s client for package %s"
Emilian Peev8131a262017-02-01 12:33:43 +00001115 "(PID %" PRId32 ", score %" PRId32 ", state %" PRId32 ")",
1116 i->getKey().string(),
1117 String8{i->getValue()->getPackageName()}.string(),
1118 i->getOwnerId(), i->getPriority().getScore(),
1119 i->getPriority().getState());
Eino-Ville Talvala022f0cb2015-05-19 16:31:16 -07001120 ALOGE(" Conflicts with: Device %s, client package %s (PID %"
Emilian Peev8131a262017-02-01 12:33:43 +00001121 PRId32 ", score %" PRId32 ", state %" PRId32 ")", i->getKey().string(),
Eino-Ville Talvala022f0cb2015-05-19 16:31:16 -07001122 String8{i->getValue()->getPackageName()}.string(), i->getOwnerId(),
Emilian Peev8131a262017-02-01 12:33:43 +00001123 i->getPriority().getScore(), i->getPriority().getState());
Ruben Brunkcc776712015-02-17 20:18:47 -08001124 }
1125
1126 // Log the client's attempt
Ruben Brunka8ca9152015-04-07 14:23:40 -07001127 Mutex::Autolock l(mLogLock);
Ruben Brunkcc776712015-02-17 20:18:47 -08001128 mEventLog.add(msg);
1129
1130 return -EBUSY;
1131 }
1132
1133 for (auto& i : evicted) {
1134 sp<BasicClient> clientSp = i->getValue();
1135 if (clientSp.get() == nullptr) {
1136 ALOGE("%s: Invalid state: Null client in active client list.", __FUNCTION__);
1137
1138 // TODO: Remove this
1139 LOG_ALWAYS_FATAL("%s: Invalid state for CameraService, null client in active list",
1140 __FUNCTION__);
1141 mActiveClientManager.remove(i);
1142 continue;
1143 }
1144
1145 ALOGE("CameraService::connect evicting conflicting client for camera ID %s",
1146 i->getKey().string());
Ruben Brunk4f9576b2015-04-10 17:26:56 -07001147 evictedClients.push_back(i);
Ruben Brunkcc776712015-02-17 20:18:47 -08001148
Ruben Brunkcc776712015-02-17 20:18:47 -08001149 // Log the clients evicted
Ruben Brunka8ca9152015-04-07 14:23:40 -07001150 logEvent(String8::format("EVICT device %s client held by package %s (PID"
Emilian Peev8131a262017-02-01 12:33:43 +00001151 " %" PRId32 ", score %" PRId32 ", state %" PRId32 ")\n - Evicted by device %s client for"
1152 " package %s (PID %d, score %" PRId32 ", state %" PRId32 ")",
Ruben Brunkcc776712015-02-17 20:18:47 -08001153 i->getKey().string(), String8{clientSp->getPackageName()}.string(),
Emilian Peev8131a262017-02-01 12:33:43 +00001154 i->getOwnerId(), i->getPriority().getScore(),
1155 i->getPriority().getState(), cameraId.string(),
Ruben Brunkcc776712015-02-17 20:18:47 -08001156 packageName.string(), clientPid,
Emilian Peev8131a262017-02-01 12:33:43 +00001157 priorityScores[priorityScores.size() - 1],
1158 states[states.size() - 1]));
Ruben Brunkcc776712015-02-17 20:18:47 -08001159
1160 // Notify the client of disconnection
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001161 clientSp->notifyError(hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED,
Ruben Brunkcc776712015-02-17 20:18:47 -08001162 CaptureResultExtras());
Zhijun Heb10cdad2014-06-16 16:38:35 -07001163 }
Ruben Brunkb2119af2014-05-09 19:57:56 -07001164 }
1165
Ruben Brunkcc776712015-02-17 20:18:47 -08001166 // Do not hold mServiceLock while disconnecting clients, but retain the condition blocking
1167 // other clients from connecting in mServiceLockWrapper if held
1168 mServiceLock.unlock();
1169
1170 // Clear caller identity temporarily so client disconnect PID checks work correctly
Jayant Chowdhary12361932018-08-27 14:46:13 -07001171 int64_t token = CameraThreadState::clearCallingIdentity();
Ruben Brunkcc776712015-02-17 20:18:47 -08001172
1173 // Destroy evicted clients
1174 for (auto& i : evictedClients) {
1175 // Disconnect is blocking, and should only have returned when HAL has cleaned up
Ruben Brunk4f9576b2015-04-10 17:26:56 -07001176 i->getValue()->disconnect(); // Clients will remove themselves from the active client list
Ruben Brunkcc776712015-02-17 20:18:47 -08001177 }
Ruben Brunkcc776712015-02-17 20:18:47 -08001178
Jayant Chowdhary12361932018-08-27 14:46:13 -07001179 CameraThreadState::restoreCallingIdentity(token);
Ruben Brunkcc776712015-02-17 20:18:47 -08001180
Ruben Brunk4f9576b2015-04-10 17:26:56 -07001181 for (const auto& i : evictedClients) {
1182 ALOGV("%s: Waiting for disconnect to complete for client for device %s (PID %" PRId32 ")",
1183 __FUNCTION__, i->getKey().string(), i->getOwnerId());
1184 ret = mActiveClientManager.waitUntilRemoved(i, DEFAULT_DISCONNECT_TIMEOUT_NS);
1185 if (ret == TIMED_OUT) {
1186 ALOGE("%s: Timed out waiting for client for device %s to disconnect, "
1187 "current clients:\n%s", __FUNCTION__, i->getKey().string(),
1188 mActiveClientManager.toString().string());
1189 return -EBUSY;
1190 }
1191 if (ret != NO_ERROR) {
1192 ALOGE("%s: Received error waiting for client for device %s to disconnect: %s (%d), "
1193 "current clients:\n%s", __FUNCTION__, i->getKey().string(), strerror(-ret),
1194 ret, mActiveClientManager.toString().string());
1195 return ret;
1196 }
1197 }
1198
1199 evictedClients.clear();
1200
Ruben Brunkcc776712015-02-17 20:18:47 -08001201 // Once clients have been disconnected, relock
1202 mServiceLock.lock();
1203
1204 // Check again if the device was unplugged or something while we weren't holding mServiceLock
1205 if ((ret = checkIfDeviceIsUsable(cameraId)) != NO_ERROR) {
1206 return ret;
Ruben Brunkb2119af2014-05-09 19:57:56 -07001207 }
1208
Ruben Brunkcc776712015-02-17 20:18:47 -08001209 *partial = clientDescriptor;
1210 return NO_ERROR;
Ruben Brunkb2119af2014-05-09 19:57:56 -07001211}
1212
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001213Status CameraService::connect(
Igor Murashkine6800ce2013-03-04 17:25:57 -08001214 const sp<ICameraClient>& cameraClient,
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -08001215 int api1CameraId,
Svetoslav Ganov280405a2015-05-12 02:19:27 +00001216 const String16& clientPackageName,
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001217 int clientUid,
Chien-Yu Chen98a668f2015-12-18 14:10:33 -08001218 int clientPid,
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001219 /*out*/
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001220 sp<ICamera>* device) {
Igor Murashkine6800ce2013-03-04 17:25:57 -08001221
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -07001222 ATRACE_CALL();
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001223 Status ret = Status::ok();
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -08001224
1225 String8 id = cameraIdIntToStr(api1CameraId);
Ruben Brunkcc776712015-02-17 20:18:47 -08001226 sp<Client> client = nullptr;
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -08001227 ret = connectHelper<ICameraClient,Client>(cameraClient, id, api1CameraId,
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001228 CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageName, clientUid, clientPid, API_1,
Shuzhen Wang06fcfb02018-07-30 18:23:31 -07001229 /*shimUpdateOnly*/ false, /*out*/client);
Igor Murashkine6800ce2013-03-04 17:25:57 -08001230
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001231 if(!ret.isOk()) {
Jayant Chowdhary12361932018-08-27 14:46:13 -07001232 logRejected(id, CameraThreadState::getCallingPid(), String8(clientPackageName),
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001233 ret.toString8());
Ruben Brunkcc776712015-02-17 20:18:47 -08001234 return ret;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001235 }
1236
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001237 *device = client;
1238 return ret;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001239}
1240
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001241Status CameraService::connectLegacy(
Zhijun Heb10cdad2014-06-16 16:38:35 -07001242 const sp<ICameraClient>& cameraClient,
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -08001243 int api1CameraId, int halVersion,
Svetoslav Ganov280405a2015-05-12 02:19:27 +00001244 const String16& clientPackageName,
Zhijun Heb10cdad2014-06-16 16:38:35 -07001245 int clientUid,
1246 /*out*/
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001247 sp<ICamera>* device) {
Zhijun Heb10cdad2014-06-16 16:38:35 -07001248
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -07001249 ATRACE_CALL();
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -08001250 String8 id = cameraIdIntToStr(api1CameraId);
Zhijun Heb10cdad2014-06-16 16:38:35 -07001251
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001252 Status ret = Status::ok();
Ruben Brunkcc776712015-02-17 20:18:47 -08001253 sp<Client> client = nullptr;
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -08001254 ret = connectHelper<ICameraClient,Client>(cameraClient, id, api1CameraId, halVersion,
Shuzhen Wang06fcfb02018-07-30 18:23:31 -07001255 clientPackageName, clientUid, USE_CALLING_PID, API_1, /*shimUpdateOnly*/ false,
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001256 /*out*/client);
Zhijun Heb10cdad2014-06-16 16:38:35 -07001257
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001258 if(!ret.isOk()) {
Jayant Chowdhary12361932018-08-27 14:46:13 -07001259 logRejected(id, CameraThreadState::getCallingPid(), String8(clientPackageName),
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001260 ret.toString8());
Ruben Brunkcc776712015-02-17 20:18:47 -08001261 return ret;
Zhijun Heb10cdad2014-06-16 16:38:35 -07001262 }
1263
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001264 *device = client;
1265 return ret;
Zhijun Heb10cdad2014-06-16 16:38:35 -07001266}
1267
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001268Status CameraService::connectDevice(
1269 const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb,
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08001270 const String16& cameraId,
Svetoslav Ganov280405a2015-05-12 02:19:27 +00001271 const String16& clientPackageName,
Ruben Brunkcc776712015-02-17 20:18:47 -08001272 int clientUid,
1273 /*out*/
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001274 sp<hardware::camera2::ICameraDeviceUser>* device) {
Ruben Brunkcc776712015-02-17 20:18:47 -08001275
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -07001276 ATRACE_CALL();
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001277 Status ret = Status::ok();
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08001278 String8 id = String8(cameraId);
Ruben Brunkcc776712015-02-17 20:18:47 -08001279 sp<CameraDeviceClient> client = nullptr;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001280 ret = connectHelper<hardware::camera2::ICameraDeviceCallbacks,CameraDeviceClient>(cameraCb, id,
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -08001281 /*api1CameraId*/-1,
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001282 CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageName,
Shuzhen Wang06fcfb02018-07-30 18:23:31 -07001283 clientUid, USE_CALLING_PID, API_2, /*shimUpdateOnly*/ false, /*out*/client);
Ruben Brunkcc776712015-02-17 20:18:47 -08001284
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001285 if(!ret.isOk()) {
Jayant Chowdhary12361932018-08-27 14:46:13 -07001286 logRejected(id, CameraThreadState::getCallingPid(), String8(clientPackageName),
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001287 ret.toString8());
Ruben Brunkcc776712015-02-17 20:18:47 -08001288 return ret;
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001289 }
1290
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001291 *device = client;
1292 return ret;
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001293}
1294
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08001295template<class CALLBACK, class CLIENT>
1296Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -08001297 int api1CameraId, int halVersion, const String16& clientPackageName, int clientUid,
Shuzhen Wang06fcfb02018-07-30 18:23:31 -07001298 int clientPid, apiLevel effectiveApiLevel, bool shimUpdateOnly,
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08001299 /*out*/sp<CLIENT>& device) {
1300 binder::Status ret = binder::Status::ok();
1301
1302 String8 clientName8(clientPackageName);
1303
1304 int originalClientPid = 0;
1305
1306 ALOGI("CameraService::connect call (PID %d \"%s\", camera ID %s) for HAL version %s and "
1307 "Camera API version %d", clientPid, clientName8.string(), cameraId.string(),
1308 (halVersion == -1) ? "default" : std::to_string(halVersion).c_str(),
1309 static_cast<int>(effectiveApiLevel));
1310
1311 sp<CLIENT> client = nullptr;
1312 {
1313 // Acquire mServiceLock and prevent other clients from connecting
1314 std::unique_ptr<AutoConditionLock> lock =
1315 AutoConditionLock::waitAndAcquire(mServiceLockWrapper, DEFAULT_CONNECT_TIMEOUT_NS);
1316
1317 if (lock == nullptr) {
1318 ALOGE("CameraService::connect (PID %d) rejected (too many other clients connecting)."
1319 , clientPid);
1320 return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE,
1321 "Cannot open camera %s for \"%s\" (PID %d): Too many other clients connecting",
1322 cameraId.string(), clientName8.string(), clientPid);
1323 }
1324
1325 // Enforce client permissions and do basic sanity checks
1326 if(!(ret = validateConnectLocked(cameraId, clientName8,
1327 /*inout*/clientUid, /*inout*/clientPid, /*out*/originalClientPid)).isOk()) {
1328 return ret;
1329 }
1330
1331 // Check the shim parameters after acquiring lock, if they have already been updated and
1332 // we were doing a shim update, return immediately
1333 if (shimUpdateOnly) {
1334 auto cameraState = getCameraState(cameraId);
1335 if (cameraState != nullptr) {
1336 if (!cameraState->getShimParams().isEmpty()) return ret;
1337 }
1338 }
1339
1340 status_t err;
1341
1342 sp<BasicClient> clientTmp = nullptr;
1343 std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>> partial;
1344 if ((err = handleEvictionsLocked(cameraId, originalClientPid, effectiveApiLevel,
1345 IInterface::asBinder(cameraCb), clientName8, /*out*/&clientTmp,
1346 /*out*/&partial)) != NO_ERROR) {
1347 switch (err) {
1348 case -ENODEV:
1349 return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
1350 "No camera device with ID \"%s\" currently available",
1351 cameraId.string());
1352 case -EBUSY:
1353 return STATUS_ERROR_FMT(ERROR_CAMERA_IN_USE,
1354 "Higher-priority client using camera, ID \"%s\" currently unavailable",
1355 cameraId.string());
1356 default:
1357 return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
1358 "Unexpected error %s (%d) opening camera \"%s\"",
1359 strerror(-err), err, cameraId.string());
1360 }
1361 }
1362
1363 if (clientTmp.get() != nullptr) {
1364 // Handle special case for API1 MediaRecorder where the existing client is returned
1365 device = static_cast<CLIENT*>(clientTmp.get());
1366 return ret;
1367 }
1368
1369 // give flashlight a chance to close devices if necessary.
1370 mFlashlight->prepareDeviceOpen(cameraId);
1371
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08001372 int facing = -1;
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001373 int deviceVersion = getDeviceVersion(cameraId, /*out*/&facing);
Eino-Ville Talvala6963d0a2017-01-31 13:00:34 -08001374 if (facing == -1) {
1375 ALOGE("%s: Unable to get camera device \"%s\" facing", __FUNCTION__, cameraId.string());
1376 return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
1377 "Unable to get camera device \"%s\" facing", cameraId.string());
1378 }
1379
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08001380 sp<BasicClient> tmp = nullptr;
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -08001381 if(!(ret = makeClient(this, cameraCb, clientPackageName,
1382 cameraId, api1CameraId, facing,
Shuzhen Wang06fcfb02018-07-30 18:23:31 -07001383 clientPid, clientUid, getpid(),
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -08001384 halVersion, deviceVersion, effectiveApiLevel,
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08001385 /*out*/&tmp)).isOk()) {
1386 return ret;
1387 }
1388 client = static_cast<CLIENT*>(tmp.get());
1389
1390 LOG_ALWAYS_FATAL_IF(client.get() == nullptr, "%s: CameraService in invalid state",
1391 __FUNCTION__);
1392
Emilian Peevbd8c5032018-02-14 23:05:40 +00001393 err = client->initialize(mCameraProviderManager, mMonitorTags);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001394 if (err != OK) {
1395 ALOGE("%s: Could not initialize client from HAL.", __FUNCTION__);
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08001396 // Errors could be from the HAL module open call or from AppOpsManager
1397 switch(err) {
1398 case BAD_VALUE:
1399 return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
1400 "Illegal argument to HAL module for camera \"%s\"", cameraId.string());
1401 case -EBUSY:
1402 return STATUS_ERROR_FMT(ERROR_CAMERA_IN_USE,
1403 "Camera \"%s\" is already open", cameraId.string());
1404 case -EUSERS:
1405 return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE,
1406 "Too many cameras already open, cannot open camera \"%s\"",
1407 cameraId.string());
1408 case PERMISSION_DENIED:
1409 return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
1410 "No permission to open camera \"%s\"", cameraId.string());
1411 case -EACCES:
1412 return STATUS_ERROR_FMT(ERROR_DISABLED,
1413 "Camera \"%s\" disabled by policy", cameraId.string());
1414 case -ENODEV:
1415 default:
1416 return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
1417 "Failed to initialize camera \"%s\": %s (%d)", cameraId.string(),
1418 strerror(-err), err);
1419 }
1420 }
1421
1422 // Update shim paremeters for legacy clients
1423 if (effectiveApiLevel == API_1) {
1424 // Assume we have always received a Client subclass for API1
1425 sp<Client> shimClient = reinterpret_cast<Client*>(client.get());
1426 String8 rawParams = shimClient->getParameters();
1427 CameraParameters params(rawParams);
1428
1429 auto cameraState = getCameraState(cameraId);
1430 if (cameraState != nullptr) {
1431 cameraState->setShimParams(params);
1432 } else {
1433 ALOGE("%s: Cannot update shim parameters for camera %s, no such device exists.",
1434 __FUNCTION__, cameraId.string());
1435 }
1436 }
1437
1438 if (shimUpdateOnly) {
1439 // If only updating legacy shim parameters, immediately disconnect client
1440 mServiceLock.unlock();
1441 client->disconnect();
1442 mServiceLock.lock();
1443 } else {
1444 // Otherwise, add client to active clients list
1445 finishConnectLocked(client, partial);
1446 }
1447 } // lock is destroyed, allow further connect calls
1448
1449 // Important: release the mutex here so the client can call back into the service from its
1450 // destructor (can be at the end of the call)
1451 device = client;
1452 return ret;
1453}
1454
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001455Status CameraService::setTorchMode(const String16& cameraId, bool enabled,
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001456 const sp<IBinder>& clientBinder) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001457 Mutex::Autolock lock(mServiceLock);
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -07001458
1459 ATRACE_CALL();
Ruben Brunk99e69712015-05-26 17:25:07 -07001460 if (enabled && clientBinder == nullptr) {
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001461 ALOGE("%s: torch client binder is NULL", __FUNCTION__);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001462 return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT,
1463 "Torch client Binder is null");
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001464 }
1465
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001466 String8 id = String8(cameraId.string());
Jayant Chowdhary12361932018-08-27 14:46:13 -07001467 int uid = CameraThreadState::getCallingUid();
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001468
1469 // verify id is valid.
Ruben Brunkcc776712015-02-17 20:18:47 -08001470 auto state = getCameraState(id);
1471 if (state == nullptr) {
Chien-Yu Chenf6463fc2015-04-07 15:11:31 -07001472 ALOGE("%s: camera id is invalid %s", __FUNCTION__, id.string());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001473 return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
1474 "Camera ID \"%s\" is a not valid camera ID", id.string());
Ruben Brunkcc776712015-02-17 20:18:47 -08001475 }
1476
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08001477 StatusInternal cameraStatus = state->getStatus();
1478 if (cameraStatus != StatusInternal::PRESENT &&
Yin-Chia Yeh52778d42016-12-22 18:20:43 -08001479 cameraStatus != StatusInternal::NOT_AVAILABLE) {
1480 ALOGE("%s: camera id is invalid %s, status %d", __FUNCTION__, id.string(), (int)cameraStatus);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001481 return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
1482 "Camera ID \"%s\" is a not valid camera ID", id.string());
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001483 }
1484
1485 {
1486 Mutex::Autolock al(mTorchStatusMutex);
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08001487 TorchModeStatus status;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001488 status_t err = getTorchStatusLocked(id, &status);
1489 if (err != OK) {
1490 if (err == NAME_NOT_FOUND) {
1491 return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
1492 "Camera \"%s\" does not have a flash unit", id.string());
1493 }
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001494 ALOGE("%s: getting current torch status failed for camera %s",
1495 __FUNCTION__, id.string());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001496 return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
1497 "Error updating torch status for camera \"%s\": %s (%d)", id.string(),
1498 strerror(-err), err);
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001499 }
1500
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08001501 if (status == TorchModeStatus::NOT_AVAILABLE) {
Yin-Chia Yeh52778d42016-12-22 18:20:43 -08001502 if (cameraStatus == StatusInternal::NOT_AVAILABLE) {
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001503 ALOGE("%s: torch mode of camera %s is not available because "
1504 "camera is in use", __FUNCTION__, id.string());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001505 return STATUS_ERROR_FMT(ERROR_CAMERA_IN_USE,
1506 "Torch for camera \"%s\" is not available due to an existing camera user",
1507 id.string());
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001508 } else {
1509 ALOGE("%s: torch mode of camera %s is not available due to "
1510 "insufficient resources", __FUNCTION__, id.string());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001511 return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE,
1512 "Torch for camera \"%s\" is not available due to insufficient resources",
1513 id.string());
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001514 }
1515 }
1516 }
1517
Ruben Brunk99e69712015-05-26 17:25:07 -07001518 {
1519 // Update UID map - this is used in the torch status changed callbacks, so must be done
1520 // before setTorchMode
Chien-Yu Chenfe751be2015-09-01 14:16:44 -07001521 Mutex::Autolock al(mTorchUidMapMutex);
Ruben Brunk99e69712015-05-26 17:25:07 -07001522 if (mTorchUidMap.find(id) == mTorchUidMap.end()) {
1523 mTorchUidMap[id].first = uid;
1524 mTorchUidMap[id].second = uid;
1525 } else {
1526 // Set the pending UID
1527 mTorchUidMap[id].first = uid;
1528 }
1529 }
1530
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001531 status_t err = mFlashlight->setTorchMode(id, enabled);
Ruben Brunk99e69712015-05-26 17:25:07 -07001532
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001533 if (err != OK) {
1534 int32_t errorCode;
1535 String8 msg;
1536 switch (err) {
1537 case -ENOSYS:
1538 msg = String8::format("Camera \"%s\" has no flashlight",
1539 id.string());
1540 errorCode = ERROR_ILLEGAL_ARGUMENT;
1541 break;
1542 default:
1543 msg = String8::format(
1544 "Setting torch mode of camera \"%s\" to %d failed: %s (%d)",
1545 id.string(), enabled, strerror(-err), err);
1546 errorCode = ERROR_INVALID_OPERATION;
1547 }
1548 ALOGE("%s: %s", __FUNCTION__, msg.string());
1549 return STATUS_ERROR(errorCode, msg.string());
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001550 }
1551
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001552 {
1553 // update the link to client's death
1554 Mutex::Autolock al(mTorchClientMapMutex);
1555 ssize_t index = mTorchClientMap.indexOfKey(id);
1556 if (enabled) {
1557 if (index == NAME_NOT_FOUND) {
1558 mTorchClientMap.add(id, clientBinder);
1559 } else {
Ruben Brunk99e69712015-05-26 17:25:07 -07001560 mTorchClientMap.valueAt(index)->unlinkToDeath(this);
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001561 mTorchClientMap.replaceValueAt(index, clientBinder);
1562 }
1563 clientBinder->linkToDeath(this);
1564 } else if (index != NAME_NOT_FOUND) {
Ruben Brunk99e69712015-05-26 17:25:07 -07001565 mTorchClientMap.valueAt(index)->unlinkToDeath(this);
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001566 }
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001567 }
1568
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001569 return Status::ok();
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001570}
1571
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001572Status CameraService::notifySystemEvent(int32_t eventId,
1573 const std::vector<int32_t>& args) {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -07001574 ATRACE_CALL();
1575
Ruben Brunk36597b22015-03-20 22:15:57 -07001576 switch(eventId) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001577 case ICameraService::EVENT_USER_SWITCHED: {
Eino-Ville Talvala8abec3f2018-03-20 11:07:00 -07001578 // Try to register for UID policy updates, in case we're recovering
1579 // from a system server crash
1580 mUidPolicy->registerSelf();
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001581 doUserSwitch(/*newUserIds*/ args);
Ruben Brunk36597b22015-03-20 22:15:57 -07001582 break;
1583 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001584 case ICameraService::EVENT_NONE:
Ruben Brunk36597b22015-03-20 22:15:57 -07001585 default: {
1586 ALOGW("%s: Received invalid system event from system_server: %d", __FUNCTION__,
1587 eventId);
1588 break;
1589 }
1590 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001591 return Status::ok();
Ruben Brunk36597b22015-03-20 22:15:57 -07001592}
1593
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08001594Status CameraService::addListener(const sp<ICameraServiceListener>& listener,
1595 /*out*/
1596 std::vector<hardware::CameraStatus> *cameraStatuses) {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -07001597 ATRACE_CALL();
1598
Igor Murashkinbfc99152013-02-27 12:55:20 -08001599 ALOGV("%s: Add listener %p", __FUNCTION__, listener.get());
Igor Murashkin634a5152013-02-20 17:15:11 -08001600
Ruben Brunk3450ba72015-06-16 11:00:37 -07001601 if (listener == nullptr) {
Igor Murashkinbd3e2e02014-03-17 13:01:41 -07001602 ALOGE("%s: Listener must not be null", __FUNCTION__);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001603 return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Null listener given to addListener");
Igor Murashkinbd3e2e02014-03-17 13:01:41 -07001604 }
1605
Igor Murashkinbfc99152013-02-27 12:55:20 -08001606 Mutex::Autolock lock(mServiceLock);
1607
Ruben Brunkcc776712015-02-17 20:18:47 -08001608 {
1609 Mutex::Autolock lock(mStatusListenerLock);
1610 for (auto& it : mListenerList) {
1611 if (IInterface::asBinder(it) == IInterface::asBinder(listener)) {
1612 ALOGW("%s: Tried to add listener %p which was already subscribed",
1613 __FUNCTION__, listener.get());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001614 return STATUS_ERROR(ERROR_ALREADY_EXISTS, "Listener already registered");
Ruben Brunkcc776712015-02-17 20:18:47 -08001615 }
Igor Murashkinbfc99152013-02-27 12:55:20 -08001616 }
Ruben Brunkcc776712015-02-17 20:18:47 -08001617
1618 mListenerList.push_back(listener);
Igor Murashkinbfc99152013-02-27 12:55:20 -08001619 }
1620
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08001621 /* Collect current devices and status */
Igor Murashkincba2c162013-03-20 15:56:31 -07001622 {
Ruben Brunkcc776712015-02-17 20:18:47 -08001623 Mutex::Autolock lock(mCameraStatesLock);
1624 for (auto& i : mCameraStates) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08001625 cameraStatuses->emplace_back(i.first, mapToInterface(i.second->getStatus()));
Igor Murashkincba2c162013-03-20 15:56:31 -07001626 }
1627 }
1628
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08001629 /*
1630 * Immediately signal current torch status to this listener only
1631 * This may be a subset of all the devices, so don't include it in the response directly
1632 */
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001633 {
1634 Mutex::Autolock al(mTorchStatusMutex);
1635 for (size_t i = 0; i < mTorchStatusMap.size(); i++ ) {
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001636 String16 id = String16(mTorchStatusMap.keyAt(i).string());
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08001637 listener->onTorchStatusChanged(mapToInterface(mTorchStatusMap.valueAt(i)), id);
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001638 }
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001639 }
1640
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001641 return Status::ok();
Igor Murashkinbfc99152013-02-27 12:55:20 -08001642}
Ruben Brunkcc776712015-02-17 20:18:47 -08001643
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001644Status CameraService::removeListener(const sp<ICameraServiceListener>& listener) {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -07001645 ATRACE_CALL();
1646
Igor Murashkinbfc99152013-02-27 12:55:20 -08001647 ALOGV("%s: Remove listener %p", __FUNCTION__, listener.get());
1648
Igor Murashkinbd3e2e02014-03-17 13:01:41 -07001649 if (listener == 0) {
1650 ALOGE("%s: Listener must not be null", __FUNCTION__);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001651 return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Null listener given to removeListener");
Igor Murashkinbd3e2e02014-03-17 13:01:41 -07001652 }
1653
Igor Murashkinbfc99152013-02-27 12:55:20 -08001654 Mutex::Autolock lock(mServiceLock);
1655
Ruben Brunkcc776712015-02-17 20:18:47 -08001656 {
1657 Mutex::Autolock lock(mStatusListenerLock);
1658 for (auto it = mListenerList.begin(); it != mListenerList.end(); it++) {
1659 if (IInterface::asBinder(*it) == IInterface::asBinder(listener)) {
1660 mListenerList.erase(it);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001661 return Status::ok();
Ruben Brunkcc776712015-02-17 20:18:47 -08001662 }
Igor Murashkinbfc99152013-02-27 12:55:20 -08001663 }
1664 }
1665
1666 ALOGW("%s: Tried to remove a listener %p which was not subscribed",
1667 __FUNCTION__, listener.get());
1668
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001669 return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Unregistered listener given to removeListener");
Igor Murashkin634a5152013-02-20 17:15:11 -08001670}
1671
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001672Status CameraService::getLegacyParameters(int cameraId, /*out*/String16* parameters) {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -07001673
1674 ATRACE_CALL();
Igor Murashkin65d14b92014-06-17 12:03:20 -07001675 ALOGV("%s: for camera ID = %d", __FUNCTION__, cameraId);
1676
1677 if (parameters == NULL) {
1678 ALOGE("%s: parameters must not be null", __FUNCTION__);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001679 return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Parameters must not be null");
Igor Murashkin65d14b92014-06-17 12:03:20 -07001680 }
1681
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001682 Status ret = Status::ok();
Igor Murashkin65d14b92014-06-17 12:03:20 -07001683
1684 CameraParameters shimParams;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001685 if (!(ret = getLegacyParametersLazy(cameraId, /*out*/&shimParams)).isOk()) {
Igor Murashkin65d14b92014-06-17 12:03:20 -07001686 // Error logged by caller
1687 return ret;
1688 }
1689
1690 String8 shimParamsString8 = shimParams.flatten();
1691 String16 shimParamsString16 = String16(shimParamsString8);
1692
1693 *parameters = shimParamsString16;
1694
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001695 return ret;
Igor Murashkin65d14b92014-06-17 12:03:20 -07001696}
1697
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08001698Status CameraService::supportsCameraApi(const String16& cameraId, int apiVersion,
1699 /*out*/ bool *isSupported) {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -07001700 ATRACE_CALL();
1701
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001702 const String8 id = String8(cameraId);
1703
1704 ALOGV("%s: for camera ID = %s", __FUNCTION__, id.string());
Igor Murashkin65d14b92014-06-17 12:03:20 -07001705
1706 switch (apiVersion) {
1707 case API_VERSION_1:
1708 case API_VERSION_2:
1709 break;
1710 default:
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001711 String8 msg = String8::format("Unknown API version %d", apiVersion);
1712 ALOGE("%s: %s", __FUNCTION__, msg.string());
1713 return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.string());
Igor Murashkin65d14b92014-06-17 12:03:20 -07001714 }
1715
Emilian Peev28ad2ea2017-02-07 16:14:32 +00001716 int deviceVersion = getDeviceVersion(id);
Shuzhen Wangf9d2c022018-08-21 12:07:35 -07001717 switch (deviceVersion) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001718 case CAMERA_DEVICE_API_VERSION_1_0:
1719 case CAMERA_DEVICE_API_VERSION_3_0:
1720 case CAMERA_DEVICE_API_VERSION_3_1:
1721 if (apiVersion == API_VERSION_2) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001722 ALOGV("%s: Camera id %s uses HAL version %d <3.2, doesn't support api2 without shim",
1723 __FUNCTION__, id.string(), deviceVersion);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001724 *isSupported = false;
1725 } else { // if (apiVersion == API_VERSION_1) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001726 ALOGV("%s: Camera id %s uses older HAL before 3.2, but api1 is always supported",
1727 __FUNCTION__, id.string());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001728 *isSupported = true;
1729 }
1730 break;
1731 case CAMERA_DEVICE_API_VERSION_3_2:
1732 case CAMERA_DEVICE_API_VERSION_3_3:
Zhijun He4afbdec2016-05-04 15:42:51 -07001733 case CAMERA_DEVICE_API_VERSION_3_4:
Shuzhen Wangf9d2c022018-08-21 12:07:35 -07001734 case CAMERA_DEVICE_API_VERSION_3_5:
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001735 ALOGV("%s: Camera id %s uses HAL3.2 or newer, supports api1/api2 directly",
1736 __FUNCTION__, id.string());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001737 *isSupported = true;
1738 break;
1739 case -1: {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001740 String8 msg = String8::format("Unknown camera ID %s", id.string());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001741 ALOGE("%s: %s", __FUNCTION__, msg.string());
1742 return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.string());
Igor Murashkin65d14b92014-06-17 12:03:20 -07001743 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001744 default: {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001745 String8 msg = String8::format("Unknown device version %x for device %s",
1746 deviceVersion, id.string());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001747 ALOGE("%s: %s", __FUNCTION__, msg.string());
1748 return STATUS_ERROR(ERROR_INVALID_OPERATION, msg.string());
1749 }
Igor Murashkin65d14b92014-06-17 12:03:20 -07001750 }
1751
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001752 return Status::ok();
Igor Murashkin65d14b92014-06-17 12:03:20 -07001753}
1754
Shuzhen Wangf9d2c022018-08-21 12:07:35 -07001755Status CameraService::isHiddenPhysicalCamera(const String16& cameraId,
1756 /*out*/ bool *isSupported) {
1757 ATRACE_CALL();
1758
1759 const String8 id = String8(cameraId);
1760
1761 ALOGV("%s: for camera ID = %s", __FUNCTION__, id.string());
1762 *isSupported = mCameraProviderManager->isHiddenPhysicalCamera(id.string());
1763
1764 return Status::ok();
1765}
1766
Ruben Brunkcc776712015-02-17 20:18:47 -08001767void CameraService::removeByClient(const BasicClient* client) {
Igor Murashkinecf17e82012-10-02 16:05:11 -07001768 Mutex::Autolock lock(mServiceLock);
Ruben Brunkcc776712015-02-17 20:18:47 -08001769 for (auto& i : mActiveClientManager.getAll()) {
1770 auto clientSp = i->getValue();
1771 if (clientSp.get() == client) {
1772 mActiveClientManager.remove(i);
Igor Murashkin634a5152013-02-20 17:15:11 -08001773 }
Igor Murashkinecf17e82012-10-02 16:05:11 -07001774 }
Igor Murashkin634a5152013-02-20 17:15:11 -08001775}
1776
Ruben Brunkcc776712015-02-17 20:18:47 -08001777bool CameraService::evictClientIdByRemote(const wp<IBinder>& remote) {
Ruben Brunkcc776712015-02-17 20:18:47 -08001778 bool ret = false;
1779 {
1780 // Acquire mServiceLock and prevent other clients from connecting
1781 std::unique_ptr<AutoConditionLock> lock =
1782 AutoConditionLock::waitAndAcquire(mServiceLockWrapper);
Igor Murashkin634a5152013-02-20 17:15:11 -08001783
Igor Murashkin634a5152013-02-20 17:15:11 -08001784
Ruben Brunkcc776712015-02-17 20:18:47 -08001785 std::vector<sp<BasicClient>> evicted;
1786 for (auto& i : mActiveClientManager.getAll()) {
1787 auto clientSp = i->getValue();
1788 if (clientSp.get() == nullptr) {
1789 ALOGE("%s: Dead client still in mActiveClientManager.", __FUNCTION__);
1790 mActiveClientManager.remove(i);
1791 continue;
1792 }
Yin-Chia Yehdbfcb382018-02-16 11:17:36 -08001793 if (remote == clientSp->getRemote()) {
Ruben Brunkcc776712015-02-17 20:18:47 -08001794 mActiveClientManager.remove(i);
1795 evicted.push_back(clientSp);
Igor Murashkin634a5152013-02-20 17:15:11 -08001796
Ruben Brunkcc776712015-02-17 20:18:47 -08001797 // Notify the client of disconnection
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001798 clientSp->notifyError(
1799 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED,
Ruben Brunkcc776712015-02-17 20:18:47 -08001800 CaptureResultExtras());
Igor Murashkin634a5152013-02-20 17:15:11 -08001801 }
1802 }
1803
Ruben Brunkcc776712015-02-17 20:18:47 -08001804 // Do not hold mServiceLock while disconnecting clients, but retain the condition blocking
1805 // other clients from connecting in mServiceLockWrapper if held
1806 mServiceLock.unlock();
1807
Ruben Brunk36597b22015-03-20 22:15:57 -07001808 // Do not clear caller identity, remote caller should be client proccess
1809
Ruben Brunkcc776712015-02-17 20:18:47 -08001810 for (auto& i : evicted) {
1811 if (i.get() != nullptr) {
1812 i->disconnect();
1813 ret = true;
1814 }
Igor Murashkin634a5152013-02-20 17:15:11 -08001815 }
1816
Ruben Brunkcc776712015-02-17 20:18:47 -08001817 // Reacquire mServiceLock
1818 mServiceLock.lock();
Igor Murashkin634a5152013-02-20 17:15:11 -08001819
Ruben Brunkcc776712015-02-17 20:18:47 -08001820 } // lock is destroyed, allow further connect calls
1821
1822 return ret;
Igor Murashkinecf17e82012-10-02 16:05:11 -07001823}
1824
Ruben Brunkcc776712015-02-17 20:18:47 -08001825std::shared_ptr<CameraService::CameraState> CameraService::getCameraState(
1826 const String8& cameraId) const {
1827 std::shared_ptr<CameraState> state;
1828 {
1829 Mutex::Autolock lock(mCameraStatesLock);
1830 auto iter = mCameraStates.find(cameraId);
1831 if (iter != mCameraStates.end()) {
1832 state = iter->second;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001833 }
1834 }
Ruben Brunkcc776712015-02-17 20:18:47 -08001835 return state;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001836}
1837
Ruben Brunkcc776712015-02-17 20:18:47 -08001838sp<CameraService::BasicClient> CameraService::removeClientLocked(const String8& cameraId) {
1839 // Remove from active clients list
1840 auto clientDescriptorPtr = mActiveClientManager.remove(cameraId);
1841 if (clientDescriptorPtr == nullptr) {
1842 ALOGW("%s: Could not evict client, no client for camera ID %s", __FUNCTION__,
1843 cameraId.string());
1844 return sp<BasicClient>{nullptr};
1845 }
1846
1847 return clientDescriptorPtr->getValue();
Keun young Parkd8973a72012-03-28 14:13:09 -07001848}
1849
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001850void CameraService::doUserSwitch(const std::vector<int32_t>& newUserIds) {
Ruben Brunk36597b22015-03-20 22:15:57 -07001851 // Acquire mServiceLock and prevent other clients from connecting
1852 std::unique_ptr<AutoConditionLock> lock =
1853 AutoConditionLock::waitAndAcquire(mServiceLockWrapper);
1854
Ruben Brunk6267b532015-04-30 17:44:07 -07001855 std::set<userid_t> newAllowedUsers;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001856 for (size_t i = 0; i < newUserIds.size(); i++) {
1857 if (newUserIds[i] < 0) {
Ruben Brunk6267b532015-04-30 17:44:07 -07001858 ALOGE("%s: Bad user ID %d given during user switch, ignoring.",
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001859 __FUNCTION__, newUserIds[i]);
Ruben Brunk6267b532015-04-30 17:44:07 -07001860 return;
1861 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001862 newAllowedUsers.insert(static_cast<userid_t>(newUserIds[i]));
Ruben Brunk36597b22015-03-20 22:15:57 -07001863 }
1864
Ruben Brunka8ca9152015-04-07 14:23:40 -07001865
Ruben Brunk6267b532015-04-30 17:44:07 -07001866 if (newAllowedUsers == mAllowedUsers) {
1867 ALOGW("%s: Received notification of user switch with no updated user IDs.", __FUNCTION__);
1868 return;
1869 }
1870
1871 logUserSwitch(mAllowedUsers, newAllowedUsers);
1872
1873 mAllowedUsers = std::move(newAllowedUsers);
Ruben Brunk36597b22015-03-20 22:15:57 -07001874
1875 // Current user has switched, evict all current clients.
1876 std::vector<sp<BasicClient>> evicted;
1877 for (auto& i : mActiveClientManager.getAll()) {
1878 auto clientSp = i->getValue();
1879
1880 if (clientSp.get() == nullptr) {
1881 ALOGE("%s: Dead client still in mActiveClientManager.", __FUNCTION__);
1882 continue;
1883 }
1884
Ruben Brunk6267b532015-04-30 17:44:07 -07001885 // Don't evict clients that are still allowed.
1886 uid_t clientUid = clientSp->getClientUid();
1887 userid_t clientUserId = multiuser_get_user_id(clientUid);
1888 if (mAllowedUsers.find(clientUserId) != mAllowedUsers.end()) {
1889 continue;
1890 }
1891
Ruben Brunk36597b22015-03-20 22:15:57 -07001892 evicted.push_back(clientSp);
1893
1894 String8 curTime = getFormattedCurrentTime();
1895
1896 ALOGE("Evicting conflicting client for camera ID %s due to user change",
1897 i->getKey().string());
Ruben Brunka8ca9152015-04-07 14:23:40 -07001898
Ruben Brunk36597b22015-03-20 22:15:57 -07001899 // Log the clients evicted
Ruben Brunka8ca9152015-04-07 14:23:40 -07001900 logEvent(String8::format("EVICT device %s client held by package %s (PID %"
Emilian Peev8131a262017-02-01 12:33:43 +00001901 PRId32 ", score %" PRId32 ", state %" PRId32 ")\n - Evicted due"
1902 " to user switch.", i->getKey().string(),
1903 String8{clientSp->getPackageName()}.string(),
1904 i->getOwnerId(), i->getPriority().getScore(),
1905 i->getPriority().getState()));
Ruben Brunk36597b22015-03-20 22:15:57 -07001906
1907 }
1908
1909 // Do not hold mServiceLock while disconnecting clients, but retain the condition
1910 // blocking other clients from connecting in mServiceLockWrapper if held.
1911 mServiceLock.unlock();
1912
1913 // Clear caller identity temporarily so client disconnect PID checks work correctly
Jayant Chowdhary12361932018-08-27 14:46:13 -07001914 int64_t token = CameraThreadState::clearCallingIdentity();
Ruben Brunk36597b22015-03-20 22:15:57 -07001915
1916 for (auto& i : evicted) {
1917 i->disconnect();
1918 }
1919
Jayant Chowdhary12361932018-08-27 14:46:13 -07001920 CameraThreadState::restoreCallingIdentity(token);
Ruben Brunk36597b22015-03-20 22:15:57 -07001921
1922 // Reacquire mServiceLock
1923 mServiceLock.lock();
1924}
Ruben Brunkcc776712015-02-17 20:18:47 -08001925
Ruben Brunka8ca9152015-04-07 14:23:40 -07001926void CameraService::logEvent(const char* event) {
Ruben Brunkcc776712015-02-17 20:18:47 -08001927 String8 curTime = getFormattedCurrentTime();
Ruben Brunka8ca9152015-04-07 14:23:40 -07001928 Mutex::Autolock l(mLogLock);
1929 mEventLog.add(String8::format("%s : %s", curTime.string(), event));
Mathias Agopian65ab4712010-07-14 17:59:35 -07001930}
1931
Ruben Brunka8ca9152015-04-07 14:23:40 -07001932void CameraService::logDisconnected(const char* cameraId, int clientPid,
Svetoslav Ganov280405a2015-05-12 02:19:27 +00001933 const char* clientPackage) {
Ruben Brunkcc776712015-02-17 20:18:47 -08001934 // Log the clients evicted
Ruben Brunka8ca9152015-04-07 14:23:40 -07001935 logEvent(String8::format("DISCONNECT device %s client for package %s (PID %d)", cameraId,
Svetoslav Ganov280405a2015-05-12 02:19:27 +00001936 clientPackage, clientPid));
Ruben Brunka8ca9152015-04-07 14:23:40 -07001937}
1938
1939void CameraService::logConnected(const char* cameraId, int clientPid,
Svetoslav Ganov280405a2015-05-12 02:19:27 +00001940 const char* clientPackage) {
Ruben Brunka8ca9152015-04-07 14:23:40 -07001941 // Log the clients evicted
1942 logEvent(String8::format("CONNECT device %s client for package %s (PID %d)", cameraId,
Svetoslav Ganov280405a2015-05-12 02:19:27 +00001943 clientPackage, clientPid));
Ruben Brunka8ca9152015-04-07 14:23:40 -07001944}
1945
1946void CameraService::logRejected(const char* cameraId, int clientPid,
Svetoslav Ganov280405a2015-05-12 02:19:27 +00001947 const char* clientPackage, const char* reason) {
Ruben Brunka8ca9152015-04-07 14:23:40 -07001948 // Log the client rejected
1949 logEvent(String8::format("REJECT device %s client for package %s (PID %d), reason: (%s)",
Svetoslav Ganov280405a2015-05-12 02:19:27 +00001950 cameraId, clientPackage, clientPid, reason));
Ruben Brunka8ca9152015-04-07 14:23:40 -07001951}
1952
Ruben Brunk6267b532015-04-30 17:44:07 -07001953void CameraService::logUserSwitch(const std::set<userid_t>& oldUserIds,
1954 const std::set<userid_t>& newUserIds) {
1955 String8 newUsers = toString(newUserIds);
1956 String8 oldUsers = toString(oldUserIds);
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -08001957 if (oldUsers.size() == 0) {
1958 oldUsers = "<None>";
1959 }
Ruben Brunka8ca9152015-04-07 14:23:40 -07001960 // Log the new and old users
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -08001961 logEvent(String8::format("USER_SWITCH previous allowed user IDs: %s, current allowed user IDs: %s",
Ruben Brunk6267b532015-04-30 17:44:07 -07001962 oldUsers.string(), newUsers.string()));
Ruben Brunka8ca9152015-04-07 14:23:40 -07001963}
1964
1965void CameraService::logDeviceRemoved(const char* cameraId, const char* reason) {
1966 // Log the device removal
1967 logEvent(String8::format("REMOVE device %s, reason: (%s)", cameraId, reason));
1968}
1969
1970void CameraService::logDeviceAdded(const char* cameraId, const char* reason) {
1971 // Log the device removal
1972 logEvent(String8::format("ADD device %s, reason: (%s)", cameraId, reason));
1973}
1974
1975void CameraService::logClientDied(int clientPid, const char* reason) {
1976 // Log the device removal
1977 logEvent(String8::format("DIED client(s) with PID %d, reason: (%s)", clientPid, reason));
Igor Murashkinecf17e82012-10-02 16:05:11 -07001978}
1979
Eino-Ville Talvala1527f072015-04-07 15:55:31 -07001980void CameraService::logServiceError(const char* msg, int errorCode) {
1981 String8 curTime = getFormattedCurrentTime();
Eino-Ville Talvalad309fb92015-11-25 12:12:45 -08001982 logEvent(String8::format("SERVICE ERROR: %s : %d (%s)", msg, errorCode, strerror(-errorCode)));
Eino-Ville Talvala1527f072015-04-07 15:55:31 -07001983}
1984
Ruben Brunk36597b22015-03-20 22:15:57 -07001985status_t CameraService::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
1986 uint32_t flags) {
1987
Jayant Chowdhary12361932018-08-27 14:46:13 -07001988 const int pid = CameraThreadState::getCallingPid();
Ruben Brunk36597b22015-03-20 22:15:57 -07001989 const int selfPid = getpid();
1990
Mathias Agopian65ab4712010-07-14 17:59:35 -07001991 // Permission checks
1992 switch (code) {
Svet Ganova453d0d2018-01-11 15:37:58 -08001993 case SHELL_COMMAND_TRANSACTION: {
1994 int in = data.readFileDescriptor();
1995 int out = data.readFileDescriptor();
1996 int err = data.readFileDescriptor();
1997 int argc = data.readInt32();
1998 Vector<String16> args;
1999 for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
2000 args.add(data.readString16());
2001 }
2002 sp<IBinder> unusedCallback;
2003 sp<IResultReceiver> resultReceiver;
2004 status_t status;
2005 if ((status = data.readNullableStrongBinder(&unusedCallback)) != NO_ERROR) {
2006 return status;
2007 }
2008 if ((status = data.readNullableStrongBinder(&resultReceiver)) != NO_ERROR) {
2009 return status;
2010 }
2011 status = shellCommand(in, out, err, args);
2012 if (resultReceiver != nullptr) {
2013 resultReceiver->send(status);
2014 }
2015 return NO_ERROR;
2016 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08002017 case BnCameraService::NOTIFYSYSTEMEVENT: {
Ruben Brunk36597b22015-03-20 22:15:57 -07002018 if (pid != selfPid) {
2019 // Ensure we're being called by system_server, or similar process with
2020 // permissions to notify the camera service about system events
2021 if (!checkCallingPermission(
2022 String16("android.permission.CAMERA_SEND_SYSTEM_EVENTS"))) {
Jayant Chowdhary12361932018-08-27 14:46:13 -07002023 const int uid = CameraThreadState::getCallingUid();
Ruben Brunk36597b22015-03-20 22:15:57 -07002024 ALOGE("Permission Denial: cannot send updates to camera service about system"
2025 " events from pid=%d, uid=%d", pid, uid);
2026 return PERMISSION_DENIED;
2027 }
2028 }
2029 break;
2030 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07002031 }
2032
2033 return BnCameraService::onTransact(code, data, reply, flags);
2034}
2035
Mathias Agopian65ab4712010-07-14 17:59:35 -07002036// We share the media players for shutter and recording sound for all clients.
2037// A reference count is kept to determine when we will actually release the
2038// media players.
2039
Jaekyun Seokef498052018-03-23 13:09:44 +09002040sp<MediaPlayer> CameraService::newMediaPlayer(const char *file) {
2041 sp<MediaPlayer> mp = new MediaPlayer();
2042 status_t error;
2043 if ((error = mp->setDataSource(NULL /* httpService */, file, NULL)) == NO_ERROR) {
Eino-Ville Talvala60a78ac2012-01-05 15:34:53 -08002044 mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE);
Jaekyun Seokef498052018-03-23 13:09:44 +09002045 error = mp->prepare();
2046 }
2047 if (error != NO_ERROR) {
Steve Block29357bc2012-01-06 19:20:56 +00002048 ALOGE("Failed to load CameraService sounds: %s", file);
Jaekyun Seokef498052018-03-23 13:09:44 +09002049 mp->disconnect();
2050 mp.clear();
Jaekyun Seok59a8ef02018-01-15 14:49:05 +09002051 return nullptr;
Mathias Agopian65ab4712010-07-14 17:59:35 -07002052 }
2053 return mp;
2054}
2055
2056void CameraService::loadSound() {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -07002057 ATRACE_CALL();
2058
Mathias Agopian65ab4712010-07-14 17:59:35 -07002059 Mutex::Autolock lock(mSoundLock);
2060 LOG1("CameraService::loadSound ref=%d", mSoundRef);
2061 if (mSoundRef++) return;
2062
Jaekyun Seok59a8ef02018-01-15 14:49:05 +09002063 mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/product/media/audio/ui/camera_click.ogg");
2064 if (mSoundPlayer[SOUND_SHUTTER] == nullptr) {
2065 mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
2066 }
2067 mSoundPlayer[SOUND_RECORDING_START] = newMediaPlayer("/product/media/audio/ui/VideoRecord.ogg");
2068 if (mSoundPlayer[SOUND_RECORDING_START] == nullptr) {
2069 mSoundPlayer[SOUND_RECORDING_START] =
2070 newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");
2071 }
2072 mSoundPlayer[SOUND_RECORDING_STOP] = newMediaPlayer("/product/media/audio/ui/VideoStop.ogg");
2073 if (mSoundPlayer[SOUND_RECORDING_STOP] == nullptr) {
2074 mSoundPlayer[SOUND_RECORDING_STOP] = newMediaPlayer("/system/media/audio/ui/VideoStop.ogg");
2075 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07002076}
2077
2078void CameraService::releaseSound() {
2079 Mutex::Autolock lock(mSoundLock);
2080 LOG1("CameraService::releaseSound ref=%d", mSoundRef);
2081 if (--mSoundRef) return;
2082
2083 for (int i = 0; i < NUM_SOUNDS; i++) {
2084 if (mSoundPlayer[i] != 0) {
2085 mSoundPlayer[i]->disconnect();
2086 mSoundPlayer[i].clear();
2087 }
2088 }
2089}
2090
2091void CameraService::playSound(sound_kind kind) {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -07002092 ATRACE_CALL();
2093
Mathias Agopian65ab4712010-07-14 17:59:35 -07002094 LOG1("playSound(%d)", kind);
2095 Mutex::Autolock lock(mSoundLock);
2096 sp<MediaPlayer> player = mSoundPlayer[kind];
2097 if (player != 0) {
Chih-Chung Chang8888a752011-10-20 10:47:26 +08002098 player->seekTo(0);
2099 player->start();
Mathias Agopian65ab4712010-07-14 17:59:35 -07002100 }
2101}
2102
2103// ----------------------------------------------------------------------------
2104
2105CameraService::Client::Client(const sp<CameraService>& cameraService,
Wu-cheng Lib7a67942010-08-17 15:45:37 -07002106 const sp<ICameraClient>& cameraClient,
Svetoslav Ganov280405a2015-05-12 02:19:27 +00002107 const String16& clientPackageName,
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -08002108 const String8& cameraIdStr,
2109 int api1CameraId, int cameraFacing,
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002110 int clientPid, uid_t clientUid,
2111 int servicePid) :
Eino-Ville Talvalae992e752014-11-07 16:17:48 -08002112 CameraService::BasicClient(cameraService,
Marco Nelissenf8880202014-11-14 07:58:25 -08002113 IInterface::asBinder(cameraClient),
Svetoslav Ganov280405a2015-05-12 02:19:27 +00002114 clientPackageName,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08002115 cameraIdStr, cameraFacing,
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002116 clientPid, clientUid,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08002117 servicePid),
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -08002118 mCameraId(api1CameraId)
Igor Murashkin634a5152013-02-20 17:15:11 -08002119{
Jayant Chowdhary12361932018-08-27 14:46:13 -07002120 int callingPid = CameraThreadState::getCallingPid();
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08002121 LOG1("Client::Client E (pid %d, id %d)", callingPid, mCameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -07002122
Igor Murashkin44cfcf02013-03-01 16:22:28 -08002123 mRemoteCallback = cameraClient;
Mathias Agopian65ab4712010-07-14 17:59:35 -07002124
Mathias Agopian65ab4712010-07-14 17:59:35 -07002125 cameraService->loadSound();
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002126
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08002127 LOG1("Client::Client X (pid %d, id %d)", callingPid, mCameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -07002128}
2129
Mathias Agopian65ab4712010-07-14 17:59:35 -07002130// tear down the client
2131CameraService::Client::~Client() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -07002132 ALOGV("~Client");
Igor Murashkin634a5152013-02-20 17:15:11 -08002133 mDestructionStarted = true;
2134
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08002135 sCameraService->releaseSound();
Igor Murashkin036bc3e2012-10-08 15:09:46 -07002136 // unconditionally disconnect. function is idempotent
2137 Client::disconnect();
Mathias Agopian65ab4712010-07-14 17:59:35 -07002138}
2139
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08002140sp<CameraService> CameraService::BasicClient::BasicClient::sCameraService;
2141
Igor Murashkin634a5152013-02-20 17:15:11 -08002142CameraService::BasicClient::BasicClient(const sp<CameraService>& cameraService,
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002143 const sp<IBinder>& remoteCallback,
Svetoslav Ganov280405a2015-05-12 02:19:27 +00002144 const String16& clientPackageName,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08002145 const String8& cameraIdStr, int cameraFacing,
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002146 int clientPid, uid_t clientUid,
2147 int servicePid):
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08002148 mCameraIdStr(cameraIdStr), mCameraFacing(cameraFacing),
2149 mClientPackageName(clientPackageName), mClientPid(clientPid), mClientUid(clientUid),
2150 mServicePid(servicePid),
2151 mDisconnected(false),
2152 mRemoteBinder(remoteCallback)
Igor Murashkin634a5152013-02-20 17:15:11 -08002153{
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08002154 if (sCameraService == nullptr) {
2155 sCameraService = cameraService;
2156 }
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002157 mOpsActive = false;
Igor Murashkin634a5152013-02-20 17:15:11 -08002158 mDestructionStarted = false;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08002159
2160 // In some cases the calling code has no access to the package it runs under.
2161 // For example, NDK camera API.
2162 // In this case we will get the packages for the calling UID and pick the first one
2163 // for attributing the app op. This will work correctly for runtime permissions
2164 // as for legacy apps we will toggle the app op for all packages in the UID.
2165 // The caveat is that the operation may be attributed to the wrong package and
2166 // stats based on app ops may be slightly off.
2167 if (mClientPackageName.size() <= 0) {
2168 sp<IServiceManager> sm = defaultServiceManager();
2169 sp<IBinder> binder = sm->getService(String16(kPermissionServiceName));
2170 if (binder == 0) {
2171 ALOGE("Cannot get permission service");
2172 // Leave mClientPackageName unchanged (empty) and the further interaction
2173 // with camera will fail in BasicClient::startCameraOps
2174 return;
2175 }
2176
2177 sp<IPermissionController> permCtrl = interface_cast<IPermissionController>(binder);
2178 Vector<String16> packages;
2179
2180 permCtrl->getPackagesForUid(mClientUid, packages);
2181
2182 if (packages.isEmpty()) {
2183 ALOGE("No packages for calling UID");
2184 // Leave mClientPackageName unchanged (empty) and the further interaction
2185 // with camera will fail in BasicClient::startCameraOps
2186 return;
2187 }
2188 mClientPackageName = packages[0];
2189 }
Igor Murashkin634a5152013-02-20 17:15:11 -08002190}
2191
2192CameraService::BasicClient::~BasicClient() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -07002193 ALOGV("~BasicClient");
Igor Murashkin634a5152013-02-20 17:15:11 -08002194 mDestructionStarted = true;
2195}
2196
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08002197binder::Status CameraService::BasicClient::disconnect() {
2198 binder::Status res = Status::ok();
Ruben Brunk36597b22015-03-20 22:15:57 -07002199 if (mDisconnected) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08002200 return res;
Ruben Brunk36597b22015-03-20 22:15:57 -07002201 }
Eino-Ville Talvala24901c82015-09-04 14:15:58 -07002202 mDisconnected = true;
Ruben Brunkcc776712015-02-17 20:18:47 -08002203
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08002204 sCameraService->removeByClient(this);
2205 sCameraService->logDisconnected(mCameraIdStr, mClientPid,
Svetoslav Ganov280405a2015-05-12 02:19:27 +00002206 String8(mClientPackageName));
Ruben Brunkcc776712015-02-17 20:18:47 -08002207
2208 sp<IBinder> remote = getRemote();
2209 if (remote != nullptr) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08002210 remote->unlinkToDeath(sCameraService);
Ruben Brunkcc776712015-02-17 20:18:47 -08002211 }
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07002212
2213 finishCameraOps();
Chien-Yu Chene4fe21b2016-08-04 12:42:40 -07002214 // Notify flashlight that a camera device is closed.
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08002215 sCameraService->mFlashlight->deviceClosed(mCameraIdStr);
2216 ALOGI("%s: Disconnected client for camera %s for PID %d", __FUNCTION__, mCameraIdStr.string(),
2217 mClientPid);
Ruben Brunkcc776712015-02-17 20:18:47 -08002218
Igor Murashkincba2c162013-03-20 15:56:31 -07002219 // client shouldn't be able to call into us anymore
2220 mClientPid = 0;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08002221
2222 return res;
Igor Murashkin634a5152013-02-20 17:15:11 -08002223}
2224
Eino-Ville Talvalac4003962016-01-13 10:07:04 -08002225status_t CameraService::BasicClient::dump(int, const Vector<String16>&) {
2226 // No dumping of clients directly over Binder,
2227 // must go through CameraService::dump
2228 android_errorWriteWithInfoLog(SN_EVENT_LOG_ID, "26265403",
Jayant Chowdhary12361932018-08-27 14:46:13 -07002229 CameraThreadState::getCallingUid(), NULL, 0);
Eino-Ville Talvalac4003962016-01-13 10:07:04 -08002230 return OK;
2231}
2232
Ruben Brunkcc776712015-02-17 20:18:47 -08002233String16 CameraService::BasicClient::getPackageName() const {
Svetoslav Ganov280405a2015-05-12 02:19:27 +00002234 return mClientPackageName;
Ruben Brunkcc776712015-02-17 20:18:47 -08002235}
2236
2237
2238int CameraService::BasicClient::getClientPid() const {
2239 return mClientPid;
2240}
2241
Ruben Brunk6267b532015-04-30 17:44:07 -07002242uid_t CameraService::BasicClient::getClientUid() const {
2243 return mClientUid;
2244}
2245
Ruben Brunk0bbf8b22015-04-30 14:35:42 -07002246bool CameraService::BasicClient::canCastToApiClient(apiLevel level) const {
2247 // Defaults to API2.
2248 return level == API_2;
2249}
2250
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002251status_t CameraService::BasicClient::startCameraOps() {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -07002252 ATRACE_CALL();
2253
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002254 int32_t res;
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07002255 // Notify app ops that the camera is not available
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002256 mOpsCallback = new OpsCallback(this);
2257
Igor Murashkine6800ce2013-03-04 17:25:57 -08002258 {
2259 ALOGV("%s: Start camera ops, package name = %s, client UID = %d",
Svetoslav Ganov280405a2015-05-12 02:19:27 +00002260 __FUNCTION__, String8(mClientPackageName).string(), mClientUid);
Igor Murashkine6800ce2013-03-04 17:25:57 -08002261 }
2262
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002263 mAppOpsManager.startWatchingMode(AppOpsManager::OP_CAMERA,
Svetoslav Ganov280405a2015-05-12 02:19:27 +00002264 mClientPackageName, mOpsCallback);
Svet Ganov1d519102018-02-26 10:48:14 -08002265 res = mAppOpsManager.startOpNoThrow(AppOpsManager::OP_CAMERA,
2266 mClientUid, mClientPackageName, /*startIfModeDefault*/ false);
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002267
Svetoslav28e8ef72015-05-11 19:21:31 -07002268 if (res == AppOpsManager::MODE_ERRORED) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08002269 ALOGI("Camera %s: Access for \"%s\" has been revoked",
2270 mCameraIdStr.string(), String8(mClientPackageName).string());
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002271 return PERMISSION_DENIED;
2272 }
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07002273
Svetoslav28e8ef72015-05-11 19:21:31 -07002274 if (res == AppOpsManager::MODE_IGNORED) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08002275 ALOGI("Camera %s: Access for \"%s\" has been restricted",
2276 mCameraIdStr.string(), String8(mClientPackageName).string());
Eino-Ville Talvalae3afb2c2015-06-03 16:03:30 -07002277 // Return the same error as for device policy manager rejection
2278 return -EACCES;
Svetoslav28e8ef72015-05-11 19:21:31 -07002279 }
2280
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002281 mOpsActive = true;
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07002282
2283 // Transition device availability listeners from PRESENT -> NOT_AVAILABLE
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08002284 sCameraService->updateStatus(StatusInternal::NOT_AVAILABLE, mCameraIdStr);
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07002285
Emilian Peev573291c2018-02-10 02:10:56 +00002286 int apiLevel = hardware::ICameraServiceProxy::CAMERA_API_LEVEL_1;
2287 if (canCastToApiClient(API_2)) {
2288 apiLevel = hardware::ICameraServiceProxy::CAMERA_API_LEVEL_2;
2289 }
Eino-Ville Talvala412fe562015-08-20 17:08:32 -07002290 // Transition device state to OPEN
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08002291 sCameraService->updateProxyDeviceState(ICameraServiceProxy::CAMERA_STATE_OPEN,
Emilian Peev573291c2018-02-10 02:10:56 +00002292 mCameraIdStr, mCameraFacing, mClientPackageName, apiLevel);
Eino-Ville Talvala412fe562015-08-20 17:08:32 -07002293
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002294 return OK;
2295}
2296
2297status_t CameraService::BasicClient::finishCameraOps() {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -07002298 ATRACE_CALL();
2299
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07002300 // Check if startCameraOps succeeded, and if so, finish the camera op
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002301 if (mOpsActive) {
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07002302 // Notify app ops that the camera is available again
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002303 mAppOpsManager.finishOp(AppOpsManager::OP_CAMERA, mClientUid,
Svetoslav Ganov280405a2015-05-12 02:19:27 +00002304 mClientPackageName);
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002305 mOpsActive = false;
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07002306
Guennadi Liakhovetski151e3be2017-11-28 16:34:18 +01002307 // This function is called when a client disconnects. This should
2308 // release the camera, but actually only if it was in a proper
2309 // functional state, i.e. with status NOT_AVAILABLE
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08002310 std::initializer_list<StatusInternal> rejected = {StatusInternal::PRESENT,
Guennadi Liakhovetski151e3be2017-11-28 16:34:18 +01002311 StatusInternal::ENUMERATING, StatusInternal::NOT_PRESENT};
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07002312
Ruben Brunkcc776712015-02-17 20:18:47 -08002313 // Transition to PRESENT if the camera is not in either of the rejected states
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08002314 sCameraService->updateStatus(StatusInternal::PRESENT,
2315 mCameraIdStr, rejected);
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07002316
Emilian Peev573291c2018-02-10 02:10:56 +00002317 int apiLevel = hardware::ICameraServiceProxy::CAMERA_API_LEVEL_1;
2318 if (canCastToApiClient(API_2)) {
2319 apiLevel = hardware::ICameraServiceProxy::CAMERA_API_LEVEL_2;
2320 }
Eino-Ville Talvala412fe562015-08-20 17:08:32 -07002321 // Transition device state to CLOSED
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08002322 sCameraService->updateProxyDeviceState(ICameraServiceProxy::CAMERA_STATE_CLOSED,
Emilian Peev573291c2018-02-10 02:10:56 +00002323 mCameraIdStr, mCameraFacing, mClientPackageName, apiLevel);
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002324 }
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07002325 // Always stop watching, even if no camera op is active
Eino-Ville Talvalae992e752014-11-07 16:17:48 -08002326 if (mOpsCallback != NULL) {
2327 mAppOpsManager.stopWatchingMode(mOpsCallback);
2328 }
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002329 mOpsCallback.clear();
2330
2331 return OK;
2332}
2333
2334void CameraService::BasicClient::opChanged(int32_t op, const String16& packageName) {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -07002335 ATRACE_CALL();
2336
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002337 String8 name(packageName);
Svetoslav Ganov280405a2015-05-12 02:19:27 +00002338 String8 myName(mClientPackageName);
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002339
2340 if (op != AppOpsManager::OP_CAMERA) {
2341 ALOGW("Unexpected app ops notification received: %d", op);
2342 return;
2343 }
2344
2345 int32_t res;
2346 res = mAppOpsManager.checkOp(AppOpsManager::OP_CAMERA,
Svetoslav Ganov280405a2015-05-12 02:19:27 +00002347 mClientUid, mClientPackageName);
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002348 ALOGV("checkOp returns: %d, %s ", res,
2349 res == AppOpsManager::MODE_ALLOWED ? "ALLOWED" :
2350 res == AppOpsManager::MODE_IGNORED ? "IGNORED" :
2351 res == AppOpsManager::MODE_ERRORED ? "ERRORED" :
2352 "UNKNOWN");
2353
2354 if (res != AppOpsManager::MODE_ALLOWED) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08002355 ALOGI("Camera %s: Access for \"%s\" revoked", mCameraIdStr.string(),
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002356 myName.string());
Svet Ganova453d0d2018-01-11 15:37:58 -08002357 block();
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002358 }
2359}
2360
Svet Ganova453d0d2018-01-11 15:37:58 -08002361void CameraService::BasicClient::block() {
2362 ATRACE_CALL();
2363
2364 // Reset the client PID to allow server-initiated disconnect,
2365 // and to prevent further calls by client.
Jayant Chowdhary12361932018-08-27 14:46:13 -07002366 mClientPid = CameraThreadState::getCallingPid();
Svet Ganova453d0d2018-01-11 15:37:58 -08002367 CaptureResultExtras resultExtras; // a dummy result (invalid)
2368 notifyError(hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISABLED, resultExtras);
2369 disconnect();
2370}
2371
Mathias Agopian65ab4712010-07-14 17:59:35 -07002372// ----------------------------------------------------------------------------
2373
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08002374void CameraService::Client::notifyError(int32_t errorCode,
Jianing Weicb0652e2014-03-12 18:29:36 -07002375 const CaptureResultExtras& resultExtras) {
Eino-Ville Talvalad309fb92015-11-25 12:12:45 -08002376 (void) resultExtras;
Ranjith Kagathi Ananda3e600892015-10-08 16:00:33 -07002377 if (mRemoteCallback != NULL) {
Yin-Chia Yehf13bda52018-05-31 12:12:59 -07002378 int32_t api1ErrorCode = CAMERA_ERROR_RELEASED;
2379 if (errorCode == hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISABLED) {
2380 api1ErrorCode = CAMERA_ERROR_DISABLED;
2381 }
2382 mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, api1ErrorCode, 0);
Ranjith Kagathi Ananda3e600892015-10-08 16:00:33 -07002383 } else {
2384 ALOGE("mRemoteCallback is NULL!!");
2385 }
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002386}
2387
Igor Murashkin036bc3e2012-10-08 15:09:46 -07002388// NOTE: function is idempotent
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08002389binder::Status CameraService::Client::disconnect() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -07002390 ALOGV("Client::disconnect");
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08002391 return BasicClient::disconnect();
Wu-cheng Lie09591e2010-10-14 20:17:44 +08002392}
2393
Ruben Brunk0bbf8b22015-04-30 14:35:42 -07002394bool CameraService::Client::canCastToApiClient(apiLevel level) const {
2395 return level == API_1;
2396}
2397
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002398CameraService::Client::OpsCallback::OpsCallback(wp<BasicClient> client):
2399 mClient(client) {
2400}
2401
2402void CameraService::Client::OpsCallback::opChanged(int32_t op,
2403 const String16& packageName) {
2404 sp<BasicClient> client = mClient.promote();
2405 if (client != NULL) {
2406 client->opChanged(op, packageName);
2407 }
2408}
2409
Mathias Agopian65ab4712010-07-14 17:59:35 -07002410// ----------------------------------------------------------------------------
Svet Ganova453d0d2018-01-11 15:37:58 -08002411// UidPolicy
2412// ----------------------------------------------------------------------------
2413
2414void CameraService::UidPolicy::registerSelf() {
Eino-Ville Talvala8abec3f2018-03-20 11:07:00 -07002415 Mutex::Autolock _l(mUidLock);
2416
Svet Ganova453d0d2018-01-11 15:37:58 -08002417 ActivityManager am;
Eino-Ville Talvala8abec3f2018-03-20 11:07:00 -07002418 if (mRegistered) return;
Svet Ganova453d0d2018-01-11 15:37:58 -08002419 am.registerUidObserver(this, ActivityManager::UID_OBSERVER_GONE
2420 | ActivityManager::UID_OBSERVER_IDLE
2421 | ActivityManager::UID_OBSERVER_ACTIVE,
2422 ActivityManager::PROCESS_STATE_UNKNOWN,
2423 String16("cameraserver"));
Eino-Ville Talvala8abec3f2018-03-20 11:07:00 -07002424 status_t res = am.linkToDeath(this);
2425 if (res == OK) {
2426 mRegistered = true;
2427 ALOGV("UidPolicy: Registered with ActivityManager");
2428 }
Svet Ganova453d0d2018-01-11 15:37:58 -08002429}
2430
2431void CameraService::UidPolicy::unregisterSelf() {
Eino-Ville Talvala8abec3f2018-03-20 11:07:00 -07002432 Mutex::Autolock _l(mUidLock);
2433
Svet Ganova453d0d2018-01-11 15:37:58 -08002434 ActivityManager am;
2435 am.unregisterUidObserver(this);
Eino-Ville Talvala8abec3f2018-03-20 11:07:00 -07002436 am.unlinkToDeath(this);
2437 mRegistered = false;
2438 mActiveUids.clear();
2439 ALOGV("UidPolicy: Unregistered with ActivityManager");
Svet Ganova453d0d2018-01-11 15:37:58 -08002440}
2441
2442void CameraService::UidPolicy::onUidGone(uid_t uid, bool disabled) {
2443 onUidIdle(uid, disabled);
2444}
2445
2446void CameraService::UidPolicy::onUidActive(uid_t uid) {
2447 Mutex::Autolock _l(mUidLock);
2448 mActiveUids.insert(uid);
2449}
2450
2451void CameraService::UidPolicy::onUidIdle(uid_t uid, bool /* disabled */) {
2452 bool deleted = false;
2453 {
2454 Mutex::Autolock _l(mUidLock);
2455 if (mActiveUids.erase(uid) > 0) {
2456 deleted = true;
2457 }
2458 }
2459 if (deleted) {
2460 sp<CameraService> service = mService.promote();
2461 if (service != nullptr) {
2462 service->blockClientsForUid(uid);
2463 }
2464 }
2465}
2466
Svet Ganov7b4ab782018-03-25 12:48:10 -07002467bool CameraService::UidPolicy::isUidActive(uid_t uid, String16 callingPackage) {
Svet Ganova453d0d2018-01-11 15:37:58 -08002468 Mutex::Autolock _l(mUidLock);
Svet Ganov7b4ab782018-03-25 12:48:10 -07002469 return isUidActiveLocked(uid, callingPackage);
Svet Ganova453d0d2018-01-11 15:37:58 -08002470}
2471
Eino-Ville Talvala32b8c202018-08-20 10:27:58 -07002472static const int64_t kPollUidActiveTimeoutTotalMillis = 300;
2473static const int64_t kPollUidActiveTimeoutMillis = 50;
Svet Ganov94ec46f2018-06-08 15:03:46 -07002474
Svet Ganov7b4ab782018-03-25 12:48:10 -07002475bool CameraService::UidPolicy::isUidActiveLocked(uid_t uid, String16 callingPackage) {
Svet Ganova453d0d2018-01-11 15:37:58 -08002476 // Non-app UIDs are considered always active
Eino-Ville Talvala8abec3f2018-03-20 11:07:00 -07002477 // If activity manager is unreachable, assume everything is active
2478 if (uid < FIRST_APPLICATION_UID || !mRegistered) {
Svet Ganova453d0d2018-01-11 15:37:58 -08002479 return true;
2480 }
2481 auto it = mOverrideUids.find(uid);
2482 if (it != mOverrideUids.end()) {
2483 return it->second;
2484 }
Svet Ganov7b4ab782018-03-25 12:48:10 -07002485 bool active = mActiveUids.find(uid) != mActiveUids.end();
2486 if (!active) {
2487 // We want active UIDs to always access camera with their first attempt since
2488 // there is no guarantee the app is robustly written and would retry getting
2489 // the camera on failure. The inverse case is not a problem as we would take
2490 // camera away soon once we get the callback that the uid is no longer active.
2491 ActivityManager am;
2492 // Okay to access with a lock held as UID changes are dispatched without
2493 // a lock and we are a higher level component.
Svet Ganov94ec46f2018-06-08 15:03:46 -07002494 int64_t startTimeMillis = 0;
2495 do {
2496 // TODO: Fix this b/109950150!
2497 // Okay this is a hack. There is a race between the UID turning active and
2498 // activity being resumed. The proper fix is very risky, so we temporary add
2499 // some polling which should happen pretty rarely anyway as the race is hard
2500 // to hit.
Eino-Ville Talvala32b8c202018-08-20 10:27:58 -07002501 active = mActiveUids.find(uid) != mActiveUids.end();
2502 if (!active) active = am.isUidActive(uid, callingPackage);
Svet Ganov94ec46f2018-06-08 15:03:46 -07002503 if (active) {
2504 break;
2505 }
2506 if (startTimeMillis <= 0) {
2507 startTimeMillis = uptimeMillis();
2508 }
2509 int64_t ellapsedTimeMillis = uptimeMillis() - startTimeMillis;
Eino-Ville Talvala32b8c202018-08-20 10:27:58 -07002510 int64_t remainingTimeMillis = kPollUidActiveTimeoutTotalMillis - ellapsedTimeMillis;
Svet Ganov94ec46f2018-06-08 15:03:46 -07002511 if (remainingTimeMillis <= 0) {
2512 break;
2513 }
Eino-Ville Talvala32b8c202018-08-20 10:27:58 -07002514 remainingTimeMillis = std::min(kPollUidActiveTimeoutMillis, remainingTimeMillis);
2515
2516 mUidLock.unlock();
Svet Ganov94ec46f2018-06-08 15:03:46 -07002517 usleep(remainingTimeMillis * 1000);
Eino-Ville Talvala32b8c202018-08-20 10:27:58 -07002518 mUidLock.lock();
Svet Ganov94ec46f2018-06-08 15:03:46 -07002519 } while (true);
2520
Svet Ganov7b4ab782018-03-25 12:48:10 -07002521 if (active) {
2522 // Now that we found out the UID is actually active, cache that
2523 mActiveUids.insert(uid);
2524 }
2525 }
2526 return active;
Svet Ganova453d0d2018-01-11 15:37:58 -08002527}
2528
Svet Ganov7b4ab782018-03-25 12:48:10 -07002529void CameraService::UidPolicy::UidPolicy::addOverrideUid(uid_t uid,
2530 String16 callingPackage, bool active) {
2531 updateOverrideUid(uid, callingPackage, active, true);
Svet Ganova453d0d2018-01-11 15:37:58 -08002532}
2533
Svet Ganov7b4ab782018-03-25 12:48:10 -07002534void CameraService::UidPolicy::removeOverrideUid(uid_t uid, String16 callingPackage) {
2535 updateOverrideUid(uid, callingPackage, false, false);
Svet Ganova453d0d2018-01-11 15:37:58 -08002536}
2537
Eino-Ville Talvala8abec3f2018-03-20 11:07:00 -07002538void CameraService::UidPolicy::binderDied(const wp<IBinder>& /*who*/) {
2539 Mutex::Autolock _l(mUidLock);
2540 ALOGV("UidPolicy: ActivityManager has died");
2541 mRegistered = false;
2542 mActiveUids.clear();
2543}
2544
Svet Ganov7b4ab782018-03-25 12:48:10 -07002545void CameraService::UidPolicy::updateOverrideUid(uid_t uid, String16 callingPackage,
2546 bool active, bool insert) {
Svet Ganova453d0d2018-01-11 15:37:58 -08002547 bool wasActive = false;
2548 bool isActive = false;
2549 {
2550 Mutex::Autolock _l(mUidLock);
Svet Ganov7b4ab782018-03-25 12:48:10 -07002551 wasActive = isUidActiveLocked(uid, callingPackage);
Svet Ganova453d0d2018-01-11 15:37:58 -08002552 mOverrideUids.erase(uid);
2553 if (insert) {
2554 mOverrideUids.insert(std::pair<uid_t, bool>(uid, active));
2555 }
Svet Ganov7b4ab782018-03-25 12:48:10 -07002556 isActive = isUidActiveLocked(uid, callingPackage);
Svet Ganova453d0d2018-01-11 15:37:58 -08002557 }
2558 if (wasActive != isActive && !isActive) {
2559 sp<CameraService> service = mService.promote();
2560 if (service != nullptr) {
2561 service->blockClientsForUid(uid);
2562 }
2563 }
2564}
2565
2566// ----------------------------------------------------------------------------
Ruben Brunkcc776712015-02-17 20:18:47 -08002567// CameraState
2568// ----------------------------------------------------------------------------
2569
2570CameraService::CameraState::CameraState(const String8& id, int cost,
2571 const std::set<String8>& conflicting) : mId(id),
Guennadi Liakhovetski151e3be2017-11-28 16:34:18 +01002572 mStatus(StatusInternal::NOT_PRESENT), mCost(cost), mConflicting(conflicting) {}
Ruben Brunkcc776712015-02-17 20:18:47 -08002573
2574CameraService::CameraState::~CameraState() {}
2575
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08002576CameraService::StatusInternal CameraService::CameraState::getStatus() const {
Ruben Brunkcc776712015-02-17 20:18:47 -08002577 Mutex::Autolock lock(mStatusLock);
2578 return mStatus;
2579}
2580
2581CameraParameters CameraService::CameraState::getShimParams() const {
2582 return mShimParams;
2583}
2584
2585void CameraService::CameraState::setShimParams(const CameraParameters& params) {
2586 mShimParams = params;
2587}
2588
2589int CameraService::CameraState::getCost() const {
2590 return mCost;
2591}
2592
2593std::set<String8> CameraService::CameraState::getConflicting() const {
2594 return mConflicting;
2595}
2596
2597String8 CameraService::CameraState::getId() const {
2598 return mId;
2599}
2600
2601// ----------------------------------------------------------------------------
Ruben Brunk99e69712015-05-26 17:25:07 -07002602// ClientEventListener
2603// ----------------------------------------------------------------------------
2604
2605void CameraService::ClientEventListener::onClientAdded(
2606 const resource_policy::ClientDescriptor<String8,
2607 sp<CameraService::BasicClient>>& descriptor) {
Chih-Hung Hsieh5404ee12016-08-09 14:25:53 -07002608 const auto& basicClient = descriptor.getValue();
Ruben Brunk99e69712015-05-26 17:25:07 -07002609 if (basicClient.get() != nullptr) {
2610 BatteryNotifier& notifier(BatteryNotifier::getInstance());
2611 notifier.noteStartCamera(descriptor.getKey(),
2612 static_cast<int>(basicClient->getClientUid()));
2613 }
2614}
2615
2616void CameraService::ClientEventListener::onClientRemoved(
2617 const resource_policy::ClientDescriptor<String8,
2618 sp<CameraService::BasicClient>>& descriptor) {
Chih-Hung Hsieh5404ee12016-08-09 14:25:53 -07002619 const auto& basicClient = descriptor.getValue();
Ruben Brunk99e69712015-05-26 17:25:07 -07002620 if (basicClient.get() != nullptr) {
2621 BatteryNotifier& notifier(BatteryNotifier::getInstance());
2622 notifier.noteStopCamera(descriptor.getKey(),
2623 static_cast<int>(basicClient->getClientUid()));
2624 }
2625}
2626
2627
2628// ----------------------------------------------------------------------------
Ruben Brunkcc776712015-02-17 20:18:47 -08002629// CameraClientManager
2630// ----------------------------------------------------------------------------
2631
Ruben Brunk99e69712015-05-26 17:25:07 -07002632CameraService::CameraClientManager::CameraClientManager() {
2633 setListener(std::make_shared<ClientEventListener>());
2634}
2635
Ruben Brunkcc776712015-02-17 20:18:47 -08002636CameraService::CameraClientManager::~CameraClientManager() {}
2637
2638sp<CameraService::BasicClient> CameraService::CameraClientManager::getCameraClient(
2639 const String8& id) const {
2640 auto descriptor = get(id);
2641 if (descriptor == nullptr) {
2642 return sp<BasicClient>{nullptr};
2643 }
2644 return descriptor->getValue();
2645}
2646
2647String8 CameraService::CameraClientManager::toString() const {
2648 auto all = getAll();
2649 String8 ret("[");
2650 bool hasAny = false;
2651 for (auto& i : all) {
2652 hasAny = true;
2653 String8 key = i->getKey();
2654 int32_t cost = i->getCost();
2655 int32_t pid = i->getOwnerId();
Emilian Peev8131a262017-02-01 12:33:43 +00002656 int32_t score = i->getPriority().getScore();
2657 int32_t state = i->getPriority().getState();
Ruben Brunkcc776712015-02-17 20:18:47 -08002658 auto conflicting = i->getConflicting();
2659 auto clientSp = i->getValue();
2660 String8 packageName;
Eino-Ville Talvala022f0cb2015-05-19 16:31:16 -07002661 userid_t clientUserId = 0;
Ruben Brunkcc776712015-02-17 20:18:47 -08002662 if (clientSp.get() != nullptr) {
2663 packageName = String8{clientSp->getPackageName()};
Ruben Brunk6267b532015-04-30 17:44:07 -07002664 uid_t clientUid = clientSp->getClientUid();
2665 clientUserId = multiuser_get_user_id(clientUid);
Ruben Brunkcc776712015-02-17 20:18:47 -08002666 }
Emilian Peev8131a262017-02-01 12:33:43 +00002667 ret.appendFormat("\n(Camera ID: %s, Cost: %" PRId32 ", PID: %" PRId32 ", Score: %"
2668 PRId32 ", State: %" PRId32, key.string(), cost, pid, score, state);
Ruben Brunkcc776712015-02-17 20:18:47 -08002669
Ruben Brunk6267b532015-04-30 17:44:07 -07002670 if (clientSp.get() != nullptr) {
2671 ret.appendFormat("User Id: %d, ", clientUserId);
2672 }
Ruben Brunkcc776712015-02-17 20:18:47 -08002673 if (packageName.size() != 0) {
2674 ret.appendFormat("Client Package Name: %s", packageName.string());
2675 }
2676
2677 ret.append(", Conflicting Client Devices: {");
2678 for (auto& j : conflicting) {
2679 ret.appendFormat("%s, ", j.string());
2680 }
2681 ret.append("})");
2682 }
2683 if (hasAny) ret.append("\n");
2684 ret.append("]\n");
2685 return ret;
2686}
2687
2688CameraService::DescriptorPtr CameraService::CameraClientManager::makeClientDescriptor(
2689 const String8& key, const sp<BasicClient>& value, int32_t cost,
Emilian Peev8131a262017-02-01 12:33:43 +00002690 const std::set<String8>& conflictingKeys, int32_t score, int32_t ownerId,
2691 int32_t state) {
Ruben Brunkcc776712015-02-17 20:18:47 -08002692
2693 return std::make_shared<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>(
Emilian Peev8131a262017-02-01 12:33:43 +00002694 key, value, cost, conflictingKeys, score, ownerId, state);
Ruben Brunkcc776712015-02-17 20:18:47 -08002695}
2696
2697CameraService::DescriptorPtr CameraService::CameraClientManager::makeClientDescriptor(
2698 const sp<BasicClient>& value, const CameraService::DescriptorPtr& partial) {
2699 return makeClientDescriptor(partial->getKey(), value, partial->getCost(),
Emilian Peev8131a262017-02-01 12:33:43 +00002700 partial->getConflicting(), partial->getPriority().getScore(),
2701 partial->getOwnerId(), partial->getPriority().getState());
Ruben Brunkcc776712015-02-17 20:18:47 -08002702}
2703
2704// ----------------------------------------------------------------------------
Mathias Agopian65ab4712010-07-14 17:59:35 -07002705
2706static const int kDumpLockRetries = 50;
2707static const int kDumpLockSleep = 60000;
2708
2709static bool tryLock(Mutex& mutex)
2710{
2711 bool locked = false;
2712 for (int i = 0; i < kDumpLockRetries; ++i) {
2713 if (mutex.tryLock() == NO_ERROR) {
2714 locked = true;
2715 break;
2716 }
2717 usleep(kDumpLockSleep);
2718 }
2719 return locked;
2720}
2721
2722status_t CameraService::dump(int fd, const Vector<String16>& args) {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -07002723 ATRACE_CALL();
2724
Mathias Agopian65ab4712010-07-14 17:59:35 -07002725 if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -08002726 dprintf(fd, "Permission Denial: can't dump CameraService from pid=%d, uid=%d\n",
Jayant Chowdhary12361932018-08-27 14:46:13 -07002727 CameraThreadState::getCallingPid(),
2728 CameraThreadState::getCallingUid());
Eino-Ville Talvala81314182017-01-30 16:13:45 -08002729 return NO_ERROR;
2730 }
Eino-Ville Talvala81314182017-01-30 16:13:45 -08002731 bool locked = tryLock(mServiceLock);
2732 // failed to lock - CameraService is probably deadlocked
2733 if (!locked) {
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -08002734 dprintf(fd, "!! CameraService may be deadlocked !!\n");
Eino-Ville Talvala81314182017-01-30 16:13:45 -08002735 }
Eino-Ville Talvala1527f072015-04-07 15:55:31 -07002736
Eino-Ville Talvala81314182017-01-30 16:13:45 -08002737 if (!mInitialized) {
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -08002738 dprintf(fd, "!! No camera HAL available !!\n");
Ruben Brunkf81648e2014-04-17 16:14:57 -07002739
Eino-Ville Talvala81314182017-01-30 16:13:45 -08002740 // Dump event log for error information
Eino-Ville Talvala1527f072015-04-07 15:55:31 -07002741 dumpEventLog(fd);
Ruben Brunkcc776712015-02-17 20:18:47 -08002742
Eino-Ville Talvala81314182017-01-30 16:13:45 -08002743 if (locked) mServiceLock.unlock();
2744 return NO_ERROR;
2745 }
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -08002746 dprintf(fd, "\n== Service global info: ==\n\n");
2747 dprintf(fd, "Number of camera devices: %d\n", mNumberOfCameras);
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -08002748 dprintf(fd, "Number of normal camera devices: %zu\n", mNormalDeviceIds.size());
2749 for (size_t i = 0; i < mNormalDeviceIds.size(); i++) {
2750 dprintf(fd, " Device %zu maps to \"%s\"\n", i, mNormalDeviceIds[i].c_str());
2751 }
Eino-Ville Talvala81314182017-01-30 16:13:45 -08002752 String8 activeClientString = mActiveClientManager.toString();
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -08002753 dprintf(fd, "Active Camera Clients:\n%s", activeClientString.string());
2754 dprintf(fd, "Allowed user IDs: %s\n", toString(mAllowedUsers).string());
Eino-Ville Talvala81314182017-01-30 16:13:45 -08002755
2756 dumpEventLog(fd);
2757
2758 bool stateLocked = tryLock(mCameraStatesLock);
2759 if (!stateLocked) {
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -08002760 dprintf(fd, "CameraStates in use, may be deadlocked\n");
Eino-Ville Talvala81314182017-01-30 16:13:45 -08002761 }
2762
Emilian Peevbd8c5032018-02-14 23:05:40 +00002763 int argSize = args.size();
2764 for (int i = 0; i < argSize; i++) {
2765 if (args[i] == TagMonitor::kMonitorOption) {
2766 if (i + 1 < argSize) {
2767 mMonitorTags = String8(args[i + 1]);
2768 }
2769 break;
2770 }
2771 }
2772
Eino-Ville Talvala81314182017-01-30 16:13:45 -08002773 for (auto& state : mCameraStates) {
2774 String8 cameraId = state.first;
Eino-Ville Talvala81314182017-01-30 16:13:45 -08002775
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -08002776 dprintf(fd, "== Camera device %s dynamic info: ==\n", cameraId.string());
Eino-Ville Talvala81314182017-01-30 16:13:45 -08002777
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -08002778 CameraParameters p = state.second->getShimParams();
2779 if (!p.isEmpty()) {
2780 dprintf(fd, " Camera1 API shim is using parameters:\n ");
2781 p.dump(fd, args);
Eino-Ville Talvala81314182017-01-30 16:13:45 -08002782 }
2783
2784 auto clientDescriptor = mActiveClientManager.get(cameraId);
Zhijun He2f140ed2017-02-08 09:57:23 -08002785 if (clientDescriptor != nullptr) {
2786 dprintf(fd, " Device %s is open. Client instance dump:\n",
2787 cameraId.string());
2788 dprintf(fd, " Client priority score: %d state: %d\n",
2789 clientDescriptor->getPriority().getScore(),
2790 clientDescriptor->getPriority().getState());
2791 dprintf(fd, " Client PID: %d\n", clientDescriptor->getOwnerId());
2792
2793 auto client = clientDescriptor->getValue();
2794 dprintf(fd, " Client package: %s\n",
2795 String8(client->getPackageName()).string());
2796
2797 client->dumpClient(fd, args);
2798 } else {
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -08002799 dprintf(fd, " Device %s is closed, no client instance\n",
Eino-Ville Talvala81314182017-01-30 16:13:45 -08002800 cameraId.string());
Eino-Ville Talvala81314182017-01-30 16:13:45 -08002801 }
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -08002802
Eino-Ville Talvala81314182017-01-30 16:13:45 -08002803 }
2804
2805 if (stateLocked) mCameraStatesLock.unlock();
2806
Eino-Ville Talvala81314182017-01-30 16:13:45 -08002807 if (locked) mServiceLock.unlock();
2808
Emilian Peevf53f66e2017-04-11 14:29:43 +01002809 mCameraProviderManager->dump(fd, args);
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -08002810
2811 dprintf(fd, "\n== Vendor tags: ==\n\n");
2812
2813 sp<VendorTagDescriptor> desc = VendorTagDescriptor::getGlobalVendorTagDescriptor();
2814 if (desc == NULL) {
Emilian Peev71c73a22017-03-21 16:35:51 +00002815 sp<VendorTagDescriptorCache> cache =
2816 VendorTagDescriptorCache::getGlobalVendorTagCache();
2817 if (cache == NULL) {
2818 dprintf(fd, "No vendor tags.\n");
2819 } else {
2820 cache->dump(fd, /*verbosity*/2, /*indentation*/2);
2821 }
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -08002822 } else {
2823 desc->dump(fd, /*verbosity*/2, /*indentation*/2);
2824 }
2825
Eino-Ville Talvala81314182017-01-30 16:13:45 -08002826 // Dump camera traces if there were any
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -08002827 dprintf(fd, "\n");
Eino-Ville Talvala81314182017-01-30 16:13:45 -08002828 camera3::CameraTraces::dump(fd, args);
2829
2830 // Process dump arguments, if any
2831 int n = args.size();
2832 String16 verboseOption("-v");
2833 String16 unreachableOption("--unreachable");
2834 for (int i = 0; i < n; i++) {
2835 if (args[i] == verboseOption) {
2836 // change logging level
2837 if (i + 1 >= n) continue;
2838 String8 levelStr(args[i+1]);
2839 int level = atoi(levelStr.string());
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -08002840 dprintf(fd, "\nSetting log level to %d.\n", level);
Eino-Ville Talvala81314182017-01-30 16:13:45 -08002841 setLogLevel(level);
Eino-Ville Talvala81314182017-01-30 16:13:45 -08002842 } else if (args[i] == unreachableOption) {
2843 // Dump memory analysis
2844 // TODO - should limit be an argument parameter?
2845 UnreachableMemoryInfo info;
2846 bool success = GetUnreachableMemory(info, /*limit*/ 10000);
2847 if (!success) {
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -08002848 dprintf(fd, "\n== Unable to dump unreachable memory. "
2849 "Try disabling SELinux enforcement. ==\n");
Eino-Ville Talvala81314182017-01-30 16:13:45 -08002850 } else {
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -08002851 dprintf(fd, "\n== Dumping unreachable memory: ==\n");
Eino-Ville Talvala81314182017-01-30 16:13:45 -08002852 std::string s = info.ToString(/*log_contents*/ true);
2853 write(fd, s.c_str(), s.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07002854 }
2855 }
2856 }
2857 return NO_ERROR;
2858}
2859
Eino-Ville Talvala1527f072015-04-07 15:55:31 -07002860void CameraService::dumpEventLog(int fd) {
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -08002861 dprintf(fd, "\n== Camera service events log (most recent at top): ==\n");
Eino-Ville Talvala1527f072015-04-07 15:55:31 -07002862
2863 Mutex::Autolock l(mLogLock);
2864 for (const auto& msg : mEventLog) {
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -08002865 dprintf(fd, " %s\n", msg.string());
Eino-Ville Talvala1527f072015-04-07 15:55:31 -07002866 }
2867
2868 if (mEventLog.size() == DEFAULT_EVENT_LOG_LENGTH) {
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -08002869 dprintf(fd, " ...\n");
Eino-Ville Talvala1527f072015-04-07 15:55:31 -07002870 } else if (mEventLog.size() == 0) {
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -08002871 dprintf(fd, " [no events yet]\n");
Eino-Ville Talvala1527f072015-04-07 15:55:31 -07002872 }
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -08002873 dprintf(fd, "\n");
Eino-Ville Talvala1527f072015-04-07 15:55:31 -07002874}
2875
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002876void CameraService::handleTorchClientBinderDied(const wp<IBinder> &who) {
Chien-Yu Chen88da5262015-02-17 13:56:46 -08002877 Mutex::Autolock al(mTorchClientMapMutex);
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002878 for (size_t i = 0; i < mTorchClientMap.size(); i++) {
2879 if (mTorchClientMap[i] == who) {
2880 // turn off the torch mode that was turned on by dead client
Chien-Yu Chen88da5262015-02-17 13:56:46 -08002881 String8 cameraId = mTorchClientMap.keyAt(i);
2882 status_t res = mFlashlight->setTorchMode(cameraId, false);
2883 if (res) {
2884 ALOGE("%s: torch client died but couldn't turn off torch: "
2885 "%s (%d)", __FUNCTION__, strerror(-res), res);
2886 return;
2887 }
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002888 mTorchClientMap.removeItemsAt(i);
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002889 break;
2890 }
2891 }
2892}
2893
Ruben Brunkcc776712015-02-17 20:18:47 -08002894/*virtual*/void CameraService::binderDied(const wp<IBinder> &who) {
Igor Murashkinecf17e82012-10-02 16:05:11 -07002895
Igor Murashkin294d0ec2012-10-05 10:44:57 -07002896 /**
Ruben Brunka8ca9152015-04-07 14:23:40 -07002897 * While tempting to promote the wp<IBinder> into a sp, it's actually not supported by the
2898 * binder driver
Igor Murashkin294d0ec2012-10-05 10:44:57 -07002899 */
Yin-Chia Yehdbfcb382018-02-16 11:17:36 -08002900 // PID here is approximate and can be wrong.
Jayant Chowdhary12361932018-08-27 14:46:13 -07002901 logClientDied(CameraThreadState::getCallingPid(), String8("Binder died unexpectedly"));
Ruben Brunka8ca9152015-04-07 14:23:40 -07002902
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002903 // check torch client
2904 handleTorchClientBinderDied(who);
2905
2906 // check camera device client
Ruben Brunkcc776712015-02-17 20:18:47 -08002907 if(!evictClientIdByRemote(who)) {
2908 ALOGV("%s: Java client's binder death already cleaned up (normal case)", __FUNCTION__);
Igor Murashkinecf17e82012-10-02 16:05:11 -07002909 return;
2910 }
2911
Ruben Brunkcc776712015-02-17 20:18:47 -08002912 ALOGE("%s: Java client's binder died, removing it from the list of active clients",
2913 __FUNCTION__);
Igor Murashkinecf17e82012-10-02 16:05:11 -07002914}
2915
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08002916void CameraService::updateStatus(StatusInternal status, const String8& cameraId) {
Ruben Brunkcc776712015-02-17 20:18:47 -08002917 updateStatus(status, cameraId, {});
Igor Murashkinbfc99152013-02-27 12:55:20 -08002918}
2919
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08002920void CameraService::updateStatus(StatusInternal status, const String8& cameraId,
2921 std::initializer_list<StatusInternal> rejectSourceStates) {
Ruben Brunkcc776712015-02-17 20:18:47 -08002922 // Do not lock mServiceLock here or can get into a deadlock from
2923 // connect() -> disconnect -> updateStatus
2924
2925 auto state = getCameraState(cameraId);
2926
2927 if (state == nullptr) {
2928 ALOGW("%s: Could not update the status for %s, no such device exists", __FUNCTION__,
2929 cameraId.string());
2930 return;
Igor Murashkincba2c162013-03-20 15:56:31 -07002931 }
2932
Ruben Brunkcc776712015-02-17 20:18:47 -08002933 // Update the status for this camera state, then send the onStatusChangedCallbacks to each
2934 // of the listeners with both the mStatusStatus and mStatusListenerLock held
2935 state->updateStatus(status, cameraId, rejectSourceStates, [this]
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08002936 (const String8& cameraId, StatusInternal status) {
Ruben Brunkcc776712015-02-17 20:18:47 -08002937
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08002938 if (status != StatusInternal::ENUMERATING) {
Chien-Yu Chenf6463fc2015-04-07 15:11:31 -07002939 // Update torch status if it has a flash unit.
2940 Mutex::Autolock al(mTorchStatusMutex);
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08002941 TorchModeStatus torchStatus;
Chien-Yu Chenf6463fc2015-04-07 15:11:31 -07002942 if (getTorchStatusLocked(cameraId, &torchStatus) !=
2943 NAME_NOT_FOUND) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08002944 TorchModeStatus newTorchStatus =
2945 status == StatusInternal::PRESENT ?
2946 TorchModeStatus::AVAILABLE_OFF :
2947 TorchModeStatus::NOT_AVAILABLE;
Chien-Yu Chenf6463fc2015-04-07 15:11:31 -07002948 if (torchStatus != newTorchStatus) {
2949 onTorchStatusChangedLocked(cameraId, newTorchStatus);
2950 }
2951 }
Ruben Brunkcc776712015-02-17 20:18:47 -08002952 }
2953
2954 Mutex::Autolock lock(mStatusListenerLock);
2955
2956 for (auto& listener : mListenerList) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08002957 listener->onStatusChanged(mapToInterface(status), String16(cameraId));
Ruben Brunkcc776712015-02-17 20:18:47 -08002958 }
2959 });
Igor Murashkincba2c162013-03-20 15:56:31 -07002960}
2961
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08002962template<class Func>
2963void CameraService::CameraState::updateStatus(StatusInternal status,
2964 const String8& cameraId,
2965 std::initializer_list<StatusInternal> rejectSourceStates,
2966 Func onStatusUpdatedLocked) {
2967 Mutex::Autolock lock(mStatusLock);
2968 StatusInternal oldStatus = mStatus;
2969 mStatus = status;
2970
2971 if (oldStatus == status) {
2972 return;
2973 }
2974
2975 ALOGV("%s: Status has changed for camera ID %s from %#x to %#x", __FUNCTION__,
2976 cameraId.string(), oldStatus, status);
2977
2978 if (oldStatus == StatusInternal::NOT_PRESENT &&
2979 (status != StatusInternal::PRESENT &&
2980 status != StatusInternal::ENUMERATING)) {
2981
2982 ALOGW("%s: From NOT_PRESENT can only transition into PRESENT or ENUMERATING",
2983 __FUNCTION__);
2984 mStatus = oldStatus;
2985 return;
2986 }
2987
2988 /**
2989 * Sometimes we want to conditionally do a transition.
2990 * For example if a client disconnects, we want to go to PRESENT
2991 * only if we weren't already in NOT_PRESENT or ENUMERATING.
2992 */
2993 for (auto& rejectStatus : rejectSourceStates) {
2994 if (oldStatus == rejectStatus) {
2995 ALOGV("%s: Rejecting status transition for Camera ID %s, since the source "
2996 "state was was in one of the bad states.", __FUNCTION__, cameraId.string());
2997 mStatus = oldStatus;
2998 return;
2999 }
3000 }
3001
3002 onStatusUpdatedLocked(cameraId, status);
3003}
3004
Eino-Ville Talvalae8c96c72017-06-27 12:24:07 -07003005void CameraService::updateProxyDeviceState(int newState,
Emilian Peev573291c2018-02-10 02:10:56 +00003006 const String8& cameraId, int facing, const String16& clientName, int apiLevel) {
Eino-Ville Talvala412fe562015-08-20 17:08:32 -07003007 sp<ICameraServiceProxy> proxyBinder = getCameraServiceProxy();
3008 if (proxyBinder == nullptr) return;
3009 String16 id(cameraId);
Emilian Peev573291c2018-02-10 02:10:56 +00003010 proxyBinder->notifyCameraState(id, newState, facing, clientName, apiLevel);
Eino-Ville Talvala412fe562015-08-20 17:08:32 -07003011}
3012
Chien-Yu Chen88da5262015-02-17 13:56:46 -08003013status_t CameraService::getTorchStatusLocked(
3014 const String8& cameraId,
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08003015 TorchModeStatus *status) const {
Chien-Yu Chen88da5262015-02-17 13:56:46 -08003016 if (!status) {
3017 return BAD_VALUE;
3018 }
Chien-Yu Chen3068d732015-02-09 13:29:57 -08003019 ssize_t index = mTorchStatusMap.indexOfKey(cameraId);
3020 if (index == NAME_NOT_FOUND) {
Chien-Yu Chen88da5262015-02-17 13:56:46 -08003021 // invalid camera ID or the camera doesn't have a flash unit
3022 return NAME_NOT_FOUND;
Chien-Yu Chen3068d732015-02-09 13:29:57 -08003023 }
3024
Chien-Yu Chen88da5262015-02-17 13:56:46 -08003025 *status = mTorchStatusMap.valueAt(index);
3026 return OK;
Chien-Yu Chen3068d732015-02-09 13:29:57 -08003027}
3028
Chien-Yu Chen88da5262015-02-17 13:56:46 -08003029status_t CameraService::setTorchStatusLocked(const String8& cameraId,
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08003030 TorchModeStatus status) {
Chien-Yu Chen3068d732015-02-09 13:29:57 -08003031 ssize_t index = mTorchStatusMap.indexOfKey(cameraId);
3032 if (index == NAME_NOT_FOUND) {
3033 return BAD_VALUE;
3034 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -08003035 mTorchStatusMap.editValueAt(index) = status;
Chien-Yu Chen3068d732015-02-09 13:29:57 -08003036
3037 return OK;
3038}
3039
Svet Ganova453d0d2018-01-11 15:37:58 -08003040void CameraService::blockClientsForUid(uid_t uid) {
3041 const auto clients = mActiveClientManager.getAll();
3042 for (auto& current : clients) {
3043 if (current != nullptr) {
3044 const auto basicClient = current->getValue();
3045 if (basicClient.get() != nullptr && basicClient->getClientUid() == uid) {
3046 basicClient->block();
3047 }
3048 }
3049 }
3050}
3051
3052// NOTE: This is a remote API - make sure all args are validated
3053status_t CameraService::shellCommand(int in, int out, int err, const Vector<String16>& args) {
3054 if (!checkCallingPermission(sManageCameraPermission, nullptr, nullptr)) {
3055 return PERMISSION_DENIED;
3056 }
3057 if (in == BAD_TYPE || out == BAD_TYPE || err == BAD_TYPE) {
3058 return BAD_VALUE;
3059 }
3060 if (args.size() == 3 && args[0] == String16("set-uid-state")) {
3061 return handleSetUidState(args, err);
3062 } else if (args.size() == 2 && args[0] == String16("reset-uid-state")) {
3063 return handleResetUidState(args, err);
3064 } else if (args.size() == 2 && args[0] == String16("get-uid-state")) {
3065 return handleGetUidState(args, out, err);
3066 } else if (args.size() == 1 && args[0] == String16("help")) {
3067 printHelp(out);
3068 return NO_ERROR;
3069 }
3070 printHelp(err);
3071 return BAD_VALUE;
3072}
3073
3074status_t CameraService::handleSetUidState(const Vector<String16>& args, int err) {
3075 PermissionController pc;
3076 int uid = pc.getPackageUid(args[1], 0);
3077 if (uid <= 0) {
3078 ALOGE("Unknown package: '%s'", String8(args[1]).string());
3079 dprintf(err, "Unknown package: '%s'\n", String8(args[1]).string());
3080 return BAD_VALUE;
3081 }
3082 bool active = false;
3083 if (args[2] == String16("active")) {
3084 active = true;
3085 } else if ((args[2] != String16("idle"))) {
3086 ALOGE("Expected active or idle but got: '%s'", String8(args[2]).string());
3087 return BAD_VALUE;
3088 }
Svet Ganov7b4ab782018-03-25 12:48:10 -07003089 mUidPolicy->addOverrideUid(uid, args[1], active);
Svet Ganova453d0d2018-01-11 15:37:58 -08003090 return NO_ERROR;
3091}
3092
3093status_t CameraService::handleResetUidState(const Vector<String16>& args, int err) {
3094 PermissionController pc;
3095 int uid = pc.getPackageUid(args[1], 0);
3096 if (uid < 0) {
3097 ALOGE("Unknown package: '%s'", String8(args[1]).string());
3098 dprintf(err, "Unknown package: '%s'\n", String8(args[1]).string());
3099 return BAD_VALUE;
3100 }
Svet Ganov7b4ab782018-03-25 12:48:10 -07003101 mUidPolicy->removeOverrideUid(uid, args[1]);
Svet Ganova453d0d2018-01-11 15:37:58 -08003102 return NO_ERROR;
3103}
3104
3105status_t CameraService::handleGetUidState(const Vector<String16>& args, int out, int err) {
3106 PermissionController pc;
3107 int uid = pc.getPackageUid(args[1], 0);
3108 if (uid <= 0) {
3109 ALOGE("Unknown package: '%s'", String8(args[1]).string());
3110 dprintf(err, "Unknown package: '%s'\n", String8(args[1]).string());
3111 return BAD_VALUE;
3112 }
Svet Ganov7b4ab782018-03-25 12:48:10 -07003113 if (mUidPolicy->isUidActive(uid, args[1])) {
Svet Ganova453d0d2018-01-11 15:37:58 -08003114 return dprintf(out, "active\n");
3115 } else {
3116 return dprintf(out, "idle\n");
3117 }
3118}
3119
3120status_t CameraService::printHelp(int out) {
3121 return dprintf(out, "Camera service commands:\n"
3122 " get-uid-state <PACKAGE> gets the uid state\n"
3123 " set-uid-state <PACKAGE> <active|idle> overrides the uid state\n"
3124 " reset-uid-state <PACKAGE> clears the uid state override\n"
3125 " help print this message\n");
3126}
3127
Mathias Agopian65ab4712010-07-14 17:59:35 -07003128}; // namespace android