CameraService.cpp revision f69c70ded4316ea3ee504ac779bd024433ed4ef7
1/* 2** 3** Copyright (C) 2008, The Android Open Source Project 4** 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" 19//#define LOG_NDEBUG 0 20 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> 30#include <cutils/properties.h> 31#include <gui/SurfaceTextureClient.h> 32#include <gui/Surface.h> 33#include <hardware/hardware.h> 34#include <media/AudioSystem.h> 35#include <media/mediaplayer.h> 36#include <utils/Errors.h> 37#include <utils/Log.h> 38#include <utils/String16.h> 39 40#include "CameraService.h" 41#include "CameraClient.h" 42#include "Camera2Client.h" 43 44namespace android { 45 46// ---------------------------------------------------------------------------- 47// Logging support -- this is for debugging only 48// Use "adb shell dumpsys media.camera -v 1" to change it. 49volatile int32_t gLogLevel = 0; 50 51#define LOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__); 52#define LOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__); 53 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() 75:mSoundRef(0), mModule(0) 76{ 77 ALOGI("CameraService started (pid=%d)", getpid()); 78 gCameraService = this; 79} 80 81void CameraService::onFirstRef() 82{ 83 BnCameraService::onFirstRef(); 84 85 if (hw_get_module(CAMERA_HARDWARE_MODULE_ID, 86 (const hw_module_t **)&mModule) < 0) { 87 ALOGE("Could not load camera HAL module"); 88 mNumberOfCameras = 0; 89 } 90 else { 91 mNumberOfCameras = mModule->get_number_of_cameras(); 92 if (mNumberOfCameras > MAX_CAMERAS) { 93 ALOGE("Number of cameras(%d) > MAX_CAMERAS(%d).", 94 mNumberOfCameras, MAX_CAMERAS); 95 mNumberOfCameras = MAX_CAMERAS; 96 } 97 for (int i = 0; i < mNumberOfCameras; i++) { 98 setCameraFree(i); 99 } 100 } 101} 102 103CameraService::~CameraService() { 104 for (int i = 0; i < mNumberOfCameras; i++) { 105 if (mBusy[i]) { 106 ALOGE("camera %d is still in use in destructor!", i); 107 } 108 } 109 110 gCameraService = NULL; 111} 112 113int32_t CameraService::getNumberOfCameras() { 114 return mNumberOfCameras; 115} 116 117status_t CameraService::getCameraInfo(int cameraId, 118 struct CameraInfo* cameraInfo) { 119 if (!mModule) { 120 return NO_INIT; 121 } 122 123 if (cameraId < 0 || cameraId >= mNumberOfCameras) { 124 return BAD_VALUE; 125 } 126 127 struct camera_info info; 128 status_t rc = mModule->get_camera_info(cameraId, &info); 129 cameraInfo->facing = info.facing; 130 cameraInfo->orientation = info.orientation; 131 return rc; 132} 133 134sp<ICamera> CameraService::connect( 135 const sp<ICameraClient>& cameraClient, int cameraId) { 136 int callingPid = getCallingPid(); 137 138 LOG1("CameraService::connect E (pid %d, id %d)", callingPid, cameraId); 139 140 if (!mModule) { 141 ALOGE("Camera HAL module not loaded"); 142 return NULL; 143 } 144 145 sp<Client> client; 146 if (cameraId < 0 || cameraId >= mNumberOfCameras) { 147 ALOGE("CameraService::connect X (pid %d) rejected (invalid cameraId %d).", 148 callingPid, cameraId); 149 return NULL; 150 } 151 152 char value[PROPERTY_VALUE_MAX]; 153 property_get("sys.secpolicy.camera.disabled", value, "0"); 154 if (strcmp(value, "1") == 0) { 155 // Camera is disabled by DevicePolicyManager. 156 ALOGI("Camera is disabled. connect X (pid %d) rejected", callingPid); 157 return NULL; 158 } 159 160 Mutex::Autolock lock(mServiceLock); 161 if (mClient[cameraId] != 0) { 162 client = mClient[cameraId].promote(); 163 if (client != 0) { 164 if (cameraClient->asBinder() == client->getCameraClient()->asBinder()) { 165 LOG1("CameraService::connect X (pid %d) (the same client)", 166 callingPid); 167 return client; 168 } else { 169 ALOGW("CameraService::connect X (pid %d) rejected (existing client).", 170 callingPid); 171 return NULL; 172 } 173 } 174 mClient[cameraId].clear(); 175 } 176 177 if (mBusy[cameraId]) { 178 ALOGW("CameraService::connect X (pid %d) rejected" 179 " (camera %d is still busy).", callingPid, cameraId); 180 return NULL; 181 } 182 183 struct camera_info info; 184 if (mModule->get_camera_info(cameraId, &info) != OK) { 185 ALOGE("Invalid camera id %d", cameraId); 186 return NULL; 187 } 188 189 int deviceVersion; 190 if (mModule->common.module_api_version == CAMERA_MODULE_API_VERSION_2_0) { 191 deviceVersion = info.device_version; 192 } else { 193 deviceVersion = CAMERA_DEVICE_API_VERSION_1_0; 194 } 195 196 switch(deviceVersion) { 197 case CAMERA_DEVICE_API_VERSION_1_0: 198 client = new CameraClient(this, cameraClient, cameraId, 199 info.facing, callingPid); 200 break; 201 case CAMERA_DEVICE_API_VERSION_2_0: 202 client = new Camera2Client(this, cameraClient, cameraId, 203 info.facing, callingPid); 204 break; 205 default: 206 ALOGE("Unknown camera device HAL version: %d", deviceVersion); 207 return NULL; 208 } 209 210 if (client->initialize(mModule) != OK) { 211 return NULL; 212 } 213 214 mClient[cameraId] = client; 215 LOG1("CameraService::connect X (id %d)", cameraId); 216 return client; 217} 218 219void CameraService::removeClient(const sp<ICameraClient>& cameraClient) { 220 int callingPid = getCallingPid(); 221 LOG1("CameraService::removeClient E (pid %d)", callingPid); 222 223 for (int i = 0; i < mNumberOfCameras; i++) { 224 // Declare this before the lock to make absolutely sure the 225 // destructor won't be called with the lock held. 226 sp<Client> client; 227 228 Mutex::Autolock lock(mServiceLock); 229 230 // This happens when we have already disconnected (or this is 231 // just another unused camera). 232 if (mClient[i] == 0) continue; 233 234 // Promote mClient. It can fail if we are called from this path: 235 // Client::~Client() -> disconnect() -> removeClient(). 236 client = mClient[i].promote(); 237 238 if (client == 0) { 239 mClient[i].clear(); 240 continue; 241 } 242 243 if (cameraClient->asBinder() == client->getCameraClient()->asBinder()) { 244 // Found our camera, clear and leave. 245 LOG1("removeClient: clear camera %d", i); 246 mClient[i].clear(); 247 break; 248 } 249 } 250 251 LOG1("CameraService::removeClient X (pid %d)", callingPid); 252} 253 254CameraService::Client* CameraService::getClientByIdUnsafe(int cameraId) { 255 if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL; 256 return mClient[cameraId].unsafe_get(); 257} 258 259Mutex* CameraService::getClientLockById(int cameraId) { 260 if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL; 261 return &mClientLock[cameraId]; 262} 263 264status_t CameraService::onTransact( 265 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { 266 // Permission checks 267 switch (code) { 268 case BnCameraService::CONNECT: 269 const int pid = getCallingPid(); 270 const int self_pid = getpid(); 271 if (pid != self_pid) { 272 // we're called from a different process, do the real check 273 if (!checkCallingPermission( 274 String16("android.permission.CAMERA"))) { 275 const int uid = getCallingUid(); 276 ALOGE("Permission Denial: " 277 "can't use the camera pid=%d, uid=%d", pid, uid); 278 return PERMISSION_DENIED; 279 } 280 } 281 break; 282 } 283 284 return BnCameraService::onTransact(code, data, reply, flags); 285} 286 287// The reason we need this busy bit is a new CameraService::connect() request 288// may come in while the previous Client's destructor has not been run or is 289// still running. If the last strong reference of the previous Client is gone 290// but the destructor has not been finished, we should not allow the new Client 291// to be created because we need to wait for the previous Client to tear down 292// the hardware first. 293void CameraService::setCameraBusy(int cameraId) { 294 android_atomic_write(1, &mBusy[cameraId]); 295} 296 297void CameraService::setCameraFree(int cameraId) { 298 android_atomic_write(0, &mBusy[cameraId]); 299} 300 301// We share the media players for shutter and recording sound for all clients. 302// A reference count is kept to determine when we will actually release the 303// media players. 304 305MediaPlayer* CameraService::newMediaPlayer(const char *file) { 306 MediaPlayer* mp = new MediaPlayer(); 307 if (mp->setDataSource(file, NULL) == NO_ERROR) { 308 mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE); 309 mp->prepare(); 310 } else { 311 ALOGE("Failed to load CameraService sounds: %s", file); 312 return NULL; 313 } 314 return mp; 315} 316 317void CameraService::loadSound() { 318 Mutex::Autolock lock(mSoundLock); 319 LOG1("CameraService::loadSound ref=%d", mSoundRef); 320 if (mSoundRef++) return; 321 322 mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg"); 323 mSoundPlayer[SOUND_RECORDING] = newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg"); 324} 325 326void CameraService::releaseSound() { 327 Mutex::Autolock lock(mSoundLock); 328 LOG1("CameraService::releaseSound ref=%d", mSoundRef); 329 if (--mSoundRef) return; 330 331 for (int i = 0; i < NUM_SOUNDS; i++) { 332 if (mSoundPlayer[i] != 0) { 333 mSoundPlayer[i]->disconnect(); 334 mSoundPlayer[i].clear(); 335 } 336 } 337} 338 339void CameraService::playSound(sound_kind kind) { 340 LOG1("playSound(%d)", kind); 341 Mutex::Autolock lock(mSoundLock); 342 sp<MediaPlayer> player = mSoundPlayer[kind]; 343 if (player != 0) { 344 player->seekTo(0); 345 player->start(); 346 } 347} 348 349// ---------------------------------------------------------------------------- 350 351CameraService::Client::Client(const sp<CameraService>& cameraService, 352 const sp<ICameraClient>& cameraClient, 353 int cameraId, int cameraFacing, int clientPid) { 354 int callingPid = getCallingPid(); 355 LOG1("Client::Client E (pid %d, id %d)", callingPid, cameraId); 356 357 mCameraService = cameraService; 358 mCameraClient = cameraClient; 359 mCameraId = cameraId; 360 mCameraFacing = cameraFacing; 361 mClientPid = clientPid; 362 mDestructionStarted = false; 363 364 cameraService->setCameraBusy(cameraId); 365 cameraService->loadSound(); 366 LOG1("Client::Client X (pid %d, id %d)", callingPid, cameraId); 367} 368 369// tear down the client 370CameraService::Client::~Client() { 371 mCameraService->releaseSound(); 372} 373 374// ---------------------------------------------------------------------------- 375 376Mutex* CameraService::Client::getClientLockFromCookie(void* user) { 377 return gCameraService->getClientLockById((int) user); 378} 379 380// Provide client pointer for callbacks. Client lock returned from getClientLockFromCookie should 381// be acquired for this to be safe 382CameraService::Client* CameraService::Client::getClientFromCookie(void* user) { 383 Client* client = gCameraService->getClientByIdUnsafe((int) user); 384 385 // This could happen if the Client is in the process of shutting down (the 386 // last strong reference is gone, but the destructor hasn't finished 387 // stopping the hardware). 388 if (client == NULL) return NULL; 389 390 // destruction already started, so should not be accessed 391 if (client->mDestructionStarted) return NULL; 392 393 return client; 394} 395 396void CameraService::Client::disconnect() { 397 mCameraService->removeClient(mCameraClient); 398 mCameraService->setCameraFree(mCameraId); 399} 400 401// ---------------------------------------------------------------------------- 402 403static const int kDumpLockRetries = 50; 404static const int kDumpLockSleep = 60000; 405 406static bool tryLock(Mutex& mutex) 407{ 408 bool locked = false; 409 for (int i = 0; i < kDumpLockRetries; ++i) { 410 if (mutex.tryLock() == NO_ERROR) { 411 locked = true; 412 break; 413 } 414 usleep(kDumpLockSleep); 415 } 416 return locked; 417} 418 419status_t CameraService::dump(int fd, const Vector<String16>& args) { 420 static const char* kDeadlockedString = "CameraService may be deadlocked\n"; 421 422 const size_t SIZE = 256; 423 char buffer[SIZE]; 424 String8 result; 425 if (checkCallingPermission(String16("android.permission.DUMP")) == false) { 426 snprintf(buffer, SIZE, "Permission Denial: " 427 "can't dump CameraService from pid=%d, uid=%d\n", 428 getCallingPid(), 429 getCallingUid()); 430 result.append(buffer); 431 write(fd, result.string(), result.size()); 432 } else { 433 bool locked = tryLock(mServiceLock); 434 // failed to lock - CameraService is probably deadlocked 435 if (!locked) { 436 String8 result(kDeadlockedString); 437 write(fd, result.string(), result.size()); 438 } 439 440 bool hasClient = false; 441 for (int i = 0; i < mNumberOfCameras; i++) { 442 sp<Client> client = mClient[i].promote(); 443 if (client == 0) continue; 444 hasClient = true; 445 client->dump(fd, args); 446 } 447 if (!hasClient) { 448 result.append("No camera client yet.\n"); 449 write(fd, result.string(), result.size()); 450 } 451 452 if (locked) mServiceLock.unlock(); 453 454 // change logging level 455 int n = args.size(); 456 for (int i = 0; i + 1 < n; i++) { 457 if (args[i] == String16("-v")) { 458 String8 levelStr(args[i+1]); 459 int level = atoi(levelStr.string()); 460 sprintf(buffer, "Set Log Level to %d", level); 461 result.append(buffer); 462 setLogLevel(level); 463 } 464 } 465 } 466 return NO_ERROR; 467} 468 469}; // namespace android 470