blob: c2df4894350776e4c297eb39f5430d98eaba9a74 [file] [log] [blame]
Mathias Agopian65ab4712010-07-14 17:59:35 -07001/*
Ruben Brunkd1176ef2014-02-21 10:51:38 -08002 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Mathias Agopian65ab4712010-07-14 17:59:35 -070016
17#define LOG_TAG "CameraService"
Iliyan Malchev8951a972011-04-14 16:55:59 -070018//#define LOG_NDEBUG 0
Mathias Agopian65ab4712010-07-14 17:59:35 -070019
Ruben Brunkcc776712015-02-17 20:18:47 -080020#include <algorithm>
21#include <climits>
Mathias Agopian65ab4712010-07-14 17:59:35 -070022#include <stdio.h>
Ruben Brunkcc776712015-02-17 20:18:47 -080023#include <cstring>
24#include <ctime>
25#include <string>
Mathias Agopian65ab4712010-07-14 17:59:35 -070026#include <sys/types.h>
Ruben Brunkcc776712015-02-17 20:18:47 -080027#include <inttypes.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070028#include <pthread.h>
29
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -080030#include <binder/AppOpsManager.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070031#include <binder/IPCThreadState.h>
32#include <binder/IServiceManager.h>
33#include <binder/MemoryBase.h>
34#include <binder/MemoryHeapBase.h>
Ruben Brunkcc776712015-02-17 20:18:47 -080035#include <binder/ProcessInfoService.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070036#include <cutils/atomic.h>
Nipun Kwatrab5ca4612010-09-11 19:31:10 -070037#include <cutils/properties.h>
Amith Yamasani228711d2015-02-13 13:25:39 -080038#include <cutils/multiuser.h>
Mathias Agopiandf712ea2012-02-25 18:48:35 -080039#include <gui/Surface.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070040#include <hardware/hardware.h>
41#include <media/AudioSystem.h>
Andreas Huber1b86fe02014-01-29 11:13:26 -080042#include <media/IMediaHTTPService.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070043#include <media/mediaplayer.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070044#include <utils/Errors.h>
45#include <utils/Log.h>
46#include <utils/String16.h>
Ruben Brunkd1176ef2014-02-21 10:51:38 -080047#include <utils/Trace.h>
48#include <system/camera_vendor_tags.h>
Ruben Brunkb2119af2014-05-09 19:57:56 -070049#include <system/camera_metadata.h>
50#include <system/camera.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070051
52#include "CameraService.h"
Eino-Ville Talvala7b82efe2013-07-25 17:12:35 -070053#include "api1/CameraClient.h"
54#include "api1/Camera2Client.h"
Eino-Ville Talvala7b82efe2013-07-25 17:12:35 -070055#include "api2/CameraDeviceClient.h"
Igor Murashkinff3e31d2013-10-23 16:40:06 -070056#include "utils/CameraTraces.h"
Igor Murashkin98e24722013-06-19 19:51:04 -070057#include "CameraDeviceFactory.h"
Mathias Agopian65ab4712010-07-14 17:59:35 -070058
59namespace android {
60
61// ----------------------------------------------------------------------------
62// Logging support -- this is for debugging only
63// Use "adb shell dumpsys media.camera -v 1" to change it.
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -070064volatile int32_t gLogLevel = 0;
Mathias Agopian65ab4712010-07-14 17:59:35 -070065
Steve Blockb8a80522011-12-20 16:23:08 +000066#define LOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__);
67#define LOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__);
Mathias Agopian65ab4712010-07-14 17:59:35 -070068
69static void setLogLevel(int level) {
70 android_atomic_write(level, &gLogLevel);
71}
72
73// ----------------------------------------------------------------------------
74
Igor Murashkincba2c162013-03-20 15:56:31 -070075extern "C" {
76static void camera_device_status_change(
77 const struct camera_module_callbacks* callbacks,
78 int camera_id,
79 int new_status) {
80 sp<CameraService> cs = const_cast<CameraService*>(
Ruben Brunkcc776712015-02-17 20:18:47 -080081 static_cast<const CameraService*>(callbacks));
Igor Murashkincba2c162013-03-20 15:56:31 -070082
Ruben Brunkcc776712015-02-17 20:18:47 -080083 cs->onDeviceStatusChanged(static_cast<camera_device_status_t>(camera_id),
84 static_cast<camera_device_status_t>(new_status));
Igor Murashkincba2c162013-03-20 15:56:31 -070085}
Chien-Yu Chen3068d732015-02-09 13:29:57 -080086
87static void torch_mode_status_change(
88 const struct camera_module_callbacks* callbacks,
89 const char* camera_id,
90 int new_status) {
91 if (!callbacks || !camera_id) {
92 ALOGE("%s invalid parameters. callbacks %p, camera_id %p", __FUNCTION__,
93 callbacks, camera_id);
94 }
95 sp<CameraService> cs = const_cast<CameraService*>(
96 static_cast<const CameraService*>(callbacks));
97
98 ICameraServiceListener::TorchStatus status;
99 switch (new_status) {
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800100 case TORCH_MODE_STATUS_NOT_AVAILABLE:
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800101 status = ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE;
102 break;
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800103 case TORCH_MODE_STATUS_AVAILABLE_OFF:
104 status = ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF;
105 break;
106 case TORCH_MODE_STATUS_AVAILABLE_ON:
107 status = ICameraServiceListener::TORCH_STATUS_AVAILABLE_ON;
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800108 break;
109 default:
110 ALOGE("Unknown torch status %d", new_status);
111 return;
112 }
113
114 cs->onTorchStatusChanged(
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800115 String8(camera_id),
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800116 status);
117}
Igor Murashkincba2c162013-03-20 15:56:31 -0700118} // extern "C"
119
Mathias Agopian65ab4712010-07-14 17:59:35 -0700120// ----------------------------------------------------------------------------
121
122// This is ugly and only safe if we never re-create the CameraService, but
123// should be ok for now.
124static CameraService *gCameraService;
125
126CameraService::CameraService()
Ruben Brunkcc776712015-02-17 20:18:47 -0800127 : mEventLog(DEFAULT_EVICTION_LOG_LENGTH), mSoundRef(0), mModule(0), mFlashlight(0)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700128{
Steve Blockdf64d152012-01-04 20:05:49 +0000129 ALOGI("CameraService started (pid=%d)", getpid());
Mathias Agopian65ab4712010-07-14 17:59:35 -0700130 gCameraService = this;
Igor Murashkinbfc99152013-02-27 12:55:20 -0800131
Igor Murashkincba2c162013-03-20 15:56:31 -0700132 this->camera_device_status_change = android::camera_device_status_change;
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800133 this->torch_mode_status_change = android::torch_mode_status_change;
134
Ruben Brunkcc776712015-02-17 20:18:47 -0800135 mServiceLockWrapper = std::make_shared<WaitableMutexWrapper>(&mServiceLock);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700136}
137
Iliyan Malchev8951a972011-04-14 16:55:59 -0700138void CameraService::onFirstRef()
139{
Ruben Brunkcc776712015-02-17 20:18:47 -0800140 ALOGI("CameraService process starting");
Igor Murashkin634a5152013-02-20 17:15:11 -0800141
Iliyan Malchev8951a972011-04-14 16:55:59 -0700142 BnCameraService::onFirstRef();
143
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800144 camera_module_t *rawModule;
Iliyan Malchev8951a972011-04-14 16:55:59 -0700145 if (hw_get_module(CAMERA_HARDWARE_MODULE_ID,
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800146 (const hw_module_t **)&rawModule) < 0) {
Steve Block29357bc2012-01-06 19:20:56 +0000147 ALOGE("Could not load camera HAL module");
Iliyan Malchev8951a972011-04-14 16:55:59 -0700148 mNumberOfCameras = 0;
149 }
150 else {
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800151 mModule = new CameraModule(rawModule);
Chien-Yu Chen676b21b2015-02-24 10:28:19 -0800152 ALOGI("Loaded \"%s\" camera module", mModule->getModuleName());
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800153 mNumberOfCameras = mModule->getNumberOfCameras();
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800154
155 mFlashlight = new CameraFlashlight(*mModule, *this);
156 status_t res = mFlashlight->findFlashUnits();
157 if (res) {
158 // impossible because we haven't open any camera devices.
Ruben Brunkcc776712015-02-17 20:18:47 -0800159 ALOGE("Failed to find flash units.");
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800160 }
161
Iliyan Malchev8951a972011-04-14 16:55:59 -0700162 for (int i = 0; i < mNumberOfCameras; i++) {
Ruben Brunkcc776712015-02-17 20:18:47 -0800163 String8 cameraId = String8::format("%d", i);
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800164
Ruben Brunkcc776712015-02-17 20:18:47 -0800165 // Defaults to use for cost and conflicting devices
166 int cost = 100;
167 char** conflicting_devices = nullptr;
168 size_t conflicting_devices_length = 0;
169
170 // If using post-2.4 module version, query the cost + conflicting devices from the HAL
Chien-Yu Chen676b21b2015-02-24 10:28:19 -0800171 if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_4) {
Ruben Brunkcc776712015-02-17 20:18:47 -0800172 struct camera_info info;
173 status_t rc = mModule->getCameraInfo(i, &info);
174 if (rc == NO_ERROR) {
175 cost = info.resource_cost;
176 conflicting_devices = info.conflicting_devices;
177 conflicting_devices_length = info.conflicting_devices_length;
178 } else {
179 ALOGE("%s: Received error loading camera info for device %d, cost and"
180 " conflicting devices fields set to defaults for this device.",
181 __FUNCTION__, i);
182 }
183 }
184
185 std::set<String8> conflicting;
186 for (size_t i = 0; i < conflicting_devices_length; i++) {
187 conflicting.emplace(String8(conflicting_devices[i]));
188 }
189
190 // Initialize state for each camera device
191 {
192 Mutex::Autolock lock(mCameraStatesLock);
193 mCameraStates.emplace(cameraId, std::make_shared<CameraState>(cameraId, cost,
194 conflicting));
195 }
196
197 if (mFlashlight->hasFlashUnit(cameraId)) {
198 mTorchStatusMap.add(cameraId,
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800199 ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF);
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800200 }
Iliyan Malchev8951a972011-04-14 16:55:59 -0700201 }
Igor Murashkincba2c162013-03-20 15:56:31 -0700202
Chien-Yu Chen676b21b2015-02-24 10:28:19 -0800203 if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_1) {
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800204 mModule->setCallbacks(this);
Igor Murashkincba2c162013-03-20 15:56:31 -0700205 }
Igor Murashkin98e24722013-06-19 19:51:04 -0700206
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800207 VendorTagDescriptor::clearGlobalVendorTagDescriptor();
208
Chien-Yu Chen676b21b2015-02-24 10:28:19 -0800209 if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_2) {
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800210 setUpVendorTags();
211 }
212
Igor Murashkin98e24722013-06-19 19:51:04 -0700213 CameraDeviceFactory::registerService(this);
Iliyan Malchev8951a972011-04-14 16:55:59 -0700214 }
215}
216
Mathias Agopian65ab4712010-07-14 17:59:35 -0700217CameraService::~CameraService() {
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800218 if (mModule) {
219 delete mModule;
Ruben Brunkcc776712015-02-17 20:18:47 -0800220 mModule = nullptr;
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800221 }
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800222 VendorTagDescriptor::clearGlobalVendorTagDescriptor();
Ruben Brunkcc776712015-02-17 20:18:47 -0800223 gCameraService = nullptr;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700224}
225
Ruben Brunkcc776712015-02-17 20:18:47 -0800226void CameraService::onDeviceStatusChanged(camera_device_status_t cameraId,
227 camera_device_status_t newStatus) {
228 ALOGI("%s: Status changed for cameraId=%d, newStatus=%d", __FUNCTION__,
Igor Murashkincba2c162013-03-20 15:56:31 -0700229 cameraId, newStatus);
230
Ruben Brunkcc776712015-02-17 20:18:47 -0800231 String8 id = String8::format("%d", cameraId);
232 std::shared_ptr<CameraState> state = getCameraState(id);
233
234 if (state == nullptr) {
Igor Murashkincba2c162013-03-20 15:56:31 -0700235 ALOGE("%s: Bad camera ID %d", __FUNCTION__, cameraId);
236 return;
237 }
238
Ruben Brunkcc776712015-02-17 20:18:47 -0800239 ICameraServiceListener::Status oldStatus = state->getStatus();
240
241 if (oldStatus == static_cast<ICameraServiceListener::Status>(newStatus)) {
242 ALOGE("%s: State transition to the same status %#x not allowed", __FUNCTION__, newStatus);
Igor Murashkincba2c162013-03-20 15:56:31 -0700243 return;
244 }
245
Igor Murashkincba2c162013-03-20 15:56:31 -0700246 if (newStatus == CAMERA_DEVICE_STATUS_NOT_PRESENT) {
Ruben Brunkcc776712015-02-17 20:18:47 -0800247 sp<BasicClient> clientToDisconnect;
Igor Murashkincba2c162013-03-20 15:56:31 -0700248 {
Ruben Brunkcc776712015-02-17 20:18:47 -0800249 // Don't do this in updateStatus to avoid deadlock over mServiceLock
250 Mutex::Autolock lock(mServiceLock);
Igor Murashkincba2c162013-03-20 15:56:31 -0700251
Ruben Brunkcc776712015-02-17 20:18:47 -0800252 // Set the device status to NOT_PRESENT, clients will no longer be able to connect
253 // to this device until the status changes
254 updateStatus(ICameraServiceListener::STATUS_NOT_PRESENT, id);
Ruben Brunkb2119af2014-05-09 19:57:56 -0700255
Ruben Brunkcc776712015-02-17 20:18:47 -0800256 // Remove cached shim parameters
257 state->setShimParams(CameraParameters());
Igor Murashkincba2c162013-03-20 15:56:31 -0700258
Ruben Brunkcc776712015-02-17 20:18:47 -0800259 // Remove the client from the list of active clients
260 clientToDisconnect = removeClientLocked(id);
261
262 // Notify the client of disconnection
263 clientToDisconnect->notifyError(ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED,
264 CaptureResultExtras{});
Igor Murashkincba2c162013-03-20 15:56:31 -0700265 }
266
Ruben Brunkcc776712015-02-17 20:18:47 -0800267 ALOGI("%s: Client for camera ID %s evicted due to device status change from HAL",
268 __FUNCTION__, id.string());
Igor Murashkincba2c162013-03-20 15:56:31 -0700269
Ruben Brunkcc776712015-02-17 20:18:47 -0800270 // Disconnect client
271 if (clientToDisconnect.get() != nullptr) {
272 // Ensure not in binder RPC so client disconnect PID checks work correctly
273 LOG_ALWAYS_FATAL_IF(getCallingPid() != getpid(),
274 "onDeviceStatusChanged must be called from the camera service process!");
275 clientToDisconnect->disconnect();
Igor Murashkincba2c162013-03-20 15:56:31 -0700276 }
277
Ruben Brunkcc776712015-02-17 20:18:47 -0800278 } else {
279 updateStatus(static_cast<ICameraServiceListener::Status>(newStatus), id);
Igor Murashkincba2c162013-03-20 15:56:31 -0700280 }
281
Igor Murashkincba2c162013-03-20 15:56:31 -0700282}
283
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800284void CameraService::onTorchStatusChanged(const String8& cameraId,
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800285 ICameraServiceListener::TorchStatus newStatus) {
286 Mutex::Autolock al(mTorchStatusMutex);
287 onTorchStatusChangedLocked(cameraId, newStatus);
288}
289
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800290void CameraService::onTorchStatusChangedLocked(const String8& cameraId,
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800291 ICameraServiceListener::TorchStatus newStatus) {
292 ALOGI("%s: Torch status changed for cameraId=%s, newStatus=%d",
293 __FUNCTION__, cameraId.string(), newStatus);
294
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800295 ICameraServiceListener::TorchStatus status;
296 status_t res = getTorchStatusLocked(cameraId, &status);
297 if (res) {
298 ALOGE("%s: cannot get torch status of camera %s", cameraId.string());
299 return;
300 }
301 if (status == newStatus) {
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800302 ALOGE("%s: Torch state transition to the same status 0x%x not allowed",
303 __FUNCTION__, (uint32_t)newStatus);
304 return;
305 }
306
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800307 res = setTorchStatusLocked(cameraId, newStatus);
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800308 if (res) {
309 ALOGE("%s: Failed to set the torch status", __FUNCTION__,
310 (uint32_t)newStatus);
311 return;
312 }
313
Ruben Brunkcc776712015-02-17 20:18:47 -0800314 {
315 Mutex::Autolock lock(mStatusListenerLock);
316 for (auto& i : mListenerList) {
317 i->onTorchStatusChanged(newStatus, String16{cameraId});
318 }
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800319 }
320}
321
322
Mathias Agopian65ab4712010-07-14 17:59:35 -0700323int32_t CameraService::getNumberOfCameras() {
324 return mNumberOfCameras;
325}
326
327status_t CameraService::getCameraInfo(int cameraId,
328 struct CameraInfo* cameraInfo) {
Iliyan Malchev8951a972011-04-14 16:55:59 -0700329 if (!mModule) {
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700330 return -ENODEV;
Iliyan Malchev8951a972011-04-14 16:55:59 -0700331 }
332
Mathias Agopian65ab4712010-07-14 17:59:35 -0700333 if (cameraId < 0 || cameraId >= mNumberOfCameras) {
334 return BAD_VALUE;
335 }
336
Iliyan Malchev8951a972011-04-14 16:55:59 -0700337 struct camera_info info;
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -0700338 status_t rc = filterGetInfoErrorCode(
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800339 mModule->getCameraInfo(cameraId, &info));
Iliyan Malchev8951a972011-04-14 16:55:59 -0700340 cameraInfo->facing = info.facing;
341 cameraInfo->orientation = info.orientation;
342 return rc;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700343}
344
Ruben Brunkcc776712015-02-17 20:18:47 -0800345int CameraService::cameraIdToInt(const String8& cameraId) {
346 errno = 0;
347 size_t pos = 0;
348 int ret = stoi(std::string{cameraId.string()}, &pos);
349 if (errno != 0 || pos != cameraId.size()) {
350 return -1;
351 }
352 return ret;
353}
Ruben Brunkb2119af2014-05-09 19:57:56 -0700354
355status_t CameraService::generateShimMetadata(int cameraId, /*out*/CameraMetadata* cameraInfo) {
356 status_t ret = OK;
357 struct CameraInfo info;
358 if ((ret = getCameraInfo(cameraId, &info)) != OK) {
359 return ret;
360 }
361
362 CameraMetadata shimInfo;
363 int32_t orientation = static_cast<int32_t>(info.orientation);
364 if ((ret = shimInfo.update(ANDROID_SENSOR_ORIENTATION, &orientation, 1)) != OK) {
365 return ret;
366 }
367
368 uint8_t facing = (info.facing == CAMERA_FACING_FRONT) ?
369 ANDROID_LENS_FACING_FRONT : ANDROID_LENS_FACING_BACK;
370 if ((ret = shimInfo.update(ANDROID_LENS_FACING, &facing, 1)) != OK) {
371 return ret;
372 }
373
Igor Murashkin65d14b92014-06-17 12:03:20 -0700374 CameraParameters shimParams;
375 if ((ret = getLegacyParametersLazy(cameraId, /*out*/&shimParams)) != OK) {
376 // Error logged by callee
377 return ret;
Ruben Brunkb2119af2014-05-09 19:57:56 -0700378 }
379
380 Vector<Size> sizes;
Ruben Brunk152dbcf2014-06-12 19:11:45 -0700381 Vector<Size> jpegSizes;
Ruben Brunkb2119af2014-05-09 19:57:56 -0700382 Vector<int32_t> formats;
383 const char* supportedPreviewFormats;
Igor Murashkin65d14b92014-06-17 12:03:20 -0700384 {
385 shimParams.getSupportedPreviewSizes(/*out*/sizes);
386 shimParams.getSupportedPreviewFormats(/*out*/formats);
387 shimParams.getSupportedPictureSizes(/*out*/jpegSizes);
Ruben Brunkb2119af2014-05-09 19:57:56 -0700388 }
389
390 // Always include IMPLEMENTATION_DEFINED
391 formats.add(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED);
392
393 const size_t INTS_PER_CONFIG = 4;
394
395 // Build available stream configurations metadata
Ruben Brunk152dbcf2014-06-12 19:11:45 -0700396 size_t streamConfigSize = (sizes.size() * formats.size() + jpegSizes.size()) * INTS_PER_CONFIG;
397
398 Vector<int32_t> streamConfigs;
399 streamConfigs.setCapacity(streamConfigSize);
400
Ruben Brunkb2119af2014-05-09 19:57:56 -0700401 for (size_t i = 0; i < formats.size(); ++i) {
402 for (size_t j = 0; j < sizes.size(); ++j) {
Ruben Brunk152dbcf2014-06-12 19:11:45 -0700403 streamConfigs.add(formats[i]);
404 streamConfigs.add(sizes[j].width);
405 streamConfigs.add(sizes[j].height);
406 streamConfigs.add(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
Ruben Brunkb2119af2014-05-09 19:57:56 -0700407 }
408 }
409
Ruben Brunk152dbcf2014-06-12 19:11:45 -0700410 for (size_t i = 0; i < jpegSizes.size(); ++i) {
411 streamConfigs.add(HAL_PIXEL_FORMAT_BLOB);
412 streamConfigs.add(jpegSizes[i].width);
413 streamConfigs.add(jpegSizes[i].height);
414 streamConfigs.add(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
415 }
416
Ruben Brunkb2119af2014-05-09 19:57:56 -0700417 if ((ret = shimInfo.update(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
Ruben Brunk152dbcf2014-06-12 19:11:45 -0700418 streamConfigs.array(), streamConfigSize)) != OK) {
Ruben Brunkb2119af2014-05-09 19:57:56 -0700419 return ret;
420 }
421
422 int64_t fakeMinFrames[0];
423 // TODO: Fixme, don't fake min frame durations.
424 if ((ret = shimInfo.update(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
425 fakeMinFrames, 0)) != OK) {
426 return ret;
427 }
428
429 int64_t fakeStalls[0];
430 // TODO: Fixme, don't fake stall durations.
431 if ((ret = shimInfo.update(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
432 fakeStalls, 0)) != OK) {
433 return ret;
434 }
435
436 *cameraInfo = shimInfo;
437 return OK;
438}
439
Zhijun He2b59be82013-09-25 10:14:30 -0700440status_t CameraService::getCameraCharacteristics(int cameraId,
441 CameraMetadata* cameraInfo) {
442 if (!cameraInfo) {
443 ALOGE("%s: cameraInfo is NULL", __FUNCTION__);
444 return BAD_VALUE;
445 }
446
447 if (!mModule) {
448 ALOGE("%s: camera hardware module doesn't exist", __FUNCTION__);
449 return -ENODEV;
450 }
451
Zhijun He2b59be82013-09-25 10:14:30 -0700452 if (cameraId < 0 || cameraId >= mNumberOfCameras) {
453 ALOGE("%s: Invalid camera id: %d", __FUNCTION__, cameraId);
454 return BAD_VALUE;
455 }
456
457 int facing;
Ruben Brunkb2119af2014-05-09 19:57:56 -0700458 status_t ret = OK;
Chien-Yu Chen676b21b2015-02-24 10:28:19 -0800459 if (mModule->getModuleApiVersion() < CAMERA_MODULE_API_VERSION_2_0 ||
Ruben Brunkb2119af2014-05-09 19:57:56 -0700460 getDeviceVersion(cameraId, &facing) <= CAMERA_DEVICE_API_VERSION_2_1 ) {
461 /**
462 * Backwards compatibility mode for old HALs:
463 * - Convert CameraInfo into static CameraMetadata properties.
464 * - Retrieve cached CameraParameters for this camera. If none exist,
465 * attempt to open CameraClient and retrieve the CameraParameters.
466 * - Convert cached CameraParameters into static CameraMetadata
467 * properties.
468 */
469 ALOGI("%s: Switching to HAL1 shim implementation...", __FUNCTION__);
Zhijun He2b59be82013-09-25 10:14:30 -0700470
Ruben Brunkb2119af2014-05-09 19:57:56 -0700471 if ((ret = generateShimMetadata(cameraId, cameraInfo)) != OK) {
472 return ret;
473 }
Zhijun Hef05e50e2013-10-01 11:05:33 -0700474
Ruben Brunkb2119af2014-05-09 19:57:56 -0700475 } else {
476 /**
477 * Normal HAL 2.1+ codepath.
478 */
479 struct camera_info info;
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800480 ret = filterGetInfoErrorCode(mModule->getCameraInfo(cameraId, &info));
Ruben Brunkb2119af2014-05-09 19:57:56 -0700481 *cameraInfo = info.static_camera_characteristics;
482 }
Zhijun He2b59be82013-09-25 10:14:30 -0700483
484 return ret;
485}
486
Ruben Brunkcc776712015-02-17 20:18:47 -0800487int CameraService::getCallingPid() {
488 return IPCThreadState::self()->getCallingPid();
489}
490
491int CameraService::getCallingUid() {
492 return IPCThreadState::self()->getCallingUid();
493}
494
495String8 CameraService::getFormattedCurrentTime() {
496 time_t now = time(nullptr);
497 char formattedTime[64];
498 strftime(formattedTime, sizeof(formattedTime), "%m-%d %H:%M:%S", localtime(&now));
499 return String8(formattedTime);
500}
501
502int CameraService::getCameraPriorityFromProcState(int procState) {
503 // Find the priority for the camera usage based on the process state. Higher priority clients
504 // win for evictions.
505 // Note: Unlike the ordering for ActivityManager, persistent system processes will always lose
506 // the camera to the top/foreground applications.
507 switch(procState) {
508 case PROCESS_STATE_TOP: // User visible
509 return 100;
510 case PROCESS_STATE_IMPORTANT_FOREGROUND: // Foreground
511 return 90;
512 case PROCESS_STATE_PERSISTENT: // Persistent system services
513 case PROCESS_STATE_PERSISTENT_UI:
514 return 80;
515 case PROCESS_STATE_IMPORTANT_BACKGROUND: // "Important" background processes
516 return 70;
517 case PROCESS_STATE_BACKUP: // Everything else
518 case PROCESS_STATE_HEAVY_WEIGHT:
519 case PROCESS_STATE_SERVICE:
520 case PROCESS_STATE_RECEIVER:
521 case PROCESS_STATE_HOME:
522 case PROCESS_STATE_LAST_ACTIVITY:
523 case PROCESS_STATE_CACHED_ACTIVITY:
524 case PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
525 case PROCESS_STATE_CACHED_EMPTY:
526 return 1;
527 case PROCESS_STATE_NONEXISTENT:
528 return -1;
529 default:
530 ALOGE("%s: Received unknown process state from ActivityManagerService!", __FUNCTION__);
531 return -1;
532 }
533}
534
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800535status_t CameraService::getCameraVendorTagDescriptor(/*out*/sp<VendorTagDescriptor>& desc) {
536 if (!mModule) {
537 ALOGE("%s: camera hardware module doesn't exist", __FUNCTION__);
538 return -ENODEV;
539 }
540
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800541 desc = VendorTagDescriptor::getGlobalVendorTagDescriptor();
542 return OK;
543}
544
Igor Murashkin634a5152013-02-20 17:15:11 -0800545int CameraService::getDeviceVersion(int cameraId, int* facing) {
546 struct camera_info info;
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800547 if (mModule->getCameraInfo(cameraId, &info) != OK) {
Igor Murashkin634a5152013-02-20 17:15:11 -0800548 return -1;
549 }
550
551 int deviceVersion;
Chien-Yu Chen676b21b2015-02-24 10:28:19 -0800552 if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_0) {
Igor Murashkin634a5152013-02-20 17:15:11 -0800553 deviceVersion = info.device_version;
554 } else {
555 deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
556 }
557
558 if (facing) {
559 *facing = info.facing;
560 }
561
562 return deviceVersion;
563}
564
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -0700565status_t CameraService::filterGetInfoErrorCode(status_t err) {
566 switch(err) {
567 case NO_ERROR:
568 case -EINVAL:
569 return err;
570 default:
571 break;
572 }
573 return -ENODEV;
Igor Murashkinbfc99152013-02-27 12:55:20 -0800574}
575
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800576bool CameraService::setUpVendorTags() {
577 vendor_tag_ops_t vOps = vendor_tag_ops_t();
578
579 // Check if vendor operations have been implemented
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800580 if (!mModule->isVendorTagDefined()) {
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800581 ALOGI("%s: No vendor tags defined for this device.", __FUNCTION__);
582 return false;
583 }
584
585 ATRACE_BEGIN("camera3->get_metadata_vendor_tag_ops");
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800586 mModule->getVendorTagOps(&vOps);
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800587 ATRACE_END();
588
589 // Ensure all vendor operations are present
590 if (vOps.get_tag_count == NULL || vOps.get_all_tags == NULL ||
591 vOps.get_section_name == NULL || vOps.get_tag_name == NULL ||
592 vOps.get_tag_type == NULL) {
593 ALOGE("%s: Vendor tag operations not fully defined. Ignoring definitions."
594 , __FUNCTION__);
595 return false;
596 }
597
598 // Read all vendor tag definitions into a descriptor
599 sp<VendorTagDescriptor> desc;
600 status_t res;
601 if ((res = VendorTagDescriptor::createDescriptorFromOps(&vOps, /*out*/desc))
602 != OK) {
603 ALOGE("%s: Could not generate descriptor from vendor tag operations,"
604 "received error %s (%d). Camera clients will not be able to use"
605 "vendor tags", __FUNCTION__, strerror(res), res);
606 return false;
607 }
608
609 // Set the global descriptor to use with camera metadata
610 VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
611 return true;
612}
613
Ruben Brunkcc776712015-02-17 20:18:47 -0800614status_t CameraService::makeClient(const sp<CameraService>& cameraService,
615 const sp<IInterface>& cameraCb, const String16& packageName, const String8& cameraId,
616 int facing, int clientPid, uid_t clientUid, int servicePid, bool legacyMode,
617 int halVersion, int deviceVersion, apiLevel effectiveApiLevel,
618 /*out*/sp<BasicClient>* client) {
619
620 // TODO: Update CameraClients + HAL interface to use strings for Camera IDs
621 int id = cameraIdToInt(cameraId);
622 if (id == -1) {
623 ALOGE("%s: Invalid camera ID %s, cannot convert to integer.", __FUNCTION__,
624 cameraId.string());
625 return BAD_VALUE;
Ruben Brunkb2119af2014-05-09 19:57:56 -0700626 }
627
Ruben Brunkcc776712015-02-17 20:18:47 -0800628 if (halVersion < 0 || halVersion == deviceVersion) {
629 // Default path: HAL version is unspecified by caller, create CameraClient
630 // based on device version reported by the HAL.
631 switch(deviceVersion) {
632 case CAMERA_DEVICE_API_VERSION_1_0:
633 if (effectiveApiLevel == API_1) { // Camera1 API route
634 sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
635 *client = new CameraClient(cameraService, tmp, packageName, id, facing,
636 clientPid, clientUid, getpid(), legacyMode);
637 } else { // Camera2 API route
638 ALOGW("Camera using old HAL version: %d", deviceVersion);
639 return -EOPNOTSUPP;
640 }
641 break;
642 case CAMERA_DEVICE_API_VERSION_2_0:
643 case CAMERA_DEVICE_API_VERSION_2_1:
644 case CAMERA_DEVICE_API_VERSION_3_0:
645 case CAMERA_DEVICE_API_VERSION_3_1:
646 case CAMERA_DEVICE_API_VERSION_3_2:
647 case CAMERA_DEVICE_API_VERSION_3_3:
648 if (effectiveApiLevel == API_1) { // Camera1 API route
649 sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
650 *client = new Camera2Client(cameraService, tmp, packageName, id, facing,
651 clientPid, clientUid, servicePid, legacyMode);
652 } else { // Camera2 API route
653 sp<ICameraDeviceCallbacks> tmp =
654 static_cast<ICameraDeviceCallbacks*>(cameraCb.get());
655 *client = new CameraDeviceClient(cameraService, tmp, packageName, id,
656 facing, clientPid, clientUid, servicePid);
657 }
658 break;
659 default:
660 // Should not be reachable
661 ALOGE("Unknown camera device HAL version: %d", deviceVersion);
662 return INVALID_OPERATION;
663 }
664 } else {
665 // A particular HAL version is requested by caller. Create CameraClient
666 // based on the requested HAL version.
667 if (deviceVersion > CAMERA_DEVICE_API_VERSION_1_0 &&
668 halVersion == CAMERA_DEVICE_API_VERSION_1_0) {
669 // Only support higher HAL version device opened as HAL1.0 device.
670 sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
671 *client = new CameraClient(cameraService, tmp, packageName, id, facing,
672 clientPid, clientUid, servicePid, legacyMode);
673 } else {
674 // Other combinations (e.g. HAL3.x open as HAL2.x) are not supported yet.
675 ALOGE("Invalid camera HAL version %x: HAL %x device can only be"
676 " opened as HAL %x device", halVersion, deviceVersion,
677 CAMERA_DEVICE_API_VERSION_1_0);
678 return INVALID_OPERATION;
679 }
680 }
681 return NO_ERROR;
682}
683
684status_t CameraService::initializeShimMetadata(int cameraId) {
685 int uid = getCallingUid();
Ruben Brunkb2119af2014-05-09 19:57:56 -0700686
687 String16 internalPackageName("media");
Ruben Brunkcc776712015-02-17 20:18:47 -0800688 String8 id = String8::format("%d", cameraId);
689 status_t ret = NO_ERROR;
690 sp<Client> tmp = nullptr;
691 if ((ret = connectHelper<ICameraClient,Client>(sp<ICameraClient>{nullptr}, id,
692 static_cast<int>(CAMERA_HAL_API_VERSION_UNSPECIFIED), internalPackageName, uid, API_1,
693 false, true, tmp)) != NO_ERROR) {
694 ALOGE("%s: Error %d (%s) initializing shim metadata.", __FUNCTION__, ret, strerror(ret));
695 return ret;
Ruben Brunkb2119af2014-05-09 19:57:56 -0700696 }
Ruben Brunkcc776712015-02-17 20:18:47 -0800697 return NO_ERROR;
Ruben Brunkb2119af2014-05-09 19:57:56 -0700698}
699
Igor Murashkin65d14b92014-06-17 12:03:20 -0700700status_t CameraService::getLegacyParametersLazy(int cameraId,
701 /*out*/
702 CameraParameters* parameters) {
703
704 ALOGV("%s: for cameraId: %d", __FUNCTION__, cameraId);
705
706 status_t ret = 0;
707
708 if (parameters == NULL) {
709 ALOGE("%s: parameters must not be null", __FUNCTION__);
710 return BAD_VALUE;
711 }
712
Ruben Brunkcc776712015-02-17 20:18:47 -0800713 String8 id = String8::format("%d", cameraId);
714
715 // Check if we already have parameters
716 {
717 // Scope for service lock
Igor Murashkin65d14b92014-06-17 12:03:20 -0700718 Mutex::Autolock lock(mServiceLock);
Ruben Brunkcc776712015-02-17 20:18:47 -0800719 auto cameraState = getCameraState(id);
720 if (cameraState == nullptr) {
721 ALOGE("%s: Invalid camera ID: %s", __FUNCTION__, id.string());
722 return BAD_VALUE;
723 }
724 CameraParameters p = cameraState->getShimParams();
725 if (!p.isEmpty()) {
726 *parameters = p;
727 return NO_ERROR;
Igor Murashkin65d14b92014-06-17 12:03:20 -0700728 }
729 }
730
Ruben Brunkcc776712015-02-17 20:18:47 -0800731 int64_t token = IPCThreadState::self()->clearCallingIdentity();
732 ret = initializeShimMetadata(cameraId);
733 IPCThreadState::self()->restoreCallingIdentity(token);
734 if (ret != NO_ERROR) {
735 // Error already logged by callee
736 return ret;
737 }
738
739 // Check for parameters again
740 {
741 // Scope for service lock
742 Mutex::Autolock lock(mServiceLock);
743 auto cameraState = getCameraState(id);
744 if (cameraState == nullptr) {
745 ALOGE("%s: Invalid camera ID: %s", __FUNCTION__, id.string());
746 return BAD_VALUE;
Igor Murashkin65d14b92014-06-17 12:03:20 -0700747 }
Ruben Brunkcc776712015-02-17 20:18:47 -0800748 CameraParameters p = cameraState->getShimParams();
749 if (!p.isEmpty()) {
750 *parameters = p;
751 return NO_ERROR;
Igor Murashkin65d14b92014-06-17 12:03:20 -0700752 }
753 }
754
Ruben Brunkcc776712015-02-17 20:18:47 -0800755 ALOGE("%s: Parameters were not initialized, or were empty. Device may not be present.",
756 __FUNCTION__);
757 return INVALID_OPERATION;
Igor Murashkin65d14b92014-06-17 12:03:20 -0700758}
759
Ruben Brunkcc776712015-02-17 20:18:47 -0800760status_t CameraService::validateConnect(const String8& cameraId, /*inout*/int& clientUid) const {
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800761
Mathias Agopian65ab4712010-07-14 17:59:35 -0700762 int callingPid = getCallingPid();
Tyler Luu5861a9a2011-10-06 00:00:03 -0500763
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800764 if (clientUid == USE_CALLING_UID) {
765 clientUid = getCallingUid();
766 } else {
767 // We only trust our own process to forward client UIDs
768 if (callingPid != getpid()) {
Ruben Brunkcc776712015-02-17 20:18:47 -0800769 ALOGE("CameraService::connect X (PID %d) rejected (don't trust clientUid)",
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800770 callingPid);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700771 return PERMISSION_DENIED;
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800772 }
773 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700774
Iliyan Malchev8951a972011-04-14 16:55:59 -0700775 if (!mModule) {
Ruben Brunkcc776712015-02-17 20:18:47 -0800776 ALOGE("CameraService::connect X (PID %d) rejected (camera HAL module not loaded)",
777 callingPid);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700778 return -ENODEV;
Iliyan Malchev8951a972011-04-14 16:55:59 -0700779 }
780
Ruben Brunkcc776712015-02-17 20:18:47 -0800781 if (getCameraState(cameraId) == nullptr) {
782 ALOGE("CameraService::connect X (PID %d) rejected (invalid camera ID %s)", callingPid,
783 cameraId.string());
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700784 return -ENODEV;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700785 }
786
Ruben Brunkcc776712015-02-17 20:18:47 -0800787 // Check device policy for this camera
Wu-cheng Lia3355432011-05-20 14:54:25 +0800788 char value[PROPERTY_VALUE_MAX];
Amith Yamasani228711d2015-02-13 13:25:39 -0800789 char key[PROPERTY_KEY_MAX];
790 int clientUserId = multiuser_get_user_id(clientUid);
791 snprintf(key, PROPERTY_KEY_MAX, "sys.secpolicy.camera.off_%d", clientUserId);
792 property_get(key, value, "0");
Wu-cheng Lia3355432011-05-20 14:54:25 +0800793 if (strcmp(value, "1") == 0) {
794 // Camera is disabled by DevicePolicyManager.
Ruben Brunkcc776712015-02-17 20:18:47 -0800795 ALOGE("CameraService::connect X (PID %d) rejected (camera %s is disabled by device "
796 "policy)", callingPid, cameraId.string());
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700797 return -EACCES;
Wu-cheng Lia3355432011-05-20 14:54:25 +0800798 }
799
Ruben Brunkcc776712015-02-17 20:18:47 -0800800 return checkIfDeviceIsUsable(cameraId);
801}
802
803status_t CameraService::checkIfDeviceIsUsable(const String8& cameraId) const {
804 auto cameraState = getCameraState(cameraId);
805 int callingPid = getCallingPid();
806 if (cameraState == nullptr) {
807 ALOGE("CameraService::connect X (PID %d) rejected (invalid camera ID %s)", callingPid,
808 cameraId.string());
809 return -ENODEV;
810 }
811
812 ICameraServiceListener::Status currentStatus = cameraState->getStatus();
Igor Murashkincba2c162013-03-20 15:56:31 -0700813 if (currentStatus == ICameraServiceListener::STATUS_NOT_PRESENT) {
Ruben Brunkcc776712015-02-17 20:18:47 -0800814 ALOGE("CameraService::connect X (PID %d) rejected (camera %s is not connected)",
815 callingPid, cameraId.string());
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700816 return -ENODEV;
Igor Murashkincba2c162013-03-20 15:56:31 -0700817 } else if (currentStatus == ICameraServiceListener::STATUS_ENUMERATING) {
Ruben Brunkcc776712015-02-17 20:18:47 -0800818 ALOGE("CameraService::connect X (PID %d) rejected, (camera %s is initializing)",
819 callingPid, cameraId.string());
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700820 return -EBUSY;
Igor Murashkincba2c162013-03-20 15:56:31 -0700821 }
Igor Murashkincba2c162013-03-20 15:56:31 -0700822
Ruben Brunkcc776712015-02-17 20:18:47 -0800823 return NO_ERROR;
Igor Murashkine6800ce2013-03-04 17:25:57 -0800824}
825
Ruben Brunkcc776712015-02-17 20:18:47 -0800826void CameraService::finishConnectLocked(const sp<BasicClient>& client,
827 const CameraService::DescriptorPtr& desc) {
Igor Murashkine6800ce2013-03-04 17:25:57 -0800828
Ruben Brunkcc776712015-02-17 20:18:47 -0800829 // Make a descriptor for the incoming client
830 auto clientDescriptor = CameraService::CameraClientManager::makeClientDescriptor(client, desc);
831 auto evicted = mActiveClientManager.addAndEvict(clientDescriptor);
832
833 logConnected(desc->getKey(), static_cast<int>(desc->getOwnerId()),
834 String8(client->getPackageName()));
835
836 if (evicted.size() > 0) {
837 // This should never happen - clients should already have been removed in disconnect
838 for (auto& i : evicted) {
839 ALOGE("%s: Invalid state: Client for camera %s was not removed in disconnect",
840 __FUNCTION__, i->getKey().string());
841 }
842
843 LOG_ALWAYS_FATAL("%s: Invalid state for CameraService, clients not evicted properly",
844 __FUNCTION__);
845 }
846}
847
848status_t CameraService::handleEvictionsLocked(const String8& cameraId, int clientPid,
849 apiLevel effectiveApiLevel, const sp<IBinder>& remoteCallback, const String8& packageName,
850 /*out*/
851 sp<BasicClient>* client,
852 std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>* partial) {
853
854 status_t ret = NO_ERROR;
855 std::vector<sp<BasicClient>> evictedClients;
856 DescriptorPtr clientDescriptor;
857 {
858 if (effectiveApiLevel == API_1) {
859 // If we are using API1, any existing client for this camera ID with the same remote
860 // should be returned rather than evicted to allow MediaRecorder to work properly.
861
862 auto current = mActiveClientManager.get(cameraId);
863 if (current != nullptr) {
864 auto clientSp = current->getValue();
865 if (clientSp.get() != nullptr) { // should never be needed
866 if (clientSp->getRemote() == remoteCallback) {
867 ALOGI("CameraService::connect X (PID %d) (second call from same"
868 "app binder, returning the same client)", clientPid);
869 *client = clientSp;
870 return NO_ERROR;
871 }
872 }
Wu-cheng Li2fd24402012-02-23 19:01:00 -0800873 }
Wu-cheng Li2fd24402012-02-23 19:01:00 -0800874 }
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800875
Ruben Brunkcc776712015-02-17 20:18:47 -0800876 // Return error if the device was unplugged or removed by the HAL for some reason
877 if ((ret = checkIfDeviceIsUsable(cameraId)) != NO_ERROR) {
878 return ret;
879 }
Igor Murashkin634a5152013-02-20 17:15:11 -0800880
Ruben Brunkcc776712015-02-17 20:18:47 -0800881 // Get current active client PIDs
882 std::vector<int> ownerPids(mActiveClientManager.getAllOwners());
883 ownerPids.push_back(clientPid);
Igor Murashkine6800ce2013-03-04 17:25:57 -0800884
Chih-Hung Hsieh54b42462015-03-19 12:04:54 -0700885 // Use the value +PROCESS_STATE_NONEXISTENT, to avoid taking
886 // address of PROCESS_STATE_NONEXISTENT as a reference argument
887 // for the vector constructor. PROCESS_STATE_NONEXISTENT does
888 // not have an out-of-class definition.
889 std::vector<int> priorities(ownerPids.size(), +PROCESS_STATE_NONEXISTENT);
Igor Murashkine6800ce2013-03-04 17:25:57 -0800890
Ruben Brunkcc776712015-02-17 20:18:47 -0800891 // Get priorites of all active PIDs
892 ProcessInfoService::getProcessStatesFromPids(ownerPids.size(), &ownerPids[0],
893 /*out*/&priorities[0]);
Ruben Brunkb2119af2014-05-09 19:57:56 -0700894
Ruben Brunkcc776712015-02-17 20:18:47 -0800895 // Update all active clients' priorities
896 std::map<int,int> pidToPriorityMap;
897 for (size_t i = 0; i < ownerPids.size() - 1; i++) {
898 pidToPriorityMap.emplace(ownerPids[i], getCameraPriorityFromProcState(priorities[i]));
899 }
900 mActiveClientManager.updatePriorities(pidToPriorityMap);
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800901
Ruben Brunkcc776712015-02-17 20:18:47 -0800902 // Get state for the given cameraId
903 auto state = getCameraState(cameraId);
904 if (state == nullptr) {
905 ALOGE("CameraService::connect X (PID %d) rejected (no camera device with ID %s)",
906 clientPid, cameraId.string());
Zhijun Heb10cdad2014-06-16 16:38:35 -0700907 return BAD_VALUE;
Zhijun Heb10cdad2014-06-16 16:38:35 -0700908 }
Ruben Brunkcc776712015-02-17 20:18:47 -0800909
910 // Make descriptor for incoming client
911 clientDescriptor = CameraClientManager::makeClientDescriptor(cameraId,
912 sp<BasicClient>{nullptr}, static_cast<int32_t>(state->getCost()),
913 state->getConflicting(),
914 getCameraPriorityFromProcState(priorities[priorities.size() - 1]), clientPid);
915
916 // Find clients that would be evicted
917 auto evicted = mActiveClientManager.wouldEvict(clientDescriptor);
918
919 // If the incoming client was 'evicted,' higher priority clients have the camera in the
920 // background, so we cannot do evictions
921 if (std::find(evicted.begin(), evicted.end(), clientDescriptor) != evicted.end()) {
922 ALOGE("CameraService::connect X (PID %d) rejected (existing client(s) with higher"
923 " priority).", clientPid);
924
925 sp<BasicClient> clientSp = clientDescriptor->getValue();
926 String8 curTime = getFormattedCurrentTime();
927 auto incompatibleClients =
928 mActiveClientManager.getIncompatibleClients(clientDescriptor);
929
930 String8 msg = String8::format("%s : DENIED connect device %s client for package %s "
931 "(PID %d, priority %d)", curTime.string(),
932 cameraId.string(), packageName.string(), clientPid,
933 getCameraPriorityFromProcState(priorities[priorities.size() - 1]));
934
935 for (auto& i : incompatibleClients) {
936 msg.appendFormat("\n - Blocked by existing device %s client for package %s"
937 "(PID %" PRId32 ", priority %" PRId32 ")", i->getKey().string(),
938 String8{i->getValue()->getPackageName()}.string(), i->getOwnerId(),
939 i->getPriority());
940 }
941
942 // Log the client's attempt
943 mEventLog.add(msg);
944
945 return -EBUSY;
946 }
947
948 for (auto& i : evicted) {
949 sp<BasicClient> clientSp = i->getValue();
950 if (clientSp.get() == nullptr) {
951 ALOGE("%s: Invalid state: Null client in active client list.", __FUNCTION__);
952
953 // TODO: Remove this
954 LOG_ALWAYS_FATAL("%s: Invalid state for CameraService, null client in active list",
955 __FUNCTION__);
956 mActiveClientManager.remove(i);
957 continue;
958 }
959
960 ALOGE("CameraService::connect evicting conflicting client for camera ID %s",
961 i->getKey().string());
962 evictedClients.push_back(clientSp);
963
964 String8 curTime = getFormattedCurrentTime();
965
966 // Log the clients evicted
967 mEventLog.add(String8::format("%s : EVICT device %s client for package %s (PID %"
968 PRId32 ", priority %" PRId32 ")\n - Evicted by device %s client for "
969 "package %s (PID %d, priority %" PRId32 ")", curTime.string(),
970 i->getKey().string(), String8{clientSp->getPackageName()}.string(),
971 i->getOwnerId(), i->getPriority(), cameraId.string(),
972 packageName.string(), clientPid,
973 getCameraPriorityFromProcState(priorities[priorities.size() - 1])));
974
975 // Notify the client of disconnection
976 clientSp->notifyError(ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED,
977 CaptureResultExtras());
Zhijun Heb10cdad2014-06-16 16:38:35 -0700978 }
Ruben Brunkb2119af2014-05-09 19:57:56 -0700979 }
980
Ruben Brunkcc776712015-02-17 20:18:47 -0800981 // Do not hold mServiceLock while disconnecting clients, but retain the condition blocking
982 // other clients from connecting in mServiceLockWrapper if held
983 mServiceLock.unlock();
984
985 // Clear caller identity temporarily so client disconnect PID checks work correctly
986 int64_t token = IPCThreadState::self()->clearCallingIdentity();
987
988 // Destroy evicted clients
989 for (auto& i : evictedClients) {
990 // Disconnect is blocking, and should only have returned when HAL has cleaned up
991 i->disconnect(); // Clients will remove themselves from the active client list here
992 }
993 evictedClients.clear();
994
995 IPCThreadState::self()->restoreCallingIdentity(token);
996
997 // Once clients have been disconnected, relock
998 mServiceLock.lock();
999
1000 // Check again if the device was unplugged or something while we weren't holding mServiceLock
1001 if ((ret = checkIfDeviceIsUsable(cameraId)) != NO_ERROR) {
1002 return ret;
Ruben Brunkb2119af2014-05-09 19:57:56 -07001003 }
1004
Ruben Brunkcc776712015-02-17 20:18:47 -08001005 *partial = clientDescriptor;
1006 return NO_ERROR;
Ruben Brunkb2119af2014-05-09 19:57:56 -07001007}
1008
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001009status_t CameraService::connect(
Igor Murashkine6800ce2013-03-04 17:25:57 -08001010 const sp<ICameraClient>& cameraClient,
1011 int cameraId,
1012 const String16& clientPackageName,
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001013 int clientUid,
1014 /*out*/
1015 sp<ICamera>& device) {
Igor Murashkine6800ce2013-03-04 17:25:57 -08001016
Ruben Brunkcc776712015-02-17 20:18:47 -08001017 status_t ret = NO_ERROR;
1018 String8 id = String8::format("%d", cameraId);
1019 sp<Client> client = nullptr;
1020 ret = connectHelper<ICameraClient,Client>(cameraClient, id, CAMERA_HAL_API_VERSION_UNSPECIFIED,
1021 clientPackageName, clientUid, API_1, false, false, /*out*/client);
Igor Murashkine6800ce2013-03-04 17:25:57 -08001022
Ruben Brunkcc776712015-02-17 20:18:47 -08001023 if(ret != NO_ERROR) {
1024 return ret;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001025 }
1026
Ruben Brunk0f61d8f2013-08-08 13:07:18 -07001027 device = client;
Ruben Brunkcc776712015-02-17 20:18:47 -08001028 return NO_ERROR;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001029}
1030
Zhijun Heb10cdad2014-06-16 16:38:35 -07001031status_t CameraService::connectLegacy(
1032 const sp<ICameraClient>& cameraClient,
1033 int cameraId, int halVersion,
1034 const String16& clientPackageName,
1035 int clientUid,
1036 /*out*/
1037 sp<ICamera>& device) {
1038
Chien-Yu Chen676b21b2015-02-24 10:28:19 -08001039 int apiVersion = mModule->getModuleApiVersion();
Igor Murashkin3d07d1a2014-06-20 11:27:03 -07001040 if (halVersion != CAMERA_HAL_API_VERSION_UNSPECIFIED &&
Yin-Chia Yehe074a932015-01-30 10:29:02 -08001041 apiVersion < CAMERA_MODULE_API_VERSION_2_3) {
Igor Murashkin3d07d1a2014-06-20 11:27:03 -07001042 /*
1043 * Either the HAL version is unspecified in which case this just creates
1044 * a camera client selected by the latest device version, or
1045 * it's a particular version in which case the HAL must supported
1046 * the open_legacy call
1047 */
Zhijun Heb10cdad2014-06-16 16:38:35 -07001048 ALOGE("%s: camera HAL module version %x doesn't support connecting to legacy HAL devices!",
Yin-Chia Yehe074a932015-01-30 10:29:02 -08001049 __FUNCTION__, apiVersion);
Zhijun Heb10cdad2014-06-16 16:38:35 -07001050 return INVALID_OPERATION;
1051 }
1052
Ruben Brunkcc776712015-02-17 20:18:47 -08001053 status_t ret = NO_ERROR;
1054 String8 id = String8::format("%d", cameraId);
1055 sp<Client> client = nullptr;
1056 ret = connectHelper<ICameraClient,Client>(cameraClient, id, halVersion, clientPackageName,
1057 clientUid, API_1, true, false, /*out*/client);
Zhijun Heb10cdad2014-06-16 16:38:35 -07001058
Ruben Brunkcc776712015-02-17 20:18:47 -08001059 if(ret != NO_ERROR) {
1060 return ret;
Zhijun Heb10cdad2014-06-16 16:38:35 -07001061 }
1062
Zhijun Heb10cdad2014-06-16 16:38:35 -07001063 device = client;
Ruben Brunkcc776712015-02-17 20:18:47 -08001064 return NO_ERROR;
Zhijun Heb10cdad2014-06-16 16:38:35 -07001065}
1066
Ruben Brunkcc776712015-02-17 20:18:47 -08001067status_t CameraService::connectDevice(
1068 const sp<ICameraDeviceCallbacks>& cameraCb,
1069 int cameraId,
1070 const String16& clientPackageName,
1071 int clientUid,
1072 /*out*/
1073 sp<ICameraDeviceUser>& device) {
1074
1075 status_t ret = NO_ERROR;
1076 String8 id = String8::format("%d", cameraId);
1077 sp<CameraDeviceClient> client = nullptr;
1078 ret = connectHelper<ICameraDeviceCallbacks,CameraDeviceClient>(cameraCb, id,
1079 CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageName, clientUid, API_2, false, false,
1080 /*out*/client);
1081
1082 if(ret != NO_ERROR) {
1083 return ret;
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001084 }
1085
Ruben Brunkcc776712015-02-17 20:18:47 -08001086 device = client;
1087 return NO_ERROR;
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001088}
1089
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001090status_t CameraService::setTorchMode(const String16& cameraId, bool enabled,
1091 const sp<IBinder>& clientBinder) {
1092 if (enabled && clientBinder == NULL) {
1093 ALOGE("%s: torch client binder is NULL", __FUNCTION__);
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001094 return -EINVAL;
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001095 }
1096
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001097 String8 id = String8(cameraId.string());
1098
1099 // verify id is valid.
Ruben Brunkcc776712015-02-17 20:18:47 -08001100 auto state = getCameraState(id);
1101 if (state == nullptr) {
1102 ALOGE("%s: camera id is invalid %s", id.string());
1103 return -EINVAL;
1104 }
1105
1106 ICameraServiceListener::Status cameraStatus = state->getStatus();
1107 if (cameraStatus != ICameraServiceListener::STATUS_PRESENT &&
1108 cameraStatus != ICameraServiceListener::STATUS_NOT_AVAILABLE) {
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001109 ALOGE("%s: camera id is invalid %s", id.string());
1110 return -EINVAL;
1111 }
1112
1113 {
1114 Mutex::Autolock al(mTorchStatusMutex);
1115 ICameraServiceListener::TorchStatus status;
1116 status_t res = getTorchStatusLocked(id, &status);
1117 if (res) {
1118 ALOGE("%s: getting current torch status failed for camera %s",
1119 __FUNCTION__, id.string());
1120 return -EINVAL;
1121 }
1122
1123 if (status == ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE) {
Ruben Brunkcc776712015-02-17 20:18:47 -08001124 if (cameraStatus == ICameraServiceListener::STATUS_NOT_AVAILABLE) {
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001125 ALOGE("%s: torch mode of camera %s is not available because "
1126 "camera is in use", __FUNCTION__, id.string());
1127 return -EBUSY;
1128 } else {
1129 ALOGE("%s: torch mode of camera %s is not available due to "
1130 "insufficient resources", __FUNCTION__, id.string());
1131 return -EUSERS;
1132 }
1133 }
1134 }
1135
1136 status_t res = mFlashlight->setTorchMode(id, enabled);
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001137 if (res) {
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001138 ALOGE("%s: setting torch mode of camera %s to %d failed. %s (%d)",
1139 __FUNCTION__, id.string(), enabled, strerror(-res), res);
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001140 return res;
1141 }
1142
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001143 {
1144 // update the link to client's death
1145 Mutex::Autolock al(mTorchClientMapMutex);
1146 ssize_t index = mTorchClientMap.indexOfKey(id);
1147 if (enabled) {
1148 if (index == NAME_NOT_FOUND) {
1149 mTorchClientMap.add(id, clientBinder);
1150 } else {
1151 const sp<IBinder> oldBinder = mTorchClientMap.valueAt(index);
1152 oldBinder->unlinkToDeath(this);
1153
1154 mTorchClientMap.replaceValueAt(index, clientBinder);
1155 }
1156 clientBinder->linkToDeath(this);
1157 } else if (index != NAME_NOT_FOUND) {
1158 sp<IBinder> oldBinder = mTorchClientMap.valueAt(index);
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001159 oldBinder->unlinkToDeath(this);
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001160 }
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001161 }
1162
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001163 return OK;
1164}
1165
Igor Murashkinbfc99152013-02-27 12:55:20 -08001166status_t CameraService::addListener(
1167 const sp<ICameraServiceListener>& listener) {
1168 ALOGV("%s: Add listener %p", __FUNCTION__, listener.get());
Igor Murashkin634a5152013-02-20 17:15:11 -08001169
Igor Murashkinbd3e2e02014-03-17 13:01:41 -07001170 if (listener == 0) {
1171 ALOGE("%s: Listener must not be null", __FUNCTION__);
1172 return BAD_VALUE;
1173 }
1174
Igor Murashkinbfc99152013-02-27 12:55:20 -08001175 Mutex::Autolock lock(mServiceLock);
1176
Ruben Brunkcc776712015-02-17 20:18:47 -08001177 {
1178 Mutex::Autolock lock(mStatusListenerLock);
1179 for (auto& it : mListenerList) {
1180 if (IInterface::asBinder(it) == IInterface::asBinder(listener)) {
1181 ALOGW("%s: Tried to add listener %p which was already subscribed",
1182 __FUNCTION__, listener.get());
1183 return ALREADY_EXISTS;
1184 }
Igor Murashkinbfc99152013-02-27 12:55:20 -08001185 }
Ruben Brunkcc776712015-02-17 20:18:47 -08001186
1187 mListenerList.push_back(listener);
Igor Murashkinbfc99152013-02-27 12:55:20 -08001188 }
1189
Igor Murashkinbfc99152013-02-27 12:55:20 -08001190
Igor Murashkincba2c162013-03-20 15:56:31 -07001191 /* Immediately signal current status to this listener only */
1192 {
Ruben Brunkcc776712015-02-17 20:18:47 -08001193 Mutex::Autolock lock(mCameraStatesLock);
1194 for (auto& i : mCameraStates) {
1195 // TODO: Update binder to use String16 for camera IDs and remove;
1196 int id = cameraIdToInt(i.first);
1197 if (id == -1) continue;
1198
1199 listener->onStatusChanged(i.second->getStatus(), id);
Igor Murashkincba2c162013-03-20 15:56:31 -07001200 }
1201 }
1202
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001203 /* Immediately signal current torch status to this listener only */
1204 {
1205 Mutex::Autolock al(mTorchStatusMutex);
1206 for (size_t i = 0; i < mTorchStatusMap.size(); i++ ) {
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001207 String16 id = String16(mTorchStatusMap.keyAt(i).string());
1208 listener->onTorchStatusChanged(mTorchStatusMap.valueAt(i), id);
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001209 }
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001210 }
1211
Igor Murashkinbfc99152013-02-27 12:55:20 -08001212 return OK;
1213}
Ruben Brunkcc776712015-02-17 20:18:47 -08001214
1215status_t CameraService::removeListener(const sp<ICameraServiceListener>& listener) {
Igor Murashkinbfc99152013-02-27 12:55:20 -08001216 ALOGV("%s: Remove listener %p", __FUNCTION__, listener.get());
1217
Igor Murashkinbd3e2e02014-03-17 13:01:41 -07001218 if (listener == 0) {
1219 ALOGE("%s: Listener must not be null", __FUNCTION__);
1220 return BAD_VALUE;
1221 }
1222
Igor Murashkinbfc99152013-02-27 12:55:20 -08001223 Mutex::Autolock lock(mServiceLock);
1224
Ruben Brunkcc776712015-02-17 20:18:47 -08001225 {
1226 Mutex::Autolock lock(mStatusListenerLock);
1227 for (auto it = mListenerList.begin(); it != mListenerList.end(); it++) {
1228 if (IInterface::asBinder(*it) == IInterface::asBinder(listener)) {
1229 mListenerList.erase(it);
1230 return OK;
1231 }
Igor Murashkinbfc99152013-02-27 12:55:20 -08001232 }
1233 }
1234
1235 ALOGW("%s: Tried to remove a listener %p which was not subscribed",
1236 __FUNCTION__, listener.get());
1237
1238 return BAD_VALUE;
Igor Murashkin634a5152013-02-20 17:15:11 -08001239}
1240
Ruben Brunkcc776712015-02-17 20:18:47 -08001241status_t CameraService::getLegacyParameters(int cameraId, /*out*/String16* parameters) {
Igor Murashkin65d14b92014-06-17 12:03:20 -07001242 ALOGV("%s: for camera ID = %d", __FUNCTION__, cameraId);
1243
1244 if (parameters == NULL) {
1245 ALOGE("%s: parameters must not be null", __FUNCTION__);
1246 return BAD_VALUE;
1247 }
1248
1249 status_t ret = 0;
1250
1251 CameraParameters shimParams;
1252 if ((ret = getLegacyParametersLazy(cameraId, /*out*/&shimParams)) != OK) {
1253 // Error logged by caller
1254 return ret;
1255 }
1256
1257 String8 shimParamsString8 = shimParams.flatten();
1258 String16 shimParamsString16 = String16(shimParamsString8);
1259
1260 *parameters = shimParamsString16;
1261
1262 return OK;
1263}
1264
1265status_t CameraService::supportsCameraApi(int cameraId, int apiVersion) {
1266 ALOGV("%s: for camera ID = %d", __FUNCTION__, cameraId);
1267
1268 switch (apiVersion) {
1269 case API_VERSION_1:
1270 case API_VERSION_2:
1271 break;
1272 default:
1273 ALOGE("%s: Bad API version %d", __FUNCTION__, apiVersion);
1274 return BAD_VALUE;
1275 }
1276
1277 int facing = -1;
1278 int deviceVersion = getDeviceVersion(cameraId, &facing);
1279
1280 switch(deviceVersion) {
1281 case CAMERA_DEVICE_API_VERSION_1_0:
1282 case CAMERA_DEVICE_API_VERSION_2_0:
1283 case CAMERA_DEVICE_API_VERSION_2_1:
1284 case CAMERA_DEVICE_API_VERSION_3_0:
1285 case CAMERA_DEVICE_API_VERSION_3_1:
1286 if (apiVersion == API_VERSION_2) {
1287 ALOGV("%s: Camera id %d uses HAL prior to HAL3.2, doesn't support api2 without shim",
1288 __FUNCTION__, cameraId);
1289 return -EOPNOTSUPP;
1290 } else { // if (apiVersion == API_VERSION_1) {
1291 ALOGV("%s: Camera id %d uses older HAL before 3.2, but api1 is always supported",
1292 __FUNCTION__, cameraId);
1293 return OK;
1294 }
1295 case CAMERA_DEVICE_API_VERSION_3_2:
Ruben Brunkcc776712015-02-17 20:18:47 -08001296 case CAMERA_DEVICE_API_VERSION_3_3:
Igor Murashkin65d14b92014-06-17 12:03:20 -07001297 ALOGV("%s: Camera id %d uses HAL3.2 or newer, supports api1/api2 directly",
1298 __FUNCTION__, cameraId);
1299 return OK;
1300 case -1:
1301 ALOGE("%s: Invalid camera id %d", __FUNCTION__, cameraId);
1302 return BAD_VALUE;
1303 default:
1304 ALOGE("%s: Unknown camera device HAL version: %d", __FUNCTION__, deviceVersion);
1305 return INVALID_OPERATION;
1306 }
1307
1308 return OK;
1309}
1310
Ruben Brunkcc776712015-02-17 20:18:47 -08001311void CameraService::removeByClient(const BasicClient* client) {
Igor Murashkinecf17e82012-10-02 16:05:11 -07001312 Mutex::Autolock lock(mServiceLock);
Ruben Brunkcc776712015-02-17 20:18:47 -08001313 for (auto& i : mActiveClientManager.getAll()) {
1314 auto clientSp = i->getValue();
1315 if (clientSp.get() == client) {
1316 mActiveClientManager.remove(i);
Igor Murashkin634a5152013-02-20 17:15:11 -08001317 }
Igor Murashkinecf17e82012-10-02 16:05:11 -07001318 }
Igor Murashkin634a5152013-02-20 17:15:11 -08001319}
1320
Ruben Brunkcc776712015-02-17 20:18:47 -08001321bool CameraService::evictClientIdByRemote(const wp<IBinder>& remote) {
1322 const int callingPid = getCallingPid();
1323 const int servicePid = getpid();
1324 bool ret = false;
1325 {
1326 // Acquire mServiceLock and prevent other clients from connecting
1327 std::unique_ptr<AutoConditionLock> lock =
1328 AutoConditionLock::waitAndAcquire(mServiceLockWrapper);
Igor Murashkin634a5152013-02-20 17:15:11 -08001329
Igor Murashkin634a5152013-02-20 17:15:11 -08001330
Ruben Brunkcc776712015-02-17 20:18:47 -08001331 std::vector<sp<BasicClient>> evicted;
1332 for (auto& i : mActiveClientManager.getAll()) {
1333 auto clientSp = i->getValue();
1334 if (clientSp.get() == nullptr) {
1335 ALOGE("%s: Dead client still in mActiveClientManager.", __FUNCTION__);
1336 mActiveClientManager.remove(i);
1337 continue;
1338 }
1339 if (remote == clientSp->getRemote() && (callingPid == servicePid ||
1340 callingPid == clientSp->getClientPid())) {
1341 mActiveClientManager.remove(i);
1342 evicted.push_back(clientSp);
Igor Murashkin634a5152013-02-20 17:15:11 -08001343
Ruben Brunkcc776712015-02-17 20:18:47 -08001344 // Notify the client of disconnection
1345 clientSp->notifyError(ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED,
1346 CaptureResultExtras());
Igor Murashkin634a5152013-02-20 17:15:11 -08001347 }
1348 }
1349
Ruben Brunkcc776712015-02-17 20:18:47 -08001350 // Do not hold mServiceLock while disconnecting clients, but retain the condition blocking
1351 // other clients from connecting in mServiceLockWrapper if held
1352 mServiceLock.unlock();
1353
1354 for (auto& i : evicted) {
1355 if (i.get() != nullptr) {
1356 i->disconnect();
1357 ret = true;
1358 }
Igor Murashkin634a5152013-02-20 17:15:11 -08001359 }
1360
Ruben Brunkcc776712015-02-17 20:18:47 -08001361 // Reacquire mServiceLock
1362 mServiceLock.lock();
Igor Murashkin634a5152013-02-20 17:15:11 -08001363
Ruben Brunkcc776712015-02-17 20:18:47 -08001364 } // lock is destroyed, allow further connect calls
1365
1366 return ret;
Igor Murashkinecf17e82012-10-02 16:05:11 -07001367}
1368
Igor Murashkinecf17e82012-10-02 16:05:11 -07001369
Ruben Brunkcc776712015-02-17 20:18:47 -08001370std::shared_ptr<CameraService::CameraState> CameraService::getCameraState(
1371 const String8& cameraId) const {
1372 std::shared_ptr<CameraState> state;
1373 {
1374 Mutex::Autolock lock(mCameraStatesLock);
1375 auto iter = mCameraStates.find(cameraId);
1376 if (iter != mCameraStates.end()) {
1377 state = iter->second;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001378 }
1379 }
Ruben Brunkcc776712015-02-17 20:18:47 -08001380 return state;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001381}
1382
Ruben Brunkcc776712015-02-17 20:18:47 -08001383sp<CameraService::BasicClient> CameraService::removeClientLocked(const String8& cameraId) {
1384 // Remove from active clients list
1385 auto clientDescriptorPtr = mActiveClientManager.remove(cameraId);
1386 if (clientDescriptorPtr == nullptr) {
1387 ALOGW("%s: Could not evict client, no client for camera ID %s", __FUNCTION__,
1388 cameraId.string());
1389 return sp<BasicClient>{nullptr};
1390 }
1391
1392 return clientDescriptorPtr->getValue();
Keun young Parkd8973a72012-03-28 14:13:09 -07001393}
1394
Ruben Brunkcc776712015-02-17 20:18:47 -08001395
1396void CameraService::logDisconnected(const String8& cameraId, int clientPid,
1397 const String8& clientPackage) {
1398
1399 String8 curTime = getFormattedCurrentTime();
1400 // Log the clients evicted
1401 mEventLog.add(String8::format("%s : DISCONNECT device %s client for package %s (PID %d)",
1402 curTime.string(), cameraId.string(), clientPackage.string(), clientPid));
Mathias Agopian65ab4712010-07-14 17:59:35 -07001403}
1404
Ruben Brunkcc776712015-02-17 20:18:47 -08001405void CameraService::logConnected(const String8& cameraId, int clientPid,
1406 const String8& clientPackage) {
Igor Murashkinecf17e82012-10-02 16:05:11 -07001407
Ruben Brunkcc776712015-02-17 20:18:47 -08001408 String8 curTime = getFormattedCurrentTime();
1409 // Log the clients evicted
1410 mEventLog.add(String8::format("%s : CONNECT device %s client for package %s (PID %d)",
1411 curTime.string(), cameraId.string(), clientPackage.string(), clientPid));
Igor Murashkinecf17e82012-10-02 16:05:11 -07001412}
1413
Mathias Agopian65ab4712010-07-14 17:59:35 -07001414status_t CameraService::onTransact(
1415 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
1416 // Permission checks
1417 switch (code) {
1418 case BnCameraService::CONNECT:
Eino-Ville Talvala63d877f2014-06-16 19:21:12 -07001419 case BnCameraService::CONNECT_DEVICE:
Zhijun Heb10cdad2014-06-16 16:38:35 -07001420 case BnCameraService::CONNECT_LEGACY:
Mathias Agopian65ab4712010-07-14 17:59:35 -07001421 const int pid = getCallingPid();
1422 const int self_pid = getpid();
1423 if (pid != self_pid) {
1424 // we're called from a different process, do the real check
1425 if (!checkCallingPermission(
1426 String16("android.permission.CAMERA"))) {
1427 const int uid = getCallingUid();
Steve Block29357bc2012-01-06 19:20:56 +00001428 ALOGE("Permission Denial: "
Mathias Agopian65ab4712010-07-14 17:59:35 -07001429 "can't use the camera pid=%d, uid=%d", pid, uid);
1430 return PERMISSION_DENIED;
1431 }
1432 }
1433 break;
1434 }
1435
1436 return BnCameraService::onTransact(code, data, reply, flags);
1437}
1438
Mathias Agopian65ab4712010-07-14 17:59:35 -07001439// We share the media players for shutter and recording sound for all clients.
1440// A reference count is kept to determine when we will actually release the
1441// media players.
1442
Chih-Chung Changff4f55c2011-10-17 19:03:12 +08001443MediaPlayer* CameraService::newMediaPlayer(const char *file) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001444 MediaPlayer* mp = new MediaPlayer();
Andreas Huber1b86fe02014-01-29 11:13:26 -08001445 if (mp->setDataSource(NULL /* httpService */, file, NULL) == NO_ERROR) {
Eino-Ville Talvala60a78ac2012-01-05 15:34:53 -08001446 mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001447 mp->prepare();
1448 } else {
Steve Block29357bc2012-01-06 19:20:56 +00001449 ALOGE("Failed to load CameraService sounds: %s", file);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001450 return NULL;
1451 }
1452 return mp;
1453}
1454
1455void CameraService::loadSound() {
1456 Mutex::Autolock lock(mSoundLock);
1457 LOG1("CameraService::loadSound ref=%d", mSoundRef);
1458 if (mSoundRef++) return;
1459
1460 mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
1461 mSoundPlayer[SOUND_RECORDING] = newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");
1462}
1463
1464void CameraService::releaseSound() {
1465 Mutex::Autolock lock(mSoundLock);
1466 LOG1("CameraService::releaseSound ref=%d", mSoundRef);
1467 if (--mSoundRef) return;
1468
1469 for (int i = 0; i < NUM_SOUNDS; i++) {
1470 if (mSoundPlayer[i] != 0) {
1471 mSoundPlayer[i]->disconnect();
1472 mSoundPlayer[i].clear();
1473 }
1474 }
1475}
1476
1477void CameraService::playSound(sound_kind kind) {
1478 LOG1("playSound(%d)", kind);
1479 Mutex::Autolock lock(mSoundLock);
1480 sp<MediaPlayer> player = mSoundPlayer[kind];
1481 if (player != 0) {
Chih-Chung Chang8888a752011-10-20 10:47:26 +08001482 player->seekTo(0);
1483 player->start();
Mathias Agopian65ab4712010-07-14 17:59:35 -07001484 }
1485}
1486
1487// ----------------------------------------------------------------------------
1488
1489CameraService::Client::Client(const sp<CameraService>& cameraService,
Wu-cheng Lib7a67942010-08-17 15:45:37 -07001490 const sp<ICameraClient>& cameraClient,
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001491 const String16& clientPackageName,
1492 int cameraId, int cameraFacing,
1493 int clientPid, uid_t clientUid,
1494 int servicePid) :
Eino-Ville Talvalae992e752014-11-07 16:17:48 -08001495 CameraService::BasicClient(cameraService,
Marco Nelissenf8880202014-11-14 07:58:25 -08001496 IInterface::asBinder(cameraClient),
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001497 clientPackageName,
1498 cameraId, cameraFacing,
1499 clientPid, clientUid,
1500 servicePid)
Igor Murashkin634a5152013-02-20 17:15:11 -08001501{
Mathias Agopian65ab4712010-07-14 17:59:35 -07001502 int callingPid = getCallingPid();
Wu-cheng Li2fd24402012-02-23 19:01:00 -08001503 LOG1("Client::Client E (pid %d, id %d)", callingPid, cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001504
Igor Murashkin44cfcf02013-03-01 16:22:28 -08001505 mRemoteCallback = cameraClient;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001506
Mathias Agopian65ab4712010-07-14 17:59:35 -07001507 cameraService->loadSound();
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001508
Wu-cheng Li2fd24402012-02-23 19:01:00 -08001509 LOG1("Client::Client X (pid %d, id %d)", callingPid, cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001510}
1511
Mathias Agopian65ab4712010-07-14 17:59:35 -07001512// tear down the client
1513CameraService::Client::~Client() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -07001514 ALOGV("~Client");
Igor Murashkin634a5152013-02-20 17:15:11 -08001515 mDestructionStarted = true;
1516
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001517 mCameraService->releaseSound();
Igor Murashkin036bc3e2012-10-08 15:09:46 -07001518 // unconditionally disconnect. function is idempotent
1519 Client::disconnect();
Mathias Agopian65ab4712010-07-14 17:59:35 -07001520}
1521
Igor Murashkin634a5152013-02-20 17:15:11 -08001522CameraService::BasicClient::BasicClient(const sp<CameraService>& cameraService,
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001523 const sp<IBinder>& remoteCallback,
1524 const String16& clientPackageName,
1525 int cameraId, int cameraFacing,
1526 int clientPid, uid_t clientUid,
1527 int servicePid):
Ruben Brunkcc776712015-02-17 20:18:47 -08001528 mClientPackageName(clientPackageName), mDisconnected(false)
Igor Murashkin634a5152013-02-20 17:15:11 -08001529{
1530 mCameraService = cameraService;
Igor Murashkin44cfcf02013-03-01 16:22:28 -08001531 mRemoteBinder = remoteCallback;
Igor Murashkin634a5152013-02-20 17:15:11 -08001532 mCameraId = cameraId;
1533 mCameraFacing = cameraFacing;
1534 mClientPid = clientPid;
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001535 mClientUid = clientUid;
Igor Murashkin634a5152013-02-20 17:15:11 -08001536 mServicePid = servicePid;
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001537 mOpsActive = false;
Igor Murashkin634a5152013-02-20 17:15:11 -08001538 mDestructionStarted = false;
1539}
1540
1541CameraService::BasicClient::~BasicClient() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -07001542 ALOGV("~BasicClient");
Igor Murashkin634a5152013-02-20 17:15:11 -08001543 mDestructionStarted = true;
1544}
1545
1546void CameraService::BasicClient::disconnect() {
Ruben Brunkcc776712015-02-17 20:18:47 -08001547 if (mDisconnected) return;
1548 mDisconnected = true;;
1549
1550 mCameraService->removeByClient(this);
1551 mCameraService->logDisconnected(String8::format("%d", mCameraId), mClientPid,
1552 String8(mClientPackageName));
1553
1554 sp<IBinder> remote = getRemote();
1555 if (remote != nullptr) {
1556 remote->unlinkToDeath(mCameraService);
1557 }
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001558
1559 finishCameraOps();
Ruben Brunkcc776712015-02-17 20:18:47 -08001560 ALOGI("%s: Disconnected client for camera %d for PID %d", __FUNCTION__, mCameraId, mClientPid);
1561
Igor Murashkincba2c162013-03-20 15:56:31 -07001562 // client shouldn't be able to call into us anymore
1563 mClientPid = 0;
Igor Murashkin634a5152013-02-20 17:15:11 -08001564}
1565
Ruben Brunkcc776712015-02-17 20:18:47 -08001566String16 CameraService::BasicClient::getPackageName() const {
1567 return mClientPackageName;
1568}
1569
1570
1571int CameraService::BasicClient::getClientPid() const {
1572 return mClientPid;
1573}
1574
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001575status_t CameraService::BasicClient::startCameraOps() {
1576 int32_t res;
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001577 // Notify app ops that the camera is not available
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001578 mOpsCallback = new OpsCallback(this);
1579
Igor Murashkine6800ce2013-03-04 17:25:57 -08001580 {
1581 ALOGV("%s: Start camera ops, package name = %s, client UID = %d",
1582 __FUNCTION__, String8(mClientPackageName).string(), mClientUid);
1583 }
1584
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001585 mAppOpsManager.startWatchingMode(AppOpsManager::OP_CAMERA,
1586 mClientPackageName, mOpsCallback);
1587 res = mAppOpsManager.startOp(AppOpsManager::OP_CAMERA,
1588 mClientUid, mClientPackageName);
1589
1590 if (res != AppOpsManager::MODE_ALLOWED) {
1591 ALOGI("Camera %d: Access for \"%s\" has been revoked",
1592 mCameraId, String8(mClientPackageName).string());
1593 return PERMISSION_DENIED;
1594 }
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001595
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001596 mOpsActive = true;
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001597
1598 // Transition device availability listeners from PRESENT -> NOT_AVAILABLE
1599 mCameraService->updateStatus(ICameraServiceListener::STATUS_NOT_AVAILABLE,
Ruben Brunkcc776712015-02-17 20:18:47 -08001600 String8::format("%d", mCameraId));
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001601
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001602 return OK;
1603}
1604
1605status_t CameraService::BasicClient::finishCameraOps() {
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001606 // Check if startCameraOps succeeded, and if so, finish the camera op
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001607 if (mOpsActive) {
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001608 // Notify app ops that the camera is available again
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001609 mAppOpsManager.finishOp(AppOpsManager::OP_CAMERA, mClientUid,
1610 mClientPackageName);
1611 mOpsActive = false;
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001612
Ruben Brunkcc776712015-02-17 20:18:47 -08001613 auto rejected = {ICameraServiceListener::STATUS_NOT_PRESENT,
1614 ICameraServiceListener::STATUS_ENUMERATING};
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001615
Ruben Brunkcc776712015-02-17 20:18:47 -08001616 // Transition to PRESENT if the camera is not in either of the rejected states
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001617 mCameraService->updateStatus(ICameraServiceListener::STATUS_PRESENT,
Ruben Brunkcc776712015-02-17 20:18:47 -08001618 String8::format("%d", mCameraId), rejected);
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001619
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001620 // Notify flashlight that a camera device is closed.
1621 mCameraService->mFlashlight->deviceClosed(
1622 String8::format("%d", mCameraId));
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001623 }
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -07001624 // Always stop watching, even if no camera op is active
Eino-Ville Talvalae992e752014-11-07 16:17:48 -08001625 if (mOpsCallback != NULL) {
1626 mAppOpsManager.stopWatchingMode(mOpsCallback);
1627 }
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001628 mOpsCallback.clear();
1629
1630 return OK;
1631}
1632
1633void CameraService::BasicClient::opChanged(int32_t op, const String16& packageName) {
1634 String8 name(packageName);
1635 String8 myName(mClientPackageName);
1636
1637 if (op != AppOpsManager::OP_CAMERA) {
1638 ALOGW("Unexpected app ops notification received: %d", op);
1639 return;
1640 }
1641
1642 int32_t res;
1643 res = mAppOpsManager.checkOp(AppOpsManager::OP_CAMERA,
1644 mClientUid, mClientPackageName);
1645 ALOGV("checkOp returns: %d, %s ", res,
1646 res == AppOpsManager::MODE_ALLOWED ? "ALLOWED" :
1647 res == AppOpsManager::MODE_IGNORED ? "IGNORED" :
1648 res == AppOpsManager::MODE_ERRORED ? "ERRORED" :
1649 "UNKNOWN");
1650
1651 if (res != AppOpsManager::MODE_ALLOWED) {
1652 ALOGI("Camera %d: Access for \"%s\" revoked", mCameraId,
1653 myName.string());
1654 // Reset the client PID to allow server-initiated disconnect,
1655 // and to prevent further calls by client.
1656 mClientPid = getCallingPid();
Jianing Weicb0652e2014-03-12 18:29:36 -07001657 CaptureResultExtras resultExtras; // a dummy result (invalid)
1658 notifyError(ICameraDeviceCallbacks::ERROR_CAMERA_SERVICE, resultExtras);
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001659 disconnect();
1660 }
1661}
1662
Mathias Agopian65ab4712010-07-14 17:59:35 -07001663// ----------------------------------------------------------------------------
1664
Ruben Brunkcc776712015-02-17 20:18:47 -08001665// Provide client strong pointer for callbacks.
1666sp<CameraService::Client> CameraService::Client::getClientFromCookie(void* user) {
1667 String8 cameraId = String8::format("%d", (int)(intptr_t) user);
1668 auto clientDescriptor = gCameraService->mActiveClientManager.get(cameraId);
1669 if (clientDescriptor != nullptr) {
1670 return sp<Client>{
1671 static_cast<Client*>(clientDescriptor->getValue().get())};
1672 }
1673 return sp<Client>{nullptr};
Mathias Agopian65ab4712010-07-14 17:59:35 -07001674}
1675
Jianing Weicb0652e2014-03-12 18:29:36 -07001676void CameraService::Client::notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode,
1677 const CaptureResultExtras& resultExtras) {
Igor Murashkin44cfcf02013-03-01 16:22:28 -08001678 mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_RELEASED, 0);
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001679}
1680
Igor Murashkin036bc3e2012-10-08 15:09:46 -07001681// NOTE: function is idempotent
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001682void CameraService::Client::disconnect() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -07001683 ALOGV("Client::disconnect");
Igor Murashkin634a5152013-02-20 17:15:11 -08001684 BasicClient::disconnect();
Wu-cheng Lie09591e2010-10-14 20:17:44 +08001685}
1686
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001687CameraService::Client::OpsCallback::OpsCallback(wp<BasicClient> client):
1688 mClient(client) {
1689}
1690
1691void CameraService::Client::OpsCallback::opChanged(int32_t op,
1692 const String16& packageName) {
1693 sp<BasicClient> client = mClient.promote();
1694 if (client != NULL) {
1695 client->opChanged(op, packageName);
1696 }
1697}
1698
Mathias Agopian65ab4712010-07-14 17:59:35 -07001699// ----------------------------------------------------------------------------
Ruben Brunkcc776712015-02-17 20:18:47 -08001700// CameraState
1701// ----------------------------------------------------------------------------
1702
1703CameraService::CameraState::CameraState(const String8& id, int cost,
1704 const std::set<String8>& conflicting) : mId(id),
1705 mStatus(ICameraServiceListener::STATUS_PRESENT), mCost(cost), mConflicting(conflicting) {}
1706
1707CameraService::CameraState::~CameraState() {}
1708
1709ICameraServiceListener::Status CameraService::CameraState::getStatus() const {
1710 Mutex::Autolock lock(mStatusLock);
1711 return mStatus;
1712}
1713
1714CameraParameters CameraService::CameraState::getShimParams() const {
1715 return mShimParams;
1716}
1717
1718void CameraService::CameraState::setShimParams(const CameraParameters& params) {
1719 mShimParams = params;
1720}
1721
1722int CameraService::CameraState::getCost() const {
1723 return mCost;
1724}
1725
1726std::set<String8> CameraService::CameraState::getConflicting() const {
1727 return mConflicting;
1728}
1729
1730String8 CameraService::CameraState::getId() const {
1731 return mId;
1732}
1733
1734// ----------------------------------------------------------------------------
1735// CameraClientManager
1736// ----------------------------------------------------------------------------
1737
1738CameraService::CameraClientManager::~CameraClientManager() {}
1739
1740sp<CameraService::BasicClient> CameraService::CameraClientManager::getCameraClient(
1741 const String8& id) const {
1742 auto descriptor = get(id);
1743 if (descriptor == nullptr) {
1744 return sp<BasicClient>{nullptr};
1745 }
1746 return descriptor->getValue();
1747}
1748
1749String8 CameraService::CameraClientManager::toString() const {
1750 auto all = getAll();
1751 String8 ret("[");
1752 bool hasAny = false;
1753 for (auto& i : all) {
1754 hasAny = true;
1755 String8 key = i->getKey();
1756 int32_t cost = i->getCost();
1757 int32_t pid = i->getOwnerId();
1758 int32_t priority = i->getPriority();
1759 auto conflicting = i->getConflicting();
1760 auto clientSp = i->getValue();
1761 String8 packageName;
1762 if (clientSp.get() != nullptr) {
1763 packageName = String8{clientSp->getPackageName()};
1764 }
1765 ret.appendFormat("\n(Camera ID: %s, Cost: %" PRId32 ", PID: %" PRId32 ", Priority: %"
1766 PRId32 ", ", key.string(), cost, pid, priority);
1767
1768 if (packageName.size() != 0) {
1769 ret.appendFormat("Client Package Name: %s", packageName.string());
1770 }
1771
1772 ret.append(", Conflicting Client Devices: {");
1773 for (auto& j : conflicting) {
1774 ret.appendFormat("%s, ", j.string());
1775 }
1776 ret.append("})");
1777 }
1778 if (hasAny) ret.append("\n");
1779 ret.append("]\n");
1780 return ret;
1781}
1782
1783CameraService::DescriptorPtr CameraService::CameraClientManager::makeClientDescriptor(
1784 const String8& key, const sp<BasicClient>& value, int32_t cost,
1785 const std::set<String8>& conflictingKeys, int32_t priority, int32_t ownerId) {
1786
1787 return std::make_shared<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>(
1788 key, value, cost, conflictingKeys, priority, ownerId);
1789}
1790
1791CameraService::DescriptorPtr CameraService::CameraClientManager::makeClientDescriptor(
1792 const sp<BasicClient>& value, const CameraService::DescriptorPtr& partial) {
1793 return makeClientDescriptor(partial->getKey(), value, partial->getCost(),
1794 partial->getConflicting(), partial->getPriority(), partial->getOwnerId());
1795}
1796
1797// ----------------------------------------------------------------------------
Mathias Agopian65ab4712010-07-14 17:59:35 -07001798
1799static const int kDumpLockRetries = 50;
1800static const int kDumpLockSleep = 60000;
1801
1802static bool tryLock(Mutex& mutex)
1803{
1804 bool locked = false;
1805 for (int i = 0; i < kDumpLockRetries; ++i) {
1806 if (mutex.tryLock() == NO_ERROR) {
1807 locked = true;
1808 break;
1809 }
1810 usleep(kDumpLockSleep);
1811 }
1812 return locked;
1813}
1814
1815status_t CameraService::dump(int fd, const Vector<String16>& args) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001816 String8 result;
1817 if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -07001818 result.appendFormat("Permission Denial: "
Mathias Agopian65ab4712010-07-14 17:59:35 -07001819 "can't dump CameraService from pid=%d, uid=%d\n",
1820 getCallingPid(),
1821 getCallingUid());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001822 write(fd, result.string(), result.size());
1823 } else {
1824 bool locked = tryLock(mServiceLock);
1825 // failed to lock - CameraService is probably deadlocked
1826 if (!locked) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -07001827 result.append("CameraService may be deadlocked\n");
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001828 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001829 }
1830
1831 bool hasClient = false;
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001832 if (!mModule) {
1833 result = String8::format("No camera module available!\n");
1834 write(fd, result.string(), result.size());
Kalle Lampila6ec3a152013-04-30 15:27:19 +03001835 if (locked) mServiceLock.unlock();
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001836 return NO_ERROR;
1837 }
1838
Chien-Yu Chen676b21b2015-02-24 10:28:19 -08001839 result = String8::format("Camera module HAL API version: 0x%x\n", mModule->getHalApiVersion());
1840 result.appendFormat("Camera module API version: 0x%x\n", mModule->getModuleApiVersion());
1841 result.appendFormat("Camera module name: %s\n", mModule->getModuleName());
1842 result.appendFormat("Camera module author: %s\n", mModule->getModuleAuthor());
Ruben Brunkcc776712015-02-17 20:18:47 -08001843 result.appendFormat("Number of camera devices: %d\n", mNumberOfCameras);
1844 String8 activeClientString = mActiveClientManager.toString();
1845 result.appendFormat("Active Camera Clients:\n%s", activeClientString.string());
1846
Ruben Brunkf81648e2014-04-17 16:14:57 -07001847 sp<VendorTagDescriptor> desc = VendorTagDescriptor::getGlobalVendorTagDescriptor();
1848 if (desc == NULL) {
1849 result.appendFormat("Vendor tags left unimplemented.\n");
1850 } else {
1851 result.appendFormat("Vendor tag definitions:\n");
1852 }
1853
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001854 write(fd, result.string(), result.size());
Ruben Brunkf81648e2014-04-17 16:14:57 -07001855
1856 if (desc != NULL) {
1857 desc->dump(fd, /*verbosity*/2, /*indentation*/4);
1858 }
1859
Ruben Brunkcc776712015-02-17 20:18:47 -08001860 result = String8("Prior client events (most recent at top):\n");
1861
1862 for (const auto& msg : mEventLog) {
1863 result.appendFormat("%s\n", msg.string());
1864 }
1865
1866 if (mEventLog.size() == DEFAULT_EVICTION_LOG_LENGTH) {
1867 result.append("...\n");
1868 }
1869
1870 write(fd, result.string(), result.size());
1871
1872 bool stateLocked = tryLock(mCameraStatesLock);
1873 if (!stateLocked) {
1874 result = String8::format("CameraStates in use, may be deadlocked\n");
1875 write(fd, result.string(), result.size());
1876 }
1877
1878 for (auto& state : mCameraStates) {
1879 String8 cameraId = state.first;
1880 result = String8::format("Camera %s information:\n", cameraId.string());
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001881 camera_info info;
1882
Ruben Brunkcc776712015-02-17 20:18:47 -08001883 // TODO: Change getCameraInfo + HAL to use String cameraIds
1884 status_t rc = mModule->getCameraInfo(cameraIdToInt(cameraId), &info);
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001885 if (rc != OK) {
1886 result.appendFormat(" Error reading static information!\n");
1887 write(fd, result.string(), result.size());
1888 } else {
1889 result.appendFormat(" Facing: %s\n",
1890 info.facing == CAMERA_FACING_BACK ? "BACK" : "FRONT");
1891 result.appendFormat(" Orientation: %d\n", info.orientation);
1892 int deviceVersion;
Chien-Yu Chen676b21b2015-02-24 10:28:19 -08001893 if (mModule->getModuleApiVersion() < CAMERA_MODULE_API_VERSION_2_0) {
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001894 deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
1895 } else {
1896 deviceVersion = info.device_version;
1897 }
Ruben Brunkcc776712015-02-17 20:18:47 -08001898
1899 auto conflicting = state.second->getConflicting();
1900 result.appendFormat(" Resource Cost: %d\n", state.second->getCost());
1901 result.appendFormat(" Conflicting Devices:");
1902 for (auto& id : conflicting) {
1903 result.appendFormat(" %s", cameraId.string());
1904 }
1905 if (conflicting.size() == 0) {
1906 result.appendFormat(" NONE");
1907 }
1908 result.appendFormat("\n");
1909
1910 result.appendFormat(" Device version: %#x\n", deviceVersion);
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001911 if (deviceVersion >= CAMERA_DEVICE_API_VERSION_2_0) {
1912 result.appendFormat(" Device static metadata:\n");
1913 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -07001914 dump_indented_camera_metadata(info.static_camera_characteristics,
Ruben Brunkf81648e2014-04-17 16:14:57 -07001915 fd, /*verbosity*/2, /*indentation*/4);
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001916 } else {
1917 write(fd, result.string(), result.size());
1918 }
Ruben Brunkcc776712015-02-17 20:18:47 -08001919
1920 CameraParameters p = state.second->getShimParams();
1921 if (!p.isEmpty()) {
1922 result = String8::format(" Camera1 API shim is using parameters:\n ");
1923 write(fd, result.string(), result.size());
1924 p.dump(fd, args);
1925 }
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001926 }
1927
Ruben Brunkcc776712015-02-17 20:18:47 -08001928 auto clientDescriptor = mActiveClientManager.get(cameraId);
1929 if (clientDescriptor == nullptr) {
1930 result = String8::format(" Device %s is closed, no client instance\n",
1931 cameraId.string());
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001932 write(fd, result.string(), result.size());
1933 continue;
1934 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001935 hasClient = true;
Ruben Brunkcc776712015-02-17 20:18:47 -08001936 result = String8::format(" Device %s is open. Client instance dump:\n\n",
1937 cameraId.string());
1938 result.appendFormat("Client priority level: %d\n", clientDescriptor->getPriority());
1939 result.appendFormat("Client PID: %d\n", clientDescriptor->getOwnerId());
1940
1941 auto client = clientDescriptor->getValue();
1942 result.appendFormat("Client package: %s\n",
1943 String8(client->getPackageName()).string());
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001944 write(fd, result.string(), result.size());
Ruben Brunkcc776712015-02-17 20:18:47 -08001945
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001946 client->dump(fd, args);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001947 }
Ruben Brunkcc776712015-02-17 20:18:47 -08001948
1949 if (stateLocked) mCameraStatesLock.unlock();
1950
Mathias Agopian65ab4712010-07-14 17:59:35 -07001951 if (!hasClient) {
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001952 result = String8::format("\nNo active camera clients yet.\n");
1953 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001954 }
1955
1956 if (locked) mServiceLock.unlock();
1957
Igor Murashkinff3e31d2013-10-23 16:40:06 -07001958 // Dump camera traces if there were any
1959 write(fd, "\n", 1);
1960 camera3::CameraTraces::dump(fd, args);
1961
Mathias Agopian65ab4712010-07-14 17:59:35 -07001962 // change logging level
1963 int n = args.size();
1964 for (int i = 0; i + 1 < n; i++) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -07001965 String16 verboseOption("-v");
1966 if (args[i] == verboseOption) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001967 String8 levelStr(args[i+1]);
1968 int level = atoi(levelStr.string());
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001969 result = String8::format("\nSetting log level to %d.\n", level);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001970 setLogLevel(level);
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001971 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001972 }
1973 }
1974 }
1975 return NO_ERROR;
1976}
1977
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001978void CameraService::handleTorchClientBinderDied(const wp<IBinder> &who) {
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001979 Mutex::Autolock al(mTorchClientMapMutex);
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001980 for (size_t i = 0; i < mTorchClientMap.size(); i++) {
1981 if (mTorchClientMap[i] == who) {
1982 // turn off the torch mode that was turned on by dead client
Chien-Yu Chen88da5262015-02-17 13:56:46 -08001983 String8 cameraId = mTorchClientMap.keyAt(i);
1984 status_t res = mFlashlight->setTorchMode(cameraId, false);
1985 if (res) {
1986 ALOGE("%s: torch client died but couldn't turn off torch: "
1987 "%s (%d)", __FUNCTION__, strerror(-res), res);
1988 return;
1989 }
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001990 mTorchClientMap.removeItemsAt(i);
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001991 break;
1992 }
1993 }
1994}
1995
Ruben Brunkcc776712015-02-17 20:18:47 -08001996/*virtual*/void CameraService::binderDied(const wp<IBinder> &who) {
Igor Murashkinecf17e82012-10-02 16:05:11 -07001997
Igor Murashkin294d0ec2012-10-05 10:44:57 -07001998 /**
1999 * While tempting to promote the wp<IBinder> into a sp,
2000 * it's actually not supported by the binder driver
2001 */
2002
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002003 // check torch client
2004 handleTorchClientBinderDied(who);
2005
2006 // check camera device client
Ruben Brunkcc776712015-02-17 20:18:47 -08002007 if(!evictClientIdByRemote(who)) {
2008 ALOGV("%s: Java client's binder death already cleaned up (normal case)", __FUNCTION__);
Igor Murashkinecf17e82012-10-02 16:05:11 -07002009 return;
2010 }
2011
Ruben Brunkcc776712015-02-17 20:18:47 -08002012 ALOGE("%s: Java client's binder died, removing it from the list of active clients",
2013 __FUNCTION__);
Igor Murashkinecf17e82012-10-02 16:05:11 -07002014}
2015
Ruben Brunkcc776712015-02-17 20:18:47 -08002016void CameraService::updateStatus(ICameraServiceListener::Status status, const String8& cameraId) {
2017 updateStatus(status, cameraId, {});
Igor Murashkinbfc99152013-02-27 12:55:20 -08002018}
2019
Ruben Brunkcc776712015-02-17 20:18:47 -08002020void CameraService::updateStatus(ICameraServiceListener::Status status, const String8& cameraId,
2021 std::initializer_list<ICameraServiceListener::Status> rejectSourceStates) {
2022 // Do not lock mServiceLock here or can get into a deadlock from
2023 // connect() -> disconnect -> updateStatus
2024
2025 auto state = getCameraState(cameraId);
2026
2027 if (state == nullptr) {
2028 ALOGW("%s: Could not update the status for %s, no such device exists", __FUNCTION__,
2029 cameraId.string());
2030 return;
Igor Murashkincba2c162013-03-20 15:56:31 -07002031 }
2032
Ruben Brunkcc776712015-02-17 20:18:47 -08002033 // Update the status for this camera state, then send the onStatusChangedCallbacks to each
2034 // of the listeners with both the mStatusStatus and mStatusListenerLock held
2035 state->updateStatus(status, cameraId, rejectSourceStates, [this]
2036 (const String8& cameraId, ICameraServiceListener::Status status) {
2037
2038 // Update torch status
2039 if (status == ICameraServiceListener::STATUS_NOT_PRESENT ||
2040 status == ICameraServiceListener::STATUS_NOT_AVAILABLE) {
2041 // Update torch status to not available when the camera device becomes not present
2042 // or not available.
2043 onTorchStatusChanged(cameraId, ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE);
2044 } else if (status == ICameraServiceListener::STATUS_PRESENT) {
2045 // Update torch status to available when the camera device becomes present or
2046 // available
2047 onTorchStatusChanged(cameraId, ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF);
2048 }
2049
2050 Mutex::Autolock lock(mStatusListenerLock);
2051
2052 for (auto& listener : mListenerList) {
2053 // TODO: Refactor status listeners to use strings for Camera IDs and remove this.
2054 int id = cameraIdToInt(cameraId);
2055 if (id != -1) listener->onStatusChanged(status, id);
2056 }
2057 });
Igor Murashkincba2c162013-03-20 15:56:31 -07002058}
2059
Chien-Yu Chen88da5262015-02-17 13:56:46 -08002060status_t CameraService::getTorchStatusLocked(
2061 const String8& cameraId,
2062 ICameraServiceListener::TorchStatus *status) const {
2063 if (!status) {
2064 return BAD_VALUE;
2065 }
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002066 ssize_t index = mTorchStatusMap.indexOfKey(cameraId);
2067 if (index == NAME_NOT_FOUND) {
Chien-Yu Chen88da5262015-02-17 13:56:46 -08002068 // invalid camera ID or the camera doesn't have a flash unit
2069 return NAME_NOT_FOUND;
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002070 }
2071
Chien-Yu Chen88da5262015-02-17 13:56:46 -08002072 *status = mTorchStatusMap.valueAt(index);
2073 return OK;
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002074}
2075
Chien-Yu Chen88da5262015-02-17 13:56:46 -08002076status_t CameraService::setTorchStatusLocked(const String8& cameraId,
Chien-Yu Chen3068d732015-02-09 13:29:57 -08002077 ICameraServiceListener::TorchStatus status) {
2078 ssize_t index = mTorchStatusMap.indexOfKey(cameraId);
2079 if (index == NAME_NOT_FOUND) {
2080 return BAD_VALUE;
2081 }
2082 ICameraServiceListener::TorchStatus& item =
2083 mTorchStatusMap.editValueAt(index);
2084 item = status;
2085
2086 return OK;
2087}
2088
Mathias Agopian65ab4712010-07-14 17:59:35 -07002089}; // namespace android