blob: eb8bc05f58a102c726dc4da290cdccb891ac3053 [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
25#include <binder/IPCThreadState.h>
26#include <binder/IServiceManager.h>
27#include <binder/MemoryBase.h>
28#include <binder/MemoryHeapBase.h>
29#include <cutils/atomic.h>
Nipun Kwatrab5ca4612010-09-11 19:31:10 -070030#include <cutils/properties.h>
Mathias Agopiandf712ea2012-02-25 18:48:35 -080031#include <gui/Surface.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070032#include <hardware/hardware.h>
33#include <media/AudioSystem.h>
34#include <media/mediaplayer.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070035#include <utils/Errors.h>
36#include <utils/Log.h>
37#include <utils/String16.h>
38
39#include "CameraService.h"
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -070040#include "CameraClient.h"
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070041#include "Camera2Client.h"
Igor Murashkin69e22432013-02-20 18:24:43 -080042#include "ProCamera2Client.h"
Mathias Agopian65ab4712010-07-14 17:59:35 -070043
44namespace android {
45
46// ----------------------------------------------------------------------------
47// Logging support -- this is for debugging only
48// Use "adb shell dumpsys media.camera -v 1" to change it.
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -070049volatile int32_t gLogLevel = 0;
Mathias Agopian65ab4712010-07-14 17:59:35 -070050
Steve Blockb8a80522011-12-20 16:23:08 +000051#define LOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__);
52#define LOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__);
Mathias Agopian65ab4712010-07-14 17:59:35 -070053
54static void setLogLevel(int level) {
55 android_atomic_write(level, &gLogLevel);
56}
57
58// ----------------------------------------------------------------------------
59
60static int getCallingPid() {
61 return IPCThreadState::self()->getCallingPid();
62}
63
64static int getCallingUid() {
65 return IPCThreadState::self()->getCallingUid();
66}
67
68// ----------------------------------------------------------------------------
69
70// This is ugly and only safe if we never re-create the CameraService, but
71// should be ok for now.
72static CameraService *gCameraService;
73
74CameraService::CameraService()
Iliyan Malchev8951a972011-04-14 16:55:59 -070075:mSoundRef(0), mModule(0)
Mathias Agopian65ab4712010-07-14 17:59:35 -070076{
Steve Blockdf64d152012-01-04 20:05:49 +000077 ALOGI("CameraService started (pid=%d)", getpid());
Mathias Agopian65ab4712010-07-14 17:59:35 -070078 gCameraService = this;
79}
80
Iliyan Malchev8951a972011-04-14 16:55:59 -070081void CameraService::onFirstRef()
82{
Igor Murashkinbfb5d5e2013-02-20 17:15:11 -080083 LOG1("CameraService::onFirstRef");
84
Iliyan Malchev8951a972011-04-14 16:55:59 -070085 BnCameraService::onFirstRef();
86
87 if (hw_get_module(CAMERA_HARDWARE_MODULE_ID,
88 (const hw_module_t **)&mModule) < 0) {
Steve Block29357bc2012-01-06 19:20:56 +000089 ALOGE("Could not load camera HAL module");
Iliyan Malchev8951a972011-04-14 16:55:59 -070090 mNumberOfCameras = 0;
91 }
92 else {
Alex Ray53c8ad32013-02-20 13:39:37 -080093 ALOGI("Loaded \"%s\" camera module", mModule->common.name);
Iliyan Malchev8951a972011-04-14 16:55:59 -070094 mNumberOfCameras = mModule->get_number_of_cameras();
95 if (mNumberOfCameras > MAX_CAMERAS) {
Steve Block29357bc2012-01-06 19:20:56 +000096 ALOGE("Number of cameras(%d) > MAX_CAMERAS(%d).",
Iliyan Malchev8951a972011-04-14 16:55:59 -070097 mNumberOfCameras, MAX_CAMERAS);
98 mNumberOfCameras = MAX_CAMERAS;
99 }
100 for (int i = 0; i < mNumberOfCameras; i++) {
101 setCameraFree(i);
102 }
103 }
104}
105
Mathias Agopian65ab4712010-07-14 17:59:35 -0700106CameraService::~CameraService() {
107 for (int i = 0; i < mNumberOfCameras; i++) {
108 if (mBusy[i]) {
Steve Block29357bc2012-01-06 19:20:56 +0000109 ALOGE("camera %d is still in use in destructor!", i);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700110 }
111 }
112
113 gCameraService = NULL;
114}
115
116int32_t CameraService::getNumberOfCameras() {
117 return mNumberOfCameras;
118}
119
120status_t CameraService::getCameraInfo(int cameraId,
121 struct CameraInfo* cameraInfo) {
Iliyan Malchev8951a972011-04-14 16:55:59 -0700122 if (!mModule) {
123 return NO_INIT;
124 }
125
Mathias Agopian65ab4712010-07-14 17:59:35 -0700126 if (cameraId < 0 || cameraId >= mNumberOfCameras) {
127 return BAD_VALUE;
128 }
129
Iliyan Malchev8951a972011-04-14 16:55:59 -0700130 struct camera_info info;
131 status_t rc = mModule->get_camera_info(cameraId, &info);
132 cameraInfo->facing = info.facing;
133 cameraInfo->orientation = info.orientation;
134 return rc;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700135}
136
Igor Murashkinbfb5d5e2013-02-20 17:15:11 -0800137int CameraService::getDeviceVersion(int cameraId, int* facing) {
138 struct camera_info info;
139 if (mModule->get_camera_info(cameraId, &info) != OK) {
140 return -1;
141 }
142
143 int deviceVersion;
144 if (mModule->common.module_api_version >= CAMERA_MODULE_API_VERSION_2_0) {
145 deviceVersion = info.device_version;
146 } else {
147 deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
148 }
149
150 if (facing) {
151 *facing = info.facing;
152 }
153
154 return deviceVersion;
155}
156
Mathias Agopian65ab4712010-07-14 17:59:35 -0700157sp<ICamera> CameraService::connect(
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800158 const sp<ICameraClient>& cameraClient, int cameraId) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700159 int callingPid = getCallingPid();
Tyler Luu5861a9a2011-10-06 00:00:03 -0500160
Mathias Agopian65ab4712010-07-14 17:59:35 -0700161 LOG1("CameraService::connect E (pid %d, id %d)", callingPid, cameraId);
162
Iliyan Malchev8951a972011-04-14 16:55:59 -0700163 if (!mModule) {
Steve Block29357bc2012-01-06 19:20:56 +0000164 ALOGE("Camera HAL module not loaded");
Iliyan Malchev8951a972011-04-14 16:55:59 -0700165 return NULL;
166 }
167
Mathias Agopian65ab4712010-07-14 17:59:35 -0700168 sp<Client> client;
169 if (cameraId < 0 || cameraId >= mNumberOfCameras) {
Steve Block29357bc2012-01-06 19:20:56 +0000170 ALOGE("CameraService::connect X (pid %d) rejected (invalid cameraId %d).",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700171 callingPid, cameraId);
172 return NULL;
173 }
174
Wu-cheng Lia3355432011-05-20 14:54:25 +0800175 char value[PROPERTY_VALUE_MAX];
176 property_get("sys.secpolicy.camera.disabled", value, "0");
177 if (strcmp(value, "1") == 0) {
178 // Camera is disabled by DevicePolicyManager.
Steve Blockdf64d152012-01-04 20:05:49 +0000179 ALOGI("Camera is disabled. connect X (pid %d) rejected", callingPid);
Wu-cheng Lia3355432011-05-20 14:54:25 +0800180 return NULL;
181 }
182
Wu-cheng Li2fd24402012-02-23 19:01:00 -0800183 Mutex::Autolock lock(mServiceLock);
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800184 if (mClient[cameraId] != 0) {
185 client = mClient[cameraId].promote();
186 if (client != 0) {
187 if (cameraClient->asBinder() == client->getCameraClient()->asBinder()) {
188 LOG1("CameraService::connect X (pid %d) (the same client)",
189 callingPid);
190 return client;
191 } else {
Igor Murashkine4e5b2f2013-02-20 16:50:13 -0800192 // TODOSC: need to support 1 regular client, multiple shared clients here
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800193 ALOGW("CameraService::connect X (pid %d) rejected (existing client).",
194 callingPid);
Wu-cheng Li2fd24402012-02-23 19:01:00 -0800195 return NULL;
196 }
Wu-cheng Li2fd24402012-02-23 19:01:00 -0800197 }
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800198 mClient[cameraId].clear();
199 }
200
Igor Murashkinbfb5d5e2013-02-20 17:15:11 -0800201 /*
202 mBusy is set to false as the last step of the Client destructor,
203 after which it is guaranteed that the Client destructor has finished (
204 including any inherited destructors)
205
206 We only need this for a Client subclasses since we don't allow
207 multiple Clents to be opened concurrently, but multiple BasicClient
208 would be fine
209 */
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800210 if (mBusy[cameraId]) {
211 ALOGW("CameraService::connect X (pid %d) rejected"
212 " (camera %d is still busy).", callingPid, cameraId);
213 return NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700214 }
215
Igor Murashkinbfb5d5e2013-02-20 17:15:11 -0800216 int facing = -1;
217 int deviceVersion = getDeviceVersion(cameraId, &facing);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700218
219 switch(deviceVersion) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700220 case CAMERA_DEVICE_API_VERSION_1_0:
221 client = new CameraClient(this, cameraClient, cameraId,
Igor Murashkinbfb5d5e2013-02-20 17:15:11 -0800222 facing, callingPid, getpid());
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700223 break;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700224 case CAMERA_DEVICE_API_VERSION_2_0:
Igor Murashkinbfb5d5e2013-02-20 17:15:11 -0800225 case CAMERA_DEVICE_API_VERSION_2_1:
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700226 client = new Camera2Client(this, cameraClient, cameraId,
Igor Murashkinbfb5d5e2013-02-20 17:15:11 -0800227 facing, callingPid, getpid());
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700228 break;
Igor Murashkinbfb5d5e2013-02-20 17:15:11 -0800229 case -1:
230 ALOGE("Invalid camera id %d", cameraId);
231 return NULL;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700232 default:
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700233 ALOGE("Unknown camera device HAL version: %d", deviceVersion);
Tyler Luu5861a9a2011-10-06 00:00:03 -0500234 return NULL;
235 }
236
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700237 if (client->initialize(mModule) != OK) {
238 return NULL;
239 }
240
Igor Murashkin8dcdb952012-10-02 16:05:11 -0700241 cameraClient->asBinder()->linkToDeath(this);
242
Mathias Agopian65ab4712010-07-14 17:59:35 -0700243 mClient[cameraId] = client;
Igor Murashkin8dcdb952012-10-02 16:05:11 -0700244 LOG1("CameraService::connect X (id %d, this pid is %d)", cameraId, getpid());
Mathias Agopian65ab4712010-07-14 17:59:35 -0700245 return client;
246}
247
Igor Murashkinbfb5d5e2013-02-20 17:15:11 -0800248sp<IProCameraUser> CameraService::connect(
249 const sp<IProCameraCallbacks>& cameraCb,
250 int cameraId)
251{
Mathias Agopian65ab4712010-07-14 17:59:35 -0700252 int callingPid = getCallingPid();
Igor Murashkinbfb5d5e2013-02-20 17:15:11 -0800253
254 LOG1("CameraService::connectPro E (pid %d, id %d)", callingPid, cameraId);
255
256 if (!mModule) {
257 ALOGE("Camera HAL module not loaded");
258 return NULL;
259 }
260
261 sp<ProClient> client;
262 if (cameraId < 0 || cameraId >= mNumberOfCameras) {
263 ALOGE("CameraService::connectPro X (pid %d) rejected (invalid cameraId %d).",
264 callingPid, cameraId);
265 return NULL;
266 }
267
268 char value[PROPERTY_VALUE_MAX];
269 property_get("sys.secpolicy.camera.disabled", value, "0");
270 if (strcmp(value, "1") == 0) {
271 // Camera is disabled by DevicePolicyManager.
272 ALOGI("Camera is disabled. connect X (pid %d) rejected", callingPid);
273 return NULL;
274 }
275
276 int facing = -1;
277 int deviceVersion = getDeviceVersion(cameraId, &facing);
278
279 switch(deviceVersion) {
280 case CAMERA_DEVICE_API_VERSION_1_0:
281 ALOGE("Camera id %d uses HALv1, doesn't support ProCamera", cameraId);
282 return NULL;
283 break;
284 case CAMERA_DEVICE_API_VERSION_2_0:
Igor Murashkin69e22432013-02-20 18:24:43 -0800285 case CAMERA_DEVICE_API_VERSION_2_1:
286 client = new ProCamera2Client(this, cameraCb, cameraId,
Igor Murashkinbfb5d5e2013-02-20 17:15:11 -0800287 facing, callingPid, getpid());
288 break;
289 case -1:
290 ALOGE("Invalid camera id %d", cameraId);
291 return NULL;
292 default:
293 ALOGE("Unknown camera device HAL version: %d", deviceVersion);
294 return NULL;
295 }
296
297 if (client->initialize(mModule) != OK) {
298 return NULL;
299 }
300
301 mProClientList[cameraId].push(client);
302
303 cameraCb->asBinder()->linkToDeath(this);
304
305 LOG1("CameraService::connect X (id %d, this pid is %d)", cameraId, getpid());
306 return client;
307
308
309 return NULL;
310}
311
312void CameraService::removeClientByRemote(const wp<IBinder>& remoteBinder) {
313 int callingPid = getCallingPid();
314 LOG1("CameraService::removeClientByRemote E (pid %d)", callingPid);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700315
Igor Murashkin8dcdb952012-10-02 16:05:11 -0700316 // Declare this before the lock to make absolutely sure the
317 // destructor won't be called with the lock held.
318 Mutex::Autolock lock(mServiceLock);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700319
Igor Murashkin8dcdb952012-10-02 16:05:11 -0700320 int outIndex;
Igor Murashkinbfb5d5e2013-02-20 17:15:11 -0800321 sp<Client> client = findClientUnsafe(remoteBinder, outIndex);
Igor Murashkin8dcdb952012-10-02 16:05:11 -0700322
323 if (client != 0) {
324 // Found our camera, clear and leave.
325 LOG1("removeClient: clear camera %d", outIndex);
326 mClient[outIndex].clear();
327
328 client->unlinkToDeath(this);
Igor Murashkinbfb5d5e2013-02-20 17:15:11 -0800329 } else {
330
331 sp<ProClient> clientPro = findProClientUnsafe(remoteBinder);
332
333 if (clientPro != NULL) {
334 // Found our camera, clear and leave.
335 LOG1("removeClient: clear pro %p", clientPro.get());
336
337 clientPro->getRemoteCallback()->asBinder()->unlinkToDeath(this);
338 }
Igor Murashkin8dcdb952012-10-02 16:05:11 -0700339 }
340
Igor Murashkinbfb5d5e2013-02-20 17:15:11 -0800341 LOG1("CameraService::removeClientByRemote X (pid %d)", callingPid);
342}
343
344sp<CameraService::ProClient> CameraService::findProClientUnsafe(
345 const wp<IBinder>& cameraCallbacksRemote)
346{
347 sp<ProClient> clientPro;
348
349 for (int i = 0; i < mNumberOfCameras; ++i) {
350 Vector<size_t> removeIdx;
351
352 for (size_t j = 0; j < mProClientList[i].size(); ++j) {
353 wp<ProClient> cl = mProClientList[i][j];
354
355 sp<ProClient> clStrong = cl.promote();
356 if (clStrong != NULL && clStrong->getRemote() == cameraCallbacksRemote) {
357 clientPro = clStrong;
358 break;
359 } else if (clStrong == NULL) {
360 // mark to clean up dead ptr
361 removeIdx.push(j);
362 }
363 }
364
365 // remove stale ptrs (in reverse so the indices dont change)
366 for (ssize_t j = (ssize_t)removeIdx.size() - 1; j >= 0; --j) {
367 mProClientList[i].removeAt(removeIdx[j]);
368 }
369
370 }
371
372 return clientPro;
Igor Murashkin8dcdb952012-10-02 16:05:11 -0700373}
374
375sp<CameraService::Client> CameraService::findClientUnsafe(
Igor Murashkin507994d2012-10-05 10:44:57 -0700376 const wp<IBinder>& cameraClient, int& outIndex) {
Igor Murashkin8dcdb952012-10-02 16:05:11 -0700377 sp<Client> client;
378
379 for (int i = 0; i < mNumberOfCameras; i++) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700380
381 // This happens when we have already disconnected (or this is
382 // just another unused camera).
383 if (mClient[i] == 0) continue;
384
385 // Promote mClient. It can fail if we are called from this path:
Igor Murashkinbfb5d5e2013-02-20 17:15:11 -0800386 // Client::~Client() -> disconnect() -> removeClientByRemote().
Mathias Agopian65ab4712010-07-14 17:59:35 -0700387 client = mClient[i].promote();
388
Igor Murashkin8dcdb952012-10-02 16:05:11 -0700389 // Clean up stale client entry
390 if (client == NULL) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700391 mClient[i].clear();
392 continue;
393 }
394
Igor Murashkin507994d2012-10-05 10:44:57 -0700395 if (cameraClient == client->getCameraClient()->asBinder()) {
Igor Murashkin8dcdb952012-10-02 16:05:11 -0700396 // Found our camera
397 outIndex = i;
398 return client;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700399 }
400 }
401
Igor Murashkin8dcdb952012-10-02 16:05:11 -0700402 outIndex = -1;
403 return NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700404}
405
Keun young Parkd8973a72012-03-28 14:13:09 -0700406CameraService::Client* CameraService::getClientByIdUnsafe(int cameraId) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700407 if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
Keun young Parkd8973a72012-03-28 14:13:09 -0700408 return mClient[cameraId].unsafe_get();
409}
410
411Mutex* CameraService::getClientLockById(int cameraId) {
412 if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
413 return &mClientLock[cameraId];
Mathias Agopian65ab4712010-07-14 17:59:35 -0700414}
415
Igor Murashkinbfb5d5e2013-02-20 17:15:11 -0800416sp<CameraService::BasicClient> CameraService::getClientByRemote(
Igor Murashkin507994d2012-10-05 10:44:57 -0700417 const wp<IBinder>& cameraClient) {
Igor Murashkin8dcdb952012-10-02 16:05:11 -0700418
419 // Declare this before the lock to make absolutely sure the
420 // destructor won't be called with the lock held.
Igor Murashkinbfb5d5e2013-02-20 17:15:11 -0800421 sp<BasicClient> client;
Igor Murashkin8dcdb952012-10-02 16:05:11 -0700422
423 Mutex::Autolock lock(mServiceLock);
424
425 int outIndex;
426 client = findClientUnsafe(cameraClient, outIndex);
427
428 return client;
429}
430
Mathias Agopian65ab4712010-07-14 17:59:35 -0700431status_t CameraService::onTransact(
432 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
433 // Permission checks
434 switch (code) {
435 case BnCameraService::CONNECT:
Igor Murashkinbfb5d5e2013-02-20 17:15:11 -0800436 case BnCameraService::CONNECT_PRO:
Mathias Agopian65ab4712010-07-14 17:59:35 -0700437 const int pid = getCallingPid();
438 const int self_pid = getpid();
439 if (pid != self_pid) {
440 // we're called from a different process, do the real check
441 if (!checkCallingPermission(
442 String16("android.permission.CAMERA"))) {
443 const int uid = getCallingUid();
Steve Block29357bc2012-01-06 19:20:56 +0000444 ALOGE("Permission Denial: "
Mathias Agopian65ab4712010-07-14 17:59:35 -0700445 "can't use the camera pid=%d, uid=%d", pid, uid);
446 return PERMISSION_DENIED;
447 }
448 }
449 break;
450 }
451
452 return BnCameraService::onTransact(code, data, reply, flags);
453}
454
455// The reason we need this busy bit is a new CameraService::connect() request
456// may come in while the previous Client's destructor has not been run or is
457// still running. If the last strong reference of the previous Client is gone
458// but the destructor has not been finished, we should not allow the new Client
459// to be created because we need to wait for the previous Client to tear down
460// the hardware first.
461void CameraService::setCameraBusy(int cameraId) {
462 android_atomic_write(1, &mBusy[cameraId]);
Igor Murashkin8dcdb952012-10-02 16:05:11 -0700463
464 ALOGV("setCameraBusy cameraId=%d", cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700465}
466
467void CameraService::setCameraFree(int cameraId) {
468 android_atomic_write(0, &mBusy[cameraId]);
Igor Murashkin8dcdb952012-10-02 16:05:11 -0700469
470 ALOGV("setCameraFree cameraId=%d", cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700471}
472
473// We share the media players for shutter and recording sound for all clients.
474// A reference count is kept to determine when we will actually release the
475// media players.
476
Chih-Chung Changff4f55c2011-10-17 19:03:12 +0800477MediaPlayer* CameraService::newMediaPlayer(const char *file) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700478 MediaPlayer* mp = new MediaPlayer();
479 if (mp->setDataSource(file, NULL) == NO_ERROR) {
Eino-Ville Talvala60a78ac2012-01-05 15:34:53 -0800480 mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700481 mp->prepare();
482 } else {
Steve Block29357bc2012-01-06 19:20:56 +0000483 ALOGE("Failed to load CameraService sounds: %s", file);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700484 return NULL;
485 }
486 return mp;
487}
488
489void CameraService::loadSound() {
490 Mutex::Autolock lock(mSoundLock);
491 LOG1("CameraService::loadSound ref=%d", mSoundRef);
492 if (mSoundRef++) return;
493
494 mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
495 mSoundPlayer[SOUND_RECORDING] = newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");
496}
497
498void CameraService::releaseSound() {
499 Mutex::Autolock lock(mSoundLock);
500 LOG1("CameraService::releaseSound ref=%d", mSoundRef);
501 if (--mSoundRef) return;
502
503 for (int i = 0; i < NUM_SOUNDS; i++) {
504 if (mSoundPlayer[i] != 0) {
505 mSoundPlayer[i]->disconnect();
506 mSoundPlayer[i].clear();
507 }
508 }
509}
510
511void CameraService::playSound(sound_kind kind) {
512 LOG1("playSound(%d)", kind);
513 Mutex::Autolock lock(mSoundLock);
514 sp<MediaPlayer> player = mSoundPlayer[kind];
515 if (player != 0) {
Chih-Chung Chang8888a752011-10-20 10:47:26 +0800516 player->seekTo(0);
517 player->start();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700518 }
519}
520
521// ----------------------------------------------------------------------------
522
523CameraService::Client::Client(const sp<CameraService>& cameraService,
Wu-cheng Lib7a67942010-08-17 15:45:37 -0700524 const sp<ICameraClient>& cameraClient,
Igor Murashkinbfb5d5e2013-02-20 17:15:11 -0800525 int cameraId, int cameraFacing, int clientPid, int servicePid) :
526 CameraService::BasicClient(cameraService, cameraClient->asBinder(),
527 cameraId, cameraFacing,
528 clientPid, servicePid)
529{
Mathias Agopian65ab4712010-07-14 17:59:35 -0700530 int callingPid = getCallingPid();
Wu-cheng Li2fd24402012-02-23 19:01:00 -0800531 LOG1("Client::Client E (pid %d, id %d)", callingPid, cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700532
Mathias Agopian65ab4712010-07-14 17:59:35 -0700533 mCameraClient = cameraClient;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700534
Mathias Agopian65ab4712010-07-14 17:59:35 -0700535 cameraService->setCameraBusy(cameraId);
536 cameraService->loadSound();
Wu-cheng Li2fd24402012-02-23 19:01:00 -0800537 LOG1("Client::Client X (pid %d, id %d)", callingPid, cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700538}
539
Mathias Agopian65ab4712010-07-14 17:59:35 -0700540// tear down the client
541CameraService::Client::~Client() {
Igor Murashkinbfb5d5e2013-02-20 17:15:11 -0800542 mDestructionStarted = true;
543
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700544 mCameraService->releaseSound();
Igor Murashkinbe8d28a2012-10-08 15:09:46 -0700545
546 // unconditionally disconnect. function is idempotent
547 Client::disconnect();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700548}
549
Igor Murashkinbfb5d5e2013-02-20 17:15:11 -0800550CameraService::BasicClient::BasicClient(const sp<CameraService>& cameraService,
551 const sp<IBinder>& remoteCallback,
552 int cameraId, int cameraFacing,
553 int clientPid, int servicePid)
554{
555 mCameraService = cameraService;
556 mRemoteCallback = remoteCallback;
557 mCameraId = cameraId;
558 mCameraFacing = cameraFacing;
559 mClientPid = clientPid;
560 mServicePid = servicePid;
561
562 mDestructionStarted = false;
563}
564
565CameraService::BasicClient::~BasicClient() {
566 mDestructionStarted = true;
567}
568
569void CameraService::BasicClient::disconnect() {
570 mCameraService->removeClientByRemote(mRemoteCallback);
571}
572
Mathias Agopian65ab4712010-07-14 17:59:35 -0700573// ----------------------------------------------------------------------------
574
Keun young Parkd8973a72012-03-28 14:13:09 -0700575Mutex* CameraService::Client::getClientLockFromCookie(void* user) {
576 return gCameraService->getClientLockById((int) user);
577}
578
579// Provide client pointer for callbacks. Client lock returned from getClientLockFromCookie should
580// be acquired for this to be safe
581CameraService::Client* CameraService::Client::getClientFromCookie(void* user) {
582 Client* client = gCameraService->getClientByIdUnsafe((int) user);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700583
584 // This could happen if the Client is in the process of shutting down (the
585 // last strong reference is gone, but the destructor hasn't finished
586 // stopping the hardware).
Keun young Parkd8973a72012-03-28 14:13:09 -0700587 if (client == NULL) return NULL;
588
589 // destruction already started, so should not be accessed
590 if (client->mDestructionStarted) return NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700591
Mathias Agopian65ab4712010-07-14 17:59:35 -0700592 return client;
593}
594
Igor Murashkinbe8d28a2012-10-08 15:09:46 -0700595// NOTE: function is idempotent
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700596void CameraService::Client::disconnect() {
Igor Murashkinbfb5d5e2013-02-20 17:15:11 -0800597 BasicClient::disconnect();
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700598 mCameraService->setCameraFree(mCameraId);
Wu-cheng Lie09591e2010-10-14 20:17:44 +0800599}
600
Mathias Agopian65ab4712010-07-14 17:59:35 -0700601// ----------------------------------------------------------------------------
Igor Murashkinbfb5d5e2013-02-20 17:15:11 -0800602// IProCamera
603// ----------------------------------------------------------------------------
604
605CameraService::ProClient::ProClient(const sp<CameraService>& cameraService,
606 const sp<IProCameraCallbacks>& remoteCallback,
607 int cameraId,
608 int cameraFacing,
609 int clientPid,
610 int servicePid)
611 : CameraService::BasicClient(cameraService, remoteCallback->asBinder(),
612 cameraId, cameraFacing,
613 clientPid, servicePid)
614{
615 mRemoteCallback = remoteCallback;
616}
617
618CameraService::ProClient::~ProClient() {
619 mDestructionStarted = true;
620
621 ProClient::disconnect();
622}
623
624status_t CameraService::ProClient::connect(const sp<IProCameraCallbacks>& callbacks) {
625 ALOGE("%s: not implemented yet", __FUNCTION__);
626
627 return INVALID_OPERATION;
628}
629
630void CameraService::ProClient::disconnect() {
631 BasicClient::disconnect();
632}
633
634status_t CameraService::ProClient::initialize(camera_module_t* module)
635{
636 ALOGW("%s: not implemented yet", __FUNCTION__);
637 return OK;
638}
639
640status_t CameraService::ProClient::exclusiveTryLock() {
641 ALOGE("%s: not implemented yet", __FUNCTION__);
642 return INVALID_OPERATION;
643}
644
645status_t CameraService::ProClient::exclusiveLock() {
646 ALOGE("%s: not implemented yet", __FUNCTION__);
647 return INVALID_OPERATION;
648}
649
650status_t CameraService::ProClient::exclusiveUnlock() {
651 ALOGE("%s: not implemented yet", __FUNCTION__);
652 return INVALID_OPERATION;
653}
654
655bool CameraService::ProClient::hasExclusiveLock() {
656 ALOGE("%s: not implemented yet", __FUNCTION__);
657 return false;
658}
659
660status_t CameraService::ProClient::submitRequest(camera_metadata_t* request, bool streaming) {
661 ALOGE("%s: not implemented yet", __FUNCTION__);
662
663 free_camera_metadata(request);
664
665 return INVALID_OPERATION;
666}
667
668status_t CameraService::ProClient::cancelRequest(int requestId) {
669 ALOGE("%s: not implemented yet", __FUNCTION__);
670
671 return INVALID_OPERATION;
672}
673
674status_t CameraService::ProClient::requestStream(int streamId) {
675 ALOGE("%s: not implemented yet", __FUNCTION__);
676
677 return INVALID_OPERATION;
678}
679
680status_t CameraService::ProClient::cancelStream(int streamId) {
681 ALOGE("%s: not implemented yet", __FUNCTION__);
682
683 return INVALID_OPERATION;
684}
685
686// ----------------------------------------------------------------------------
Mathias Agopian65ab4712010-07-14 17:59:35 -0700687
688static const int kDumpLockRetries = 50;
689static const int kDumpLockSleep = 60000;
690
691static bool tryLock(Mutex& mutex)
692{
693 bool locked = false;
694 for (int i = 0; i < kDumpLockRetries; ++i) {
695 if (mutex.tryLock() == NO_ERROR) {
696 locked = true;
697 break;
698 }
699 usleep(kDumpLockSleep);
700 }
701 return locked;
702}
703
704status_t CameraService::dump(int fd, const Vector<String16>& args) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700705 String8 result;
706 if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700707 result.appendFormat("Permission Denial: "
Mathias Agopian65ab4712010-07-14 17:59:35 -0700708 "can't dump CameraService from pid=%d, uid=%d\n",
709 getCallingPid(),
710 getCallingUid());
Mathias Agopian65ab4712010-07-14 17:59:35 -0700711 write(fd, result.string(), result.size());
712 } else {
713 bool locked = tryLock(mServiceLock);
714 // failed to lock - CameraService is probably deadlocked
715 if (!locked) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700716 result.append("CameraService may be deadlocked\n");
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -0700717 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -0700718 }
719
720 bool hasClient = false;
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -0700721 if (!mModule) {
722 result = String8::format("No camera module available!\n");
723 write(fd, result.string(), result.size());
724 return NO_ERROR;
725 }
726
727 result = String8::format("Camera module HAL API version: 0x%x\n",
728 mModule->common.hal_api_version);
729 result.appendFormat("Camera module API version: 0x%x\n",
730 mModule->common.module_api_version);
731 result.appendFormat("Camera module name: %s\n",
732 mModule->common.name);
733 result.appendFormat("Camera module author: %s\n",
734 mModule->common.author);
735 result.appendFormat("Number of camera devices: %d\n\n", mNumberOfCameras);
736 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -0700737 for (int i = 0; i < mNumberOfCameras; i++) {
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -0700738 result = String8::format("Camera %d static information:\n", i);
739 camera_info info;
740
741 status_t rc = mModule->get_camera_info(i, &info);
742 if (rc != OK) {
743 result.appendFormat(" Error reading static information!\n");
744 write(fd, result.string(), result.size());
745 } else {
746 result.appendFormat(" Facing: %s\n",
747 info.facing == CAMERA_FACING_BACK ? "BACK" : "FRONT");
748 result.appendFormat(" Orientation: %d\n", info.orientation);
749 int deviceVersion;
750 if (mModule->common.module_api_version <
751 CAMERA_MODULE_API_VERSION_2_0) {
752 deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
753 } else {
754 deviceVersion = info.device_version;
755 }
756 result.appendFormat(" Device version: 0x%x\n", deviceVersion);
757 if (deviceVersion >= CAMERA_DEVICE_API_VERSION_2_0) {
758 result.appendFormat(" Device static metadata:\n");
759 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700760 dump_indented_camera_metadata(info.static_camera_characteristics,
761 fd, 2, 4);
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -0700762 } else {
763 write(fd, result.string(), result.size());
764 }
765 }
766
Mathias Agopian65ab4712010-07-14 17:59:35 -0700767 sp<Client> client = mClient[i].promote();
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -0700768 if (client == 0) {
769 result = String8::format(" Device is closed, no client instance\n");
770 write(fd, result.string(), result.size());
771 continue;
772 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700773 hasClient = true;
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -0700774 result = String8::format(" Device is open. Client instance dump:\n");
775 write(fd, result.string(), result.size());
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700776 client->dump(fd, args);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700777 }
778 if (!hasClient) {
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -0700779 result = String8::format("\nNo active camera clients yet.\n");
780 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -0700781 }
782
783 if (locked) mServiceLock.unlock();
784
785 // change logging level
786 int n = args.size();
787 for (int i = 0; i + 1 < n; i++) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700788 String16 verboseOption("-v");
789 if (args[i] == verboseOption) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700790 String8 levelStr(args[i+1]);
791 int level = atoi(levelStr.string());
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -0700792 result = String8::format("\nSetting log level to %d.\n", level);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700793 setLogLevel(level);
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -0700794 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -0700795 }
796 }
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -0700797
Mathias Agopian65ab4712010-07-14 17:59:35 -0700798 }
799 return NO_ERROR;
800}
801
Igor Murashkin8dcdb952012-10-02 16:05:11 -0700802/*virtual*/void CameraService::binderDied(
803 const wp<IBinder> &who) {
804
Igor Murashkin507994d2012-10-05 10:44:57 -0700805 /**
806 * While tempting to promote the wp<IBinder> into a sp,
807 * it's actually not supported by the binder driver
808 */
809
Igor Murashkin8dcdb952012-10-02 16:05:11 -0700810 ALOGV("java clients' binder died");
811
Igor Murashkinbfb5d5e2013-02-20 17:15:11 -0800812 sp<BasicClient> cameraClient = getClientByRemote(who);
Igor Murashkin8dcdb952012-10-02 16:05:11 -0700813
Igor Murashkin507994d2012-10-05 10:44:57 -0700814 if (cameraClient == 0) {
Igor Murashkin8dcdb952012-10-02 16:05:11 -0700815 ALOGV("java clients' binder death already cleaned up (normal case)");
816 return;
817 }
818
Igor Murashkin8dcdb952012-10-02 16:05:11 -0700819 ALOGW("Disconnecting camera client %p since the binder for it "
820 "died (this pid %d)", cameraClient.get(), getCallingPid());
821
822 cameraClient->disconnect();
823
824}
825
Mathias Agopian65ab4712010-07-14 17:59:35 -0700826}; // namespace android