blob: 757a781e8ac03d11eeedf68ca95b144f1dffa9a1 [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>
35#include <media/mediaplayer.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070036#include <utils/Errors.h>
37#include <utils/Log.h>
38#include <utils/String16.h>
39
40#include "CameraService.h"
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -070041#include "CameraClient.h"
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070042#include "Camera2Client.h"
Igor Murashkin985fd302013-02-20 18:24:43 -080043#include "ProCamera2Client.h"
Mathias Agopian65ab4712010-07-14 17:59:35 -070044
45namespace android {
46
47// ----------------------------------------------------------------------------
48// Logging support -- this is for debugging only
49// Use "adb shell dumpsys media.camera -v 1" to change it.
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -070050volatile int32_t gLogLevel = 0;
Mathias Agopian65ab4712010-07-14 17:59:35 -070051
Steve Blockb8a80522011-12-20 16:23:08 +000052#define LOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__);
53#define LOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__);
Mathias Agopian65ab4712010-07-14 17:59:35 -070054
55static void setLogLevel(int level) {
56 android_atomic_write(level, &gLogLevel);
57}
58
59// ----------------------------------------------------------------------------
60
61static int getCallingPid() {
62 return IPCThreadState::self()->getCallingPid();
63}
64
65static int getCallingUid() {
66 return IPCThreadState::self()->getCallingUid();
67}
68
Igor Murashkincba2c162013-03-20 15:56:31 -070069extern "C" {
70static void camera_device_status_change(
71 const struct camera_module_callbacks* callbacks,
72 int camera_id,
73 int new_status) {
74 sp<CameraService> cs = const_cast<CameraService*>(
75 static_cast<const CameraService*>(callbacks));
76
77 cs->onDeviceStatusChanged(
78 camera_id,
79 new_status);
80}
81} // extern "C"
82
Mathias Agopian65ab4712010-07-14 17:59:35 -070083// ----------------------------------------------------------------------------
84
85// This is ugly and only safe if we never re-create the CameraService, but
86// should be ok for now.
87static CameraService *gCameraService;
88
89CameraService::CameraService()
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -080090 :mSoundRef(0), mModule(0)
Mathias Agopian65ab4712010-07-14 17:59:35 -070091{
Steve Blockdf64d152012-01-04 20:05:49 +000092 ALOGI("CameraService started (pid=%d)", getpid());
Mathias Agopian65ab4712010-07-14 17:59:35 -070093 gCameraService = this;
Igor Murashkinbfc99152013-02-27 12:55:20 -080094
95 for (size_t i = 0; i < MAX_CAMERAS; ++i) {
Igor Murashkincba2c162013-03-20 15:56:31 -070096 mStatusList[i] = ICameraServiceListener::STATUS_PRESENT;
Igor Murashkinbfc99152013-02-27 12:55:20 -080097 }
Igor Murashkincba2c162013-03-20 15:56:31 -070098
99 this->camera_device_status_change = android::camera_device_status_change;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700100}
101
Iliyan Malchev8951a972011-04-14 16:55:59 -0700102void CameraService::onFirstRef()
103{
Igor Murashkin634a5152013-02-20 17:15:11 -0800104 LOG1("CameraService::onFirstRef");
105
Iliyan Malchev8951a972011-04-14 16:55:59 -0700106 BnCameraService::onFirstRef();
107
108 if (hw_get_module(CAMERA_HARDWARE_MODULE_ID,
109 (const hw_module_t **)&mModule) < 0) {
Steve Block29357bc2012-01-06 19:20:56 +0000110 ALOGE("Could not load camera HAL module");
Iliyan Malchev8951a972011-04-14 16:55:59 -0700111 mNumberOfCameras = 0;
112 }
113 else {
Alex Rayc0dd54f2013-02-20 13:39:37 -0800114 ALOGI("Loaded \"%s\" camera module", mModule->common.name);
Iliyan Malchev8951a972011-04-14 16:55:59 -0700115 mNumberOfCameras = mModule->get_number_of_cameras();
116 if (mNumberOfCameras > MAX_CAMERAS) {
Steve Block29357bc2012-01-06 19:20:56 +0000117 ALOGE("Number of cameras(%d) > MAX_CAMERAS(%d).",
Iliyan Malchev8951a972011-04-14 16:55:59 -0700118 mNumberOfCameras, MAX_CAMERAS);
119 mNumberOfCameras = MAX_CAMERAS;
120 }
121 for (int i = 0; i < mNumberOfCameras; i++) {
122 setCameraFree(i);
123 }
Igor Murashkincba2c162013-03-20 15:56:31 -0700124
125 if (mModule->common.module_api_version >=
126 CAMERA_MODULE_API_VERSION_2_1) {
127 mModule->set_callbacks(this);
128 }
Iliyan Malchev8951a972011-04-14 16:55:59 -0700129 }
130}
131
Mathias Agopian65ab4712010-07-14 17:59:35 -0700132CameraService::~CameraService() {
133 for (int i = 0; i < mNumberOfCameras; i++) {
134 if (mBusy[i]) {
Steve Block29357bc2012-01-06 19:20:56 +0000135 ALOGE("camera %d is still in use in destructor!", i);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700136 }
137 }
138
139 gCameraService = NULL;
140}
141
Igor Murashkincba2c162013-03-20 15:56:31 -0700142void CameraService::onDeviceStatusChanged(int cameraId,
143 int newStatus)
144{
145 ALOGI("%s: Status changed for cameraId=%d, newStatus=%d", __FUNCTION__,
146 cameraId, newStatus);
147
148 if (cameraId < 0 || cameraId >= MAX_CAMERAS) {
149 ALOGE("%s: Bad camera ID %d", __FUNCTION__, cameraId);
150 return;
151 }
152
153 if ((int)getStatus(cameraId) == newStatus) {
154 ALOGE("%s: State transition to the same status 0x%x not allowed",
155 __FUNCTION__, (uint32_t)newStatus);
156 return;
157 }
158
159 /* don't do this in updateStatus
160 since it is also called from connect and we could get into a deadlock */
161 if (newStatus == CAMERA_DEVICE_STATUS_NOT_PRESENT) {
162 Vector<sp<BasicClient> > clientsToDisconnect;
163 {
164 Mutex::Autolock al(mServiceLock);
165
166 /* Find all clients that we need to disconnect */
167 sp<Client> client = mClient[cameraId].promote();
168 if (client.get() != NULL) {
169 clientsToDisconnect.push_back(client);
170 }
171
172 int i = cameraId;
173 for (size_t j = 0; j < mProClientList[i].size(); ++j) {
174 sp<ProClient> cl = mProClientList[i][j].promote();
175 if (cl != NULL) {
176 clientsToDisconnect.push_back(cl);
177 }
178 }
179 }
180
181 /* now disconnect them. don't hold the lock
182 or we can get into a deadlock */
183
184 for (size_t i = 0; i < clientsToDisconnect.size(); ++i) {
185 sp<BasicClient> client = clientsToDisconnect[i];
186
187 client->disconnect();
188 /**
189 * The remote app will no longer be able to call methods on the
190 * client since the client PID will be reset to 0
191 */
192 }
193
194 ALOGV("%s: After unplug, disconnected %d clients",
195 __FUNCTION__, clientsToDisconnect.size());
196 }
197
198 updateStatus(
199 static_cast<ICameraServiceListener::Status>(newStatus), cameraId);
200
201}
202
Mathias Agopian65ab4712010-07-14 17:59:35 -0700203int32_t CameraService::getNumberOfCameras() {
204 return mNumberOfCameras;
205}
206
207status_t CameraService::getCameraInfo(int cameraId,
208 struct CameraInfo* cameraInfo) {
Iliyan Malchev8951a972011-04-14 16:55:59 -0700209 if (!mModule) {
210 return NO_INIT;
211 }
212
Mathias Agopian65ab4712010-07-14 17:59:35 -0700213 if (cameraId < 0 || cameraId >= mNumberOfCameras) {
214 return BAD_VALUE;
215 }
216
Iliyan Malchev8951a972011-04-14 16:55:59 -0700217 struct camera_info info;
218 status_t rc = mModule->get_camera_info(cameraId, &info);
219 cameraInfo->facing = info.facing;
220 cameraInfo->orientation = info.orientation;
221 return rc;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700222}
223
Igor Murashkin634a5152013-02-20 17:15:11 -0800224int CameraService::getDeviceVersion(int cameraId, int* facing) {
225 struct camera_info info;
226 if (mModule->get_camera_info(cameraId, &info) != OK) {
227 return -1;
228 }
229
230 int deviceVersion;
231 if (mModule->common.module_api_version >= CAMERA_MODULE_API_VERSION_2_0) {
232 deviceVersion = info.device_version;
233 } else {
234 deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
235 }
236
237 if (facing) {
238 *facing = info.facing;
239 }
240
241 return deviceVersion;
242}
243
Igor Murashkinbfc99152013-02-27 12:55:20 -0800244bool CameraService::isValidCameraId(int cameraId) {
245 int facing;
246 int deviceVersion = getDeviceVersion(cameraId, &facing);
247
248 switch(deviceVersion) {
249 case CAMERA_DEVICE_API_VERSION_1_0:
250 case CAMERA_DEVICE_API_VERSION_2_0:
251 case CAMERA_DEVICE_API_VERSION_2_1:
252 case CAMERA_DEVICE_API_VERSION_3_0:
253 return true;
254 default:
255 return false;
256 }
257
258 return false;
259}
260
Igor Murashkine6800ce2013-03-04 17:25:57 -0800261bool CameraService::validateConnect(int cameraId,
262 /*inout*/
263 int& clientUid) const {
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800264
Mathias Agopian65ab4712010-07-14 17:59:35 -0700265 int callingPid = getCallingPid();
Tyler Luu5861a9a2011-10-06 00:00:03 -0500266
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800267 if (clientUid == USE_CALLING_UID) {
268 clientUid = getCallingUid();
269 } else {
270 // We only trust our own process to forward client UIDs
271 if (callingPid != getpid()) {
272 ALOGE("CameraService::connect X (pid %d) rejected (don't trust clientUid)",
273 callingPid);
Igor Murashkine6800ce2013-03-04 17:25:57 -0800274 return false;
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800275 }
276 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700277
Iliyan Malchev8951a972011-04-14 16:55:59 -0700278 if (!mModule) {
Steve Block29357bc2012-01-06 19:20:56 +0000279 ALOGE("Camera HAL module not loaded");
Igor Murashkine6800ce2013-03-04 17:25:57 -0800280 return false;
Iliyan Malchev8951a972011-04-14 16:55:59 -0700281 }
282
Mathias Agopian65ab4712010-07-14 17:59:35 -0700283 if (cameraId < 0 || cameraId >= mNumberOfCameras) {
Steve Block29357bc2012-01-06 19:20:56 +0000284 ALOGE("CameraService::connect X (pid %d) rejected (invalid cameraId %d).",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700285 callingPid, cameraId);
Igor Murashkine6800ce2013-03-04 17:25:57 -0800286 return false;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700287 }
288
Wu-cheng Lia3355432011-05-20 14:54:25 +0800289 char value[PROPERTY_VALUE_MAX];
290 property_get("sys.secpolicy.camera.disabled", value, "0");
291 if (strcmp(value, "1") == 0) {
292 // Camera is disabled by DevicePolicyManager.
Steve Blockdf64d152012-01-04 20:05:49 +0000293 ALOGI("Camera is disabled. connect X (pid %d) rejected", callingPid);
Igor Murashkine6800ce2013-03-04 17:25:57 -0800294 return false;
Wu-cheng Lia3355432011-05-20 14:54:25 +0800295 }
296
Igor Murashkincba2c162013-03-20 15:56:31 -0700297 ICameraServiceListener::Status currentStatus = getStatus(cameraId);
298 if (currentStatus == ICameraServiceListener::STATUS_NOT_PRESENT) {
299 ALOGI("Camera is not plugged in,"
300 " connect X (pid %d) rejected", callingPid);
301 return false;
302 } else if (currentStatus == ICameraServiceListener::STATUS_ENUMERATING) {
303 ALOGI("Camera is enumerating,"
304 " connect X (pid %d) rejected", callingPid);
305 return false;
306 }
307 // Else don't check for STATUS_NOT_AVAILABLE.
308 // -- It's done implicitly in canConnectUnsafe /w the mBusy array
309
Igor Murashkine6800ce2013-03-04 17:25:57 -0800310 return true;
311}
312
313bool CameraService::canConnectUnsafe(int cameraId,
314 const String16& clientPackageName,
315 const sp<IBinder>& remoteCallback,
316 sp<Client> &client) {
317 String8 clientName8(clientPackageName);
318 int callingPid = getCallingPid();
319
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800320 if (mClient[cameraId] != 0) {
321 client = mClient[cameraId].promote();
322 if (client != 0) {
Igor Murashkine6800ce2013-03-04 17:25:57 -0800323 if (remoteCallback == client->getRemoteCallback()->asBinder()) {
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800324 LOG1("CameraService::connect X (pid %d) (the same client)",
325 callingPid);
Igor Murashkine6800ce2013-03-04 17:25:57 -0800326 return true;
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800327 } else {
Igor Murashkine6800ce2013-03-04 17:25:57 -0800328 // TODOSC: need to support 1 regular client,
329 // multiple shared clients here
330 ALOGW("CameraService::connect X (pid %d) rejected"
331 " (existing client).", callingPid);
332 return false;
Wu-cheng Li2fd24402012-02-23 19:01:00 -0800333 }
Wu-cheng Li2fd24402012-02-23 19:01:00 -0800334 }
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800335 mClient[cameraId].clear();
336 }
337
Igor Murashkin634a5152013-02-20 17:15:11 -0800338 /*
339 mBusy is set to false as the last step of the Client destructor,
340 after which it is guaranteed that the Client destructor has finished (
341 including any inherited destructors)
342
343 We only need this for a Client subclasses since we don't allow
344 multiple Clents to be opened concurrently, but multiple BasicClient
345 would be fine
346 */
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800347 if (mBusy[cameraId]) {
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800348 ALOGW("CameraService::connect X (pid %d, \"%s\") rejected"
349 " (camera %d is still busy).", callingPid,
350 clientName8.string(), cameraId);
Igor Murashkine6800ce2013-03-04 17:25:57 -0800351 return false;
352 }
353
354 return true;
355}
356
357sp<ICamera> CameraService::connect(
358 const sp<ICameraClient>& cameraClient,
359 int cameraId,
360 const String16& clientPackageName,
361 int clientUid) {
362
363 String8 clientName8(clientPackageName);
364 int callingPid = getCallingPid();
365
366 LOG1("CameraService::connect E (pid %d \"%s\", id %d)", callingPid,
367 clientName8.string(), cameraId);
368
369 if (!validateConnect(cameraId, /*inout*/clientUid)) {
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800370 return NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700371 }
372
Igor Murashkine6800ce2013-03-04 17:25:57 -0800373 sp<Client> client;
374
Igor Murashkinacd695c2013-03-13 17:23:00 -0700375 {
376 Mutex::Autolock lock(mServiceLock);
377 if (!canConnectUnsafe(cameraId, clientPackageName,
378 cameraClient->asBinder(),
379 /*out*/client)) {
380 return NULL;
381 } else if (client.get() != NULL) {
382 return client;
383 }
384
385 int facing = -1;
386 int deviceVersion = getDeviceVersion(cameraId, &facing);
387
388 // If there are other non-exclusive users of the camera,
389 // this will tear them down before we can reuse the camera
390 if (isValidCameraId(cameraId)) {
Igor Murashkincba2c162013-03-20 15:56:31 -0700391 // transition from PRESENT -> NOT_AVAILABLE
Igor Murashkinacd695c2013-03-13 17:23:00 -0700392 updateStatus(ICameraServiceListener::STATUS_NOT_AVAILABLE,
393 cameraId);
394 }
395
396 switch(deviceVersion) {
397 case CAMERA_DEVICE_API_VERSION_1_0:
398 client = new CameraClient(this, cameraClient,
399 clientPackageName, cameraId,
400 facing, callingPid, clientUid, getpid());
401 break;
402 case CAMERA_DEVICE_API_VERSION_2_0:
403 case CAMERA_DEVICE_API_VERSION_2_1:
404 case CAMERA_DEVICE_API_VERSION_3_0:
405 client = new Camera2Client(this, cameraClient,
406 clientPackageName, cameraId,
407 facing, callingPid, clientUid, getpid(),
408 deviceVersion);
409 break;
410 case -1:
411 ALOGE("Invalid camera id %d", cameraId);
412 return NULL;
413 default:
414 ALOGE("Unknown camera device HAL version: %d", deviceVersion);
415 return NULL;
416 }
417
418 if (!connectFinishUnsafe(client, client->asBinder())) {
419 // this is probably not recoverable.. maybe the client can try again
Igor Murashkincba2c162013-03-20 15:56:31 -0700420 // OK: we can only get here if we were originally in PRESENT state
421 updateStatus(ICameraServiceListener::STATUS_PRESENT, cameraId);
Igor Murashkinacd695c2013-03-13 17:23:00 -0700422
423 return NULL;
424 }
425
426 mClient[cameraId] = client;
427 LOG1("CameraService::connect X (id %d, this pid is %d)", cameraId,
428 getpid());
Igor Murashkine6800ce2013-03-04 17:25:57 -0800429 }
Igor Murashkinacd695c2013-03-13 17:23:00 -0700430 // important: release the mutex here so the client can call back
431 // into the service from its destructor (can be at the end of the call)
Igor Murashkinbfc99152013-02-27 12:55:20 -0800432
Mathias Agopian65ab4712010-07-14 17:59:35 -0700433 return client;
434}
435
Igor Murashkine6800ce2013-03-04 17:25:57 -0800436bool CameraService::connectFinishUnsafe(const sp<BasicClient>& client,
437 const sp<IBinder>& clientBinder) {
438 if (client->initialize(mModule) != OK) {
439 return false;
440 }
441
442 clientBinder->linkToDeath(this);
443
444 return true;
445}
446
Igor Murashkin634a5152013-02-20 17:15:11 -0800447sp<IProCameraUser> CameraService::connect(
448 const sp<IProCameraCallbacks>& cameraCb,
Igor Murashkinc073ba52013-02-26 14:32:34 -0800449 int cameraId,
450 const String16& clientPackageName,
451 int clientUid)
Igor Murashkin634a5152013-02-20 17:15:11 -0800452{
Igor Murashkinbfc99152013-02-27 12:55:20 -0800453 String8 clientName8(clientPackageName);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700454 int callingPid = getCallingPid();
Igor Murashkin634a5152013-02-20 17:15:11 -0800455
Igor Murashkine6800ce2013-03-04 17:25:57 -0800456 LOG1("CameraService::connectPro E (pid %d \"%s\", id %d)", callingPid,
457 clientName8.string(), cameraId);
Igor Murashkinc073ba52013-02-26 14:32:34 -0800458
Igor Murashkine6800ce2013-03-04 17:25:57 -0800459 if (!validateConnect(cameraId, /*inout*/clientUid)) {
Igor Murashkin634a5152013-02-20 17:15:11 -0800460 return NULL;
461 }
462
Igor Murashkinacd695c2013-03-13 17:23:00 -0700463 sp<ProClient> client;
Igor Murashkine6800ce2013-03-04 17:25:57 -0800464 {
Igor Murashkinacd695c2013-03-13 17:23:00 -0700465 Mutex::Autolock lock(mServiceLock);
466 {
467 sp<Client> client;
468 if (!canConnectUnsafe(cameraId, clientPackageName,
469 cameraCb->asBinder(),
470 /*out*/client)) {
471 return NULL;
472 }
473 }
474
475 int facing = -1;
476 int deviceVersion = getDeviceVersion(cameraId, &facing);
477
478 switch(deviceVersion) {
479 case CAMERA_DEVICE_API_VERSION_1_0:
480 ALOGE("Camera id %d uses HALv1, doesn't support ProCamera",
481 cameraId);
482 return NULL;
483 break;
484 case CAMERA_DEVICE_API_VERSION_2_0:
485 case CAMERA_DEVICE_API_VERSION_2_1:
486 client = new ProCamera2Client(this, cameraCb, String16(),
487 cameraId, facing, callingPid, USE_CALLING_UID, getpid());
488 break;
489 case -1:
490 ALOGE("Invalid camera id %d", cameraId);
491 return NULL;
492 default:
493 ALOGE("Unknown camera device HAL version: %d", deviceVersion);
Igor Murashkine6800ce2013-03-04 17:25:57 -0800494 return NULL;
495 }
Igor Murashkinacd695c2013-03-13 17:23:00 -0700496
497 if (!connectFinishUnsafe(client, client->asBinder())) {
498 return NULL;
499 }
500
501 mProClientList[cameraId].push(client);
502
503 LOG1("CameraService::connectPro X (id %d, this pid is %d)", cameraId,
504 getpid());
Igor Murashkine6800ce2013-03-04 17:25:57 -0800505 }
Igor Murashkinacd695c2013-03-13 17:23:00 -0700506 // important: release the mutex here so the client can call back
507 // into the service from its destructor (can be at the end of the call)
Igor Murashkine6800ce2013-03-04 17:25:57 -0800508
Igor Murashkin634a5152013-02-20 17:15:11 -0800509 return client;
Igor Murashkinbfc99152013-02-27 12:55:20 -0800510}
Igor Murashkin634a5152013-02-20 17:15:11 -0800511
Igor Murashkinbfc99152013-02-27 12:55:20 -0800512status_t CameraService::addListener(
513 const sp<ICameraServiceListener>& listener) {
514 ALOGV("%s: Add listener %p", __FUNCTION__, listener.get());
Igor Murashkin634a5152013-02-20 17:15:11 -0800515
Igor Murashkinbfc99152013-02-27 12:55:20 -0800516 Mutex::Autolock lock(mServiceLock);
517
518 Vector<sp<ICameraServiceListener> >::iterator it, end;
519 for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
520 if ((*it)->asBinder() == listener->asBinder()) {
521 ALOGW("%s: Tried to add listener %p which was already subscribed",
522 __FUNCTION__, listener.get());
523 return ALREADY_EXISTS;
524 }
525 }
526
527 mListenerList.push_back(listener);
528
Igor Murashkincba2c162013-03-20 15:56:31 -0700529 /* Immediately signal current status to this listener only */
530 {
531 Mutex::Autolock m(mStatusMutex) ;
532 int numCams = getNumberOfCameras();
533 for (int i = 0; i < numCams; ++i) {
534 listener->onStatusChanged(mStatusList[i], i);
535 }
536 }
537
Igor Murashkinbfc99152013-02-27 12:55:20 -0800538 return OK;
539}
540status_t CameraService::removeListener(
541 const sp<ICameraServiceListener>& listener) {
542 ALOGV("%s: Remove listener %p", __FUNCTION__, listener.get());
543
544 Mutex::Autolock lock(mServiceLock);
545
546 Vector<sp<ICameraServiceListener> >::iterator it;
547 for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
548 if ((*it)->asBinder() == listener->asBinder()) {
549 mListenerList.erase(it);
550 return OK;
551 }
552 }
553
554 ALOGW("%s: Tried to remove a listener %p which was not subscribed",
555 __FUNCTION__, listener.get());
556
557 return BAD_VALUE;
Igor Murashkin634a5152013-02-20 17:15:11 -0800558}
559
560void CameraService::removeClientByRemote(const wp<IBinder>& remoteBinder) {
561 int callingPid = getCallingPid();
562 LOG1("CameraService::removeClientByRemote E (pid %d)", callingPid);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700563
Igor Murashkinecf17e82012-10-02 16:05:11 -0700564 // Declare this before the lock to make absolutely sure the
565 // destructor won't be called with the lock held.
566 Mutex::Autolock lock(mServiceLock);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700567
Igor Murashkinecf17e82012-10-02 16:05:11 -0700568 int outIndex;
Igor Murashkin634a5152013-02-20 17:15:11 -0800569 sp<Client> client = findClientUnsafe(remoteBinder, outIndex);
Igor Murashkinecf17e82012-10-02 16:05:11 -0700570
571 if (client != 0) {
572 // Found our camera, clear and leave.
573 LOG1("removeClient: clear camera %d", outIndex);
574 mClient[outIndex].clear();
575
576 client->unlinkToDeath(this);
Igor Murashkin634a5152013-02-20 17:15:11 -0800577 } else {
578
579 sp<ProClient> clientPro = findProClientUnsafe(remoteBinder);
580
581 if (clientPro != NULL) {
582 // Found our camera, clear and leave.
583 LOG1("removeClient: clear pro %p", clientPro.get());
584
585 clientPro->getRemoteCallback()->asBinder()->unlinkToDeath(this);
586 }
Igor Murashkinecf17e82012-10-02 16:05:11 -0700587 }
588
Igor Murashkin634a5152013-02-20 17:15:11 -0800589 LOG1("CameraService::removeClientByRemote X (pid %d)", callingPid);
590}
591
592sp<CameraService::ProClient> CameraService::findProClientUnsafe(
593 const wp<IBinder>& cameraCallbacksRemote)
594{
595 sp<ProClient> clientPro;
596
597 for (int i = 0; i < mNumberOfCameras; ++i) {
598 Vector<size_t> removeIdx;
599
600 for (size_t j = 0; j < mProClientList[i].size(); ++j) {
601 wp<ProClient> cl = mProClientList[i][j];
602
603 sp<ProClient> clStrong = cl.promote();
604 if (clStrong != NULL && clStrong->getRemote() == cameraCallbacksRemote) {
605 clientPro = clStrong;
606 break;
607 } else if (clStrong == NULL) {
608 // mark to clean up dead ptr
609 removeIdx.push(j);
610 }
611 }
612
613 // remove stale ptrs (in reverse so the indices dont change)
614 for (ssize_t j = (ssize_t)removeIdx.size() - 1; j >= 0; --j) {
615 mProClientList[i].removeAt(removeIdx[j]);
616 }
617
618 }
619
620 return clientPro;
Igor Murashkinecf17e82012-10-02 16:05:11 -0700621}
622
623sp<CameraService::Client> CameraService::findClientUnsafe(
Igor Murashkin294d0ec2012-10-05 10:44:57 -0700624 const wp<IBinder>& cameraClient, int& outIndex) {
Igor Murashkinecf17e82012-10-02 16:05:11 -0700625 sp<Client> client;
626
627 for (int i = 0; i < mNumberOfCameras; i++) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700628
629 // This happens when we have already disconnected (or this is
630 // just another unused camera).
631 if (mClient[i] == 0) continue;
632
633 // Promote mClient. It can fail if we are called from this path:
Igor Murashkin634a5152013-02-20 17:15:11 -0800634 // Client::~Client() -> disconnect() -> removeClientByRemote().
Mathias Agopian65ab4712010-07-14 17:59:35 -0700635 client = mClient[i].promote();
636
Igor Murashkinecf17e82012-10-02 16:05:11 -0700637 // Clean up stale client entry
638 if (client == NULL) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700639 mClient[i].clear();
640 continue;
641 }
642
Igor Murashkin44cfcf02013-03-01 16:22:28 -0800643 if (cameraClient == client->getRemoteCallback()->asBinder()) {
Igor Murashkinecf17e82012-10-02 16:05:11 -0700644 // Found our camera
645 outIndex = i;
646 return client;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700647 }
648 }
649
Igor Murashkinecf17e82012-10-02 16:05:11 -0700650 outIndex = -1;
651 return NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700652}
653
Keun young Parkd8973a72012-03-28 14:13:09 -0700654CameraService::Client* CameraService::getClientByIdUnsafe(int cameraId) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700655 if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
Keun young Parkd8973a72012-03-28 14:13:09 -0700656 return mClient[cameraId].unsafe_get();
657}
658
659Mutex* CameraService::getClientLockById(int cameraId) {
660 if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
661 return &mClientLock[cameraId];
Mathias Agopian65ab4712010-07-14 17:59:35 -0700662}
663
Igor Murashkin634a5152013-02-20 17:15:11 -0800664sp<CameraService::BasicClient> CameraService::getClientByRemote(
Igor Murashkin294d0ec2012-10-05 10:44:57 -0700665 const wp<IBinder>& cameraClient) {
Igor Murashkinecf17e82012-10-02 16:05:11 -0700666
667 // Declare this before the lock to make absolutely sure the
668 // destructor won't be called with the lock held.
Igor Murashkin634a5152013-02-20 17:15:11 -0800669 sp<BasicClient> client;
Igor Murashkinecf17e82012-10-02 16:05:11 -0700670
671 Mutex::Autolock lock(mServiceLock);
672
673 int outIndex;
674 client = findClientUnsafe(cameraClient, outIndex);
675
676 return client;
677}
678
Mathias Agopian65ab4712010-07-14 17:59:35 -0700679status_t CameraService::onTransact(
680 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
681 // Permission checks
682 switch (code) {
683 case BnCameraService::CONNECT:
Igor Murashkin634a5152013-02-20 17:15:11 -0800684 case BnCameraService::CONNECT_PRO:
Mathias Agopian65ab4712010-07-14 17:59:35 -0700685 const int pid = getCallingPid();
686 const int self_pid = getpid();
687 if (pid != self_pid) {
688 // we're called from a different process, do the real check
689 if (!checkCallingPermission(
690 String16("android.permission.CAMERA"))) {
691 const int uid = getCallingUid();
Steve Block29357bc2012-01-06 19:20:56 +0000692 ALOGE("Permission Denial: "
Mathias Agopian65ab4712010-07-14 17:59:35 -0700693 "can't use the camera pid=%d, uid=%d", pid, uid);
694 return PERMISSION_DENIED;
695 }
696 }
697 break;
698 }
699
700 return BnCameraService::onTransact(code, data, reply, flags);
701}
702
703// The reason we need this busy bit is a new CameraService::connect() request
704// may come in while the previous Client's destructor has not been run or is
705// still running. If the last strong reference of the previous Client is gone
706// but the destructor has not been finished, we should not allow the new Client
707// to be created because we need to wait for the previous Client to tear down
708// the hardware first.
709void CameraService::setCameraBusy(int cameraId) {
710 android_atomic_write(1, &mBusy[cameraId]);
Igor Murashkinecf17e82012-10-02 16:05:11 -0700711
712 ALOGV("setCameraBusy cameraId=%d", cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700713}
714
715void CameraService::setCameraFree(int cameraId) {
716 android_atomic_write(0, &mBusy[cameraId]);
Igor Murashkinecf17e82012-10-02 16:05:11 -0700717
718 ALOGV("setCameraFree cameraId=%d", cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700719}
720
721// We share the media players for shutter and recording sound for all clients.
722// A reference count is kept to determine when we will actually release the
723// media players.
724
Chih-Chung Changff4f55c2011-10-17 19:03:12 +0800725MediaPlayer* CameraService::newMediaPlayer(const char *file) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700726 MediaPlayer* mp = new MediaPlayer();
727 if (mp->setDataSource(file, NULL) == NO_ERROR) {
Eino-Ville Talvala60a78ac2012-01-05 15:34:53 -0800728 mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700729 mp->prepare();
730 } else {
Steve Block29357bc2012-01-06 19:20:56 +0000731 ALOGE("Failed to load CameraService sounds: %s", file);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700732 return NULL;
733 }
734 return mp;
735}
736
737void CameraService::loadSound() {
738 Mutex::Autolock lock(mSoundLock);
739 LOG1("CameraService::loadSound ref=%d", mSoundRef);
740 if (mSoundRef++) return;
741
742 mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
743 mSoundPlayer[SOUND_RECORDING] = newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");
744}
745
746void CameraService::releaseSound() {
747 Mutex::Autolock lock(mSoundLock);
748 LOG1("CameraService::releaseSound ref=%d", mSoundRef);
749 if (--mSoundRef) return;
750
751 for (int i = 0; i < NUM_SOUNDS; i++) {
752 if (mSoundPlayer[i] != 0) {
753 mSoundPlayer[i]->disconnect();
754 mSoundPlayer[i].clear();
755 }
756 }
757}
758
759void CameraService::playSound(sound_kind kind) {
760 LOG1("playSound(%d)", kind);
761 Mutex::Autolock lock(mSoundLock);
762 sp<MediaPlayer> player = mSoundPlayer[kind];
763 if (player != 0) {
Chih-Chung Chang8888a752011-10-20 10:47:26 +0800764 player->seekTo(0);
765 player->start();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700766 }
767}
768
769// ----------------------------------------------------------------------------
770
771CameraService::Client::Client(const sp<CameraService>& cameraService,
Wu-cheng Lib7a67942010-08-17 15:45:37 -0700772 const sp<ICameraClient>& cameraClient,
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800773 const String16& clientPackageName,
774 int cameraId, int cameraFacing,
775 int clientPid, uid_t clientUid,
776 int servicePid) :
Igor Murashkin634a5152013-02-20 17:15:11 -0800777 CameraService::BasicClient(cameraService, cameraClient->asBinder(),
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800778 clientPackageName,
779 cameraId, cameraFacing,
780 clientPid, clientUid,
781 servicePid)
Igor Murashkin634a5152013-02-20 17:15:11 -0800782{
Mathias Agopian65ab4712010-07-14 17:59:35 -0700783 int callingPid = getCallingPid();
Wu-cheng Li2fd24402012-02-23 19:01:00 -0800784 LOG1("Client::Client E (pid %d, id %d)", callingPid, cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700785
Igor Murashkin44cfcf02013-03-01 16:22:28 -0800786 mRemoteCallback = cameraClient;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700787
Mathias Agopian65ab4712010-07-14 17:59:35 -0700788 cameraService->setCameraBusy(cameraId);
789 cameraService->loadSound();
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800790
Wu-cheng Li2fd24402012-02-23 19:01:00 -0800791 LOG1("Client::Client X (pid %d, id %d)", callingPid, cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700792}
793
Mathias Agopian65ab4712010-07-14 17:59:35 -0700794// tear down the client
795CameraService::Client::~Client() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700796 ALOGV("~Client");
Igor Murashkin634a5152013-02-20 17:15:11 -0800797 mDestructionStarted = true;
798
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700799 mCameraService->releaseSound();
Igor Murashkin036bc3e2012-10-08 15:09:46 -0700800 // unconditionally disconnect. function is idempotent
801 Client::disconnect();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700802}
803
Igor Murashkin634a5152013-02-20 17:15:11 -0800804CameraService::BasicClient::BasicClient(const sp<CameraService>& cameraService,
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800805 const sp<IBinder>& remoteCallback,
806 const String16& clientPackageName,
807 int cameraId, int cameraFacing,
808 int clientPid, uid_t clientUid,
809 int servicePid):
810 mClientPackageName(clientPackageName)
Igor Murashkin634a5152013-02-20 17:15:11 -0800811{
812 mCameraService = cameraService;
Igor Murashkin44cfcf02013-03-01 16:22:28 -0800813 mRemoteBinder = remoteCallback;
Igor Murashkin634a5152013-02-20 17:15:11 -0800814 mCameraId = cameraId;
815 mCameraFacing = cameraFacing;
816 mClientPid = clientPid;
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800817 mClientUid = clientUid;
Igor Murashkin634a5152013-02-20 17:15:11 -0800818 mServicePid = servicePid;
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800819 mOpsActive = false;
Igor Murashkin634a5152013-02-20 17:15:11 -0800820 mDestructionStarted = false;
821}
822
823CameraService::BasicClient::~BasicClient() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700824 ALOGV("~BasicClient");
Igor Murashkin634a5152013-02-20 17:15:11 -0800825 mDestructionStarted = true;
826}
827
828void CameraService::BasicClient::disconnect() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700829 ALOGV("BasicClient::disconnect");
Igor Murashkin44cfcf02013-03-01 16:22:28 -0800830 mCameraService->removeClientByRemote(mRemoteBinder);
Igor Murashkincba2c162013-03-20 15:56:31 -0700831 // client shouldn't be able to call into us anymore
832 mClientPid = 0;
Igor Murashkin634a5152013-02-20 17:15:11 -0800833}
834
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800835status_t CameraService::BasicClient::startCameraOps() {
836 int32_t res;
837
838 mOpsCallback = new OpsCallback(this);
839
Igor Murashkine6800ce2013-03-04 17:25:57 -0800840 {
841 ALOGV("%s: Start camera ops, package name = %s, client UID = %d",
842 __FUNCTION__, String8(mClientPackageName).string(), mClientUid);
843 }
844
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800845 mAppOpsManager.startWatchingMode(AppOpsManager::OP_CAMERA,
846 mClientPackageName, mOpsCallback);
847 res = mAppOpsManager.startOp(AppOpsManager::OP_CAMERA,
848 mClientUid, mClientPackageName);
849
850 if (res != AppOpsManager::MODE_ALLOWED) {
851 ALOGI("Camera %d: Access for \"%s\" has been revoked",
852 mCameraId, String8(mClientPackageName).string());
853 return PERMISSION_DENIED;
854 }
855 mOpsActive = true;
856 return OK;
857}
858
859status_t CameraService::BasicClient::finishCameraOps() {
860 if (mOpsActive) {
861 mAppOpsManager.finishOp(AppOpsManager::OP_CAMERA, mClientUid,
862 mClientPackageName);
863 mOpsActive = false;
864 }
865 mAppOpsManager.stopWatchingMode(mOpsCallback);
866 mOpsCallback.clear();
867
868 return OK;
869}
870
871void CameraService::BasicClient::opChanged(int32_t op, const String16& packageName) {
872 String8 name(packageName);
873 String8 myName(mClientPackageName);
874
875 if (op != AppOpsManager::OP_CAMERA) {
876 ALOGW("Unexpected app ops notification received: %d", op);
877 return;
878 }
879
880 int32_t res;
881 res = mAppOpsManager.checkOp(AppOpsManager::OP_CAMERA,
882 mClientUid, mClientPackageName);
883 ALOGV("checkOp returns: %d, %s ", res,
884 res == AppOpsManager::MODE_ALLOWED ? "ALLOWED" :
885 res == AppOpsManager::MODE_IGNORED ? "IGNORED" :
886 res == AppOpsManager::MODE_ERRORED ? "ERRORED" :
887 "UNKNOWN");
888
889 if (res != AppOpsManager::MODE_ALLOWED) {
890 ALOGI("Camera %d: Access for \"%s\" revoked", mCameraId,
891 myName.string());
892 // Reset the client PID to allow server-initiated disconnect,
893 // and to prevent further calls by client.
894 mClientPid = getCallingPid();
895 notifyError();
896 disconnect();
897 }
898}
899
Mathias Agopian65ab4712010-07-14 17:59:35 -0700900// ----------------------------------------------------------------------------
901
Keun young Parkd8973a72012-03-28 14:13:09 -0700902Mutex* CameraService::Client::getClientLockFromCookie(void* user) {
903 return gCameraService->getClientLockById((int) user);
904}
905
906// Provide client pointer for callbacks. Client lock returned from getClientLockFromCookie should
907// be acquired for this to be safe
908CameraService::Client* CameraService::Client::getClientFromCookie(void* user) {
909 Client* client = gCameraService->getClientByIdUnsafe((int) user);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700910
911 // This could happen if the Client is in the process of shutting down (the
912 // last strong reference is gone, but the destructor hasn't finished
913 // stopping the hardware).
Keun young Parkd8973a72012-03-28 14:13:09 -0700914 if (client == NULL) return NULL;
915
916 // destruction already started, so should not be accessed
917 if (client->mDestructionStarted) return NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700918
Mathias Agopian65ab4712010-07-14 17:59:35 -0700919 return client;
920}
921
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800922void CameraService::Client::notifyError() {
Igor Murashkin44cfcf02013-03-01 16:22:28 -0800923 mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_RELEASED, 0);
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800924}
925
Igor Murashkin036bc3e2012-10-08 15:09:46 -0700926// NOTE: function is idempotent
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700927void CameraService::Client::disconnect() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700928 ALOGV("Client::disconnect");
Igor Murashkin634a5152013-02-20 17:15:11 -0800929 BasicClient::disconnect();
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700930 mCameraService->setCameraFree(mCameraId);
Igor Murashkin93747b92013-05-01 15:42:20 -0700931
932 StatusVector rejectSourceStates;
933 rejectSourceStates.push_back(ICameraServiceListener::STATUS_NOT_PRESENT);
934 rejectSourceStates.push_back(ICameraServiceListener::STATUS_ENUMERATING);
935
936 // Transition to PRESENT if the camera is not in either of above 2 states
Igor Murashkincba2c162013-03-20 15:56:31 -0700937 mCameraService->updateStatus(ICameraServiceListener::STATUS_PRESENT,
Igor Murashkin93747b92013-05-01 15:42:20 -0700938 mCameraId,
939 &rejectSourceStates);
Wu-cheng Lie09591e2010-10-14 20:17:44 +0800940}
941
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800942CameraService::Client::OpsCallback::OpsCallback(wp<BasicClient> client):
943 mClient(client) {
944}
945
946void CameraService::Client::OpsCallback::opChanged(int32_t op,
947 const String16& packageName) {
948 sp<BasicClient> client = mClient.promote();
949 if (client != NULL) {
950 client->opChanged(op, packageName);
951 }
952}
953
Mathias Agopian65ab4712010-07-14 17:59:35 -0700954// ----------------------------------------------------------------------------
Igor Murashkin634a5152013-02-20 17:15:11 -0800955// IProCamera
956// ----------------------------------------------------------------------------
957
958CameraService::ProClient::ProClient(const sp<CameraService>& cameraService,
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800959 const sp<IProCameraCallbacks>& remoteCallback,
960 const String16& clientPackageName,
961 int cameraId,
962 int cameraFacing,
963 int clientPid,
964 uid_t clientUid,
965 int servicePid)
966 : CameraService::BasicClient(cameraService, remoteCallback->asBinder(),
967 clientPackageName, cameraId, cameraFacing,
968 clientPid, clientUid, servicePid)
Igor Murashkin634a5152013-02-20 17:15:11 -0800969{
970 mRemoteCallback = remoteCallback;
971}
972
973CameraService::ProClient::~ProClient() {
Igor Murashkin634a5152013-02-20 17:15:11 -0800974}
975
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800976void CameraService::ProClient::notifyError() {
Igor Murashkine6800ce2013-03-04 17:25:57 -0800977 mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_RELEASED, 0);
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800978}
979
Igor Murashkin634a5152013-02-20 17:15:11 -0800980// ----------------------------------------------------------------------------
Mathias Agopian65ab4712010-07-14 17:59:35 -0700981
982static const int kDumpLockRetries = 50;
983static const int kDumpLockSleep = 60000;
984
985static bool tryLock(Mutex& mutex)
986{
987 bool locked = false;
988 for (int i = 0; i < kDumpLockRetries; ++i) {
989 if (mutex.tryLock() == NO_ERROR) {
990 locked = true;
991 break;
992 }
993 usleep(kDumpLockSleep);
994 }
995 return locked;
996}
997
998status_t CameraService::dump(int fd, const Vector<String16>& args) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700999 String8 result;
1000 if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -07001001 result.appendFormat("Permission Denial: "
Mathias Agopian65ab4712010-07-14 17:59:35 -07001002 "can't dump CameraService from pid=%d, uid=%d\n",
1003 getCallingPid(),
1004 getCallingUid());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001005 write(fd, result.string(), result.size());
1006 } else {
1007 bool locked = tryLock(mServiceLock);
1008 // failed to lock - CameraService is probably deadlocked
1009 if (!locked) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -07001010 result.append("CameraService may be deadlocked\n");
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001011 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001012 }
1013
1014 bool hasClient = false;
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001015 if (!mModule) {
1016 result = String8::format("No camera module available!\n");
1017 write(fd, result.string(), result.size());
1018 return NO_ERROR;
1019 }
1020
1021 result = String8::format("Camera module HAL API version: 0x%x\n",
1022 mModule->common.hal_api_version);
1023 result.appendFormat("Camera module API version: 0x%x\n",
1024 mModule->common.module_api_version);
1025 result.appendFormat("Camera module name: %s\n",
1026 mModule->common.name);
1027 result.appendFormat("Camera module author: %s\n",
1028 mModule->common.author);
1029 result.appendFormat("Number of camera devices: %d\n\n", mNumberOfCameras);
1030 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001031 for (int i = 0; i < mNumberOfCameras; i++) {
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001032 result = String8::format("Camera %d static information:\n", i);
1033 camera_info info;
1034
1035 status_t rc = mModule->get_camera_info(i, &info);
1036 if (rc != OK) {
1037 result.appendFormat(" Error reading static information!\n");
1038 write(fd, result.string(), result.size());
1039 } else {
1040 result.appendFormat(" Facing: %s\n",
1041 info.facing == CAMERA_FACING_BACK ? "BACK" : "FRONT");
1042 result.appendFormat(" Orientation: %d\n", info.orientation);
1043 int deviceVersion;
1044 if (mModule->common.module_api_version <
1045 CAMERA_MODULE_API_VERSION_2_0) {
1046 deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
1047 } else {
1048 deviceVersion = info.device_version;
1049 }
1050 result.appendFormat(" Device version: 0x%x\n", deviceVersion);
1051 if (deviceVersion >= CAMERA_DEVICE_API_VERSION_2_0) {
1052 result.appendFormat(" Device static metadata:\n");
1053 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -07001054 dump_indented_camera_metadata(info.static_camera_characteristics,
1055 fd, 2, 4);
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001056 } else {
1057 write(fd, result.string(), result.size());
1058 }
1059 }
1060
Mathias Agopian65ab4712010-07-14 17:59:35 -07001061 sp<Client> client = mClient[i].promote();
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001062 if (client == 0) {
1063 result = String8::format(" Device is closed, no client instance\n");
1064 write(fd, result.string(), result.size());
1065 continue;
1066 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001067 hasClient = true;
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001068 result = String8::format(" Device is open. Client instance dump:\n");
1069 write(fd, result.string(), result.size());
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001070 client->dump(fd, args);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001071 }
1072 if (!hasClient) {
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001073 result = String8::format("\nNo active camera clients yet.\n");
1074 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001075 }
1076
1077 if (locked) mServiceLock.unlock();
1078
1079 // change logging level
1080 int n = args.size();
1081 for (int i = 0; i + 1 < n; i++) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -07001082 String16 verboseOption("-v");
1083 if (args[i] == verboseOption) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001084 String8 levelStr(args[i+1]);
1085 int level = atoi(levelStr.string());
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001086 result = String8::format("\nSetting log level to %d.\n", level);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001087 setLogLevel(level);
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001088 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001089 }
1090 }
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001091
Mathias Agopian65ab4712010-07-14 17:59:35 -07001092 }
1093 return NO_ERROR;
1094}
1095
Igor Murashkinecf17e82012-10-02 16:05:11 -07001096/*virtual*/void CameraService::binderDied(
1097 const wp<IBinder> &who) {
1098
Igor Murashkin294d0ec2012-10-05 10:44:57 -07001099 /**
1100 * While tempting to promote the wp<IBinder> into a sp,
1101 * it's actually not supported by the binder driver
1102 */
1103
Igor Murashkinecf17e82012-10-02 16:05:11 -07001104 ALOGV("java clients' binder died");
1105
Igor Murashkin634a5152013-02-20 17:15:11 -08001106 sp<BasicClient> cameraClient = getClientByRemote(who);
Igor Murashkinecf17e82012-10-02 16:05:11 -07001107
Igor Murashkin294d0ec2012-10-05 10:44:57 -07001108 if (cameraClient == 0) {
Igor Murashkinecf17e82012-10-02 16:05:11 -07001109 ALOGV("java clients' binder death already cleaned up (normal case)");
1110 return;
1111 }
1112
Igor Murashkinecf17e82012-10-02 16:05:11 -07001113 ALOGW("Disconnecting camera client %p since the binder for it "
1114 "died (this pid %d)", cameraClient.get(), getCallingPid());
1115
1116 cameraClient->disconnect();
1117
1118}
1119
Igor Murashkinbfc99152013-02-27 12:55:20 -08001120void CameraService::updateStatus(ICameraServiceListener::Status status,
Igor Murashkin93747b92013-05-01 15:42:20 -07001121 int32_t cameraId,
1122 const StatusVector *rejectSourceStates) {
Igor Murashkinbfc99152013-02-27 12:55:20 -08001123 // do not lock mServiceLock here or can get into a deadlock from
1124 // connect() -> ProClient::disconnect -> updateStatus
1125 Mutex::Autolock lock(mStatusMutex);
Igor Murashkinbfc99152013-02-27 12:55:20 -08001126
1127 ICameraServiceListener::Status oldStatus = mStatusList[cameraId];
1128
1129 mStatusList[cameraId] = status;
1130
1131 if (oldStatus != status) {
1132 ALOGV("%s: Status has changed for camera ID %d from 0x%x to 0x%x",
1133 __FUNCTION__, cameraId, (uint32_t)oldStatus, (uint32_t)status);
1134
Igor Murashkincba2c162013-03-20 15:56:31 -07001135 if (oldStatus == ICameraServiceListener::STATUS_NOT_PRESENT &&
1136 (status != ICameraServiceListener::STATUS_PRESENT &&
1137 status != ICameraServiceListener::STATUS_ENUMERATING)) {
1138
1139 ALOGW("%s: From NOT_PRESENT can only transition into PRESENT"
1140 " or ENUMERATING", __FUNCTION__);
1141 mStatusList[cameraId] = oldStatus;
1142 return;
1143 }
1144
Igor Murashkin93747b92013-05-01 15:42:20 -07001145 if (rejectSourceStates != NULL) {
1146 const StatusVector &rejectList = *rejectSourceStates;
1147 StatusVector::const_iterator it = rejectList.begin();
1148
1149 /**
1150 * Sometimes we want to conditionally do a transition.
1151 * For example if a client disconnects, we want to go to PRESENT
1152 * only if we weren't already in NOT_PRESENT or ENUMERATING.
1153 */
1154 for (; it != rejectList.end(); ++it) {
1155 if (oldStatus == *it) {
1156 ALOGV("%s: Rejecting status transition for Camera ID %d, "
1157 " since the source state was was in one of the bad "
1158 " states.", __FUNCTION__, cameraId);
1159 mStatusList[cameraId] = oldStatus;
1160 return;
1161 }
1162 }
1163 }
1164
Igor Murashkinbfc99152013-02-27 12:55:20 -08001165 /**
1166 * ProClients lose their exclusive lock.
1167 * - Done before the CameraClient can initialize the HAL device,
1168 * since we want to be able to close it before they get to initialize
1169 */
1170 if (status == ICameraServiceListener::STATUS_NOT_AVAILABLE) {
1171 Vector<wp<ProClient> > proClients(mProClientList[cameraId]);
1172 Vector<wp<ProClient> >::const_iterator it;
1173
1174 for (it = proClients.begin(); it != proClients.end(); ++it) {
1175 sp<ProClient> proCl = it->promote();
1176 if (proCl.get() != NULL) {
1177 proCl->onExclusiveLockStolen();
1178 }
1179 }
1180 }
1181
1182 Vector<sp<ICameraServiceListener> >::const_iterator it;
1183 for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
1184 (*it)->onStatusChanged(status, cameraId);
1185 }
1186 }
1187}
1188
Igor Murashkincba2c162013-03-20 15:56:31 -07001189ICameraServiceListener::Status CameraService::getStatus(int cameraId) const {
1190 if (cameraId < 0 || cameraId >= MAX_CAMERAS) {
1191 ALOGE("%s: Invalid camera ID %d", __FUNCTION__, cameraId);
1192 return ICameraServiceListener::STATUS_UNKNOWN;
1193 }
1194
1195 Mutex::Autolock al(mStatusMutex);
1196 return mStatusList[cameraId];
1197}
1198
Mathias Agopian65ab4712010-07-14 17:59:35 -07001199}; // namespace android