blob: e9c96c663e5df334f20b97134d578f53d2d6edb0 [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>
Mathias Agopiandf712ea2012-02-25 18:48:35 -080038#include <gui/Surface.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070039#include <hardware/hardware.h>
40#include <media/AudioSystem.h>
Andreas Huber1b86fe02014-01-29 11:13:26 -080041#include <media/IMediaHTTPService.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070042#include <media/mediaplayer.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070043#include <utils/Errors.h>
44#include <utils/Log.h>
45#include <utils/String16.h>
Ruben Brunkd1176ef2014-02-21 10:51:38 -080046#include <utils/Trace.h>
47#include <system/camera_vendor_tags.h>
Ruben Brunkb2119af2014-05-09 19:57:56 -070048#include <system/camera_metadata.h>
49#include <system/camera.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070050
51#include "CameraService.h"
Eino-Ville Talvala7b82efe2013-07-25 17:12:35 -070052#include "api1/CameraClient.h"
53#include "api1/Camera2Client.h"
Eino-Ville Talvala7b82efe2013-07-25 17:12:35 -070054#include "api2/CameraDeviceClient.h"
Igor Murashkinff3e31d2013-10-23 16:40:06 -070055#include "utils/CameraTraces.h"
Igor Murashkin98e24722013-06-19 19:51:04 -070056#include "CameraDeviceFactory.h"
Mathias Agopian65ab4712010-07-14 17:59:35 -070057
58namespace android {
59
60// ----------------------------------------------------------------------------
61// Logging support -- this is for debugging only
62// Use "adb shell dumpsys media.camera -v 1" to change it.
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -070063volatile int32_t gLogLevel = 0;
Mathias Agopian65ab4712010-07-14 17:59:35 -070064
Steve Blockb8a80522011-12-20 16:23:08 +000065#define LOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__);
66#define LOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__);
Mathias Agopian65ab4712010-07-14 17:59:35 -070067
68static void setLogLevel(int level) {
69 android_atomic_write(level, &gLogLevel);
70}
71
72// ----------------------------------------------------------------------------
73
Igor Murashkincba2c162013-03-20 15:56:31 -070074extern "C" {
75static void camera_device_status_change(
76 const struct camera_module_callbacks* callbacks,
77 int camera_id,
78 int new_status) {
79 sp<CameraService> cs = const_cast<CameraService*>(
Ruben Brunkcc776712015-02-17 20:18:47 -080080 static_cast<const CameraService*>(callbacks));
Igor Murashkincba2c162013-03-20 15:56:31 -070081
Ruben Brunkcc776712015-02-17 20:18:47 -080082 cs->onDeviceStatusChanged(static_cast<camera_device_status_t>(camera_id),
83 static_cast<camera_device_status_t>(new_status));
Igor Murashkincba2c162013-03-20 15:56:31 -070084}
Chien-Yu Chen3068d732015-02-09 13:29:57 -080085
86static void torch_mode_status_change(
87 const struct camera_module_callbacks* callbacks,
88 const char* camera_id,
89 int new_status) {
90 if (!callbacks || !camera_id) {
91 ALOGE("%s invalid parameters. callbacks %p, camera_id %p", __FUNCTION__,
92 callbacks, camera_id);
93 }
94 sp<CameraService> cs = const_cast<CameraService*>(
95 static_cast<const CameraService*>(callbacks));
96
97 ICameraServiceListener::TorchStatus status;
98 switch (new_status) {
Chien-Yu Chen88da5262015-02-17 13:56:46 -080099 case TORCH_MODE_STATUS_NOT_AVAILABLE:
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800100 status = ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE;
101 break;
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800102 case TORCH_MODE_STATUS_AVAILABLE_OFF:
103 status = ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF;
104 break;
105 case TORCH_MODE_STATUS_AVAILABLE_ON:
106 status = ICameraServiceListener::TORCH_STATUS_AVAILABLE_ON;
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800107 break;
108 default:
109 ALOGE("Unknown torch status %d", new_status);
110 return;
111 }
112
113 cs->onTorchStatusChanged(
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800114 String8(camera_id),
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800115 status);
116}
Igor Murashkincba2c162013-03-20 15:56:31 -0700117} // extern "C"
118
Mathias Agopian65ab4712010-07-14 17:59:35 -0700119// ----------------------------------------------------------------------------
120
121// This is ugly and only safe if we never re-create the CameraService, but
122// should be ok for now.
123static CameraService *gCameraService;
124
Ruben Brunk36597b22015-03-20 22:15:57 -0700125CameraService::CameraService() : mEventLog(DEFAULT_EVICTION_LOG_LENGTH),
126 mLastUserId(DEFAULT_LAST_USER_ID), mSoundRef(0), mModule(0), mFlashlight(0) {
Steve Blockdf64d152012-01-04 20:05:49 +0000127 ALOGI("CameraService started (pid=%d)", getpid());
Mathias Agopian65ab4712010-07-14 17:59:35 -0700128 gCameraService = this;
Igor Murashkinbfc99152013-02-27 12:55:20 -0800129
Igor Murashkincba2c162013-03-20 15:56:31 -0700130 this->camera_device_status_change = android::camera_device_status_change;
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800131 this->torch_mode_status_change = android::torch_mode_status_change;
132
Ruben Brunkcc776712015-02-17 20:18:47 -0800133 mServiceLockWrapper = std::make_shared<WaitableMutexWrapper>(&mServiceLock);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700134}
135
Iliyan Malchev8951a972011-04-14 16:55:59 -0700136void CameraService::onFirstRef()
137{
Ruben Brunkcc776712015-02-17 20:18:47 -0800138 ALOGI("CameraService process starting");
Igor Murashkin634a5152013-02-20 17:15:11 -0800139
Iliyan Malchev8951a972011-04-14 16:55:59 -0700140 BnCameraService::onFirstRef();
141
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800142 camera_module_t *rawModule;
Iliyan Malchev8951a972011-04-14 16:55:59 -0700143 if (hw_get_module(CAMERA_HARDWARE_MODULE_ID,
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800144 (const hw_module_t **)&rawModule) < 0) {
Steve Block29357bc2012-01-06 19:20:56 +0000145 ALOGE("Could not load camera HAL module");
Iliyan Malchev8951a972011-04-14 16:55:59 -0700146 mNumberOfCameras = 0;
147 }
148 else {
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800149 mModule = new CameraModule(rawModule);
Chien-Yu Chen676b21b2015-02-24 10:28:19 -0800150 ALOGI("Loaded \"%s\" camera module", mModule->getModuleName());
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800151 mNumberOfCameras = mModule->getNumberOfCameras();
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800152
153 mFlashlight = new CameraFlashlight(*mModule, *this);
154 status_t res = mFlashlight->findFlashUnits();
155 if (res) {
156 // impossible because we haven't open any camera devices.
Ruben Brunkcc776712015-02-17 20:18:47 -0800157 ALOGE("Failed to find flash units.");
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800158 }
159
Iliyan Malchev8951a972011-04-14 16:55:59 -0700160 for (int i = 0; i < mNumberOfCameras; i++) {
Ruben Brunkcc776712015-02-17 20:18:47 -0800161 String8 cameraId = String8::format("%d", i);
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800162
Ruben Brunkcc776712015-02-17 20:18:47 -0800163 // Defaults to use for cost and conflicting devices
164 int cost = 100;
165 char** conflicting_devices = nullptr;
166 size_t conflicting_devices_length = 0;
167
168 // If using post-2.4 module version, query the cost + conflicting devices from the HAL
Chien-Yu Chen676b21b2015-02-24 10:28:19 -0800169 if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_4) {
Ruben Brunkcc776712015-02-17 20:18:47 -0800170 struct camera_info info;
171 status_t rc = mModule->getCameraInfo(i, &info);
172 if (rc == NO_ERROR) {
173 cost = info.resource_cost;
174 conflicting_devices = info.conflicting_devices;
175 conflicting_devices_length = info.conflicting_devices_length;
176 } else {
177 ALOGE("%s: Received error loading camera info for device %d, cost and"
178 " conflicting devices fields set to defaults for this device.",
179 __FUNCTION__, i);
180 }
181 }
182
183 std::set<String8> conflicting;
184 for (size_t i = 0; i < conflicting_devices_length; i++) {
185 conflicting.emplace(String8(conflicting_devices[i]));
186 }
187
188 // Initialize state for each camera device
189 {
190 Mutex::Autolock lock(mCameraStatesLock);
191 mCameraStates.emplace(cameraId, std::make_shared<CameraState>(cameraId, cost,
192 conflicting));
193 }
194
195 if (mFlashlight->hasFlashUnit(cameraId)) {
196 mTorchStatusMap.add(cameraId,
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800197 ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF);
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800198 }
Iliyan Malchev8951a972011-04-14 16:55:59 -0700199 }
Igor Murashkincba2c162013-03-20 15:56:31 -0700200
Chien-Yu Chen676b21b2015-02-24 10:28:19 -0800201 if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_1) {
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800202 mModule->setCallbacks(this);
Igor Murashkincba2c162013-03-20 15:56:31 -0700203 }
Igor Murashkin98e24722013-06-19 19:51:04 -0700204
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800205 VendorTagDescriptor::clearGlobalVendorTagDescriptor();
206
Chien-Yu Chen676b21b2015-02-24 10:28:19 -0800207 if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_2) {
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800208 setUpVendorTags();
209 }
210
Igor Murashkin98e24722013-06-19 19:51:04 -0700211 CameraDeviceFactory::registerService(this);
Iliyan Malchev8951a972011-04-14 16:55:59 -0700212 }
213}
214
Mathias Agopian65ab4712010-07-14 17:59:35 -0700215CameraService::~CameraService() {
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800216 if (mModule) {
217 delete mModule;
Ruben Brunkcc776712015-02-17 20:18:47 -0800218 mModule = nullptr;
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800219 }
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800220 VendorTagDescriptor::clearGlobalVendorTagDescriptor();
Ruben Brunkcc776712015-02-17 20:18:47 -0800221 gCameraService = nullptr;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700222}
223
Ruben Brunkcc776712015-02-17 20:18:47 -0800224void CameraService::onDeviceStatusChanged(camera_device_status_t cameraId,
225 camera_device_status_t newStatus) {
226 ALOGI("%s: Status changed for cameraId=%d, newStatus=%d", __FUNCTION__,
Igor Murashkincba2c162013-03-20 15:56:31 -0700227 cameraId, newStatus);
228
Ruben Brunkcc776712015-02-17 20:18:47 -0800229 String8 id = String8::format("%d", cameraId);
230 std::shared_ptr<CameraState> state = getCameraState(id);
231
232 if (state == nullptr) {
Igor Murashkincba2c162013-03-20 15:56:31 -0700233 ALOGE("%s: Bad camera ID %d", __FUNCTION__, cameraId);
234 return;
235 }
236
Ruben Brunkcc776712015-02-17 20:18:47 -0800237 ICameraServiceListener::Status oldStatus = state->getStatus();
238
239 if (oldStatus == static_cast<ICameraServiceListener::Status>(newStatus)) {
240 ALOGE("%s: State transition to the same status %#x not allowed", __FUNCTION__, newStatus);
Igor Murashkincba2c162013-03-20 15:56:31 -0700241 return;
242 }
243
Igor Murashkincba2c162013-03-20 15:56:31 -0700244 if (newStatus == CAMERA_DEVICE_STATUS_NOT_PRESENT) {
Ruben Brunkcc776712015-02-17 20:18:47 -0800245 sp<BasicClient> clientToDisconnect;
Igor Murashkincba2c162013-03-20 15:56:31 -0700246 {
Ruben Brunkcc776712015-02-17 20:18:47 -0800247 // Don't do this in updateStatus to avoid deadlock over mServiceLock
248 Mutex::Autolock lock(mServiceLock);
Igor Murashkincba2c162013-03-20 15:56:31 -0700249
Ruben Brunkcc776712015-02-17 20:18:47 -0800250 // Set the device status to NOT_PRESENT, clients will no longer be able to connect
251 // to this device until the status changes
252 updateStatus(ICameraServiceListener::STATUS_NOT_PRESENT, id);
Ruben Brunkb2119af2014-05-09 19:57:56 -0700253
Ruben Brunkcc776712015-02-17 20:18:47 -0800254 // Remove cached shim parameters
255 state->setShimParams(CameraParameters());
Igor Murashkincba2c162013-03-20 15:56:31 -0700256
Ruben Brunkcc776712015-02-17 20:18:47 -0800257 // Remove the client from the list of active clients
258 clientToDisconnect = removeClientLocked(id);
259
260 // Notify the client of disconnection
261 clientToDisconnect->notifyError(ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED,
262 CaptureResultExtras{});
Igor Murashkincba2c162013-03-20 15:56:31 -0700263 }
264
Ruben Brunkcc776712015-02-17 20:18:47 -0800265 ALOGI("%s: Client for camera ID %s evicted due to device status change from HAL",
266 __FUNCTION__, id.string());
Igor Murashkincba2c162013-03-20 15:56:31 -0700267
Ruben Brunkcc776712015-02-17 20:18:47 -0800268 // Disconnect client
269 if (clientToDisconnect.get() != nullptr) {
270 // Ensure not in binder RPC so client disconnect PID checks work correctly
271 LOG_ALWAYS_FATAL_IF(getCallingPid() != getpid(),
272 "onDeviceStatusChanged must be called from the camera service process!");
273 clientToDisconnect->disconnect();
Igor Murashkincba2c162013-03-20 15:56:31 -0700274 }
275
Ruben Brunkcc776712015-02-17 20:18:47 -0800276 } else {
277 updateStatus(static_cast<ICameraServiceListener::Status>(newStatus), id);
Igor Murashkincba2c162013-03-20 15:56:31 -0700278 }
279
Igor Murashkincba2c162013-03-20 15:56:31 -0700280}
281
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800282void CameraService::onTorchStatusChanged(const String8& cameraId,
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800283 ICameraServiceListener::TorchStatus newStatus) {
284 Mutex::Autolock al(mTorchStatusMutex);
285 onTorchStatusChangedLocked(cameraId, newStatus);
286}
287
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800288void CameraService::onTorchStatusChangedLocked(const String8& cameraId,
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800289 ICameraServiceListener::TorchStatus newStatus) {
290 ALOGI("%s: Torch status changed for cameraId=%s, newStatus=%d",
291 __FUNCTION__, cameraId.string(), newStatus);
292
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800293 ICameraServiceListener::TorchStatus status;
294 status_t res = getTorchStatusLocked(cameraId, &status);
295 if (res) {
296 ALOGE("%s: cannot get torch status of camera %s", cameraId.string());
297 return;
298 }
299 if (status == newStatus) {
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800300 ALOGE("%s: Torch state transition to the same status 0x%x not allowed",
301 __FUNCTION__, (uint32_t)newStatus);
302 return;
303 }
304
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800305 res = setTorchStatusLocked(cameraId, newStatus);
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800306 if (res) {
307 ALOGE("%s: Failed to set the torch status", __FUNCTION__,
308 (uint32_t)newStatus);
309 return;
310 }
311
Ruben Brunkcc776712015-02-17 20:18:47 -0800312 {
313 Mutex::Autolock lock(mStatusListenerLock);
314 for (auto& i : mListenerList) {
315 i->onTorchStatusChanged(newStatus, String16{cameraId});
316 }
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800317 }
318}
319
320
Mathias Agopian65ab4712010-07-14 17:59:35 -0700321int32_t CameraService::getNumberOfCameras() {
322 return mNumberOfCameras;
323}
324
325status_t CameraService::getCameraInfo(int cameraId,
326 struct CameraInfo* cameraInfo) {
Iliyan Malchev8951a972011-04-14 16:55:59 -0700327 if (!mModule) {
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700328 return -ENODEV;
Iliyan Malchev8951a972011-04-14 16:55:59 -0700329 }
330
Mathias Agopian65ab4712010-07-14 17:59:35 -0700331 if (cameraId < 0 || cameraId >= mNumberOfCameras) {
332 return BAD_VALUE;
333 }
334
Iliyan Malchev8951a972011-04-14 16:55:59 -0700335 struct camera_info info;
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -0700336 status_t rc = filterGetInfoErrorCode(
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800337 mModule->getCameraInfo(cameraId, &info));
Iliyan Malchev8951a972011-04-14 16:55:59 -0700338 cameraInfo->facing = info.facing;
339 cameraInfo->orientation = info.orientation;
340 return rc;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700341}
342
Ruben Brunkcc776712015-02-17 20:18:47 -0800343int CameraService::cameraIdToInt(const String8& cameraId) {
344 errno = 0;
345 size_t pos = 0;
346 int ret = stoi(std::string{cameraId.string()}, &pos);
347 if (errno != 0 || pos != cameraId.size()) {
348 return -1;
349 }
350 return ret;
351}
Ruben Brunkb2119af2014-05-09 19:57:56 -0700352
353status_t CameraService::generateShimMetadata(int cameraId, /*out*/CameraMetadata* cameraInfo) {
354 status_t ret = OK;
355 struct CameraInfo info;
356 if ((ret = getCameraInfo(cameraId, &info)) != OK) {
357 return ret;
358 }
359
360 CameraMetadata shimInfo;
361 int32_t orientation = static_cast<int32_t>(info.orientation);
362 if ((ret = shimInfo.update(ANDROID_SENSOR_ORIENTATION, &orientation, 1)) != OK) {
363 return ret;
364 }
365
366 uint8_t facing = (info.facing == CAMERA_FACING_FRONT) ?
367 ANDROID_LENS_FACING_FRONT : ANDROID_LENS_FACING_BACK;
368 if ((ret = shimInfo.update(ANDROID_LENS_FACING, &facing, 1)) != OK) {
369 return ret;
370 }
371
Igor Murashkin65d14b92014-06-17 12:03:20 -0700372 CameraParameters shimParams;
373 if ((ret = getLegacyParametersLazy(cameraId, /*out*/&shimParams)) != OK) {
374 // Error logged by callee
375 return ret;
Ruben Brunkb2119af2014-05-09 19:57:56 -0700376 }
377
378 Vector<Size> sizes;
Ruben Brunk152dbcf2014-06-12 19:11:45 -0700379 Vector<Size> jpegSizes;
Ruben Brunkb2119af2014-05-09 19:57:56 -0700380 Vector<int32_t> formats;
381 const char* supportedPreviewFormats;
Igor Murashkin65d14b92014-06-17 12:03:20 -0700382 {
383 shimParams.getSupportedPreviewSizes(/*out*/sizes);
384 shimParams.getSupportedPreviewFormats(/*out*/formats);
385 shimParams.getSupportedPictureSizes(/*out*/jpegSizes);
Ruben Brunkb2119af2014-05-09 19:57:56 -0700386 }
387
388 // Always include IMPLEMENTATION_DEFINED
389 formats.add(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED);
390
391 const size_t INTS_PER_CONFIG = 4;
392
393 // Build available stream configurations metadata
Ruben Brunk152dbcf2014-06-12 19:11:45 -0700394 size_t streamConfigSize = (sizes.size() * formats.size() + jpegSizes.size()) * INTS_PER_CONFIG;
395
396 Vector<int32_t> streamConfigs;
397 streamConfigs.setCapacity(streamConfigSize);
398
Ruben Brunkb2119af2014-05-09 19:57:56 -0700399 for (size_t i = 0; i < formats.size(); ++i) {
400 for (size_t j = 0; j < sizes.size(); ++j) {
Ruben Brunk152dbcf2014-06-12 19:11:45 -0700401 streamConfigs.add(formats[i]);
402 streamConfigs.add(sizes[j].width);
403 streamConfigs.add(sizes[j].height);
404 streamConfigs.add(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
Ruben Brunkb2119af2014-05-09 19:57:56 -0700405 }
406 }
407
Ruben Brunk152dbcf2014-06-12 19:11:45 -0700408 for (size_t i = 0; i < jpegSizes.size(); ++i) {
409 streamConfigs.add(HAL_PIXEL_FORMAT_BLOB);
410 streamConfigs.add(jpegSizes[i].width);
411 streamConfigs.add(jpegSizes[i].height);
412 streamConfigs.add(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
413 }
414
Ruben Brunkb2119af2014-05-09 19:57:56 -0700415 if ((ret = shimInfo.update(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
Ruben Brunk152dbcf2014-06-12 19:11:45 -0700416 streamConfigs.array(), streamConfigSize)) != OK) {
Ruben Brunkb2119af2014-05-09 19:57:56 -0700417 return ret;
418 }
419
420 int64_t fakeMinFrames[0];
421 // TODO: Fixme, don't fake min frame durations.
422 if ((ret = shimInfo.update(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
423 fakeMinFrames, 0)) != OK) {
424 return ret;
425 }
426
427 int64_t fakeStalls[0];
428 // TODO: Fixme, don't fake stall durations.
429 if ((ret = shimInfo.update(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
430 fakeStalls, 0)) != OK) {
431 return ret;
432 }
433
434 *cameraInfo = shimInfo;
435 return OK;
436}
437
Zhijun He2b59be82013-09-25 10:14:30 -0700438status_t CameraService::getCameraCharacteristics(int cameraId,
439 CameraMetadata* cameraInfo) {
440 if (!cameraInfo) {
441 ALOGE("%s: cameraInfo is NULL", __FUNCTION__);
442 return BAD_VALUE;
443 }
444
445 if (!mModule) {
446 ALOGE("%s: camera hardware module doesn't exist", __FUNCTION__);
447 return -ENODEV;
448 }
449
Zhijun He2b59be82013-09-25 10:14:30 -0700450 if (cameraId < 0 || cameraId >= mNumberOfCameras) {
451 ALOGE("%s: Invalid camera id: %d", __FUNCTION__, cameraId);
452 return BAD_VALUE;
453 }
454
455 int facing;
Ruben Brunkb2119af2014-05-09 19:57:56 -0700456 status_t ret = OK;
Chien-Yu Chen676b21b2015-02-24 10:28:19 -0800457 if (mModule->getModuleApiVersion() < CAMERA_MODULE_API_VERSION_2_0 ||
Ruben Brunkb2119af2014-05-09 19:57:56 -0700458 getDeviceVersion(cameraId, &facing) <= CAMERA_DEVICE_API_VERSION_2_1 ) {
459 /**
460 * Backwards compatibility mode for old HALs:
461 * - Convert CameraInfo into static CameraMetadata properties.
462 * - Retrieve cached CameraParameters for this camera. If none exist,
463 * attempt to open CameraClient and retrieve the CameraParameters.
464 * - Convert cached CameraParameters into static CameraMetadata
465 * properties.
466 */
467 ALOGI("%s: Switching to HAL1 shim implementation...", __FUNCTION__);
Zhijun He2b59be82013-09-25 10:14:30 -0700468
Ruben Brunkb2119af2014-05-09 19:57:56 -0700469 if ((ret = generateShimMetadata(cameraId, cameraInfo)) != OK) {
470 return ret;
471 }
Zhijun Hef05e50e2013-10-01 11:05:33 -0700472
Ruben Brunkb2119af2014-05-09 19:57:56 -0700473 } else {
474 /**
475 * Normal HAL 2.1+ codepath.
476 */
477 struct camera_info info;
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800478 ret = filterGetInfoErrorCode(mModule->getCameraInfo(cameraId, &info));
Ruben Brunkb2119af2014-05-09 19:57:56 -0700479 *cameraInfo = info.static_camera_characteristics;
480 }
Zhijun He2b59be82013-09-25 10:14:30 -0700481
482 return ret;
483}
484
Ruben Brunkcc776712015-02-17 20:18:47 -0800485int CameraService::getCallingPid() {
486 return IPCThreadState::self()->getCallingPid();
487}
488
489int CameraService::getCallingUid() {
490 return IPCThreadState::self()->getCallingUid();
491}
492
493String8 CameraService::getFormattedCurrentTime() {
494 time_t now = time(nullptr);
495 char formattedTime[64];
496 strftime(formattedTime, sizeof(formattedTime), "%m-%d %H:%M:%S", localtime(&now));
497 return String8(formattedTime);
498}
499
500int CameraService::getCameraPriorityFromProcState(int procState) {
501 // Find the priority for the camera usage based on the process state. Higher priority clients
502 // win for evictions.
503 // Note: Unlike the ordering for ActivityManager, persistent system processes will always lose
504 // the camera to the top/foreground applications.
505 switch(procState) {
506 case PROCESS_STATE_TOP: // User visible
507 return 100;
508 case PROCESS_STATE_IMPORTANT_FOREGROUND: // Foreground
509 return 90;
510 case PROCESS_STATE_PERSISTENT: // Persistent system services
511 case PROCESS_STATE_PERSISTENT_UI:
512 return 80;
513 case PROCESS_STATE_IMPORTANT_BACKGROUND: // "Important" background processes
514 return 70;
515 case PROCESS_STATE_BACKUP: // Everything else
516 case PROCESS_STATE_HEAVY_WEIGHT:
517 case PROCESS_STATE_SERVICE:
518 case PROCESS_STATE_RECEIVER:
519 case PROCESS_STATE_HOME:
520 case PROCESS_STATE_LAST_ACTIVITY:
521 case PROCESS_STATE_CACHED_ACTIVITY:
522 case PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
523 case PROCESS_STATE_CACHED_EMPTY:
524 return 1;
525 case PROCESS_STATE_NONEXISTENT:
526 return -1;
527 default:
528 ALOGE("%s: Received unknown process state from ActivityManagerService!", __FUNCTION__);
529 return -1;
530 }
531}
532
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800533status_t CameraService::getCameraVendorTagDescriptor(/*out*/sp<VendorTagDescriptor>& desc) {
534 if (!mModule) {
535 ALOGE("%s: camera hardware module doesn't exist", __FUNCTION__);
536 return -ENODEV;
537 }
538
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800539 desc = VendorTagDescriptor::getGlobalVendorTagDescriptor();
540 return OK;
541}
542
Igor Murashkin634a5152013-02-20 17:15:11 -0800543int CameraService::getDeviceVersion(int cameraId, int* facing) {
544 struct camera_info info;
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800545 if (mModule->getCameraInfo(cameraId, &info) != OK) {
Igor Murashkin634a5152013-02-20 17:15:11 -0800546 return -1;
547 }
548
549 int deviceVersion;
Chien-Yu Chen676b21b2015-02-24 10:28:19 -0800550 if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_0) {
Igor Murashkin634a5152013-02-20 17:15:11 -0800551 deviceVersion = info.device_version;
552 } else {
553 deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
554 }
555
556 if (facing) {
557 *facing = info.facing;
558 }
559
560 return deviceVersion;
561}
562
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -0700563status_t CameraService::filterGetInfoErrorCode(status_t err) {
564 switch(err) {
565 case NO_ERROR:
566 case -EINVAL:
567 return err;
568 default:
569 break;
570 }
571 return -ENODEV;
Igor Murashkinbfc99152013-02-27 12:55:20 -0800572}
573
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800574bool CameraService::setUpVendorTags() {
575 vendor_tag_ops_t vOps = vendor_tag_ops_t();
576
577 // Check if vendor operations have been implemented
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800578 if (!mModule->isVendorTagDefined()) {
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800579 ALOGI("%s: No vendor tags defined for this device.", __FUNCTION__);
580 return false;
581 }
582
583 ATRACE_BEGIN("camera3->get_metadata_vendor_tag_ops");
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800584 mModule->getVendorTagOps(&vOps);
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800585 ATRACE_END();
586
587 // Ensure all vendor operations are present
588 if (vOps.get_tag_count == NULL || vOps.get_all_tags == NULL ||
589 vOps.get_section_name == NULL || vOps.get_tag_name == NULL ||
590 vOps.get_tag_type == NULL) {
591 ALOGE("%s: Vendor tag operations not fully defined. Ignoring definitions."
592 , __FUNCTION__);
593 return false;
594 }
595
596 // Read all vendor tag definitions into a descriptor
597 sp<VendorTagDescriptor> desc;
598 status_t res;
599 if ((res = VendorTagDescriptor::createDescriptorFromOps(&vOps, /*out*/desc))
600 != OK) {
601 ALOGE("%s: Could not generate descriptor from vendor tag operations,"
602 "received error %s (%d). Camera clients will not be able to use"
603 "vendor tags", __FUNCTION__, strerror(res), res);
604 return false;
605 }
606
607 // Set the global descriptor to use with camera metadata
608 VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
609 return true;
610}
611
Ruben Brunkcc776712015-02-17 20:18:47 -0800612status_t CameraService::makeClient(const sp<CameraService>& cameraService,
613 const sp<IInterface>& cameraCb, const String16& packageName, const String8& cameraId,
614 int facing, int clientPid, uid_t clientUid, int servicePid, bool legacyMode,
615 int halVersion, int deviceVersion, apiLevel effectiveApiLevel,
616 /*out*/sp<BasicClient>* client) {
617
618 // TODO: Update CameraClients + HAL interface to use strings for Camera IDs
619 int id = cameraIdToInt(cameraId);
620 if (id == -1) {
621 ALOGE("%s: Invalid camera ID %s, cannot convert to integer.", __FUNCTION__,
622 cameraId.string());
623 return BAD_VALUE;
Ruben Brunkb2119af2014-05-09 19:57:56 -0700624 }
625
Ruben Brunkcc776712015-02-17 20:18:47 -0800626 if (halVersion < 0 || halVersion == deviceVersion) {
627 // Default path: HAL version is unspecified by caller, create CameraClient
628 // based on device version reported by the HAL.
629 switch(deviceVersion) {
630 case CAMERA_DEVICE_API_VERSION_1_0:
631 if (effectiveApiLevel == API_1) { // Camera1 API route
632 sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
633 *client = new CameraClient(cameraService, tmp, packageName, id, facing,
634 clientPid, clientUid, getpid(), legacyMode);
635 } else { // Camera2 API route
636 ALOGW("Camera using old HAL version: %d", deviceVersion);
637 return -EOPNOTSUPP;
638 }
639 break;
640 case CAMERA_DEVICE_API_VERSION_2_0:
641 case CAMERA_DEVICE_API_VERSION_2_1:
642 case CAMERA_DEVICE_API_VERSION_3_0:
643 case CAMERA_DEVICE_API_VERSION_3_1:
644 case CAMERA_DEVICE_API_VERSION_3_2:
645 case CAMERA_DEVICE_API_VERSION_3_3:
646 if (effectiveApiLevel == API_1) { // Camera1 API route
647 sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
648 *client = new Camera2Client(cameraService, tmp, packageName, id, facing,
649 clientPid, clientUid, servicePid, legacyMode);
650 } else { // Camera2 API route
651 sp<ICameraDeviceCallbacks> tmp =
652 static_cast<ICameraDeviceCallbacks*>(cameraCb.get());
653 *client = new CameraDeviceClient(cameraService, tmp, packageName, id,
654 facing, clientPid, clientUid, servicePid);
655 }
656 break;
657 default:
658 // Should not be reachable
659 ALOGE("Unknown camera device HAL version: %d", deviceVersion);
660 return INVALID_OPERATION;
661 }
662 } else {
663 // A particular HAL version is requested by caller. Create CameraClient
664 // based on the requested HAL version.
665 if (deviceVersion > CAMERA_DEVICE_API_VERSION_1_0 &&
666 halVersion == CAMERA_DEVICE_API_VERSION_1_0) {
667 // Only support higher HAL version device opened as HAL1.0 device.
668 sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
669 *client = new CameraClient(cameraService, tmp, packageName, id, facing,
670 clientPid, clientUid, servicePid, legacyMode);
671 } else {
672 // Other combinations (e.g. HAL3.x open as HAL2.x) are not supported yet.
673 ALOGE("Invalid camera HAL version %x: HAL %x device can only be"
674 " opened as HAL %x device", halVersion, deviceVersion,
675 CAMERA_DEVICE_API_VERSION_1_0);
676 return INVALID_OPERATION;
677 }
678 }
679 return NO_ERROR;
680}
681
682status_t CameraService::initializeShimMetadata(int cameraId) {
683 int uid = getCallingUid();
Ruben Brunkb2119af2014-05-09 19:57:56 -0700684
685 String16 internalPackageName("media");
Ruben Brunkcc776712015-02-17 20:18:47 -0800686 String8 id = String8::format("%d", cameraId);
687 status_t ret = NO_ERROR;
688 sp<Client> tmp = nullptr;
689 if ((ret = connectHelper<ICameraClient,Client>(sp<ICameraClient>{nullptr}, id,
690 static_cast<int>(CAMERA_HAL_API_VERSION_UNSPECIFIED), internalPackageName, uid, API_1,
691 false, true, tmp)) != NO_ERROR) {
692 ALOGE("%s: Error %d (%s) initializing shim metadata.", __FUNCTION__, ret, strerror(ret));
693 return ret;
Ruben Brunkb2119af2014-05-09 19:57:56 -0700694 }
Ruben Brunkcc776712015-02-17 20:18:47 -0800695 return NO_ERROR;
Ruben Brunkb2119af2014-05-09 19:57:56 -0700696}
697
Igor Murashkin65d14b92014-06-17 12:03:20 -0700698status_t CameraService::getLegacyParametersLazy(int cameraId,
699 /*out*/
700 CameraParameters* parameters) {
701
702 ALOGV("%s: for cameraId: %d", __FUNCTION__, cameraId);
703
704 status_t ret = 0;
705
706 if (parameters == NULL) {
707 ALOGE("%s: parameters must not be null", __FUNCTION__);
708 return BAD_VALUE;
709 }
710
Ruben Brunkcc776712015-02-17 20:18:47 -0800711 String8 id = String8::format("%d", cameraId);
712
713 // Check if we already have parameters
714 {
715 // Scope for service lock
Igor Murashkin65d14b92014-06-17 12:03:20 -0700716 Mutex::Autolock lock(mServiceLock);
Ruben Brunkcc776712015-02-17 20:18:47 -0800717 auto cameraState = getCameraState(id);
718 if (cameraState == nullptr) {
719 ALOGE("%s: Invalid camera ID: %s", __FUNCTION__, id.string());
720 return BAD_VALUE;
721 }
722 CameraParameters p = cameraState->getShimParams();
723 if (!p.isEmpty()) {
724 *parameters = p;
725 return NO_ERROR;
Igor Murashkin65d14b92014-06-17 12:03:20 -0700726 }
727 }
728
Ruben Brunkcc776712015-02-17 20:18:47 -0800729 int64_t token = IPCThreadState::self()->clearCallingIdentity();
730 ret = initializeShimMetadata(cameraId);
731 IPCThreadState::self()->restoreCallingIdentity(token);
732 if (ret != NO_ERROR) {
733 // Error already logged by callee
734 return ret;
735 }
736
737 // Check for parameters again
738 {
739 // Scope for service lock
740 Mutex::Autolock lock(mServiceLock);
741 auto cameraState = getCameraState(id);
742 if (cameraState == nullptr) {
743 ALOGE("%s: Invalid camera ID: %s", __FUNCTION__, id.string());
744 return BAD_VALUE;
Igor Murashkin65d14b92014-06-17 12:03:20 -0700745 }
Ruben Brunkcc776712015-02-17 20:18:47 -0800746 CameraParameters p = cameraState->getShimParams();
747 if (!p.isEmpty()) {
748 *parameters = p;
749 return NO_ERROR;
Igor Murashkin65d14b92014-06-17 12:03:20 -0700750 }
751 }
752
Ruben Brunkcc776712015-02-17 20:18:47 -0800753 ALOGE("%s: Parameters were not initialized, or were empty. Device may not be present.",
754 __FUNCTION__);
755 return INVALID_OPERATION;
Igor Murashkin65d14b92014-06-17 12:03:20 -0700756}
757
Ruben Brunk36597b22015-03-20 22:15:57 -0700758status_t CameraService::validateConnectLocked(const String8& cameraId, /*inout*/int& clientUid)
759 const {
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800760
Mathias Agopian65ab4712010-07-14 17:59:35 -0700761 int callingPid = getCallingPid();
Tyler Luu5861a9a2011-10-06 00:00:03 -0500762
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800763 if (clientUid == USE_CALLING_UID) {
764 clientUid = getCallingUid();
765 } else {
766 // We only trust our own process to forward client UIDs
767 if (callingPid != getpid()) {
Ruben Brunkcc776712015-02-17 20:18:47 -0800768 ALOGE("CameraService::connect X (PID %d) rejected (don't trust clientUid)",
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800769 callingPid);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700770 return PERMISSION_DENIED;
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800771 }
772 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700773
Iliyan Malchev8951a972011-04-14 16:55:59 -0700774 if (!mModule) {
Ruben Brunkcc776712015-02-17 20:18:47 -0800775 ALOGE("CameraService::connect X (PID %d) rejected (camera HAL module not loaded)",
776 callingPid);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700777 return -ENODEV;
Iliyan Malchev8951a972011-04-14 16:55:59 -0700778 }
779
Ruben Brunkcc776712015-02-17 20:18:47 -0800780 if (getCameraState(cameraId) == nullptr) {
781 ALOGE("CameraService::connect X (PID %d) rejected (invalid camera ID %s)", callingPid,
782 cameraId.string());
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700783 return -ENODEV;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700784 }
785
Ruben Brunkcc776712015-02-17 20:18:47 -0800786 // Check device policy for this camera
Wu-cheng Lia3355432011-05-20 14:54:25 +0800787 char value[PROPERTY_VALUE_MAX];
Amith Yamasani228711d2015-02-13 13:25:39 -0800788 char key[PROPERTY_KEY_MAX];
789 int clientUserId = multiuser_get_user_id(clientUid);
790 snprintf(key, PROPERTY_KEY_MAX, "sys.secpolicy.camera.off_%d", clientUserId);
791 property_get(key, value, "0");
Wu-cheng Lia3355432011-05-20 14:54:25 +0800792 if (strcmp(value, "1") == 0) {
793 // Camera is disabled by DevicePolicyManager.
Ruben Brunkcc776712015-02-17 20:18:47 -0800794 ALOGE("CameraService::connect X (PID %d) rejected (camera %s is disabled by device "
795 "policy)", callingPid, cameraId.string());
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700796 return -EACCES;
Wu-cheng Lia3355432011-05-20 14:54:25 +0800797 }
798
Ruben Brunk36597b22015-03-20 22:15:57 -0700799 // Only allow clients who are being used by the current foreground device user.
800 if (mLastUserId != clientUserId && mLastUserId != DEFAULT_LAST_USER_ID) {
801 ALOGE("CameraService::connect X (PID %d) rejected (cannot connect from non-foreground "
802 "device user)", callingPid);
803 return PERMISSION_DENIED;
804 }
805
Ruben Brunkcc776712015-02-17 20:18:47 -0800806 return checkIfDeviceIsUsable(cameraId);
807}
808
809status_t CameraService::checkIfDeviceIsUsable(const String8& cameraId) const {
810 auto cameraState = getCameraState(cameraId);
811 int callingPid = getCallingPid();
812 if (cameraState == nullptr) {
813 ALOGE("CameraService::connect X (PID %d) rejected (invalid camera ID %s)", callingPid,
814 cameraId.string());
815 return -ENODEV;
816 }
817
818 ICameraServiceListener::Status currentStatus = cameraState->getStatus();
Igor Murashkincba2c162013-03-20 15:56:31 -0700819 if (currentStatus == ICameraServiceListener::STATUS_NOT_PRESENT) {
Ruben Brunkcc776712015-02-17 20:18:47 -0800820 ALOGE("CameraService::connect X (PID %d) rejected (camera %s is not connected)",
821 callingPid, cameraId.string());
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700822 return -ENODEV;
Igor Murashkincba2c162013-03-20 15:56:31 -0700823 } else if (currentStatus == ICameraServiceListener::STATUS_ENUMERATING) {
Ruben Brunkcc776712015-02-17 20:18:47 -0800824 ALOGE("CameraService::connect X (PID %d) rejected, (camera %s is initializing)",
825 callingPid, cameraId.string());
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700826 return -EBUSY;
Igor Murashkincba2c162013-03-20 15:56:31 -0700827 }
Igor Murashkincba2c162013-03-20 15:56:31 -0700828
Ruben Brunkcc776712015-02-17 20:18:47 -0800829 return NO_ERROR;
Igor Murashkine6800ce2013-03-04 17:25:57 -0800830}
831
Ruben Brunkcc776712015-02-17 20:18:47 -0800832void CameraService::finishConnectLocked(const sp<BasicClient>& client,
833 const CameraService::DescriptorPtr& desc) {
Igor Murashkine6800ce2013-03-04 17:25:57 -0800834
Ruben Brunkcc776712015-02-17 20:18:47 -0800835 // Make a descriptor for the incoming client
836 auto clientDescriptor = CameraService::CameraClientManager::makeClientDescriptor(client, desc);
837 auto evicted = mActiveClientManager.addAndEvict(clientDescriptor);
838
839 logConnected(desc->getKey(), static_cast<int>(desc->getOwnerId()),
840 String8(client->getPackageName()));
841
842 if (evicted.size() > 0) {
843 // This should never happen - clients should already have been removed in disconnect
844 for (auto& i : evicted) {
845 ALOGE("%s: Invalid state: Client for camera %s was not removed in disconnect",
846 __FUNCTION__, i->getKey().string());
847 }
848
849 LOG_ALWAYS_FATAL("%s: Invalid state for CameraService, clients not evicted properly",
850 __FUNCTION__);
851 }
852}
853
854status_t CameraService::handleEvictionsLocked(const String8& cameraId, int clientPid,
855 apiLevel effectiveApiLevel, const sp<IBinder>& remoteCallback, const String8& packageName,
856 /*out*/
857 sp<BasicClient>* client,
858 std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>* partial) {
859
860 status_t ret = NO_ERROR;
861 std::vector<sp<BasicClient>> evictedClients;
862 DescriptorPtr clientDescriptor;
863 {
864 if (effectiveApiLevel == API_1) {
865 // If we are using API1, any existing client for this camera ID with the same remote
866 // should be returned rather than evicted to allow MediaRecorder to work properly.
867
868 auto current = mActiveClientManager.get(cameraId);
869 if (current != nullptr) {
870 auto clientSp = current->getValue();
871 if (clientSp.get() != nullptr) { // should never be needed
872 if (clientSp->getRemote() == remoteCallback) {
873 ALOGI("CameraService::connect X (PID %d) (second call from same"
874 "app binder, returning the same client)", clientPid);
875 *client = clientSp;
876 return NO_ERROR;
877 }
878 }
Wu-cheng Li2fd24402012-02-23 19:01:00 -0800879 }
Wu-cheng Li2fd24402012-02-23 19:01:00 -0800880 }
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800881
Ruben Brunkcc776712015-02-17 20:18:47 -0800882 // Return error if the device was unplugged or removed by the HAL for some reason
883 if ((ret = checkIfDeviceIsUsable(cameraId)) != NO_ERROR) {
884 return ret;
885 }
Igor Murashkin634a5152013-02-20 17:15:11 -0800886
Ruben Brunkcc776712015-02-17 20:18:47 -0800887 // Get current active client PIDs
888 std::vector<int> ownerPids(mActiveClientManager.getAllOwners());
889 ownerPids.push_back(clientPid);
Igor Murashkine6800ce2013-03-04 17:25:57 -0800890
Chih-Hung Hsieh54b42462015-03-19 12:04:54 -0700891 // Use the value +PROCESS_STATE_NONEXISTENT, to avoid taking
892 // address of PROCESS_STATE_NONEXISTENT as a reference argument
893 // for the vector constructor. PROCESS_STATE_NONEXISTENT does
894 // not have an out-of-class definition.
895 std::vector<int> priorities(ownerPids.size(), +PROCESS_STATE_NONEXISTENT);
Igor Murashkine6800ce2013-03-04 17:25:57 -0800896
Ruben Brunkcc776712015-02-17 20:18:47 -0800897 // Get priorites of all active PIDs
898 ProcessInfoService::getProcessStatesFromPids(ownerPids.size(), &ownerPids[0],
899 /*out*/&priorities[0]);
Ruben Brunkb2119af2014-05-09 19:57:56 -0700900
Ruben Brunkcc776712015-02-17 20:18:47 -0800901 // Update all active clients' priorities
902 std::map<int,int> pidToPriorityMap;
903 for (size_t i = 0; i < ownerPids.size() - 1; i++) {
904 pidToPriorityMap.emplace(ownerPids[i], getCameraPriorityFromProcState(priorities[i]));
905 }
906 mActiveClientManager.updatePriorities(pidToPriorityMap);
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800907
Ruben Brunkcc776712015-02-17 20:18:47 -0800908 // Get state for the given cameraId
909 auto state = getCameraState(cameraId);
910 if (state == nullptr) {
911 ALOGE("CameraService::connect X (PID %d) rejected (no camera device with ID %s)",
912 clientPid, cameraId.string());
Zhijun Heb10cdad2014-06-16 16:38:35 -0700913 return BAD_VALUE;
Zhijun Heb10cdad2014-06-16 16:38:35 -0700914 }
Ruben Brunkcc776712015-02-17 20:18:47 -0800915
916 // Make descriptor for incoming client
917 clientDescriptor = CameraClientManager::makeClientDescriptor(cameraId,
918 sp<BasicClient>{nullptr}, static_cast<int32_t>(state->getCost()),
919 state->getConflicting(),
920 getCameraPriorityFromProcState(priorities[priorities.size() - 1]), clientPid);
921
922 // Find clients that would be evicted
923 auto evicted = mActiveClientManager.wouldEvict(clientDescriptor);
924
925 // If the incoming client was 'evicted,' higher priority clients have the camera in the
926 // background, so we cannot do evictions
927 if (std::find(evicted.begin(), evicted.end(), clientDescriptor) != evicted.end()) {
928 ALOGE("CameraService::connect X (PID %d) rejected (existing client(s) with higher"
929 " priority).", clientPid);
930
931 sp<BasicClient> clientSp = clientDescriptor->getValue();
932 String8 curTime = getFormattedCurrentTime();
933 auto incompatibleClients =
934 mActiveClientManager.getIncompatibleClients(clientDescriptor);
935
936 String8 msg = String8::format("%s : DENIED connect device %s client for package %s "
937 "(PID %d, priority %d)", curTime.string(),
938 cameraId.string(), packageName.string(), clientPid,
939 getCameraPriorityFromProcState(priorities[priorities.size() - 1]));
940
941 for (auto& i : incompatibleClients) {
942 msg.appendFormat("\n - Blocked by existing device %s client for package %s"
943 "(PID %" PRId32 ", priority %" PRId32 ")", i->getKey().string(),
944 String8{i->getValue()->getPackageName()}.string(), i->getOwnerId(),
945 i->getPriority());
946 }
947
948 // Log the client's attempt
949 mEventLog.add(msg);
950
951 return -EBUSY;
952 }
953
954 for (auto& i : evicted) {
955 sp<BasicClient> clientSp = i->getValue();
956 if (clientSp.get() == nullptr) {
957 ALOGE("%s: Invalid state: Null client in active client list.", __FUNCTION__);
958
959 // TODO: Remove this
960 LOG_ALWAYS_FATAL("%s: Invalid state for CameraService, null client in active list",
961 __FUNCTION__);
962 mActiveClientManager.remove(i);
963 continue;
964 }
965
966 ALOGE("CameraService::connect evicting conflicting client for camera ID %s",
967 i->getKey().string());
968 evictedClients.push_back(clientSp);
969
970 String8 curTime = getFormattedCurrentTime();
971
972 // Log the clients evicted
973 mEventLog.add(String8::format("%s : EVICT device %s client for package %s (PID %"
974 PRId32 ", priority %" PRId32 ")\n - Evicted by device %s client for "
975 "package %s (PID %d, priority %" PRId32 ")", curTime.string(),
976 i->getKey().string(), String8{clientSp->getPackageName()}.string(),
977 i->getOwnerId(), i->getPriority(), cameraId.string(),
978 packageName.string(), clientPid,
979 getCameraPriorityFromProcState(priorities[priorities.size() - 1])));
980
981 // Notify the client of disconnection
982 clientSp->notifyError(ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED,
983 CaptureResultExtras());
Zhijun Heb10cdad2014-06-16 16:38:35 -0700984 }
Ruben Brunkb2119af2014-05-09 19:57:56 -0700985 }
986
Ruben Brunkcc776712015-02-17 20:18:47 -0800987 // Do not hold mServiceLock while disconnecting clients, but retain the condition blocking
988 // other clients from connecting in mServiceLockWrapper if held
989 mServiceLock.unlock();
990
991 // Clear caller identity temporarily so client disconnect PID checks work correctly
992 int64_t token = IPCThreadState::self()->clearCallingIdentity();
993
994 // Destroy evicted clients
995 for (auto& i : evictedClients) {
996 // Disconnect is blocking, and should only have returned when HAL has cleaned up
997 i->disconnect(); // Clients will remove themselves from the active client list here
998 }
999 evictedClients.clear();
1000
1001 IPCThreadState::self()->restoreCallingIdentity(token);
1002
1003 // Once clients have been disconnected, relock
1004 mServiceLock.lock();
1005
1006 // Check again if the device was unplugged or something while we weren't holding mServiceLock
1007 if ((ret = checkIfDeviceIsUsable(cameraId)) != NO_ERROR) {
1008 return ret;
Ruben Brunkb2119af2014-05-09 19:57:56 -07001009 }
1010
Ruben Brunkcc776712015-02-17 20:18:47 -08001011 *partial = clientDescriptor;
1012 return NO_ERROR;
Ruben Brunkb2119af2014-05-09 19:57:56 -07001013}
1014
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001015status_t CameraService::connect(
Igor Murashkine6800ce2013-03-04 17:25:57 -08001016 const sp<ICameraClient>& cameraClient,
1017 int cameraId,
1018 const String16& clientPackageName,
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001019 int clientUid,
1020 /*out*/
1021 sp<ICamera>& device) {
Igor Murashkine6800ce2013-03-04 17:25:57 -08001022
Ruben Brunkcc776712015-02-17 20:18:47 -08001023 status_t ret = NO_ERROR;
1024 String8 id = String8::format("%d", cameraId);
1025 sp<Client> client = nullptr;
1026 ret = connectHelper<ICameraClient,Client>(cameraClient, id, CAMERA_HAL_API_VERSION_UNSPECIFIED,
1027 clientPackageName, clientUid, API_1, false, false, /*out*/client);
Igor Murashkine6800ce2013-03-04 17:25:57 -08001028
Ruben Brunkcc776712015-02-17 20:18:47 -08001029 if(ret != NO_ERROR) {
1030 return ret;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001031 }
1032
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001033 device = client;
Ruben Brunkcc776712015-02-17 20:18:47 -08001034 return NO_ERROR;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001035}
1036
Zhijun Heb10cdad2014-06-16 16:38:35 -07001037status_t CameraService::connectLegacy(
1038 const sp<ICameraClient>& cameraClient,
1039 int cameraId, int halVersion,
1040 const String16& clientPackageName,
1041 int clientUid,
1042 /*out*/
1043 sp<ICamera>& device) {
1044
Chien-Yu Chen676b21b2015-02-24 10:28:19 -08001045 int apiVersion = mModule->getModuleApiVersion();
Igor Murashkin3d07d1a2014-06-20 11:27:03 -07001046 if (halVersion != CAMERA_HAL_API_VERSION_UNSPECIFIED &&
Yin-Chia Yehe074a932015-01-30 10:29:02 -08001047 apiVersion < CAMERA_MODULE_API_VERSION_2_3) {
Igor Murashkin3d07d1a2014-06-20 11:27:03 -07001048 /*
1049 * Either the HAL version is unspecified in which case this just creates
1050 * a camera client selected by the latest device version, or
1051 * it's a particular version in which case the HAL must supported
1052 * the open_legacy call
1053 */
Zhijun Heb10cdad2014-06-16 16:38:35 -07001054 ALOGE("%s: camera HAL module version %x doesn't support connecting to legacy HAL devices!",
Yin-Chia Yehe074a932015-01-30 10:29:02 -08001055 __FUNCTION__, apiVersion);
Zhijun Heb10cdad2014-06-16 16:38:35 -07001056 return INVALID_OPERATION;
1057 }
1058
Ruben Brunkcc776712015-02-17 20:18:47 -08001059 status_t ret = NO_ERROR;
1060 String8 id = String8::format("%d", cameraId);
1061 sp<Client> client = nullptr;
1062 ret = connectHelper<ICameraClient,Client>(cameraClient, id, halVersion, clientPackageName,
1063 clientUid, API_1, true, false, /*out*/client);
Zhijun Heb10cdad2014-06-16 16:38:35 -07001064
Ruben Brunkcc776712015-02-17 20:18:47 -08001065 if(ret != NO_ERROR) {
1066 return ret;
Zhijun Heb10cdad2014-06-16 16:38:35 -07001067 }
1068
Zhijun Heb10cdad2014-06-16 16:38:35 -07001069 device = client;
Ruben Brunkcc776712015-02-17 20:18:47 -08001070 return NO_ERROR;
Zhijun Heb10cdad2014-06-16 16:38:35 -07001071}
1072
Ruben Brunkcc776712015-02-17 20:18:47 -08001073status_t CameraService::connectDevice(
1074 const sp<ICameraDeviceCallbacks>& cameraCb,
1075 int cameraId,
1076 const String16& clientPackageName,
1077 int clientUid,
1078 /*out*/
1079 sp<ICameraDeviceUser>& device) {
1080
1081 status_t ret = NO_ERROR;
1082 String8 id = String8::format("%d", cameraId);
1083 sp<CameraDeviceClient> client = nullptr;
1084 ret = connectHelper<ICameraDeviceCallbacks,CameraDeviceClient>(cameraCb, id,
1085 CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageName, clientUid, API_2, false, false,
1086 /*out*/client);
1087
1088 if(ret != NO_ERROR) {
1089 return ret;
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001090 }
1091
Ruben Brunkcc776712015-02-17 20:18:47 -08001092 device = client;
1093 return NO_ERROR;
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001094}
1095
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001096status_t CameraService::setTorchMode(const String16& cameraId, bool enabled,
1097 const sp<IBinder>& clientBinder) {
1098 if (enabled && clientBinder == NULL) {
1099 ALOGE("%s: torch client binder is NULL", __FUNCTION__);
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001100 return -EINVAL;
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001101 }
1102
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001103 String8 id = String8(cameraId.string());
1104
1105 // verify id is valid.
Ruben Brunkcc776712015-02-17 20:18:47 -08001106 auto state = getCameraState(id);
1107 if (state == nullptr) {
1108 ALOGE("%s: camera id is invalid %s", id.string());
1109 return -EINVAL;
1110 }
1111
1112 ICameraServiceListener::Status cameraStatus = state->getStatus();
1113 if (cameraStatus != ICameraServiceListener::STATUS_PRESENT &&
1114 cameraStatus != ICameraServiceListener::STATUS_NOT_AVAILABLE) {
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001115 ALOGE("%s: camera id is invalid %s", id.string());
1116 return -EINVAL;
1117 }
1118
1119 {
1120 Mutex::Autolock al(mTorchStatusMutex);
1121 ICameraServiceListener::TorchStatus status;
1122 status_t res = getTorchStatusLocked(id, &status);
1123 if (res) {
1124 ALOGE("%s: getting current torch status failed for camera %s",
1125 __FUNCTION__, id.string());
1126 return -EINVAL;
1127 }
1128
1129 if (status == ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE) {
Ruben Brunkcc776712015-02-17 20:18:47 -08001130 if (cameraStatus == ICameraServiceListener::STATUS_NOT_AVAILABLE) {
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001131 ALOGE("%s: torch mode of camera %s is not available because "
1132 "camera is in use", __FUNCTION__, id.string());
1133 return -EBUSY;
1134 } else {
1135 ALOGE("%s: torch mode of camera %s is not available due to "
1136 "insufficient resources", __FUNCTION__, id.string());
1137 return -EUSERS;
1138 }
1139 }
1140 }
1141
1142 status_t res = mFlashlight->setTorchMode(id, enabled);
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001143 if (res) {
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001144 ALOGE("%s: setting torch mode of camera %s to %d failed. %s (%d)",
1145 __FUNCTION__, id.string(), enabled, strerror(-res), res);
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001146 return res;
1147 }
1148
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001149 {
1150 // update the link to client's death
1151 Mutex::Autolock al(mTorchClientMapMutex);
1152 ssize_t index = mTorchClientMap.indexOfKey(id);
1153 if (enabled) {
1154 if (index == NAME_NOT_FOUND) {
1155 mTorchClientMap.add(id, clientBinder);
1156 } else {
1157 const sp<IBinder> oldBinder = mTorchClientMap.valueAt(index);
1158 oldBinder->unlinkToDeath(this);
1159
1160 mTorchClientMap.replaceValueAt(index, clientBinder);
1161 }
1162 clientBinder->linkToDeath(this);
1163 } else if (index != NAME_NOT_FOUND) {
1164 sp<IBinder> oldBinder = mTorchClientMap.valueAt(index);
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001165 oldBinder->unlinkToDeath(this);
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001166 }
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001167 }
1168
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001169 return OK;
1170}
1171
Ruben Brunk36597b22015-03-20 22:15:57 -07001172void CameraService::notifySystemEvent(int eventId, int arg0) {
1173 switch(eventId) {
1174 case ICameraService::USER_SWITCHED: {
1175 doUserSwitch(/*newUserId*/arg0);
1176 break;
1177 }
1178 case ICameraService::NO_EVENT:
1179 default: {
1180 ALOGW("%s: Received invalid system event from system_server: %d", __FUNCTION__,
1181 eventId);
1182 break;
1183 }
1184 }
1185}
1186
Igor Murashkinbfc99152013-02-27 12:55:20 -08001187status_t CameraService::addListener(
1188 const sp<ICameraServiceListener>& listener) {
1189 ALOGV("%s: Add listener %p", __FUNCTION__, listener.get());
Igor Murashkin634a5152013-02-20 17:15:11 -08001190
Igor Murashkinbd3e2e02014-03-17 13:01:41 -07001191 if (listener == 0) {
1192 ALOGE("%s: Listener must not be null", __FUNCTION__);
1193 return BAD_VALUE;
1194 }
1195
Igor Murashkinbfc99152013-02-27 12:55:20 -08001196 Mutex::Autolock lock(mServiceLock);
1197
Ruben Brunkcc776712015-02-17 20:18:47 -08001198 {
1199 Mutex::Autolock lock(mStatusListenerLock);
1200 for (auto& it : mListenerList) {
1201 if (IInterface::asBinder(it) == IInterface::asBinder(listener)) {
1202 ALOGW("%s: Tried to add listener %p which was already subscribed",
1203 __FUNCTION__, listener.get());
1204 return ALREADY_EXISTS;
1205 }
Igor Murashkinbfc99152013-02-27 12:55:20 -08001206 }
Ruben Brunkcc776712015-02-17 20:18:47 -08001207
1208 mListenerList.push_back(listener);
Igor Murashkinbfc99152013-02-27 12:55:20 -08001209 }
1210
Igor Murashkinbfc99152013-02-27 12:55:20 -08001211
Igor Murashkincba2c162013-03-20 15:56:31 -07001212 /* Immediately signal current status to this listener only */
1213 {
Ruben Brunkcc776712015-02-17 20:18:47 -08001214 Mutex::Autolock lock(mCameraStatesLock);
1215 for (auto& i : mCameraStates) {
1216 // TODO: Update binder to use String16 for camera IDs and remove;
1217 int id = cameraIdToInt(i.first);
1218 if (id == -1) continue;
1219
1220 listener->onStatusChanged(i.second->getStatus(), id);
Igor Murashkincba2c162013-03-20 15:56:31 -07001221 }
1222 }
1223
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001224 /* Immediately signal current torch status to this listener only */
1225 {
1226 Mutex::Autolock al(mTorchStatusMutex);
1227 for (size_t i = 0; i < mTorchStatusMap.size(); i++ ) {
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001228 String16 id = String16(mTorchStatusMap.keyAt(i).string());
1229 listener->onTorchStatusChanged(mTorchStatusMap.valueAt(i), id);
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001230 }
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001231 }
1232
Igor Murashkinbfc99152013-02-27 12:55:20 -08001233 return OK;
1234}
Ruben Brunkcc776712015-02-17 20:18:47 -08001235
1236status_t CameraService::removeListener(const sp<ICameraServiceListener>& listener) {
Igor Murashkinbfc99152013-02-27 12:55:20 -08001237 ALOGV("%s: Remove listener %p", __FUNCTION__, listener.get());
1238
Igor Murashkinbd3e2e02014-03-17 13:01:41 -07001239 if (listener == 0) {
1240 ALOGE("%s: Listener must not be null", __FUNCTION__);
1241 return BAD_VALUE;
1242 }
1243
Igor Murashkinbfc99152013-02-27 12:55:20 -08001244 Mutex::Autolock lock(mServiceLock);
1245
Ruben Brunkcc776712015-02-17 20:18:47 -08001246 {
1247 Mutex::Autolock lock(mStatusListenerLock);
1248 for (auto it = mListenerList.begin(); it != mListenerList.end(); it++) {
1249 if (IInterface::asBinder(*it) == IInterface::asBinder(listener)) {
1250 mListenerList.erase(it);
1251 return OK;
1252 }
Igor Murashkinbfc99152013-02-27 12:55:20 -08001253 }
1254 }
1255
1256 ALOGW("%s: Tried to remove a listener %p which was not subscribed",
1257 __FUNCTION__, listener.get());
1258
1259 return BAD_VALUE;
Igor Murashkin634a5152013-02-20 17:15:11 -08001260}
1261
Ruben Brunkcc776712015-02-17 20:18:47 -08001262status_t CameraService::getLegacyParameters(int cameraId, /*out*/String16* parameters) {
Igor Murashkin65d14b92014-06-17 12:03:20 -07001263 ALOGV("%s: for camera ID = %d", __FUNCTION__, cameraId);
1264
1265 if (parameters == NULL) {
1266 ALOGE("%s: parameters must not be null", __FUNCTION__);
1267 return BAD_VALUE;
1268 }
1269
1270 status_t ret = 0;
1271
1272 CameraParameters shimParams;
1273 if ((ret = getLegacyParametersLazy(cameraId, /*out*/&shimParams)) != OK) {
1274 // Error logged by caller
1275 return ret;
1276 }
1277
1278 String8 shimParamsString8 = shimParams.flatten();
1279 String16 shimParamsString16 = String16(shimParamsString8);
1280
1281 *parameters = shimParamsString16;
1282
1283 return OK;
1284}
1285
1286status_t CameraService::supportsCameraApi(int cameraId, int apiVersion) {
1287 ALOGV("%s: for camera ID = %d", __FUNCTION__, cameraId);
1288
1289 switch (apiVersion) {
1290 case API_VERSION_1:
1291 case API_VERSION_2:
1292 break;
1293 default:
1294 ALOGE("%s: Bad API version %d", __FUNCTION__, apiVersion);
1295 return BAD_VALUE;
1296 }
1297
1298 int facing = -1;
1299 int deviceVersion = getDeviceVersion(cameraId, &facing);
1300
1301 switch(deviceVersion) {
1302 case CAMERA_DEVICE_API_VERSION_1_0:
1303 case CAMERA_DEVICE_API_VERSION_2_0:
1304 case CAMERA_DEVICE_API_VERSION_2_1:
1305 case CAMERA_DEVICE_API_VERSION_3_0:
1306 case CAMERA_DEVICE_API_VERSION_3_1:
1307 if (apiVersion == API_VERSION_2) {
1308 ALOGV("%s: Camera id %d uses HAL prior to HAL3.2, doesn't support api2 without shim",
1309 __FUNCTION__, cameraId);
1310 return -EOPNOTSUPP;
1311 } else { // if (apiVersion == API_VERSION_1) {
1312 ALOGV("%s: Camera id %d uses older HAL before 3.2, but api1 is always supported",
1313 __FUNCTION__, cameraId);
1314 return OK;
1315 }
1316 case CAMERA_DEVICE_API_VERSION_3_2:
Ruben Brunkcc776712015-02-17 20:18:47 -08001317 case CAMERA_DEVICE_API_VERSION_3_3:
Igor Murashkin65d14b92014-06-17 12:03:20 -07001318 ALOGV("%s: Camera id %d uses HAL3.2 or newer, supports api1/api2 directly",
1319 __FUNCTION__, cameraId);
1320 return OK;
1321 case -1:
1322 ALOGE("%s: Invalid camera id %d", __FUNCTION__, cameraId);
1323 return BAD_VALUE;
1324 default:
1325 ALOGE("%s: Unknown camera device HAL version: %d", __FUNCTION__, deviceVersion);
1326 return INVALID_OPERATION;
1327 }
1328
1329 return OK;
1330}
1331
Ruben Brunkcc776712015-02-17 20:18:47 -08001332void CameraService::removeByClient(const BasicClient* client) {
Igor Murashkinecf17e82012-10-02 16:05:11 -07001333 Mutex::Autolock lock(mServiceLock);
Ruben Brunkcc776712015-02-17 20:18:47 -08001334 for (auto& i : mActiveClientManager.getAll()) {
1335 auto clientSp = i->getValue();
1336 if (clientSp.get() == client) {
1337 mActiveClientManager.remove(i);
Igor Murashkin634a5152013-02-20 17:15:11 -08001338 }
Igor Murashkinecf17e82012-10-02 16:05:11 -07001339 }
Igor Murashkin634a5152013-02-20 17:15:11 -08001340}
1341
Ruben Brunkcc776712015-02-17 20:18:47 -08001342bool CameraService::evictClientIdByRemote(const wp<IBinder>& remote) {
1343 const int callingPid = getCallingPid();
1344 const int servicePid = getpid();
1345 bool ret = false;
1346 {
1347 // Acquire mServiceLock and prevent other clients from connecting
1348 std::unique_ptr<AutoConditionLock> lock =
1349 AutoConditionLock::waitAndAcquire(mServiceLockWrapper);
Igor Murashkin634a5152013-02-20 17:15:11 -08001350
Igor Murashkin634a5152013-02-20 17:15:11 -08001351
Ruben Brunkcc776712015-02-17 20:18:47 -08001352 std::vector<sp<BasicClient>> evicted;
1353 for (auto& i : mActiveClientManager.getAll()) {
1354 auto clientSp = i->getValue();
1355 if (clientSp.get() == nullptr) {
1356 ALOGE("%s: Dead client still in mActiveClientManager.", __FUNCTION__);
1357 mActiveClientManager.remove(i);
1358 continue;
1359 }
1360 if (remote == clientSp->getRemote() && (callingPid == servicePid ||
1361 callingPid == clientSp->getClientPid())) {
1362 mActiveClientManager.remove(i);
1363 evicted.push_back(clientSp);
Igor Murashkin634a5152013-02-20 17:15:11 -08001364
Ruben Brunkcc776712015-02-17 20:18:47 -08001365 // Notify the client of disconnection
1366 clientSp->notifyError(ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED,
1367 CaptureResultExtras());
Igor Murashkin634a5152013-02-20 17:15:11 -08001368 }
1369 }
1370
Ruben Brunkcc776712015-02-17 20:18:47 -08001371 // Do not hold mServiceLock while disconnecting clients, but retain the condition blocking
1372 // other clients from connecting in mServiceLockWrapper if held
1373 mServiceLock.unlock();
1374
Ruben Brunk36597b22015-03-20 22:15:57 -07001375 // Do not clear caller identity, remote caller should be client proccess
1376
Ruben Brunkcc776712015-02-17 20:18:47 -08001377 for (auto& i : evicted) {
1378 if (i.get() != nullptr) {
1379 i->disconnect();
1380 ret = true;
1381 }
Igor Murashkin634a5152013-02-20 17:15:11 -08001382 }
1383
Ruben Brunkcc776712015-02-17 20:18:47 -08001384 // Reacquire mServiceLock
1385 mServiceLock.lock();
Igor Murashkin634a5152013-02-20 17:15:11 -08001386
Ruben Brunkcc776712015-02-17 20:18:47 -08001387 } // lock is destroyed, allow further connect calls
1388
1389 return ret;
Igor Murashkinecf17e82012-10-02 16:05:11 -07001390}
1391
Igor Murashkinecf17e82012-10-02 16:05:11 -07001392
Ruben Brunkcc776712015-02-17 20:18:47 -08001393std::shared_ptr<CameraService::CameraState> CameraService::getCameraState(
1394 const String8& cameraId) const {
1395 std::shared_ptr<CameraState> state;
1396 {
1397 Mutex::Autolock lock(mCameraStatesLock);
1398 auto iter = mCameraStates.find(cameraId);
1399 if (iter != mCameraStates.end()) {
1400 state = iter->second;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001401 }
1402 }
Ruben Brunkcc776712015-02-17 20:18:47 -08001403 return state;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001404}
1405
Ruben Brunkcc776712015-02-17 20:18:47 -08001406sp<CameraService::BasicClient> CameraService::removeClientLocked(const String8& cameraId) {
1407 // Remove from active clients list
1408 auto clientDescriptorPtr = mActiveClientManager.remove(cameraId);
1409 if (clientDescriptorPtr == nullptr) {
1410 ALOGW("%s: Could not evict client, no client for camera ID %s", __FUNCTION__,
1411 cameraId.string());
1412 return sp<BasicClient>{nullptr};
1413 }
1414
1415 return clientDescriptorPtr->getValue();
Keun young Parkd8973a72012-03-28 14:13:09 -07001416}
1417
Ruben Brunk36597b22015-03-20 22:15:57 -07001418void CameraService::doUserSwitch(int newUserId) {
1419 // Acquire mServiceLock and prevent other clients from connecting
1420 std::unique_ptr<AutoConditionLock> lock =
1421 AutoConditionLock::waitAndAcquire(mServiceLockWrapper);
1422
1423 if (newUserId <= 0) {
1424 ALOGW("%s: Bad user ID %d given during user switch, resetting to default.", __FUNCTION__,
1425 newUserId);
1426 newUserId = DEFAULT_LAST_USER_ID;
1427 }
1428
1429 mLastUserId = newUserId;
1430
1431 // Current user has switched, evict all current clients.
1432 std::vector<sp<BasicClient>> evicted;
1433 for (auto& i : mActiveClientManager.getAll()) {
1434 auto clientSp = i->getValue();
1435
1436 if (clientSp.get() == nullptr) {
1437 ALOGE("%s: Dead client still in mActiveClientManager.", __FUNCTION__);
1438 continue;
1439 }
1440
1441 evicted.push_back(clientSp);
1442
1443 String8 curTime = getFormattedCurrentTime();
1444
1445 ALOGE("Evicting conflicting client for camera ID %s due to user change",
1446 i->getKey().string());
1447 // Log the clients evicted
1448 mEventLog.add(String8::format("%s : EVICT device %s client for package %s (PID %"
1449 PRId32 ", priority %" PRId32 ")\n - Evicted due to user switch.",
1450 curTime.string(), i->getKey().string(),
1451 String8{clientSp->getPackageName()}.string(), i->getOwnerId(),
1452 i->getPriority()));
1453
1454 }
1455
1456 // Do not hold mServiceLock while disconnecting clients, but retain the condition
1457 // blocking other clients from connecting in mServiceLockWrapper if held.
1458 mServiceLock.unlock();
1459
1460 // Clear caller identity temporarily so client disconnect PID checks work correctly
1461 int64_t token = IPCThreadState::self()->clearCallingIdentity();
1462
1463 for (auto& i : evicted) {
1464 i->disconnect();
1465 }
1466
1467 IPCThreadState::self()->restoreCallingIdentity(token);
1468
1469 // Reacquire mServiceLock
1470 mServiceLock.lock();
1471}
Ruben Brunkcc776712015-02-17 20:18:47 -08001472
1473void CameraService::logDisconnected(const String8& cameraId, int clientPid,
1474 const String8& clientPackage) {
1475
1476 String8 curTime = getFormattedCurrentTime();
1477 // Log the clients evicted
1478 mEventLog.add(String8::format("%s : DISCONNECT device %s client for package %s (PID %d)",
1479 curTime.string(), cameraId.string(), clientPackage.string(), clientPid));
Mathias Agopian65ab4712010-07-14 17:59:35 -07001480}
1481
Ruben Brunkcc776712015-02-17 20:18:47 -08001482void CameraService::logConnected(const String8& cameraId, int clientPid,
1483 const String8& clientPackage) {
Igor Murashkinecf17e82012-10-02 16:05:11 -07001484
Ruben Brunkcc776712015-02-17 20:18:47 -08001485 String8 curTime = getFormattedCurrentTime();
1486 // Log the clients evicted
1487 mEventLog.add(String8::format("%s : CONNECT device %s client for package %s (PID %d)",
1488 curTime.string(), cameraId.string(), clientPackage.string(), clientPid));
Igor Murashkinecf17e82012-10-02 16:05:11 -07001489}
1490
Ruben Brunk36597b22015-03-20 22:15:57 -07001491status_t CameraService::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
1492 uint32_t flags) {
1493
1494 const int pid = getCallingPid();
1495 const int selfPid = getpid();
1496
Mathias Agopian65ab4712010-07-14 17:59:35 -07001497 // Permission checks
1498 switch (code) {
1499 case BnCameraService::CONNECT:
Eino-Ville Talvala63d877f2014-06-16 19:21:12 -07001500 case BnCameraService::CONNECT_DEVICE:
Ruben Brunk36597b22015-03-20 22:15:57 -07001501 case BnCameraService::CONNECT_LEGACY: {
1502 if (pid != selfPid) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001503 // we're called from a different process, do the real check
1504 if (!checkCallingPermission(
1505 String16("android.permission.CAMERA"))) {
1506 const int uid = getCallingUid();
Steve Block29357bc2012-01-06 19:20:56 +00001507 ALOGE("Permission Denial: "
Mathias Agopian65ab4712010-07-14 17:59:35 -07001508 "can't use the camera pid=%d, uid=%d", pid, uid);
1509 return PERMISSION_DENIED;
1510 }
1511 }
1512 break;
Ruben Brunk36597b22015-03-20 22:15:57 -07001513 }
1514 case BnCameraService::NOTIFY_SYSTEM_EVENT: {
1515 if (pid != selfPid) {
1516 // Ensure we're being called by system_server, or similar process with
1517 // permissions to notify the camera service about system events
1518 if (!checkCallingPermission(
1519 String16("android.permission.CAMERA_SEND_SYSTEM_EVENTS"))) {
1520 const int uid = getCallingUid();
1521 ALOGE("Permission Denial: cannot send updates to camera service about system"
1522 " events from pid=%d, uid=%d", pid, uid);
1523 return PERMISSION_DENIED;
1524 }
1525 }
1526 break;
1527 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001528 }
1529
1530 return BnCameraService::onTransact(code, data, reply, flags);
1531}
1532
Mathias Agopian65ab4712010-07-14 17:59:35 -07001533// We share the media players for shutter and recording sound for all clients.
1534// A reference count is kept to determine when we will actually release the
1535// media players.
1536
Chih-Chung Changff4f55c2011-10-17 19:03:12 +08001537MediaPlayer* CameraService::newMediaPlayer(const char *file) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001538 MediaPlayer* mp = new MediaPlayer();
Andreas Huber1b86fe02014-01-29 11:13:26 -08001539 if (mp->setDataSource(NULL /* httpService */, file, NULL) == NO_ERROR) {
Eino-Ville Talvala60a78ac2012-01-05 15:34:53 -08001540 mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001541 mp->prepare();
1542 } else {
Steve Block29357bc2012-01-06 19:20:56 +00001543 ALOGE("Failed to load CameraService sounds: %s", file);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001544 return NULL;
1545 }
1546 return mp;
1547}
1548
1549void CameraService::loadSound() {
1550 Mutex::Autolock lock(mSoundLock);
1551 LOG1("CameraService::loadSound ref=%d", mSoundRef);
1552 if (mSoundRef++) return;
1553
1554 mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
1555 mSoundPlayer[SOUND_RECORDING] = newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");
1556}
1557
1558void CameraService::releaseSound() {
1559 Mutex::Autolock lock(mSoundLock);
1560 LOG1("CameraService::releaseSound ref=%d", mSoundRef);
1561 if (--mSoundRef) return;
1562
1563 for (int i = 0; i < NUM_SOUNDS; i++) {
1564 if (mSoundPlayer[i] != 0) {
1565 mSoundPlayer[i]->disconnect();
1566 mSoundPlayer[i].clear();
1567 }
1568 }
1569}
1570
1571void CameraService::playSound(sound_kind kind) {
1572 LOG1("playSound(%d)", kind);
1573 Mutex::Autolock lock(mSoundLock);
1574 sp<MediaPlayer> player = mSoundPlayer[kind];
1575 if (player != 0) {
Chih-Chung Chang8888a752011-10-20 10:47:26 +08001576 player->seekTo(0);
1577 player->start();
Mathias Agopian65ab4712010-07-14 17:59:35 -07001578 }
1579}
1580
1581// ----------------------------------------------------------------------------
1582
1583CameraService::Client::Client(const sp<CameraService>& cameraService,
Wu-cheng Lib7a67942010-08-17 15:45:37 -07001584 const sp<ICameraClient>& cameraClient,
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001585 const String16& clientPackageName,
1586 int cameraId, int cameraFacing,
1587 int clientPid, uid_t clientUid,
1588 int servicePid) :
Eino-Ville Talvalae992e752014-11-07 16:17:48 -08001589 CameraService::BasicClient(cameraService,
Marco Nelissenf8880202014-11-14 07:58:25 -08001590 IInterface::asBinder(cameraClient),
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001591 clientPackageName,
1592 cameraId, cameraFacing,
1593 clientPid, clientUid,
1594 servicePid)
Igor Murashkin634a5152013-02-20 17:15:11 -08001595{
Mathias Agopian65ab4712010-07-14 17:59:35 -07001596 int callingPid = getCallingPid();
Wu-cheng Li2fd24402012-02-23 19:01:00 -08001597 LOG1("Client::Client E (pid %d, id %d)", callingPid, cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001598
Igor Murashkin44cfcf02013-03-01 16:22:28 -08001599 mRemoteCallback = cameraClient;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001600
Mathias Agopian65ab4712010-07-14 17:59:35 -07001601 cameraService->loadSound();
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001602
Wu-cheng Li2fd24402012-02-23 19:01:00 -08001603 LOG1("Client::Client X (pid %d, id %d)", callingPid, cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001604}
1605
Mathias Agopian65ab4712010-07-14 17:59:35 -07001606// tear down the client
1607CameraService::Client::~Client() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -07001608 ALOGV("~Client");
Igor Murashkin634a5152013-02-20 17:15:11 -08001609 mDestructionStarted = true;
1610
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001611 mCameraService->releaseSound();
Igor Murashkin036bc3e2012-10-08 15:09:46 -07001612 // unconditionally disconnect. function is idempotent
1613 Client::disconnect();
Mathias Agopian65ab4712010-07-14 17:59:35 -07001614}
1615
Igor Murashkin634a5152013-02-20 17:15:11 -08001616CameraService::BasicClient::BasicClient(const sp<CameraService>& cameraService,
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001617 const sp<IBinder>& remoteCallback,
1618 const String16& clientPackageName,
1619 int cameraId, int cameraFacing,
1620 int clientPid, uid_t clientUid,
1621 int servicePid):
Ruben Brunkcc776712015-02-17 20:18:47 -08001622 mClientPackageName(clientPackageName), mDisconnected(false)
Igor Murashkin634a5152013-02-20 17:15:11 -08001623{
1624 mCameraService = cameraService;
Igor Murashkin44cfcf02013-03-01 16:22:28 -08001625 mRemoteBinder = remoteCallback;
Igor Murashkin634a5152013-02-20 17:15:11 -08001626 mCameraId = cameraId;
1627 mCameraFacing = cameraFacing;
1628 mClientPid = clientPid;
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001629 mClientUid = clientUid;
Igor Murashkin634a5152013-02-20 17:15:11 -08001630 mServicePid = servicePid;
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001631 mOpsActive = false;
Igor Murashkin634a5152013-02-20 17:15:11 -08001632 mDestructionStarted = false;
1633}
1634
1635CameraService::BasicClient::~BasicClient() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -07001636 ALOGV("~BasicClient");
Igor Murashkin634a5152013-02-20 17:15:11 -08001637 mDestructionStarted = true;
1638}
1639
1640void CameraService::BasicClient::disconnect() {
Ruben Brunk36597b22015-03-20 22:15:57 -07001641 if (mDisconnected) {
1642 ALOGE("%s: Disconnect called on already disconnected client for device %d", __FUNCTION__,
1643 mCameraId);
1644 return;
1645 }
Ruben Brunkcc776712015-02-17 20:18:47 -08001646 mDisconnected = true;;
1647
1648 mCameraService->removeByClient(this);
1649 mCameraService->logDisconnected(String8::format("%d", mCameraId), mClientPid,
1650 String8(mClientPackageName));
1651
1652 sp<IBinder> remote = getRemote();
1653 if (remote != nullptr) {
1654 remote->unlinkToDeath(mCameraService);
1655 }
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001656
1657 finishCameraOps();
Ruben Brunkcc776712015-02-17 20:18:47 -08001658 ALOGI("%s: Disconnected client for camera %d for PID %d", __FUNCTION__, mCameraId, mClientPid);
1659
Igor Murashkincba2c162013-03-20 15:56:31 -07001660 // client shouldn't be able to call into us anymore
1661 mClientPid = 0;
Igor Murashkin634a5152013-02-20 17:15:11 -08001662}
1663
Ruben Brunkcc776712015-02-17 20:18:47 -08001664String16 CameraService::BasicClient::getPackageName() const {
1665 return mClientPackageName;
1666}
1667
1668
1669int CameraService::BasicClient::getClientPid() const {
1670 return mClientPid;
1671}
1672
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001673status_t CameraService::BasicClient::startCameraOps() {
1674 int32_t res;
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001675 // Notify app ops that the camera is not available
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001676 mOpsCallback = new OpsCallback(this);
1677
Igor Murashkine6800ce2013-03-04 17:25:57 -08001678 {
1679 ALOGV("%s: Start camera ops, package name = %s, client UID = %d",
1680 __FUNCTION__, String8(mClientPackageName).string(), mClientUid);
1681 }
1682
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001683 mAppOpsManager.startWatchingMode(AppOpsManager::OP_CAMERA,
1684 mClientPackageName, mOpsCallback);
1685 res = mAppOpsManager.startOp(AppOpsManager::OP_CAMERA,
1686 mClientUid, mClientPackageName);
1687
1688 if (res != AppOpsManager::MODE_ALLOWED) {
1689 ALOGI("Camera %d: Access for \"%s\" has been revoked",
1690 mCameraId, String8(mClientPackageName).string());
1691 return PERMISSION_DENIED;
1692 }
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001693
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001694 mOpsActive = true;
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001695
1696 // Transition device availability listeners from PRESENT -> NOT_AVAILABLE
1697 mCameraService->updateStatus(ICameraServiceListener::STATUS_NOT_AVAILABLE,
Ruben Brunkcc776712015-02-17 20:18:47 -08001698 String8::format("%d", mCameraId));
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001699
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001700 return OK;
1701}
1702
1703status_t CameraService::BasicClient::finishCameraOps() {
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001704 // Check if startCameraOps succeeded, and if so, finish the camera op
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001705 if (mOpsActive) {
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001706 // Notify app ops that the camera is available again
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001707 mAppOpsManager.finishOp(AppOpsManager::OP_CAMERA, mClientUid,
1708 mClientPackageName);
1709 mOpsActive = false;
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001710
Ruben Brunkcc776712015-02-17 20:18:47 -08001711 auto rejected = {ICameraServiceListener::STATUS_NOT_PRESENT,
1712 ICameraServiceListener::STATUS_ENUMERATING};
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001713
Ruben Brunkcc776712015-02-17 20:18:47 -08001714 // Transition to PRESENT if the camera is not in either of the rejected states
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001715 mCameraService->updateStatus(ICameraServiceListener::STATUS_PRESENT,
Ruben Brunkcc776712015-02-17 20:18:47 -08001716 String8::format("%d", mCameraId), rejected);
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001717
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001718 // Notify flashlight that a camera device is closed.
1719 mCameraService->mFlashlight->deviceClosed(
1720 String8::format("%d", mCameraId));
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001721 }
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001722 // Always stop watching, even if no camera op is active
Eino-Ville Talvalae992e752014-11-07 16:17:48 -08001723 if (mOpsCallback != NULL) {
1724 mAppOpsManager.stopWatchingMode(mOpsCallback);
1725 }
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001726 mOpsCallback.clear();
1727
1728 return OK;
1729}
1730
1731void CameraService::BasicClient::opChanged(int32_t op, const String16& packageName) {
1732 String8 name(packageName);
1733 String8 myName(mClientPackageName);
1734
1735 if (op != AppOpsManager::OP_CAMERA) {
1736 ALOGW("Unexpected app ops notification received: %d", op);
1737 return;
1738 }
1739
1740 int32_t res;
1741 res = mAppOpsManager.checkOp(AppOpsManager::OP_CAMERA,
1742 mClientUid, mClientPackageName);
1743 ALOGV("checkOp returns: %d, %s ", res,
1744 res == AppOpsManager::MODE_ALLOWED ? "ALLOWED" :
1745 res == AppOpsManager::MODE_IGNORED ? "IGNORED" :
1746 res == AppOpsManager::MODE_ERRORED ? "ERRORED" :
1747 "UNKNOWN");
1748
1749 if (res != AppOpsManager::MODE_ALLOWED) {
1750 ALOGI("Camera %d: Access for \"%s\" revoked", mCameraId,
1751 myName.string());
1752 // Reset the client PID to allow server-initiated disconnect,
1753 // and to prevent further calls by client.
1754 mClientPid = getCallingPid();
Jianing Weicb0652e2014-03-12 18:29:36 -07001755 CaptureResultExtras resultExtras; // a dummy result (invalid)
1756 notifyError(ICameraDeviceCallbacks::ERROR_CAMERA_SERVICE, resultExtras);
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001757 disconnect();
1758 }
1759}
1760
Mathias Agopian65ab4712010-07-14 17:59:35 -07001761// ----------------------------------------------------------------------------
1762
Ruben Brunkcc776712015-02-17 20:18:47 -08001763// Provide client strong pointer for callbacks.
1764sp<CameraService::Client> CameraService::Client::getClientFromCookie(void* user) {
1765 String8 cameraId = String8::format("%d", (int)(intptr_t) user);
1766 auto clientDescriptor = gCameraService->mActiveClientManager.get(cameraId);
1767 if (clientDescriptor != nullptr) {
1768 return sp<Client>{
1769 static_cast<Client*>(clientDescriptor->getValue().get())};
1770 }
1771 return sp<Client>{nullptr};
Mathias Agopian65ab4712010-07-14 17:59:35 -07001772}
1773
Jianing Weicb0652e2014-03-12 18:29:36 -07001774void CameraService::Client::notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode,
1775 const CaptureResultExtras& resultExtras) {
Igor Murashkin44cfcf02013-03-01 16:22:28 -08001776 mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_RELEASED, 0);
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001777}
1778
Igor Murashkin036bc3e2012-10-08 15:09:46 -07001779// NOTE: function is idempotent
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001780void CameraService::Client::disconnect() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -07001781 ALOGV("Client::disconnect");
Igor Murashkin634a5152013-02-20 17:15:11 -08001782 BasicClient::disconnect();
Wu-cheng Lie09591e2010-10-14 20:17:44 +08001783}
1784
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001785CameraService::Client::OpsCallback::OpsCallback(wp<BasicClient> client):
1786 mClient(client) {
1787}
1788
1789void CameraService::Client::OpsCallback::opChanged(int32_t op,
1790 const String16& packageName) {
1791 sp<BasicClient> client = mClient.promote();
1792 if (client != NULL) {
1793 client->opChanged(op, packageName);
1794 }
1795}
1796
Mathias Agopian65ab4712010-07-14 17:59:35 -07001797// ----------------------------------------------------------------------------
Ruben Brunkcc776712015-02-17 20:18:47 -08001798// CameraState
1799// ----------------------------------------------------------------------------
1800
1801CameraService::CameraState::CameraState(const String8& id, int cost,
1802 const std::set<String8>& conflicting) : mId(id),
1803 mStatus(ICameraServiceListener::STATUS_PRESENT), mCost(cost), mConflicting(conflicting) {}
1804
1805CameraService::CameraState::~CameraState() {}
1806
1807ICameraServiceListener::Status CameraService::CameraState::getStatus() const {
1808 Mutex::Autolock lock(mStatusLock);
1809 return mStatus;
1810}
1811
1812CameraParameters CameraService::CameraState::getShimParams() const {
1813 return mShimParams;
1814}
1815
1816void CameraService::CameraState::setShimParams(const CameraParameters& params) {
1817 mShimParams = params;
1818}
1819
1820int CameraService::CameraState::getCost() const {
1821 return mCost;
1822}
1823
1824std::set<String8> CameraService::CameraState::getConflicting() const {
1825 return mConflicting;
1826}
1827
1828String8 CameraService::CameraState::getId() const {
1829 return mId;
1830}
1831
1832// ----------------------------------------------------------------------------
1833// CameraClientManager
1834// ----------------------------------------------------------------------------
1835
1836CameraService::CameraClientManager::~CameraClientManager() {}
1837
1838sp<CameraService::BasicClient> CameraService::CameraClientManager::getCameraClient(
1839 const String8& id) const {
1840 auto descriptor = get(id);
1841 if (descriptor == nullptr) {
1842 return sp<BasicClient>{nullptr};
1843 }
1844 return descriptor->getValue();
1845}
1846
1847String8 CameraService::CameraClientManager::toString() const {
1848 auto all = getAll();
1849 String8 ret("[");
1850 bool hasAny = false;
1851 for (auto& i : all) {
1852 hasAny = true;
1853 String8 key = i->getKey();
1854 int32_t cost = i->getCost();
1855 int32_t pid = i->getOwnerId();
1856 int32_t priority = i->getPriority();
1857 auto conflicting = i->getConflicting();
1858 auto clientSp = i->getValue();
1859 String8 packageName;
1860 if (clientSp.get() != nullptr) {
1861 packageName = String8{clientSp->getPackageName()};
1862 }
1863 ret.appendFormat("\n(Camera ID: %s, Cost: %" PRId32 ", PID: %" PRId32 ", Priority: %"
1864 PRId32 ", ", key.string(), cost, pid, priority);
1865
1866 if (packageName.size() != 0) {
1867 ret.appendFormat("Client Package Name: %s", packageName.string());
1868 }
1869
1870 ret.append(", Conflicting Client Devices: {");
1871 for (auto& j : conflicting) {
1872 ret.appendFormat("%s, ", j.string());
1873 }
1874 ret.append("})");
1875 }
1876 if (hasAny) ret.append("\n");
1877 ret.append("]\n");
1878 return ret;
1879}
1880
1881CameraService::DescriptorPtr CameraService::CameraClientManager::makeClientDescriptor(
1882 const String8& key, const sp<BasicClient>& value, int32_t cost,
1883 const std::set<String8>& conflictingKeys, int32_t priority, int32_t ownerId) {
1884
1885 return std::make_shared<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>(
1886 key, value, cost, conflictingKeys, priority, ownerId);
1887}
1888
1889CameraService::DescriptorPtr CameraService::CameraClientManager::makeClientDescriptor(
1890 const sp<BasicClient>& value, const CameraService::DescriptorPtr& partial) {
1891 return makeClientDescriptor(partial->getKey(), value, partial->getCost(),
1892 partial->getConflicting(), partial->getPriority(), partial->getOwnerId());
1893}
1894
1895// ----------------------------------------------------------------------------
Mathias Agopian65ab4712010-07-14 17:59:35 -07001896
1897static const int kDumpLockRetries = 50;
1898static const int kDumpLockSleep = 60000;
1899
1900static bool tryLock(Mutex& mutex)
1901{
1902 bool locked = false;
1903 for (int i = 0; i < kDumpLockRetries; ++i) {
1904 if (mutex.tryLock() == NO_ERROR) {
1905 locked = true;
1906 break;
1907 }
1908 usleep(kDumpLockSleep);
1909 }
1910 return locked;
1911}
1912
1913status_t CameraService::dump(int fd, const Vector<String16>& args) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001914 String8 result;
1915 if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -07001916 result.appendFormat("Permission Denial: "
Mathias Agopian65ab4712010-07-14 17:59:35 -07001917 "can't dump CameraService from pid=%d, uid=%d\n",
1918 getCallingPid(),
1919 getCallingUid());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001920 write(fd, result.string(), result.size());
1921 } else {
1922 bool locked = tryLock(mServiceLock);
1923 // failed to lock - CameraService is probably deadlocked
1924 if (!locked) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -07001925 result.append("CameraService may be deadlocked\n");
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001926 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001927 }
1928
1929 bool hasClient = false;
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001930 if (!mModule) {
1931 result = String8::format("No camera module available!\n");
1932 write(fd, result.string(), result.size());
Kalle Lampila6ec3a152013-04-30 15:27:19 +03001933 if (locked) mServiceLock.unlock();
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001934 return NO_ERROR;
1935 }
1936
Chien-Yu Chen676b21b2015-02-24 10:28:19 -08001937 result = String8::format("Camera module HAL API version: 0x%x\n", mModule->getHalApiVersion());
1938 result.appendFormat("Camera module API version: 0x%x\n", mModule->getModuleApiVersion());
1939 result.appendFormat("Camera module name: %s\n", mModule->getModuleName());
1940 result.appendFormat("Camera module author: %s\n", mModule->getModuleAuthor());
Ruben Brunkcc776712015-02-17 20:18:47 -08001941 result.appendFormat("Number of camera devices: %d\n", mNumberOfCameras);
1942 String8 activeClientString = mActiveClientManager.toString();
1943 result.appendFormat("Active Camera Clients:\n%s", activeClientString.string());
1944
Ruben Brunkf81648e2014-04-17 16:14:57 -07001945 sp<VendorTagDescriptor> desc = VendorTagDescriptor::getGlobalVendorTagDescriptor();
1946 if (desc == NULL) {
1947 result.appendFormat("Vendor tags left unimplemented.\n");
1948 } else {
1949 result.appendFormat("Vendor tag definitions:\n");
1950 }
1951
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001952 write(fd, result.string(), result.size());
Ruben Brunkf81648e2014-04-17 16:14:57 -07001953
1954 if (desc != NULL) {
1955 desc->dump(fd, /*verbosity*/2, /*indentation*/4);
1956 }
1957
Ruben Brunkcc776712015-02-17 20:18:47 -08001958 result = String8("Prior client events (most recent at top):\n");
1959
1960 for (const auto& msg : mEventLog) {
1961 result.appendFormat("%s\n", msg.string());
1962 }
1963
1964 if (mEventLog.size() == DEFAULT_EVICTION_LOG_LENGTH) {
1965 result.append("...\n");
1966 }
1967
1968 write(fd, result.string(), result.size());
1969
1970 bool stateLocked = tryLock(mCameraStatesLock);
1971 if (!stateLocked) {
1972 result = String8::format("CameraStates in use, may be deadlocked\n");
1973 write(fd, result.string(), result.size());
1974 }
1975
1976 for (auto& state : mCameraStates) {
1977 String8 cameraId = state.first;
1978 result = String8::format("Camera %s information:\n", cameraId.string());
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001979 camera_info info;
1980
Ruben Brunkcc776712015-02-17 20:18:47 -08001981 // TODO: Change getCameraInfo + HAL to use String cameraIds
1982 status_t rc = mModule->getCameraInfo(cameraIdToInt(cameraId), &info);
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001983 if (rc != OK) {
1984 result.appendFormat(" Error reading static information!\n");
1985 write(fd, result.string(), result.size());
1986 } else {
1987 result.appendFormat(" Facing: %s\n",
1988 info.facing == CAMERA_FACING_BACK ? "BACK" : "FRONT");
1989 result.appendFormat(" Orientation: %d\n", info.orientation);
1990 int deviceVersion;
Chien-Yu Chen676b21b2015-02-24 10:28:19 -08001991 if (mModule->getModuleApiVersion() < CAMERA_MODULE_API_VERSION_2_0) {
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001992 deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
1993 } else {
1994 deviceVersion = info.device_version;
1995 }
Ruben Brunkcc776712015-02-17 20:18:47 -08001996
1997 auto conflicting = state.second->getConflicting();
1998 result.appendFormat(" Resource Cost: %d\n", state.second->getCost());
1999 result.appendFormat(" Conflicting Devices:");
2000 for (auto& id : conflicting) {
2001 result.appendFormat(" %s", cameraId.string());
2002 }
2003 if (conflicting.size() == 0) {
2004 result.appendFormat(" NONE");
2005 }
2006 result.appendFormat("\n");
2007
2008 result.appendFormat(" Device version: %#x\n", deviceVersion);
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07002009 if (deviceVersion >= CAMERA_DEVICE_API_VERSION_2_0) {
2010 result.appendFormat(" Device static metadata:\n");
2011 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -07002012 dump_indented_camera_metadata(info.static_camera_characteristics,
Ruben Brunkf81648e2014-04-17 16:14:57 -07002013 fd, /*verbosity*/2, /*indentation*/4);
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07002014 } else {
2015 write(fd, result.string(), result.size());
2016 }
Ruben Brunkcc776712015-02-17 20:18:47 -08002017
2018 CameraParameters p = state.second->getShimParams();
2019 if (!p.isEmpty()) {
2020 result = String8::format(" Camera1 API shim is using parameters:\n ");
2021 write(fd, result.string(), result.size());
2022 p.dump(fd, args);
2023 }
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07002024 }
2025
Ruben Brunkcc776712015-02-17 20:18:47 -08002026 auto clientDescriptor = mActiveClientManager.get(cameraId);
2027 if (clientDescriptor == nullptr) {
2028 result = String8::format(" Device %s is closed, no client instance\n",
2029 cameraId.string());
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07002030 write(fd, result.string(), result.size());
2031 continue;
2032 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07002033 hasClient = true;
Ruben Brunkcc776712015-02-17 20:18:47 -08002034 result = String8::format(" Device %s is open. Client instance dump:\n\n",
2035 cameraId.string());
2036 result.appendFormat("Client priority level: %d\n", clientDescriptor->getPriority());
2037 result.appendFormat("Client PID: %d\n", clientDescriptor->getOwnerId());
2038
2039 auto client = clientDescriptor->getValue();
2040 result.appendFormat("Client package: %s\n",
2041 String8(client->getPackageName()).string());
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07002042 write(fd, result.string(), result.size());
Ruben Brunkcc776712015-02-17 20:18:47 -08002043
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07002044 client->dump(fd, args);
Mathias Agopian65ab4712010-07-14 17:59:35 -07002045 }
Ruben Brunkcc776712015-02-17 20:18:47 -08002046
2047 if (stateLocked) mCameraStatesLock.unlock();
2048
Mathias Agopian65ab4712010-07-14 17:59:35 -07002049 if (!hasClient) {
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07002050 result = String8::format("\nNo active camera clients yet.\n");
2051 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07002052 }
2053
2054 if (locked) mServiceLock.unlock();
2055
Igor Murashkinff3e31d2013-10-23 16:40:06 -07002056 // Dump camera traces if there were any
2057 write(fd, "\n", 1);
2058 camera3::CameraTraces::dump(fd, args);
2059
Mathias Agopian65ab4712010-07-14 17:59:35 -07002060 // change logging level
2061 int n = args.size();
2062 for (int i = 0; i + 1 < n; i++) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -07002063 String16 verboseOption("-v");
2064 if (args[i] == verboseOption) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07002065 String8 levelStr(args[i+1]);
2066 int level = atoi(levelStr.string());
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07002067 result = String8::format("\nSetting log level to %d.\n", level);
Mathias Agopian65ab4712010-07-14 17:59:35 -07002068 setLogLevel(level);
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07002069 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07002070 }
2071 }
2072 }
2073 return NO_ERROR;
2074}
2075
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002076void CameraService::handleTorchClientBinderDied(const wp<IBinder> &who) {
Chien-Yu Chen88da5262015-02-17 13:56:46 -08002077 Mutex::Autolock al(mTorchClientMapMutex);
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002078 for (size_t i = 0; i < mTorchClientMap.size(); i++) {
2079 if (mTorchClientMap[i] == who) {
2080 // turn off the torch mode that was turned on by dead client
Chien-Yu Chen88da5262015-02-17 13:56:46 -08002081 String8 cameraId = mTorchClientMap.keyAt(i);
2082 status_t res = mFlashlight->setTorchMode(cameraId, false);
2083 if (res) {
2084 ALOGE("%s: torch client died but couldn't turn off torch: "
2085 "%s (%d)", __FUNCTION__, strerror(-res), res);
2086 return;
2087 }
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002088 mTorchClientMap.removeItemsAt(i);
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002089 break;
2090 }
2091 }
2092}
2093
Ruben Brunkcc776712015-02-17 20:18:47 -08002094/*virtual*/void CameraService::binderDied(const wp<IBinder> &who) {
Igor Murashkinecf17e82012-10-02 16:05:11 -07002095
Igor Murashkin294d0ec2012-10-05 10:44:57 -07002096 /**
2097 * While tempting to promote the wp<IBinder> into a sp,
2098 * it's actually not supported by the binder driver
2099 */
2100
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002101 // check torch client
2102 handleTorchClientBinderDied(who);
2103
2104 // check camera device client
Ruben Brunkcc776712015-02-17 20:18:47 -08002105 if(!evictClientIdByRemote(who)) {
2106 ALOGV("%s: Java client's binder death already cleaned up (normal case)", __FUNCTION__);
Igor Murashkinecf17e82012-10-02 16:05:11 -07002107 return;
2108 }
2109
Ruben Brunkcc776712015-02-17 20:18:47 -08002110 ALOGE("%s: Java client's binder died, removing it from the list of active clients",
2111 __FUNCTION__);
Igor Murashkinecf17e82012-10-02 16:05:11 -07002112}
2113
Ruben Brunkcc776712015-02-17 20:18:47 -08002114void CameraService::updateStatus(ICameraServiceListener::Status status, const String8& cameraId) {
2115 updateStatus(status, cameraId, {});
Igor Murashkinbfc99152013-02-27 12:55:20 -08002116}
2117
Ruben Brunkcc776712015-02-17 20:18:47 -08002118void CameraService::updateStatus(ICameraServiceListener::Status status, const String8& cameraId,
2119 std::initializer_list<ICameraServiceListener::Status> rejectSourceStates) {
2120 // Do not lock mServiceLock here or can get into a deadlock from
2121 // connect() -> disconnect -> updateStatus
2122
2123 auto state = getCameraState(cameraId);
2124
2125 if (state == nullptr) {
2126 ALOGW("%s: Could not update the status for %s, no such device exists", __FUNCTION__,
2127 cameraId.string());
2128 return;
Igor Murashkincba2c162013-03-20 15:56:31 -07002129 }
2130
Ruben Brunkcc776712015-02-17 20:18:47 -08002131 // Update the status for this camera state, then send the onStatusChangedCallbacks to each
2132 // of the listeners with both the mStatusStatus and mStatusListenerLock held
2133 state->updateStatus(status, cameraId, rejectSourceStates, [this]
2134 (const String8& cameraId, ICameraServiceListener::Status status) {
2135
2136 // Update torch status
2137 if (status == ICameraServiceListener::STATUS_NOT_PRESENT ||
2138 status == ICameraServiceListener::STATUS_NOT_AVAILABLE) {
2139 // Update torch status to not available when the camera device becomes not present
2140 // or not available.
2141 onTorchStatusChanged(cameraId, ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE);
2142 } else if (status == ICameraServiceListener::STATUS_PRESENT) {
2143 // Update torch status to available when the camera device becomes present or
2144 // available
2145 onTorchStatusChanged(cameraId, ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF);
2146 }
2147
2148 Mutex::Autolock lock(mStatusListenerLock);
2149
2150 for (auto& listener : mListenerList) {
2151 // TODO: Refactor status listeners to use strings for Camera IDs and remove this.
2152 int id = cameraIdToInt(cameraId);
2153 if (id != -1) listener->onStatusChanged(status, id);
2154 }
2155 });
Igor Murashkincba2c162013-03-20 15:56:31 -07002156}
2157
Chien-Yu Chen88da5262015-02-17 13:56:46 -08002158status_t CameraService::getTorchStatusLocked(
2159 const String8& cameraId,
2160 ICameraServiceListener::TorchStatus *status) const {
2161 if (!status) {
2162 return BAD_VALUE;
2163 }
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002164 ssize_t index = mTorchStatusMap.indexOfKey(cameraId);
2165 if (index == NAME_NOT_FOUND) {
Chien-Yu Chen88da5262015-02-17 13:56:46 -08002166 // invalid camera ID or the camera doesn't have a flash unit
2167 return NAME_NOT_FOUND;
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002168 }
2169
Chien-Yu Chen88da5262015-02-17 13:56:46 -08002170 *status = mTorchStatusMap.valueAt(index);
2171 return OK;
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002172}
2173
Chien-Yu Chen88da5262015-02-17 13:56:46 -08002174status_t CameraService::setTorchStatusLocked(const String8& cameraId,
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002175 ICameraServiceListener::TorchStatus status) {
2176 ssize_t index = mTorchStatusMap.indexOfKey(cameraId);
2177 if (index == NAME_NOT_FOUND) {
2178 return BAD_VALUE;
2179 }
2180 ICameraServiceListener::TorchStatus& item =
2181 mTorchStatusMap.editValueAt(index);
2182 item = status;
2183
2184 return OK;
2185}
2186
Mathias Agopian65ab4712010-07-14 17:59:35 -07002187}; // namespace android