blob: 79fbf76311f012a0e20536d75dad44be3c761e31 [file] [log] [blame]
Mathias Agopian65ab4712010-07-14 17:59:35 -07001/*
2**
3** Copyright (C) 2008, The Android Open Source Project
Mathias Agopian65ab4712010-07-14 17:59:35 -07004**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9** http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17
18#define LOG_TAG "CameraService"
Iliyan Malchev8951a972011-04-14 16:55:59 -070019//#define LOG_NDEBUG 0
Mathias Agopian65ab4712010-07-14 17:59:35 -070020
21#include <stdio.h>
22#include <sys/types.h>
23#include <pthread.h>
24
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -080025#include <binder/AppOpsManager.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070026#include <binder/IPCThreadState.h>
27#include <binder/IServiceManager.h>
28#include <binder/MemoryBase.h>
29#include <binder/MemoryHeapBase.h>
30#include <cutils/atomic.h>
Nipun Kwatrab5ca4612010-09-11 19:31:10 -070031#include <cutils/properties.h>
Mathias Agopiandf712ea2012-02-25 18:48:35 -080032#include <gui/Surface.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070033#include <hardware/hardware.h>
34#include <media/AudioSystem.h>
Andreas Huber1b86fe02014-01-29 11:13:26 -080035#include <media/IMediaHTTPService.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070036#include <media/mediaplayer.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070037#include <utils/Errors.h>
38#include <utils/Log.h>
39#include <utils/String16.h>
40
41#include "CameraService.h"
Eino-Ville Talvala7b82efe2013-07-25 17:12:35 -070042#include "api1/CameraClient.h"
43#include "api1/Camera2Client.h"
44#include "api_pro/ProCamera2Client.h"
45#include "api2/CameraDeviceClient.h"
Igor Murashkinff3e31d2013-10-23 16:40:06 -070046#include "utils/CameraTraces.h"
Igor Murashkin98e24722013-06-19 19:51:04 -070047#include "CameraDeviceFactory.h"
Mathias Agopian65ab4712010-07-14 17:59:35 -070048
49namespace android {
50
51// ----------------------------------------------------------------------------
52// Logging support -- this is for debugging only
53// Use "adb shell dumpsys media.camera -v 1" to change it.
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -070054volatile int32_t gLogLevel = 0;
Mathias Agopian65ab4712010-07-14 17:59:35 -070055
Steve Blockb8a80522011-12-20 16:23:08 +000056#define LOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__);
57#define LOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__);
Mathias Agopian65ab4712010-07-14 17:59:35 -070058
59static void setLogLevel(int level) {
60 android_atomic_write(level, &gLogLevel);
61}
62
63// ----------------------------------------------------------------------------
64
65static int getCallingPid() {
66 return IPCThreadState::self()->getCallingPid();
67}
68
69static int getCallingUid() {
70 return IPCThreadState::self()->getCallingUid();
71}
72
Igor Murashkincba2c162013-03-20 15:56:31 -070073extern "C" {
74static void camera_device_status_change(
75 const struct camera_module_callbacks* callbacks,
76 int camera_id,
77 int new_status) {
78 sp<CameraService> cs = const_cast<CameraService*>(
79 static_cast<const CameraService*>(callbacks));
80
81 cs->onDeviceStatusChanged(
82 camera_id,
83 new_status);
84}
85} // extern "C"
86
Mathias Agopian65ab4712010-07-14 17:59:35 -070087// ----------------------------------------------------------------------------
88
89// This is ugly and only safe if we never re-create the CameraService, but
90// should be ok for now.
91static CameraService *gCameraService;
92
93CameraService::CameraService()
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -080094 :mSoundRef(0), mModule(0)
Mathias Agopian65ab4712010-07-14 17:59:35 -070095{
Steve Blockdf64d152012-01-04 20:05:49 +000096 ALOGI("CameraService started (pid=%d)", getpid());
Mathias Agopian65ab4712010-07-14 17:59:35 -070097 gCameraService = this;
Igor Murashkinbfc99152013-02-27 12:55:20 -080098
99 for (size_t i = 0; i < MAX_CAMERAS; ++i) {
Igor Murashkincba2c162013-03-20 15:56:31 -0700100 mStatusList[i] = ICameraServiceListener::STATUS_PRESENT;
Igor Murashkinbfc99152013-02-27 12:55:20 -0800101 }
Igor Murashkincba2c162013-03-20 15:56:31 -0700102
103 this->camera_device_status_change = android::camera_device_status_change;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700104}
105
Iliyan Malchev8951a972011-04-14 16:55:59 -0700106void CameraService::onFirstRef()
107{
Igor Murashkin634a5152013-02-20 17:15:11 -0800108 LOG1("CameraService::onFirstRef");
109
Iliyan Malchev8951a972011-04-14 16:55:59 -0700110 BnCameraService::onFirstRef();
111
112 if (hw_get_module(CAMERA_HARDWARE_MODULE_ID,
113 (const hw_module_t **)&mModule) < 0) {
Steve Block29357bc2012-01-06 19:20:56 +0000114 ALOGE("Could not load camera HAL module");
Iliyan Malchev8951a972011-04-14 16:55:59 -0700115 mNumberOfCameras = 0;
116 }
117 else {
Alex Rayc0dd54f2013-02-20 13:39:37 -0800118 ALOGI("Loaded \"%s\" camera module", mModule->common.name);
Iliyan Malchev8951a972011-04-14 16:55:59 -0700119 mNumberOfCameras = mModule->get_number_of_cameras();
120 if (mNumberOfCameras > MAX_CAMERAS) {
Steve Block29357bc2012-01-06 19:20:56 +0000121 ALOGE("Number of cameras(%d) > MAX_CAMERAS(%d).",
Iliyan Malchev8951a972011-04-14 16:55:59 -0700122 mNumberOfCameras, MAX_CAMERAS);
123 mNumberOfCameras = MAX_CAMERAS;
124 }
125 for (int i = 0; i < mNumberOfCameras; i++) {
126 setCameraFree(i);
127 }
Igor Murashkincba2c162013-03-20 15:56:31 -0700128
129 if (mModule->common.module_api_version >=
130 CAMERA_MODULE_API_VERSION_2_1) {
131 mModule->set_callbacks(this);
132 }
Igor Murashkin98e24722013-06-19 19:51:04 -0700133
134 CameraDeviceFactory::registerService(this);
Iliyan Malchev8951a972011-04-14 16:55:59 -0700135 }
136}
137
Mathias Agopian65ab4712010-07-14 17:59:35 -0700138CameraService::~CameraService() {
139 for (int i = 0; i < mNumberOfCameras; i++) {
140 if (mBusy[i]) {
Steve Block29357bc2012-01-06 19:20:56 +0000141 ALOGE("camera %d is still in use in destructor!", i);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700142 }
143 }
144
145 gCameraService = NULL;
146}
147
Igor Murashkincba2c162013-03-20 15:56:31 -0700148void CameraService::onDeviceStatusChanged(int cameraId,
149 int newStatus)
150{
151 ALOGI("%s: Status changed for cameraId=%d, newStatus=%d", __FUNCTION__,
152 cameraId, newStatus);
153
154 if (cameraId < 0 || cameraId >= MAX_CAMERAS) {
155 ALOGE("%s: Bad camera ID %d", __FUNCTION__, cameraId);
156 return;
157 }
158
159 if ((int)getStatus(cameraId) == newStatus) {
160 ALOGE("%s: State transition to the same status 0x%x not allowed",
161 __FUNCTION__, (uint32_t)newStatus);
162 return;
163 }
164
165 /* don't do this in updateStatus
166 since it is also called from connect and we could get into a deadlock */
167 if (newStatus == CAMERA_DEVICE_STATUS_NOT_PRESENT) {
168 Vector<sp<BasicClient> > clientsToDisconnect;
169 {
170 Mutex::Autolock al(mServiceLock);
171
172 /* Find all clients that we need to disconnect */
Igor Murashkine7ee7632013-06-11 18:10:18 -0700173 sp<BasicClient> client = mClient[cameraId].promote();
Igor Murashkincba2c162013-03-20 15:56:31 -0700174 if (client.get() != NULL) {
175 clientsToDisconnect.push_back(client);
176 }
177
178 int i = cameraId;
179 for (size_t j = 0; j < mProClientList[i].size(); ++j) {
180 sp<ProClient> cl = mProClientList[i][j].promote();
181 if (cl != NULL) {
182 clientsToDisconnect.push_back(cl);
183 }
184 }
185 }
186
187 /* now disconnect them. don't hold the lock
188 or we can get into a deadlock */
189
190 for (size_t i = 0; i < clientsToDisconnect.size(); ++i) {
191 sp<BasicClient> client = clientsToDisconnect[i];
192
193 client->disconnect();
194 /**
195 * The remote app will no longer be able to call methods on the
196 * client since the client PID will be reset to 0
197 */
198 }
199
200 ALOGV("%s: After unplug, disconnected %d clients",
201 __FUNCTION__, clientsToDisconnect.size());
202 }
203
204 updateStatus(
205 static_cast<ICameraServiceListener::Status>(newStatus), cameraId);
206
207}
208
Mathias Agopian65ab4712010-07-14 17:59:35 -0700209int32_t CameraService::getNumberOfCameras() {
210 return mNumberOfCameras;
211}
212
213status_t CameraService::getCameraInfo(int cameraId,
214 struct CameraInfo* cameraInfo) {
Iliyan Malchev8951a972011-04-14 16:55:59 -0700215 if (!mModule) {
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700216 return -ENODEV;
Iliyan Malchev8951a972011-04-14 16:55:59 -0700217 }
218
Mathias Agopian65ab4712010-07-14 17:59:35 -0700219 if (cameraId < 0 || cameraId >= mNumberOfCameras) {
220 return BAD_VALUE;
221 }
222
Iliyan Malchev8951a972011-04-14 16:55:59 -0700223 struct camera_info info;
224 status_t rc = mModule->get_camera_info(cameraId, &info);
225 cameraInfo->facing = info.facing;
226 cameraInfo->orientation = info.orientation;
227 return rc;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700228}
229
Zhijun He2b59be82013-09-25 10:14:30 -0700230status_t CameraService::getCameraCharacteristics(int cameraId,
231 CameraMetadata* cameraInfo) {
232 if (!cameraInfo) {
233 ALOGE("%s: cameraInfo is NULL", __FUNCTION__);
234 return BAD_VALUE;
235 }
236
237 if (!mModule) {
238 ALOGE("%s: camera hardware module doesn't exist", __FUNCTION__);
239 return -ENODEV;
240 }
241
242 if (mModule->common.module_api_version < CAMERA_MODULE_API_VERSION_2_0) {
243 // TODO: Remove this check once HAL1 shim is in place.
244 ALOGE("%s: Only HAL module version V2 or higher supports static metadata", __FUNCTION__);
245 return BAD_VALUE;
246 }
247
248 if (cameraId < 0 || cameraId >= mNumberOfCameras) {
249 ALOGE("%s: Invalid camera id: %d", __FUNCTION__, cameraId);
250 return BAD_VALUE;
251 }
252
253 int facing;
254 if (getDeviceVersion(cameraId, &facing) == CAMERA_DEVICE_API_VERSION_1_0) {
255 // TODO: Remove this check once HAL1 shim is in place.
256 ALOGE("%s: HAL1 doesn't support static metadata yet", __FUNCTION__);
257 return BAD_VALUE;
258 }
259
Zhijun Hef05e50e2013-10-01 11:05:33 -0700260 if (getDeviceVersion(cameraId, &facing) <= CAMERA_DEVICE_API_VERSION_2_1) {
261 // Disable HAL2.x support for camera2 API for now.
262 ALOGW("%s: HAL2.x doesn't support getCameraCharacteristics for now", __FUNCTION__);
263 return BAD_VALUE;
264 }
265
Zhijun He2b59be82013-09-25 10:14:30 -0700266 struct camera_info info;
267 status_t ret = mModule->get_camera_info(cameraId, &info);
268 *cameraInfo = info.static_camera_characteristics;
269
270 return ret;
271}
272
Igor Murashkin634a5152013-02-20 17:15:11 -0800273int CameraService::getDeviceVersion(int cameraId, int* facing) {
274 struct camera_info info;
275 if (mModule->get_camera_info(cameraId, &info) != OK) {
276 return -1;
277 }
278
279 int deviceVersion;
280 if (mModule->common.module_api_version >= CAMERA_MODULE_API_VERSION_2_0) {
281 deviceVersion = info.device_version;
282 } else {
283 deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
284 }
285
286 if (facing) {
287 *facing = info.facing;
288 }
289
290 return deviceVersion;
291}
292
Igor Murashkinbfc99152013-02-27 12:55:20 -0800293bool CameraService::isValidCameraId(int cameraId) {
294 int facing;
295 int deviceVersion = getDeviceVersion(cameraId, &facing);
296
297 switch(deviceVersion) {
298 case CAMERA_DEVICE_API_VERSION_1_0:
299 case CAMERA_DEVICE_API_VERSION_2_0:
300 case CAMERA_DEVICE_API_VERSION_2_1:
301 case CAMERA_DEVICE_API_VERSION_3_0:
302 return true;
303 default:
304 return false;
305 }
306
307 return false;
308}
309
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700310status_t CameraService::validateConnect(int cameraId,
Igor Murashkine6800ce2013-03-04 17:25:57 -0800311 /*inout*/
312 int& clientUid) const {
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800313
Mathias Agopian65ab4712010-07-14 17:59:35 -0700314 int callingPid = getCallingPid();
Tyler Luu5861a9a2011-10-06 00:00:03 -0500315
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800316 if (clientUid == USE_CALLING_UID) {
317 clientUid = getCallingUid();
318 } else {
319 // We only trust our own process to forward client UIDs
320 if (callingPid != getpid()) {
321 ALOGE("CameraService::connect X (pid %d) rejected (don't trust clientUid)",
322 callingPid);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700323 return PERMISSION_DENIED;
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800324 }
325 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700326
Iliyan Malchev8951a972011-04-14 16:55:59 -0700327 if (!mModule) {
Steve Block29357bc2012-01-06 19:20:56 +0000328 ALOGE("Camera HAL module not loaded");
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700329 return -ENODEV;
Iliyan Malchev8951a972011-04-14 16:55:59 -0700330 }
331
Mathias Agopian65ab4712010-07-14 17:59:35 -0700332 if (cameraId < 0 || cameraId >= mNumberOfCameras) {
Steve Block29357bc2012-01-06 19:20:56 +0000333 ALOGE("CameraService::connect X (pid %d) rejected (invalid cameraId %d).",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700334 callingPid, cameraId);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700335 return -ENODEV;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700336 }
337
Wu-cheng Lia3355432011-05-20 14:54:25 +0800338 char value[PROPERTY_VALUE_MAX];
339 property_get("sys.secpolicy.camera.disabled", value, "0");
340 if (strcmp(value, "1") == 0) {
341 // Camera is disabled by DevicePolicyManager.
Steve Blockdf64d152012-01-04 20:05:49 +0000342 ALOGI("Camera is disabled. connect X (pid %d) rejected", callingPid);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700343 return -EACCES;
Wu-cheng Lia3355432011-05-20 14:54:25 +0800344 }
345
Igor Murashkincba2c162013-03-20 15:56:31 -0700346 ICameraServiceListener::Status currentStatus = getStatus(cameraId);
347 if (currentStatus == ICameraServiceListener::STATUS_NOT_PRESENT) {
348 ALOGI("Camera is not plugged in,"
349 " connect X (pid %d) rejected", callingPid);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700350 return -ENODEV;
Igor Murashkincba2c162013-03-20 15:56:31 -0700351 } else if (currentStatus == ICameraServiceListener::STATUS_ENUMERATING) {
352 ALOGI("Camera is enumerating,"
353 " connect X (pid %d) rejected", callingPid);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700354 return -EBUSY;
Igor Murashkincba2c162013-03-20 15:56:31 -0700355 }
356 // Else don't check for STATUS_NOT_AVAILABLE.
357 // -- It's done implicitly in canConnectUnsafe /w the mBusy array
358
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700359 return OK;
Igor Murashkine6800ce2013-03-04 17:25:57 -0800360}
361
362bool CameraService::canConnectUnsafe(int cameraId,
363 const String16& clientPackageName,
364 const sp<IBinder>& remoteCallback,
Igor Murashkine7ee7632013-06-11 18:10:18 -0700365 sp<BasicClient> &client) {
Igor Murashkine6800ce2013-03-04 17:25:57 -0800366 String8 clientName8(clientPackageName);
367 int callingPid = getCallingPid();
368
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800369 if (mClient[cameraId] != 0) {
370 client = mClient[cameraId].promote();
371 if (client != 0) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700372 if (remoteCallback == client->getRemote()) {
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800373 LOG1("CameraService::connect X (pid %d) (the same client)",
374 callingPid);
Igor Murashkine6800ce2013-03-04 17:25:57 -0800375 return true;
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800376 } else {
Igor Murashkine6800ce2013-03-04 17:25:57 -0800377 // TODOSC: need to support 1 regular client,
378 // multiple shared clients here
379 ALOGW("CameraService::connect X (pid %d) rejected"
380 " (existing client).", callingPid);
381 return false;
Wu-cheng Li2fd24402012-02-23 19:01:00 -0800382 }
Wu-cheng Li2fd24402012-02-23 19:01:00 -0800383 }
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800384 mClient[cameraId].clear();
385 }
386
Igor Murashkin634a5152013-02-20 17:15:11 -0800387 /*
388 mBusy is set to false as the last step of the Client destructor,
389 after which it is guaranteed that the Client destructor has finished (
390 including any inherited destructors)
391
392 We only need this for a Client subclasses since we don't allow
393 multiple Clents to be opened concurrently, but multiple BasicClient
394 would be fine
395 */
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800396 if (mBusy[cameraId]) {
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800397 ALOGW("CameraService::connect X (pid %d, \"%s\") rejected"
398 " (camera %d is still busy).", callingPid,
399 clientName8.string(), cameraId);
Igor Murashkine6800ce2013-03-04 17:25:57 -0800400 return false;
401 }
402
403 return true;
404}
405
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700406status_t CameraService::connect(
Igor Murashkine6800ce2013-03-04 17:25:57 -0800407 const sp<ICameraClient>& cameraClient,
408 int cameraId,
409 const String16& clientPackageName,
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700410 int clientUid,
411 /*out*/
412 sp<ICamera>& device) {
Igor Murashkine6800ce2013-03-04 17:25:57 -0800413
414 String8 clientName8(clientPackageName);
415 int callingPid = getCallingPid();
416
417 LOG1("CameraService::connect E (pid %d \"%s\", id %d)", callingPid,
418 clientName8.string(), cameraId);
419
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700420 status_t status = validateConnect(cameraId, /*inout*/clientUid);
421 if (status != OK) {
422 return status;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700423 }
424
Igor Murashkine6800ce2013-03-04 17:25:57 -0800425
Igor Murashkine7ee7632013-06-11 18:10:18 -0700426 sp<Client> client;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700427 {
428 Mutex::Autolock lock(mServiceLock);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700429 sp<BasicClient> clientTmp;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700430 if (!canConnectUnsafe(cameraId, clientPackageName,
431 cameraClient->asBinder(),
Igor Murashkine7ee7632013-06-11 18:10:18 -0700432 /*out*/clientTmp)) {
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700433 return -EBUSY;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700434 } else if (client.get() != NULL) {
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700435 device = static_cast<Client*>(clientTmp.get());
436 return OK;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700437 }
438
439 int facing = -1;
440 int deviceVersion = getDeviceVersion(cameraId, &facing);
441
442 // If there are other non-exclusive users of the camera,
443 // this will tear them down before we can reuse the camera
444 if (isValidCameraId(cameraId)) {
Igor Murashkincba2c162013-03-20 15:56:31 -0700445 // transition from PRESENT -> NOT_AVAILABLE
Igor Murashkinacd695c2013-03-13 17:23:00 -0700446 updateStatus(ICameraServiceListener::STATUS_NOT_AVAILABLE,
447 cameraId);
448 }
449
450 switch(deviceVersion) {
451 case CAMERA_DEVICE_API_VERSION_1_0:
452 client = new CameraClient(this, cameraClient,
453 clientPackageName, cameraId,
454 facing, callingPid, clientUid, getpid());
455 break;
456 case CAMERA_DEVICE_API_VERSION_2_0:
457 case CAMERA_DEVICE_API_VERSION_2_1:
458 case CAMERA_DEVICE_API_VERSION_3_0:
459 client = new Camera2Client(this, cameraClient,
460 clientPackageName, cameraId,
461 facing, callingPid, clientUid, getpid(),
462 deviceVersion);
463 break;
464 case -1:
465 ALOGE("Invalid camera id %d", cameraId);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700466 return BAD_VALUE;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700467 default:
468 ALOGE("Unknown camera device HAL version: %d", deviceVersion);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700469 return INVALID_OPERATION;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700470 }
471
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700472 status_t status = connectFinishUnsafe(client, client->getRemote());
473 if (status != OK) {
Igor Murashkinacd695c2013-03-13 17:23:00 -0700474 // this is probably not recoverable.. maybe the client can try again
Igor Murashkincba2c162013-03-20 15:56:31 -0700475 // OK: we can only get here if we were originally in PRESENT state
476 updateStatus(ICameraServiceListener::STATUS_PRESENT, cameraId);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700477 return status;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700478 }
479
480 mClient[cameraId] = client;
481 LOG1("CameraService::connect X (id %d, this pid is %d)", cameraId,
482 getpid());
Igor Murashkine6800ce2013-03-04 17:25:57 -0800483 }
Igor Murashkinacd695c2013-03-13 17:23:00 -0700484 // important: release the mutex here so the client can call back
485 // into the service from its destructor (can be at the end of the call)
Igor Murashkinbfc99152013-02-27 12:55:20 -0800486
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700487 device = client;
488 return OK;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700489}
490
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700491status_t CameraService::connectFinishUnsafe(const sp<BasicClient>& client,
492 const sp<IBinder>& remoteCallback) {
493 status_t status = client->initialize(mModule);
494 if (status != OK) {
495 return status;
Igor Murashkine6800ce2013-03-04 17:25:57 -0800496 }
497
Igor Murashkine7ee7632013-06-11 18:10:18 -0700498 remoteCallback->linkToDeath(this);
Igor Murashkine6800ce2013-03-04 17:25:57 -0800499
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700500 return OK;
Igor Murashkine6800ce2013-03-04 17:25:57 -0800501}
502
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700503status_t CameraService::connectPro(
Igor Murashkin634a5152013-02-20 17:15:11 -0800504 const sp<IProCameraCallbacks>& cameraCb,
Igor Murashkinc073ba52013-02-26 14:32:34 -0800505 int cameraId,
506 const String16& clientPackageName,
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700507 int clientUid,
508 /*out*/
509 sp<IProCameraUser>& device)
Igor Murashkin634a5152013-02-20 17:15:11 -0800510{
Igor Murashkinbfc99152013-02-27 12:55:20 -0800511 String8 clientName8(clientPackageName);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700512 int callingPid = getCallingPid();
Igor Murashkin634a5152013-02-20 17:15:11 -0800513
Igor Murashkine6800ce2013-03-04 17:25:57 -0800514 LOG1("CameraService::connectPro E (pid %d \"%s\", id %d)", callingPid,
515 clientName8.string(), cameraId);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700516 status_t status = validateConnect(cameraId, /*inout*/clientUid);
517 if (status != OK) {
518 return status;
Igor Murashkin634a5152013-02-20 17:15:11 -0800519 }
520
Igor Murashkinacd695c2013-03-13 17:23:00 -0700521 sp<ProClient> client;
Igor Murashkine6800ce2013-03-04 17:25:57 -0800522 {
Igor Murashkinacd695c2013-03-13 17:23:00 -0700523 Mutex::Autolock lock(mServiceLock);
524 {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700525 sp<BasicClient> client;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700526 if (!canConnectUnsafe(cameraId, clientPackageName,
527 cameraCb->asBinder(),
528 /*out*/client)) {
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700529 return -EBUSY;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700530 }
531 }
532
533 int facing = -1;
534 int deviceVersion = getDeviceVersion(cameraId, &facing);
535
536 switch(deviceVersion) {
537 case CAMERA_DEVICE_API_VERSION_1_0:
538 ALOGE("Camera id %d uses HALv1, doesn't support ProCamera",
539 cameraId);
Ruben Brunk17963d12013-08-19 15:21:19 -0700540 return -EOPNOTSUPP;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700541 break;
542 case CAMERA_DEVICE_API_VERSION_2_0:
543 case CAMERA_DEVICE_API_VERSION_2_1:
Zhijun He47110052013-07-22 17:34:34 -0700544 case CAMERA_DEVICE_API_VERSION_3_0:
Igor Murashkinacd695c2013-03-13 17:23:00 -0700545 client = new ProCamera2Client(this, cameraCb, String16(),
546 cameraId, facing, callingPid, USE_CALLING_UID, getpid());
547 break;
548 case -1:
549 ALOGE("Invalid camera id %d", cameraId);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700550 return BAD_VALUE;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700551 default:
552 ALOGE("Unknown camera device HAL version: %d", deviceVersion);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700553 return INVALID_OPERATION;
Igor Murashkine6800ce2013-03-04 17:25:57 -0800554 }
Igor Murashkinacd695c2013-03-13 17:23:00 -0700555
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700556 status_t status = connectFinishUnsafe(client, client->getRemote());
557 if (status != OK) {
558 return status;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700559 }
560
561 mProClientList[cameraId].push(client);
562
563 LOG1("CameraService::connectPro X (id %d, this pid is %d)", cameraId,
564 getpid());
Igor Murashkine6800ce2013-03-04 17:25:57 -0800565 }
Igor Murashkinacd695c2013-03-13 17:23:00 -0700566 // important: release the mutex here so the client can call back
567 // into the service from its destructor (can be at the end of the call)
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700568 device = client;
569 return OK;
Igor Murashkinbfc99152013-02-27 12:55:20 -0800570}
Igor Murashkin634a5152013-02-20 17:15:11 -0800571
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700572status_t CameraService::connectDevice(
Igor Murashkine7ee7632013-06-11 18:10:18 -0700573 const sp<ICameraDeviceCallbacks>& cameraCb,
574 int cameraId,
575 const String16& clientPackageName,
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700576 int clientUid,
577 /*out*/
578 sp<ICameraDeviceUser>& device)
Igor Murashkine7ee7632013-06-11 18:10:18 -0700579{
Igor Murashkine7ee7632013-06-11 18:10:18 -0700580
581 String8 clientName8(clientPackageName);
582 int callingPid = getCallingPid();
583
584 LOG1("CameraService::connectDevice E (pid %d \"%s\", id %d)", callingPid,
585 clientName8.string(), cameraId);
586
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700587 status_t status = validateConnect(cameraId, /*inout*/clientUid);
588 if (status != OK) {
589 return status;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700590 }
591
592 sp<CameraDeviceClient> client;
593 {
594 Mutex::Autolock lock(mServiceLock);
595 {
596 sp<BasicClient> client;
597 if (!canConnectUnsafe(cameraId, clientPackageName,
598 cameraCb->asBinder(),
599 /*out*/client)) {
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700600 return -EBUSY;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700601 }
602 }
603
604 int facing = -1;
605 int deviceVersion = getDeviceVersion(cameraId, &facing);
606
607 // If there are other non-exclusive users of the camera,
608 // this will tear them down before we can reuse the camera
609 if (isValidCameraId(cameraId)) {
610 // transition from PRESENT -> NOT_AVAILABLE
611 updateStatus(ICameraServiceListener::STATUS_NOT_AVAILABLE,
612 cameraId);
613 }
614
615 switch(deviceVersion) {
616 case CAMERA_DEVICE_API_VERSION_1_0:
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700617 ALOGW("Camera using old HAL version: %d", deviceVersion);
Ruben Brunk17963d12013-08-19 15:21:19 -0700618 return -EOPNOTSUPP;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700619 // TODO: don't allow 2.0 Only allow 2.1 and higher
620 case CAMERA_DEVICE_API_VERSION_2_0:
621 case CAMERA_DEVICE_API_VERSION_2_1:
622 case CAMERA_DEVICE_API_VERSION_3_0:
623 client = new CameraDeviceClient(this, cameraCb, String16(),
624 cameraId, facing, callingPid, USE_CALLING_UID, getpid());
625 break;
626 case -1:
627 ALOGE("Invalid camera id %d", cameraId);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700628 return BAD_VALUE;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700629 default:
630 ALOGE("Unknown camera device HAL version: %d", deviceVersion);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700631 return INVALID_OPERATION;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700632 }
633
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700634 status_t status = connectFinishUnsafe(client, client->getRemote());
635 if (status != OK) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700636 // this is probably not recoverable.. maybe the client can try again
637 // OK: we can only get here if we were originally in PRESENT state
638 updateStatus(ICameraServiceListener::STATUS_PRESENT, cameraId);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700639 return status;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700640 }
641
642 LOG1("CameraService::connectDevice X (id %d, this pid is %d)", cameraId,
643 getpid());
644
645 mClient[cameraId] = client;
646 }
647 // important: release the mutex here so the client can call back
648 // into the service from its destructor (can be at the end of the call)
649
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700650 device = client;
651 return OK;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700652}
653
654
Igor Murashkinbfc99152013-02-27 12:55:20 -0800655status_t CameraService::addListener(
656 const sp<ICameraServiceListener>& listener) {
657 ALOGV("%s: Add listener %p", __FUNCTION__, listener.get());
Igor Murashkin634a5152013-02-20 17:15:11 -0800658
Igor Murashkinbfc99152013-02-27 12:55:20 -0800659 Mutex::Autolock lock(mServiceLock);
660
661 Vector<sp<ICameraServiceListener> >::iterator it, end;
662 for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
663 if ((*it)->asBinder() == listener->asBinder()) {
664 ALOGW("%s: Tried to add listener %p which was already subscribed",
665 __FUNCTION__, listener.get());
666 return ALREADY_EXISTS;
667 }
668 }
669
670 mListenerList.push_back(listener);
671
Igor Murashkincba2c162013-03-20 15:56:31 -0700672 /* Immediately signal current status to this listener only */
673 {
674 Mutex::Autolock m(mStatusMutex) ;
675 int numCams = getNumberOfCameras();
676 for (int i = 0; i < numCams; ++i) {
677 listener->onStatusChanged(mStatusList[i], i);
678 }
679 }
680
Igor Murashkinbfc99152013-02-27 12:55:20 -0800681 return OK;
682}
683status_t CameraService::removeListener(
684 const sp<ICameraServiceListener>& listener) {
685 ALOGV("%s: Remove listener %p", __FUNCTION__, listener.get());
686
687 Mutex::Autolock lock(mServiceLock);
688
689 Vector<sp<ICameraServiceListener> >::iterator it;
690 for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
691 if ((*it)->asBinder() == listener->asBinder()) {
692 mListenerList.erase(it);
693 return OK;
694 }
695 }
696
697 ALOGW("%s: Tried to remove a listener %p which was not subscribed",
698 __FUNCTION__, listener.get());
699
700 return BAD_VALUE;
Igor Murashkin634a5152013-02-20 17:15:11 -0800701}
702
703void CameraService::removeClientByRemote(const wp<IBinder>& remoteBinder) {
704 int callingPid = getCallingPid();
705 LOG1("CameraService::removeClientByRemote E (pid %d)", callingPid);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700706
Igor Murashkinecf17e82012-10-02 16:05:11 -0700707 // Declare this before the lock to make absolutely sure the
708 // destructor won't be called with the lock held.
709 Mutex::Autolock lock(mServiceLock);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700710
Igor Murashkinecf17e82012-10-02 16:05:11 -0700711 int outIndex;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700712 sp<BasicClient> client = findClientUnsafe(remoteBinder, outIndex);
Igor Murashkinecf17e82012-10-02 16:05:11 -0700713
714 if (client != 0) {
715 // Found our camera, clear and leave.
716 LOG1("removeClient: clear camera %d", outIndex);
717 mClient[outIndex].clear();
718
Igor Murashkine7ee7632013-06-11 18:10:18 -0700719 client->getRemote()->unlinkToDeath(this);
Igor Murashkin634a5152013-02-20 17:15:11 -0800720 } else {
721
722 sp<ProClient> clientPro = findProClientUnsafe(remoteBinder);
723
724 if (clientPro != NULL) {
725 // Found our camera, clear and leave.
726 LOG1("removeClient: clear pro %p", clientPro.get());
727
728 clientPro->getRemoteCallback()->asBinder()->unlinkToDeath(this);
729 }
Igor Murashkinecf17e82012-10-02 16:05:11 -0700730 }
731
Igor Murashkin634a5152013-02-20 17:15:11 -0800732 LOG1("CameraService::removeClientByRemote X (pid %d)", callingPid);
733}
734
735sp<CameraService::ProClient> CameraService::findProClientUnsafe(
736 const wp<IBinder>& cameraCallbacksRemote)
737{
738 sp<ProClient> clientPro;
739
740 for (int i = 0; i < mNumberOfCameras; ++i) {
741 Vector<size_t> removeIdx;
742
743 for (size_t j = 0; j < mProClientList[i].size(); ++j) {
744 wp<ProClient> cl = mProClientList[i][j];
745
746 sp<ProClient> clStrong = cl.promote();
747 if (clStrong != NULL && clStrong->getRemote() == cameraCallbacksRemote) {
748 clientPro = clStrong;
749 break;
750 } else if (clStrong == NULL) {
751 // mark to clean up dead ptr
752 removeIdx.push(j);
753 }
754 }
755
756 // remove stale ptrs (in reverse so the indices dont change)
757 for (ssize_t j = (ssize_t)removeIdx.size() - 1; j >= 0; --j) {
758 mProClientList[i].removeAt(removeIdx[j]);
759 }
760
761 }
762
763 return clientPro;
Igor Murashkinecf17e82012-10-02 16:05:11 -0700764}
765
Igor Murashkine7ee7632013-06-11 18:10:18 -0700766sp<CameraService::BasicClient> CameraService::findClientUnsafe(
Igor Murashkin294d0ec2012-10-05 10:44:57 -0700767 const wp<IBinder>& cameraClient, int& outIndex) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700768 sp<BasicClient> client;
Igor Murashkinecf17e82012-10-02 16:05:11 -0700769
770 for (int i = 0; i < mNumberOfCameras; i++) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700771
772 // This happens when we have already disconnected (or this is
773 // just another unused camera).
774 if (mClient[i] == 0) continue;
775
776 // Promote mClient. It can fail if we are called from this path:
Igor Murashkin634a5152013-02-20 17:15:11 -0800777 // Client::~Client() -> disconnect() -> removeClientByRemote().
Mathias Agopian65ab4712010-07-14 17:59:35 -0700778 client = mClient[i].promote();
779
Igor Murashkinecf17e82012-10-02 16:05:11 -0700780 // Clean up stale client entry
781 if (client == NULL) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700782 mClient[i].clear();
783 continue;
784 }
785
Igor Murashkine7ee7632013-06-11 18:10:18 -0700786 if (cameraClient == client->getRemote()) {
Igor Murashkinecf17e82012-10-02 16:05:11 -0700787 // Found our camera
788 outIndex = i;
789 return client;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700790 }
791 }
792
Igor Murashkinecf17e82012-10-02 16:05:11 -0700793 outIndex = -1;
794 return NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700795}
796
Igor Murashkine7ee7632013-06-11 18:10:18 -0700797CameraService::BasicClient* CameraService::getClientByIdUnsafe(int cameraId) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700798 if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
Keun young Parkd8973a72012-03-28 14:13:09 -0700799 return mClient[cameraId].unsafe_get();
800}
801
802Mutex* CameraService::getClientLockById(int cameraId) {
803 if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
804 return &mClientLock[cameraId];
Mathias Agopian65ab4712010-07-14 17:59:35 -0700805}
806
Igor Murashkin634a5152013-02-20 17:15:11 -0800807sp<CameraService::BasicClient> CameraService::getClientByRemote(
Igor Murashkin294d0ec2012-10-05 10:44:57 -0700808 const wp<IBinder>& cameraClient) {
Igor Murashkinecf17e82012-10-02 16:05:11 -0700809
810 // Declare this before the lock to make absolutely sure the
811 // destructor won't be called with the lock held.
Igor Murashkin634a5152013-02-20 17:15:11 -0800812 sp<BasicClient> client;
Igor Murashkinecf17e82012-10-02 16:05:11 -0700813
814 Mutex::Autolock lock(mServiceLock);
815
816 int outIndex;
817 client = findClientUnsafe(cameraClient, outIndex);
818
819 return client;
820}
821
Mathias Agopian65ab4712010-07-14 17:59:35 -0700822status_t CameraService::onTransact(
823 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
824 // Permission checks
825 switch (code) {
826 case BnCameraService::CONNECT:
Igor Murashkin634a5152013-02-20 17:15:11 -0800827 case BnCameraService::CONNECT_PRO:
Mathias Agopian65ab4712010-07-14 17:59:35 -0700828 const int pid = getCallingPid();
829 const int self_pid = getpid();
830 if (pid != self_pid) {
831 // we're called from a different process, do the real check
832 if (!checkCallingPermission(
833 String16("android.permission.CAMERA"))) {
834 const int uid = getCallingUid();
Steve Block29357bc2012-01-06 19:20:56 +0000835 ALOGE("Permission Denial: "
Mathias Agopian65ab4712010-07-14 17:59:35 -0700836 "can't use the camera pid=%d, uid=%d", pid, uid);
837 return PERMISSION_DENIED;
838 }
839 }
840 break;
841 }
842
843 return BnCameraService::onTransact(code, data, reply, flags);
844}
845
846// The reason we need this busy bit is a new CameraService::connect() request
847// may come in while the previous Client's destructor has not been run or is
848// still running. If the last strong reference of the previous Client is gone
849// but the destructor has not been finished, we should not allow the new Client
850// to be created because we need to wait for the previous Client to tear down
851// the hardware first.
852void CameraService::setCameraBusy(int cameraId) {
853 android_atomic_write(1, &mBusy[cameraId]);
Igor Murashkinecf17e82012-10-02 16:05:11 -0700854
855 ALOGV("setCameraBusy cameraId=%d", cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700856}
857
858void CameraService::setCameraFree(int cameraId) {
859 android_atomic_write(0, &mBusy[cameraId]);
Igor Murashkinecf17e82012-10-02 16:05:11 -0700860
861 ALOGV("setCameraFree cameraId=%d", cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700862}
863
864// We share the media players for shutter and recording sound for all clients.
865// A reference count is kept to determine when we will actually release the
866// media players.
867
Chih-Chung Changff4f55c2011-10-17 19:03:12 +0800868MediaPlayer* CameraService::newMediaPlayer(const char *file) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700869 MediaPlayer* mp = new MediaPlayer();
Andreas Huber1b86fe02014-01-29 11:13:26 -0800870 if (mp->setDataSource(NULL /* httpService */, file, NULL) == NO_ERROR) {
Eino-Ville Talvala60a78ac2012-01-05 15:34:53 -0800871 mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700872 mp->prepare();
873 } else {
Steve Block29357bc2012-01-06 19:20:56 +0000874 ALOGE("Failed to load CameraService sounds: %s", file);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700875 return NULL;
876 }
877 return mp;
878}
879
880void CameraService::loadSound() {
881 Mutex::Autolock lock(mSoundLock);
882 LOG1("CameraService::loadSound ref=%d", mSoundRef);
883 if (mSoundRef++) return;
884
885 mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
886 mSoundPlayer[SOUND_RECORDING] = newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");
887}
888
889void CameraService::releaseSound() {
890 Mutex::Autolock lock(mSoundLock);
891 LOG1("CameraService::releaseSound ref=%d", mSoundRef);
892 if (--mSoundRef) return;
893
894 for (int i = 0; i < NUM_SOUNDS; i++) {
895 if (mSoundPlayer[i] != 0) {
896 mSoundPlayer[i]->disconnect();
897 mSoundPlayer[i].clear();
898 }
899 }
900}
901
902void CameraService::playSound(sound_kind kind) {
903 LOG1("playSound(%d)", kind);
904 Mutex::Autolock lock(mSoundLock);
905 sp<MediaPlayer> player = mSoundPlayer[kind];
906 if (player != 0) {
Chih-Chung Chang8888a752011-10-20 10:47:26 +0800907 player->seekTo(0);
908 player->start();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700909 }
910}
911
912// ----------------------------------------------------------------------------
913
914CameraService::Client::Client(const sp<CameraService>& cameraService,
Wu-cheng Lib7a67942010-08-17 15:45:37 -0700915 const sp<ICameraClient>& cameraClient,
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800916 const String16& clientPackageName,
917 int cameraId, int cameraFacing,
918 int clientPid, uid_t clientUid,
919 int servicePid) :
Igor Murashkin634a5152013-02-20 17:15:11 -0800920 CameraService::BasicClient(cameraService, cameraClient->asBinder(),
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800921 clientPackageName,
922 cameraId, cameraFacing,
923 clientPid, clientUid,
924 servicePid)
Igor Murashkin634a5152013-02-20 17:15:11 -0800925{
Mathias Agopian65ab4712010-07-14 17:59:35 -0700926 int callingPid = getCallingPid();
Wu-cheng Li2fd24402012-02-23 19:01:00 -0800927 LOG1("Client::Client E (pid %d, id %d)", callingPid, cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700928
Igor Murashkin44cfcf02013-03-01 16:22:28 -0800929 mRemoteCallback = cameraClient;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700930
Mathias Agopian65ab4712010-07-14 17:59:35 -0700931 cameraService->setCameraBusy(cameraId);
932 cameraService->loadSound();
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800933
Wu-cheng Li2fd24402012-02-23 19:01:00 -0800934 LOG1("Client::Client X (pid %d, id %d)", callingPid, cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700935}
936
Mathias Agopian65ab4712010-07-14 17:59:35 -0700937// tear down the client
938CameraService::Client::~Client() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700939 ALOGV("~Client");
Igor Murashkin634a5152013-02-20 17:15:11 -0800940 mDestructionStarted = true;
941
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700942 mCameraService->releaseSound();
Igor Murashkin036bc3e2012-10-08 15:09:46 -0700943 // unconditionally disconnect. function is idempotent
944 Client::disconnect();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700945}
946
Igor Murashkin634a5152013-02-20 17:15:11 -0800947CameraService::BasicClient::BasicClient(const sp<CameraService>& cameraService,
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800948 const sp<IBinder>& remoteCallback,
949 const String16& clientPackageName,
950 int cameraId, int cameraFacing,
951 int clientPid, uid_t clientUid,
952 int servicePid):
953 mClientPackageName(clientPackageName)
Igor Murashkin634a5152013-02-20 17:15:11 -0800954{
955 mCameraService = cameraService;
Igor Murashkin44cfcf02013-03-01 16:22:28 -0800956 mRemoteBinder = remoteCallback;
Igor Murashkin634a5152013-02-20 17:15:11 -0800957 mCameraId = cameraId;
958 mCameraFacing = cameraFacing;
959 mClientPid = clientPid;
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800960 mClientUid = clientUid;
Igor Murashkin634a5152013-02-20 17:15:11 -0800961 mServicePid = servicePid;
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800962 mOpsActive = false;
Igor Murashkin634a5152013-02-20 17:15:11 -0800963 mDestructionStarted = false;
964}
965
966CameraService::BasicClient::~BasicClient() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700967 ALOGV("~BasicClient");
Igor Murashkin634a5152013-02-20 17:15:11 -0800968 mDestructionStarted = true;
969}
970
971void CameraService::BasicClient::disconnect() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700972 ALOGV("BasicClient::disconnect");
Igor Murashkin44cfcf02013-03-01 16:22:28 -0800973 mCameraService->removeClientByRemote(mRemoteBinder);
Igor Murashkincba2c162013-03-20 15:56:31 -0700974 // client shouldn't be able to call into us anymore
975 mClientPid = 0;
Igor Murashkin634a5152013-02-20 17:15:11 -0800976}
977
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800978status_t CameraService::BasicClient::startCameraOps() {
979 int32_t res;
980
981 mOpsCallback = new OpsCallback(this);
982
Igor Murashkine6800ce2013-03-04 17:25:57 -0800983 {
984 ALOGV("%s: Start camera ops, package name = %s, client UID = %d",
985 __FUNCTION__, String8(mClientPackageName).string(), mClientUid);
986 }
987
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800988 mAppOpsManager.startWatchingMode(AppOpsManager::OP_CAMERA,
989 mClientPackageName, mOpsCallback);
990 res = mAppOpsManager.startOp(AppOpsManager::OP_CAMERA,
991 mClientUid, mClientPackageName);
992
993 if (res != AppOpsManager::MODE_ALLOWED) {
994 ALOGI("Camera %d: Access for \"%s\" has been revoked",
995 mCameraId, String8(mClientPackageName).string());
996 return PERMISSION_DENIED;
997 }
998 mOpsActive = true;
999 return OK;
1000}
1001
1002status_t CameraService::BasicClient::finishCameraOps() {
1003 if (mOpsActive) {
1004 mAppOpsManager.finishOp(AppOpsManager::OP_CAMERA, mClientUid,
1005 mClientPackageName);
1006 mOpsActive = false;
1007 }
1008 mAppOpsManager.stopWatchingMode(mOpsCallback);
1009 mOpsCallback.clear();
1010
1011 return OK;
1012}
1013
1014void CameraService::BasicClient::opChanged(int32_t op, const String16& packageName) {
1015 String8 name(packageName);
1016 String8 myName(mClientPackageName);
1017
1018 if (op != AppOpsManager::OP_CAMERA) {
1019 ALOGW("Unexpected app ops notification received: %d", op);
1020 return;
1021 }
1022
1023 int32_t res;
1024 res = mAppOpsManager.checkOp(AppOpsManager::OP_CAMERA,
1025 mClientUid, mClientPackageName);
1026 ALOGV("checkOp returns: %d, %s ", res,
1027 res == AppOpsManager::MODE_ALLOWED ? "ALLOWED" :
1028 res == AppOpsManager::MODE_IGNORED ? "IGNORED" :
1029 res == AppOpsManager::MODE_ERRORED ? "ERRORED" :
1030 "UNKNOWN");
1031
1032 if (res != AppOpsManager::MODE_ALLOWED) {
1033 ALOGI("Camera %d: Access for \"%s\" revoked", mCameraId,
1034 myName.string());
1035 // Reset the client PID to allow server-initiated disconnect,
1036 // and to prevent further calls by client.
1037 mClientPid = getCallingPid();
1038 notifyError();
1039 disconnect();
1040 }
1041}
1042
Mathias Agopian65ab4712010-07-14 17:59:35 -07001043// ----------------------------------------------------------------------------
1044
Keun young Parkd8973a72012-03-28 14:13:09 -07001045Mutex* CameraService::Client::getClientLockFromCookie(void* user) {
Kévin PETIT377b2ec2014-02-03 12:35:36 +00001046 return gCameraService->getClientLockById((int)(intptr_t) user);
Keun young Parkd8973a72012-03-28 14:13:09 -07001047}
1048
1049// Provide client pointer for callbacks. Client lock returned from getClientLockFromCookie should
1050// be acquired for this to be safe
1051CameraService::Client* CameraService::Client::getClientFromCookie(void* user) {
Kévin PETIT377b2ec2014-02-03 12:35:36 +00001052 BasicClient *basicClient = gCameraService->getClientByIdUnsafe((int)(intptr_t) user);
Igor Murashkine7ee7632013-06-11 18:10:18 -07001053 // OK: only CameraClient calls this, and they already cast anyway.
1054 Client* client = static_cast<Client*>(basicClient);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001055
1056 // This could happen if the Client is in the process of shutting down (the
1057 // last strong reference is gone, but the destructor hasn't finished
1058 // stopping the hardware).
Keun young Parkd8973a72012-03-28 14:13:09 -07001059 if (client == NULL) return NULL;
1060
1061 // destruction already started, so should not be accessed
1062 if (client->mDestructionStarted) return NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001063
Mathias Agopian65ab4712010-07-14 17:59:35 -07001064 return client;
1065}
1066
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001067void CameraService::Client::notifyError() {
Igor Murashkin44cfcf02013-03-01 16:22:28 -08001068 mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_RELEASED, 0);
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001069}
1070
Igor Murashkin036bc3e2012-10-08 15:09:46 -07001071// NOTE: function is idempotent
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001072void CameraService::Client::disconnect() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -07001073 ALOGV("Client::disconnect");
Igor Murashkin634a5152013-02-20 17:15:11 -08001074 BasicClient::disconnect();
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001075 mCameraService->setCameraFree(mCameraId);
Igor Murashkin93747b92013-05-01 15:42:20 -07001076
1077 StatusVector rejectSourceStates;
1078 rejectSourceStates.push_back(ICameraServiceListener::STATUS_NOT_PRESENT);
1079 rejectSourceStates.push_back(ICameraServiceListener::STATUS_ENUMERATING);
1080
1081 // Transition to PRESENT if the camera is not in either of above 2 states
Igor Murashkincba2c162013-03-20 15:56:31 -07001082 mCameraService->updateStatus(ICameraServiceListener::STATUS_PRESENT,
Igor Murashkin93747b92013-05-01 15:42:20 -07001083 mCameraId,
1084 &rejectSourceStates);
Wu-cheng Lie09591e2010-10-14 20:17:44 +08001085}
1086
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001087CameraService::Client::OpsCallback::OpsCallback(wp<BasicClient> client):
1088 mClient(client) {
1089}
1090
1091void CameraService::Client::OpsCallback::opChanged(int32_t op,
1092 const String16& packageName) {
1093 sp<BasicClient> client = mClient.promote();
1094 if (client != NULL) {
1095 client->opChanged(op, packageName);
1096 }
1097}
1098
Mathias Agopian65ab4712010-07-14 17:59:35 -07001099// ----------------------------------------------------------------------------
Igor Murashkin634a5152013-02-20 17:15:11 -08001100// IProCamera
1101// ----------------------------------------------------------------------------
1102
1103CameraService::ProClient::ProClient(const sp<CameraService>& cameraService,
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001104 const sp<IProCameraCallbacks>& remoteCallback,
1105 const String16& clientPackageName,
1106 int cameraId,
1107 int cameraFacing,
1108 int clientPid,
1109 uid_t clientUid,
1110 int servicePid)
1111 : CameraService::BasicClient(cameraService, remoteCallback->asBinder(),
1112 clientPackageName, cameraId, cameraFacing,
1113 clientPid, clientUid, servicePid)
Igor Murashkin634a5152013-02-20 17:15:11 -08001114{
1115 mRemoteCallback = remoteCallback;
1116}
1117
1118CameraService::ProClient::~ProClient() {
Igor Murashkin634a5152013-02-20 17:15:11 -08001119}
1120
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001121void CameraService::ProClient::notifyError() {
Igor Murashkine6800ce2013-03-04 17:25:57 -08001122 mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_RELEASED, 0);
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001123}
1124
Igor Murashkin634a5152013-02-20 17:15:11 -08001125// ----------------------------------------------------------------------------
Mathias Agopian65ab4712010-07-14 17:59:35 -07001126
1127static const int kDumpLockRetries = 50;
1128static const int kDumpLockSleep = 60000;
1129
1130static bool tryLock(Mutex& mutex)
1131{
1132 bool locked = false;
1133 for (int i = 0; i < kDumpLockRetries; ++i) {
1134 if (mutex.tryLock() == NO_ERROR) {
1135 locked = true;
1136 break;
1137 }
1138 usleep(kDumpLockSleep);
1139 }
1140 return locked;
1141}
1142
1143status_t CameraService::dump(int fd, const Vector<String16>& args) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001144 String8 result;
1145 if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -07001146 result.appendFormat("Permission Denial: "
Mathias Agopian65ab4712010-07-14 17:59:35 -07001147 "can't dump CameraService from pid=%d, uid=%d\n",
1148 getCallingPid(),
1149 getCallingUid());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001150 write(fd, result.string(), result.size());
1151 } else {
1152 bool locked = tryLock(mServiceLock);
1153 // failed to lock - CameraService is probably deadlocked
1154 if (!locked) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -07001155 result.append("CameraService may be deadlocked\n");
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001156 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001157 }
1158
1159 bool hasClient = false;
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001160 if (!mModule) {
1161 result = String8::format("No camera module available!\n");
1162 write(fd, result.string(), result.size());
1163 return NO_ERROR;
1164 }
1165
1166 result = String8::format("Camera module HAL API version: 0x%x\n",
1167 mModule->common.hal_api_version);
1168 result.appendFormat("Camera module API version: 0x%x\n",
1169 mModule->common.module_api_version);
1170 result.appendFormat("Camera module name: %s\n",
1171 mModule->common.name);
1172 result.appendFormat("Camera module author: %s\n",
1173 mModule->common.author);
1174 result.appendFormat("Number of camera devices: %d\n\n", mNumberOfCameras);
1175 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001176 for (int i = 0; i < mNumberOfCameras; i++) {
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001177 result = String8::format("Camera %d static information:\n", i);
1178 camera_info info;
1179
1180 status_t rc = mModule->get_camera_info(i, &info);
1181 if (rc != OK) {
1182 result.appendFormat(" Error reading static information!\n");
1183 write(fd, result.string(), result.size());
1184 } else {
1185 result.appendFormat(" Facing: %s\n",
1186 info.facing == CAMERA_FACING_BACK ? "BACK" : "FRONT");
1187 result.appendFormat(" Orientation: %d\n", info.orientation);
1188 int deviceVersion;
1189 if (mModule->common.module_api_version <
1190 CAMERA_MODULE_API_VERSION_2_0) {
1191 deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
1192 } else {
1193 deviceVersion = info.device_version;
1194 }
1195 result.appendFormat(" Device version: 0x%x\n", deviceVersion);
1196 if (deviceVersion >= CAMERA_DEVICE_API_VERSION_2_0) {
1197 result.appendFormat(" Device static metadata:\n");
1198 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -07001199 dump_indented_camera_metadata(info.static_camera_characteristics,
1200 fd, 2, 4);
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001201 } else {
1202 write(fd, result.string(), result.size());
1203 }
1204 }
1205
Igor Murashkine7ee7632013-06-11 18:10:18 -07001206 sp<BasicClient> client = mClient[i].promote();
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001207 if (client == 0) {
1208 result = String8::format(" Device is closed, no client instance\n");
1209 write(fd, result.string(), result.size());
1210 continue;
1211 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001212 hasClient = true;
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001213 result = String8::format(" Device is open. Client instance dump:\n");
1214 write(fd, result.string(), result.size());
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001215 client->dump(fd, args);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001216 }
1217 if (!hasClient) {
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001218 result = String8::format("\nNo active camera clients yet.\n");
1219 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001220 }
1221
1222 if (locked) mServiceLock.unlock();
1223
Igor Murashkinff3e31d2013-10-23 16:40:06 -07001224 // Dump camera traces if there were any
1225 write(fd, "\n", 1);
1226 camera3::CameraTraces::dump(fd, args);
1227
Mathias Agopian65ab4712010-07-14 17:59:35 -07001228 // change logging level
1229 int n = args.size();
1230 for (int i = 0; i + 1 < n; i++) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -07001231 String16 verboseOption("-v");
1232 if (args[i] == verboseOption) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001233 String8 levelStr(args[i+1]);
1234 int level = atoi(levelStr.string());
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001235 result = String8::format("\nSetting log level to %d.\n", level);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001236 setLogLevel(level);
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001237 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001238 }
1239 }
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001240
Mathias Agopian65ab4712010-07-14 17:59:35 -07001241 }
1242 return NO_ERROR;
1243}
1244
Igor Murashkinecf17e82012-10-02 16:05:11 -07001245/*virtual*/void CameraService::binderDied(
1246 const wp<IBinder> &who) {
1247
Igor Murashkin294d0ec2012-10-05 10:44:57 -07001248 /**
1249 * While tempting to promote the wp<IBinder> into a sp,
1250 * it's actually not supported by the binder driver
1251 */
1252
Igor Murashkinecf17e82012-10-02 16:05:11 -07001253 ALOGV("java clients' binder died");
1254
Igor Murashkin634a5152013-02-20 17:15:11 -08001255 sp<BasicClient> cameraClient = getClientByRemote(who);
Igor Murashkinecf17e82012-10-02 16:05:11 -07001256
Igor Murashkin294d0ec2012-10-05 10:44:57 -07001257 if (cameraClient == 0) {
Igor Murashkinecf17e82012-10-02 16:05:11 -07001258 ALOGV("java clients' binder death already cleaned up (normal case)");
1259 return;
1260 }
1261
Igor Murashkinecf17e82012-10-02 16:05:11 -07001262 ALOGW("Disconnecting camera client %p since the binder for it "
1263 "died (this pid %d)", cameraClient.get(), getCallingPid());
1264
1265 cameraClient->disconnect();
1266
1267}
1268
Igor Murashkinbfc99152013-02-27 12:55:20 -08001269void CameraService::updateStatus(ICameraServiceListener::Status status,
Igor Murashkin93747b92013-05-01 15:42:20 -07001270 int32_t cameraId,
1271 const StatusVector *rejectSourceStates) {
Igor Murashkinbfc99152013-02-27 12:55:20 -08001272 // do not lock mServiceLock here or can get into a deadlock from
1273 // connect() -> ProClient::disconnect -> updateStatus
1274 Mutex::Autolock lock(mStatusMutex);
Igor Murashkinbfc99152013-02-27 12:55:20 -08001275
1276 ICameraServiceListener::Status oldStatus = mStatusList[cameraId];
1277
1278 mStatusList[cameraId] = status;
1279
1280 if (oldStatus != status) {
1281 ALOGV("%s: Status has changed for camera ID %d from 0x%x to 0x%x",
1282 __FUNCTION__, cameraId, (uint32_t)oldStatus, (uint32_t)status);
1283
Igor Murashkincba2c162013-03-20 15:56:31 -07001284 if (oldStatus == ICameraServiceListener::STATUS_NOT_PRESENT &&
1285 (status != ICameraServiceListener::STATUS_PRESENT &&
1286 status != ICameraServiceListener::STATUS_ENUMERATING)) {
1287
1288 ALOGW("%s: From NOT_PRESENT can only transition into PRESENT"
1289 " or ENUMERATING", __FUNCTION__);
1290 mStatusList[cameraId] = oldStatus;
1291 return;
1292 }
1293
Igor Murashkin93747b92013-05-01 15:42:20 -07001294 if (rejectSourceStates != NULL) {
1295 const StatusVector &rejectList = *rejectSourceStates;
1296 StatusVector::const_iterator it = rejectList.begin();
1297
1298 /**
1299 * Sometimes we want to conditionally do a transition.
1300 * For example if a client disconnects, we want to go to PRESENT
1301 * only if we weren't already in NOT_PRESENT or ENUMERATING.
1302 */
1303 for (; it != rejectList.end(); ++it) {
1304 if (oldStatus == *it) {
1305 ALOGV("%s: Rejecting status transition for Camera ID %d, "
1306 " since the source state was was in one of the bad "
1307 " states.", __FUNCTION__, cameraId);
1308 mStatusList[cameraId] = oldStatus;
1309 return;
1310 }
1311 }
1312 }
1313
Igor Murashkinbfc99152013-02-27 12:55:20 -08001314 /**
1315 * ProClients lose their exclusive lock.
1316 * - Done before the CameraClient can initialize the HAL device,
1317 * since we want to be able to close it before they get to initialize
1318 */
1319 if (status == ICameraServiceListener::STATUS_NOT_AVAILABLE) {
1320 Vector<wp<ProClient> > proClients(mProClientList[cameraId]);
1321 Vector<wp<ProClient> >::const_iterator it;
1322
1323 for (it = proClients.begin(); it != proClients.end(); ++it) {
1324 sp<ProClient> proCl = it->promote();
1325 if (proCl.get() != NULL) {
1326 proCl->onExclusiveLockStolen();
1327 }
1328 }
1329 }
1330
1331 Vector<sp<ICameraServiceListener> >::const_iterator it;
1332 for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
1333 (*it)->onStatusChanged(status, cameraId);
1334 }
1335 }
1336}
1337
Igor Murashkincba2c162013-03-20 15:56:31 -07001338ICameraServiceListener::Status CameraService::getStatus(int cameraId) const {
1339 if (cameraId < 0 || cameraId >= MAX_CAMERAS) {
1340 ALOGE("%s: Invalid camera ID %d", __FUNCTION__, cameraId);
1341 return ICameraServiceListener::STATUS_UNKNOWN;
1342 }
1343
1344 Mutex::Autolock al(mStatusMutex);
1345 return mStatusList[cameraId];
1346}
1347
Mathias Agopian65ab4712010-07-14 17:59:35 -07001348}; // namespace android