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