blob: 5e84aaf5a1f76646179a899c6c6b9ffdbe2c0975 [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 Talvala7b82efe2013-07-25 17:12:35 -070041#include "api1/CameraClient.h"
42#include "api1/Camera2Client.h"
43#include "api_pro/ProCamera2Client.h"
44#include "api2/CameraDeviceClient.h"
Igor Murashkin98e24722013-06-19 19:51:04 -070045#include "CameraDeviceFactory.h"
Mathias Agopian65ab4712010-07-14 17:59:35 -070046
47namespace android {
48
49// ----------------------------------------------------------------------------
50// Logging support -- this is for debugging only
51// Use "adb shell dumpsys media.camera -v 1" to change it.
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -070052volatile int32_t gLogLevel = 0;
Mathias Agopian65ab4712010-07-14 17:59:35 -070053
Steve Blockb8a80522011-12-20 16:23:08 +000054#define LOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__);
55#define LOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__);
Mathias Agopian65ab4712010-07-14 17:59:35 -070056
57static void setLogLevel(int level) {
58 android_atomic_write(level, &gLogLevel);
59}
60
61// ----------------------------------------------------------------------------
62
63static int getCallingPid() {
64 return IPCThreadState::self()->getCallingPid();
65}
66
67static int getCallingUid() {
68 return IPCThreadState::self()->getCallingUid();
69}
70
Igor Murashkincba2c162013-03-20 15:56:31 -070071extern "C" {
72static void camera_device_status_change(
73 const struct camera_module_callbacks* callbacks,
74 int camera_id,
75 int new_status) {
76 sp<CameraService> cs = const_cast<CameraService*>(
77 static_cast<const CameraService*>(callbacks));
78
79 cs->onDeviceStatusChanged(
80 camera_id,
81 new_status);
82}
83} // extern "C"
84
Mathias Agopian65ab4712010-07-14 17:59:35 -070085// ----------------------------------------------------------------------------
86
87// This is ugly and only safe if we never re-create the CameraService, but
88// should be ok for now.
89static CameraService *gCameraService;
90
91CameraService::CameraService()
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -080092 :mSoundRef(0), mModule(0)
Mathias Agopian65ab4712010-07-14 17:59:35 -070093{
Steve Blockdf64d152012-01-04 20:05:49 +000094 ALOGI("CameraService started (pid=%d)", getpid());
Mathias Agopian65ab4712010-07-14 17:59:35 -070095 gCameraService = this;
Igor Murashkinbfc99152013-02-27 12:55:20 -080096
97 for (size_t i = 0; i < MAX_CAMERAS; ++i) {
Igor Murashkincba2c162013-03-20 15:56:31 -070098 mStatusList[i] = ICameraServiceListener::STATUS_PRESENT;
Igor Murashkinbfc99152013-02-27 12:55:20 -080099 }
Igor Murashkincba2c162013-03-20 15:56:31 -0700100
101 this->camera_device_status_change = android::camera_device_status_change;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700102}
103
Iliyan Malchev8951a972011-04-14 16:55:59 -0700104void CameraService::onFirstRef()
105{
Igor Murashkin634a5152013-02-20 17:15:11 -0800106 LOG1("CameraService::onFirstRef");
107
Iliyan Malchev8951a972011-04-14 16:55:59 -0700108 BnCameraService::onFirstRef();
109
110 if (hw_get_module(CAMERA_HARDWARE_MODULE_ID,
111 (const hw_module_t **)&mModule) < 0) {
Steve Block29357bc2012-01-06 19:20:56 +0000112 ALOGE("Could not load camera HAL module");
Iliyan Malchev8951a972011-04-14 16:55:59 -0700113 mNumberOfCameras = 0;
114 }
115 else {
Alex Rayc0dd54f2013-02-20 13:39:37 -0800116 ALOGI("Loaded \"%s\" camera module", mModule->common.name);
Iliyan Malchev8951a972011-04-14 16:55:59 -0700117 mNumberOfCameras = mModule->get_number_of_cameras();
118 if (mNumberOfCameras > MAX_CAMERAS) {
Steve Block29357bc2012-01-06 19:20:56 +0000119 ALOGE("Number of cameras(%d) > MAX_CAMERAS(%d).",
Iliyan Malchev8951a972011-04-14 16:55:59 -0700120 mNumberOfCameras, MAX_CAMERAS);
121 mNumberOfCameras = MAX_CAMERAS;
122 }
123 for (int i = 0; i < mNumberOfCameras; i++) {
124 setCameraFree(i);
125 }
Igor Murashkincba2c162013-03-20 15:56:31 -0700126
127 if (mModule->common.module_api_version >=
128 CAMERA_MODULE_API_VERSION_2_1) {
129 mModule->set_callbacks(this);
130 }
Igor Murashkin98e24722013-06-19 19:51:04 -0700131
132 CameraDeviceFactory::registerService(this);
Iliyan Malchev8951a972011-04-14 16:55:59 -0700133 }
134}
135
Mathias Agopian65ab4712010-07-14 17:59:35 -0700136CameraService::~CameraService() {
137 for (int i = 0; i < mNumberOfCameras; i++) {
138 if (mBusy[i]) {
Steve Block29357bc2012-01-06 19:20:56 +0000139 ALOGE("camera %d is still in use in destructor!", i);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700140 }
141 }
142
143 gCameraService = NULL;
144}
145
Igor Murashkincba2c162013-03-20 15:56:31 -0700146void CameraService::onDeviceStatusChanged(int cameraId,
147 int newStatus)
148{
149 ALOGI("%s: Status changed for cameraId=%d, newStatus=%d", __FUNCTION__,
150 cameraId, newStatus);
151
152 if (cameraId < 0 || cameraId >= MAX_CAMERAS) {
153 ALOGE("%s: Bad camera ID %d", __FUNCTION__, cameraId);
154 return;
155 }
156
157 if ((int)getStatus(cameraId) == newStatus) {
158 ALOGE("%s: State transition to the same status 0x%x not allowed",
159 __FUNCTION__, (uint32_t)newStatus);
160 return;
161 }
162
163 /* don't do this in updateStatus
164 since it is also called from connect and we could get into a deadlock */
165 if (newStatus == CAMERA_DEVICE_STATUS_NOT_PRESENT) {
166 Vector<sp<BasicClient> > clientsToDisconnect;
167 {
168 Mutex::Autolock al(mServiceLock);
169
170 /* Find all clients that we need to disconnect */
Igor Murashkine7ee7632013-06-11 18:10:18 -0700171 sp<BasicClient> client = mClient[cameraId].promote();
Igor Murashkincba2c162013-03-20 15:56:31 -0700172 if (client.get() != NULL) {
173 clientsToDisconnect.push_back(client);
174 }
175
176 int i = cameraId;
177 for (size_t j = 0; j < mProClientList[i].size(); ++j) {
178 sp<ProClient> cl = mProClientList[i][j].promote();
179 if (cl != NULL) {
180 clientsToDisconnect.push_back(cl);
181 }
182 }
183 }
184
185 /* now disconnect them. don't hold the lock
186 or we can get into a deadlock */
187
188 for (size_t i = 0; i < clientsToDisconnect.size(); ++i) {
189 sp<BasicClient> client = clientsToDisconnect[i];
190
191 client->disconnect();
192 /**
193 * The remote app will no longer be able to call methods on the
194 * client since the client PID will be reset to 0
195 */
196 }
197
198 ALOGV("%s: After unplug, disconnected %d clients",
199 __FUNCTION__, clientsToDisconnect.size());
200 }
201
202 updateStatus(
203 static_cast<ICameraServiceListener::Status>(newStatus), cameraId);
204
205}
206
Mathias Agopian65ab4712010-07-14 17:59:35 -0700207int32_t CameraService::getNumberOfCameras() {
208 return mNumberOfCameras;
209}
210
211status_t CameraService::getCameraInfo(int cameraId,
212 struct CameraInfo* cameraInfo) {
Iliyan Malchev8951a972011-04-14 16:55:59 -0700213 if (!mModule) {
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700214 return -ENODEV;
Iliyan Malchev8951a972011-04-14 16:55:59 -0700215 }
216
Mathias Agopian65ab4712010-07-14 17:59:35 -0700217 if (cameraId < 0 || cameraId >= mNumberOfCameras) {
218 return BAD_VALUE;
219 }
220
Iliyan Malchev8951a972011-04-14 16:55:59 -0700221 struct camera_info info;
222 status_t rc = mModule->get_camera_info(cameraId, &info);
223 cameraInfo->facing = info.facing;
224 cameraInfo->orientation = info.orientation;
225 return rc;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700226}
227
Zhijun He2b59be82013-09-25 10:14:30 -0700228status_t CameraService::getCameraCharacteristics(int cameraId,
229 CameraMetadata* cameraInfo) {
230 if (!cameraInfo) {
231 ALOGE("%s: cameraInfo is NULL", __FUNCTION__);
232 return BAD_VALUE;
233 }
234
235 if (!mModule) {
236 ALOGE("%s: camera hardware module doesn't exist", __FUNCTION__);
237 return -ENODEV;
238 }
239
240 if (mModule->common.module_api_version < CAMERA_MODULE_API_VERSION_2_0) {
241 // TODO: Remove this check once HAL1 shim is in place.
242 ALOGE("%s: Only HAL module version V2 or higher supports static metadata", __FUNCTION__);
243 return BAD_VALUE;
244 }
245
246 if (cameraId < 0 || cameraId >= mNumberOfCameras) {
247 ALOGE("%s: Invalid camera id: %d", __FUNCTION__, cameraId);
248 return BAD_VALUE;
249 }
250
251 int facing;
252 if (getDeviceVersion(cameraId, &facing) == CAMERA_DEVICE_API_VERSION_1_0) {
253 // TODO: Remove this check once HAL1 shim is in place.
254 ALOGE("%s: HAL1 doesn't support static metadata yet", __FUNCTION__);
255 return BAD_VALUE;
256 }
257
258 struct camera_info info;
259 status_t ret = mModule->get_camera_info(cameraId, &info);
260 *cameraInfo = info.static_camera_characteristics;
261
262 return ret;
263}
264
Igor Murashkin634a5152013-02-20 17:15:11 -0800265int CameraService::getDeviceVersion(int cameraId, int* facing) {
266 struct camera_info info;
267 if (mModule->get_camera_info(cameraId, &info) != OK) {
268 return -1;
269 }
270
271 int deviceVersion;
272 if (mModule->common.module_api_version >= CAMERA_MODULE_API_VERSION_2_0) {
273 deviceVersion = info.device_version;
274 } else {
275 deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
276 }
277
278 if (facing) {
279 *facing = info.facing;
280 }
281
282 return deviceVersion;
283}
284
Igor Murashkinbfc99152013-02-27 12:55:20 -0800285bool CameraService::isValidCameraId(int cameraId) {
286 int facing;
287 int deviceVersion = getDeviceVersion(cameraId, &facing);
288
289 switch(deviceVersion) {
290 case CAMERA_DEVICE_API_VERSION_1_0:
291 case CAMERA_DEVICE_API_VERSION_2_0:
292 case CAMERA_DEVICE_API_VERSION_2_1:
293 case CAMERA_DEVICE_API_VERSION_3_0:
294 return true;
295 default:
296 return false;
297 }
298
299 return false;
300}
301
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700302status_t CameraService::validateConnect(int cameraId,
Igor Murashkine6800ce2013-03-04 17:25:57 -0800303 /*inout*/
304 int& clientUid) const {
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800305
Mathias Agopian65ab4712010-07-14 17:59:35 -0700306 int callingPid = getCallingPid();
Tyler Luu5861a9a2011-10-06 00:00:03 -0500307
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800308 if (clientUid == USE_CALLING_UID) {
309 clientUid = getCallingUid();
310 } else {
311 // We only trust our own process to forward client UIDs
312 if (callingPid != getpid()) {
313 ALOGE("CameraService::connect X (pid %d) rejected (don't trust clientUid)",
314 callingPid);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700315 return PERMISSION_DENIED;
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800316 }
317 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700318
Iliyan Malchev8951a972011-04-14 16:55:59 -0700319 if (!mModule) {
Steve Block29357bc2012-01-06 19:20:56 +0000320 ALOGE("Camera HAL module not loaded");
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700321 return -ENODEV;
Iliyan Malchev8951a972011-04-14 16:55:59 -0700322 }
323
Mathias Agopian65ab4712010-07-14 17:59:35 -0700324 if (cameraId < 0 || cameraId >= mNumberOfCameras) {
Steve Block29357bc2012-01-06 19:20:56 +0000325 ALOGE("CameraService::connect X (pid %d) rejected (invalid cameraId %d).",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700326 callingPid, cameraId);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700327 return -ENODEV;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700328 }
329
Wu-cheng Lia3355432011-05-20 14:54:25 +0800330 char value[PROPERTY_VALUE_MAX];
331 property_get("sys.secpolicy.camera.disabled", value, "0");
332 if (strcmp(value, "1") == 0) {
333 // Camera is disabled by DevicePolicyManager.
Steve Blockdf64d152012-01-04 20:05:49 +0000334 ALOGI("Camera is disabled. connect X (pid %d) rejected", callingPid);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700335 return -EACCES;
Wu-cheng Lia3355432011-05-20 14:54:25 +0800336 }
337
Igor Murashkincba2c162013-03-20 15:56:31 -0700338 ICameraServiceListener::Status currentStatus = getStatus(cameraId);
339 if (currentStatus == ICameraServiceListener::STATUS_NOT_PRESENT) {
340 ALOGI("Camera is not plugged in,"
341 " connect X (pid %d) rejected", callingPid);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700342 return -ENODEV;
Igor Murashkincba2c162013-03-20 15:56:31 -0700343 } else if (currentStatus == ICameraServiceListener::STATUS_ENUMERATING) {
344 ALOGI("Camera is enumerating,"
345 " connect X (pid %d) rejected", callingPid);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700346 return -EBUSY;
Igor Murashkincba2c162013-03-20 15:56:31 -0700347 }
348 // Else don't check for STATUS_NOT_AVAILABLE.
349 // -- It's done implicitly in canConnectUnsafe /w the mBusy array
350
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700351 return OK;
Igor Murashkine6800ce2013-03-04 17:25:57 -0800352}
353
354bool CameraService::canConnectUnsafe(int cameraId,
355 const String16& clientPackageName,
356 const sp<IBinder>& remoteCallback,
Igor Murashkine7ee7632013-06-11 18:10:18 -0700357 sp<BasicClient> &client) {
Igor Murashkine6800ce2013-03-04 17:25:57 -0800358 String8 clientName8(clientPackageName);
359 int callingPid = getCallingPid();
360
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800361 if (mClient[cameraId] != 0) {
362 client = mClient[cameraId].promote();
363 if (client != 0) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700364 if (remoteCallback == client->getRemote()) {
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800365 LOG1("CameraService::connect X (pid %d) (the same client)",
366 callingPid);
Igor Murashkine6800ce2013-03-04 17:25:57 -0800367 return true;
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800368 } else {
Igor Murashkine6800ce2013-03-04 17:25:57 -0800369 // TODOSC: need to support 1 regular client,
370 // multiple shared clients here
371 ALOGW("CameraService::connect X (pid %d) rejected"
372 " (existing client).", callingPid);
373 return false;
Wu-cheng Li2fd24402012-02-23 19:01:00 -0800374 }
Wu-cheng Li2fd24402012-02-23 19:01:00 -0800375 }
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800376 mClient[cameraId].clear();
377 }
378
Igor Murashkin634a5152013-02-20 17:15:11 -0800379 /*
380 mBusy is set to false as the last step of the Client destructor,
381 after which it is guaranteed that the Client destructor has finished (
382 including any inherited destructors)
383
384 We only need this for a Client subclasses since we don't allow
385 multiple Clents to be opened concurrently, but multiple BasicClient
386 would be fine
387 */
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800388 if (mBusy[cameraId]) {
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800389 ALOGW("CameraService::connect X (pid %d, \"%s\") rejected"
390 " (camera %d is still busy).", callingPid,
391 clientName8.string(), cameraId);
Igor Murashkine6800ce2013-03-04 17:25:57 -0800392 return false;
393 }
394
395 return true;
396}
397
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700398status_t CameraService::connect(
Igor Murashkine6800ce2013-03-04 17:25:57 -0800399 const sp<ICameraClient>& cameraClient,
400 int cameraId,
401 const String16& clientPackageName,
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700402 int clientUid,
403 /*out*/
404 sp<ICamera>& device) {
Igor Murashkine6800ce2013-03-04 17:25:57 -0800405
406 String8 clientName8(clientPackageName);
407 int callingPid = getCallingPid();
408
409 LOG1("CameraService::connect E (pid %d \"%s\", id %d)", callingPid,
410 clientName8.string(), cameraId);
411
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700412 status_t status = validateConnect(cameraId, /*inout*/clientUid);
413 if (status != OK) {
414 return status;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700415 }
416
Igor Murashkine6800ce2013-03-04 17:25:57 -0800417
Igor Murashkine7ee7632013-06-11 18:10:18 -0700418 sp<Client> client;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700419 {
420 Mutex::Autolock lock(mServiceLock);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700421 sp<BasicClient> clientTmp;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700422 if (!canConnectUnsafe(cameraId, clientPackageName,
423 cameraClient->asBinder(),
Igor Murashkine7ee7632013-06-11 18:10:18 -0700424 /*out*/clientTmp)) {
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700425 return -EBUSY;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700426 } else if (client.get() != NULL) {
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700427 device = static_cast<Client*>(clientTmp.get());
428 return OK;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700429 }
430
431 int facing = -1;
432 int deviceVersion = getDeviceVersion(cameraId, &facing);
433
434 // If there are other non-exclusive users of the camera,
435 // this will tear them down before we can reuse the camera
436 if (isValidCameraId(cameraId)) {
Igor Murashkincba2c162013-03-20 15:56:31 -0700437 // transition from PRESENT -> NOT_AVAILABLE
Igor Murashkinacd695c2013-03-13 17:23:00 -0700438 updateStatus(ICameraServiceListener::STATUS_NOT_AVAILABLE,
439 cameraId);
440 }
441
442 switch(deviceVersion) {
443 case CAMERA_DEVICE_API_VERSION_1_0:
444 client = new CameraClient(this, cameraClient,
445 clientPackageName, cameraId,
446 facing, callingPid, clientUid, getpid());
447 break;
448 case CAMERA_DEVICE_API_VERSION_2_0:
449 case CAMERA_DEVICE_API_VERSION_2_1:
450 case CAMERA_DEVICE_API_VERSION_3_0:
451 client = new Camera2Client(this, cameraClient,
452 clientPackageName, cameraId,
453 facing, callingPid, clientUid, getpid(),
454 deviceVersion);
455 break;
456 case -1:
457 ALOGE("Invalid camera id %d", cameraId);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700458 return BAD_VALUE;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700459 default:
460 ALOGE("Unknown camera device HAL version: %d", deviceVersion);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700461 return INVALID_OPERATION;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700462 }
463
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700464 status_t status = connectFinishUnsafe(client, client->getRemote());
465 if (status != OK) {
Igor Murashkinacd695c2013-03-13 17:23:00 -0700466 // this is probably not recoverable.. maybe the client can try again
Igor Murashkincba2c162013-03-20 15:56:31 -0700467 // OK: we can only get here if we were originally in PRESENT state
468 updateStatus(ICameraServiceListener::STATUS_PRESENT, cameraId);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700469 return status;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700470 }
471
472 mClient[cameraId] = client;
473 LOG1("CameraService::connect X (id %d, this pid is %d)", cameraId,
474 getpid());
Igor Murashkine6800ce2013-03-04 17:25:57 -0800475 }
Igor Murashkinacd695c2013-03-13 17:23:00 -0700476 // important: release the mutex here so the client can call back
477 // into the service from its destructor (can be at the end of the call)
Igor Murashkinbfc99152013-02-27 12:55:20 -0800478
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700479 device = client;
480 return OK;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700481}
482
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700483status_t CameraService::connectFinishUnsafe(const sp<BasicClient>& client,
484 const sp<IBinder>& remoteCallback) {
485 status_t status = client->initialize(mModule);
486 if (status != OK) {
487 return status;
Igor Murashkine6800ce2013-03-04 17:25:57 -0800488 }
489
Igor Murashkine7ee7632013-06-11 18:10:18 -0700490 remoteCallback->linkToDeath(this);
Igor Murashkine6800ce2013-03-04 17:25:57 -0800491
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700492 return OK;
Igor Murashkine6800ce2013-03-04 17:25:57 -0800493}
494
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700495status_t CameraService::connectPro(
Igor Murashkin634a5152013-02-20 17:15:11 -0800496 const sp<IProCameraCallbacks>& cameraCb,
Igor Murashkinc073ba52013-02-26 14:32:34 -0800497 int cameraId,
498 const String16& clientPackageName,
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700499 int clientUid,
500 /*out*/
501 sp<IProCameraUser>& device)
Igor Murashkin634a5152013-02-20 17:15:11 -0800502{
Igor Murashkinbfc99152013-02-27 12:55:20 -0800503 String8 clientName8(clientPackageName);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700504 int callingPid = getCallingPid();
Igor Murashkin634a5152013-02-20 17:15:11 -0800505
Igor Murashkine6800ce2013-03-04 17:25:57 -0800506 LOG1("CameraService::connectPro E (pid %d \"%s\", id %d)", callingPid,
507 clientName8.string(), cameraId);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700508 status_t status = validateConnect(cameraId, /*inout*/clientUid);
509 if (status != OK) {
510 return status;
Igor Murashkin634a5152013-02-20 17:15:11 -0800511 }
512
Igor Murashkinacd695c2013-03-13 17:23:00 -0700513 sp<ProClient> client;
Igor Murashkine6800ce2013-03-04 17:25:57 -0800514 {
Igor Murashkinacd695c2013-03-13 17:23:00 -0700515 Mutex::Autolock lock(mServiceLock);
516 {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700517 sp<BasicClient> client;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700518 if (!canConnectUnsafe(cameraId, clientPackageName,
519 cameraCb->asBinder(),
520 /*out*/client)) {
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700521 return -EBUSY;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700522 }
523 }
524
525 int facing = -1;
526 int deviceVersion = getDeviceVersion(cameraId, &facing);
527
528 switch(deviceVersion) {
529 case CAMERA_DEVICE_API_VERSION_1_0:
530 ALOGE("Camera id %d uses HALv1, doesn't support ProCamera",
531 cameraId);
Ruben Brunk17963d12013-08-19 15:21:19 -0700532 return -EOPNOTSUPP;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700533 break;
534 case CAMERA_DEVICE_API_VERSION_2_0:
535 case CAMERA_DEVICE_API_VERSION_2_1:
Zhijun He47110052013-07-22 17:34:34 -0700536 case CAMERA_DEVICE_API_VERSION_3_0:
Igor Murashkinacd695c2013-03-13 17:23:00 -0700537 client = new ProCamera2Client(this, cameraCb, String16(),
538 cameraId, facing, callingPid, USE_CALLING_UID, getpid());
539 break;
540 case -1:
541 ALOGE("Invalid camera id %d", cameraId);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700542 return BAD_VALUE;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700543 default:
544 ALOGE("Unknown camera device HAL version: %d", deviceVersion);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700545 return INVALID_OPERATION;
Igor Murashkine6800ce2013-03-04 17:25:57 -0800546 }
Igor Murashkinacd695c2013-03-13 17:23:00 -0700547
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700548 status_t status = connectFinishUnsafe(client, client->getRemote());
549 if (status != OK) {
550 return status;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700551 }
552
553 mProClientList[cameraId].push(client);
554
555 LOG1("CameraService::connectPro X (id %d, this pid is %d)", cameraId,
556 getpid());
Igor Murashkine6800ce2013-03-04 17:25:57 -0800557 }
Igor Murashkinacd695c2013-03-13 17:23:00 -0700558 // important: release the mutex here so the client can call back
559 // into the service from its destructor (can be at the end of the call)
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700560 device = client;
561 return OK;
Igor Murashkinbfc99152013-02-27 12:55:20 -0800562}
Igor Murashkin634a5152013-02-20 17:15:11 -0800563
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700564status_t CameraService::connectDevice(
Igor Murashkine7ee7632013-06-11 18:10:18 -0700565 const sp<ICameraDeviceCallbacks>& cameraCb,
566 int cameraId,
567 const String16& clientPackageName,
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700568 int clientUid,
569 /*out*/
570 sp<ICameraDeviceUser>& device)
Igor Murashkine7ee7632013-06-11 18:10:18 -0700571{
Igor Murashkine7ee7632013-06-11 18:10:18 -0700572
573 String8 clientName8(clientPackageName);
574 int callingPid = getCallingPid();
575
576 LOG1("CameraService::connectDevice E (pid %d \"%s\", id %d)", callingPid,
577 clientName8.string(), cameraId);
578
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700579 status_t status = validateConnect(cameraId, /*inout*/clientUid);
580 if (status != OK) {
581 return status;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700582 }
583
584 sp<CameraDeviceClient> client;
585 {
586 Mutex::Autolock lock(mServiceLock);
587 {
588 sp<BasicClient> client;
589 if (!canConnectUnsafe(cameraId, clientPackageName,
590 cameraCb->asBinder(),
591 /*out*/client)) {
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700592 return -EBUSY;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700593 }
594 }
595
596 int facing = -1;
597 int deviceVersion = getDeviceVersion(cameraId, &facing);
598
599 // If there are other non-exclusive users of the camera,
600 // this will tear them down before we can reuse the camera
601 if (isValidCameraId(cameraId)) {
602 // transition from PRESENT -> NOT_AVAILABLE
603 updateStatus(ICameraServiceListener::STATUS_NOT_AVAILABLE,
604 cameraId);
605 }
606
607 switch(deviceVersion) {
608 case CAMERA_DEVICE_API_VERSION_1_0:
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700609 ALOGW("Camera using old HAL version: %d", deviceVersion);
Ruben Brunk17963d12013-08-19 15:21:19 -0700610 return -EOPNOTSUPP;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700611 // TODO: don't allow 2.0 Only allow 2.1 and higher
612 case CAMERA_DEVICE_API_VERSION_2_0:
613 case CAMERA_DEVICE_API_VERSION_2_1:
614 case CAMERA_DEVICE_API_VERSION_3_0:
615 client = new CameraDeviceClient(this, cameraCb, String16(),
616 cameraId, facing, callingPid, USE_CALLING_UID, getpid());
617 break;
618 case -1:
619 ALOGE("Invalid camera id %d", cameraId);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700620 return BAD_VALUE;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700621 default:
622 ALOGE("Unknown camera device HAL version: %d", deviceVersion);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700623 return INVALID_OPERATION;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700624 }
625
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700626 status_t status = connectFinishUnsafe(client, client->getRemote());
627 if (status != OK) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700628 // this is probably not recoverable.. maybe the client can try again
629 // OK: we can only get here if we were originally in PRESENT state
630 updateStatus(ICameraServiceListener::STATUS_PRESENT, cameraId);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700631 return status;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700632 }
633
634 LOG1("CameraService::connectDevice X (id %d, this pid is %d)", cameraId,
635 getpid());
636
637 mClient[cameraId] = client;
638 }
639 // important: release the mutex here so the client can call back
640 // into the service from its destructor (can be at the end of the call)
641
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700642 device = client;
643 return OK;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700644}
645
646
Igor Murashkinbfc99152013-02-27 12:55:20 -0800647status_t CameraService::addListener(
648 const sp<ICameraServiceListener>& listener) {
649 ALOGV("%s: Add listener %p", __FUNCTION__, listener.get());
Igor Murashkin634a5152013-02-20 17:15:11 -0800650
Igor Murashkinbfc99152013-02-27 12:55:20 -0800651 Mutex::Autolock lock(mServiceLock);
652
653 Vector<sp<ICameraServiceListener> >::iterator it, end;
654 for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
655 if ((*it)->asBinder() == listener->asBinder()) {
656 ALOGW("%s: Tried to add listener %p which was already subscribed",
657 __FUNCTION__, listener.get());
658 return ALREADY_EXISTS;
659 }
660 }
661
662 mListenerList.push_back(listener);
663
Igor Murashkincba2c162013-03-20 15:56:31 -0700664 /* Immediately signal current status to this listener only */
665 {
666 Mutex::Autolock m(mStatusMutex) ;
667 int numCams = getNumberOfCameras();
668 for (int i = 0; i < numCams; ++i) {
669 listener->onStatusChanged(mStatusList[i], i);
670 }
671 }
672
Igor Murashkinbfc99152013-02-27 12:55:20 -0800673 return OK;
674}
675status_t CameraService::removeListener(
676 const sp<ICameraServiceListener>& listener) {
677 ALOGV("%s: Remove listener %p", __FUNCTION__, listener.get());
678
679 Mutex::Autolock lock(mServiceLock);
680
681 Vector<sp<ICameraServiceListener> >::iterator it;
682 for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
683 if ((*it)->asBinder() == listener->asBinder()) {
684 mListenerList.erase(it);
685 return OK;
686 }
687 }
688
689 ALOGW("%s: Tried to remove a listener %p which was not subscribed",
690 __FUNCTION__, listener.get());
691
692 return BAD_VALUE;
Igor Murashkin634a5152013-02-20 17:15:11 -0800693}
694
695void CameraService::removeClientByRemote(const wp<IBinder>& remoteBinder) {
696 int callingPid = getCallingPid();
697 LOG1("CameraService::removeClientByRemote E (pid %d)", callingPid);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700698
Igor Murashkinecf17e82012-10-02 16:05:11 -0700699 // Declare this before the lock to make absolutely sure the
700 // destructor won't be called with the lock held.
701 Mutex::Autolock lock(mServiceLock);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700702
Igor Murashkinecf17e82012-10-02 16:05:11 -0700703 int outIndex;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700704 sp<BasicClient> client = findClientUnsafe(remoteBinder, outIndex);
Igor Murashkinecf17e82012-10-02 16:05:11 -0700705
706 if (client != 0) {
707 // Found our camera, clear and leave.
708 LOG1("removeClient: clear camera %d", outIndex);
709 mClient[outIndex].clear();
710
Igor Murashkine7ee7632013-06-11 18:10:18 -0700711 client->getRemote()->unlinkToDeath(this);
Igor Murashkin634a5152013-02-20 17:15:11 -0800712 } else {
713
714 sp<ProClient> clientPro = findProClientUnsafe(remoteBinder);
715
716 if (clientPro != NULL) {
717 // Found our camera, clear and leave.
718 LOG1("removeClient: clear pro %p", clientPro.get());
719
720 clientPro->getRemoteCallback()->asBinder()->unlinkToDeath(this);
721 }
Igor Murashkinecf17e82012-10-02 16:05:11 -0700722 }
723
Igor Murashkin634a5152013-02-20 17:15:11 -0800724 LOG1("CameraService::removeClientByRemote X (pid %d)", callingPid);
725}
726
727sp<CameraService::ProClient> CameraService::findProClientUnsafe(
728 const wp<IBinder>& cameraCallbacksRemote)
729{
730 sp<ProClient> clientPro;
731
732 for (int i = 0; i < mNumberOfCameras; ++i) {
733 Vector<size_t> removeIdx;
734
735 for (size_t j = 0; j < mProClientList[i].size(); ++j) {
736 wp<ProClient> cl = mProClientList[i][j];
737
738 sp<ProClient> clStrong = cl.promote();
739 if (clStrong != NULL && clStrong->getRemote() == cameraCallbacksRemote) {
740 clientPro = clStrong;
741 break;
742 } else if (clStrong == NULL) {
743 // mark to clean up dead ptr
744 removeIdx.push(j);
745 }
746 }
747
748 // remove stale ptrs (in reverse so the indices dont change)
749 for (ssize_t j = (ssize_t)removeIdx.size() - 1; j >= 0; --j) {
750 mProClientList[i].removeAt(removeIdx[j]);
751 }
752
753 }
754
755 return clientPro;
Igor Murashkinecf17e82012-10-02 16:05:11 -0700756}
757
Igor Murashkine7ee7632013-06-11 18:10:18 -0700758sp<CameraService::BasicClient> CameraService::findClientUnsafe(
Igor Murashkin294d0ec2012-10-05 10:44:57 -0700759 const wp<IBinder>& cameraClient, int& outIndex) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700760 sp<BasicClient> client;
Igor Murashkinecf17e82012-10-02 16:05:11 -0700761
762 for (int i = 0; i < mNumberOfCameras; i++) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700763
764 // This happens when we have already disconnected (or this is
765 // just another unused camera).
766 if (mClient[i] == 0) continue;
767
768 // Promote mClient. It can fail if we are called from this path:
Igor Murashkin634a5152013-02-20 17:15:11 -0800769 // Client::~Client() -> disconnect() -> removeClientByRemote().
Mathias Agopian65ab4712010-07-14 17:59:35 -0700770 client = mClient[i].promote();
771
Igor Murashkinecf17e82012-10-02 16:05:11 -0700772 // Clean up stale client entry
773 if (client == NULL) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700774 mClient[i].clear();
775 continue;
776 }
777
Igor Murashkine7ee7632013-06-11 18:10:18 -0700778 if (cameraClient == client->getRemote()) {
Igor Murashkinecf17e82012-10-02 16:05:11 -0700779 // Found our camera
780 outIndex = i;
781 return client;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700782 }
783 }
784
Igor Murashkinecf17e82012-10-02 16:05:11 -0700785 outIndex = -1;
786 return NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700787}
788
Igor Murashkine7ee7632013-06-11 18:10:18 -0700789CameraService::BasicClient* CameraService::getClientByIdUnsafe(int cameraId) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700790 if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
Keun young Parkd8973a72012-03-28 14:13:09 -0700791 return mClient[cameraId].unsafe_get();
792}
793
794Mutex* CameraService::getClientLockById(int cameraId) {
795 if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
796 return &mClientLock[cameraId];
Mathias Agopian65ab4712010-07-14 17:59:35 -0700797}
798
Igor Murashkin634a5152013-02-20 17:15:11 -0800799sp<CameraService::BasicClient> CameraService::getClientByRemote(
Igor Murashkin294d0ec2012-10-05 10:44:57 -0700800 const wp<IBinder>& cameraClient) {
Igor Murashkinecf17e82012-10-02 16:05:11 -0700801
802 // Declare this before the lock to make absolutely sure the
803 // destructor won't be called with the lock held.
Igor Murashkin634a5152013-02-20 17:15:11 -0800804 sp<BasicClient> client;
Igor Murashkinecf17e82012-10-02 16:05:11 -0700805
806 Mutex::Autolock lock(mServiceLock);
807
808 int outIndex;
809 client = findClientUnsafe(cameraClient, outIndex);
810
811 return client;
812}
813
Mathias Agopian65ab4712010-07-14 17:59:35 -0700814status_t CameraService::onTransact(
815 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
816 // Permission checks
817 switch (code) {
818 case BnCameraService::CONNECT:
Igor Murashkin634a5152013-02-20 17:15:11 -0800819 case BnCameraService::CONNECT_PRO:
Mathias Agopian65ab4712010-07-14 17:59:35 -0700820 const int pid = getCallingPid();
821 const int self_pid = getpid();
822 if (pid != self_pid) {
823 // we're called from a different process, do the real check
824 if (!checkCallingPermission(
825 String16("android.permission.CAMERA"))) {
826 const int uid = getCallingUid();
Steve Block29357bc2012-01-06 19:20:56 +0000827 ALOGE("Permission Denial: "
Mathias Agopian65ab4712010-07-14 17:59:35 -0700828 "can't use the camera pid=%d, uid=%d", pid, uid);
829 return PERMISSION_DENIED;
830 }
831 }
832 break;
833 }
834
835 return BnCameraService::onTransact(code, data, reply, flags);
836}
837
838// The reason we need this busy bit is a new CameraService::connect() request
839// may come in while the previous Client's destructor has not been run or is
840// still running. If the last strong reference of the previous Client is gone
841// but the destructor has not been finished, we should not allow the new Client
842// to be created because we need to wait for the previous Client to tear down
843// the hardware first.
844void CameraService::setCameraBusy(int cameraId) {
845 android_atomic_write(1, &mBusy[cameraId]);
Igor Murashkinecf17e82012-10-02 16:05:11 -0700846
847 ALOGV("setCameraBusy cameraId=%d", cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700848}
849
850void CameraService::setCameraFree(int cameraId) {
851 android_atomic_write(0, &mBusy[cameraId]);
Igor Murashkinecf17e82012-10-02 16:05:11 -0700852
853 ALOGV("setCameraFree cameraId=%d", cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700854}
855
856// We share the media players for shutter and recording sound for all clients.
857// A reference count is kept to determine when we will actually release the
858// media players.
859
Chih-Chung Changff4f55c2011-10-17 19:03:12 +0800860MediaPlayer* CameraService::newMediaPlayer(const char *file) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700861 MediaPlayer* mp = new MediaPlayer();
862 if (mp->setDataSource(file, NULL) == NO_ERROR) {
Eino-Ville Talvala60a78ac2012-01-05 15:34:53 -0800863 mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700864 mp->prepare();
865 } else {
Steve Block29357bc2012-01-06 19:20:56 +0000866 ALOGE("Failed to load CameraService sounds: %s", file);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700867 return NULL;
868 }
869 return mp;
870}
871
872void CameraService::loadSound() {
873 Mutex::Autolock lock(mSoundLock);
874 LOG1("CameraService::loadSound ref=%d", mSoundRef);
875 if (mSoundRef++) return;
876
877 mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
878 mSoundPlayer[SOUND_RECORDING] = newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");
879}
880
881void CameraService::releaseSound() {
882 Mutex::Autolock lock(mSoundLock);
883 LOG1("CameraService::releaseSound ref=%d", mSoundRef);
884 if (--mSoundRef) return;
885
886 for (int i = 0; i < NUM_SOUNDS; i++) {
887 if (mSoundPlayer[i] != 0) {
888 mSoundPlayer[i]->disconnect();
889 mSoundPlayer[i].clear();
890 }
891 }
892}
893
894void CameraService::playSound(sound_kind kind) {
895 LOG1("playSound(%d)", kind);
896 Mutex::Autolock lock(mSoundLock);
897 sp<MediaPlayer> player = mSoundPlayer[kind];
898 if (player != 0) {
Chih-Chung Chang8888a752011-10-20 10:47:26 +0800899 player->seekTo(0);
900 player->start();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700901 }
902}
903
904// ----------------------------------------------------------------------------
905
906CameraService::Client::Client(const sp<CameraService>& cameraService,
Wu-cheng Lib7a67942010-08-17 15:45:37 -0700907 const sp<ICameraClient>& cameraClient,
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800908 const String16& clientPackageName,
909 int cameraId, int cameraFacing,
910 int clientPid, uid_t clientUid,
911 int servicePid) :
Igor Murashkin634a5152013-02-20 17:15:11 -0800912 CameraService::BasicClient(cameraService, cameraClient->asBinder(),
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800913 clientPackageName,
914 cameraId, cameraFacing,
915 clientPid, clientUid,
916 servicePid)
Igor Murashkin634a5152013-02-20 17:15:11 -0800917{
Mathias Agopian65ab4712010-07-14 17:59:35 -0700918 int callingPid = getCallingPid();
Wu-cheng Li2fd24402012-02-23 19:01:00 -0800919 LOG1("Client::Client E (pid %d, id %d)", callingPid, cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700920
Igor Murashkin44cfcf02013-03-01 16:22:28 -0800921 mRemoteCallback = cameraClient;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700922
Mathias Agopian65ab4712010-07-14 17:59:35 -0700923 cameraService->setCameraBusy(cameraId);
924 cameraService->loadSound();
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800925
Wu-cheng Li2fd24402012-02-23 19:01:00 -0800926 LOG1("Client::Client X (pid %d, id %d)", callingPid, cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700927}
928
Mathias Agopian65ab4712010-07-14 17:59:35 -0700929// tear down the client
930CameraService::Client::~Client() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700931 ALOGV("~Client");
Igor Murashkin634a5152013-02-20 17:15:11 -0800932 mDestructionStarted = true;
933
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700934 mCameraService->releaseSound();
Igor Murashkin036bc3e2012-10-08 15:09:46 -0700935 // unconditionally disconnect. function is idempotent
936 Client::disconnect();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700937}
938
Igor Murashkin634a5152013-02-20 17:15:11 -0800939CameraService::BasicClient::BasicClient(const sp<CameraService>& cameraService,
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800940 const sp<IBinder>& remoteCallback,
941 const String16& clientPackageName,
942 int cameraId, int cameraFacing,
943 int clientPid, uid_t clientUid,
944 int servicePid):
945 mClientPackageName(clientPackageName)
Igor Murashkin634a5152013-02-20 17:15:11 -0800946{
947 mCameraService = cameraService;
Igor Murashkin44cfcf02013-03-01 16:22:28 -0800948 mRemoteBinder = remoteCallback;
Igor Murashkin634a5152013-02-20 17:15:11 -0800949 mCameraId = cameraId;
950 mCameraFacing = cameraFacing;
951 mClientPid = clientPid;
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800952 mClientUid = clientUid;
Igor Murashkin634a5152013-02-20 17:15:11 -0800953 mServicePid = servicePid;
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800954 mOpsActive = false;
Igor Murashkin634a5152013-02-20 17:15:11 -0800955 mDestructionStarted = false;
956}
957
958CameraService::BasicClient::~BasicClient() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700959 ALOGV("~BasicClient");
Igor Murashkin634a5152013-02-20 17:15:11 -0800960 mDestructionStarted = true;
961}
962
963void CameraService::BasicClient::disconnect() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700964 ALOGV("BasicClient::disconnect");
Igor Murashkin44cfcf02013-03-01 16:22:28 -0800965 mCameraService->removeClientByRemote(mRemoteBinder);
Igor Murashkincba2c162013-03-20 15:56:31 -0700966 // client shouldn't be able to call into us anymore
967 mClientPid = 0;
Igor Murashkin634a5152013-02-20 17:15:11 -0800968}
969
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800970status_t CameraService::BasicClient::startCameraOps() {
971 int32_t res;
972
973 mOpsCallback = new OpsCallback(this);
974
Igor Murashkine6800ce2013-03-04 17:25:57 -0800975 {
976 ALOGV("%s: Start camera ops, package name = %s, client UID = %d",
977 __FUNCTION__, String8(mClientPackageName).string(), mClientUid);
978 }
979
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800980 mAppOpsManager.startWatchingMode(AppOpsManager::OP_CAMERA,
981 mClientPackageName, mOpsCallback);
982 res = mAppOpsManager.startOp(AppOpsManager::OP_CAMERA,
983 mClientUid, mClientPackageName);
984
985 if (res != AppOpsManager::MODE_ALLOWED) {
986 ALOGI("Camera %d: Access for \"%s\" has been revoked",
987 mCameraId, String8(mClientPackageName).string());
988 return PERMISSION_DENIED;
989 }
990 mOpsActive = true;
991 return OK;
992}
993
994status_t CameraService::BasicClient::finishCameraOps() {
995 if (mOpsActive) {
996 mAppOpsManager.finishOp(AppOpsManager::OP_CAMERA, mClientUid,
997 mClientPackageName);
998 mOpsActive = false;
999 }
1000 mAppOpsManager.stopWatchingMode(mOpsCallback);
1001 mOpsCallback.clear();
1002
1003 return OK;
1004}
1005
1006void CameraService::BasicClient::opChanged(int32_t op, const String16& packageName) {
1007 String8 name(packageName);
1008 String8 myName(mClientPackageName);
1009
1010 if (op != AppOpsManager::OP_CAMERA) {
1011 ALOGW("Unexpected app ops notification received: %d", op);
1012 return;
1013 }
1014
1015 int32_t res;
1016 res = mAppOpsManager.checkOp(AppOpsManager::OP_CAMERA,
1017 mClientUid, mClientPackageName);
1018 ALOGV("checkOp returns: %d, %s ", res,
1019 res == AppOpsManager::MODE_ALLOWED ? "ALLOWED" :
1020 res == AppOpsManager::MODE_IGNORED ? "IGNORED" :
1021 res == AppOpsManager::MODE_ERRORED ? "ERRORED" :
1022 "UNKNOWN");
1023
1024 if (res != AppOpsManager::MODE_ALLOWED) {
1025 ALOGI("Camera %d: Access for \"%s\" revoked", mCameraId,
1026 myName.string());
1027 // Reset the client PID to allow server-initiated disconnect,
1028 // and to prevent further calls by client.
1029 mClientPid = getCallingPid();
1030 notifyError();
1031 disconnect();
1032 }
1033}
1034
Mathias Agopian65ab4712010-07-14 17:59:35 -07001035// ----------------------------------------------------------------------------
1036
Keun young Parkd8973a72012-03-28 14:13:09 -07001037Mutex* CameraService::Client::getClientLockFromCookie(void* user) {
1038 return gCameraService->getClientLockById((int) user);
1039}
1040
1041// Provide client pointer for callbacks. Client lock returned from getClientLockFromCookie should
1042// be acquired for this to be safe
1043CameraService::Client* CameraService::Client::getClientFromCookie(void* user) {
Igor Murashkine7ee7632013-06-11 18:10:18 -07001044 BasicClient *basicClient = gCameraService->getClientByIdUnsafe((int) user);
1045 // OK: only CameraClient calls this, and they already cast anyway.
1046 Client* client = static_cast<Client*>(basicClient);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001047
1048 // This could happen if the Client is in the process of shutting down (the
1049 // last strong reference is gone, but the destructor hasn't finished
1050 // stopping the hardware).
Keun young Parkd8973a72012-03-28 14:13:09 -07001051 if (client == NULL) return NULL;
1052
1053 // destruction already started, so should not be accessed
1054 if (client->mDestructionStarted) return NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001055
Mathias Agopian65ab4712010-07-14 17:59:35 -07001056 return client;
1057}
1058
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001059void CameraService::Client::notifyError() {
Igor Murashkin44cfcf02013-03-01 16:22:28 -08001060 mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_RELEASED, 0);
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001061}
1062
Igor Murashkin036bc3e2012-10-08 15:09:46 -07001063// NOTE: function is idempotent
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001064void CameraService::Client::disconnect() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -07001065 ALOGV("Client::disconnect");
Igor Murashkin634a5152013-02-20 17:15:11 -08001066 BasicClient::disconnect();
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001067 mCameraService->setCameraFree(mCameraId);
Igor Murashkin93747b92013-05-01 15:42:20 -07001068
1069 StatusVector rejectSourceStates;
1070 rejectSourceStates.push_back(ICameraServiceListener::STATUS_NOT_PRESENT);
1071 rejectSourceStates.push_back(ICameraServiceListener::STATUS_ENUMERATING);
1072
1073 // Transition to PRESENT if the camera is not in either of above 2 states
Igor Murashkincba2c162013-03-20 15:56:31 -07001074 mCameraService->updateStatus(ICameraServiceListener::STATUS_PRESENT,
Igor Murashkin93747b92013-05-01 15:42:20 -07001075 mCameraId,
1076 &rejectSourceStates);
Wu-cheng Lie09591e2010-10-14 20:17:44 +08001077}
1078
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001079CameraService::Client::OpsCallback::OpsCallback(wp<BasicClient> client):
1080 mClient(client) {
1081}
1082
1083void CameraService::Client::OpsCallback::opChanged(int32_t op,
1084 const String16& packageName) {
1085 sp<BasicClient> client = mClient.promote();
1086 if (client != NULL) {
1087 client->opChanged(op, packageName);
1088 }
1089}
1090
Mathias Agopian65ab4712010-07-14 17:59:35 -07001091// ----------------------------------------------------------------------------
Igor Murashkin634a5152013-02-20 17:15:11 -08001092// IProCamera
1093// ----------------------------------------------------------------------------
1094
1095CameraService::ProClient::ProClient(const sp<CameraService>& cameraService,
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001096 const sp<IProCameraCallbacks>& remoteCallback,
1097 const String16& clientPackageName,
1098 int cameraId,
1099 int cameraFacing,
1100 int clientPid,
1101 uid_t clientUid,
1102 int servicePid)
1103 : CameraService::BasicClient(cameraService, remoteCallback->asBinder(),
1104 clientPackageName, cameraId, cameraFacing,
1105 clientPid, clientUid, servicePid)
Igor Murashkin634a5152013-02-20 17:15:11 -08001106{
1107 mRemoteCallback = remoteCallback;
1108}
1109
1110CameraService::ProClient::~ProClient() {
Igor Murashkin634a5152013-02-20 17:15:11 -08001111}
1112
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001113void CameraService::ProClient::notifyError() {
Igor Murashkine6800ce2013-03-04 17:25:57 -08001114 mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_RELEASED, 0);
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001115}
1116
Igor Murashkin634a5152013-02-20 17:15:11 -08001117// ----------------------------------------------------------------------------
Mathias Agopian65ab4712010-07-14 17:59:35 -07001118
1119static const int kDumpLockRetries = 50;
1120static const int kDumpLockSleep = 60000;
1121
1122static bool tryLock(Mutex& mutex)
1123{
1124 bool locked = false;
1125 for (int i = 0; i < kDumpLockRetries; ++i) {
1126 if (mutex.tryLock() == NO_ERROR) {
1127 locked = true;
1128 break;
1129 }
1130 usleep(kDumpLockSleep);
1131 }
1132 return locked;
1133}
1134
1135status_t CameraService::dump(int fd, const Vector<String16>& args) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001136 String8 result;
1137 if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -07001138 result.appendFormat("Permission Denial: "
Mathias Agopian65ab4712010-07-14 17:59:35 -07001139 "can't dump CameraService from pid=%d, uid=%d\n",
1140 getCallingPid(),
1141 getCallingUid());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001142 write(fd, result.string(), result.size());
1143 } else {
1144 bool locked = tryLock(mServiceLock);
1145 // failed to lock - CameraService is probably deadlocked
1146 if (!locked) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -07001147 result.append("CameraService may be deadlocked\n");
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001148 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001149 }
1150
1151 bool hasClient = false;
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001152 if (!mModule) {
1153 result = String8::format("No camera module available!\n");
1154 write(fd, result.string(), result.size());
1155 return NO_ERROR;
1156 }
1157
1158 result = String8::format("Camera module HAL API version: 0x%x\n",
1159 mModule->common.hal_api_version);
1160 result.appendFormat("Camera module API version: 0x%x\n",
1161 mModule->common.module_api_version);
1162 result.appendFormat("Camera module name: %s\n",
1163 mModule->common.name);
1164 result.appendFormat("Camera module author: %s\n",
1165 mModule->common.author);
1166 result.appendFormat("Number of camera devices: %d\n\n", mNumberOfCameras);
1167 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001168 for (int i = 0; i < mNumberOfCameras; i++) {
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001169 result = String8::format("Camera %d static information:\n", i);
1170 camera_info info;
1171
1172 status_t rc = mModule->get_camera_info(i, &info);
1173 if (rc != OK) {
1174 result.appendFormat(" Error reading static information!\n");
1175 write(fd, result.string(), result.size());
1176 } else {
1177 result.appendFormat(" Facing: %s\n",
1178 info.facing == CAMERA_FACING_BACK ? "BACK" : "FRONT");
1179 result.appendFormat(" Orientation: %d\n", info.orientation);
1180 int deviceVersion;
1181 if (mModule->common.module_api_version <
1182 CAMERA_MODULE_API_VERSION_2_0) {
1183 deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
1184 } else {
1185 deviceVersion = info.device_version;
1186 }
1187 result.appendFormat(" Device version: 0x%x\n", deviceVersion);
1188 if (deviceVersion >= CAMERA_DEVICE_API_VERSION_2_0) {
1189 result.appendFormat(" Device static metadata:\n");
1190 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -07001191 dump_indented_camera_metadata(info.static_camera_characteristics,
1192 fd, 2, 4);
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001193 } else {
1194 write(fd, result.string(), result.size());
1195 }
1196 }
1197
Igor Murashkine7ee7632013-06-11 18:10:18 -07001198 sp<BasicClient> client = mClient[i].promote();
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001199 if (client == 0) {
1200 result = String8::format(" Device is closed, no client instance\n");
1201 write(fd, result.string(), result.size());
1202 continue;
1203 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001204 hasClient = true;
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001205 result = String8::format(" Device is open. Client instance dump:\n");
1206 write(fd, result.string(), result.size());
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001207 client->dump(fd, args);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001208 }
1209 if (!hasClient) {
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001210 result = String8::format("\nNo active camera clients yet.\n");
1211 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001212 }
1213
1214 if (locked) mServiceLock.unlock();
1215
1216 // change logging level
1217 int n = args.size();
1218 for (int i = 0; i + 1 < n; i++) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -07001219 String16 verboseOption("-v");
1220 if (args[i] == verboseOption) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001221 String8 levelStr(args[i+1]);
1222 int level = atoi(levelStr.string());
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001223 result = String8::format("\nSetting log level to %d.\n", level);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001224 setLogLevel(level);
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001225 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001226 }
1227 }
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001228
Mathias Agopian65ab4712010-07-14 17:59:35 -07001229 }
1230 return NO_ERROR;
1231}
1232
Igor Murashkinecf17e82012-10-02 16:05:11 -07001233/*virtual*/void CameraService::binderDied(
1234 const wp<IBinder> &who) {
1235
Igor Murashkin294d0ec2012-10-05 10:44:57 -07001236 /**
1237 * While tempting to promote the wp<IBinder> into a sp,
1238 * it's actually not supported by the binder driver
1239 */
1240
Igor Murashkinecf17e82012-10-02 16:05:11 -07001241 ALOGV("java clients' binder died");
1242
Igor Murashkin634a5152013-02-20 17:15:11 -08001243 sp<BasicClient> cameraClient = getClientByRemote(who);
Igor Murashkinecf17e82012-10-02 16:05:11 -07001244
Igor Murashkin294d0ec2012-10-05 10:44:57 -07001245 if (cameraClient == 0) {
Igor Murashkinecf17e82012-10-02 16:05:11 -07001246 ALOGV("java clients' binder death already cleaned up (normal case)");
1247 return;
1248 }
1249
Igor Murashkinecf17e82012-10-02 16:05:11 -07001250 ALOGW("Disconnecting camera client %p since the binder for it "
1251 "died (this pid %d)", cameraClient.get(), getCallingPid());
1252
1253 cameraClient->disconnect();
1254
1255}
1256
Igor Murashkinbfc99152013-02-27 12:55:20 -08001257void CameraService::updateStatus(ICameraServiceListener::Status status,
Igor Murashkin93747b92013-05-01 15:42:20 -07001258 int32_t cameraId,
1259 const StatusVector *rejectSourceStates) {
Igor Murashkinbfc99152013-02-27 12:55:20 -08001260 // do not lock mServiceLock here or can get into a deadlock from
1261 // connect() -> ProClient::disconnect -> updateStatus
1262 Mutex::Autolock lock(mStatusMutex);
Igor Murashkinbfc99152013-02-27 12:55:20 -08001263
1264 ICameraServiceListener::Status oldStatus = mStatusList[cameraId];
1265
1266 mStatusList[cameraId] = status;
1267
1268 if (oldStatus != status) {
1269 ALOGV("%s: Status has changed for camera ID %d from 0x%x to 0x%x",
1270 __FUNCTION__, cameraId, (uint32_t)oldStatus, (uint32_t)status);
1271
Igor Murashkincba2c162013-03-20 15:56:31 -07001272 if (oldStatus == ICameraServiceListener::STATUS_NOT_PRESENT &&
1273 (status != ICameraServiceListener::STATUS_PRESENT &&
1274 status != ICameraServiceListener::STATUS_ENUMERATING)) {
1275
1276 ALOGW("%s: From NOT_PRESENT can only transition into PRESENT"
1277 " or ENUMERATING", __FUNCTION__);
1278 mStatusList[cameraId] = oldStatus;
1279 return;
1280 }
1281
Igor Murashkin93747b92013-05-01 15:42:20 -07001282 if (rejectSourceStates != NULL) {
1283 const StatusVector &rejectList = *rejectSourceStates;
1284 StatusVector::const_iterator it = rejectList.begin();
1285
1286 /**
1287 * Sometimes we want to conditionally do a transition.
1288 * For example if a client disconnects, we want to go to PRESENT
1289 * only if we weren't already in NOT_PRESENT or ENUMERATING.
1290 */
1291 for (; it != rejectList.end(); ++it) {
1292 if (oldStatus == *it) {
1293 ALOGV("%s: Rejecting status transition for Camera ID %d, "
1294 " since the source state was was in one of the bad "
1295 " states.", __FUNCTION__, cameraId);
1296 mStatusList[cameraId] = oldStatus;
1297 return;
1298 }
1299 }
1300 }
1301
Igor Murashkinbfc99152013-02-27 12:55:20 -08001302 /**
1303 * ProClients lose their exclusive lock.
1304 * - Done before the CameraClient can initialize the HAL device,
1305 * since we want to be able to close it before they get to initialize
1306 */
1307 if (status == ICameraServiceListener::STATUS_NOT_AVAILABLE) {
1308 Vector<wp<ProClient> > proClients(mProClientList[cameraId]);
1309 Vector<wp<ProClient> >::const_iterator it;
1310
1311 for (it = proClients.begin(); it != proClients.end(); ++it) {
1312 sp<ProClient> proCl = it->promote();
1313 if (proCl.get() != NULL) {
1314 proCl->onExclusiveLockStolen();
1315 }
1316 }
1317 }
1318
1319 Vector<sp<ICameraServiceListener> >::const_iterator it;
1320 for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
1321 (*it)->onStatusChanged(status, cameraId);
1322 }
1323 }
1324}
1325
Igor Murashkincba2c162013-03-20 15:56:31 -07001326ICameraServiceListener::Status CameraService::getStatus(int cameraId) const {
1327 if (cameraId < 0 || cameraId >= MAX_CAMERAS) {
1328 ALOGE("%s: Invalid camera ID %d", __FUNCTION__, cameraId);
1329 return ICameraServiceListener::STATUS_UNKNOWN;
1330 }
1331
1332 Mutex::Autolock al(mStatusMutex);
1333 return mStatusList[cameraId];
1334}
1335
Mathias Agopian65ab4712010-07-14 17:59:35 -07001336}; // namespace android