blob: 9632ea956c9790bec9c2060b9e48bc955fea7fb9 [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"
Iliyan Malchev8951a972011-04-14 16:55:59 -070018//#define LOG_NDEBUG 0
Mathias Agopian65ab4712010-07-14 17:59:35 -070019
Ruben Brunkcc776712015-02-17 20:18:47 -080020#include <algorithm>
21#include <climits>
Mathias Agopian65ab4712010-07-14 17:59:35 -070022#include <stdio.h>
Ruben Brunkcc776712015-02-17 20:18:47 -080023#include <cstring>
24#include <ctime>
25#include <string>
Mathias Agopian65ab4712010-07-14 17:59:35 -070026#include <sys/types.h>
Ruben Brunkcc776712015-02-17 20:18:47 -080027#include <inttypes.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070028#include <pthread.h>
29
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -080030#include <binder/AppOpsManager.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070031#include <binder/IPCThreadState.h>
32#include <binder/IServiceManager.h>
33#include <binder/MemoryBase.h>
34#include <binder/MemoryHeapBase.h>
Ruben Brunkcc776712015-02-17 20:18:47 -080035#include <binder/ProcessInfoService.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070036#include <cutils/atomic.h>
Nipun Kwatrab5ca4612010-09-11 19:31:10 -070037#include <cutils/properties.h>
Amith Yamasani228711d2015-02-13 13:25:39 -080038#include <cutils/multiuser.h>
Mathias Agopiandf712ea2012-02-25 18:48:35 -080039#include <gui/Surface.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070040#include <hardware/hardware.h>
41#include <media/AudioSystem.h>
Andreas Huber1b86fe02014-01-29 11:13:26 -080042#include <media/IMediaHTTPService.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070043#include <media/mediaplayer.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070044#include <utils/Errors.h>
45#include <utils/Log.h>
46#include <utils/String16.h>
Ruben Brunkd1176ef2014-02-21 10:51:38 -080047#include <utils/Trace.h>
48#include <system/camera_vendor_tags.h>
Ruben Brunkb2119af2014-05-09 19:57:56 -070049#include <system/camera_metadata.h>
50#include <system/camera.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070051
52#include "CameraService.h"
Eino-Ville Talvala7b82efe2013-07-25 17:12:35 -070053#include "api1/CameraClient.h"
54#include "api1/Camera2Client.h"
55#include "api_pro/ProCamera2Client.h"
56#include "api2/CameraDeviceClient.h"
Igor Murashkinff3e31d2013-10-23 16:40:06 -070057#include "utils/CameraTraces.h"
Igor Murashkin98e24722013-06-19 19:51:04 -070058#include "CameraDeviceFactory.h"
Mathias Agopian65ab4712010-07-14 17:59:35 -070059
60namespace android {
61
62// ----------------------------------------------------------------------------
63// Logging support -- this is for debugging only
64// Use "adb shell dumpsys media.camera -v 1" to change it.
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -070065volatile int32_t gLogLevel = 0;
Mathias Agopian65ab4712010-07-14 17:59:35 -070066
Steve Blockb8a80522011-12-20 16:23:08 +000067#define LOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__);
68#define LOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__);
Mathias Agopian65ab4712010-07-14 17:59:35 -070069
70static void setLogLevel(int level) {
71 android_atomic_write(level, &gLogLevel);
72}
73
74// ----------------------------------------------------------------------------
75
Igor Murashkincba2c162013-03-20 15:56:31 -070076extern "C" {
77static void camera_device_status_change(
78 const struct camera_module_callbacks* callbacks,
79 int camera_id,
80 int new_status) {
81 sp<CameraService> cs = const_cast<CameraService*>(
Ruben Brunkcc776712015-02-17 20:18:47 -080082 static_cast<const CameraService*>(callbacks));
Igor Murashkincba2c162013-03-20 15:56:31 -070083
Ruben Brunkcc776712015-02-17 20:18:47 -080084 cs->onDeviceStatusChanged(static_cast<camera_device_status_t>(camera_id),
85 static_cast<camera_device_status_t>(new_status));
Igor Murashkincba2c162013-03-20 15:56:31 -070086}
Chien-Yu Chen3068d732015-02-09 13:29:57 -080087
88static void torch_mode_status_change(
89 const struct camera_module_callbacks* callbacks,
90 const char* camera_id,
91 int new_status) {
92 if (!callbacks || !camera_id) {
93 ALOGE("%s invalid parameters. callbacks %p, camera_id %p", __FUNCTION__,
94 callbacks, camera_id);
95 }
96 sp<CameraService> cs = const_cast<CameraService*>(
97 static_cast<const CameraService*>(callbacks));
98
99 ICameraServiceListener::TorchStatus status;
100 switch (new_status) {
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800101 case TORCH_MODE_STATUS_NOT_AVAILABLE:
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800102 status = ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE;
103 break;
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800104 case TORCH_MODE_STATUS_AVAILABLE_OFF:
105 status = ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF;
106 break;
107 case TORCH_MODE_STATUS_AVAILABLE_ON:
108 status = ICameraServiceListener::TORCH_STATUS_AVAILABLE_ON;
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800109 break;
110 default:
111 ALOGE("Unknown torch status %d", new_status);
112 return;
113 }
114
115 cs->onTorchStatusChanged(
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800116 String8(camera_id),
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800117 status);
118}
Igor Murashkincba2c162013-03-20 15:56:31 -0700119} // extern "C"
120
Mathias Agopian65ab4712010-07-14 17:59:35 -0700121// ----------------------------------------------------------------------------
122
123// This is ugly and only safe if we never re-create the CameraService, but
124// should be ok for now.
125static CameraService *gCameraService;
126
127CameraService::CameraService()
Ruben Brunkcc776712015-02-17 20:18:47 -0800128 : mEventLog(DEFAULT_EVICTION_LOG_LENGTH), mSoundRef(0), mModule(0), mFlashlight(0)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700129{
Steve Blockdf64d152012-01-04 20:05:49 +0000130 ALOGI("CameraService started (pid=%d)", getpid());
Mathias Agopian65ab4712010-07-14 17:59:35 -0700131 gCameraService = this;
Igor Murashkinbfc99152013-02-27 12:55:20 -0800132
Igor Murashkincba2c162013-03-20 15:56:31 -0700133 this->camera_device_status_change = android::camera_device_status_change;
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800134 this->torch_mode_status_change = android::torch_mode_status_change;
135
Ruben Brunkcc776712015-02-17 20:18:47 -0800136 mServiceLockWrapper = std::make_shared<WaitableMutexWrapper>(&mServiceLock);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700137}
138
Iliyan Malchev8951a972011-04-14 16:55:59 -0700139void CameraService::onFirstRef()
140{
Ruben Brunkcc776712015-02-17 20:18:47 -0800141 ALOGI("CameraService process starting");
Igor Murashkin634a5152013-02-20 17:15:11 -0800142
Iliyan Malchev8951a972011-04-14 16:55:59 -0700143 BnCameraService::onFirstRef();
144
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800145 camera_module_t *rawModule;
Iliyan Malchev8951a972011-04-14 16:55:59 -0700146 if (hw_get_module(CAMERA_HARDWARE_MODULE_ID,
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800147 (const hw_module_t **)&rawModule) < 0) {
Steve Block29357bc2012-01-06 19:20:56 +0000148 ALOGE("Could not load camera HAL module");
Iliyan Malchev8951a972011-04-14 16:55:59 -0700149 mNumberOfCameras = 0;
150 }
151 else {
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800152 mModule = new CameraModule(rawModule);
Chien-Yu Chen676b21b2015-02-24 10:28:19 -0800153 ALOGI("Loaded \"%s\" camera module", mModule->getModuleName());
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800154 mNumberOfCameras = mModule->getNumberOfCameras();
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800155
156 mFlashlight = new CameraFlashlight(*mModule, *this);
157 status_t res = mFlashlight->findFlashUnits();
158 if (res) {
159 // impossible because we haven't open any camera devices.
Ruben Brunkcc776712015-02-17 20:18:47 -0800160 ALOGE("Failed to find flash units.");
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800161 }
162
Iliyan Malchev8951a972011-04-14 16:55:59 -0700163 for (int i = 0; i < mNumberOfCameras; i++) {
Ruben Brunkcc776712015-02-17 20:18:47 -0800164 String8 cameraId = String8::format("%d", i);
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800165
Ruben Brunkcc776712015-02-17 20:18:47 -0800166 // Defaults to use for cost and conflicting devices
167 int cost = 100;
168 char** conflicting_devices = nullptr;
169 size_t conflicting_devices_length = 0;
170
171 // If using post-2.4 module version, query the cost + conflicting devices from the HAL
Chien-Yu Chen676b21b2015-02-24 10:28:19 -0800172 if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_4) {
Ruben Brunkcc776712015-02-17 20:18:47 -0800173 struct camera_info info;
174 status_t rc = mModule->getCameraInfo(i, &info);
175 if (rc == NO_ERROR) {
176 cost = info.resource_cost;
177 conflicting_devices = info.conflicting_devices;
178 conflicting_devices_length = info.conflicting_devices_length;
179 } else {
180 ALOGE("%s: Received error loading camera info for device %d, cost and"
181 " conflicting devices fields set to defaults for this device.",
182 __FUNCTION__, i);
183 }
184 }
185
186 std::set<String8> conflicting;
187 for (size_t i = 0; i < conflicting_devices_length; i++) {
188 conflicting.emplace(String8(conflicting_devices[i]));
189 }
190
191 // Initialize state for each camera device
192 {
193 Mutex::Autolock lock(mCameraStatesLock);
194 mCameraStates.emplace(cameraId, std::make_shared<CameraState>(cameraId, cost,
195 conflicting));
196 }
197
198 if (mFlashlight->hasFlashUnit(cameraId)) {
199 mTorchStatusMap.add(cameraId,
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800200 ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF);
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800201 }
Iliyan Malchev8951a972011-04-14 16:55:59 -0700202 }
Igor Murashkincba2c162013-03-20 15:56:31 -0700203
Chien-Yu Chen676b21b2015-02-24 10:28:19 -0800204 if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_1) {
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800205 mModule->setCallbacks(this);
Igor Murashkincba2c162013-03-20 15:56:31 -0700206 }
Igor Murashkin98e24722013-06-19 19:51:04 -0700207
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800208 VendorTagDescriptor::clearGlobalVendorTagDescriptor();
209
Chien-Yu Chen676b21b2015-02-24 10:28:19 -0800210 if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_2) {
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800211 setUpVendorTags();
212 }
213
Igor Murashkin98e24722013-06-19 19:51:04 -0700214 CameraDeviceFactory::registerService(this);
Iliyan Malchev8951a972011-04-14 16:55:59 -0700215 }
216}
217
Mathias Agopian65ab4712010-07-14 17:59:35 -0700218CameraService::~CameraService() {
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800219 if (mModule) {
220 delete mModule;
Ruben Brunkcc776712015-02-17 20:18:47 -0800221 mModule = nullptr;
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800222 }
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800223 VendorTagDescriptor::clearGlobalVendorTagDescriptor();
Ruben Brunkcc776712015-02-17 20:18:47 -0800224 gCameraService = nullptr;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700225}
226
Ruben Brunkcc776712015-02-17 20:18:47 -0800227void CameraService::onDeviceStatusChanged(camera_device_status_t cameraId,
228 camera_device_status_t newStatus) {
229 ALOGI("%s: Status changed for cameraId=%d, newStatus=%d", __FUNCTION__,
Igor Murashkincba2c162013-03-20 15:56:31 -0700230 cameraId, newStatus);
231
Ruben Brunkcc776712015-02-17 20:18:47 -0800232 String8 id = String8::format("%d", cameraId);
233 std::shared_ptr<CameraState> state = getCameraState(id);
234
235 if (state == nullptr) {
Igor Murashkincba2c162013-03-20 15:56:31 -0700236 ALOGE("%s: Bad camera ID %d", __FUNCTION__, cameraId);
237 return;
238 }
239
Ruben Brunkcc776712015-02-17 20:18:47 -0800240 ICameraServiceListener::Status oldStatus = state->getStatus();
241
242 if (oldStatus == static_cast<ICameraServiceListener::Status>(newStatus)) {
243 ALOGE("%s: State transition to the same status %#x not allowed", __FUNCTION__, newStatus);
Igor Murashkincba2c162013-03-20 15:56:31 -0700244 return;
245 }
246
Igor Murashkincba2c162013-03-20 15:56:31 -0700247 if (newStatus == CAMERA_DEVICE_STATUS_NOT_PRESENT) {
Ruben Brunkcc776712015-02-17 20:18:47 -0800248 sp<BasicClient> clientToDisconnect;
Igor Murashkincba2c162013-03-20 15:56:31 -0700249 {
Ruben Brunkcc776712015-02-17 20:18:47 -0800250 // Don't do this in updateStatus to avoid deadlock over mServiceLock
251 Mutex::Autolock lock(mServiceLock);
Igor Murashkincba2c162013-03-20 15:56:31 -0700252
Ruben Brunkcc776712015-02-17 20:18:47 -0800253 // Set the device status to NOT_PRESENT, clients will no longer be able to connect
254 // to this device until the status changes
255 updateStatus(ICameraServiceListener::STATUS_NOT_PRESENT, id);
Ruben Brunkb2119af2014-05-09 19:57:56 -0700256
Ruben Brunkcc776712015-02-17 20:18:47 -0800257 // Remove cached shim parameters
258 state->setShimParams(CameraParameters());
Igor Murashkincba2c162013-03-20 15:56:31 -0700259
Ruben Brunkcc776712015-02-17 20:18:47 -0800260 // Remove the client from the list of active clients
261 clientToDisconnect = removeClientLocked(id);
262
263 // Notify the client of disconnection
264 clientToDisconnect->notifyError(ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED,
265 CaptureResultExtras{});
Igor Murashkincba2c162013-03-20 15:56:31 -0700266 }
267
Ruben Brunkcc776712015-02-17 20:18:47 -0800268 ALOGI("%s: Client for camera ID %s evicted due to device status change from HAL",
269 __FUNCTION__, id.string());
Igor Murashkincba2c162013-03-20 15:56:31 -0700270
Ruben Brunkcc776712015-02-17 20:18:47 -0800271 // Disconnect client
272 if (clientToDisconnect.get() != nullptr) {
273 // Ensure not in binder RPC so client disconnect PID checks work correctly
274 LOG_ALWAYS_FATAL_IF(getCallingPid() != getpid(),
275 "onDeviceStatusChanged must be called from the camera service process!");
276 clientToDisconnect->disconnect();
Igor Murashkincba2c162013-03-20 15:56:31 -0700277 }
278
Ruben Brunkcc776712015-02-17 20:18:47 -0800279 } else {
280 updateStatus(static_cast<ICameraServiceListener::Status>(newStatus), id);
Igor Murashkincba2c162013-03-20 15:56:31 -0700281 }
282
Igor Murashkincba2c162013-03-20 15:56:31 -0700283}
284
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800285void CameraService::onTorchStatusChanged(const String8& cameraId,
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800286 ICameraServiceListener::TorchStatus newStatus) {
287 Mutex::Autolock al(mTorchStatusMutex);
288 onTorchStatusChangedLocked(cameraId, newStatus);
289}
290
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800291void CameraService::onTorchStatusChangedLocked(const String8& cameraId,
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800292 ICameraServiceListener::TorchStatus newStatus) {
293 ALOGI("%s: Torch status changed for cameraId=%s, newStatus=%d",
294 __FUNCTION__, cameraId.string(), newStatus);
295
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800296 ICameraServiceListener::TorchStatus status;
297 status_t res = getTorchStatusLocked(cameraId, &status);
298 if (res) {
299 ALOGE("%s: cannot get torch status of camera %s", cameraId.string());
300 return;
301 }
302 if (status == newStatus) {
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800303 ALOGE("%s: Torch state transition to the same status 0x%x not allowed",
304 __FUNCTION__, (uint32_t)newStatus);
305 return;
306 }
307
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800308 res = setTorchStatusLocked(cameraId, newStatus);
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800309 if (res) {
310 ALOGE("%s: Failed to set the torch status", __FUNCTION__,
311 (uint32_t)newStatus);
312 return;
313 }
314
Ruben Brunkcc776712015-02-17 20:18:47 -0800315 {
316 Mutex::Autolock lock(mStatusListenerLock);
317 for (auto& i : mListenerList) {
318 i->onTorchStatusChanged(newStatus, String16{cameraId});
319 }
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800320 }
321}
322
323
Mathias Agopian65ab4712010-07-14 17:59:35 -0700324int32_t CameraService::getNumberOfCameras() {
325 return mNumberOfCameras;
326}
327
328status_t CameraService::getCameraInfo(int cameraId,
329 struct CameraInfo* cameraInfo) {
Iliyan Malchev8951a972011-04-14 16:55:59 -0700330 if (!mModule) {
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700331 return -ENODEV;
Iliyan Malchev8951a972011-04-14 16:55:59 -0700332 }
333
Mathias Agopian65ab4712010-07-14 17:59:35 -0700334 if (cameraId < 0 || cameraId >= mNumberOfCameras) {
335 return BAD_VALUE;
336 }
337
Iliyan Malchev8951a972011-04-14 16:55:59 -0700338 struct camera_info info;
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -0700339 status_t rc = filterGetInfoErrorCode(
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800340 mModule->getCameraInfo(cameraId, &info));
Iliyan Malchev8951a972011-04-14 16:55:59 -0700341 cameraInfo->facing = info.facing;
342 cameraInfo->orientation = info.orientation;
343 return rc;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700344}
345
Ruben Brunkcc776712015-02-17 20:18:47 -0800346int CameraService::cameraIdToInt(const String8& cameraId) {
347 errno = 0;
348 size_t pos = 0;
349 int ret = stoi(std::string{cameraId.string()}, &pos);
350 if (errno != 0 || pos != cameraId.size()) {
351 return -1;
352 }
353 return ret;
354}
Ruben Brunkb2119af2014-05-09 19:57:56 -0700355
356status_t CameraService::generateShimMetadata(int cameraId, /*out*/CameraMetadata* cameraInfo) {
357 status_t ret = OK;
358 struct CameraInfo info;
359 if ((ret = getCameraInfo(cameraId, &info)) != OK) {
360 return ret;
361 }
362
363 CameraMetadata shimInfo;
364 int32_t orientation = static_cast<int32_t>(info.orientation);
365 if ((ret = shimInfo.update(ANDROID_SENSOR_ORIENTATION, &orientation, 1)) != OK) {
366 return ret;
367 }
368
369 uint8_t facing = (info.facing == CAMERA_FACING_FRONT) ?
370 ANDROID_LENS_FACING_FRONT : ANDROID_LENS_FACING_BACK;
371 if ((ret = shimInfo.update(ANDROID_LENS_FACING, &facing, 1)) != OK) {
372 return ret;
373 }
374
Igor Murashkin65d14b92014-06-17 12:03:20 -0700375 CameraParameters shimParams;
376 if ((ret = getLegacyParametersLazy(cameraId, /*out*/&shimParams)) != OK) {
377 // Error logged by callee
378 return ret;
Ruben Brunkb2119af2014-05-09 19:57:56 -0700379 }
380
381 Vector<Size> sizes;
Ruben Brunk152dbcf2014-06-12 19:11:45 -0700382 Vector<Size> jpegSizes;
Ruben Brunkb2119af2014-05-09 19:57:56 -0700383 Vector<int32_t> formats;
384 const char* supportedPreviewFormats;
Igor Murashkin65d14b92014-06-17 12:03:20 -0700385 {
386 shimParams.getSupportedPreviewSizes(/*out*/sizes);
387 shimParams.getSupportedPreviewFormats(/*out*/formats);
388 shimParams.getSupportedPictureSizes(/*out*/jpegSizes);
Ruben Brunkb2119af2014-05-09 19:57:56 -0700389 }
390
391 // Always include IMPLEMENTATION_DEFINED
392 formats.add(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED);
393
394 const size_t INTS_PER_CONFIG = 4;
395
396 // Build available stream configurations metadata
Ruben Brunk152dbcf2014-06-12 19:11:45 -0700397 size_t streamConfigSize = (sizes.size() * formats.size() + jpegSizes.size()) * INTS_PER_CONFIG;
398
399 Vector<int32_t> streamConfigs;
400 streamConfigs.setCapacity(streamConfigSize);
401
Ruben Brunkb2119af2014-05-09 19:57:56 -0700402 for (size_t i = 0; i < formats.size(); ++i) {
403 for (size_t j = 0; j < sizes.size(); ++j) {
Ruben Brunk152dbcf2014-06-12 19:11:45 -0700404 streamConfigs.add(formats[i]);
405 streamConfigs.add(sizes[j].width);
406 streamConfigs.add(sizes[j].height);
407 streamConfigs.add(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
Ruben Brunkb2119af2014-05-09 19:57:56 -0700408 }
409 }
410
Ruben Brunk152dbcf2014-06-12 19:11:45 -0700411 for (size_t i = 0; i < jpegSizes.size(); ++i) {
412 streamConfigs.add(HAL_PIXEL_FORMAT_BLOB);
413 streamConfigs.add(jpegSizes[i].width);
414 streamConfigs.add(jpegSizes[i].height);
415 streamConfigs.add(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
416 }
417
Ruben Brunkb2119af2014-05-09 19:57:56 -0700418 if ((ret = shimInfo.update(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
Ruben Brunk152dbcf2014-06-12 19:11:45 -0700419 streamConfigs.array(), streamConfigSize)) != OK) {
Ruben Brunkb2119af2014-05-09 19:57:56 -0700420 return ret;
421 }
422
423 int64_t fakeMinFrames[0];
424 // TODO: Fixme, don't fake min frame durations.
425 if ((ret = shimInfo.update(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
426 fakeMinFrames, 0)) != OK) {
427 return ret;
428 }
429
430 int64_t fakeStalls[0];
431 // TODO: Fixme, don't fake stall durations.
432 if ((ret = shimInfo.update(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
433 fakeStalls, 0)) != OK) {
434 return ret;
435 }
436
437 *cameraInfo = shimInfo;
438 return OK;
439}
440
Zhijun He2b59be82013-09-25 10:14:30 -0700441status_t CameraService::getCameraCharacteristics(int cameraId,
442 CameraMetadata* cameraInfo) {
443 if (!cameraInfo) {
444 ALOGE("%s: cameraInfo is NULL", __FUNCTION__);
445 return BAD_VALUE;
446 }
447
448 if (!mModule) {
449 ALOGE("%s: camera hardware module doesn't exist", __FUNCTION__);
450 return -ENODEV;
451 }
452
Zhijun He2b59be82013-09-25 10:14:30 -0700453 if (cameraId < 0 || cameraId >= mNumberOfCameras) {
454 ALOGE("%s: Invalid camera id: %d", __FUNCTION__, cameraId);
455 return BAD_VALUE;
456 }
457
458 int facing;
Ruben Brunkb2119af2014-05-09 19:57:56 -0700459 status_t ret = OK;
Chien-Yu Chen676b21b2015-02-24 10:28:19 -0800460 if (mModule->getModuleApiVersion() < CAMERA_MODULE_API_VERSION_2_0 ||
Ruben Brunkb2119af2014-05-09 19:57:56 -0700461 getDeviceVersion(cameraId, &facing) <= CAMERA_DEVICE_API_VERSION_2_1 ) {
462 /**
463 * Backwards compatibility mode for old HALs:
464 * - Convert CameraInfo into static CameraMetadata properties.
465 * - Retrieve cached CameraParameters for this camera. If none exist,
466 * attempt to open CameraClient and retrieve the CameraParameters.
467 * - Convert cached CameraParameters into static CameraMetadata
468 * properties.
469 */
470 ALOGI("%s: Switching to HAL1 shim implementation...", __FUNCTION__);
Zhijun He2b59be82013-09-25 10:14:30 -0700471
Ruben Brunkb2119af2014-05-09 19:57:56 -0700472 if ((ret = generateShimMetadata(cameraId, cameraInfo)) != OK) {
473 return ret;
474 }
Zhijun Hef05e50e2013-10-01 11:05:33 -0700475
Ruben Brunkb2119af2014-05-09 19:57:56 -0700476 } else {
477 /**
478 * Normal HAL 2.1+ codepath.
479 */
480 struct camera_info info;
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800481 ret = filterGetInfoErrorCode(mModule->getCameraInfo(cameraId, &info));
Ruben Brunkb2119af2014-05-09 19:57:56 -0700482 *cameraInfo = info.static_camera_characteristics;
483 }
Zhijun He2b59be82013-09-25 10:14:30 -0700484
485 return ret;
486}
487
Ruben Brunkcc776712015-02-17 20:18:47 -0800488int CameraService::getCallingPid() {
489 return IPCThreadState::self()->getCallingPid();
490}
491
492int CameraService::getCallingUid() {
493 return IPCThreadState::self()->getCallingUid();
494}
495
496String8 CameraService::getFormattedCurrentTime() {
497 time_t now = time(nullptr);
498 char formattedTime[64];
499 strftime(formattedTime, sizeof(formattedTime), "%m-%d %H:%M:%S", localtime(&now));
500 return String8(formattedTime);
501}
502
503int CameraService::getCameraPriorityFromProcState(int procState) {
504 // Find the priority for the camera usage based on the process state. Higher priority clients
505 // win for evictions.
506 // Note: Unlike the ordering for ActivityManager, persistent system processes will always lose
507 // the camera to the top/foreground applications.
508 switch(procState) {
509 case PROCESS_STATE_TOP: // User visible
510 return 100;
511 case PROCESS_STATE_IMPORTANT_FOREGROUND: // Foreground
512 return 90;
513 case PROCESS_STATE_PERSISTENT: // Persistent system services
514 case PROCESS_STATE_PERSISTENT_UI:
515 return 80;
516 case PROCESS_STATE_IMPORTANT_BACKGROUND: // "Important" background processes
517 return 70;
518 case PROCESS_STATE_BACKUP: // Everything else
519 case PROCESS_STATE_HEAVY_WEIGHT:
520 case PROCESS_STATE_SERVICE:
521 case PROCESS_STATE_RECEIVER:
522 case PROCESS_STATE_HOME:
523 case PROCESS_STATE_LAST_ACTIVITY:
524 case PROCESS_STATE_CACHED_ACTIVITY:
525 case PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
526 case PROCESS_STATE_CACHED_EMPTY:
527 return 1;
528 case PROCESS_STATE_NONEXISTENT:
529 return -1;
530 default:
531 ALOGE("%s: Received unknown process state from ActivityManagerService!", __FUNCTION__);
532 return -1;
533 }
534}
535
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800536status_t CameraService::getCameraVendorTagDescriptor(/*out*/sp<VendorTagDescriptor>& desc) {
537 if (!mModule) {
538 ALOGE("%s: camera hardware module doesn't exist", __FUNCTION__);
539 return -ENODEV;
540 }
541
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800542 desc = VendorTagDescriptor::getGlobalVendorTagDescriptor();
543 return OK;
544}
545
Igor Murashkin634a5152013-02-20 17:15:11 -0800546int CameraService::getDeviceVersion(int cameraId, int* facing) {
547 struct camera_info info;
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800548 if (mModule->getCameraInfo(cameraId, &info) != OK) {
Igor Murashkin634a5152013-02-20 17:15:11 -0800549 return -1;
550 }
551
552 int deviceVersion;
Chien-Yu Chen676b21b2015-02-24 10:28:19 -0800553 if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_0) {
Igor Murashkin634a5152013-02-20 17:15:11 -0800554 deviceVersion = info.device_version;
555 } else {
556 deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
557 }
558
559 if (facing) {
560 *facing = info.facing;
561 }
562
563 return deviceVersion;
564}
565
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -0700566status_t CameraService::filterGetInfoErrorCode(status_t err) {
567 switch(err) {
568 case NO_ERROR:
569 case -EINVAL:
570 return err;
571 default:
572 break;
573 }
574 return -ENODEV;
Igor Murashkinbfc99152013-02-27 12:55:20 -0800575}
576
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800577bool CameraService::setUpVendorTags() {
578 vendor_tag_ops_t vOps = vendor_tag_ops_t();
579
580 // Check if vendor operations have been implemented
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800581 if (!mModule->isVendorTagDefined()) {
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800582 ALOGI("%s: No vendor tags defined for this device.", __FUNCTION__);
583 return false;
584 }
585
586 ATRACE_BEGIN("camera3->get_metadata_vendor_tag_ops");
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800587 mModule->getVendorTagOps(&vOps);
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800588 ATRACE_END();
589
590 // Ensure all vendor operations are present
591 if (vOps.get_tag_count == NULL || vOps.get_all_tags == NULL ||
592 vOps.get_section_name == NULL || vOps.get_tag_name == NULL ||
593 vOps.get_tag_type == NULL) {
594 ALOGE("%s: Vendor tag operations not fully defined. Ignoring definitions."
595 , __FUNCTION__);
596 return false;
597 }
598
599 // Read all vendor tag definitions into a descriptor
600 sp<VendorTagDescriptor> desc;
601 status_t res;
602 if ((res = VendorTagDescriptor::createDescriptorFromOps(&vOps, /*out*/desc))
603 != OK) {
604 ALOGE("%s: Could not generate descriptor from vendor tag operations,"
605 "received error %s (%d). Camera clients will not be able to use"
606 "vendor tags", __FUNCTION__, strerror(res), res);
607 return false;
608 }
609
610 // Set the global descriptor to use with camera metadata
611 VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
612 return true;
613}
614
Ruben Brunkcc776712015-02-17 20:18:47 -0800615status_t CameraService::makeClient(const sp<CameraService>& cameraService,
616 const sp<IInterface>& cameraCb, const String16& packageName, const String8& cameraId,
617 int facing, int clientPid, uid_t clientUid, int servicePid, bool legacyMode,
618 int halVersion, int deviceVersion, apiLevel effectiveApiLevel,
619 /*out*/sp<BasicClient>* client) {
620
621 // TODO: Update CameraClients + HAL interface to use strings for Camera IDs
622 int id = cameraIdToInt(cameraId);
623 if (id == -1) {
624 ALOGE("%s: Invalid camera ID %s, cannot convert to integer.", __FUNCTION__,
625 cameraId.string());
626 return BAD_VALUE;
Ruben Brunkb2119af2014-05-09 19:57:56 -0700627 }
628
Ruben Brunkcc776712015-02-17 20:18:47 -0800629 if (halVersion < 0 || halVersion == deviceVersion) {
630 // Default path: HAL version is unspecified by caller, create CameraClient
631 // based on device version reported by the HAL.
632 switch(deviceVersion) {
633 case CAMERA_DEVICE_API_VERSION_1_0:
634 if (effectiveApiLevel == API_1) { // Camera1 API route
635 sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
636 *client = new CameraClient(cameraService, tmp, packageName, id, facing,
637 clientPid, clientUid, getpid(), legacyMode);
638 } else { // Camera2 API route
639 ALOGW("Camera using old HAL version: %d", deviceVersion);
640 return -EOPNOTSUPP;
641 }
642 break;
643 case CAMERA_DEVICE_API_VERSION_2_0:
644 case CAMERA_DEVICE_API_VERSION_2_1:
645 case CAMERA_DEVICE_API_VERSION_3_0:
646 case CAMERA_DEVICE_API_VERSION_3_1:
647 case CAMERA_DEVICE_API_VERSION_3_2:
648 case CAMERA_DEVICE_API_VERSION_3_3:
649 if (effectiveApiLevel == API_1) { // Camera1 API route
650 sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
651 *client = new Camera2Client(cameraService, tmp, packageName, id, facing,
652 clientPid, clientUid, servicePid, legacyMode);
653 } else { // Camera2 API route
654 sp<ICameraDeviceCallbacks> tmp =
655 static_cast<ICameraDeviceCallbacks*>(cameraCb.get());
656 *client = new CameraDeviceClient(cameraService, tmp, packageName, id,
657 facing, clientPid, clientUid, servicePid);
658 }
659 break;
660 default:
661 // Should not be reachable
662 ALOGE("Unknown camera device HAL version: %d", deviceVersion);
663 return INVALID_OPERATION;
664 }
665 } else {
666 // A particular HAL version is requested by caller. Create CameraClient
667 // based on the requested HAL version.
668 if (deviceVersion > CAMERA_DEVICE_API_VERSION_1_0 &&
669 halVersion == CAMERA_DEVICE_API_VERSION_1_0) {
670 // Only support higher HAL version device opened as HAL1.0 device.
671 sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
672 *client = new CameraClient(cameraService, tmp, packageName, id, facing,
673 clientPid, clientUid, servicePid, legacyMode);
674 } else {
675 // Other combinations (e.g. HAL3.x open as HAL2.x) are not supported yet.
676 ALOGE("Invalid camera HAL version %x: HAL %x device can only be"
677 " opened as HAL %x device", halVersion, deviceVersion,
678 CAMERA_DEVICE_API_VERSION_1_0);
679 return INVALID_OPERATION;
680 }
681 }
682 return NO_ERROR;
683}
684
685status_t CameraService::initializeShimMetadata(int cameraId) {
686 int uid = getCallingUid();
Ruben Brunkb2119af2014-05-09 19:57:56 -0700687
688 String16 internalPackageName("media");
Ruben Brunkcc776712015-02-17 20:18:47 -0800689 String8 id = String8::format("%d", cameraId);
690 status_t ret = NO_ERROR;
691 sp<Client> tmp = nullptr;
692 if ((ret = connectHelper<ICameraClient,Client>(sp<ICameraClient>{nullptr}, id,
693 static_cast<int>(CAMERA_HAL_API_VERSION_UNSPECIFIED), internalPackageName, uid, API_1,
694 false, true, tmp)) != NO_ERROR) {
695 ALOGE("%s: Error %d (%s) initializing shim metadata.", __FUNCTION__, ret, strerror(ret));
696 return ret;
Ruben Brunkb2119af2014-05-09 19:57:56 -0700697 }
Ruben Brunkcc776712015-02-17 20:18:47 -0800698 return NO_ERROR;
Ruben Brunkb2119af2014-05-09 19:57:56 -0700699}
700
Igor Murashkin65d14b92014-06-17 12:03:20 -0700701status_t CameraService::getLegacyParametersLazy(int cameraId,
702 /*out*/
703 CameraParameters* parameters) {
704
705 ALOGV("%s: for cameraId: %d", __FUNCTION__, cameraId);
706
707 status_t ret = 0;
708
709 if (parameters == NULL) {
710 ALOGE("%s: parameters must not be null", __FUNCTION__);
711 return BAD_VALUE;
712 }
713
Ruben Brunkcc776712015-02-17 20:18:47 -0800714 String8 id = String8::format("%d", cameraId);
715
716 // Check if we already have parameters
717 {
718 // Scope for service lock
Igor Murashkin65d14b92014-06-17 12:03:20 -0700719 Mutex::Autolock lock(mServiceLock);
Ruben Brunkcc776712015-02-17 20:18:47 -0800720 auto cameraState = getCameraState(id);
721 if (cameraState == nullptr) {
722 ALOGE("%s: Invalid camera ID: %s", __FUNCTION__, id.string());
723 return BAD_VALUE;
724 }
725 CameraParameters p = cameraState->getShimParams();
726 if (!p.isEmpty()) {
727 *parameters = p;
728 return NO_ERROR;
Igor Murashkin65d14b92014-06-17 12:03:20 -0700729 }
730 }
731
Ruben Brunkcc776712015-02-17 20:18:47 -0800732 int64_t token = IPCThreadState::self()->clearCallingIdentity();
733 ret = initializeShimMetadata(cameraId);
734 IPCThreadState::self()->restoreCallingIdentity(token);
735 if (ret != NO_ERROR) {
736 // Error already logged by callee
737 return ret;
738 }
739
740 // Check for parameters again
741 {
742 // Scope for service lock
743 Mutex::Autolock lock(mServiceLock);
744 auto cameraState = getCameraState(id);
745 if (cameraState == nullptr) {
746 ALOGE("%s: Invalid camera ID: %s", __FUNCTION__, id.string());
747 return BAD_VALUE;
Igor Murashkin65d14b92014-06-17 12:03:20 -0700748 }
Ruben Brunkcc776712015-02-17 20:18:47 -0800749 CameraParameters p = cameraState->getShimParams();
750 if (!p.isEmpty()) {
751 *parameters = p;
752 return NO_ERROR;
Igor Murashkin65d14b92014-06-17 12:03:20 -0700753 }
754 }
755
Ruben Brunkcc776712015-02-17 20:18:47 -0800756 ALOGE("%s: Parameters were not initialized, or were empty. Device may not be present.",
757 __FUNCTION__);
758 return INVALID_OPERATION;
Igor Murashkin65d14b92014-06-17 12:03:20 -0700759}
760
Ruben Brunkcc776712015-02-17 20:18:47 -0800761status_t CameraService::validateConnect(const String8& cameraId, /*inout*/int& clientUid) const {
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800762
Mathias Agopian65ab4712010-07-14 17:59:35 -0700763 int callingPid = getCallingPid();
Tyler Luu5861a9a2011-10-06 00:00:03 -0500764
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800765 if (clientUid == USE_CALLING_UID) {
766 clientUid = getCallingUid();
767 } else {
768 // We only trust our own process to forward client UIDs
769 if (callingPid != getpid()) {
Ruben Brunkcc776712015-02-17 20:18:47 -0800770 ALOGE("CameraService::connect X (PID %d) rejected (don't trust clientUid)",
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800771 callingPid);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700772 return PERMISSION_DENIED;
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800773 }
774 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700775
Iliyan Malchev8951a972011-04-14 16:55:59 -0700776 if (!mModule) {
Ruben Brunkcc776712015-02-17 20:18:47 -0800777 ALOGE("CameraService::connect X (PID %d) rejected (camera HAL module not loaded)",
778 callingPid);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700779 return -ENODEV;
Iliyan Malchev8951a972011-04-14 16:55:59 -0700780 }
781
Ruben Brunkcc776712015-02-17 20:18:47 -0800782 if (getCameraState(cameraId) == nullptr) {
783 ALOGE("CameraService::connect X (PID %d) rejected (invalid camera ID %s)", callingPid,
784 cameraId.string());
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700785 return -ENODEV;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700786 }
787
Ruben Brunkcc776712015-02-17 20:18:47 -0800788 // Check device policy for this camera
Wu-cheng Lia3355432011-05-20 14:54:25 +0800789 char value[PROPERTY_VALUE_MAX];
Amith Yamasani228711d2015-02-13 13:25:39 -0800790 char key[PROPERTY_KEY_MAX];
791 int clientUserId = multiuser_get_user_id(clientUid);
792 snprintf(key, PROPERTY_KEY_MAX, "sys.secpolicy.camera.off_%d", clientUserId);
793 property_get(key, value, "0");
Wu-cheng Lia3355432011-05-20 14:54:25 +0800794 if (strcmp(value, "1") == 0) {
795 // Camera is disabled by DevicePolicyManager.
Ruben Brunkcc776712015-02-17 20:18:47 -0800796 ALOGE("CameraService::connect X (PID %d) rejected (camera %s is disabled by device "
797 "policy)", callingPid, cameraId.string());
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700798 return -EACCES;
Wu-cheng Lia3355432011-05-20 14:54:25 +0800799 }
800
Ruben Brunkcc776712015-02-17 20:18:47 -0800801 return checkIfDeviceIsUsable(cameraId);
802}
803
804status_t CameraService::checkIfDeviceIsUsable(const String8& cameraId) const {
805 auto cameraState = getCameraState(cameraId);
806 int callingPid = getCallingPid();
807 if (cameraState == nullptr) {
808 ALOGE("CameraService::connect X (PID %d) rejected (invalid camera ID %s)", callingPid,
809 cameraId.string());
810 return -ENODEV;
811 }
812
813 ICameraServiceListener::Status currentStatus = cameraState->getStatus();
Igor Murashkincba2c162013-03-20 15:56:31 -0700814 if (currentStatus == ICameraServiceListener::STATUS_NOT_PRESENT) {
Ruben Brunkcc776712015-02-17 20:18:47 -0800815 ALOGE("CameraService::connect X (PID %d) rejected (camera %s is not connected)",
816 callingPid, cameraId.string());
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700817 return -ENODEV;
Igor Murashkincba2c162013-03-20 15:56:31 -0700818 } else if (currentStatus == ICameraServiceListener::STATUS_ENUMERATING) {
Ruben Brunkcc776712015-02-17 20:18:47 -0800819 ALOGE("CameraService::connect X (PID %d) rejected, (camera %s is initializing)",
820 callingPid, cameraId.string());
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700821 return -EBUSY;
Igor Murashkincba2c162013-03-20 15:56:31 -0700822 }
Igor Murashkincba2c162013-03-20 15:56:31 -0700823
Ruben Brunkcc776712015-02-17 20:18:47 -0800824 return NO_ERROR;
Igor Murashkine6800ce2013-03-04 17:25:57 -0800825}
826
Ruben Brunkcc776712015-02-17 20:18:47 -0800827void CameraService::finishConnectLocked(const sp<BasicClient>& client,
828 const CameraService::DescriptorPtr& desc) {
Igor Murashkine6800ce2013-03-04 17:25:57 -0800829
Ruben Brunkcc776712015-02-17 20:18:47 -0800830 // Make a descriptor for the incoming client
831 auto clientDescriptor = CameraService::CameraClientManager::makeClientDescriptor(client, desc);
832 auto evicted = mActiveClientManager.addAndEvict(clientDescriptor);
833
834 logConnected(desc->getKey(), static_cast<int>(desc->getOwnerId()),
835 String8(client->getPackageName()));
836
837 if (evicted.size() > 0) {
838 // This should never happen - clients should already have been removed in disconnect
839 for (auto& i : evicted) {
840 ALOGE("%s: Invalid state: Client for camera %s was not removed in disconnect",
841 __FUNCTION__, i->getKey().string());
842 }
843
844 LOG_ALWAYS_FATAL("%s: Invalid state for CameraService, clients not evicted properly",
845 __FUNCTION__);
846 }
847}
848
849status_t CameraService::handleEvictionsLocked(const String8& cameraId, int clientPid,
850 apiLevel effectiveApiLevel, const sp<IBinder>& remoteCallback, const String8& packageName,
851 /*out*/
852 sp<BasicClient>* client,
853 std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>* partial) {
854
855 status_t ret = NO_ERROR;
856 std::vector<sp<BasicClient>> evictedClients;
857 DescriptorPtr clientDescriptor;
858 {
859 if (effectiveApiLevel == API_1) {
860 // If we are using API1, any existing client for this camera ID with the same remote
861 // should be returned rather than evicted to allow MediaRecorder to work properly.
862
863 auto current = mActiveClientManager.get(cameraId);
864 if (current != nullptr) {
865 auto clientSp = current->getValue();
866 if (clientSp.get() != nullptr) { // should never be needed
867 if (clientSp->getRemote() == remoteCallback) {
868 ALOGI("CameraService::connect X (PID %d) (second call from same"
869 "app binder, returning the same client)", clientPid);
870 *client = clientSp;
871 return NO_ERROR;
872 }
873 }
Wu-cheng Li2fd24402012-02-23 19:01:00 -0800874 }
Wu-cheng Li2fd24402012-02-23 19:01:00 -0800875 }
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800876
Ruben Brunkcc776712015-02-17 20:18:47 -0800877 // Return error if the device was unplugged or removed by the HAL for some reason
878 if ((ret = checkIfDeviceIsUsable(cameraId)) != NO_ERROR) {
879 return ret;
880 }
Igor Murashkin634a5152013-02-20 17:15:11 -0800881
Ruben Brunkcc776712015-02-17 20:18:47 -0800882 // Get current active client PIDs
883 std::vector<int> ownerPids(mActiveClientManager.getAllOwners());
884 ownerPids.push_back(clientPid);
Igor Murashkine6800ce2013-03-04 17:25:57 -0800885
Chih-Hung Hsieh54b42462015-03-19 12:04:54 -0700886 // Use the value +PROCESS_STATE_NONEXISTENT, to avoid taking
887 // address of PROCESS_STATE_NONEXISTENT as a reference argument
888 // for the vector constructor. PROCESS_STATE_NONEXISTENT does
889 // not have an out-of-class definition.
890 std::vector<int> priorities(ownerPids.size(), +PROCESS_STATE_NONEXISTENT);
Igor Murashkine6800ce2013-03-04 17:25:57 -0800891
Ruben Brunkcc776712015-02-17 20:18:47 -0800892 // Get priorites of all active PIDs
893 ProcessInfoService::getProcessStatesFromPids(ownerPids.size(), &ownerPids[0],
894 /*out*/&priorities[0]);
Ruben Brunkb2119af2014-05-09 19:57:56 -0700895
Ruben Brunkcc776712015-02-17 20:18:47 -0800896 // Update all active clients' priorities
897 std::map<int,int> pidToPriorityMap;
898 for (size_t i = 0; i < ownerPids.size() - 1; i++) {
899 pidToPriorityMap.emplace(ownerPids[i], getCameraPriorityFromProcState(priorities[i]));
900 }
901 mActiveClientManager.updatePriorities(pidToPriorityMap);
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800902
Ruben Brunkcc776712015-02-17 20:18:47 -0800903 // Get state for the given cameraId
904 auto state = getCameraState(cameraId);
905 if (state == nullptr) {
906 ALOGE("CameraService::connect X (PID %d) rejected (no camera device with ID %s)",
907 clientPid, cameraId.string());
Zhijun Heb10cdad2014-06-16 16:38:35 -0700908 return BAD_VALUE;
Zhijun Heb10cdad2014-06-16 16:38:35 -0700909 }
Ruben Brunkcc776712015-02-17 20:18:47 -0800910
911 // Make descriptor for incoming client
912 clientDescriptor = CameraClientManager::makeClientDescriptor(cameraId,
913 sp<BasicClient>{nullptr}, static_cast<int32_t>(state->getCost()),
914 state->getConflicting(),
915 getCameraPriorityFromProcState(priorities[priorities.size() - 1]), clientPid);
916
917 // Find clients that would be evicted
918 auto evicted = mActiveClientManager.wouldEvict(clientDescriptor);
919
920 // If the incoming client was 'evicted,' higher priority clients have the camera in the
921 // background, so we cannot do evictions
922 if (std::find(evicted.begin(), evicted.end(), clientDescriptor) != evicted.end()) {
923 ALOGE("CameraService::connect X (PID %d) rejected (existing client(s) with higher"
924 " priority).", clientPid);
925
926 sp<BasicClient> clientSp = clientDescriptor->getValue();
927 String8 curTime = getFormattedCurrentTime();
928 auto incompatibleClients =
929 mActiveClientManager.getIncompatibleClients(clientDescriptor);
930
931 String8 msg = String8::format("%s : DENIED connect device %s client for package %s "
932 "(PID %d, priority %d)", curTime.string(),
933 cameraId.string(), packageName.string(), clientPid,
934 getCameraPriorityFromProcState(priorities[priorities.size() - 1]));
935
936 for (auto& i : incompatibleClients) {
937 msg.appendFormat("\n - Blocked by existing device %s client for package %s"
938 "(PID %" PRId32 ", priority %" PRId32 ")", i->getKey().string(),
939 String8{i->getValue()->getPackageName()}.string(), i->getOwnerId(),
940 i->getPriority());
941 }
942
943 // Log the client's attempt
944 mEventLog.add(msg);
945
946 return -EBUSY;
947 }
948
949 for (auto& i : evicted) {
950 sp<BasicClient> clientSp = i->getValue();
951 if (clientSp.get() == nullptr) {
952 ALOGE("%s: Invalid state: Null client in active client list.", __FUNCTION__);
953
954 // TODO: Remove this
955 LOG_ALWAYS_FATAL("%s: Invalid state for CameraService, null client in active list",
956 __FUNCTION__);
957 mActiveClientManager.remove(i);
958 continue;
959 }
960
961 ALOGE("CameraService::connect evicting conflicting client for camera ID %s",
962 i->getKey().string());
963 evictedClients.push_back(clientSp);
964
965 String8 curTime = getFormattedCurrentTime();
966
967 // Log the clients evicted
968 mEventLog.add(String8::format("%s : EVICT device %s client for package %s (PID %"
969 PRId32 ", priority %" PRId32 ")\n - Evicted by device %s client for "
970 "package %s (PID %d, priority %" PRId32 ")", curTime.string(),
971 i->getKey().string(), String8{clientSp->getPackageName()}.string(),
972 i->getOwnerId(), i->getPriority(), cameraId.string(),
973 packageName.string(), clientPid,
974 getCameraPriorityFromProcState(priorities[priorities.size() - 1])));
975
976 // Notify the client of disconnection
977 clientSp->notifyError(ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED,
978 CaptureResultExtras());
Zhijun Heb10cdad2014-06-16 16:38:35 -0700979 }
Ruben Brunkb2119af2014-05-09 19:57:56 -0700980 }
981
Ruben Brunkcc776712015-02-17 20:18:47 -0800982 // Do not hold mServiceLock while disconnecting clients, but retain the condition blocking
983 // other clients from connecting in mServiceLockWrapper if held
984 mServiceLock.unlock();
985
986 // Clear caller identity temporarily so client disconnect PID checks work correctly
987 int64_t token = IPCThreadState::self()->clearCallingIdentity();
988
989 // Destroy evicted clients
990 for (auto& i : evictedClients) {
991 // Disconnect is blocking, and should only have returned when HAL has cleaned up
992 i->disconnect(); // Clients will remove themselves from the active client list here
993 }
994 evictedClients.clear();
995
996 IPCThreadState::self()->restoreCallingIdentity(token);
997
998 // Once clients have been disconnected, relock
999 mServiceLock.lock();
1000
1001 // Check again if the device was unplugged or something while we weren't holding mServiceLock
1002 if ((ret = checkIfDeviceIsUsable(cameraId)) != NO_ERROR) {
1003 return ret;
Ruben Brunkb2119af2014-05-09 19:57:56 -07001004 }
1005
Ruben Brunkcc776712015-02-17 20:18:47 -08001006 *partial = clientDescriptor;
1007 return NO_ERROR;
Ruben Brunkb2119af2014-05-09 19:57:56 -07001008}
1009
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001010status_t CameraService::connect(
Igor Murashkine6800ce2013-03-04 17:25:57 -08001011 const sp<ICameraClient>& cameraClient,
1012 int cameraId,
1013 const String16& clientPackageName,
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001014 int clientUid,
1015 /*out*/
1016 sp<ICamera>& device) {
Igor Murashkine6800ce2013-03-04 17:25:57 -08001017
Ruben Brunkcc776712015-02-17 20:18:47 -08001018 status_t ret = NO_ERROR;
1019 String8 id = String8::format("%d", cameraId);
1020 sp<Client> client = nullptr;
1021 ret = connectHelper<ICameraClient,Client>(cameraClient, id, CAMERA_HAL_API_VERSION_UNSPECIFIED,
1022 clientPackageName, clientUid, API_1, false, false, /*out*/client);
Igor Murashkine6800ce2013-03-04 17:25:57 -08001023
Ruben Brunkcc776712015-02-17 20:18:47 -08001024 if(ret != NO_ERROR) {
1025 return ret;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001026 }
1027
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001028 device = client;
Ruben Brunkcc776712015-02-17 20:18:47 -08001029 return NO_ERROR;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001030}
1031
Zhijun Heb10cdad2014-06-16 16:38:35 -07001032status_t CameraService::connectLegacy(
1033 const sp<ICameraClient>& cameraClient,
1034 int cameraId, int halVersion,
1035 const String16& clientPackageName,
1036 int clientUid,
1037 /*out*/
1038 sp<ICamera>& device) {
1039
Chien-Yu Chen676b21b2015-02-24 10:28:19 -08001040 int apiVersion = mModule->getModuleApiVersion();
Igor Murashkin3d07d1a2014-06-20 11:27:03 -07001041 if (halVersion != CAMERA_HAL_API_VERSION_UNSPECIFIED &&
Yin-Chia Yehe074a932015-01-30 10:29:02 -08001042 apiVersion < CAMERA_MODULE_API_VERSION_2_3) {
Igor Murashkin3d07d1a2014-06-20 11:27:03 -07001043 /*
1044 * Either the HAL version is unspecified in which case this just creates
1045 * a camera client selected by the latest device version, or
1046 * it's a particular version in which case the HAL must supported
1047 * the open_legacy call
1048 */
Zhijun Heb10cdad2014-06-16 16:38:35 -07001049 ALOGE("%s: camera HAL module version %x doesn't support connecting to legacy HAL devices!",
Yin-Chia Yehe074a932015-01-30 10:29:02 -08001050 __FUNCTION__, apiVersion);
Zhijun Heb10cdad2014-06-16 16:38:35 -07001051 return INVALID_OPERATION;
1052 }
1053
Ruben Brunkcc776712015-02-17 20:18:47 -08001054 status_t ret = NO_ERROR;
1055 String8 id = String8::format("%d", cameraId);
1056 sp<Client> client = nullptr;
1057 ret = connectHelper<ICameraClient,Client>(cameraClient, id, halVersion, clientPackageName,
1058 clientUid, API_1, true, false, /*out*/client);
Zhijun Heb10cdad2014-06-16 16:38:35 -07001059
Ruben Brunkcc776712015-02-17 20:18:47 -08001060 if(ret != NO_ERROR) {
1061 return ret;
Zhijun Heb10cdad2014-06-16 16:38:35 -07001062 }
1063
Zhijun Heb10cdad2014-06-16 16:38:35 -07001064 device = client;
Ruben Brunkcc776712015-02-17 20:18:47 -08001065 return NO_ERROR;
Zhijun Heb10cdad2014-06-16 16:38:35 -07001066}
1067
Ruben Brunkcc776712015-02-17 20:18:47 -08001068status_t CameraService::connectPro(const sp<IProCameraCallbacks>& cameraCb,
1069 int cameraId,
1070 const String16& clientPackageName,
1071 int clientUid,
1072 /*out*/
1073 sp<IProCameraUser>& device) {
1074 ALOGE("%s: Unimplemented, please use connectDevice", __FUNCTION__);
1075 return INVALID_OPERATION;
1076}
1077
1078status_t CameraService::connectDevice(
1079 const sp<ICameraDeviceCallbacks>& cameraCb,
1080 int cameraId,
1081 const String16& clientPackageName,
1082 int clientUid,
1083 /*out*/
1084 sp<ICameraDeviceUser>& device) {
1085
1086 status_t ret = NO_ERROR;
1087 String8 id = String8::format("%d", cameraId);
1088 sp<CameraDeviceClient> client = nullptr;
1089 ret = connectHelper<ICameraDeviceCallbacks,CameraDeviceClient>(cameraCb, id,
1090 CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageName, clientUid, API_2, false, false,
1091 /*out*/client);
1092
1093 if(ret != NO_ERROR) {
1094 return ret;
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001095 }
1096
Ruben Brunkcc776712015-02-17 20:18:47 -08001097 device = client;
1098 return NO_ERROR;
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001099}
1100
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001101status_t CameraService::setTorchMode(const String16& cameraId, bool enabled,
1102 const sp<IBinder>& clientBinder) {
1103 if (enabled && clientBinder == NULL) {
1104 ALOGE("%s: torch client binder is NULL", __FUNCTION__);
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001105 return -EINVAL;
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001106 }
1107
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001108 String8 id = String8(cameraId.string());
1109
1110 // verify id is valid.
Ruben Brunkcc776712015-02-17 20:18:47 -08001111 auto state = getCameraState(id);
1112 if (state == nullptr) {
1113 ALOGE("%s: camera id is invalid %s", id.string());
1114 return -EINVAL;
1115 }
1116
1117 ICameraServiceListener::Status cameraStatus = state->getStatus();
1118 if (cameraStatus != ICameraServiceListener::STATUS_PRESENT &&
1119 cameraStatus != ICameraServiceListener::STATUS_NOT_AVAILABLE) {
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001120 ALOGE("%s: camera id is invalid %s", id.string());
1121 return -EINVAL;
1122 }
1123
1124 {
1125 Mutex::Autolock al(mTorchStatusMutex);
1126 ICameraServiceListener::TorchStatus status;
1127 status_t res = getTorchStatusLocked(id, &status);
1128 if (res) {
1129 ALOGE("%s: getting current torch status failed for camera %s",
1130 __FUNCTION__, id.string());
1131 return -EINVAL;
1132 }
1133
1134 if (status == ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE) {
Ruben Brunkcc776712015-02-17 20:18:47 -08001135 if (cameraStatus == ICameraServiceListener::STATUS_NOT_AVAILABLE) {
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001136 ALOGE("%s: torch mode of camera %s is not available because "
1137 "camera is in use", __FUNCTION__, id.string());
1138 return -EBUSY;
1139 } else {
1140 ALOGE("%s: torch mode of camera %s is not available due to "
1141 "insufficient resources", __FUNCTION__, id.string());
1142 return -EUSERS;
1143 }
1144 }
1145 }
1146
1147 status_t res = mFlashlight->setTorchMode(id, enabled);
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001148 if (res) {
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001149 ALOGE("%s: setting torch mode of camera %s to %d failed. %s (%d)",
1150 __FUNCTION__, id.string(), enabled, strerror(-res), res);
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001151 return res;
1152 }
1153
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001154 {
1155 // update the link to client's death
1156 Mutex::Autolock al(mTorchClientMapMutex);
1157 ssize_t index = mTorchClientMap.indexOfKey(id);
1158 if (enabled) {
1159 if (index == NAME_NOT_FOUND) {
1160 mTorchClientMap.add(id, clientBinder);
1161 } else {
1162 const sp<IBinder> oldBinder = mTorchClientMap.valueAt(index);
1163 oldBinder->unlinkToDeath(this);
1164
1165 mTorchClientMap.replaceValueAt(index, clientBinder);
1166 }
1167 clientBinder->linkToDeath(this);
1168 } else if (index != NAME_NOT_FOUND) {
1169 sp<IBinder> oldBinder = mTorchClientMap.valueAt(index);
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001170 oldBinder->unlinkToDeath(this);
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001171 }
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001172 }
1173
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001174 return OK;
1175}
1176
Igor Murashkinbfc99152013-02-27 12:55:20 -08001177status_t CameraService::addListener(
1178 const sp<ICameraServiceListener>& listener) {
1179 ALOGV("%s: Add listener %p", __FUNCTION__, listener.get());
Igor Murashkin634a5152013-02-20 17:15:11 -08001180
Igor Murashkinbd3e2e02014-03-17 13:01:41 -07001181 if (listener == 0) {
1182 ALOGE("%s: Listener must not be null", __FUNCTION__);
1183 return BAD_VALUE;
1184 }
1185
Igor Murashkinbfc99152013-02-27 12:55:20 -08001186 Mutex::Autolock lock(mServiceLock);
1187
Ruben Brunkcc776712015-02-17 20:18:47 -08001188 {
1189 Mutex::Autolock lock(mStatusListenerLock);
1190 for (auto& it : mListenerList) {
1191 if (IInterface::asBinder(it) == IInterface::asBinder(listener)) {
1192 ALOGW("%s: Tried to add listener %p which was already subscribed",
1193 __FUNCTION__, listener.get());
1194 return ALREADY_EXISTS;
1195 }
Igor Murashkinbfc99152013-02-27 12:55:20 -08001196 }
Ruben Brunkcc776712015-02-17 20:18:47 -08001197
1198 mListenerList.push_back(listener);
Igor Murashkinbfc99152013-02-27 12:55:20 -08001199 }
1200
Igor Murashkinbfc99152013-02-27 12:55:20 -08001201
Igor Murashkincba2c162013-03-20 15:56:31 -07001202 /* Immediately signal current status to this listener only */
1203 {
Ruben Brunkcc776712015-02-17 20:18:47 -08001204 Mutex::Autolock lock(mCameraStatesLock);
1205 for (auto& i : mCameraStates) {
1206 // TODO: Update binder to use String16 for camera IDs and remove;
1207 int id = cameraIdToInt(i.first);
1208 if (id == -1) continue;
1209
1210 listener->onStatusChanged(i.second->getStatus(), id);
Igor Murashkincba2c162013-03-20 15:56:31 -07001211 }
1212 }
1213
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001214 /* Immediately signal current torch status to this listener only */
1215 {
1216 Mutex::Autolock al(mTorchStatusMutex);
1217 for (size_t i = 0; i < mTorchStatusMap.size(); i++ ) {
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001218 String16 id = String16(mTorchStatusMap.keyAt(i).string());
1219 listener->onTorchStatusChanged(mTorchStatusMap.valueAt(i), id);
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001220 }
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001221 }
1222
Igor Murashkinbfc99152013-02-27 12:55:20 -08001223 return OK;
1224}
Ruben Brunkcc776712015-02-17 20:18:47 -08001225
1226status_t CameraService::removeListener(const sp<ICameraServiceListener>& listener) {
Igor Murashkinbfc99152013-02-27 12:55:20 -08001227 ALOGV("%s: Remove listener %p", __FUNCTION__, listener.get());
1228
Igor Murashkinbd3e2e02014-03-17 13:01:41 -07001229 if (listener == 0) {
1230 ALOGE("%s: Listener must not be null", __FUNCTION__);
1231 return BAD_VALUE;
1232 }
1233
Igor Murashkinbfc99152013-02-27 12:55:20 -08001234 Mutex::Autolock lock(mServiceLock);
1235
Ruben Brunkcc776712015-02-17 20:18:47 -08001236 {
1237 Mutex::Autolock lock(mStatusListenerLock);
1238 for (auto it = mListenerList.begin(); it != mListenerList.end(); it++) {
1239 if (IInterface::asBinder(*it) == IInterface::asBinder(listener)) {
1240 mListenerList.erase(it);
1241 return OK;
1242 }
Igor Murashkinbfc99152013-02-27 12:55:20 -08001243 }
1244 }
1245
1246 ALOGW("%s: Tried to remove a listener %p which was not subscribed",
1247 __FUNCTION__, listener.get());
1248
1249 return BAD_VALUE;
Igor Murashkin634a5152013-02-20 17:15:11 -08001250}
1251
Ruben Brunkcc776712015-02-17 20:18:47 -08001252status_t CameraService::getLegacyParameters(int cameraId, /*out*/String16* parameters) {
Igor Murashkin65d14b92014-06-17 12:03:20 -07001253 ALOGV("%s: for camera ID = %d", __FUNCTION__, cameraId);
1254
1255 if (parameters == NULL) {
1256 ALOGE("%s: parameters must not be null", __FUNCTION__);
1257 return BAD_VALUE;
1258 }
1259
1260 status_t ret = 0;
1261
1262 CameraParameters shimParams;
1263 if ((ret = getLegacyParametersLazy(cameraId, /*out*/&shimParams)) != OK) {
1264 // Error logged by caller
1265 return ret;
1266 }
1267
1268 String8 shimParamsString8 = shimParams.flatten();
1269 String16 shimParamsString16 = String16(shimParamsString8);
1270
1271 *parameters = shimParamsString16;
1272
1273 return OK;
1274}
1275
1276status_t CameraService::supportsCameraApi(int cameraId, int apiVersion) {
1277 ALOGV("%s: for camera ID = %d", __FUNCTION__, cameraId);
1278
1279 switch (apiVersion) {
1280 case API_VERSION_1:
1281 case API_VERSION_2:
1282 break;
1283 default:
1284 ALOGE("%s: Bad API version %d", __FUNCTION__, apiVersion);
1285 return BAD_VALUE;
1286 }
1287
1288 int facing = -1;
1289 int deviceVersion = getDeviceVersion(cameraId, &facing);
1290
1291 switch(deviceVersion) {
1292 case CAMERA_DEVICE_API_VERSION_1_0:
1293 case CAMERA_DEVICE_API_VERSION_2_0:
1294 case CAMERA_DEVICE_API_VERSION_2_1:
1295 case CAMERA_DEVICE_API_VERSION_3_0:
1296 case CAMERA_DEVICE_API_VERSION_3_1:
1297 if (apiVersion == API_VERSION_2) {
1298 ALOGV("%s: Camera id %d uses HAL prior to HAL3.2, doesn't support api2 without shim",
1299 __FUNCTION__, cameraId);
1300 return -EOPNOTSUPP;
1301 } else { // if (apiVersion == API_VERSION_1) {
1302 ALOGV("%s: Camera id %d uses older HAL before 3.2, but api1 is always supported",
1303 __FUNCTION__, cameraId);
1304 return OK;
1305 }
1306 case CAMERA_DEVICE_API_VERSION_3_2:
Ruben Brunkcc776712015-02-17 20:18:47 -08001307 case CAMERA_DEVICE_API_VERSION_3_3:
Igor Murashkin65d14b92014-06-17 12:03:20 -07001308 ALOGV("%s: Camera id %d uses HAL3.2 or newer, supports api1/api2 directly",
1309 __FUNCTION__, cameraId);
1310 return OK;
1311 case -1:
1312 ALOGE("%s: Invalid camera id %d", __FUNCTION__, cameraId);
1313 return BAD_VALUE;
1314 default:
1315 ALOGE("%s: Unknown camera device HAL version: %d", __FUNCTION__, deviceVersion);
1316 return INVALID_OPERATION;
1317 }
1318
1319 return OK;
1320}
1321
Ruben Brunkcc776712015-02-17 20:18:47 -08001322void CameraService::removeByClient(const BasicClient* client) {
Igor Murashkinecf17e82012-10-02 16:05:11 -07001323 Mutex::Autolock lock(mServiceLock);
Ruben Brunkcc776712015-02-17 20:18:47 -08001324 for (auto& i : mActiveClientManager.getAll()) {
1325 auto clientSp = i->getValue();
1326 if (clientSp.get() == client) {
1327 mActiveClientManager.remove(i);
Igor Murashkin634a5152013-02-20 17:15:11 -08001328 }
Igor Murashkinecf17e82012-10-02 16:05:11 -07001329 }
Igor Murashkin634a5152013-02-20 17:15:11 -08001330}
1331
Ruben Brunkcc776712015-02-17 20:18:47 -08001332bool CameraService::evictClientIdByRemote(const wp<IBinder>& remote) {
1333 const int callingPid = getCallingPid();
1334 const int servicePid = getpid();
1335 bool ret = false;
1336 {
1337 // Acquire mServiceLock and prevent other clients from connecting
1338 std::unique_ptr<AutoConditionLock> lock =
1339 AutoConditionLock::waitAndAcquire(mServiceLockWrapper);
Igor Murashkin634a5152013-02-20 17:15:11 -08001340
Igor Murashkin634a5152013-02-20 17:15:11 -08001341
Ruben Brunkcc776712015-02-17 20:18:47 -08001342 std::vector<sp<BasicClient>> evicted;
1343 for (auto& i : mActiveClientManager.getAll()) {
1344 auto clientSp = i->getValue();
1345 if (clientSp.get() == nullptr) {
1346 ALOGE("%s: Dead client still in mActiveClientManager.", __FUNCTION__);
1347 mActiveClientManager.remove(i);
1348 continue;
1349 }
1350 if (remote == clientSp->getRemote() && (callingPid == servicePid ||
1351 callingPid == clientSp->getClientPid())) {
1352 mActiveClientManager.remove(i);
1353 evicted.push_back(clientSp);
Igor Murashkin634a5152013-02-20 17:15:11 -08001354
Ruben Brunkcc776712015-02-17 20:18:47 -08001355 // Notify the client of disconnection
1356 clientSp->notifyError(ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED,
1357 CaptureResultExtras());
Igor Murashkin634a5152013-02-20 17:15:11 -08001358 }
1359 }
1360
Ruben Brunkcc776712015-02-17 20:18:47 -08001361 // Do not hold mServiceLock while disconnecting clients, but retain the condition blocking
1362 // other clients from connecting in mServiceLockWrapper if held
1363 mServiceLock.unlock();
1364
1365 for (auto& i : evicted) {
1366 if (i.get() != nullptr) {
1367 i->disconnect();
1368 ret = true;
1369 }
Igor Murashkin634a5152013-02-20 17:15:11 -08001370 }
1371
Ruben Brunkcc776712015-02-17 20:18:47 -08001372 // Reacquire mServiceLock
1373 mServiceLock.lock();
Igor Murashkin634a5152013-02-20 17:15:11 -08001374
Ruben Brunkcc776712015-02-17 20:18:47 -08001375 } // lock is destroyed, allow further connect calls
1376
1377 return ret;
Igor Murashkinecf17e82012-10-02 16:05:11 -07001378}
1379
Igor Murashkinecf17e82012-10-02 16:05:11 -07001380
Ruben Brunkcc776712015-02-17 20:18:47 -08001381std::shared_ptr<CameraService::CameraState> CameraService::getCameraState(
1382 const String8& cameraId) const {
1383 std::shared_ptr<CameraState> state;
1384 {
1385 Mutex::Autolock lock(mCameraStatesLock);
1386 auto iter = mCameraStates.find(cameraId);
1387 if (iter != mCameraStates.end()) {
1388 state = iter->second;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001389 }
1390 }
Ruben Brunkcc776712015-02-17 20:18:47 -08001391 return state;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001392}
1393
Ruben Brunkcc776712015-02-17 20:18:47 -08001394sp<CameraService::BasicClient> CameraService::removeClientLocked(const String8& cameraId) {
1395 // Remove from active clients list
1396 auto clientDescriptorPtr = mActiveClientManager.remove(cameraId);
1397 if (clientDescriptorPtr == nullptr) {
1398 ALOGW("%s: Could not evict client, no client for camera ID %s", __FUNCTION__,
1399 cameraId.string());
1400 return sp<BasicClient>{nullptr};
1401 }
1402
1403 return clientDescriptorPtr->getValue();
Keun young Parkd8973a72012-03-28 14:13:09 -07001404}
1405
Ruben Brunkcc776712015-02-17 20:18:47 -08001406
1407void CameraService::logDisconnected(const String8& cameraId, int clientPid,
1408 const String8& clientPackage) {
1409
1410 String8 curTime = getFormattedCurrentTime();
1411 // Log the clients evicted
1412 mEventLog.add(String8::format("%s : DISCONNECT device %s client for package %s (PID %d)",
1413 curTime.string(), cameraId.string(), clientPackage.string(), clientPid));
Mathias Agopian65ab4712010-07-14 17:59:35 -07001414}
1415
Ruben Brunkcc776712015-02-17 20:18:47 -08001416void CameraService::logConnected(const String8& cameraId, int clientPid,
1417 const String8& clientPackage) {
Igor Murashkinecf17e82012-10-02 16:05:11 -07001418
Ruben Brunkcc776712015-02-17 20:18:47 -08001419 String8 curTime = getFormattedCurrentTime();
1420 // Log the clients evicted
1421 mEventLog.add(String8::format("%s : CONNECT device %s client for package %s (PID %d)",
1422 curTime.string(), cameraId.string(), clientPackage.string(), clientPid));
Igor Murashkinecf17e82012-10-02 16:05:11 -07001423}
1424
Mathias Agopian65ab4712010-07-14 17:59:35 -07001425status_t CameraService::onTransact(
1426 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
1427 // Permission checks
1428 switch (code) {
1429 case BnCameraService::CONNECT:
Igor Murashkin634a5152013-02-20 17:15:11 -08001430 case BnCameraService::CONNECT_PRO:
Eino-Ville Talvala63d877f2014-06-16 19:21:12 -07001431 case BnCameraService::CONNECT_DEVICE:
Zhijun Heb10cdad2014-06-16 16:38:35 -07001432 case BnCameraService::CONNECT_LEGACY:
Mathias Agopian65ab4712010-07-14 17:59:35 -07001433 const int pid = getCallingPid();
1434 const int self_pid = getpid();
1435 if (pid != self_pid) {
1436 // we're called from a different process, do the real check
1437 if (!checkCallingPermission(
1438 String16("android.permission.CAMERA"))) {
1439 const int uid = getCallingUid();
Steve Block29357bc2012-01-06 19:20:56 +00001440 ALOGE("Permission Denial: "
Mathias Agopian65ab4712010-07-14 17:59:35 -07001441 "can't use the camera pid=%d, uid=%d", pid, uid);
1442 return PERMISSION_DENIED;
1443 }
1444 }
1445 break;
1446 }
1447
1448 return BnCameraService::onTransact(code, data, reply, flags);
1449}
1450
Mathias Agopian65ab4712010-07-14 17:59:35 -07001451// We share the media players for shutter and recording sound for all clients.
1452// A reference count is kept to determine when we will actually release the
1453// media players.
1454
Chih-Chung Changff4f55c2011-10-17 19:03:12 +08001455MediaPlayer* CameraService::newMediaPlayer(const char *file) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001456 MediaPlayer* mp = new MediaPlayer();
Andreas Huber1b86fe02014-01-29 11:13:26 -08001457 if (mp->setDataSource(NULL /* httpService */, file, NULL) == NO_ERROR) {
Eino-Ville Talvala60a78ac2012-01-05 15:34:53 -08001458 mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001459 mp->prepare();
1460 } else {
Steve Block29357bc2012-01-06 19:20:56 +00001461 ALOGE("Failed to load CameraService sounds: %s", file);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001462 return NULL;
1463 }
1464 return mp;
1465}
1466
1467void CameraService::loadSound() {
1468 Mutex::Autolock lock(mSoundLock);
1469 LOG1("CameraService::loadSound ref=%d", mSoundRef);
1470 if (mSoundRef++) return;
1471
1472 mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
1473 mSoundPlayer[SOUND_RECORDING] = newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");
1474}
1475
1476void CameraService::releaseSound() {
1477 Mutex::Autolock lock(mSoundLock);
1478 LOG1("CameraService::releaseSound ref=%d", mSoundRef);
1479 if (--mSoundRef) return;
1480
1481 for (int i = 0; i < NUM_SOUNDS; i++) {
1482 if (mSoundPlayer[i] != 0) {
1483 mSoundPlayer[i]->disconnect();
1484 mSoundPlayer[i].clear();
1485 }
1486 }
1487}
1488
1489void CameraService::playSound(sound_kind kind) {
1490 LOG1("playSound(%d)", kind);
1491 Mutex::Autolock lock(mSoundLock);
1492 sp<MediaPlayer> player = mSoundPlayer[kind];
1493 if (player != 0) {
Chih-Chung Chang8888a752011-10-20 10:47:26 +08001494 player->seekTo(0);
1495 player->start();
Mathias Agopian65ab4712010-07-14 17:59:35 -07001496 }
1497}
1498
1499// ----------------------------------------------------------------------------
1500
1501CameraService::Client::Client(const sp<CameraService>& cameraService,
Wu-cheng Lib7a67942010-08-17 15:45:37 -07001502 const sp<ICameraClient>& cameraClient,
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001503 const String16& clientPackageName,
1504 int cameraId, int cameraFacing,
1505 int clientPid, uid_t clientUid,
1506 int servicePid) :
Eino-Ville Talvalae992e752014-11-07 16:17:48 -08001507 CameraService::BasicClient(cameraService,
Marco Nelissenf8880202014-11-14 07:58:25 -08001508 IInterface::asBinder(cameraClient),
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001509 clientPackageName,
1510 cameraId, cameraFacing,
1511 clientPid, clientUid,
1512 servicePid)
Igor Murashkin634a5152013-02-20 17:15:11 -08001513{
Mathias Agopian65ab4712010-07-14 17:59:35 -07001514 int callingPid = getCallingPid();
Wu-cheng Li2fd24402012-02-23 19:01:00 -08001515 LOG1("Client::Client E (pid %d, id %d)", callingPid, cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001516
Igor Murashkin44cfcf02013-03-01 16:22:28 -08001517 mRemoteCallback = cameraClient;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001518
Mathias Agopian65ab4712010-07-14 17:59:35 -07001519 cameraService->loadSound();
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001520
Wu-cheng Li2fd24402012-02-23 19:01:00 -08001521 LOG1("Client::Client X (pid %d, id %d)", callingPid, cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001522}
1523
Mathias Agopian65ab4712010-07-14 17:59:35 -07001524// tear down the client
1525CameraService::Client::~Client() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -07001526 ALOGV("~Client");
Igor Murashkin634a5152013-02-20 17:15:11 -08001527 mDestructionStarted = true;
1528
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001529 mCameraService->releaseSound();
Igor Murashkin036bc3e2012-10-08 15:09:46 -07001530 // unconditionally disconnect. function is idempotent
1531 Client::disconnect();
Mathias Agopian65ab4712010-07-14 17:59:35 -07001532}
1533
Igor Murashkin634a5152013-02-20 17:15:11 -08001534CameraService::BasicClient::BasicClient(const sp<CameraService>& cameraService,
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001535 const sp<IBinder>& remoteCallback,
1536 const String16& clientPackageName,
1537 int cameraId, int cameraFacing,
1538 int clientPid, uid_t clientUid,
1539 int servicePid):
Ruben Brunkcc776712015-02-17 20:18:47 -08001540 mClientPackageName(clientPackageName), mDisconnected(false)
Igor Murashkin634a5152013-02-20 17:15:11 -08001541{
1542 mCameraService = cameraService;
Igor Murashkin44cfcf02013-03-01 16:22:28 -08001543 mRemoteBinder = remoteCallback;
Igor Murashkin634a5152013-02-20 17:15:11 -08001544 mCameraId = cameraId;
1545 mCameraFacing = cameraFacing;
1546 mClientPid = clientPid;
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001547 mClientUid = clientUid;
Igor Murashkin634a5152013-02-20 17:15:11 -08001548 mServicePid = servicePid;
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001549 mOpsActive = false;
Igor Murashkin634a5152013-02-20 17:15:11 -08001550 mDestructionStarted = false;
1551}
1552
1553CameraService::BasicClient::~BasicClient() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -07001554 ALOGV("~BasicClient");
Igor Murashkin634a5152013-02-20 17:15:11 -08001555 mDestructionStarted = true;
1556}
1557
1558void CameraService::BasicClient::disconnect() {
Ruben Brunkcc776712015-02-17 20:18:47 -08001559 if (mDisconnected) return;
1560 mDisconnected = true;;
1561
1562 mCameraService->removeByClient(this);
1563 mCameraService->logDisconnected(String8::format("%d", mCameraId), mClientPid,
1564 String8(mClientPackageName));
1565
1566 sp<IBinder> remote = getRemote();
1567 if (remote != nullptr) {
1568 remote->unlinkToDeath(mCameraService);
1569 }
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001570
1571 finishCameraOps();
Ruben Brunkcc776712015-02-17 20:18:47 -08001572 ALOGI("%s: Disconnected client for camera %d for PID %d", __FUNCTION__, mCameraId, mClientPid);
1573
Igor Murashkincba2c162013-03-20 15:56:31 -07001574 // client shouldn't be able to call into us anymore
1575 mClientPid = 0;
Igor Murashkin634a5152013-02-20 17:15:11 -08001576}
1577
Ruben Brunkcc776712015-02-17 20:18:47 -08001578String16 CameraService::BasicClient::getPackageName() const {
1579 return mClientPackageName;
1580}
1581
1582
1583int CameraService::BasicClient::getClientPid() const {
1584 return mClientPid;
1585}
1586
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001587status_t CameraService::BasicClient::startCameraOps() {
1588 int32_t res;
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001589 // Notify app ops that the camera is not available
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001590 mOpsCallback = new OpsCallback(this);
1591
Igor Murashkine6800ce2013-03-04 17:25:57 -08001592 {
1593 ALOGV("%s: Start camera ops, package name = %s, client UID = %d",
1594 __FUNCTION__, String8(mClientPackageName).string(), mClientUid);
1595 }
1596
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001597 mAppOpsManager.startWatchingMode(AppOpsManager::OP_CAMERA,
1598 mClientPackageName, mOpsCallback);
1599 res = mAppOpsManager.startOp(AppOpsManager::OP_CAMERA,
1600 mClientUid, mClientPackageName);
1601
1602 if (res != AppOpsManager::MODE_ALLOWED) {
1603 ALOGI("Camera %d: Access for \"%s\" has been revoked",
1604 mCameraId, String8(mClientPackageName).string());
1605 return PERMISSION_DENIED;
1606 }
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001607
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001608 mOpsActive = true;
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001609
1610 // Transition device availability listeners from PRESENT -> NOT_AVAILABLE
1611 mCameraService->updateStatus(ICameraServiceListener::STATUS_NOT_AVAILABLE,
Ruben Brunkcc776712015-02-17 20:18:47 -08001612 String8::format("%d", mCameraId));
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001613
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001614 return OK;
1615}
1616
1617status_t CameraService::BasicClient::finishCameraOps() {
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001618 // Check if startCameraOps succeeded, and if so, finish the camera op
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001619 if (mOpsActive) {
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001620 // Notify app ops that the camera is available again
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001621 mAppOpsManager.finishOp(AppOpsManager::OP_CAMERA, mClientUid,
1622 mClientPackageName);
1623 mOpsActive = false;
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001624
Ruben Brunkcc776712015-02-17 20:18:47 -08001625 auto rejected = {ICameraServiceListener::STATUS_NOT_PRESENT,
1626 ICameraServiceListener::STATUS_ENUMERATING};
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001627
Ruben Brunkcc776712015-02-17 20:18:47 -08001628 // Transition to PRESENT if the camera is not in either of the rejected states
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001629 mCameraService->updateStatus(ICameraServiceListener::STATUS_PRESENT,
Ruben Brunkcc776712015-02-17 20:18:47 -08001630 String8::format("%d", mCameraId), rejected);
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001631
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001632 // Notify flashlight that a camera device is closed.
1633 mCameraService->mFlashlight->deviceClosed(
1634 String8::format("%d", mCameraId));
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001635 }
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001636 // Always stop watching, even if no camera op is active
Eino-Ville Talvalae992e752014-11-07 16:17:48 -08001637 if (mOpsCallback != NULL) {
1638 mAppOpsManager.stopWatchingMode(mOpsCallback);
1639 }
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001640 mOpsCallback.clear();
1641
1642 return OK;
1643}
1644
1645void CameraService::BasicClient::opChanged(int32_t op, const String16& packageName) {
1646 String8 name(packageName);
1647 String8 myName(mClientPackageName);
1648
1649 if (op != AppOpsManager::OP_CAMERA) {
1650 ALOGW("Unexpected app ops notification received: %d", op);
1651 return;
1652 }
1653
1654 int32_t res;
1655 res = mAppOpsManager.checkOp(AppOpsManager::OP_CAMERA,
1656 mClientUid, mClientPackageName);
1657 ALOGV("checkOp returns: %d, %s ", res,
1658 res == AppOpsManager::MODE_ALLOWED ? "ALLOWED" :
1659 res == AppOpsManager::MODE_IGNORED ? "IGNORED" :
1660 res == AppOpsManager::MODE_ERRORED ? "ERRORED" :
1661 "UNKNOWN");
1662
1663 if (res != AppOpsManager::MODE_ALLOWED) {
1664 ALOGI("Camera %d: Access for \"%s\" revoked", mCameraId,
1665 myName.string());
1666 // Reset the client PID to allow server-initiated disconnect,
1667 // and to prevent further calls by client.
1668 mClientPid = getCallingPid();
Jianing Weicb0652e2014-03-12 18:29:36 -07001669 CaptureResultExtras resultExtras; // a dummy result (invalid)
1670 notifyError(ICameraDeviceCallbacks::ERROR_CAMERA_SERVICE, resultExtras);
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001671 disconnect();
1672 }
1673}
1674
Mathias Agopian65ab4712010-07-14 17:59:35 -07001675// ----------------------------------------------------------------------------
1676
Ruben Brunkcc776712015-02-17 20:18:47 -08001677// Provide client strong pointer for callbacks.
1678sp<CameraService::Client> CameraService::Client::getClientFromCookie(void* user) {
1679 String8 cameraId = String8::format("%d", (int)(intptr_t) user);
1680 auto clientDescriptor = gCameraService->mActiveClientManager.get(cameraId);
1681 if (clientDescriptor != nullptr) {
1682 return sp<Client>{
1683 static_cast<Client*>(clientDescriptor->getValue().get())};
1684 }
1685 return sp<Client>{nullptr};
Mathias Agopian65ab4712010-07-14 17:59:35 -07001686}
1687
Jianing Weicb0652e2014-03-12 18:29:36 -07001688void CameraService::Client::notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode,
1689 const CaptureResultExtras& resultExtras) {
Igor Murashkin44cfcf02013-03-01 16:22:28 -08001690 mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_RELEASED, 0);
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001691}
1692
Igor Murashkin036bc3e2012-10-08 15:09:46 -07001693// NOTE: function is idempotent
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001694void CameraService::Client::disconnect() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -07001695 ALOGV("Client::disconnect");
Igor Murashkin634a5152013-02-20 17:15:11 -08001696 BasicClient::disconnect();
Wu-cheng Lie09591e2010-10-14 20:17:44 +08001697}
1698
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001699CameraService::Client::OpsCallback::OpsCallback(wp<BasicClient> client):
1700 mClient(client) {
1701}
1702
1703void CameraService::Client::OpsCallback::opChanged(int32_t op,
1704 const String16& packageName) {
1705 sp<BasicClient> client = mClient.promote();
1706 if (client != NULL) {
1707 client->opChanged(op, packageName);
1708 }
1709}
1710
Mathias Agopian65ab4712010-07-14 17:59:35 -07001711// ----------------------------------------------------------------------------
Igor Murashkin634a5152013-02-20 17:15:11 -08001712// IProCamera
1713// ----------------------------------------------------------------------------
1714
1715CameraService::ProClient::ProClient(const sp<CameraService>& cameraService,
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001716 const sp<IProCameraCallbacks>& remoteCallback,
1717 const String16& clientPackageName,
1718 int cameraId,
1719 int cameraFacing,
1720 int clientPid,
1721 uid_t clientUid,
1722 int servicePid)
Marco Nelissenf8880202014-11-14 07:58:25 -08001723 : CameraService::BasicClient(cameraService, IInterface::asBinder(remoteCallback),
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001724 clientPackageName, cameraId, cameraFacing,
1725 clientPid, clientUid, servicePid)
Igor Murashkin634a5152013-02-20 17:15:11 -08001726{
1727 mRemoteCallback = remoteCallback;
1728}
1729
1730CameraService::ProClient::~ProClient() {
Igor Murashkin634a5152013-02-20 17:15:11 -08001731}
1732
Jianing Weicb0652e2014-03-12 18:29:36 -07001733void CameraService::ProClient::notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode,
1734 const CaptureResultExtras& resultExtras) {
Igor Murashkine6800ce2013-03-04 17:25:57 -08001735 mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_RELEASED, 0);
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001736}
1737
Igor Murashkin634a5152013-02-20 17:15:11 -08001738// ----------------------------------------------------------------------------
Ruben Brunkcc776712015-02-17 20:18:47 -08001739// CameraState
1740// ----------------------------------------------------------------------------
1741
1742CameraService::CameraState::CameraState(const String8& id, int cost,
1743 const std::set<String8>& conflicting) : mId(id),
1744 mStatus(ICameraServiceListener::STATUS_PRESENT), mCost(cost), mConflicting(conflicting) {}
1745
1746CameraService::CameraState::~CameraState() {}
1747
1748ICameraServiceListener::Status CameraService::CameraState::getStatus() const {
1749 Mutex::Autolock lock(mStatusLock);
1750 return mStatus;
1751}
1752
1753CameraParameters CameraService::CameraState::getShimParams() const {
1754 return mShimParams;
1755}
1756
1757void CameraService::CameraState::setShimParams(const CameraParameters& params) {
1758 mShimParams = params;
1759}
1760
1761int CameraService::CameraState::getCost() const {
1762 return mCost;
1763}
1764
1765std::set<String8> CameraService::CameraState::getConflicting() const {
1766 return mConflicting;
1767}
1768
1769String8 CameraService::CameraState::getId() const {
1770 return mId;
1771}
1772
1773// ----------------------------------------------------------------------------
1774// CameraClientManager
1775// ----------------------------------------------------------------------------
1776
1777CameraService::CameraClientManager::~CameraClientManager() {}
1778
1779sp<CameraService::BasicClient> CameraService::CameraClientManager::getCameraClient(
1780 const String8& id) const {
1781 auto descriptor = get(id);
1782 if (descriptor == nullptr) {
1783 return sp<BasicClient>{nullptr};
1784 }
1785 return descriptor->getValue();
1786}
1787
1788String8 CameraService::CameraClientManager::toString() const {
1789 auto all = getAll();
1790 String8 ret("[");
1791 bool hasAny = false;
1792 for (auto& i : all) {
1793 hasAny = true;
1794 String8 key = i->getKey();
1795 int32_t cost = i->getCost();
1796 int32_t pid = i->getOwnerId();
1797 int32_t priority = i->getPriority();
1798 auto conflicting = i->getConflicting();
1799 auto clientSp = i->getValue();
1800 String8 packageName;
1801 if (clientSp.get() != nullptr) {
1802 packageName = String8{clientSp->getPackageName()};
1803 }
1804 ret.appendFormat("\n(Camera ID: %s, Cost: %" PRId32 ", PID: %" PRId32 ", Priority: %"
1805 PRId32 ", ", key.string(), cost, pid, priority);
1806
1807 if (packageName.size() != 0) {
1808 ret.appendFormat("Client Package Name: %s", packageName.string());
1809 }
1810
1811 ret.append(", Conflicting Client Devices: {");
1812 for (auto& j : conflicting) {
1813 ret.appendFormat("%s, ", j.string());
1814 }
1815 ret.append("})");
1816 }
1817 if (hasAny) ret.append("\n");
1818 ret.append("]\n");
1819 return ret;
1820}
1821
1822CameraService::DescriptorPtr CameraService::CameraClientManager::makeClientDescriptor(
1823 const String8& key, const sp<BasicClient>& value, int32_t cost,
1824 const std::set<String8>& conflictingKeys, int32_t priority, int32_t ownerId) {
1825
1826 return std::make_shared<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>(
1827 key, value, cost, conflictingKeys, priority, ownerId);
1828}
1829
1830CameraService::DescriptorPtr CameraService::CameraClientManager::makeClientDescriptor(
1831 const sp<BasicClient>& value, const CameraService::DescriptorPtr& partial) {
1832 return makeClientDescriptor(partial->getKey(), value, partial->getCost(),
1833 partial->getConflicting(), partial->getPriority(), partial->getOwnerId());
1834}
1835
1836// ----------------------------------------------------------------------------
Mathias Agopian65ab4712010-07-14 17:59:35 -07001837
1838static const int kDumpLockRetries = 50;
1839static const int kDumpLockSleep = 60000;
1840
1841static bool tryLock(Mutex& mutex)
1842{
1843 bool locked = false;
1844 for (int i = 0; i < kDumpLockRetries; ++i) {
1845 if (mutex.tryLock() == NO_ERROR) {
1846 locked = true;
1847 break;
1848 }
1849 usleep(kDumpLockSleep);
1850 }
1851 return locked;
1852}
1853
1854status_t CameraService::dump(int fd, const Vector<String16>& args) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001855 String8 result;
1856 if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -07001857 result.appendFormat("Permission Denial: "
Mathias Agopian65ab4712010-07-14 17:59:35 -07001858 "can't dump CameraService from pid=%d, uid=%d\n",
1859 getCallingPid(),
1860 getCallingUid());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001861 write(fd, result.string(), result.size());
1862 } else {
1863 bool locked = tryLock(mServiceLock);
1864 // failed to lock - CameraService is probably deadlocked
1865 if (!locked) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -07001866 result.append("CameraService may be deadlocked\n");
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001867 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001868 }
1869
1870 bool hasClient = false;
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001871 if (!mModule) {
1872 result = String8::format("No camera module available!\n");
1873 write(fd, result.string(), result.size());
Kalle Lampila6ec3a152013-04-30 15:27:19 +03001874 if (locked) mServiceLock.unlock();
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001875 return NO_ERROR;
1876 }
1877
Chien-Yu Chen676b21b2015-02-24 10:28:19 -08001878 result = String8::format("Camera module HAL API version: 0x%x\n", mModule->getHalApiVersion());
1879 result.appendFormat("Camera module API version: 0x%x\n", mModule->getModuleApiVersion());
1880 result.appendFormat("Camera module name: %s\n", mModule->getModuleName());
1881 result.appendFormat("Camera module author: %s\n", mModule->getModuleAuthor());
Ruben Brunkcc776712015-02-17 20:18:47 -08001882 result.appendFormat("Number of camera devices: %d\n", mNumberOfCameras);
1883 String8 activeClientString = mActiveClientManager.toString();
1884 result.appendFormat("Active Camera Clients:\n%s", activeClientString.string());
1885
Ruben Brunkf81648e2014-04-17 16:14:57 -07001886 sp<VendorTagDescriptor> desc = VendorTagDescriptor::getGlobalVendorTagDescriptor();
1887 if (desc == NULL) {
1888 result.appendFormat("Vendor tags left unimplemented.\n");
1889 } else {
1890 result.appendFormat("Vendor tag definitions:\n");
1891 }
1892
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001893 write(fd, result.string(), result.size());
Ruben Brunkf81648e2014-04-17 16:14:57 -07001894
1895 if (desc != NULL) {
1896 desc->dump(fd, /*verbosity*/2, /*indentation*/4);
1897 }
1898
Ruben Brunkcc776712015-02-17 20:18:47 -08001899 result = String8("Prior client events (most recent at top):\n");
1900
1901 for (const auto& msg : mEventLog) {
1902 result.appendFormat("%s\n", msg.string());
1903 }
1904
1905 if (mEventLog.size() == DEFAULT_EVICTION_LOG_LENGTH) {
1906 result.append("...\n");
1907 }
1908
1909 write(fd, result.string(), result.size());
1910
1911 bool stateLocked = tryLock(mCameraStatesLock);
1912 if (!stateLocked) {
1913 result = String8::format("CameraStates in use, may be deadlocked\n");
1914 write(fd, result.string(), result.size());
1915 }
1916
1917 for (auto& state : mCameraStates) {
1918 String8 cameraId = state.first;
1919 result = String8::format("Camera %s information:\n", cameraId.string());
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001920 camera_info info;
1921
Ruben Brunkcc776712015-02-17 20:18:47 -08001922 // TODO: Change getCameraInfo + HAL to use String cameraIds
1923 status_t rc = mModule->getCameraInfo(cameraIdToInt(cameraId), &info);
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001924 if (rc != OK) {
1925 result.appendFormat(" Error reading static information!\n");
1926 write(fd, result.string(), result.size());
1927 } else {
1928 result.appendFormat(" Facing: %s\n",
1929 info.facing == CAMERA_FACING_BACK ? "BACK" : "FRONT");
1930 result.appendFormat(" Orientation: %d\n", info.orientation);
1931 int deviceVersion;
Chien-Yu Chen676b21b2015-02-24 10:28:19 -08001932 if (mModule->getModuleApiVersion() < CAMERA_MODULE_API_VERSION_2_0) {
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001933 deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
1934 } else {
1935 deviceVersion = info.device_version;
1936 }
Ruben Brunkcc776712015-02-17 20:18:47 -08001937
1938 auto conflicting = state.second->getConflicting();
1939 result.appendFormat(" Resource Cost: %d\n", state.second->getCost());
1940 result.appendFormat(" Conflicting Devices:");
1941 for (auto& id : conflicting) {
1942 result.appendFormat(" %s", cameraId.string());
1943 }
1944 if (conflicting.size() == 0) {
1945 result.appendFormat(" NONE");
1946 }
1947 result.appendFormat("\n");
1948
1949 result.appendFormat(" Device version: %#x\n", deviceVersion);
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001950 if (deviceVersion >= CAMERA_DEVICE_API_VERSION_2_0) {
1951 result.appendFormat(" Device static metadata:\n");
1952 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -07001953 dump_indented_camera_metadata(info.static_camera_characteristics,
Ruben Brunkf81648e2014-04-17 16:14:57 -07001954 fd, /*verbosity*/2, /*indentation*/4);
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001955 } else {
1956 write(fd, result.string(), result.size());
1957 }
Ruben Brunkcc776712015-02-17 20:18:47 -08001958
1959 CameraParameters p = state.second->getShimParams();
1960 if (!p.isEmpty()) {
1961 result = String8::format(" Camera1 API shim is using parameters:\n ");
1962 write(fd, result.string(), result.size());
1963 p.dump(fd, args);
1964 }
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001965 }
1966
Ruben Brunkcc776712015-02-17 20:18:47 -08001967 auto clientDescriptor = mActiveClientManager.get(cameraId);
1968 if (clientDescriptor == nullptr) {
1969 result = String8::format(" Device %s is closed, no client instance\n",
1970 cameraId.string());
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001971 write(fd, result.string(), result.size());
1972 continue;
1973 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001974 hasClient = true;
Ruben Brunkcc776712015-02-17 20:18:47 -08001975 result = String8::format(" Device %s is open. Client instance dump:\n\n",
1976 cameraId.string());
1977 result.appendFormat("Client priority level: %d\n", clientDescriptor->getPriority());
1978 result.appendFormat("Client PID: %d\n", clientDescriptor->getOwnerId());
1979
1980 auto client = clientDescriptor->getValue();
1981 result.appendFormat("Client package: %s\n",
1982 String8(client->getPackageName()).string());
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001983 write(fd, result.string(), result.size());
Ruben Brunkcc776712015-02-17 20:18:47 -08001984
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001985 client->dump(fd, args);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001986 }
Ruben Brunkcc776712015-02-17 20:18:47 -08001987
1988 if (stateLocked) mCameraStatesLock.unlock();
1989
Mathias Agopian65ab4712010-07-14 17:59:35 -07001990 if (!hasClient) {
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001991 result = String8::format("\nNo active camera clients yet.\n");
1992 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001993 }
1994
1995 if (locked) mServiceLock.unlock();
1996
Igor Murashkinff3e31d2013-10-23 16:40:06 -07001997 // Dump camera traces if there were any
1998 write(fd, "\n", 1);
1999 camera3::CameraTraces::dump(fd, args);
2000
Mathias Agopian65ab4712010-07-14 17:59:35 -07002001 // change logging level
2002 int n = args.size();
2003 for (int i = 0; i + 1 < n; i++) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -07002004 String16 verboseOption("-v");
2005 if (args[i] == verboseOption) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07002006 String8 levelStr(args[i+1]);
2007 int level = atoi(levelStr.string());
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07002008 result = String8::format("\nSetting log level to %d.\n", level);
Mathias Agopian65ab4712010-07-14 17:59:35 -07002009 setLogLevel(level);
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07002010 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07002011 }
2012 }
2013 }
2014 return NO_ERROR;
2015}
2016
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002017void CameraService::handleTorchClientBinderDied(const wp<IBinder> &who) {
Chien-Yu Chen88da5262015-02-17 13:56:46 -08002018 Mutex::Autolock al(mTorchClientMapMutex);
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002019 for (size_t i = 0; i < mTorchClientMap.size(); i++) {
2020 if (mTorchClientMap[i] == who) {
2021 // turn off the torch mode that was turned on by dead client
Chien-Yu Chen88da5262015-02-17 13:56:46 -08002022 String8 cameraId = mTorchClientMap.keyAt(i);
2023 status_t res = mFlashlight->setTorchMode(cameraId, false);
2024 if (res) {
2025 ALOGE("%s: torch client died but couldn't turn off torch: "
2026 "%s (%d)", __FUNCTION__, strerror(-res), res);
2027 return;
2028 }
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002029 mTorchClientMap.removeItemsAt(i);
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002030 break;
2031 }
2032 }
2033}
2034
Ruben Brunkcc776712015-02-17 20:18:47 -08002035/*virtual*/void CameraService::binderDied(const wp<IBinder> &who) {
Igor Murashkinecf17e82012-10-02 16:05:11 -07002036
Igor Murashkin294d0ec2012-10-05 10:44:57 -07002037 /**
2038 * While tempting to promote the wp<IBinder> into a sp,
2039 * it's actually not supported by the binder driver
2040 */
2041
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002042 // check torch client
2043 handleTorchClientBinderDied(who);
2044
2045 // check camera device client
Ruben Brunkcc776712015-02-17 20:18:47 -08002046 if(!evictClientIdByRemote(who)) {
2047 ALOGV("%s: Java client's binder death already cleaned up (normal case)", __FUNCTION__);
Igor Murashkinecf17e82012-10-02 16:05:11 -07002048 return;
2049 }
2050
Ruben Brunkcc776712015-02-17 20:18:47 -08002051 ALOGE("%s: Java client's binder died, removing it from the list of active clients",
2052 __FUNCTION__);
Igor Murashkinecf17e82012-10-02 16:05:11 -07002053}
2054
Ruben Brunkcc776712015-02-17 20:18:47 -08002055void CameraService::updateStatus(ICameraServiceListener::Status status, const String8& cameraId) {
2056 updateStatus(status, cameraId, {});
Igor Murashkinbfc99152013-02-27 12:55:20 -08002057}
2058
Ruben Brunkcc776712015-02-17 20:18:47 -08002059void CameraService::updateStatus(ICameraServiceListener::Status status, const String8& cameraId,
2060 std::initializer_list<ICameraServiceListener::Status> rejectSourceStates) {
2061 // Do not lock mServiceLock here or can get into a deadlock from
2062 // connect() -> disconnect -> updateStatus
2063
2064 auto state = getCameraState(cameraId);
2065
2066 if (state == nullptr) {
2067 ALOGW("%s: Could not update the status for %s, no such device exists", __FUNCTION__,
2068 cameraId.string());
2069 return;
Igor Murashkincba2c162013-03-20 15:56:31 -07002070 }
2071
Ruben Brunkcc776712015-02-17 20:18:47 -08002072 // Update the status for this camera state, then send the onStatusChangedCallbacks to each
2073 // of the listeners with both the mStatusStatus and mStatusListenerLock held
2074 state->updateStatus(status, cameraId, rejectSourceStates, [this]
2075 (const String8& cameraId, ICameraServiceListener::Status status) {
2076
2077 // Update torch status
2078 if (status == ICameraServiceListener::STATUS_NOT_PRESENT ||
2079 status == ICameraServiceListener::STATUS_NOT_AVAILABLE) {
2080 // Update torch status to not available when the camera device becomes not present
2081 // or not available.
2082 onTorchStatusChanged(cameraId, ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE);
2083 } else if (status == ICameraServiceListener::STATUS_PRESENT) {
2084 // Update torch status to available when the camera device becomes present or
2085 // available
2086 onTorchStatusChanged(cameraId, ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF);
2087 }
2088
2089 Mutex::Autolock lock(mStatusListenerLock);
2090
2091 for (auto& listener : mListenerList) {
2092 // TODO: Refactor status listeners to use strings for Camera IDs and remove this.
2093 int id = cameraIdToInt(cameraId);
2094 if (id != -1) listener->onStatusChanged(status, id);
2095 }
2096 });
Igor Murashkincba2c162013-03-20 15:56:31 -07002097}
2098
Chien-Yu Chen88da5262015-02-17 13:56:46 -08002099status_t CameraService::getTorchStatusLocked(
2100 const String8& cameraId,
2101 ICameraServiceListener::TorchStatus *status) const {
2102 if (!status) {
2103 return BAD_VALUE;
2104 }
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002105 ssize_t index = mTorchStatusMap.indexOfKey(cameraId);
2106 if (index == NAME_NOT_FOUND) {
Chien-Yu Chen88da5262015-02-17 13:56:46 -08002107 // invalid camera ID or the camera doesn't have a flash unit
2108 return NAME_NOT_FOUND;
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002109 }
2110
Chien-Yu Chen88da5262015-02-17 13:56:46 -08002111 *status = mTorchStatusMap.valueAt(index);
2112 return OK;
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002113}
2114
Chien-Yu Chen88da5262015-02-17 13:56:46 -08002115status_t CameraService::setTorchStatusLocked(const String8& cameraId,
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002116 ICameraServiceListener::TorchStatus status) {
2117 ssize_t index = mTorchStatusMap.indexOfKey(cameraId);
2118 if (index == NAME_NOT_FOUND) {
2119 return BAD_VALUE;
2120 }
2121 ICameraServiceListener::TorchStatus& item =
2122 mTorchStatusMap.editValueAt(index);
2123 item = status;
2124
2125 return OK;
2126}
2127
Mathias Agopian65ab4712010-07-14 17:59:35 -07002128}; // namespace android