blob: 86c48a4c53cd6433c6216b90297ceadb14654380 [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 Talvalaceb388d2013-02-19 10:40:14 -080035#include <binder/AppOpsManager.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070036#include <binder/IPCThreadState.h>
37#include <binder/IServiceManager.h>
38#include <binder/MemoryBase.h>
39#include <binder/MemoryHeapBase.h>
Ruben Brunkcc776712015-02-17 20:18:47 -080040#include <binder/ProcessInfoService.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070041#include <cutils/atomic.h>
Nipun Kwatrab5ca4612010-09-11 19:31:10 -070042#include <cutils/properties.h>
Mathias Agopiandf712ea2012-02-25 18:48:35 -080043#include <gui/Surface.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070044#include <hardware/hardware.h>
Eino-Ville Talvalad89821e2016-04-20 11:23:50 -070045#include <memunreachable/memunreachable.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070046#include <media/AudioSystem.h>
Andreas Huber1b86fe02014-01-29 11:13:26 -080047#include <media/IMediaHTTPService.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070048#include <media/mediaplayer.h>
Ruben Brunk99e69712015-05-26 17:25:07 -070049#include <mediautils/BatteryNotifier.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070050#include <utils/Errors.h>
51#include <utils/Log.h>
52#include <utils/String16.h>
Ruben Brunkd1176ef2014-02-21 10:51:38 -080053#include <utils/Trace.h>
Chien-Yu Chen98a668f2015-12-18 14:10:33 -080054#include <private/android_filesystem_config.h>
Ruben Brunkd1176ef2014-02-21 10:51:38 -080055#include <system/camera_vendor_tags.h>
Ruben Brunkb2119af2014-05-09 19:57:56 -070056#include <system/camera_metadata.h>
57#include <system/camera.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070058
59#include "CameraService.h"
Eino-Ville Talvala7b82efe2013-07-25 17:12:35 -070060#include "api1/CameraClient.h"
61#include "api1/Camera2Client.h"
Eino-Ville Talvala7b82efe2013-07-25 17:12:35 -070062#include "api2/CameraDeviceClient.h"
Igor Murashkinff3e31d2013-10-23 16:40:06 -070063#include "utils/CameraTraces.h"
Mathias Agopian65ab4712010-07-14 17:59:35 -070064
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080065namespace {
66 const char* kPermissionServiceName = "permission";
67}; // namespace anonymous
68
Mathias Agopian65ab4712010-07-14 17:59:35 -070069namespace android {
70
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080071using binder::Status;
72using namespace hardware;
73
Mathias Agopian65ab4712010-07-14 17:59:35 -070074// ----------------------------------------------------------------------------
75// Logging support -- this is for debugging only
76// Use "adb shell dumpsys media.camera -v 1" to change it.
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -070077volatile int32_t gLogLevel = 0;
Mathias Agopian65ab4712010-07-14 17:59:35 -070078
Steve Blockb8a80522011-12-20 16:23:08 +000079#define LOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__);
80#define LOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__);
Mathias Agopian65ab4712010-07-14 17:59:35 -070081
82static void setLogLevel(int level) {
83 android_atomic_write(level, &gLogLevel);
84}
85
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080086// Convenience methods for constructing binder::Status objects for error returns
87
88#define STATUS_ERROR(errorCode, errorString) \
89 binder::Status::fromServiceSpecificError(errorCode, \
90 String8::format("%s:%d: %s", __FUNCTION__, __LINE__, errorString))
91
92#define STATUS_ERROR_FMT(errorCode, errorString, ...) \
93 binder::Status::fromServiceSpecificError(errorCode, \
94 String8::format("%s:%d: " errorString, __FUNCTION__, __LINE__, \
95 __VA_ARGS__))
96
Mathias Agopian65ab4712010-07-14 17:59:35 -070097// ----------------------------------------------------------------------------
98
Igor Murashkincba2c162013-03-20 15:56:31 -070099extern "C" {
100static void camera_device_status_change(
101 const struct camera_module_callbacks* callbacks,
102 int camera_id,
103 int new_status) {
104 sp<CameraService> cs = const_cast<CameraService*>(
Ruben Brunkcc776712015-02-17 20:18:47 -0800105 static_cast<const CameraService*>(callbacks));
Igor Murashkincba2c162013-03-20 15:56:31 -0700106
Bin Chene16d1162016-02-22 18:19:58 +1100107 cs->onDeviceStatusChanged(camera_id,
Ruben Brunkcc776712015-02-17 20:18:47 -0800108 static_cast<camera_device_status_t>(new_status));
Igor Murashkincba2c162013-03-20 15:56:31 -0700109}
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800110
111static void torch_mode_status_change(
112 const struct camera_module_callbacks* callbacks,
113 const char* camera_id,
114 int new_status) {
115 if (!callbacks || !camera_id) {
116 ALOGE("%s invalid parameters. callbacks %p, camera_id %p", __FUNCTION__,
117 callbacks, camera_id);
118 }
119 sp<CameraService> cs = const_cast<CameraService*>(
120 static_cast<const CameraService*>(callbacks));
121
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800122 int32_t status;
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800123 switch (new_status) {
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800124 case TORCH_MODE_STATUS_NOT_AVAILABLE:
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800125 status = ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE;
126 break;
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800127 case TORCH_MODE_STATUS_AVAILABLE_OFF:
128 status = ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF;
129 break;
130 case TORCH_MODE_STATUS_AVAILABLE_ON:
131 status = ICameraServiceListener::TORCH_STATUS_AVAILABLE_ON;
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800132 break;
133 default:
134 ALOGE("Unknown torch status %d", new_status);
135 return;
136 }
137
138 cs->onTorchStatusChanged(
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800139 String8(camera_id),
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800140 status);
141}
Igor Murashkincba2c162013-03-20 15:56:31 -0700142} // extern "C"
143
Mathias Agopian65ab4712010-07-14 17:59:35 -0700144// ----------------------------------------------------------------------------
145
146// This is ugly and only safe if we never re-create the CameraService, but
147// should be ok for now.
148static CameraService *gCameraService;
149
Eino-Ville Talvala49c97052016-01-12 14:29:40 -0800150CameraService::CameraService() :
151 mEventLog(DEFAULT_EVENT_LOG_LENGTH),
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800152 mNumberOfCameras(0), mNumberOfNormalCameras(0),
153 mSoundRef(0), mModule(nullptr) {
Steve Blockdf64d152012-01-04 20:05:49 +0000154 ALOGI("CameraService started (pid=%d)", getpid());
Mathias Agopian65ab4712010-07-14 17:59:35 -0700155 gCameraService = this;
Igor Murashkinbfc99152013-02-27 12:55:20 -0800156
Igor Murashkincba2c162013-03-20 15:56:31 -0700157 this->camera_device_status_change = android::camera_device_status_change;
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800158 this->torch_mode_status_change = android::torch_mode_status_change;
159
Ruben Brunkcc776712015-02-17 20:18:47 -0800160 mServiceLockWrapper = std::make_shared<WaitableMutexWrapper>(&mServiceLock);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700161}
162
Iliyan Malchev8951a972011-04-14 16:55:59 -0700163void CameraService::onFirstRef()
164{
Ruben Brunkcc776712015-02-17 20:18:47 -0800165 ALOGI("CameraService process starting");
Igor Murashkin634a5152013-02-20 17:15:11 -0800166
Iliyan Malchev8951a972011-04-14 16:55:59 -0700167 BnCameraService::onFirstRef();
168
Ruben Brunk99e69712015-05-26 17:25:07 -0700169 // Update battery life tracking if service is restarting
170 BatteryNotifier& notifier(BatteryNotifier::getInstance());
171 notifier.noteResetCamera();
172 notifier.noteResetFlashlight();
173
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800174 camera_module_t *rawModule;
Eino-Ville Talvala1527f072015-04-07 15:55:31 -0700175 int err = hw_get_module(CAMERA_HARDWARE_MODULE_ID,
176 (const hw_module_t **)&rawModule);
177 if (err < 0) {
178 ALOGE("Could not load camera HAL module: %d (%s)", err, strerror(-err));
179 logServiceError("Could not load camera HAL module", err);
Eino-Ville Talvala1527f072015-04-07 15:55:31 -0700180 return;
Iliyan Malchev8951a972011-04-14 16:55:59 -0700181 }
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800182
Eino-Ville Talvala1527f072015-04-07 15:55:31 -0700183 mModule = new CameraModule(rawModule);
Eino-Ville Talvala1527f072015-04-07 15:55:31 -0700184 err = mModule->init();
185 if (err != OK) {
186 ALOGE("Could not initialize camera HAL module: %d (%s)", err,
187 strerror(-err));
188 logServiceError("Could not initialize camera HAL module", err);
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800189
Eino-Ville Talvala1527f072015-04-07 15:55:31 -0700190 delete mModule;
191 mModule = nullptr;
192 return;
Iliyan Malchev8951a972011-04-14 16:55:59 -0700193 }
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -0700194 ALOGI("Loaded \"%s\" camera module", mModule->getModuleName());
Eino-Ville Talvala1527f072015-04-07 15:55:31 -0700195
196 mNumberOfCameras = mModule->getNumberOfCameras();
Eino-Ville Talvalabad43582015-08-14 13:12:32 -0700197 mNumberOfNormalCameras = mNumberOfCameras;
Eino-Ville Talvala1527f072015-04-07 15:55:31 -0700198
Yin-Chia Yehd4a653a2015-10-14 11:05:44 -0700199 // Setup vendor tags before we call get_camera_info the first time
200 // because HAL might need to setup static vendor keys in get_camera_info
201 VendorTagDescriptor::clearGlobalVendorTagDescriptor();
202 if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_2) {
203 setUpVendorTags();
204 }
205
Eino-Ville Talvala1527f072015-04-07 15:55:31 -0700206 mFlashlight = new CameraFlashlight(*mModule, *this);
207 status_t res = mFlashlight->findFlashUnits();
208 if (res) {
209 // impossible because we haven't open any camera devices.
210 ALOGE("Failed to find flash units.");
211 }
212
Eino-Ville Talvalabad43582015-08-14 13:12:32 -0700213 int latestStrangeCameraId = INT_MAX;
Eino-Ville Talvala1527f072015-04-07 15:55:31 -0700214 for (int i = 0; i < mNumberOfCameras; i++) {
215 String8 cameraId = String8::format("%d", i);
216
Eino-Ville Talvalabad43582015-08-14 13:12:32 -0700217 // Get camera info
218
219 struct camera_info info;
220 bool haveInfo = true;
221 status_t rc = mModule->getCameraInfo(i, &info);
222 if (rc != NO_ERROR) {
223 ALOGE("%s: Received error loading camera info for device %d, cost and"
224 " conflicting devices fields set to defaults for this device.",
225 __FUNCTION__, i);
226 haveInfo = false;
227 }
228
229 // Check for backwards-compatibility support
230 if (haveInfo) {
231 if (checkCameraCapabilities(i, info, &latestStrangeCameraId) != OK) {
232 delete mModule;
233 mModule = nullptr;
234 return;
235 }
236 }
237
Eino-Ville Talvala1527f072015-04-07 15:55:31 -0700238 // Defaults to use for cost and conflicting devices
239 int cost = 100;
240 char** conflicting_devices = nullptr;
241 size_t conflicting_devices_length = 0;
242
243 // If using post-2.4 module version, query the cost + conflicting devices from the HAL
Eino-Ville Talvalabad43582015-08-14 13:12:32 -0700244 if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_4 && haveInfo) {
245 cost = info.resource_cost;
246 conflicting_devices = info.conflicting_devices;
247 conflicting_devices_length = info.conflicting_devices_length;
Eino-Ville Talvala1527f072015-04-07 15:55:31 -0700248 }
249
250 std::set<String8> conflicting;
251 for (size_t i = 0; i < conflicting_devices_length; i++) {
252 conflicting.emplace(String8(conflicting_devices[i]));
253 }
254
255 // Initialize state for each camera device
256 {
257 Mutex::Autolock lock(mCameraStatesLock);
258 mCameraStates.emplace(cameraId, std::make_shared<CameraState>(cameraId, cost,
259 conflicting));
260 }
261
262 if (mFlashlight->hasFlashUnit(cameraId)) {
263 mTorchStatusMap.add(cameraId,
264 ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF);
265 }
266 }
267
268 if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_1) {
269 mModule->setCallbacks(this);
270 }
271
Ruben Brunk2823ce02015-05-19 17:25:13 -0700272 CameraService::pingCameraServiceProxy();
273}
274
Eino-Ville Talvala412fe562015-08-20 17:08:32 -0700275sp<ICameraServiceProxy> CameraService::getCameraServiceProxy() {
Christopher Wiley92c06fc2016-02-11 15:40:05 -0800276 sp<ICameraServiceProxy> proxyBinder = nullptr;
277#ifndef __BRILLO__
Ruben Brunk2823ce02015-05-19 17:25:13 -0700278 sp<IServiceManager> sm = defaultServiceManager();
Eino-Ville Talvalaf4db13d2016-12-08 11:20:51 -0800279 // Use checkService because cameraserver normally starts before the
280 // system server and the proxy service. So the long timeout that getService
281 // has before giving up is inappropriate.
282 sp<IBinder> binder = sm->checkService(String16("media.camera.proxy"));
Christopher Wiley92c06fc2016-02-11 15:40:05 -0800283 if (binder != nullptr) {
284 proxyBinder = interface_cast<ICameraServiceProxy>(binder);
Ruben Brunk2823ce02015-05-19 17:25:13 -0700285 }
Christopher Wiley92c06fc2016-02-11 15:40:05 -0800286#endif
Eino-Ville Talvala412fe562015-08-20 17:08:32 -0700287 return proxyBinder;
288}
289
290void CameraService::pingCameraServiceProxy() {
291 sp<ICameraServiceProxy> proxyBinder = getCameraServiceProxy();
292 if (proxyBinder == nullptr) return;
Ruben Brunk2823ce02015-05-19 17:25:13 -0700293 proxyBinder->pingForUserUpdate();
Iliyan Malchev8951a972011-04-14 16:55:59 -0700294}
295
Mathias Agopian65ab4712010-07-14 17:59:35 -0700296CameraService::~CameraService() {
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800297 if (mModule) {
298 delete mModule;
Ruben Brunkcc776712015-02-17 20:18:47 -0800299 mModule = nullptr;
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800300 }
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800301 VendorTagDescriptor::clearGlobalVendorTagDescriptor();
Ruben Brunkcc776712015-02-17 20:18:47 -0800302 gCameraService = nullptr;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700303}
304
Bin Chene16d1162016-02-22 18:19:58 +1100305void CameraService::onDeviceStatusChanged(int cameraId,
Ruben Brunkcc776712015-02-17 20:18:47 -0800306 camera_device_status_t newStatus) {
307 ALOGI("%s: Status changed for cameraId=%d, newStatus=%d", __FUNCTION__,
Igor Murashkincba2c162013-03-20 15:56:31 -0700308 cameraId, newStatus);
309
Ruben Brunkcc776712015-02-17 20:18:47 -0800310 String8 id = String8::format("%d", cameraId);
311 std::shared_ptr<CameraState> state = getCameraState(id);
312
313 if (state == nullptr) {
Igor Murashkincba2c162013-03-20 15:56:31 -0700314 ALOGE("%s: Bad camera ID %d", __FUNCTION__, cameraId);
315 return;
316 }
317
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800318 int32_t oldStatus = state->getStatus();
Ruben Brunkcc776712015-02-17 20:18:47 -0800319
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800320 if (oldStatus == static_cast<int32_t>(newStatus)) {
Ruben Brunkcc776712015-02-17 20:18:47 -0800321 ALOGE("%s: State transition to the same status %#x not allowed", __FUNCTION__, newStatus);
Igor Murashkincba2c162013-03-20 15:56:31 -0700322 return;
323 }
324
Igor Murashkincba2c162013-03-20 15:56:31 -0700325 if (newStatus == CAMERA_DEVICE_STATUS_NOT_PRESENT) {
Ruben Brunka8ca9152015-04-07 14:23:40 -0700326 logDeviceRemoved(id, String8::format("Device status changed from %d to %d", oldStatus,
327 newStatus));
Ruben Brunkcc776712015-02-17 20:18:47 -0800328 sp<BasicClient> clientToDisconnect;
Igor Murashkincba2c162013-03-20 15:56:31 -0700329 {
Ruben Brunkcc776712015-02-17 20:18:47 -0800330 // Don't do this in updateStatus to avoid deadlock over mServiceLock
331 Mutex::Autolock lock(mServiceLock);
Igor Murashkincba2c162013-03-20 15:56:31 -0700332
Ruben Brunkcc776712015-02-17 20:18:47 -0800333 // Set the device status to NOT_PRESENT, clients will no longer be able to connect
334 // to this device until the status changes
335 updateStatus(ICameraServiceListener::STATUS_NOT_PRESENT, id);
Ruben Brunkb2119af2014-05-09 19:57:56 -0700336
Ruben Brunkcc776712015-02-17 20:18:47 -0800337 // Remove cached shim parameters
338 state->setShimParams(CameraParameters());
Igor Murashkincba2c162013-03-20 15:56:31 -0700339
Ruben Brunkcc776712015-02-17 20:18:47 -0800340 // Remove the client from the list of active clients
341 clientToDisconnect = removeClientLocked(id);
342
343 // Notify the client of disconnection
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800344 clientToDisconnect->notifyError(
345 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED,
Ruben Brunkcc776712015-02-17 20:18:47 -0800346 CaptureResultExtras{});
Igor Murashkincba2c162013-03-20 15:56:31 -0700347 }
348
Ruben Brunkcc776712015-02-17 20:18:47 -0800349 ALOGI("%s: Client for camera ID %s evicted due to device status change from HAL",
350 __FUNCTION__, id.string());
Igor Murashkincba2c162013-03-20 15:56:31 -0700351
Ruben Brunkcc776712015-02-17 20:18:47 -0800352 // Disconnect client
353 if (clientToDisconnect.get() != nullptr) {
354 // Ensure not in binder RPC so client disconnect PID checks work correctly
355 LOG_ALWAYS_FATAL_IF(getCallingPid() != getpid(),
356 "onDeviceStatusChanged must be called from the camera service process!");
357 clientToDisconnect->disconnect();
Igor Murashkincba2c162013-03-20 15:56:31 -0700358 }
359
Ruben Brunkcc776712015-02-17 20:18:47 -0800360 } else {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800361 if (oldStatus == ICameraServiceListener::STATUS_NOT_PRESENT) {
Ruben Brunka8ca9152015-04-07 14:23:40 -0700362 logDeviceAdded(id, String8::format("Device status changed from %d to %d", oldStatus,
363 newStatus));
364 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800365 updateStatus(static_cast<int32_t>(newStatus), id);
Igor Murashkincba2c162013-03-20 15:56:31 -0700366 }
367
Igor Murashkincba2c162013-03-20 15:56:31 -0700368}
369
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800370void CameraService::onTorchStatusChanged(const String8& cameraId,
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800371 int32_t newStatus) {
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800372 Mutex::Autolock al(mTorchStatusMutex);
373 onTorchStatusChangedLocked(cameraId, newStatus);
374}
375
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800376void CameraService::onTorchStatusChangedLocked(const String8& cameraId,
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800377 int32_t newStatus) {
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800378 ALOGI("%s: Torch status changed for cameraId=%s, newStatus=%d",
379 __FUNCTION__, cameraId.string(), newStatus);
380
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800381 int32_t status;
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800382 status_t res = getTorchStatusLocked(cameraId, &status);
383 if (res) {
Chien-Yu Chenf6463fc2015-04-07 15:11:31 -0700384 ALOGE("%s: cannot get torch status of camera %s: %s (%d)",
385 __FUNCTION__, cameraId.string(), strerror(-res), res);
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800386 return;
387 }
388 if (status == newStatus) {
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800389 return;
390 }
391
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800392 res = setTorchStatusLocked(cameraId, newStatus);
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800393 if (res) {
Eino-Ville Talvalad309fb92015-11-25 12:12:45 -0800394 ALOGE("%s: Failed to set the torch status to %d: %s (%d)", __FUNCTION__,
395 (uint32_t)newStatus, strerror(-res), res);
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800396 return;
397 }
398
Ruben Brunkcc776712015-02-17 20:18:47 -0800399 {
Ruben Brunk99e69712015-05-26 17:25:07 -0700400 // Update battery life logging for flashlight
Chien-Yu Chenfe751be2015-09-01 14:16:44 -0700401 Mutex::Autolock al(mTorchUidMapMutex);
Ruben Brunk99e69712015-05-26 17:25:07 -0700402 auto iter = mTorchUidMap.find(cameraId);
403 if (iter != mTorchUidMap.end()) {
404 int oldUid = iter->second.second;
405 int newUid = iter->second.first;
406 BatteryNotifier& notifier(BatteryNotifier::getInstance());
407 if (oldUid != newUid) {
408 // If the UID has changed, log the status and update current UID in mTorchUidMap
409 if (status == ICameraServiceListener::TORCH_STATUS_AVAILABLE_ON) {
410 notifier.noteFlashlightOff(cameraId, oldUid);
411 }
412 if (newStatus == ICameraServiceListener::TORCH_STATUS_AVAILABLE_ON) {
413 notifier.noteFlashlightOn(cameraId, newUid);
414 }
415 iter->second.second = newUid;
416 } else {
417 // If the UID has not changed, log the status
418 if (newStatus == ICameraServiceListener::TORCH_STATUS_AVAILABLE_ON) {
419 notifier.noteFlashlightOn(cameraId, oldUid);
420 } else {
421 notifier.noteFlashlightOff(cameraId, oldUid);
422 }
423 }
424 }
425 }
426
427 {
Ruben Brunkcc776712015-02-17 20:18:47 -0800428 Mutex::Autolock lock(mStatusListenerLock);
429 for (auto& i : mListenerList) {
430 i->onTorchStatusChanged(newStatus, String16{cameraId});
431 }
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800432 }
433}
434
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800435Status CameraService::getNumberOfCameras(int32_t type, int32_t* numCameras) {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -0700436 ATRACE_CALL();
Eino-Ville Talvalabad43582015-08-14 13:12:32 -0700437 switch (type) {
438 case CAMERA_TYPE_BACKWARD_COMPATIBLE:
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800439 *numCameras = mNumberOfNormalCameras;
440 break;
Eino-Ville Talvalabad43582015-08-14 13:12:32 -0700441 case CAMERA_TYPE_ALL:
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800442 *numCameras = mNumberOfCameras;
443 break;
Eino-Ville Talvalabad43582015-08-14 13:12:32 -0700444 default:
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800445 ALOGW("%s: Unknown camera type %d",
Eino-Ville Talvalabad43582015-08-14 13:12:32 -0700446 __FUNCTION__, type);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800447 return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
448 "Unknown camera type %d", type);
Eino-Ville Talvalabad43582015-08-14 13:12:32 -0700449 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800450 return Status::ok();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700451}
452
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800453Status CameraService::getCameraInfo(int cameraId,
454 CameraInfo* cameraInfo) {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -0700455 ATRACE_CALL();
Iliyan Malchev8951a972011-04-14 16:55:59 -0700456 if (!mModule) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800457 return STATUS_ERROR(ERROR_DISCONNECTED,
458 "Camera subsystem is not available");
Iliyan Malchev8951a972011-04-14 16:55:59 -0700459 }
460
Mathias Agopian65ab4712010-07-14 17:59:35 -0700461 if (cameraId < 0 || cameraId >= mNumberOfCameras) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800462 return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT,
463 "CameraId is not valid");
Mathias Agopian65ab4712010-07-14 17:59:35 -0700464 }
465
Iliyan Malchev8951a972011-04-14 16:55:59 -0700466 struct camera_info info;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800467 Status rc = filterGetInfoErrorCode(
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800468 mModule->getCameraInfo(cameraId, &info));
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800469
470 if (rc.isOk()) {
471 cameraInfo->facing = info.facing;
472 cameraInfo->orientation = info.orientation;
Yin-Chia Yeh9b5a6e92016-04-22 13:24:05 -0700473 // CameraInfo is for android.hardware.Camera which does not
474 // support external camera facing. The closest approximation would be
475 // front camera.
Yin-Chia Yeh13cd59a2016-11-29 12:13:15 -0800476 if (cameraInfo->facing == CAMERA_FACING_EXTERNAL) {
477 cameraInfo->facing = CAMERA_FACING_FRONT;
Yin-Chia Yeh9b5a6e92016-04-22 13:24:05 -0700478 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800479 }
Iliyan Malchev8951a972011-04-14 16:55:59 -0700480 return rc;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700481}
482
Ruben Brunkcc776712015-02-17 20:18:47 -0800483int CameraService::cameraIdToInt(const String8& cameraId) {
484 errno = 0;
485 size_t pos = 0;
486 int ret = stoi(std::string{cameraId.string()}, &pos);
487 if (errno != 0 || pos != cameraId.size()) {
488 return -1;
489 }
490 return ret;
491}
Ruben Brunkb2119af2014-05-09 19:57:56 -0700492
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800493Status CameraService::generateShimMetadata(int cameraId, /*out*/CameraMetadata* cameraInfo) {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -0700494 ATRACE_CALL();
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800495
496 Status ret = Status::ok();
497
Ruben Brunkb2119af2014-05-09 19:57:56 -0700498 struct CameraInfo info;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800499 if (!(ret = getCameraInfo(cameraId, &info)).isOk()) {
Ruben Brunkb2119af2014-05-09 19:57:56 -0700500 return ret;
501 }
502
503 CameraMetadata shimInfo;
504 int32_t orientation = static_cast<int32_t>(info.orientation);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800505 status_t rc;
506 if ((rc = shimInfo.update(ANDROID_SENSOR_ORIENTATION, &orientation, 1)) != OK) {
507 return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
508 "Error updating metadata: %d (%s)", rc, strerror(-rc));
Ruben Brunkb2119af2014-05-09 19:57:56 -0700509 }
510
511 uint8_t facing = (info.facing == CAMERA_FACING_FRONT) ?
512 ANDROID_LENS_FACING_FRONT : ANDROID_LENS_FACING_BACK;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800513 if ((rc = shimInfo.update(ANDROID_LENS_FACING, &facing, 1)) != OK) {
514 return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
515 "Error updating metadata: %d (%s)", rc, strerror(-rc));
Ruben Brunkb2119af2014-05-09 19:57:56 -0700516 }
517
Igor Murashkin65d14b92014-06-17 12:03:20 -0700518 CameraParameters shimParams;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800519 if (!(ret = getLegacyParametersLazy(cameraId, /*out*/&shimParams)).isOk()) {
Igor Murashkin65d14b92014-06-17 12:03:20 -0700520 // Error logged by callee
521 return ret;
Ruben Brunkb2119af2014-05-09 19:57:56 -0700522 }
523
524 Vector<Size> sizes;
Ruben Brunk152dbcf2014-06-12 19:11:45 -0700525 Vector<Size> jpegSizes;
Ruben Brunkb2119af2014-05-09 19:57:56 -0700526 Vector<int32_t> formats;
Igor Murashkin65d14b92014-06-17 12:03:20 -0700527 {
528 shimParams.getSupportedPreviewSizes(/*out*/sizes);
529 shimParams.getSupportedPreviewFormats(/*out*/formats);
530 shimParams.getSupportedPictureSizes(/*out*/jpegSizes);
Ruben Brunkb2119af2014-05-09 19:57:56 -0700531 }
532
533 // Always include IMPLEMENTATION_DEFINED
534 formats.add(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED);
535
536 const size_t INTS_PER_CONFIG = 4;
537
538 // Build available stream configurations metadata
Ruben Brunk152dbcf2014-06-12 19:11:45 -0700539 size_t streamConfigSize = (sizes.size() * formats.size() + jpegSizes.size()) * INTS_PER_CONFIG;
540
541 Vector<int32_t> streamConfigs;
542 streamConfigs.setCapacity(streamConfigSize);
543
Ruben Brunkb2119af2014-05-09 19:57:56 -0700544 for (size_t i = 0; i < formats.size(); ++i) {
545 for (size_t j = 0; j < sizes.size(); ++j) {
Ruben Brunk152dbcf2014-06-12 19:11:45 -0700546 streamConfigs.add(formats[i]);
547 streamConfigs.add(sizes[j].width);
548 streamConfigs.add(sizes[j].height);
549 streamConfigs.add(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
Ruben Brunkb2119af2014-05-09 19:57:56 -0700550 }
551 }
552
Ruben Brunk152dbcf2014-06-12 19:11:45 -0700553 for (size_t i = 0; i < jpegSizes.size(); ++i) {
554 streamConfigs.add(HAL_PIXEL_FORMAT_BLOB);
555 streamConfigs.add(jpegSizes[i].width);
556 streamConfigs.add(jpegSizes[i].height);
557 streamConfigs.add(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
558 }
559
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800560 if ((rc = shimInfo.update(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
Ruben Brunk152dbcf2014-06-12 19:11:45 -0700561 streamConfigs.array(), streamConfigSize)) != OK) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800562 return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
563 "Error updating metadata: %d (%s)", rc, strerror(-rc));
Ruben Brunkb2119af2014-05-09 19:57:56 -0700564 }
565
566 int64_t fakeMinFrames[0];
567 // TODO: Fixme, don't fake min frame durations.
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800568 if ((rc = shimInfo.update(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
Ruben Brunkb2119af2014-05-09 19:57:56 -0700569 fakeMinFrames, 0)) != OK) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800570 return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
571 "Error updating metadata: %d (%s)", rc, strerror(-rc));
Ruben Brunkb2119af2014-05-09 19:57:56 -0700572 }
573
574 int64_t fakeStalls[0];
575 // TODO: Fixme, don't fake stall durations.
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800576 if ((rc = shimInfo.update(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
Ruben Brunkb2119af2014-05-09 19:57:56 -0700577 fakeStalls, 0)) != OK) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800578 return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
579 "Error updating metadata: %d (%s)", rc, strerror(-rc));
Ruben Brunkb2119af2014-05-09 19:57:56 -0700580 }
581
582 *cameraInfo = shimInfo;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800583 return ret;
Ruben Brunkb2119af2014-05-09 19:57:56 -0700584}
585
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800586Status CameraService::getCameraCharacteristics(int cameraId,
Zhijun He2b59be82013-09-25 10:14:30 -0700587 CameraMetadata* cameraInfo) {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -0700588 ATRACE_CALL();
Zhijun He2b59be82013-09-25 10:14:30 -0700589 if (!cameraInfo) {
590 ALOGE("%s: cameraInfo is NULL", __FUNCTION__);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800591 return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "cameraInfo is NULL");
Zhijun He2b59be82013-09-25 10:14:30 -0700592 }
593
594 if (!mModule) {
595 ALOGE("%s: camera hardware module doesn't exist", __FUNCTION__);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800596 return STATUS_ERROR(ERROR_DISCONNECTED,
597 "Camera subsystem is not available");;
Zhijun He2b59be82013-09-25 10:14:30 -0700598 }
599
Zhijun He2b59be82013-09-25 10:14:30 -0700600 if (cameraId < 0 || cameraId >= mNumberOfCameras) {
601 ALOGE("%s: Invalid camera id: %d", __FUNCTION__, cameraId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800602 return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
603 "Invalid camera id: %d", cameraId);
Zhijun He2b59be82013-09-25 10:14:30 -0700604 }
605
606 int facing;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800607 Status ret;
Chien-Yu Chen676b21b2015-02-24 10:28:19 -0800608 if (mModule->getModuleApiVersion() < CAMERA_MODULE_API_VERSION_2_0 ||
Eino-Ville Talvalad309fb92015-11-25 12:12:45 -0800609 getDeviceVersion(cameraId, &facing) < CAMERA_DEVICE_API_VERSION_3_0) {
Ruben Brunkb2119af2014-05-09 19:57:56 -0700610 /**
611 * Backwards compatibility mode for old HALs:
612 * - Convert CameraInfo into static CameraMetadata properties.
613 * - Retrieve cached CameraParameters for this camera. If none exist,
614 * attempt to open CameraClient and retrieve the CameraParameters.
615 * - Convert cached CameraParameters into static CameraMetadata
616 * properties.
617 */
618 ALOGI("%s: Switching to HAL1 shim implementation...", __FUNCTION__);
Zhijun He2b59be82013-09-25 10:14:30 -0700619
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800620 ret = generateShimMetadata(cameraId, cameraInfo);
Ruben Brunkb2119af2014-05-09 19:57:56 -0700621 } else {
622 /**
623 * Normal HAL 2.1+ codepath.
624 */
625 struct camera_info info;
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800626 ret = filterGetInfoErrorCode(mModule->getCameraInfo(cameraId, &info));
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800627 if (ret.isOk()) {
628 *cameraInfo = info.static_camera_characteristics;
629 }
Ruben Brunkb2119af2014-05-09 19:57:56 -0700630 }
Zhijun He2b59be82013-09-25 10:14:30 -0700631
632 return ret;
633}
634
Ruben Brunkcc776712015-02-17 20:18:47 -0800635int CameraService::getCallingPid() {
636 return IPCThreadState::self()->getCallingPid();
637}
638
639int CameraService::getCallingUid() {
640 return IPCThreadState::self()->getCallingUid();
641}
642
643String8 CameraService::getFormattedCurrentTime() {
644 time_t now = time(nullptr);
645 char formattedTime[64];
646 strftime(formattedTime, sizeof(formattedTime), "%m-%d %H:%M:%S", localtime(&now));
647 return String8(formattedTime);
648}
649
650int CameraService::getCameraPriorityFromProcState(int procState) {
651 // Find the priority for the camera usage based on the process state. Higher priority clients
652 // win for evictions.
Ruben Brunkbe0b6b42015-05-12 16:10:52 -0700653 if (procState < 0) {
654 ALOGE("%s: Received invalid process state %d from ActivityManagerService!", __FUNCTION__,
655 procState);
656 return -1;
Ruben Brunkcc776712015-02-17 20:18:47 -0800657 }
Eino-Ville Talvala52aad852015-09-03 12:24:24 -0700658 // Treat sleeping TOP processes the same as regular TOP processes, for
659 // access priority. This is important for lock-screen camera launch scenarios
660 if (procState == PROCESS_STATE_TOP_SLEEPING) {
661 procState = PROCESS_STATE_TOP;
662 }
Ruben Brunkbe0b6b42015-05-12 16:10:52 -0700663 return INT_MAX - procState;
Ruben Brunkcc776712015-02-17 20:18:47 -0800664}
665
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800666Status CameraService::getCameraVendorTagDescriptor(
667 /*out*/
668 hardware::camera2::params::VendorTagDescriptor* desc) {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -0700669 ATRACE_CALL();
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800670 if (!mModule) {
671 ALOGE("%s: camera hardware module doesn't exist", __FUNCTION__);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800672 return STATUS_ERROR(ERROR_DISCONNECTED, "Camera subsystem not available");
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800673 }
Eino-Ville Talvala1e74e242016-03-03 11:24:28 -0800674 sp<VendorTagDescriptor> globalDescriptor = VendorTagDescriptor::getGlobalVendorTagDescriptor();
675 if (globalDescriptor != nullptr) {
676 *desc = *(globalDescriptor.get());
677 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800678 return Status::ok();
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800679}
680
Igor Murashkin634a5152013-02-20 17:15:11 -0800681int CameraService::getDeviceVersion(int cameraId, int* facing) {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -0700682 ATRACE_CALL();
Igor Murashkin634a5152013-02-20 17:15:11 -0800683 struct camera_info info;
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800684 if (mModule->getCameraInfo(cameraId, &info) != OK) {
Igor Murashkin634a5152013-02-20 17:15:11 -0800685 return -1;
686 }
687
688 int deviceVersion;
Chien-Yu Chen676b21b2015-02-24 10:28:19 -0800689 if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_0) {
Igor Murashkin634a5152013-02-20 17:15:11 -0800690 deviceVersion = info.device_version;
691 } else {
692 deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
693 }
694
695 if (facing) {
696 *facing = info.facing;
697 }
698
699 return deviceVersion;
700}
701
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800702Status CameraService::filterGetInfoErrorCode(status_t err) {
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -0700703 switch(err) {
704 case NO_ERROR:
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800705 return Status::ok();
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -0700706 case -EINVAL:
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800707 return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT,
708 "CameraId is not valid for HAL module");
709 case -ENODEV:
710 return STATUS_ERROR(ERROR_DISCONNECTED,
711 "Camera device not available");
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -0700712 default:
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800713 return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
714 "Camera HAL encountered error %d: %s",
715 err, strerror(-err));
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -0700716 }
Igor Murashkinbfc99152013-02-27 12:55:20 -0800717}
718
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800719bool CameraService::setUpVendorTags() {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -0700720 ATRACE_CALL();
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800721 vendor_tag_ops_t vOps = vendor_tag_ops_t();
722
723 // Check if vendor operations have been implemented
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800724 if (!mModule->isVendorTagDefined()) {
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800725 ALOGI("%s: No vendor tags defined for this device.", __FUNCTION__);
726 return false;
727 }
728
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800729 mModule->getVendorTagOps(&vOps);
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800730
731 // Ensure all vendor operations are present
732 if (vOps.get_tag_count == NULL || vOps.get_all_tags == NULL ||
733 vOps.get_section_name == NULL || vOps.get_tag_name == NULL ||
734 vOps.get_tag_type == NULL) {
735 ALOGE("%s: Vendor tag operations not fully defined. Ignoring definitions."
736 , __FUNCTION__);
737 return false;
738 }
739
740 // Read all vendor tag definitions into a descriptor
741 sp<VendorTagDescriptor> desc;
742 status_t res;
743 if ((res = VendorTagDescriptor::createDescriptorFromOps(&vOps, /*out*/desc))
744 != OK) {
745 ALOGE("%s: Could not generate descriptor from vendor tag operations,"
746 "received error %s (%d). Camera clients will not be able to use"
747 "vendor tags", __FUNCTION__, strerror(res), res);
748 return false;
749 }
750
751 // Set the global descriptor to use with camera metadata
752 VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
753 return true;
754}
755
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800756Status CameraService::makeClient(const sp<CameraService>& cameraService,
757 const sp<IInterface>& cameraCb, const String16& packageName, int cameraId,
Ruben Brunkcc776712015-02-17 20:18:47 -0800758 int facing, int clientPid, uid_t clientUid, int servicePid, bool legacyMode,
759 int halVersion, int deviceVersion, apiLevel effectiveApiLevel,
760 /*out*/sp<BasicClient>* client) {
761
Ruben Brunkcc776712015-02-17 20:18:47 -0800762 if (halVersion < 0 || halVersion == deviceVersion) {
763 // Default path: HAL version is unspecified by caller, create CameraClient
764 // based on device version reported by the HAL.
765 switch(deviceVersion) {
766 case CAMERA_DEVICE_API_VERSION_1_0:
767 if (effectiveApiLevel == API_1) { // Camera1 API route
768 sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800769 *client = new CameraClient(cameraService, tmp, packageName, cameraId, facing,
Ruben Brunkcc776712015-02-17 20:18:47 -0800770 clientPid, clientUid, getpid(), legacyMode);
771 } else { // Camera2 API route
772 ALOGW("Camera using old HAL version: %d", deviceVersion);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800773 return STATUS_ERROR_FMT(ERROR_DEPRECATED_HAL,
774 "Camera device \"%d\" HAL version %d does not support camera2 API",
775 cameraId, deviceVersion);
Ruben Brunkcc776712015-02-17 20:18:47 -0800776 }
777 break;
Ruben Brunkcc776712015-02-17 20:18:47 -0800778 case CAMERA_DEVICE_API_VERSION_3_0:
779 case CAMERA_DEVICE_API_VERSION_3_1:
780 case CAMERA_DEVICE_API_VERSION_3_2:
781 case CAMERA_DEVICE_API_VERSION_3_3:
Zhijun He4afbdec2016-05-04 15:42:51 -0700782 case CAMERA_DEVICE_API_VERSION_3_4:
Ruben Brunkcc776712015-02-17 20:18:47 -0800783 if (effectiveApiLevel == API_1) { // Camera1 API route
784 sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800785 *client = new Camera2Client(cameraService, tmp, packageName, cameraId, facing,
Ruben Brunkcc776712015-02-17 20:18:47 -0800786 clientPid, clientUid, servicePid, legacyMode);
787 } else { // Camera2 API route
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800788 sp<hardware::camera2::ICameraDeviceCallbacks> tmp =
789 static_cast<hardware::camera2::ICameraDeviceCallbacks*>(cameraCb.get());
790 *client = new CameraDeviceClient(cameraService, tmp, packageName, cameraId,
Ruben Brunkcc776712015-02-17 20:18:47 -0800791 facing, clientPid, clientUid, servicePid);
792 }
793 break;
794 default:
795 // Should not be reachable
796 ALOGE("Unknown camera device HAL version: %d", deviceVersion);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800797 return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
798 "Camera device \"%d\" has unknown HAL version %d",
799 cameraId, deviceVersion);
Ruben Brunkcc776712015-02-17 20:18:47 -0800800 }
801 } else {
802 // A particular HAL version is requested by caller. Create CameraClient
803 // based on the requested HAL version.
804 if (deviceVersion > CAMERA_DEVICE_API_VERSION_1_0 &&
805 halVersion == CAMERA_DEVICE_API_VERSION_1_0) {
806 // Only support higher HAL version device opened as HAL1.0 device.
807 sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800808 *client = new CameraClient(cameraService, tmp, packageName, cameraId, facing,
Ruben Brunkcc776712015-02-17 20:18:47 -0800809 clientPid, clientUid, servicePid, legacyMode);
810 } else {
811 // Other combinations (e.g. HAL3.x open as HAL2.x) are not supported yet.
812 ALOGE("Invalid camera HAL version %x: HAL %x device can only be"
813 " opened as HAL %x device", halVersion, deviceVersion,
814 CAMERA_DEVICE_API_VERSION_1_0);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800815 return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
816 "Camera device \"%d\" (HAL version %d) cannot be opened as HAL version %d",
817 cameraId, deviceVersion, halVersion);
Ruben Brunkcc776712015-02-17 20:18:47 -0800818 }
819 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800820 return Status::ok();
Ruben Brunkcc776712015-02-17 20:18:47 -0800821}
822
Ruben Brunk6267b532015-04-30 17:44:07 -0700823String8 CameraService::toString(std::set<userid_t> intSet) {
824 String8 s("");
825 bool first = true;
826 for (userid_t i : intSet) {
827 if (first) {
828 s.appendFormat("%d", i);
829 first = false;
830 } else {
831 s.appendFormat(", %d", i);
832 }
833 }
834 return s;
835}
836
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800837Status CameraService::initializeShimMetadata(int cameraId) {
Ruben Brunkcc776712015-02-17 20:18:47 -0800838 int uid = getCallingUid();
Ruben Brunkb2119af2014-05-09 19:57:56 -0700839
Chien-Yu Chen98a668f2015-12-18 14:10:33 -0800840 String16 internalPackageName("cameraserver");
Ruben Brunkcc776712015-02-17 20:18:47 -0800841 String8 id = String8::format("%d", cameraId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800842 Status ret = Status::ok();
Ruben Brunkcc776712015-02-17 20:18:47 -0800843 sp<Client> tmp = nullptr;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800844 if (!(ret = connectHelper<ICameraClient,Client>(
845 sp<ICameraClient>{nullptr}, id, static_cast<int>(CAMERA_HAL_API_VERSION_UNSPECIFIED),
846 internalPackageName, uid, USE_CALLING_PID,
847 API_1, /*legacyMode*/ false, /*shimUpdateOnly*/ true,
848 /*out*/ tmp)
849 ).isOk()) {
850 ALOGE("%s: Error initializing shim metadata: %s", __FUNCTION__, ret.toString8().string());
Ruben Brunkb2119af2014-05-09 19:57:56 -0700851 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800852 return ret;
Ruben Brunkb2119af2014-05-09 19:57:56 -0700853}
854
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800855Status CameraService::getLegacyParametersLazy(int cameraId,
Igor Murashkin65d14b92014-06-17 12:03:20 -0700856 /*out*/
857 CameraParameters* parameters) {
858
859 ALOGV("%s: for cameraId: %d", __FUNCTION__, cameraId);
860
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800861 Status ret = Status::ok();
Igor Murashkin65d14b92014-06-17 12:03:20 -0700862
863 if (parameters == NULL) {
864 ALOGE("%s: parameters must not be null", __FUNCTION__);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800865 return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Parameters must not be null");
Igor Murashkin65d14b92014-06-17 12:03:20 -0700866 }
867
Ruben Brunkcc776712015-02-17 20:18:47 -0800868 String8 id = String8::format("%d", cameraId);
869
870 // Check if we already have parameters
871 {
872 // Scope for service lock
Igor Murashkin65d14b92014-06-17 12:03:20 -0700873 Mutex::Autolock lock(mServiceLock);
Ruben Brunkcc776712015-02-17 20:18:47 -0800874 auto cameraState = getCameraState(id);
875 if (cameraState == nullptr) {
876 ALOGE("%s: Invalid camera ID: %s", __FUNCTION__, id.string());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800877 return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
878 "Invalid camera ID: %s", id.string());
Ruben Brunkcc776712015-02-17 20:18:47 -0800879 }
880 CameraParameters p = cameraState->getShimParams();
881 if (!p.isEmpty()) {
882 *parameters = p;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800883 return ret;
Igor Murashkin65d14b92014-06-17 12:03:20 -0700884 }
885 }
886
Ruben Brunkcc776712015-02-17 20:18:47 -0800887 int64_t token = IPCThreadState::self()->clearCallingIdentity();
888 ret = initializeShimMetadata(cameraId);
889 IPCThreadState::self()->restoreCallingIdentity(token);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800890 if (!ret.isOk()) {
Ruben Brunkcc776712015-02-17 20:18:47 -0800891 // Error already logged by callee
892 return ret;
893 }
894
895 // Check for parameters again
896 {
897 // Scope for service lock
898 Mutex::Autolock lock(mServiceLock);
899 auto cameraState = getCameraState(id);
900 if (cameraState == nullptr) {
901 ALOGE("%s: Invalid camera ID: %s", __FUNCTION__, id.string());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800902 return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
903 "Invalid camera ID: %s", id.string());
Igor Murashkin65d14b92014-06-17 12:03:20 -0700904 }
Ruben Brunkcc776712015-02-17 20:18:47 -0800905 CameraParameters p = cameraState->getShimParams();
906 if (!p.isEmpty()) {
907 *parameters = p;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800908 return ret;
Igor Murashkin65d14b92014-06-17 12:03:20 -0700909 }
910 }
911
Ruben Brunkcc776712015-02-17 20:18:47 -0800912 ALOGE("%s: Parameters were not initialized, or were empty. Device may not be present.",
913 __FUNCTION__);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800914 return STATUS_ERROR(ERROR_INVALID_OPERATION, "Unable to initialize legacy parameters");
Igor Murashkin65d14b92014-06-17 12:03:20 -0700915}
916
Chien-Yu Chen98a668f2015-12-18 14:10:33 -0800917// Can camera service trust the caller based on the calling UID?
918static bool isTrustedCallingUid(uid_t uid) {
919 switch (uid) {
Eino-Ville Talvalaaf9d0302016-06-29 14:40:10 -0700920 case AID_MEDIA: // mediaserver
Chien-Yu Chen98a668f2015-12-18 14:10:33 -0800921 case AID_CAMERASERVER: // cameraserver
Eino-Ville Talvalaaf9d0302016-06-29 14:40:10 -0700922 case AID_RADIO: // telephony
Chien-Yu Chen98a668f2015-12-18 14:10:33 -0800923 return true;
924 default:
925 return false;
926 }
927}
928
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800929Status CameraService::validateConnectLocked(const String8& cameraId,
Chien-Yu Chen18df60e2016-03-18 18:18:09 -0700930 const String8& clientName8, /*inout*/int& clientUid, /*inout*/int& clientPid,
931 /*out*/int& originalClientPid) const {
Tyler Luu5861a9a2011-10-06 00:00:03 -0500932
Alex Deymo9c2a2c22016-08-25 11:59:14 -0700933#ifdef __BRILLO__
934 UNUSED(clientName8);
935 UNUSED(clientUid);
936 UNUSED(clientPid);
937 UNUSED(originalClientPid);
938#else
Chien-Yu Chen7939aee2016-03-21 18:19:33 -0700939 Status allowed = validateClientPermissionsLocked(cameraId, clientName8, clientUid, clientPid,
940 originalClientPid);
Eino-Ville Talvala04926862016-03-02 15:42:53 -0800941 if (!allowed.isOk()) {
Christopher Wileyce761d12016-02-16 10:15:00 -0800942 return allowed;
943 }
Alex Deymo9c2a2c22016-08-25 11:59:14 -0700944#endif // __BRILLO__
Christopher Wileyce761d12016-02-16 10:15:00 -0800945
Eino-Ville Talvala04926862016-03-02 15:42:53 -0800946 int callingPid = getCallingPid();
947
Iliyan Malchev8951a972011-04-14 16:55:59 -0700948 if (!mModule) {
Ruben Brunkcc776712015-02-17 20:18:47 -0800949 ALOGE("CameraService::connect X (PID %d) rejected (camera HAL module not loaded)",
950 callingPid);
Eino-Ville Talvala04926862016-03-02 15:42:53 -0800951 return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
952 "No camera HAL module available to open camera device \"%s\"", cameraId.string());
Iliyan Malchev8951a972011-04-14 16:55:59 -0700953 }
954
Ruben Brunkcc776712015-02-17 20:18:47 -0800955 if (getCameraState(cameraId) == nullptr) {
956 ALOGE("CameraService::connect X (PID %d) rejected (invalid camera ID %s)", callingPid,
957 cameraId.string());
Eino-Ville Talvala04926862016-03-02 15:42:53 -0800958 return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
959 "No camera device with ID \"%s\" available", cameraId.string());
Mathias Agopian65ab4712010-07-14 17:59:35 -0700960 }
961
Eino-Ville Talvala04926862016-03-02 15:42:53 -0800962 status_t err = checkIfDeviceIsUsable(cameraId);
963 if (err != NO_ERROR) {
964 switch(err) {
965 case -ENODEV:
966 case -EBUSY:
967 return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
968 "No camera device with ID \"%s\" currently available", cameraId.string());
969 default:
970 return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
971 "Unknown error connecting to ID \"%s\"", cameraId.string());
972 }
973 }
974 return Status::ok();
Christopher Wiley0039bcf2016-02-05 10:29:50 -0800975}
976
Eino-Ville Talvala04926862016-03-02 15:42:53 -0800977Status CameraService::validateClientPermissionsLocked(const String8& cameraId,
Chien-Yu Chen7939aee2016-03-21 18:19:33 -0700978 const String8& clientName8, int& clientUid, int& clientPid,
979 /*out*/int& originalClientPid) const {
Christopher Wiley0039bcf2016-02-05 10:29:50 -0800980 int callingPid = getCallingPid();
Chien-Yu Chen98a668f2015-12-18 14:10:33 -0800981 int callingUid = getCallingUid();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700982
Chien-Yu Chen98a668f2015-12-18 14:10:33 -0800983 // Check if we can trust clientUid
Mathias Agopian65ab4712010-07-14 17:59:35 -0700984 if (clientUid == USE_CALLING_UID) {
Chien-Yu Chen98a668f2015-12-18 14:10:33 -0800985 clientUid = callingUid;
986 } else if (!isTrustedCallingUid(callingUid)) {
987 ALOGE("CameraService::connect X (calling PID %d, calling UID %d) rejected "
988 "(don't trust clientUid %d)", callingPid, callingUid, clientUid);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800989 return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
990 "Untrusted caller (calling PID %d, UID %d) trying to "
991 "forward camera access to camera %s for client %s (PID %d, UID %d)",
992 callingPid, callingUid, cameraId.string(),
993 clientName8.string(), clientUid, clientPid);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700994 }
995
Chien-Yu Chen98a668f2015-12-18 14:10:33 -0800996 // Check if we can trust clientPid
997 if (clientPid == USE_CALLING_PID) {
998 clientPid = callingPid;
999 } else if (!isTrustedCallingUid(callingUid)) {
1000 ALOGE("CameraService::connect X (calling PID %d, calling UID %d) rejected "
1001 "(don't trust clientPid %d)", callingPid, callingUid, clientPid);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001002 return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
1003 "Untrusted caller (calling PID %d, UID %d) trying to "
1004 "forward camera access to camera %s for client %s (PID %d, UID %d)",
1005 callingPid, callingUid, cameraId.string(),
1006 clientName8.string(), clientUid, clientPid);
Chien-Yu Chen98a668f2015-12-18 14:10:33 -08001007 }
1008
1009 // If it's not calling from cameraserver, check the permission.
1010 if (callingPid != getpid() &&
1011 !checkPermission(String16("android.permission.CAMERA"), clientPid, clientUid)) {
1012 ALOGE("Permission Denial: can't use the camera pid=%d, uid=%d", clientPid, clientUid);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001013 return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
1014 "Caller \"%s\" (PID %d, UID %d) cannot open camera \"%s\" without camera permission",
1015 clientName8.string(), clientUid, clientPid, cameraId.string());
Chien-Yu Chen98a668f2015-12-18 14:10:33 -08001016 }
1017
Chien-Yu Chen4f3d6202016-03-22 10:50:23 -07001018 // Only use passed in clientPid to check permission. Use calling PID as the client PID that's
1019 // connected to camera service directly.
Chien-Yu Chen18df60e2016-03-18 18:18:09 -07001020 originalClientPid = clientPid;
Chien-Yu Chen4f3d6202016-03-22 10:50:23 -07001021 clientPid = callingPid;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001022
Ruben Brunk6267b532015-04-30 17:44:07 -07001023 userid_t clientUserId = multiuser_get_user_id(clientUid);
Wu-cheng Lia3355432011-05-20 14:54:25 +08001024
Ruben Brunka8ca9152015-04-07 14:23:40 -07001025 // Only allow clients who are being used by the current foreground device user, unless calling
1026 // from our own process.
Ruben Brunk6267b532015-04-30 17:44:07 -07001027 if (callingPid != getpid() && (mAllowedUsers.find(clientUserId) == mAllowedUsers.end())) {
1028 ALOGE("CameraService::connect X (PID %d) rejected (cannot connect from "
1029 "device user %d, currently allowed device users: %s)", callingPid, clientUserId,
1030 toString(mAllowedUsers).string());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001031 return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
1032 "Callers from device user %d are not currently allowed to connect to camera \"%s\"",
1033 clientUserId, cameraId.string());
Ruben Brunk36597b22015-03-20 22:15:57 -07001034 }
1035
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001036 return Status::ok();
Ruben Brunkcc776712015-02-17 20:18:47 -08001037}
1038
1039status_t CameraService::checkIfDeviceIsUsable(const String8& cameraId) const {
1040 auto cameraState = getCameraState(cameraId);
1041 int callingPid = getCallingPid();
1042 if (cameraState == nullptr) {
1043 ALOGE("CameraService::connect X (PID %d) rejected (invalid camera ID %s)", callingPid,
1044 cameraId.string());
1045 return -ENODEV;
1046 }
1047
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001048 int32_t currentStatus = cameraState->getStatus();
Igor Murashkincba2c162013-03-20 15:56:31 -07001049 if (currentStatus == ICameraServiceListener::STATUS_NOT_PRESENT) {
Ruben Brunkcc776712015-02-17 20:18:47 -08001050 ALOGE("CameraService::connect X (PID %d) rejected (camera %s is not connected)",
1051 callingPid, cameraId.string());
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001052 return -ENODEV;
Igor Murashkincba2c162013-03-20 15:56:31 -07001053 } else if (currentStatus == ICameraServiceListener::STATUS_ENUMERATING) {
Ruben Brunkcc776712015-02-17 20:18:47 -08001054 ALOGE("CameraService::connect X (PID %d) rejected, (camera %s is initializing)",
1055 callingPid, cameraId.string());
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001056 return -EBUSY;
Igor Murashkincba2c162013-03-20 15:56:31 -07001057 }
Igor Murashkincba2c162013-03-20 15:56:31 -07001058
Ruben Brunkcc776712015-02-17 20:18:47 -08001059 return NO_ERROR;
Igor Murashkine6800ce2013-03-04 17:25:57 -08001060}
1061
Ruben Brunkcc776712015-02-17 20:18:47 -08001062void CameraService::finishConnectLocked(const sp<BasicClient>& client,
1063 const CameraService::DescriptorPtr& desc) {
Igor Murashkine6800ce2013-03-04 17:25:57 -08001064
Ruben Brunkcc776712015-02-17 20:18:47 -08001065 // Make a descriptor for the incoming client
1066 auto clientDescriptor = CameraService::CameraClientManager::makeClientDescriptor(client, desc);
1067 auto evicted = mActiveClientManager.addAndEvict(clientDescriptor);
1068
1069 logConnected(desc->getKey(), static_cast<int>(desc->getOwnerId()),
1070 String8(client->getPackageName()));
1071
1072 if (evicted.size() > 0) {
1073 // This should never happen - clients should already have been removed in disconnect
1074 for (auto& i : evicted) {
1075 ALOGE("%s: Invalid state: Client for camera %s was not removed in disconnect",
1076 __FUNCTION__, i->getKey().string());
1077 }
1078
1079 LOG_ALWAYS_FATAL("%s: Invalid state for CameraService, clients not evicted properly",
1080 __FUNCTION__);
1081 }
Eino-Ville Talvala24901c82015-09-04 14:15:58 -07001082
1083 // And register a death notification for the client callback. Do
1084 // this last to avoid Binder policy where a nested Binder
1085 // transaction might be pre-empted to service the client death
1086 // notification if the client process dies before linkToDeath is
1087 // invoked.
1088 sp<IBinder> remoteCallback = client->getRemote();
1089 if (remoteCallback != nullptr) {
1090 remoteCallback->linkToDeath(this);
1091 }
Ruben Brunkcc776712015-02-17 20:18:47 -08001092}
1093
1094status_t CameraService::handleEvictionsLocked(const String8& cameraId, int clientPid,
1095 apiLevel effectiveApiLevel, const sp<IBinder>& remoteCallback, const String8& packageName,
1096 /*out*/
1097 sp<BasicClient>* client,
1098 std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>* partial) {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -07001099 ATRACE_CALL();
Ruben Brunkcc776712015-02-17 20:18:47 -08001100 status_t ret = NO_ERROR;
Ruben Brunk4f9576b2015-04-10 17:26:56 -07001101 std::vector<DescriptorPtr> evictedClients;
Ruben Brunkcc776712015-02-17 20:18:47 -08001102 DescriptorPtr clientDescriptor;
1103 {
1104 if (effectiveApiLevel == API_1) {
1105 // If we are using API1, any existing client for this camera ID with the same remote
1106 // should be returned rather than evicted to allow MediaRecorder to work properly.
1107
1108 auto current = mActiveClientManager.get(cameraId);
1109 if (current != nullptr) {
1110 auto clientSp = current->getValue();
1111 if (clientSp.get() != nullptr) { // should never be needed
Ruben Brunk0bbf8b22015-04-30 14:35:42 -07001112 if (!clientSp->canCastToApiClient(effectiveApiLevel)) {
1113 ALOGW("CameraService connect called from same client, but with a different"
1114 " API level, evicting prior client...");
1115 } else if (clientSp->getRemote() == remoteCallback) {
Ruben Brunkcc776712015-02-17 20:18:47 -08001116 ALOGI("CameraService::connect X (PID %d) (second call from same"
Ruben Brunk0bbf8b22015-04-30 14:35:42 -07001117 " app binder, returning the same client)", clientPid);
Ruben Brunkcc776712015-02-17 20:18:47 -08001118 *client = clientSp;
1119 return NO_ERROR;
1120 }
1121 }
Wu-cheng Li2fd24402012-02-23 19:01:00 -08001122 }
Wu-cheng Li2fd24402012-02-23 19:01:00 -08001123 }
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +08001124
Ruben Brunkcc776712015-02-17 20:18:47 -08001125 // Get current active client PIDs
1126 std::vector<int> ownerPids(mActiveClientManager.getAllOwners());
1127 ownerPids.push_back(clientPid);
Igor Murashkine6800ce2013-03-04 17:25:57 -08001128
Chih-Hung Hsieh54b42462015-03-19 12:04:54 -07001129 // Use the value +PROCESS_STATE_NONEXISTENT, to avoid taking
1130 // address of PROCESS_STATE_NONEXISTENT as a reference argument
1131 // for the vector constructor. PROCESS_STATE_NONEXISTENT does
1132 // not have an out-of-class definition.
1133 std::vector<int> priorities(ownerPids.size(), +PROCESS_STATE_NONEXISTENT);
Igor Murashkine6800ce2013-03-04 17:25:57 -08001134
Ruben Brunkcc776712015-02-17 20:18:47 -08001135 // Get priorites of all active PIDs
1136 ProcessInfoService::getProcessStatesFromPids(ownerPids.size(), &ownerPids[0],
1137 /*out*/&priorities[0]);
Ruben Brunkb2119af2014-05-09 19:57:56 -07001138
Ruben Brunkcc776712015-02-17 20:18:47 -08001139 // Update all active clients' priorities
1140 std::map<int,int> pidToPriorityMap;
1141 for (size_t i = 0; i < ownerPids.size() - 1; i++) {
1142 pidToPriorityMap.emplace(ownerPids[i], getCameraPriorityFromProcState(priorities[i]));
1143 }
1144 mActiveClientManager.updatePriorities(pidToPriorityMap);
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001145
Ruben Brunkcc776712015-02-17 20:18:47 -08001146 // Get state for the given cameraId
1147 auto state = getCameraState(cameraId);
1148 if (state == nullptr) {
1149 ALOGE("CameraService::connect X (PID %d) rejected (no camera device with ID %s)",
1150 clientPid, cameraId.string());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001151 // Should never get here because validateConnectLocked should have errored out
Zhijun Heb10cdad2014-06-16 16:38:35 -07001152 return BAD_VALUE;
Zhijun Heb10cdad2014-06-16 16:38:35 -07001153 }
Ruben Brunkcc776712015-02-17 20:18:47 -08001154
1155 // Make descriptor for incoming client
1156 clientDescriptor = CameraClientManager::makeClientDescriptor(cameraId,
1157 sp<BasicClient>{nullptr}, static_cast<int32_t>(state->getCost()),
1158 state->getConflicting(),
1159 getCameraPriorityFromProcState(priorities[priorities.size() - 1]), clientPid);
1160
1161 // Find clients that would be evicted
1162 auto evicted = mActiveClientManager.wouldEvict(clientDescriptor);
1163
1164 // If the incoming client was 'evicted,' higher priority clients have the camera in the
1165 // background, so we cannot do evictions
1166 if (std::find(evicted.begin(), evicted.end(), clientDescriptor) != evicted.end()) {
1167 ALOGE("CameraService::connect X (PID %d) rejected (existing client(s) with higher"
1168 " priority).", clientPid);
1169
1170 sp<BasicClient> clientSp = clientDescriptor->getValue();
1171 String8 curTime = getFormattedCurrentTime();
1172 auto incompatibleClients =
1173 mActiveClientManager.getIncompatibleClients(clientDescriptor);
1174
1175 String8 msg = String8::format("%s : DENIED connect device %s client for package %s "
Ruben Brunka8ca9152015-04-07 14:23:40 -07001176 "(PID %d, priority %d) due to eviction policy", curTime.string(),
Ruben Brunkcc776712015-02-17 20:18:47 -08001177 cameraId.string(), packageName.string(), clientPid,
1178 getCameraPriorityFromProcState(priorities[priorities.size() - 1]));
1179
1180 for (auto& i : incompatibleClients) {
1181 msg.appendFormat("\n - Blocked by existing device %s client for package %s"
1182 "(PID %" PRId32 ", priority %" PRId32 ")", i->getKey().string(),
1183 String8{i->getValue()->getPackageName()}.string(), i->getOwnerId(),
1184 i->getPriority());
Eino-Ville Talvala022f0cb2015-05-19 16:31:16 -07001185 ALOGE(" Conflicts with: Device %s, client package %s (PID %"
1186 PRId32 ", priority %" PRId32 ")", i->getKey().string(),
1187 String8{i->getValue()->getPackageName()}.string(), i->getOwnerId(),
1188 i->getPriority());
Ruben Brunkcc776712015-02-17 20:18:47 -08001189 }
1190
1191 // Log the client's attempt
Ruben Brunka8ca9152015-04-07 14:23:40 -07001192 Mutex::Autolock l(mLogLock);
Ruben Brunkcc776712015-02-17 20:18:47 -08001193 mEventLog.add(msg);
1194
1195 return -EBUSY;
1196 }
1197
1198 for (auto& i : evicted) {
1199 sp<BasicClient> clientSp = i->getValue();
1200 if (clientSp.get() == nullptr) {
1201 ALOGE("%s: Invalid state: Null client in active client list.", __FUNCTION__);
1202
1203 // TODO: Remove this
1204 LOG_ALWAYS_FATAL("%s: Invalid state for CameraService, null client in active list",
1205 __FUNCTION__);
1206 mActiveClientManager.remove(i);
1207 continue;
1208 }
1209
1210 ALOGE("CameraService::connect evicting conflicting client for camera ID %s",
1211 i->getKey().string());
Ruben Brunk4f9576b2015-04-10 17:26:56 -07001212 evictedClients.push_back(i);
Ruben Brunkcc776712015-02-17 20:18:47 -08001213
Ruben Brunkcc776712015-02-17 20:18:47 -08001214 // Log the clients evicted
Ruben Brunka8ca9152015-04-07 14:23:40 -07001215 logEvent(String8::format("EVICT device %s client held by package %s (PID"
1216 " %" PRId32 ", priority %" PRId32 ")\n - Evicted by device %s client for"
1217 " package %s (PID %d, priority %" PRId32 ")",
Ruben Brunkcc776712015-02-17 20:18:47 -08001218 i->getKey().string(), String8{clientSp->getPackageName()}.string(),
1219 i->getOwnerId(), i->getPriority(), cameraId.string(),
1220 packageName.string(), clientPid,
1221 getCameraPriorityFromProcState(priorities[priorities.size() - 1])));
1222
1223 // Notify the client of disconnection
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001224 clientSp->notifyError(hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED,
Ruben Brunkcc776712015-02-17 20:18:47 -08001225 CaptureResultExtras());
Zhijun Heb10cdad2014-06-16 16:38:35 -07001226 }
Ruben Brunkb2119af2014-05-09 19:57:56 -07001227 }
1228
Ruben Brunkcc776712015-02-17 20:18:47 -08001229 // Do not hold mServiceLock while disconnecting clients, but retain the condition blocking
1230 // other clients from connecting in mServiceLockWrapper if held
1231 mServiceLock.unlock();
1232
1233 // Clear caller identity temporarily so client disconnect PID checks work correctly
1234 int64_t token = IPCThreadState::self()->clearCallingIdentity();
1235
1236 // Destroy evicted clients
1237 for (auto& i : evictedClients) {
1238 // Disconnect is blocking, and should only have returned when HAL has cleaned up
Ruben Brunk4f9576b2015-04-10 17:26:56 -07001239 i->getValue()->disconnect(); // Clients will remove themselves from the active client list
Ruben Brunkcc776712015-02-17 20:18:47 -08001240 }
Ruben Brunkcc776712015-02-17 20:18:47 -08001241
1242 IPCThreadState::self()->restoreCallingIdentity(token);
1243
Ruben Brunk4f9576b2015-04-10 17:26:56 -07001244 for (const auto& i : evictedClients) {
1245 ALOGV("%s: Waiting for disconnect to complete for client for device %s (PID %" PRId32 ")",
1246 __FUNCTION__, i->getKey().string(), i->getOwnerId());
1247 ret = mActiveClientManager.waitUntilRemoved(i, DEFAULT_DISCONNECT_TIMEOUT_NS);
1248 if (ret == TIMED_OUT) {
1249 ALOGE("%s: Timed out waiting for client for device %s to disconnect, "
1250 "current clients:\n%s", __FUNCTION__, i->getKey().string(),
1251 mActiveClientManager.toString().string());
1252 return -EBUSY;
1253 }
1254 if (ret != NO_ERROR) {
1255 ALOGE("%s: Received error waiting for client for device %s to disconnect: %s (%d), "
1256 "current clients:\n%s", __FUNCTION__, i->getKey().string(), strerror(-ret),
1257 ret, mActiveClientManager.toString().string());
1258 return ret;
1259 }
1260 }
1261
1262 evictedClients.clear();
1263
Ruben Brunkcc776712015-02-17 20:18:47 -08001264 // Once clients have been disconnected, relock
1265 mServiceLock.lock();
1266
1267 // Check again if the device was unplugged or something while we weren't holding mServiceLock
1268 if ((ret = checkIfDeviceIsUsable(cameraId)) != NO_ERROR) {
1269 return ret;
Ruben Brunkb2119af2014-05-09 19:57:56 -07001270 }
1271
Ruben Brunkcc776712015-02-17 20:18:47 -08001272 *partial = clientDescriptor;
1273 return NO_ERROR;
Ruben Brunkb2119af2014-05-09 19:57:56 -07001274}
1275
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001276Status CameraService::connect(
Igor Murashkine6800ce2013-03-04 17:25:57 -08001277 const sp<ICameraClient>& cameraClient,
1278 int cameraId,
Svetoslav Ganov280405a2015-05-12 02:19:27 +00001279 const String16& clientPackageName,
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001280 int clientUid,
Chien-Yu Chen98a668f2015-12-18 14:10:33 -08001281 int clientPid,
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001282 /*out*/
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001283 sp<ICamera>* device) {
Igor Murashkine6800ce2013-03-04 17:25:57 -08001284
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -07001285 ATRACE_CALL();
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001286 Status ret = Status::ok();
Ruben Brunkcc776712015-02-17 20:18:47 -08001287 String8 id = String8::format("%d", cameraId);
1288 sp<Client> client = nullptr;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001289 ret = connectHelper<ICameraClient,Client>(cameraClient, id,
1290 CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageName, clientUid, clientPid, API_1,
1291 /*legacyMode*/ false, /*shimUpdateOnly*/ false,
1292 /*out*/client);
Igor Murashkine6800ce2013-03-04 17:25:57 -08001293
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001294 if(!ret.isOk()) {
Svetoslav Ganov280405a2015-05-12 02:19:27 +00001295 logRejected(id, getCallingPid(), String8(clientPackageName),
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001296 ret.toString8());
Ruben Brunkcc776712015-02-17 20:18:47 -08001297 return ret;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001298 }
1299
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001300 *device = client;
1301 return ret;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001302}
1303
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001304Status CameraService::connectLegacy(
Zhijun Heb10cdad2014-06-16 16:38:35 -07001305 const sp<ICameraClient>& cameraClient,
1306 int cameraId, int halVersion,
Svetoslav Ganov280405a2015-05-12 02:19:27 +00001307 const String16& clientPackageName,
Zhijun Heb10cdad2014-06-16 16:38:35 -07001308 int clientUid,
1309 /*out*/
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001310 sp<ICamera>* device) {
Zhijun Heb10cdad2014-06-16 16:38:35 -07001311
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -07001312 ATRACE_CALL();
Ruben Brunka8ca9152015-04-07 14:23:40 -07001313 String8 id = String8::format("%d", cameraId);
Chien-Yu Chen676b21b2015-02-24 10:28:19 -08001314 int apiVersion = mModule->getModuleApiVersion();
Igor Murashkin3d07d1a2014-06-20 11:27:03 -07001315 if (halVersion != CAMERA_HAL_API_VERSION_UNSPECIFIED &&
Yin-Chia Yehe074a932015-01-30 10:29:02 -08001316 apiVersion < CAMERA_MODULE_API_VERSION_2_3) {
Igor Murashkin3d07d1a2014-06-20 11:27:03 -07001317 /*
1318 * Either the HAL version is unspecified in which case this just creates
1319 * a camera client selected by the latest device version, or
1320 * it's a particular version in which case the HAL must supported
1321 * the open_legacy call
1322 */
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001323 String8 msg = String8::format("Camera HAL module version %x too old for connectLegacy!",
1324 apiVersion);
1325 ALOGE("%s: %s",
1326 __FUNCTION__, msg.string());
Svetoslav Ganov280405a2015-05-12 02:19:27 +00001327 logRejected(id, getCallingPid(), String8(clientPackageName),
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001328 msg);
1329 return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.string());
Zhijun Heb10cdad2014-06-16 16:38:35 -07001330 }
1331
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001332 Status ret = Status::ok();
Ruben Brunkcc776712015-02-17 20:18:47 -08001333 sp<Client> client = nullptr;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001334 ret = connectHelper<ICameraClient,Client>(cameraClient, id, halVersion,
1335 clientPackageName, clientUid, USE_CALLING_PID, API_1,
1336 /*legacyMode*/ true, /*shimUpdateOnly*/ false,
1337 /*out*/client);
Zhijun Heb10cdad2014-06-16 16:38:35 -07001338
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001339 if(!ret.isOk()) {
Svetoslav Ganov280405a2015-05-12 02:19:27 +00001340 logRejected(id, getCallingPid(), String8(clientPackageName),
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001341 ret.toString8());
Ruben Brunkcc776712015-02-17 20:18:47 -08001342 return ret;
Zhijun Heb10cdad2014-06-16 16:38:35 -07001343 }
1344
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001345 *device = client;
1346 return ret;
Zhijun Heb10cdad2014-06-16 16:38:35 -07001347}
1348
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001349Status CameraService::connectDevice(
1350 const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb,
Ruben Brunkcc776712015-02-17 20:18:47 -08001351 int cameraId,
Svetoslav Ganov280405a2015-05-12 02:19:27 +00001352 const String16& clientPackageName,
Ruben Brunkcc776712015-02-17 20:18:47 -08001353 int clientUid,
1354 /*out*/
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001355 sp<hardware::camera2::ICameraDeviceUser>* device) {
Ruben Brunkcc776712015-02-17 20:18:47 -08001356
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -07001357 ATRACE_CALL();
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001358 Status ret = Status::ok();
Ruben Brunkcc776712015-02-17 20:18:47 -08001359 String8 id = String8::format("%d", cameraId);
1360 sp<CameraDeviceClient> client = nullptr;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001361 ret = connectHelper<hardware::camera2::ICameraDeviceCallbacks,CameraDeviceClient>(cameraCb, id,
1362 CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageName,
1363 clientUid, USE_CALLING_PID, API_2,
1364 /*legacyMode*/ false, /*shimUpdateOnly*/ false,
1365 /*out*/client);
Ruben Brunkcc776712015-02-17 20:18:47 -08001366
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001367 if(!ret.isOk()) {
Svetoslav Ganov280405a2015-05-12 02:19:27 +00001368 logRejected(id, getCallingPid(), String8(clientPackageName),
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001369 ret.toString8());
Ruben Brunkcc776712015-02-17 20:18:47 -08001370 return ret;
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001371 }
1372
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001373 *device = client;
1374 return ret;
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001375}
1376
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001377Status CameraService::setTorchMode(const String16& cameraId, bool enabled,
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001378 const sp<IBinder>& clientBinder) {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -07001379
1380 ATRACE_CALL();
Ruben Brunk99e69712015-05-26 17:25:07 -07001381 if (enabled && clientBinder == nullptr) {
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001382 ALOGE("%s: torch client binder is NULL", __FUNCTION__);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001383 return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT,
1384 "Torch client Binder is null");
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001385 }
1386
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001387 String8 id = String8(cameraId.string());
Ruben Brunk99e69712015-05-26 17:25:07 -07001388 int uid = getCallingUid();
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001389
1390 // verify id is valid.
Ruben Brunkcc776712015-02-17 20:18:47 -08001391 auto state = getCameraState(id);
1392 if (state == nullptr) {
Chien-Yu Chenf6463fc2015-04-07 15:11:31 -07001393 ALOGE("%s: camera id is invalid %s", __FUNCTION__, id.string());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001394 return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
1395 "Camera ID \"%s\" is a not valid camera ID", id.string());
Ruben Brunkcc776712015-02-17 20:18:47 -08001396 }
1397
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001398 int32_t cameraStatus = state->getStatus();
Ruben Brunkcc776712015-02-17 20:18:47 -08001399 if (cameraStatus != ICameraServiceListener::STATUS_PRESENT &&
1400 cameraStatus != ICameraServiceListener::STATUS_NOT_AVAILABLE) {
Chien-Yu Chenf6463fc2015-04-07 15:11:31 -07001401 ALOGE("%s: camera id is invalid %s", __FUNCTION__, id.string());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001402 return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
1403 "Camera ID \"%s\" is a not valid camera ID", id.string());
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001404 }
1405
1406 {
1407 Mutex::Autolock al(mTorchStatusMutex);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001408 int32_t status;
1409 status_t err = getTorchStatusLocked(id, &status);
1410 if (err != OK) {
1411 if (err == NAME_NOT_FOUND) {
1412 return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
1413 "Camera \"%s\" does not have a flash unit", id.string());
1414 }
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001415 ALOGE("%s: getting current torch status failed for camera %s",
1416 __FUNCTION__, id.string());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001417 return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
1418 "Error updating torch status for camera \"%s\": %s (%d)", id.string(),
1419 strerror(-err), err);
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001420 }
1421
1422 if (status == ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE) {
Ruben Brunkcc776712015-02-17 20:18:47 -08001423 if (cameraStatus == ICameraServiceListener::STATUS_NOT_AVAILABLE) {
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001424 ALOGE("%s: torch mode of camera %s is not available because "
1425 "camera is in use", __FUNCTION__, id.string());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001426 return STATUS_ERROR_FMT(ERROR_CAMERA_IN_USE,
1427 "Torch for camera \"%s\" is not available due to an existing camera user",
1428 id.string());
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001429 } else {
1430 ALOGE("%s: torch mode of camera %s is not available due to "
1431 "insufficient resources", __FUNCTION__, id.string());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001432 return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE,
1433 "Torch for camera \"%s\" is not available due to insufficient resources",
1434 id.string());
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001435 }
1436 }
1437 }
1438
Ruben Brunk99e69712015-05-26 17:25:07 -07001439 {
1440 // Update UID map - this is used in the torch status changed callbacks, so must be done
1441 // before setTorchMode
Chien-Yu Chenfe751be2015-09-01 14:16:44 -07001442 Mutex::Autolock al(mTorchUidMapMutex);
Ruben Brunk99e69712015-05-26 17:25:07 -07001443 if (mTorchUidMap.find(id) == mTorchUidMap.end()) {
1444 mTorchUidMap[id].first = uid;
1445 mTorchUidMap[id].second = uid;
1446 } else {
1447 // Set the pending UID
1448 mTorchUidMap[id].first = uid;
1449 }
1450 }
1451
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001452 status_t err = mFlashlight->setTorchMode(id, enabled);
Ruben Brunk99e69712015-05-26 17:25:07 -07001453
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001454 if (err != OK) {
1455 int32_t errorCode;
1456 String8 msg;
1457 switch (err) {
1458 case -ENOSYS:
1459 msg = String8::format("Camera \"%s\" has no flashlight",
1460 id.string());
1461 errorCode = ERROR_ILLEGAL_ARGUMENT;
1462 break;
1463 default:
1464 msg = String8::format(
1465 "Setting torch mode of camera \"%s\" to %d failed: %s (%d)",
1466 id.string(), enabled, strerror(-err), err);
1467 errorCode = ERROR_INVALID_OPERATION;
1468 }
1469 ALOGE("%s: %s", __FUNCTION__, msg.string());
1470 return STATUS_ERROR(errorCode, msg.string());
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001471 }
1472
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001473 {
1474 // update the link to client's death
1475 Mutex::Autolock al(mTorchClientMapMutex);
1476 ssize_t index = mTorchClientMap.indexOfKey(id);
1477 if (enabled) {
1478 if (index == NAME_NOT_FOUND) {
1479 mTorchClientMap.add(id, clientBinder);
1480 } else {
Ruben Brunk99e69712015-05-26 17:25:07 -07001481 mTorchClientMap.valueAt(index)->unlinkToDeath(this);
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001482 mTorchClientMap.replaceValueAt(index, clientBinder);
1483 }
1484 clientBinder->linkToDeath(this);
1485 } else if (index != NAME_NOT_FOUND) {
Ruben Brunk99e69712015-05-26 17:25:07 -07001486 mTorchClientMap.valueAt(index)->unlinkToDeath(this);
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001487 }
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001488 }
1489
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001490 return Status::ok();
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001491}
1492
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001493Status CameraService::notifySystemEvent(int32_t eventId,
1494 const std::vector<int32_t>& args) {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -07001495 ATRACE_CALL();
1496
Ruben Brunk36597b22015-03-20 22:15:57 -07001497 switch(eventId) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001498 case ICameraService::EVENT_USER_SWITCHED: {
1499 doUserSwitch(/*newUserIds*/ args);
Ruben Brunk36597b22015-03-20 22:15:57 -07001500 break;
1501 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001502 case ICameraService::EVENT_NONE:
Ruben Brunk36597b22015-03-20 22:15:57 -07001503 default: {
1504 ALOGW("%s: Received invalid system event from system_server: %d", __FUNCTION__,
1505 eventId);
1506 break;
1507 }
1508 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001509 return Status::ok();
Ruben Brunk36597b22015-03-20 22:15:57 -07001510}
1511
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001512Status CameraService::addListener(const sp<ICameraServiceListener>& listener) {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -07001513 ATRACE_CALL();
1514
Igor Murashkinbfc99152013-02-27 12:55:20 -08001515 ALOGV("%s: Add listener %p", __FUNCTION__, listener.get());
Igor Murashkin634a5152013-02-20 17:15:11 -08001516
Ruben Brunk3450ba72015-06-16 11:00:37 -07001517 if (listener == nullptr) {
Igor Murashkinbd3e2e02014-03-17 13:01:41 -07001518 ALOGE("%s: Listener must not be null", __FUNCTION__);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001519 return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Null listener given to addListener");
Igor Murashkinbd3e2e02014-03-17 13:01:41 -07001520 }
1521
Igor Murashkinbfc99152013-02-27 12:55:20 -08001522 Mutex::Autolock lock(mServiceLock);
1523
Ruben Brunkcc776712015-02-17 20:18:47 -08001524 {
1525 Mutex::Autolock lock(mStatusListenerLock);
1526 for (auto& it : mListenerList) {
1527 if (IInterface::asBinder(it) == IInterface::asBinder(listener)) {
1528 ALOGW("%s: Tried to add listener %p which was already subscribed",
1529 __FUNCTION__, listener.get());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001530 return STATUS_ERROR(ERROR_ALREADY_EXISTS, "Listener already registered");
Ruben Brunkcc776712015-02-17 20:18:47 -08001531 }
Igor Murashkinbfc99152013-02-27 12:55:20 -08001532 }
Ruben Brunkcc776712015-02-17 20:18:47 -08001533
1534 mListenerList.push_back(listener);
Igor Murashkinbfc99152013-02-27 12:55:20 -08001535 }
1536
Igor Murashkinbfc99152013-02-27 12:55:20 -08001537
Igor Murashkincba2c162013-03-20 15:56:31 -07001538 /* Immediately signal current status to this listener only */
1539 {
Ruben Brunkcc776712015-02-17 20:18:47 -08001540 Mutex::Autolock lock(mCameraStatesLock);
1541 for (auto& i : mCameraStates) {
1542 // TODO: Update binder to use String16 for camera IDs and remove;
1543 int id = cameraIdToInt(i.first);
1544 if (id == -1) continue;
1545
1546 listener->onStatusChanged(i.second->getStatus(), id);
Igor Murashkincba2c162013-03-20 15:56:31 -07001547 }
1548 }
1549
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001550 /* Immediately signal current torch status to this listener only */
1551 {
1552 Mutex::Autolock al(mTorchStatusMutex);
1553 for (size_t i = 0; i < mTorchStatusMap.size(); i++ ) {
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001554 String16 id = String16(mTorchStatusMap.keyAt(i).string());
1555 listener->onTorchStatusChanged(mTorchStatusMap.valueAt(i), id);
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001556 }
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001557 }
1558
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001559 return Status::ok();
Igor Murashkinbfc99152013-02-27 12:55:20 -08001560}
Ruben Brunkcc776712015-02-17 20:18:47 -08001561
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001562Status CameraService::removeListener(const sp<ICameraServiceListener>& listener) {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -07001563 ATRACE_CALL();
1564
Igor Murashkinbfc99152013-02-27 12:55:20 -08001565 ALOGV("%s: Remove listener %p", __FUNCTION__, listener.get());
1566
Igor Murashkinbd3e2e02014-03-17 13:01:41 -07001567 if (listener == 0) {
1568 ALOGE("%s: Listener must not be null", __FUNCTION__);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001569 return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Null listener given to removeListener");
Igor Murashkinbd3e2e02014-03-17 13:01:41 -07001570 }
1571
Igor Murashkinbfc99152013-02-27 12:55:20 -08001572 Mutex::Autolock lock(mServiceLock);
1573
Ruben Brunkcc776712015-02-17 20:18:47 -08001574 {
1575 Mutex::Autolock lock(mStatusListenerLock);
1576 for (auto it = mListenerList.begin(); it != mListenerList.end(); it++) {
1577 if (IInterface::asBinder(*it) == IInterface::asBinder(listener)) {
1578 mListenerList.erase(it);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001579 return Status::ok();
Ruben Brunkcc776712015-02-17 20:18:47 -08001580 }
Igor Murashkinbfc99152013-02-27 12:55:20 -08001581 }
1582 }
1583
1584 ALOGW("%s: Tried to remove a listener %p which was not subscribed",
1585 __FUNCTION__, listener.get());
1586
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001587 return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Unregistered listener given to removeListener");
Igor Murashkin634a5152013-02-20 17:15:11 -08001588}
1589
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001590Status CameraService::getLegacyParameters(int cameraId, /*out*/String16* parameters) {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -07001591
1592 ATRACE_CALL();
Igor Murashkin65d14b92014-06-17 12:03:20 -07001593 ALOGV("%s: for camera ID = %d", __FUNCTION__, cameraId);
1594
1595 if (parameters == NULL) {
1596 ALOGE("%s: parameters must not be null", __FUNCTION__);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001597 return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Parameters must not be null");
Igor Murashkin65d14b92014-06-17 12:03:20 -07001598 }
1599
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001600 Status ret = Status::ok();
Igor Murashkin65d14b92014-06-17 12:03:20 -07001601
1602 CameraParameters shimParams;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001603 if (!(ret = getLegacyParametersLazy(cameraId, /*out*/&shimParams)).isOk()) {
Igor Murashkin65d14b92014-06-17 12:03:20 -07001604 // Error logged by caller
1605 return ret;
1606 }
1607
1608 String8 shimParamsString8 = shimParams.flatten();
1609 String16 shimParamsString16 = String16(shimParamsString8);
1610
1611 *parameters = shimParamsString16;
1612
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001613 return ret;
Igor Murashkin65d14b92014-06-17 12:03:20 -07001614}
1615
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001616Status CameraService::supportsCameraApi(int cameraId, int apiVersion, bool *isSupported) {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -07001617 ATRACE_CALL();
1618
Igor Murashkin65d14b92014-06-17 12:03:20 -07001619 ALOGV("%s: for camera ID = %d", __FUNCTION__, cameraId);
1620
1621 switch (apiVersion) {
1622 case API_VERSION_1:
1623 case API_VERSION_2:
1624 break;
1625 default:
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001626 String8 msg = String8::format("Unknown API version %d", apiVersion);
1627 ALOGE("%s: %s", __FUNCTION__, msg.string());
1628 return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.string());
Igor Murashkin65d14b92014-06-17 12:03:20 -07001629 }
1630
1631 int facing = -1;
1632 int deviceVersion = getDeviceVersion(cameraId, &facing);
1633
1634 switch(deviceVersion) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001635 case CAMERA_DEVICE_API_VERSION_1_0:
1636 case CAMERA_DEVICE_API_VERSION_3_0:
1637 case CAMERA_DEVICE_API_VERSION_3_1:
1638 if (apiVersion == API_VERSION_2) {
1639 ALOGV("%s: Camera id %d uses HAL version %d <3.2, doesn't support api2 without shim",
1640 __FUNCTION__, cameraId, deviceVersion);
1641 *isSupported = false;
1642 } else { // if (apiVersion == API_VERSION_1) {
1643 ALOGV("%s: Camera id %d uses older HAL before 3.2, but api1 is always supported",
1644 __FUNCTION__, cameraId);
1645 *isSupported = true;
1646 }
1647 break;
1648 case CAMERA_DEVICE_API_VERSION_3_2:
1649 case CAMERA_DEVICE_API_VERSION_3_3:
Zhijun He4afbdec2016-05-04 15:42:51 -07001650 case CAMERA_DEVICE_API_VERSION_3_4:
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001651 ALOGV("%s: Camera id %d uses HAL3.2 or newer, supports api1/api2 directly",
Igor Murashkin65d14b92014-06-17 12:03:20 -07001652 __FUNCTION__, cameraId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001653 *isSupported = true;
1654 break;
1655 case -1: {
1656 String8 msg = String8::format("Unknown camera ID %d", cameraId);
1657 ALOGE("%s: %s", __FUNCTION__, msg.string());
1658 return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.string());
Igor Murashkin65d14b92014-06-17 12:03:20 -07001659 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001660 default: {
1661 String8 msg = String8::format("Unknown device version %d for device %d",
1662 deviceVersion, cameraId);
1663 ALOGE("%s: %s", __FUNCTION__, msg.string());
1664 return STATUS_ERROR(ERROR_INVALID_OPERATION, msg.string());
1665 }
Igor Murashkin65d14b92014-06-17 12:03:20 -07001666 }
1667
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001668 return Status::ok();
Igor Murashkin65d14b92014-06-17 12:03:20 -07001669}
1670
Ruben Brunkcc776712015-02-17 20:18:47 -08001671void CameraService::removeByClient(const BasicClient* client) {
Igor Murashkinecf17e82012-10-02 16:05:11 -07001672 Mutex::Autolock lock(mServiceLock);
Ruben Brunkcc776712015-02-17 20:18:47 -08001673 for (auto& i : mActiveClientManager.getAll()) {
1674 auto clientSp = i->getValue();
1675 if (clientSp.get() == client) {
1676 mActiveClientManager.remove(i);
Igor Murashkin634a5152013-02-20 17:15:11 -08001677 }
Igor Murashkinecf17e82012-10-02 16:05:11 -07001678 }
Igor Murashkin634a5152013-02-20 17:15:11 -08001679}
1680
Ruben Brunkcc776712015-02-17 20:18:47 -08001681bool CameraService::evictClientIdByRemote(const wp<IBinder>& remote) {
1682 const int callingPid = getCallingPid();
1683 const int servicePid = getpid();
1684 bool ret = false;
1685 {
1686 // Acquire mServiceLock and prevent other clients from connecting
1687 std::unique_ptr<AutoConditionLock> lock =
1688 AutoConditionLock::waitAndAcquire(mServiceLockWrapper);
Igor Murashkin634a5152013-02-20 17:15:11 -08001689
Igor Murashkin634a5152013-02-20 17:15:11 -08001690
Ruben Brunkcc776712015-02-17 20:18:47 -08001691 std::vector<sp<BasicClient>> evicted;
1692 for (auto& i : mActiveClientManager.getAll()) {
1693 auto clientSp = i->getValue();
1694 if (clientSp.get() == nullptr) {
1695 ALOGE("%s: Dead client still in mActiveClientManager.", __FUNCTION__);
1696 mActiveClientManager.remove(i);
1697 continue;
1698 }
1699 if (remote == clientSp->getRemote() && (callingPid == servicePid ||
1700 callingPid == clientSp->getClientPid())) {
1701 mActiveClientManager.remove(i);
1702 evicted.push_back(clientSp);
Igor Murashkin634a5152013-02-20 17:15:11 -08001703
Ruben Brunkcc776712015-02-17 20:18:47 -08001704 // Notify the client of disconnection
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001705 clientSp->notifyError(
1706 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED,
Ruben Brunkcc776712015-02-17 20:18:47 -08001707 CaptureResultExtras());
Igor Murashkin634a5152013-02-20 17:15:11 -08001708 }
1709 }
1710
Ruben Brunkcc776712015-02-17 20:18:47 -08001711 // Do not hold mServiceLock while disconnecting clients, but retain the condition blocking
1712 // other clients from connecting in mServiceLockWrapper if held
1713 mServiceLock.unlock();
1714
Ruben Brunk36597b22015-03-20 22:15:57 -07001715 // Do not clear caller identity, remote caller should be client proccess
1716
Ruben Brunkcc776712015-02-17 20:18:47 -08001717 for (auto& i : evicted) {
1718 if (i.get() != nullptr) {
1719 i->disconnect();
1720 ret = true;
1721 }
Igor Murashkin634a5152013-02-20 17:15:11 -08001722 }
1723
Ruben Brunkcc776712015-02-17 20:18:47 -08001724 // Reacquire mServiceLock
1725 mServiceLock.lock();
Igor Murashkin634a5152013-02-20 17:15:11 -08001726
Ruben Brunkcc776712015-02-17 20:18:47 -08001727 } // lock is destroyed, allow further connect calls
1728
1729 return ret;
Igor Murashkinecf17e82012-10-02 16:05:11 -07001730}
1731
Igor Murashkinecf17e82012-10-02 16:05:11 -07001732
Eino-Ville Talvalabad43582015-08-14 13:12:32 -07001733/**
1734 * Check camera capabilities, such as support for basic color operation
Eino-Ville Talvalad309fb92015-11-25 12:12:45 -08001735 * Also check that the device HAL version is still in support
Eino-Ville Talvalabad43582015-08-14 13:12:32 -07001736 */
1737int CameraService::checkCameraCapabilities(int id, camera_info info, int *latestStrangeCameraId) {
Yin-Chia Yeh654b4bf2015-12-08 12:19:31 -08001738 // device_version undefined in CAMERA_MODULE_API_VERSION_1_0,
1739 // All CAMERA_MODULE_API_VERSION_1_0 devices are backward-compatible
1740 if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_0) {
1741 // Verify the device version is in the supported range
1742 switch (info.device_version) {
1743 case CAMERA_DEVICE_API_VERSION_1_0:
1744 case CAMERA_DEVICE_API_VERSION_3_0:
1745 case CAMERA_DEVICE_API_VERSION_3_1:
1746 case CAMERA_DEVICE_API_VERSION_3_2:
1747 case CAMERA_DEVICE_API_VERSION_3_3:
Zhijun He4afbdec2016-05-04 15:42:51 -07001748 case CAMERA_DEVICE_API_VERSION_3_4:
Yin-Chia Yeh654b4bf2015-12-08 12:19:31 -08001749 // in support
1750 break;
1751 case CAMERA_DEVICE_API_VERSION_2_0:
1752 case CAMERA_DEVICE_API_VERSION_2_1:
1753 // no longer supported
1754 default:
1755 ALOGE("%s: Device %d has HAL version %x, which is not supported",
1756 __FUNCTION__, id, info.device_version);
1757 String8 msg = String8::format(
1758 "Unsupported device HAL version %x for device %d",
1759 info.device_version, id);
1760 logServiceError(msg.string(), NO_INIT);
1761 return NO_INIT;
1762 }
Eino-Ville Talvalad309fb92015-11-25 12:12:45 -08001763 }
1764
Eino-Ville Talvalabad43582015-08-14 13:12:32 -07001765 // Assume all devices pre-v3.3 are backward-compatible
1766 bool isBackwardCompatible = true;
1767 if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_0
1768 && info.device_version >= CAMERA_DEVICE_API_VERSION_3_3) {
1769 isBackwardCompatible = false;
1770 status_t res;
1771 camera_metadata_ro_entry_t caps;
1772 res = find_camera_metadata_ro_entry(
1773 info.static_camera_characteristics,
1774 ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
1775 &caps);
1776 if (res != 0) {
1777 ALOGW("%s: Unable to find camera capabilities for camera device %d",
1778 __FUNCTION__, id);
1779 caps.count = 0;
1780 }
1781 for (size_t i = 0; i < caps.count; i++) {
1782 if (caps.data.u8[i] ==
1783 ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE) {
1784 isBackwardCompatible = true;
1785 break;
1786 }
1787 }
1788 }
1789
1790 if (!isBackwardCompatible) {
1791 mNumberOfNormalCameras--;
1792 *latestStrangeCameraId = id;
1793 } else {
1794 if (id > *latestStrangeCameraId) {
1795 ALOGE("%s: Normal camera ID %d higher than strange camera ID %d. "
1796 "This is not allowed due backward-compatibility requirements",
1797 __FUNCTION__, id, *latestStrangeCameraId);
Eino-Ville Talvalad309fb92015-11-25 12:12:45 -08001798 logServiceError("Invalid order of camera devices", NO_INIT);
Eino-Ville Talvalabad43582015-08-14 13:12:32 -07001799 mNumberOfCameras = 0;
1800 mNumberOfNormalCameras = 0;
Eino-Ville Talvalad309fb92015-11-25 12:12:45 -08001801 return NO_INIT;
Eino-Ville Talvalabad43582015-08-14 13:12:32 -07001802 }
1803 }
1804 return OK;
1805}
1806
Ruben Brunkcc776712015-02-17 20:18:47 -08001807std::shared_ptr<CameraService::CameraState> CameraService::getCameraState(
1808 const String8& cameraId) const {
1809 std::shared_ptr<CameraState> state;
1810 {
1811 Mutex::Autolock lock(mCameraStatesLock);
1812 auto iter = mCameraStates.find(cameraId);
1813 if (iter != mCameraStates.end()) {
1814 state = iter->second;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001815 }
1816 }
Ruben Brunkcc776712015-02-17 20:18:47 -08001817 return state;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001818}
1819
Ruben Brunkcc776712015-02-17 20:18:47 -08001820sp<CameraService::BasicClient> CameraService::removeClientLocked(const String8& cameraId) {
1821 // Remove from active clients list
1822 auto clientDescriptorPtr = mActiveClientManager.remove(cameraId);
1823 if (clientDescriptorPtr == nullptr) {
1824 ALOGW("%s: Could not evict client, no client for camera ID %s", __FUNCTION__,
1825 cameraId.string());
1826 return sp<BasicClient>{nullptr};
1827 }
1828
1829 return clientDescriptorPtr->getValue();
Keun young Parkd8973a72012-03-28 14:13:09 -07001830}
1831
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001832void CameraService::doUserSwitch(const std::vector<int32_t>& newUserIds) {
Ruben Brunk36597b22015-03-20 22:15:57 -07001833 // Acquire mServiceLock and prevent other clients from connecting
1834 std::unique_ptr<AutoConditionLock> lock =
1835 AutoConditionLock::waitAndAcquire(mServiceLockWrapper);
1836
Ruben Brunk6267b532015-04-30 17:44:07 -07001837 std::set<userid_t> newAllowedUsers;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001838 for (size_t i = 0; i < newUserIds.size(); i++) {
1839 if (newUserIds[i] < 0) {
Ruben Brunk6267b532015-04-30 17:44:07 -07001840 ALOGE("%s: Bad user ID %d given during user switch, ignoring.",
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001841 __FUNCTION__, newUserIds[i]);
Ruben Brunk6267b532015-04-30 17:44:07 -07001842 return;
1843 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001844 newAllowedUsers.insert(static_cast<userid_t>(newUserIds[i]));
Ruben Brunk36597b22015-03-20 22:15:57 -07001845 }
1846
Ruben Brunka8ca9152015-04-07 14:23:40 -07001847
Ruben Brunk6267b532015-04-30 17:44:07 -07001848 if (newAllowedUsers == mAllowedUsers) {
1849 ALOGW("%s: Received notification of user switch with no updated user IDs.", __FUNCTION__);
1850 return;
1851 }
1852
1853 logUserSwitch(mAllowedUsers, newAllowedUsers);
1854
1855 mAllowedUsers = std::move(newAllowedUsers);
Ruben Brunk36597b22015-03-20 22:15:57 -07001856
1857 // Current user has switched, evict all current clients.
1858 std::vector<sp<BasicClient>> evicted;
1859 for (auto& i : mActiveClientManager.getAll()) {
1860 auto clientSp = i->getValue();
1861
1862 if (clientSp.get() == nullptr) {
1863 ALOGE("%s: Dead client still in mActiveClientManager.", __FUNCTION__);
1864 continue;
1865 }
1866
Ruben Brunk6267b532015-04-30 17:44:07 -07001867 // Don't evict clients that are still allowed.
1868 uid_t clientUid = clientSp->getClientUid();
1869 userid_t clientUserId = multiuser_get_user_id(clientUid);
1870 if (mAllowedUsers.find(clientUserId) != mAllowedUsers.end()) {
1871 continue;
1872 }
1873
Ruben Brunk36597b22015-03-20 22:15:57 -07001874 evicted.push_back(clientSp);
1875
1876 String8 curTime = getFormattedCurrentTime();
1877
1878 ALOGE("Evicting conflicting client for camera ID %s due to user change",
1879 i->getKey().string());
Ruben Brunka8ca9152015-04-07 14:23:40 -07001880
Ruben Brunk36597b22015-03-20 22:15:57 -07001881 // Log the clients evicted
Ruben Brunka8ca9152015-04-07 14:23:40 -07001882 logEvent(String8::format("EVICT device %s client held by package %s (PID %"
Ruben Brunk36597b22015-03-20 22:15:57 -07001883 PRId32 ", priority %" PRId32 ")\n - Evicted due to user switch.",
Ruben Brunka8ca9152015-04-07 14:23:40 -07001884 i->getKey().string(), String8{clientSp->getPackageName()}.string(),
1885 i->getOwnerId(), i->getPriority()));
Ruben Brunk36597b22015-03-20 22:15:57 -07001886
1887 }
1888
1889 // Do not hold mServiceLock while disconnecting clients, but retain the condition
1890 // blocking other clients from connecting in mServiceLockWrapper if held.
1891 mServiceLock.unlock();
1892
1893 // Clear caller identity temporarily so client disconnect PID checks work correctly
1894 int64_t token = IPCThreadState::self()->clearCallingIdentity();
1895
1896 for (auto& i : evicted) {
1897 i->disconnect();
1898 }
1899
1900 IPCThreadState::self()->restoreCallingIdentity(token);
1901
1902 // Reacquire mServiceLock
1903 mServiceLock.lock();
1904}
Ruben Brunkcc776712015-02-17 20:18:47 -08001905
Ruben Brunka8ca9152015-04-07 14:23:40 -07001906void CameraService::logEvent(const char* event) {
Ruben Brunkcc776712015-02-17 20:18:47 -08001907 String8 curTime = getFormattedCurrentTime();
Ruben Brunka8ca9152015-04-07 14:23:40 -07001908 Mutex::Autolock l(mLogLock);
1909 mEventLog.add(String8::format("%s : %s", curTime.string(), event));
Mathias Agopian65ab4712010-07-14 17:59:35 -07001910}
1911
Ruben Brunka8ca9152015-04-07 14:23:40 -07001912void CameraService::logDisconnected(const char* cameraId, int clientPid,
Svetoslav Ganov280405a2015-05-12 02:19:27 +00001913 const char* clientPackage) {
Ruben Brunkcc776712015-02-17 20:18:47 -08001914 // Log the clients evicted
Ruben Brunka8ca9152015-04-07 14:23:40 -07001915 logEvent(String8::format("DISCONNECT device %s client for package %s (PID %d)", cameraId,
Svetoslav Ganov280405a2015-05-12 02:19:27 +00001916 clientPackage, clientPid));
Ruben Brunka8ca9152015-04-07 14:23:40 -07001917}
1918
1919void CameraService::logConnected(const char* cameraId, int clientPid,
Svetoslav Ganov280405a2015-05-12 02:19:27 +00001920 const char* clientPackage) {
Ruben Brunka8ca9152015-04-07 14:23:40 -07001921 // Log the clients evicted
1922 logEvent(String8::format("CONNECT device %s client for package %s (PID %d)", cameraId,
Svetoslav Ganov280405a2015-05-12 02:19:27 +00001923 clientPackage, clientPid));
Ruben Brunka8ca9152015-04-07 14:23:40 -07001924}
1925
1926void CameraService::logRejected(const char* cameraId, int clientPid,
Svetoslav Ganov280405a2015-05-12 02:19:27 +00001927 const char* clientPackage, const char* reason) {
Ruben Brunka8ca9152015-04-07 14:23:40 -07001928 // Log the client rejected
1929 logEvent(String8::format("REJECT device %s client for package %s (PID %d), reason: (%s)",
Svetoslav Ganov280405a2015-05-12 02:19:27 +00001930 cameraId, clientPackage, clientPid, reason));
Ruben Brunka8ca9152015-04-07 14:23:40 -07001931}
1932
Ruben Brunk6267b532015-04-30 17:44:07 -07001933void CameraService::logUserSwitch(const std::set<userid_t>& oldUserIds,
1934 const std::set<userid_t>& newUserIds) {
1935 String8 newUsers = toString(newUserIds);
1936 String8 oldUsers = toString(oldUserIds);
Ruben Brunka8ca9152015-04-07 14:23:40 -07001937 // Log the new and old users
Ruben Brunk6267b532015-04-30 17:44:07 -07001938 logEvent(String8::format("USER_SWITCH previous allowed users: %s , current allowed users: %s",
1939 oldUsers.string(), newUsers.string()));
Ruben Brunka8ca9152015-04-07 14:23:40 -07001940}
1941
1942void CameraService::logDeviceRemoved(const char* cameraId, const char* reason) {
1943 // Log the device removal
1944 logEvent(String8::format("REMOVE device %s, reason: (%s)", cameraId, reason));
1945}
1946
1947void CameraService::logDeviceAdded(const char* cameraId, const char* reason) {
1948 // Log the device removal
1949 logEvent(String8::format("ADD device %s, reason: (%s)", cameraId, reason));
1950}
1951
1952void CameraService::logClientDied(int clientPid, const char* reason) {
1953 // Log the device removal
1954 logEvent(String8::format("DIED client(s) with PID %d, reason: (%s)", clientPid, reason));
Igor Murashkinecf17e82012-10-02 16:05:11 -07001955}
1956
Eino-Ville Talvala1527f072015-04-07 15:55:31 -07001957void CameraService::logServiceError(const char* msg, int errorCode) {
1958 String8 curTime = getFormattedCurrentTime();
Eino-Ville Talvalad309fb92015-11-25 12:12:45 -08001959 logEvent(String8::format("SERVICE ERROR: %s : %d (%s)", msg, errorCode, strerror(-errorCode)));
Eino-Ville Talvala1527f072015-04-07 15:55:31 -07001960}
1961
Ruben Brunk36597b22015-03-20 22:15:57 -07001962status_t CameraService::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
1963 uint32_t flags) {
1964
1965 const int pid = getCallingPid();
1966 const int selfPid = getpid();
1967
Mathias Agopian65ab4712010-07-14 17:59:35 -07001968 // Permission checks
1969 switch (code) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001970 case BnCameraService::NOTIFYSYSTEMEVENT: {
Ruben Brunk36597b22015-03-20 22:15:57 -07001971 if (pid != selfPid) {
1972 // Ensure we're being called by system_server, or similar process with
1973 // permissions to notify the camera service about system events
1974 if (!checkCallingPermission(
1975 String16("android.permission.CAMERA_SEND_SYSTEM_EVENTS"))) {
1976 const int uid = getCallingUid();
1977 ALOGE("Permission Denial: cannot send updates to camera service about system"
1978 " events from pid=%d, uid=%d", pid, uid);
1979 return PERMISSION_DENIED;
1980 }
1981 }
1982 break;
1983 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001984 }
1985
1986 return BnCameraService::onTransact(code, data, reply, flags);
1987}
1988
Mathias Agopian65ab4712010-07-14 17:59:35 -07001989// We share the media players for shutter and recording sound for all clients.
1990// A reference count is kept to determine when we will actually release the
1991// media players.
1992
Chih-Chung Changff4f55c2011-10-17 19:03:12 +08001993MediaPlayer* CameraService::newMediaPlayer(const char *file) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001994 MediaPlayer* mp = new MediaPlayer();
Andreas Huber1b86fe02014-01-29 11:13:26 -08001995 if (mp->setDataSource(NULL /* httpService */, file, NULL) == NO_ERROR) {
Eino-Ville Talvala60a78ac2012-01-05 15:34:53 -08001996 mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001997 mp->prepare();
1998 } else {
Steve Block29357bc2012-01-06 19:20:56 +00001999 ALOGE("Failed to load CameraService sounds: %s", file);
Mathias Agopian65ab4712010-07-14 17:59:35 -07002000 return NULL;
2001 }
2002 return mp;
2003}
2004
2005void CameraService::loadSound() {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -07002006 ATRACE_CALL();
2007
Mathias Agopian65ab4712010-07-14 17:59:35 -07002008 Mutex::Autolock lock(mSoundLock);
2009 LOG1("CameraService::loadSound ref=%d", mSoundRef);
2010 if (mSoundRef++) return;
2011
2012 mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
Chien-Yu Chen82104eb2015-10-14 11:29:31 -07002013 mSoundPlayer[SOUND_RECORDING_START] = newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");
2014 mSoundPlayer[SOUND_RECORDING_STOP] = newMediaPlayer("/system/media/audio/ui/VideoStop.ogg");
Mathias Agopian65ab4712010-07-14 17:59:35 -07002015}
2016
2017void CameraService::releaseSound() {
2018 Mutex::Autolock lock(mSoundLock);
2019 LOG1("CameraService::releaseSound ref=%d", mSoundRef);
2020 if (--mSoundRef) return;
2021
2022 for (int i = 0; i < NUM_SOUNDS; i++) {
2023 if (mSoundPlayer[i] != 0) {
2024 mSoundPlayer[i]->disconnect();
2025 mSoundPlayer[i].clear();
2026 }
2027 }
2028}
2029
2030void CameraService::playSound(sound_kind kind) {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -07002031 ATRACE_CALL();
2032
Mathias Agopian65ab4712010-07-14 17:59:35 -07002033 LOG1("playSound(%d)", kind);
2034 Mutex::Autolock lock(mSoundLock);
2035 sp<MediaPlayer> player = mSoundPlayer[kind];
2036 if (player != 0) {
Chih-Chung Chang8888a752011-10-20 10:47:26 +08002037 player->seekTo(0);
2038 player->start();
Mathias Agopian65ab4712010-07-14 17:59:35 -07002039 }
2040}
2041
2042// ----------------------------------------------------------------------------
2043
2044CameraService::Client::Client(const sp<CameraService>& cameraService,
Wu-cheng Lib7a67942010-08-17 15:45:37 -07002045 const sp<ICameraClient>& cameraClient,
Svetoslav Ganov280405a2015-05-12 02:19:27 +00002046 const String16& clientPackageName,
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002047 int cameraId, int cameraFacing,
2048 int clientPid, uid_t clientUid,
2049 int servicePid) :
Eino-Ville Talvalae992e752014-11-07 16:17:48 -08002050 CameraService::BasicClient(cameraService,
Marco Nelissenf8880202014-11-14 07:58:25 -08002051 IInterface::asBinder(cameraClient),
Svetoslav Ganov280405a2015-05-12 02:19:27 +00002052 clientPackageName,
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002053 cameraId, cameraFacing,
2054 clientPid, clientUid,
2055 servicePid)
Igor Murashkin634a5152013-02-20 17:15:11 -08002056{
Mathias Agopian65ab4712010-07-14 17:59:35 -07002057 int callingPid = getCallingPid();
Wu-cheng Li2fd24402012-02-23 19:01:00 -08002058 LOG1("Client::Client E (pid %d, id %d)", callingPid, cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -07002059
Igor Murashkin44cfcf02013-03-01 16:22:28 -08002060 mRemoteCallback = cameraClient;
Mathias Agopian65ab4712010-07-14 17:59:35 -07002061
Mathias Agopian65ab4712010-07-14 17:59:35 -07002062 cameraService->loadSound();
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002063
Wu-cheng Li2fd24402012-02-23 19:01:00 -08002064 LOG1("Client::Client X (pid %d, id %d)", callingPid, cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -07002065}
2066
Mathias Agopian65ab4712010-07-14 17:59:35 -07002067// tear down the client
2068CameraService::Client::~Client() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -07002069 ALOGV("~Client");
Igor Murashkin634a5152013-02-20 17:15:11 -08002070 mDestructionStarted = true;
2071
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002072 mCameraService->releaseSound();
Igor Murashkin036bc3e2012-10-08 15:09:46 -07002073 // unconditionally disconnect. function is idempotent
2074 Client::disconnect();
Mathias Agopian65ab4712010-07-14 17:59:35 -07002075}
2076
Igor Murashkin634a5152013-02-20 17:15:11 -08002077CameraService::BasicClient::BasicClient(const sp<CameraService>& cameraService,
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002078 const sp<IBinder>& remoteCallback,
Svetoslav Ganov280405a2015-05-12 02:19:27 +00002079 const String16& clientPackageName,
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002080 int cameraId, int cameraFacing,
2081 int clientPid, uid_t clientUid,
2082 int servicePid):
Svetoslav Ganov280405a2015-05-12 02:19:27 +00002083 mClientPackageName(clientPackageName), mDisconnected(false)
Igor Murashkin634a5152013-02-20 17:15:11 -08002084{
2085 mCameraService = cameraService;
Igor Murashkin44cfcf02013-03-01 16:22:28 -08002086 mRemoteBinder = remoteCallback;
Igor Murashkin634a5152013-02-20 17:15:11 -08002087 mCameraId = cameraId;
2088 mCameraFacing = cameraFacing;
2089 mClientPid = clientPid;
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002090 mClientUid = clientUid;
Igor Murashkin634a5152013-02-20 17:15:11 -08002091 mServicePid = servicePid;
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002092 mOpsActive = false;
Igor Murashkin634a5152013-02-20 17:15:11 -08002093 mDestructionStarted = false;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08002094
2095 // In some cases the calling code has no access to the package it runs under.
2096 // For example, NDK camera API.
2097 // In this case we will get the packages for the calling UID and pick the first one
2098 // for attributing the app op. This will work correctly for runtime permissions
2099 // as for legacy apps we will toggle the app op for all packages in the UID.
2100 // The caveat is that the operation may be attributed to the wrong package and
2101 // stats based on app ops may be slightly off.
2102 if (mClientPackageName.size() <= 0) {
2103 sp<IServiceManager> sm = defaultServiceManager();
2104 sp<IBinder> binder = sm->getService(String16(kPermissionServiceName));
2105 if (binder == 0) {
2106 ALOGE("Cannot get permission service");
2107 // Leave mClientPackageName unchanged (empty) and the further interaction
2108 // with camera will fail in BasicClient::startCameraOps
2109 return;
2110 }
2111
2112 sp<IPermissionController> permCtrl = interface_cast<IPermissionController>(binder);
2113 Vector<String16> packages;
2114
2115 permCtrl->getPackagesForUid(mClientUid, packages);
2116
2117 if (packages.isEmpty()) {
2118 ALOGE("No packages for calling UID");
2119 // Leave mClientPackageName unchanged (empty) and the further interaction
2120 // with camera will fail in BasicClient::startCameraOps
2121 return;
2122 }
2123 mClientPackageName = packages[0];
2124 }
Igor Murashkin634a5152013-02-20 17:15:11 -08002125}
2126
2127CameraService::BasicClient::~BasicClient() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -07002128 ALOGV("~BasicClient");
Igor Murashkin634a5152013-02-20 17:15:11 -08002129 mDestructionStarted = true;
2130}
2131
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08002132binder::Status CameraService::BasicClient::disconnect() {
2133 binder::Status res = Status::ok();
Ruben Brunk36597b22015-03-20 22:15:57 -07002134 if (mDisconnected) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08002135 return res;
Ruben Brunk36597b22015-03-20 22:15:57 -07002136 }
Eino-Ville Talvala24901c82015-09-04 14:15:58 -07002137 mDisconnected = true;
Ruben Brunkcc776712015-02-17 20:18:47 -08002138
2139 mCameraService->removeByClient(this);
2140 mCameraService->logDisconnected(String8::format("%d", mCameraId), mClientPid,
Svetoslav Ganov280405a2015-05-12 02:19:27 +00002141 String8(mClientPackageName));
Ruben Brunkcc776712015-02-17 20:18:47 -08002142
2143 sp<IBinder> remote = getRemote();
2144 if (remote != nullptr) {
2145 remote->unlinkToDeath(mCameraService);
2146 }
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07002147
2148 finishCameraOps();
Chien-Yu Chene4fe21b2016-08-04 12:42:40 -07002149 // Notify flashlight that a camera device is closed.
2150 mCameraService->mFlashlight->deviceClosed(String8::format("%d", mCameraId));
Ruben Brunkcc776712015-02-17 20:18:47 -08002151 ALOGI("%s: Disconnected client for camera %d for PID %d", __FUNCTION__, mCameraId, mClientPid);
2152
Igor Murashkincba2c162013-03-20 15:56:31 -07002153 // client shouldn't be able to call into us anymore
2154 mClientPid = 0;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08002155
2156 return res;
Igor Murashkin634a5152013-02-20 17:15:11 -08002157}
2158
Eino-Ville Talvalac4003962016-01-13 10:07:04 -08002159status_t CameraService::BasicClient::dump(int, const Vector<String16>&) {
2160 // No dumping of clients directly over Binder,
2161 // must go through CameraService::dump
2162 android_errorWriteWithInfoLog(SN_EVENT_LOG_ID, "26265403",
2163 IPCThreadState::self()->getCallingUid(), NULL, 0);
2164 return OK;
2165}
2166
Ruben Brunkcc776712015-02-17 20:18:47 -08002167String16 CameraService::BasicClient::getPackageName() const {
Svetoslav Ganov280405a2015-05-12 02:19:27 +00002168 return mClientPackageName;
Ruben Brunkcc776712015-02-17 20:18:47 -08002169}
2170
2171
2172int CameraService::BasicClient::getClientPid() const {
2173 return mClientPid;
2174}
2175
Ruben Brunk6267b532015-04-30 17:44:07 -07002176uid_t CameraService::BasicClient::getClientUid() const {
2177 return mClientUid;
2178}
2179
Ruben Brunk0bbf8b22015-04-30 14:35:42 -07002180bool CameraService::BasicClient::canCastToApiClient(apiLevel level) const {
2181 // Defaults to API2.
2182 return level == API_2;
2183}
2184
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002185status_t CameraService::BasicClient::startCameraOps() {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -07002186 ATRACE_CALL();
2187
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002188 int32_t res;
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07002189 // Notify app ops that the camera is not available
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002190 mOpsCallback = new OpsCallback(this);
2191
Igor Murashkine6800ce2013-03-04 17:25:57 -08002192 {
2193 ALOGV("%s: Start camera ops, package name = %s, client UID = %d",
Svetoslav Ganov280405a2015-05-12 02:19:27 +00002194 __FUNCTION__, String8(mClientPackageName).string(), mClientUid);
Igor Murashkine6800ce2013-03-04 17:25:57 -08002195 }
2196
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002197 mAppOpsManager.startWatchingMode(AppOpsManager::OP_CAMERA,
Svetoslav Ganov280405a2015-05-12 02:19:27 +00002198 mClientPackageName, mOpsCallback);
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002199 res = mAppOpsManager.startOp(AppOpsManager::OP_CAMERA,
Svetoslav Ganov280405a2015-05-12 02:19:27 +00002200 mClientUid, mClientPackageName);
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002201
Svetoslav28e8ef72015-05-11 19:21:31 -07002202 if (res == AppOpsManager::MODE_ERRORED) {
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002203 ALOGI("Camera %d: Access for \"%s\" has been revoked",
Svetoslav Ganov280405a2015-05-12 02:19:27 +00002204 mCameraId, String8(mClientPackageName).string());
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002205 return PERMISSION_DENIED;
2206 }
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07002207
Svetoslav28e8ef72015-05-11 19:21:31 -07002208 if (res == AppOpsManager::MODE_IGNORED) {
2209 ALOGI("Camera %d: Access for \"%s\" has been restricted",
2210 mCameraId, String8(mClientPackageName).string());
Eino-Ville Talvalae3afb2c2015-06-03 16:03:30 -07002211 // Return the same error as for device policy manager rejection
2212 return -EACCES;
Svetoslav28e8ef72015-05-11 19:21:31 -07002213 }
2214
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002215 mOpsActive = true;
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07002216
2217 // Transition device availability listeners from PRESENT -> NOT_AVAILABLE
2218 mCameraService->updateStatus(ICameraServiceListener::STATUS_NOT_AVAILABLE,
Ruben Brunkcc776712015-02-17 20:18:47 -08002219 String8::format("%d", mCameraId));
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07002220
Eino-Ville Talvala412fe562015-08-20 17:08:32 -07002221 // Transition device state to OPEN
2222 mCameraService->updateProxyDeviceState(ICameraServiceProxy::CAMERA_STATE_OPEN,
2223 String8::format("%d", mCameraId));
2224
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002225 return OK;
2226}
2227
2228status_t CameraService::BasicClient::finishCameraOps() {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -07002229 ATRACE_CALL();
2230
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07002231 // Check if startCameraOps succeeded, and if so, finish the camera op
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002232 if (mOpsActive) {
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07002233 // Notify app ops that the camera is available again
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002234 mAppOpsManager.finishOp(AppOpsManager::OP_CAMERA, mClientUid,
Svetoslav Ganov280405a2015-05-12 02:19:27 +00002235 mClientPackageName);
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002236 mOpsActive = false;
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07002237
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08002238 std::initializer_list<int32_t> rejected = {ICameraServiceListener::STATUS_NOT_PRESENT,
Ruben Brunkcc776712015-02-17 20:18:47 -08002239 ICameraServiceListener::STATUS_ENUMERATING};
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07002240
Ruben Brunkcc776712015-02-17 20:18:47 -08002241 // Transition to PRESENT if the camera is not in either of the rejected states
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07002242 mCameraService->updateStatus(ICameraServiceListener::STATUS_PRESENT,
Ruben Brunkcc776712015-02-17 20:18:47 -08002243 String8::format("%d", mCameraId), rejected);
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07002244
Eino-Ville Talvala412fe562015-08-20 17:08:32 -07002245 // Transition device state to CLOSED
2246 mCameraService->updateProxyDeviceState(ICameraServiceProxy::CAMERA_STATE_CLOSED,
2247 String8::format("%d", mCameraId));
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002248 }
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07002249 // Always stop watching, even if no camera op is active
Eino-Ville Talvalae992e752014-11-07 16:17:48 -08002250 if (mOpsCallback != NULL) {
2251 mAppOpsManager.stopWatchingMode(mOpsCallback);
2252 }
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002253 mOpsCallback.clear();
2254
2255 return OK;
2256}
2257
2258void CameraService::BasicClient::opChanged(int32_t op, const String16& packageName) {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -07002259 ATRACE_CALL();
2260
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002261 String8 name(packageName);
Svetoslav Ganov280405a2015-05-12 02:19:27 +00002262 String8 myName(mClientPackageName);
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002263
2264 if (op != AppOpsManager::OP_CAMERA) {
2265 ALOGW("Unexpected app ops notification received: %d", op);
2266 return;
2267 }
2268
2269 int32_t res;
2270 res = mAppOpsManager.checkOp(AppOpsManager::OP_CAMERA,
Svetoslav Ganov280405a2015-05-12 02:19:27 +00002271 mClientUid, mClientPackageName);
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002272 ALOGV("checkOp returns: %d, %s ", res,
2273 res == AppOpsManager::MODE_ALLOWED ? "ALLOWED" :
2274 res == AppOpsManager::MODE_IGNORED ? "IGNORED" :
2275 res == AppOpsManager::MODE_ERRORED ? "ERRORED" :
2276 "UNKNOWN");
2277
2278 if (res != AppOpsManager::MODE_ALLOWED) {
2279 ALOGI("Camera %d: Access for \"%s\" revoked", mCameraId,
2280 myName.string());
2281 // Reset the client PID to allow server-initiated disconnect,
2282 // and to prevent further calls by client.
2283 mClientPid = getCallingPid();
Jianing Weicb0652e2014-03-12 18:29:36 -07002284 CaptureResultExtras resultExtras; // a dummy result (invalid)
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08002285 notifyError(hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_SERVICE, resultExtras);
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002286 disconnect();
2287 }
2288}
2289
Mathias Agopian65ab4712010-07-14 17:59:35 -07002290// ----------------------------------------------------------------------------
2291
Ruben Brunkcc776712015-02-17 20:18:47 -08002292// Provide client strong pointer for callbacks.
2293sp<CameraService::Client> CameraService::Client::getClientFromCookie(void* user) {
2294 String8 cameraId = String8::format("%d", (int)(intptr_t) user);
2295 auto clientDescriptor = gCameraService->mActiveClientManager.get(cameraId);
2296 if (clientDescriptor != nullptr) {
2297 return sp<Client>{
2298 static_cast<Client*>(clientDescriptor->getValue().get())};
2299 }
2300 return sp<Client>{nullptr};
Mathias Agopian65ab4712010-07-14 17:59:35 -07002301}
2302
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08002303void CameraService::Client::notifyError(int32_t errorCode,
Jianing Weicb0652e2014-03-12 18:29:36 -07002304 const CaptureResultExtras& resultExtras) {
Eino-Ville Talvalad309fb92015-11-25 12:12:45 -08002305 (void) errorCode;
2306 (void) resultExtras;
Ranjith Kagathi Ananda3e600892015-10-08 16:00:33 -07002307 if (mRemoteCallback != NULL) {
2308 mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_RELEASED, 0);
2309 } else {
2310 ALOGE("mRemoteCallback is NULL!!");
2311 }
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002312}
2313
Igor Murashkin036bc3e2012-10-08 15:09:46 -07002314// NOTE: function is idempotent
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08002315binder::Status CameraService::Client::disconnect() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -07002316 ALOGV("Client::disconnect");
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08002317 return BasicClient::disconnect();
Wu-cheng Lie09591e2010-10-14 20:17:44 +08002318}
2319
Ruben Brunk0bbf8b22015-04-30 14:35:42 -07002320bool CameraService::Client::canCastToApiClient(apiLevel level) const {
2321 return level == API_1;
2322}
2323
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08002324CameraService::Client::OpsCallback::OpsCallback(wp<BasicClient> client):
2325 mClient(client) {
2326}
2327
2328void CameraService::Client::OpsCallback::opChanged(int32_t op,
2329 const String16& packageName) {
2330 sp<BasicClient> client = mClient.promote();
2331 if (client != NULL) {
2332 client->opChanged(op, packageName);
2333 }
2334}
2335
Mathias Agopian65ab4712010-07-14 17:59:35 -07002336// ----------------------------------------------------------------------------
Ruben Brunkcc776712015-02-17 20:18:47 -08002337// CameraState
2338// ----------------------------------------------------------------------------
2339
2340CameraService::CameraState::CameraState(const String8& id, int cost,
2341 const std::set<String8>& conflicting) : mId(id),
2342 mStatus(ICameraServiceListener::STATUS_PRESENT), mCost(cost), mConflicting(conflicting) {}
2343
2344CameraService::CameraState::~CameraState() {}
2345
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08002346int32_t CameraService::CameraState::getStatus() const {
Ruben Brunkcc776712015-02-17 20:18:47 -08002347 Mutex::Autolock lock(mStatusLock);
2348 return mStatus;
2349}
2350
2351CameraParameters CameraService::CameraState::getShimParams() const {
2352 return mShimParams;
2353}
2354
2355void CameraService::CameraState::setShimParams(const CameraParameters& params) {
2356 mShimParams = params;
2357}
2358
2359int CameraService::CameraState::getCost() const {
2360 return mCost;
2361}
2362
2363std::set<String8> CameraService::CameraState::getConflicting() const {
2364 return mConflicting;
2365}
2366
2367String8 CameraService::CameraState::getId() const {
2368 return mId;
2369}
2370
2371// ----------------------------------------------------------------------------
Ruben Brunk99e69712015-05-26 17:25:07 -07002372// ClientEventListener
2373// ----------------------------------------------------------------------------
2374
2375void CameraService::ClientEventListener::onClientAdded(
2376 const resource_policy::ClientDescriptor<String8,
2377 sp<CameraService::BasicClient>>& descriptor) {
Chih-Hung Hsieh5404ee12016-08-09 14:25:53 -07002378 const auto& basicClient = descriptor.getValue();
Ruben Brunk99e69712015-05-26 17:25:07 -07002379 if (basicClient.get() != nullptr) {
2380 BatteryNotifier& notifier(BatteryNotifier::getInstance());
2381 notifier.noteStartCamera(descriptor.getKey(),
2382 static_cast<int>(basicClient->getClientUid()));
2383 }
2384}
2385
2386void CameraService::ClientEventListener::onClientRemoved(
2387 const resource_policy::ClientDescriptor<String8,
2388 sp<CameraService::BasicClient>>& descriptor) {
Chih-Hung Hsieh5404ee12016-08-09 14:25:53 -07002389 const auto& basicClient = descriptor.getValue();
Ruben Brunk99e69712015-05-26 17:25:07 -07002390 if (basicClient.get() != nullptr) {
2391 BatteryNotifier& notifier(BatteryNotifier::getInstance());
2392 notifier.noteStopCamera(descriptor.getKey(),
2393 static_cast<int>(basicClient->getClientUid()));
2394 }
2395}
2396
2397
2398// ----------------------------------------------------------------------------
Ruben Brunkcc776712015-02-17 20:18:47 -08002399// CameraClientManager
2400// ----------------------------------------------------------------------------
2401
Ruben Brunk99e69712015-05-26 17:25:07 -07002402CameraService::CameraClientManager::CameraClientManager() {
2403 setListener(std::make_shared<ClientEventListener>());
2404}
2405
Ruben Brunkcc776712015-02-17 20:18:47 -08002406CameraService::CameraClientManager::~CameraClientManager() {}
2407
2408sp<CameraService::BasicClient> CameraService::CameraClientManager::getCameraClient(
2409 const String8& id) const {
2410 auto descriptor = get(id);
2411 if (descriptor == nullptr) {
2412 return sp<BasicClient>{nullptr};
2413 }
2414 return descriptor->getValue();
2415}
2416
2417String8 CameraService::CameraClientManager::toString() const {
2418 auto all = getAll();
2419 String8 ret("[");
2420 bool hasAny = false;
2421 for (auto& i : all) {
2422 hasAny = true;
2423 String8 key = i->getKey();
2424 int32_t cost = i->getCost();
2425 int32_t pid = i->getOwnerId();
2426 int32_t priority = i->getPriority();
2427 auto conflicting = i->getConflicting();
2428 auto clientSp = i->getValue();
2429 String8 packageName;
Eino-Ville Talvala022f0cb2015-05-19 16:31:16 -07002430 userid_t clientUserId = 0;
Ruben Brunkcc776712015-02-17 20:18:47 -08002431 if (clientSp.get() != nullptr) {
2432 packageName = String8{clientSp->getPackageName()};
Ruben Brunk6267b532015-04-30 17:44:07 -07002433 uid_t clientUid = clientSp->getClientUid();
2434 clientUserId = multiuser_get_user_id(clientUid);
Ruben Brunkcc776712015-02-17 20:18:47 -08002435 }
2436 ret.appendFormat("\n(Camera ID: %s, Cost: %" PRId32 ", PID: %" PRId32 ", Priority: %"
2437 PRId32 ", ", key.string(), cost, pid, priority);
2438
Ruben Brunk6267b532015-04-30 17:44:07 -07002439 if (clientSp.get() != nullptr) {
2440 ret.appendFormat("User Id: %d, ", clientUserId);
2441 }
Ruben Brunkcc776712015-02-17 20:18:47 -08002442 if (packageName.size() != 0) {
2443 ret.appendFormat("Client Package Name: %s", packageName.string());
2444 }
2445
2446 ret.append(", Conflicting Client Devices: {");
2447 for (auto& j : conflicting) {
2448 ret.appendFormat("%s, ", j.string());
2449 }
2450 ret.append("})");
2451 }
2452 if (hasAny) ret.append("\n");
2453 ret.append("]\n");
2454 return ret;
2455}
2456
2457CameraService::DescriptorPtr CameraService::CameraClientManager::makeClientDescriptor(
2458 const String8& key, const sp<BasicClient>& value, int32_t cost,
2459 const std::set<String8>& conflictingKeys, int32_t priority, int32_t ownerId) {
2460
2461 return std::make_shared<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>(
2462 key, value, cost, conflictingKeys, priority, ownerId);
2463}
2464
2465CameraService::DescriptorPtr CameraService::CameraClientManager::makeClientDescriptor(
2466 const sp<BasicClient>& value, const CameraService::DescriptorPtr& partial) {
2467 return makeClientDescriptor(partial->getKey(), value, partial->getCost(),
2468 partial->getConflicting(), partial->getPriority(), partial->getOwnerId());
2469}
2470
2471// ----------------------------------------------------------------------------
Mathias Agopian65ab4712010-07-14 17:59:35 -07002472
2473static const int kDumpLockRetries = 50;
2474static const int kDumpLockSleep = 60000;
2475
2476static bool tryLock(Mutex& mutex)
2477{
2478 bool locked = false;
2479 for (int i = 0; i < kDumpLockRetries; ++i) {
2480 if (mutex.tryLock() == NO_ERROR) {
2481 locked = true;
2482 break;
2483 }
2484 usleep(kDumpLockSleep);
2485 }
2486 return locked;
2487}
2488
2489status_t CameraService::dump(int fd, const Vector<String16>& args) {
Eino-Ville Talvalaa84bbe62015-09-08 17:59:17 -07002490 ATRACE_CALL();
2491
Ruben Brunka8ca9152015-04-07 14:23:40 -07002492 String8 result("Dump of the Camera Service:\n");
Mathias Agopian65ab4712010-07-14 17:59:35 -07002493 if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
dcashmanfefa6142015-09-09 13:43:01 -07002494 result = result.format("Permission Denial: "
Mathias Agopian65ab4712010-07-14 17:59:35 -07002495 "can't dump CameraService from pid=%d, uid=%d\n",
2496 getCallingPid(),
2497 getCallingUid());
Mathias Agopian65ab4712010-07-14 17:59:35 -07002498 write(fd, result.string(), result.size());
2499 } else {
2500 bool locked = tryLock(mServiceLock);
2501 // failed to lock - CameraService is probably deadlocked
2502 if (!locked) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -07002503 result.append("CameraService may be deadlocked\n");
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07002504 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07002505 }
2506
2507 bool hasClient = false;
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07002508 if (!mModule) {
2509 result = String8::format("No camera module available!\n");
2510 write(fd, result.string(), result.size());
Eino-Ville Talvala1527f072015-04-07 15:55:31 -07002511
2512 // Dump event log for error information
2513 dumpEventLog(fd);
2514
Kalle Lampila6ec3a152013-04-30 15:27:19 +03002515 if (locked) mServiceLock.unlock();
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07002516 return NO_ERROR;
2517 }
2518
Chien-Yu Chen676b21b2015-02-24 10:28:19 -08002519 result = String8::format("Camera module HAL API version: 0x%x\n", mModule->getHalApiVersion());
2520 result.appendFormat("Camera module API version: 0x%x\n", mModule->getModuleApiVersion());
2521 result.appendFormat("Camera module name: %s\n", mModule->getModuleName());
2522 result.appendFormat("Camera module author: %s\n", mModule->getModuleAuthor());
Ruben Brunkcc776712015-02-17 20:18:47 -08002523 result.appendFormat("Number of camera devices: %d\n", mNumberOfCameras);
Eino-Ville Talvala49c97052016-01-12 14:29:40 -08002524 result.appendFormat("Number of normal camera devices: %d\n", mNumberOfNormalCameras);
Ruben Brunkcc776712015-02-17 20:18:47 -08002525 String8 activeClientString = mActiveClientManager.toString();
2526 result.appendFormat("Active Camera Clients:\n%s", activeClientString.string());
Ruben Brunk6267b532015-04-30 17:44:07 -07002527 result.appendFormat("Allowed users:\n%s\n", toString(mAllowedUsers).string());
Ruben Brunkcc776712015-02-17 20:18:47 -08002528
Ruben Brunkf81648e2014-04-17 16:14:57 -07002529 sp<VendorTagDescriptor> desc = VendorTagDescriptor::getGlobalVendorTagDescriptor();
2530 if (desc == NULL) {
2531 result.appendFormat("Vendor tags left unimplemented.\n");
2532 } else {
2533 result.appendFormat("Vendor tag definitions:\n");
2534 }
2535
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07002536 write(fd, result.string(), result.size());
Ruben Brunkf81648e2014-04-17 16:14:57 -07002537
2538 if (desc != NULL) {
2539 desc->dump(fd, /*verbosity*/2, /*indentation*/4);
2540 }
2541
Eino-Ville Talvala1527f072015-04-07 15:55:31 -07002542 dumpEventLog(fd);
Ruben Brunkcc776712015-02-17 20:18:47 -08002543
2544 bool stateLocked = tryLock(mCameraStatesLock);
2545 if (!stateLocked) {
2546 result = String8::format("CameraStates in use, may be deadlocked\n");
2547 write(fd, result.string(), result.size());
2548 }
2549
2550 for (auto& state : mCameraStates) {
2551 String8 cameraId = state.first;
2552 result = String8::format("Camera %s information:\n", cameraId.string());
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07002553 camera_info info;
2554
Ruben Brunkcc776712015-02-17 20:18:47 -08002555 // TODO: Change getCameraInfo + HAL to use String cameraIds
2556 status_t rc = mModule->getCameraInfo(cameraIdToInt(cameraId), &info);
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07002557 if (rc != OK) {
2558 result.appendFormat(" Error reading static information!\n");
2559 write(fd, result.string(), result.size());
2560 } else {
2561 result.appendFormat(" Facing: %s\n",
Yin-Chia Yeh13cd59a2016-11-29 12:13:15 -08002562 info.facing == CAMERA_FACING_BACK ? "BACK" :
2563 info.facing == CAMERA_FACING_FRONT ? "FRONT" : "EXTERNAL");
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07002564 result.appendFormat(" Orientation: %d\n", info.orientation);
2565 int deviceVersion;
Chien-Yu Chen676b21b2015-02-24 10:28:19 -08002566 if (mModule->getModuleApiVersion() < CAMERA_MODULE_API_VERSION_2_0) {
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07002567 deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
2568 } else {
2569 deviceVersion = info.device_version;
2570 }
Ruben Brunkcc776712015-02-17 20:18:47 -08002571
2572 auto conflicting = state.second->getConflicting();
2573 result.appendFormat(" Resource Cost: %d\n", state.second->getCost());
2574 result.appendFormat(" Conflicting Devices:");
2575 for (auto& id : conflicting) {
Eino-Ville Talvalad309fb92015-11-25 12:12:45 -08002576 result.appendFormat(" %s", id.string());
Ruben Brunkcc776712015-02-17 20:18:47 -08002577 }
2578 if (conflicting.size() == 0) {
2579 result.appendFormat(" NONE");
2580 }
2581 result.appendFormat("\n");
2582
2583 result.appendFormat(" Device version: %#x\n", deviceVersion);
Eino-Ville Talvalad309fb92015-11-25 12:12:45 -08002584 if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_0) {
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07002585 result.appendFormat(" Device static metadata:\n");
2586 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -07002587 dump_indented_camera_metadata(info.static_camera_characteristics,
Ruben Brunkf81648e2014-04-17 16:14:57 -07002588 fd, /*verbosity*/2, /*indentation*/4);
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07002589 } else {
2590 write(fd, result.string(), result.size());
2591 }
Ruben Brunkcc776712015-02-17 20:18:47 -08002592
2593 CameraParameters p = state.second->getShimParams();
2594 if (!p.isEmpty()) {
2595 result = String8::format(" Camera1 API shim is using parameters:\n ");
2596 write(fd, result.string(), result.size());
2597 p.dump(fd, args);
2598 }
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07002599 }
2600
Ruben Brunkcc776712015-02-17 20:18:47 -08002601 auto clientDescriptor = mActiveClientManager.get(cameraId);
2602 if (clientDescriptor == nullptr) {
2603 result = String8::format(" Device %s is closed, no client instance\n",
2604 cameraId.string());
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07002605 write(fd, result.string(), result.size());
2606 continue;
2607 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07002608 hasClient = true;
Ruben Brunkcc776712015-02-17 20:18:47 -08002609 result = String8::format(" Device %s is open. Client instance dump:\n\n",
2610 cameraId.string());
2611 result.appendFormat("Client priority level: %d\n", clientDescriptor->getPriority());
2612 result.appendFormat("Client PID: %d\n", clientDescriptor->getOwnerId());
2613
2614 auto client = clientDescriptor->getValue();
2615 result.appendFormat("Client package: %s\n",
2616 String8(client->getPackageName()).string());
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07002617 write(fd, result.string(), result.size());
Ruben Brunkcc776712015-02-17 20:18:47 -08002618
Eino-Ville Talvalac4003962016-01-13 10:07:04 -08002619 client->dumpClient(fd, args);
Mathias Agopian65ab4712010-07-14 17:59:35 -07002620 }
Ruben Brunkcc776712015-02-17 20:18:47 -08002621
2622 if (stateLocked) mCameraStatesLock.unlock();
2623
Mathias Agopian65ab4712010-07-14 17:59:35 -07002624 if (!hasClient) {
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07002625 result = String8::format("\nNo active camera clients yet.\n");
2626 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07002627 }
2628
2629 if (locked) mServiceLock.unlock();
2630
Igor Murashkinff3e31d2013-10-23 16:40:06 -07002631 // Dump camera traces if there were any
2632 write(fd, "\n", 1);
2633 camera3::CameraTraces::dump(fd, args);
2634
Eino-Ville Talvalad89821e2016-04-20 11:23:50 -07002635 // Process dump arguments, if any
Mathias Agopian65ab4712010-07-14 17:59:35 -07002636 int n = args.size();
Eino-Ville Talvalad89821e2016-04-20 11:23:50 -07002637 String16 verboseOption("-v");
2638 String16 unreachableOption("--unreachable");
2639 for (int i = 0; i < n; i++) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -07002640 if (args[i] == verboseOption) {
Eino-Ville Talvalad89821e2016-04-20 11:23:50 -07002641 // change logging level
2642 if (i + 1 >= n) continue;
Mathias Agopian65ab4712010-07-14 17:59:35 -07002643 String8 levelStr(args[i+1]);
2644 int level = atoi(levelStr.string());
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07002645 result = String8::format("\nSetting log level to %d.\n", level);
Mathias Agopian65ab4712010-07-14 17:59:35 -07002646 setLogLevel(level);
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07002647 write(fd, result.string(), result.size());
Eino-Ville Talvalad89821e2016-04-20 11:23:50 -07002648 } else if (args[i] == unreachableOption) {
2649 // Dump memory analysis
2650 // TODO - should limit be an argument parameter?
2651 UnreachableMemoryInfo info;
2652 bool success = GetUnreachableMemory(info, /*limit*/ 10000);
2653 if (!success) {
2654 dprintf(fd, "\nUnable to dump unreachable memory. "
2655 "Try disabling SELinux enforcement.\n");
2656 } else {
2657 dprintf(fd, "\nDumping unreachable memory:\n");
2658 std::string s = info.ToString(/*log_contents*/ true);
2659 write(fd, s.c_str(), s.size());
2660 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07002661 }
2662 }
2663 }
2664 return NO_ERROR;
2665}
2666
Eino-Ville Talvala1527f072015-04-07 15:55:31 -07002667void CameraService::dumpEventLog(int fd) {
2668 String8 result = String8("\nPrior client events (most recent at top):\n");
2669
2670 Mutex::Autolock l(mLogLock);
2671 for (const auto& msg : mEventLog) {
2672 result.appendFormat(" %s\n", msg.string());
2673 }
2674
2675 if (mEventLog.size() == DEFAULT_EVENT_LOG_LENGTH) {
2676 result.append(" ...\n");
2677 } else if (mEventLog.size() == 0) {
2678 result.append(" [no events yet]\n");
2679 }
2680 result.append("\n");
2681
2682 write(fd, result.string(), result.size());
2683}
2684
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002685void CameraService::handleTorchClientBinderDied(const wp<IBinder> &who) {
Chien-Yu Chen88da5262015-02-17 13:56:46 -08002686 Mutex::Autolock al(mTorchClientMapMutex);
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002687 for (size_t i = 0; i < mTorchClientMap.size(); i++) {
2688 if (mTorchClientMap[i] == who) {
2689 // turn off the torch mode that was turned on by dead client
Chien-Yu Chen88da5262015-02-17 13:56:46 -08002690 String8 cameraId = mTorchClientMap.keyAt(i);
2691 status_t res = mFlashlight->setTorchMode(cameraId, false);
2692 if (res) {
2693 ALOGE("%s: torch client died but couldn't turn off torch: "
2694 "%s (%d)", __FUNCTION__, strerror(-res), res);
2695 return;
2696 }
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002697 mTorchClientMap.removeItemsAt(i);
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002698 break;
2699 }
2700 }
2701}
2702
Ruben Brunkcc776712015-02-17 20:18:47 -08002703/*virtual*/void CameraService::binderDied(const wp<IBinder> &who) {
Igor Murashkinecf17e82012-10-02 16:05:11 -07002704
Igor Murashkin294d0ec2012-10-05 10:44:57 -07002705 /**
Ruben Brunka8ca9152015-04-07 14:23:40 -07002706 * While tempting to promote the wp<IBinder> into a sp, it's actually not supported by the
2707 * binder driver
Igor Murashkin294d0ec2012-10-05 10:44:57 -07002708 */
2709
Ruben Brunka8ca9152015-04-07 14:23:40 -07002710 logClientDied(getCallingPid(), String8("Binder died unexpectedly"));
2711
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002712 // check torch client
2713 handleTorchClientBinderDied(who);
2714
2715 // check camera device client
Ruben Brunkcc776712015-02-17 20:18:47 -08002716 if(!evictClientIdByRemote(who)) {
2717 ALOGV("%s: Java client's binder death already cleaned up (normal case)", __FUNCTION__);
Igor Murashkinecf17e82012-10-02 16:05:11 -07002718 return;
2719 }
2720
Ruben Brunkcc776712015-02-17 20:18:47 -08002721 ALOGE("%s: Java client's binder died, removing it from the list of active clients",
2722 __FUNCTION__);
Igor Murashkinecf17e82012-10-02 16:05:11 -07002723}
2724
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08002725void CameraService::updateStatus(int32_t status, const String8& cameraId) {
Ruben Brunkcc776712015-02-17 20:18:47 -08002726 updateStatus(status, cameraId, {});
Igor Murashkinbfc99152013-02-27 12:55:20 -08002727}
2728
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08002729void CameraService::updateStatus(int32_t status, const String8& cameraId,
2730 std::initializer_list<int32_t> rejectSourceStates) {
Ruben Brunkcc776712015-02-17 20:18:47 -08002731 // Do not lock mServiceLock here or can get into a deadlock from
2732 // connect() -> disconnect -> updateStatus
2733
2734 auto state = getCameraState(cameraId);
2735
2736 if (state == nullptr) {
2737 ALOGW("%s: Could not update the status for %s, no such device exists", __FUNCTION__,
2738 cameraId.string());
2739 return;
Igor Murashkincba2c162013-03-20 15:56:31 -07002740 }
2741
Ruben Brunkcc776712015-02-17 20:18:47 -08002742 // Update the status for this camera state, then send the onStatusChangedCallbacks to each
2743 // of the listeners with both the mStatusStatus and mStatusListenerLock held
2744 state->updateStatus(status, cameraId, rejectSourceStates, [this]
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08002745 (const String8& cameraId, int32_t status) {
Ruben Brunkcc776712015-02-17 20:18:47 -08002746
Chien-Yu Chenf6463fc2015-04-07 15:11:31 -07002747 if (status != ICameraServiceListener::STATUS_ENUMERATING) {
2748 // Update torch status if it has a flash unit.
2749 Mutex::Autolock al(mTorchStatusMutex);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08002750 int32_t torchStatus;
Chien-Yu Chenf6463fc2015-04-07 15:11:31 -07002751 if (getTorchStatusLocked(cameraId, &torchStatus) !=
2752 NAME_NOT_FOUND) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08002753 int32_t newTorchStatus =
Chien-Yu Chenf6463fc2015-04-07 15:11:31 -07002754 status == ICameraServiceListener::STATUS_PRESENT ?
2755 ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF :
2756 ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE;
2757 if (torchStatus != newTorchStatus) {
2758 onTorchStatusChangedLocked(cameraId, newTorchStatus);
2759 }
2760 }
Ruben Brunkcc776712015-02-17 20:18:47 -08002761 }
2762
2763 Mutex::Autolock lock(mStatusListenerLock);
2764
2765 for (auto& listener : mListenerList) {
2766 // TODO: Refactor status listeners to use strings for Camera IDs and remove this.
2767 int id = cameraIdToInt(cameraId);
2768 if (id != -1) listener->onStatusChanged(status, id);
2769 }
2770 });
Igor Murashkincba2c162013-03-20 15:56:31 -07002771}
2772
Eino-Ville Talvala412fe562015-08-20 17:08:32 -07002773void CameraService::updateProxyDeviceState(ICameraServiceProxy::CameraState newState,
2774 const String8& cameraId) {
2775 sp<ICameraServiceProxy> proxyBinder = getCameraServiceProxy();
2776 if (proxyBinder == nullptr) return;
2777 String16 id(cameraId);
2778 proxyBinder->notifyCameraState(id, newState);
2779}
2780
Chien-Yu Chen88da5262015-02-17 13:56:46 -08002781status_t CameraService::getTorchStatusLocked(
2782 const String8& cameraId,
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08002783 int32_t *status) const {
Chien-Yu Chen88da5262015-02-17 13:56:46 -08002784 if (!status) {
2785 return BAD_VALUE;
2786 }
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002787 ssize_t index = mTorchStatusMap.indexOfKey(cameraId);
2788 if (index == NAME_NOT_FOUND) {
Chien-Yu Chen88da5262015-02-17 13:56:46 -08002789 // invalid camera ID or the camera doesn't have a flash unit
2790 return NAME_NOT_FOUND;
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002791 }
2792
Chien-Yu Chen88da5262015-02-17 13:56:46 -08002793 *status = mTorchStatusMap.valueAt(index);
2794 return OK;
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002795}
2796
Chien-Yu Chen88da5262015-02-17 13:56:46 -08002797status_t CameraService::setTorchStatusLocked(const String8& cameraId,
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08002798 int32_t status) {
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002799 ssize_t index = mTorchStatusMap.indexOfKey(cameraId);
2800 if (index == NAME_NOT_FOUND) {
2801 return BAD_VALUE;
2802 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08002803 int32_t& item =
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002804 mTorchStatusMap.editValueAt(index);
2805 item = status;
2806
2807 return OK;
2808}
2809
Mathias Agopian65ab4712010-07-14 17:59:35 -07002810}; // namespace android