CameraService.cpp revision 5e08d60617fc63c2e41f9069ff89f5c00db2617d
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 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 sp<CameraHardwareInterface> hardware = NULL; 138 139 LOG1("CameraService::connect E (pid %d, id %d)", callingPid, cameraId); 140 141 if (!mModule) { 142 ALOGE("Camera HAL module not loaded"); 143 return NULL; 144 } 145 146 sp<Client> client; 147 if (cameraId < 0 || cameraId >= mNumberOfCameras) { 148 ALOGE("CameraService::connect X (pid %d) rejected (invalid cameraId %d).", 149 callingPid, cameraId); 150 return NULL; 151 } 152 153 char value[PROPERTY_VALUE_MAX]; 154 property_get("sys.secpolicy.camera.disabled", value, "0"); 155 if (strcmp(value, "1") == 0) { 156 // Camera is disabled by DevicePolicyManager. 157 ALOGI("Camera is disabled. connect X (pid %d) rejected", callingPid); 158 return NULL; 159 } 160 161 Mutex::Autolock lock(mServiceLock); 162 if (mClient[cameraId] != 0) { 163 client = mClient[cameraId].promote(); 164 if (client != 0) { 165 if (cameraClient->asBinder() == client->getCameraClient()->asBinder()) { 166 LOG1("CameraService::connect X (pid %d) (the same client)", 167 callingPid); 168 return client; 169 } else { 170 ALOGW("CameraService::connect X (pid %d) rejected (existing client).", 171 callingPid); 172 return NULL; 173 } 174 } 175 mClient[cameraId].clear(); 176 } 177 178 if (mBusy[cameraId]) { 179 ALOGW("CameraService::connect X (pid %d) rejected" 180 " (camera %d is still busy).", callingPid, cameraId); 181 return NULL; 182 } 183 184 struct camera_info info; 185 if (mModule->get_camera_info(cameraId, &info) != OK) { 186 ALOGE("Invalid camera id %d", cameraId); 187 return NULL; 188 } 189 190 char camera_device_name[10]; 191 snprintf(camera_device_name, sizeof(camera_device_name), "%d", cameraId); 192 193 hardware = new CameraHardwareInterface(camera_device_name); 194 if (hardware->initialize(&mModule->common) != OK) { 195 hardware.clear(); 196 return NULL; 197 } 198 199 client = new CameraClient(this, cameraClient, hardware, cameraId, info.facing, callingPid); 200 mClient[cameraId] = client; 201 LOG1("CameraService::connect X (id %d)", cameraId); 202 return client; 203} 204 205void CameraService::removeClient(const sp<ICameraClient>& cameraClient) { 206 int callingPid = getCallingPid(); 207 LOG1("CameraService::removeClient E (pid %d)", callingPid); 208 209 for (int i = 0; i < mNumberOfCameras; i++) { 210 // Declare this before the lock to make absolutely sure the 211 // destructor won't be called with the lock held. 212 sp<Client> client; 213 214 Mutex::Autolock lock(mServiceLock); 215 216 // This happens when we have already disconnected (or this is 217 // just another unused camera). 218 if (mClient[i] == 0) continue; 219 220 // Promote mClient. It can fail if we are called from this path: 221 // Client::~Client() -> disconnect() -> removeClient(). 222 client = mClient[i].promote(); 223 224 if (client == 0) { 225 mClient[i].clear(); 226 continue; 227 } 228 229 if (cameraClient->asBinder() == client->getCameraClient()->asBinder()) { 230 // Found our camera, clear and leave. 231 LOG1("removeClient: clear camera %d", i); 232 mClient[i].clear(); 233 break; 234 } 235 } 236 237 LOG1("CameraService::removeClient X (pid %d)", callingPid); 238} 239 240CameraService::Client* CameraService::getClientByIdUnsafe(int cameraId) { 241 if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL; 242 return mClient[cameraId].unsafe_get(); 243} 244 245Mutex* CameraService::getClientLockById(int cameraId) { 246 if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL; 247 return &mClientLock[cameraId]; 248} 249 250status_t CameraService::onTransact( 251 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { 252 // Permission checks 253 switch (code) { 254 case BnCameraService::CONNECT: 255 const int pid = getCallingPid(); 256 const int self_pid = getpid(); 257 if (pid != self_pid) { 258 // we're called from a different process, do the real check 259 if (!checkCallingPermission( 260 String16("android.permission.CAMERA"))) { 261 const int uid = getCallingUid(); 262 ALOGE("Permission Denial: " 263 "can't use the camera pid=%d, uid=%d", pid, uid); 264 return PERMISSION_DENIED; 265 } 266 } 267 break; 268 } 269 270 return BnCameraService::onTransact(code, data, reply, flags); 271} 272 273// The reason we need this busy bit is a new CameraService::connect() request 274// may come in while the previous Client's destructor has not been run or is 275// still running. If the last strong reference of the previous Client is gone 276// but the destructor has not been finished, we should not allow the new Client 277// to be created because we need to wait for the previous Client to tear down 278// the hardware first. 279void CameraService::setCameraBusy(int cameraId) { 280 android_atomic_write(1, &mBusy[cameraId]); 281} 282 283void CameraService::setCameraFree(int cameraId) { 284 android_atomic_write(0, &mBusy[cameraId]); 285} 286 287// We share the media players for shutter and recording sound for all clients. 288// A reference count is kept to determine when we will actually release the 289// media players. 290 291MediaPlayer* CameraService::newMediaPlayer(const char *file) { 292 MediaPlayer* mp = new MediaPlayer(); 293 if (mp->setDataSource(file, NULL) == NO_ERROR) { 294 mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE); 295 mp->prepare(); 296 } else { 297 ALOGE("Failed to load CameraService sounds: %s", file); 298 return NULL; 299 } 300 return mp; 301} 302 303void CameraService::loadSound() { 304 Mutex::Autolock lock(mSoundLock); 305 LOG1("CameraService::loadSound ref=%d", mSoundRef); 306 if (mSoundRef++) return; 307 308 mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg"); 309 mSoundPlayer[SOUND_RECORDING] = newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg"); 310} 311 312void CameraService::releaseSound() { 313 Mutex::Autolock lock(mSoundLock); 314 LOG1("CameraService::releaseSound ref=%d", mSoundRef); 315 if (--mSoundRef) return; 316 317 for (int i = 0; i < NUM_SOUNDS; i++) { 318 if (mSoundPlayer[i] != 0) { 319 mSoundPlayer[i]->disconnect(); 320 mSoundPlayer[i].clear(); 321 } 322 } 323} 324 325void CameraService::playSound(sound_kind kind) { 326 LOG1("playSound(%d)", kind); 327 Mutex::Autolock lock(mSoundLock); 328 sp<MediaPlayer> player = mSoundPlayer[kind]; 329 if (player != 0) { 330 player->seekTo(0); 331 player->start(); 332 } 333} 334 335// ---------------------------------------------------------------------------- 336 337CameraService::Client::Client(const sp<CameraService>& cameraService, 338 const sp<ICameraClient>& cameraClient, 339 int cameraId, int cameraFacing, int clientPid) { 340 int callingPid = getCallingPid(); 341 LOG1("Client::Client E (pid %d, id %d)", callingPid, cameraId); 342 343 mCameraService = cameraService; 344 mCameraClient = cameraClient; 345 mCameraId = cameraId; 346 mCameraFacing = cameraFacing; 347 mClientPid = clientPid; 348 mDestructionStarted = false; 349 350 cameraService->setCameraBusy(cameraId); 351 cameraService->loadSound(); 352 LOG1("Client::Client X (pid %d, id %d)", callingPid, cameraId); 353} 354 355// tear down the client 356CameraService::Client::~Client() { 357} 358 359// ---------------------------------------------------------------------------- 360 361Mutex* CameraService::Client::getClientLockFromCookie(void* user) { 362 return gCameraService->getClientLockById((int) user); 363} 364 365// Provide client pointer for callbacks. Client lock returned from getClientLockFromCookie should 366// be acquired for this to be safe 367CameraService::Client* CameraService::Client::getClientFromCookie(void* user) { 368 Client* client = gCameraService->getClientByIdUnsafe((int) user); 369 370 // This could happen if the Client is in the process of shutting down (the 371 // last strong reference is gone, but the destructor hasn't finished 372 // stopping the hardware). 373 if (client == NULL) return NULL; 374 375 // destruction already started, so should not be accessed 376 if (client->mDestructionStarted) return NULL; 377 378 return client; 379} 380 381void CameraService::Client::disconnect() { 382 mCameraService->removeClient(mCameraClient); 383 mCameraService->setCameraFree(mCameraId); 384} 385 386// ---------------------------------------------------------------------------- 387 388static const int kDumpLockRetries = 50; 389static const int kDumpLockSleep = 60000; 390 391static bool tryLock(Mutex& mutex) 392{ 393 bool locked = false; 394 for (int i = 0; i < kDumpLockRetries; ++i) { 395 if (mutex.tryLock() == NO_ERROR) { 396 locked = true; 397 break; 398 } 399 usleep(kDumpLockSleep); 400 } 401 return locked; 402} 403 404status_t CameraService::dump(int fd, const Vector<String16>& args) { 405 static const char* kDeadlockedString = "CameraService may be deadlocked\n"; 406 407 const size_t SIZE = 256; 408 char buffer[SIZE]; 409 String8 result; 410 if (checkCallingPermission(String16("android.permission.DUMP")) == false) { 411 snprintf(buffer, SIZE, "Permission Denial: " 412 "can't dump CameraService from pid=%d, uid=%d\n", 413 getCallingPid(), 414 getCallingUid()); 415 result.append(buffer); 416 write(fd, result.string(), result.size()); 417 } else { 418 bool locked = tryLock(mServiceLock); 419 // failed to lock - CameraService is probably deadlocked 420 if (!locked) { 421 String8 result(kDeadlockedString); 422 write(fd, result.string(), result.size()); 423 } 424 425 bool hasClient = false; 426 for (int i = 0; i < mNumberOfCameras; i++) { 427 sp<Client> client = mClient[i].promote(); 428 if (client == 0) continue; 429 hasClient = true; 430 client->dump(fd, args); 431 } 432 if (!hasClient) { 433 result.append("No camera client yet.\n"); 434 write(fd, result.string(), result.size()); 435 } 436 437 if (locked) mServiceLock.unlock(); 438 439 // change logging level 440 int n = args.size(); 441 for (int i = 0; i + 1 < n; i++) { 442 if (args[i] == String16("-v")) { 443 String8 levelStr(args[i+1]); 444 int level = atoi(levelStr.string()); 445 sprintf(buffer, "Set Log Level to %d", level); 446 result.append(buffer); 447 setLogLevel(level); 448 } 449 } 450 } 451 return NO_ERROR; 452} 453 454}; // namespace android 455