CameraService.cpp revision c073ba525404f3416c2824c435d3d926a9892f1b
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/AppOpsManager.h> 26#include <binder/IPCThreadState.h> 27#include <binder/IServiceManager.h> 28#include <binder/MemoryBase.h> 29#include <binder/MemoryHeapBase.h> 30#include <cutils/atomic.h> 31#include <cutils/properties.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#include "ProCamera2Client.h" 44 45namespace android { 46 47// ---------------------------------------------------------------------------- 48// Logging support -- this is for debugging only 49// Use "adb shell dumpsys media.camera -v 1" to change it. 50volatile int32_t gLogLevel = 0; 51 52#define LOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__); 53#define LOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__); 54 55static void setLogLevel(int level) { 56 android_atomic_write(level, &gLogLevel); 57} 58 59// ---------------------------------------------------------------------------- 60 61static int getCallingPid() { 62 return IPCThreadState::self()->getCallingPid(); 63} 64 65static int getCallingUid() { 66 return IPCThreadState::self()->getCallingUid(); 67} 68 69// ---------------------------------------------------------------------------- 70 71// This is ugly and only safe if we never re-create the CameraService, but 72// should be ok for now. 73static CameraService *gCameraService; 74 75CameraService::CameraService() 76 :mSoundRef(0), mModule(0) 77{ 78 ALOGI("CameraService started (pid=%d)", getpid()); 79 gCameraService = this; 80} 81 82void CameraService::onFirstRef() 83{ 84 LOG1("CameraService::onFirstRef"); 85 86 BnCameraService::onFirstRef(); 87 88 if (hw_get_module(CAMERA_HARDWARE_MODULE_ID, 89 (const hw_module_t **)&mModule) < 0) { 90 ALOGE("Could not load camera HAL module"); 91 mNumberOfCameras = 0; 92 } 93 else { 94 ALOGI("Loaded \"%s\" camera module", mModule->common.name); 95 mNumberOfCameras = mModule->get_number_of_cameras(); 96 if (mNumberOfCameras > MAX_CAMERAS) { 97 ALOGE("Number of cameras(%d) > MAX_CAMERAS(%d).", 98 mNumberOfCameras, MAX_CAMERAS); 99 mNumberOfCameras = MAX_CAMERAS; 100 } 101 for (int i = 0; i < mNumberOfCameras; i++) { 102 setCameraFree(i); 103 } 104 } 105} 106 107CameraService::~CameraService() { 108 for (int i = 0; i < mNumberOfCameras; i++) { 109 if (mBusy[i]) { 110 ALOGE("camera %d is still in use in destructor!", i); 111 } 112 } 113 114 gCameraService = NULL; 115} 116 117int32_t CameraService::getNumberOfCameras() { 118 return mNumberOfCameras; 119} 120 121status_t CameraService::getCameraInfo(int cameraId, 122 struct CameraInfo* cameraInfo) { 123 if (!mModule) { 124 return NO_INIT; 125 } 126 127 if (cameraId < 0 || cameraId >= mNumberOfCameras) { 128 return BAD_VALUE; 129 } 130 131 struct camera_info info; 132 status_t rc = mModule->get_camera_info(cameraId, &info); 133 cameraInfo->facing = info.facing; 134 cameraInfo->orientation = info.orientation; 135 return rc; 136} 137 138int CameraService::getDeviceVersion(int cameraId, int* facing) { 139 struct camera_info info; 140 if (mModule->get_camera_info(cameraId, &info) != OK) { 141 return -1; 142 } 143 144 int deviceVersion; 145 if (mModule->common.module_api_version >= CAMERA_MODULE_API_VERSION_2_0) { 146 deviceVersion = info.device_version; 147 } else { 148 deviceVersion = CAMERA_DEVICE_API_VERSION_1_0; 149 } 150 151 if (facing) { 152 *facing = info.facing; 153 } 154 155 return deviceVersion; 156} 157 158sp<ICamera> CameraService::connect( 159 const sp<ICameraClient>& cameraClient, 160 int cameraId, 161 const String16& clientPackageName, 162 int clientUid) { 163 164 String8 clientName8(clientPackageName); 165 int callingPid = getCallingPid(); 166 167 LOG1("CameraService::connect E (pid %d \"%s\", id %d)", callingPid, 168 clientName8.string(), cameraId); 169 170 if (clientUid == USE_CALLING_UID) { 171 clientUid = getCallingUid(); 172 } else { 173 // We only trust our own process to forward client UIDs 174 if (callingPid != getpid()) { 175 ALOGE("CameraService::connect X (pid %d) rejected (don't trust clientUid)", 176 callingPid); 177 return NULL; 178 } 179 } 180 181 if (!mModule) { 182 ALOGE("Camera HAL module not loaded"); 183 return NULL; 184 } 185 186 sp<Client> client; 187 if (cameraId < 0 || cameraId >= mNumberOfCameras) { 188 ALOGE("CameraService::connect X (pid %d) rejected (invalid cameraId %d).", 189 callingPid, cameraId); 190 return NULL; 191 } 192 193 char value[PROPERTY_VALUE_MAX]; 194 property_get("sys.secpolicy.camera.disabled", value, "0"); 195 if (strcmp(value, "1") == 0) { 196 // Camera is disabled by DevicePolicyManager. 197 ALOGI("Camera is disabled. connect X (pid %d) rejected", callingPid); 198 return NULL; 199 } 200 201 Mutex::Autolock lock(mServiceLock); 202 if (mClient[cameraId] != 0) { 203 client = mClient[cameraId].promote(); 204 if (client != 0) { 205 if (cameraClient->asBinder() == client->getCameraClient()->asBinder()) { 206 LOG1("CameraService::connect X (pid %d) (the same client)", 207 callingPid); 208 return client; 209 } else { 210 // TODOSC: need to support 1 regular client, multiple shared clients here 211 ALOGW("CameraService::connect X (pid %d) rejected (existing client).", 212 callingPid); 213 return NULL; 214 } 215 } 216 mClient[cameraId].clear(); 217 } 218 219 /* 220 mBusy is set to false as the last step of the Client destructor, 221 after which it is guaranteed that the Client destructor has finished ( 222 including any inherited destructors) 223 224 We only need this for a Client subclasses since we don't allow 225 multiple Clents to be opened concurrently, but multiple BasicClient 226 would be fine 227 */ 228 if (mBusy[cameraId]) { 229 230 ALOGW("CameraService::connect X (pid %d, \"%s\") rejected" 231 " (camera %d is still busy).", callingPid, 232 clientName8.string(), cameraId); 233 return NULL; 234 } 235 236 int facing = -1; 237 int deviceVersion = getDeviceVersion(cameraId, &facing); 238 239 switch(deviceVersion) { 240 case CAMERA_DEVICE_API_VERSION_1_0: 241 client = new CameraClient(this, cameraClient, 242 clientPackageName, cameraId, 243 facing, callingPid, clientUid, getpid()); 244 break; 245 case CAMERA_DEVICE_API_VERSION_2_0: 246 case CAMERA_DEVICE_API_VERSION_2_1: 247 client = new Camera2Client(this, cameraClient, 248 clientPackageName, cameraId, 249 facing, callingPid, clientUid, getpid()); 250 break; 251 case -1: 252 ALOGE("Invalid camera id %d", cameraId); 253 return NULL; 254 default: 255 ALOGE("Unknown camera device HAL version: %d", deviceVersion); 256 return NULL; 257 } 258 259 if (client->initialize(mModule) != OK) { 260 return NULL; 261 } 262 263 cameraClient->asBinder()->linkToDeath(this); 264 265 mClient[cameraId] = client; 266 LOG1("CameraService::connect X (id %d, this pid is %d)", cameraId, getpid()); 267 return client; 268} 269 270sp<IProCameraUser> CameraService::connect( 271 const sp<IProCameraCallbacks>& cameraCb, 272 int cameraId, 273 const String16& clientPackageName, 274 int clientUid) 275{ 276 int callingPid = getCallingPid(); 277 278 // TODO: use clientPackageName and clientUid with appOpsMangr 279 280 LOG1("CameraService::connectPro E (pid %d, id %d)", callingPid, cameraId); 281 282 if (!mModule) { 283 ALOGE("Camera HAL module not loaded"); 284 return NULL; 285 } 286 287 sp<ProClient> client; 288 if (cameraId < 0 || cameraId >= mNumberOfCameras) { 289 ALOGE("CameraService::connectPro X (pid %d) rejected (invalid cameraId %d).", 290 callingPid, cameraId); 291 return NULL; 292 } 293 294 char value[PROPERTY_VALUE_MAX]; 295 property_get("sys.secpolicy.camera.disabled", value, "0"); 296 if (strcmp(value, "1") == 0) { 297 // Camera is disabled by DevicePolicyManager. 298 ALOGI("Camera is disabled. connect X (pid %d) rejected", callingPid); 299 return NULL; 300 } 301 302 int facing = -1; 303 int deviceVersion = getDeviceVersion(cameraId, &facing); 304 305 switch(deviceVersion) { 306 case CAMERA_DEVICE_API_VERSION_1_0: 307 ALOGE("Camera id %d uses HALv1, doesn't support ProCamera", cameraId); 308 return NULL; 309 break; 310 case CAMERA_DEVICE_API_VERSION_2_0: 311 case CAMERA_DEVICE_API_VERSION_2_1: 312 client = new ProCamera2Client(this, cameraCb, String16(), 313 cameraId, facing, callingPid, USE_CALLING_UID, getpid()); 314 break; 315 case -1: 316 ALOGE("Invalid camera id %d", cameraId); 317 return NULL; 318 default: 319 ALOGE("Unknown camera device HAL version: %d", deviceVersion); 320 return NULL; 321 } 322 323 if (client->initialize(mModule) != OK) { 324 return NULL; 325 } 326 327 mProClientList[cameraId].push(client); 328 329 cameraCb->asBinder()->linkToDeath(this); 330 331 LOG1("CameraService::connectPro X (id %d, this pid is %d)", cameraId, 332 getpid()); 333 return client; 334 335 336 return NULL; 337} 338 339void CameraService::removeClientByRemote(const wp<IBinder>& remoteBinder) { 340 int callingPid = getCallingPid(); 341 LOG1("CameraService::removeClientByRemote E (pid %d)", callingPid); 342 343 // Declare this before the lock to make absolutely sure the 344 // destructor won't be called with the lock held. 345 Mutex::Autolock lock(mServiceLock); 346 347 int outIndex; 348 sp<Client> client = findClientUnsafe(remoteBinder, outIndex); 349 350 if (client != 0) { 351 // Found our camera, clear and leave. 352 LOG1("removeClient: clear camera %d", outIndex); 353 mClient[outIndex].clear(); 354 355 client->unlinkToDeath(this); 356 } else { 357 358 sp<ProClient> clientPro = findProClientUnsafe(remoteBinder); 359 360 if (clientPro != NULL) { 361 // Found our camera, clear and leave. 362 LOG1("removeClient: clear pro %p", clientPro.get()); 363 364 clientPro->getRemoteCallback()->asBinder()->unlinkToDeath(this); 365 } 366 } 367 368 LOG1("CameraService::removeClientByRemote X (pid %d)", callingPid); 369} 370 371sp<CameraService::ProClient> CameraService::findProClientUnsafe( 372 const wp<IBinder>& cameraCallbacksRemote) 373{ 374 sp<ProClient> clientPro; 375 376 for (int i = 0; i < mNumberOfCameras; ++i) { 377 Vector<size_t> removeIdx; 378 379 for (size_t j = 0; j < mProClientList[i].size(); ++j) { 380 wp<ProClient> cl = mProClientList[i][j]; 381 382 sp<ProClient> clStrong = cl.promote(); 383 if (clStrong != NULL && clStrong->getRemote() == cameraCallbacksRemote) { 384 clientPro = clStrong; 385 break; 386 } else if (clStrong == NULL) { 387 // mark to clean up dead ptr 388 removeIdx.push(j); 389 } 390 } 391 392 // remove stale ptrs (in reverse so the indices dont change) 393 for (ssize_t j = (ssize_t)removeIdx.size() - 1; j >= 0; --j) { 394 mProClientList[i].removeAt(removeIdx[j]); 395 } 396 397 } 398 399 return clientPro; 400} 401 402sp<CameraService::Client> CameraService::findClientUnsafe( 403 const wp<IBinder>& cameraClient, int& outIndex) { 404 sp<Client> client; 405 406 for (int i = 0; i < mNumberOfCameras; i++) { 407 408 // This happens when we have already disconnected (or this is 409 // just another unused camera). 410 if (mClient[i] == 0) continue; 411 412 // Promote mClient. It can fail if we are called from this path: 413 // Client::~Client() -> disconnect() -> removeClientByRemote(). 414 client = mClient[i].promote(); 415 416 // Clean up stale client entry 417 if (client == NULL) { 418 mClient[i].clear(); 419 continue; 420 } 421 422 if (cameraClient == client->getCameraClient()->asBinder()) { 423 // Found our camera 424 outIndex = i; 425 return client; 426 } 427 } 428 429 outIndex = -1; 430 return NULL; 431} 432 433CameraService::Client* CameraService::getClientByIdUnsafe(int cameraId) { 434 if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL; 435 return mClient[cameraId].unsafe_get(); 436} 437 438Mutex* CameraService::getClientLockById(int cameraId) { 439 if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL; 440 return &mClientLock[cameraId]; 441} 442 443sp<CameraService::BasicClient> CameraService::getClientByRemote( 444 const wp<IBinder>& cameraClient) { 445 446 // Declare this before the lock to make absolutely sure the 447 // destructor won't be called with the lock held. 448 sp<BasicClient> client; 449 450 Mutex::Autolock lock(mServiceLock); 451 452 int outIndex; 453 client = findClientUnsafe(cameraClient, outIndex); 454 455 return client; 456} 457 458status_t CameraService::onTransact( 459 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { 460 // Permission checks 461 switch (code) { 462 case BnCameraService::CONNECT: 463 case BnCameraService::CONNECT_PRO: 464 const int pid = getCallingPid(); 465 const int self_pid = getpid(); 466 if (pid != self_pid) { 467 // we're called from a different process, do the real check 468 if (!checkCallingPermission( 469 String16("android.permission.CAMERA"))) { 470 const int uid = getCallingUid(); 471 ALOGE("Permission Denial: " 472 "can't use the camera pid=%d, uid=%d", pid, uid); 473 return PERMISSION_DENIED; 474 } 475 } 476 break; 477 } 478 479 return BnCameraService::onTransact(code, data, reply, flags); 480} 481 482// The reason we need this busy bit is a new CameraService::connect() request 483// may come in while the previous Client's destructor has not been run or is 484// still running. If the last strong reference of the previous Client is gone 485// but the destructor has not been finished, we should not allow the new Client 486// to be created because we need to wait for the previous Client to tear down 487// the hardware first. 488void CameraService::setCameraBusy(int cameraId) { 489 android_atomic_write(1, &mBusy[cameraId]); 490 491 ALOGV("setCameraBusy cameraId=%d", cameraId); 492} 493 494void CameraService::setCameraFree(int cameraId) { 495 android_atomic_write(0, &mBusy[cameraId]); 496 497 ALOGV("setCameraFree cameraId=%d", cameraId); 498} 499 500// We share the media players for shutter and recording sound for all clients. 501// A reference count is kept to determine when we will actually release the 502// media players. 503 504MediaPlayer* CameraService::newMediaPlayer(const char *file) { 505 MediaPlayer* mp = new MediaPlayer(); 506 if (mp->setDataSource(file, NULL) == NO_ERROR) { 507 mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE); 508 mp->prepare(); 509 } else { 510 ALOGE("Failed to load CameraService sounds: %s", file); 511 return NULL; 512 } 513 return mp; 514} 515 516void CameraService::loadSound() { 517 Mutex::Autolock lock(mSoundLock); 518 LOG1("CameraService::loadSound ref=%d", mSoundRef); 519 if (mSoundRef++) return; 520 521 mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg"); 522 mSoundPlayer[SOUND_RECORDING] = newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg"); 523} 524 525void CameraService::releaseSound() { 526 Mutex::Autolock lock(mSoundLock); 527 LOG1("CameraService::releaseSound ref=%d", mSoundRef); 528 if (--mSoundRef) return; 529 530 for (int i = 0; i < NUM_SOUNDS; i++) { 531 if (mSoundPlayer[i] != 0) { 532 mSoundPlayer[i]->disconnect(); 533 mSoundPlayer[i].clear(); 534 } 535 } 536} 537 538void CameraService::playSound(sound_kind kind) { 539 LOG1("playSound(%d)", kind); 540 Mutex::Autolock lock(mSoundLock); 541 sp<MediaPlayer> player = mSoundPlayer[kind]; 542 if (player != 0) { 543 player->seekTo(0); 544 player->start(); 545 } 546} 547 548// ---------------------------------------------------------------------------- 549 550CameraService::Client::Client(const sp<CameraService>& cameraService, 551 const sp<ICameraClient>& cameraClient, 552 const String16& clientPackageName, 553 int cameraId, int cameraFacing, 554 int clientPid, uid_t clientUid, 555 int servicePid) : 556 CameraService::BasicClient(cameraService, cameraClient->asBinder(), 557 clientPackageName, 558 cameraId, cameraFacing, 559 clientPid, clientUid, 560 servicePid) 561{ 562 int callingPid = getCallingPid(); 563 LOG1("Client::Client E (pid %d, id %d)", callingPid, cameraId); 564 565 mCameraClient = cameraClient; 566 567 cameraService->setCameraBusy(cameraId); 568 cameraService->loadSound(); 569 570 LOG1("Client::Client X (pid %d, id %d)", callingPid, cameraId); 571} 572 573// tear down the client 574CameraService::Client::~Client() { 575 mDestructionStarted = true; 576 577 mCameraService->releaseSound(); 578 finishCameraOps(); 579 // unconditionally disconnect. function is idempotent 580 Client::disconnect(); 581} 582 583CameraService::BasicClient::BasicClient(const sp<CameraService>& cameraService, 584 const sp<IBinder>& remoteCallback, 585 const String16& clientPackageName, 586 int cameraId, int cameraFacing, 587 int clientPid, uid_t clientUid, 588 int servicePid): 589 mClientPackageName(clientPackageName) 590{ 591 mCameraService = cameraService; 592 mRemoteCallback = remoteCallback; 593 mCameraId = cameraId; 594 mCameraFacing = cameraFacing; 595 mClientPid = clientPid; 596 mClientUid = clientUid; 597 mServicePid = servicePid; 598 mOpsActive = false; 599 mDestructionStarted = false; 600} 601 602CameraService::BasicClient::~BasicClient() { 603 mDestructionStarted = true; 604} 605 606void CameraService::BasicClient::disconnect() { 607 mCameraService->removeClientByRemote(mRemoteCallback); 608} 609 610status_t CameraService::BasicClient::startCameraOps() { 611 int32_t res; 612 613 mOpsCallback = new OpsCallback(this); 614 615 mAppOpsManager.startWatchingMode(AppOpsManager::OP_CAMERA, 616 mClientPackageName, mOpsCallback); 617 res = mAppOpsManager.startOp(AppOpsManager::OP_CAMERA, 618 mClientUid, mClientPackageName); 619 620 if (res != AppOpsManager::MODE_ALLOWED) { 621 ALOGI("Camera %d: Access for \"%s\" has been revoked", 622 mCameraId, String8(mClientPackageName).string()); 623 return PERMISSION_DENIED; 624 } 625 mOpsActive = true; 626 return OK; 627} 628 629status_t CameraService::BasicClient::finishCameraOps() { 630 if (mOpsActive) { 631 mAppOpsManager.finishOp(AppOpsManager::OP_CAMERA, mClientUid, 632 mClientPackageName); 633 mOpsActive = false; 634 } 635 mAppOpsManager.stopWatchingMode(mOpsCallback); 636 mOpsCallback.clear(); 637 638 return OK; 639} 640 641void CameraService::BasicClient::opChanged(int32_t op, const String16& packageName) { 642 String8 name(packageName); 643 String8 myName(mClientPackageName); 644 645 if (op != AppOpsManager::OP_CAMERA) { 646 ALOGW("Unexpected app ops notification received: %d", op); 647 return; 648 } 649 650 int32_t res; 651 res = mAppOpsManager.checkOp(AppOpsManager::OP_CAMERA, 652 mClientUid, mClientPackageName); 653 ALOGV("checkOp returns: %d, %s ", res, 654 res == AppOpsManager::MODE_ALLOWED ? "ALLOWED" : 655 res == AppOpsManager::MODE_IGNORED ? "IGNORED" : 656 res == AppOpsManager::MODE_ERRORED ? "ERRORED" : 657 "UNKNOWN"); 658 659 if (res != AppOpsManager::MODE_ALLOWED) { 660 ALOGI("Camera %d: Access for \"%s\" revoked", mCameraId, 661 myName.string()); 662 // Reset the client PID to allow server-initiated disconnect, 663 // and to prevent further calls by client. 664 mClientPid = getCallingPid(); 665 notifyError(); 666 disconnect(); 667 } 668} 669 670// ---------------------------------------------------------------------------- 671 672Mutex* CameraService::Client::getClientLockFromCookie(void* user) { 673 return gCameraService->getClientLockById((int) user); 674} 675 676// Provide client pointer for callbacks. Client lock returned from getClientLockFromCookie should 677// be acquired for this to be safe 678CameraService::Client* CameraService::Client::getClientFromCookie(void* user) { 679 Client* client = gCameraService->getClientByIdUnsafe((int) user); 680 681 // This could happen if the Client is in the process of shutting down (the 682 // last strong reference is gone, but the destructor hasn't finished 683 // stopping the hardware). 684 if (client == NULL) return NULL; 685 686 // destruction already started, so should not be accessed 687 if (client->mDestructionStarted) return NULL; 688 689 return client; 690} 691 692void CameraService::Client::notifyError() { 693 mCameraClient->notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_RELEASED, 0); 694} 695 696// NOTE: function is idempotent 697void CameraService::Client::disconnect() { 698 BasicClient::disconnect(); 699 mCameraService->setCameraFree(mCameraId); 700} 701 702CameraService::Client::OpsCallback::OpsCallback(wp<BasicClient> client): 703 mClient(client) { 704} 705 706void CameraService::Client::OpsCallback::opChanged(int32_t op, 707 const String16& packageName) { 708 sp<BasicClient> client = mClient.promote(); 709 if (client != NULL) { 710 client->opChanged(op, packageName); 711 } 712} 713 714// ---------------------------------------------------------------------------- 715// IProCamera 716// ---------------------------------------------------------------------------- 717 718CameraService::ProClient::ProClient(const sp<CameraService>& cameraService, 719 const sp<IProCameraCallbacks>& remoteCallback, 720 const String16& clientPackageName, 721 int cameraId, 722 int cameraFacing, 723 int clientPid, 724 uid_t clientUid, 725 int servicePid) 726 : CameraService::BasicClient(cameraService, remoteCallback->asBinder(), 727 clientPackageName, cameraId, cameraFacing, 728 clientPid, clientUid, servicePid) 729{ 730 mRemoteCallback = remoteCallback; 731} 732 733CameraService::ProClient::~ProClient() { 734 mDestructionStarted = true; 735 736 ProClient::disconnect(); 737} 738 739status_t CameraService::ProClient::connect(const sp<IProCameraCallbacks>& callbacks) { 740 ALOGE("%s: not implemented yet", __FUNCTION__); 741 742 return INVALID_OPERATION; 743} 744 745void CameraService::ProClient::disconnect() { 746 BasicClient::disconnect(); 747} 748 749status_t CameraService::ProClient::initialize(camera_module_t* module) 750{ 751 ALOGW("%s: not implemented yet", __FUNCTION__); 752 return OK; 753} 754 755status_t CameraService::ProClient::exclusiveTryLock() { 756 ALOGE("%s: not implemented yet", __FUNCTION__); 757 return INVALID_OPERATION; 758} 759 760status_t CameraService::ProClient::exclusiveLock() { 761 ALOGE("%s: not implemented yet", __FUNCTION__); 762 return INVALID_OPERATION; 763} 764 765status_t CameraService::ProClient::exclusiveUnlock() { 766 ALOGE("%s: not implemented yet", __FUNCTION__); 767 return INVALID_OPERATION; 768} 769 770bool CameraService::ProClient::hasExclusiveLock() { 771 ALOGE("%s: not implemented yet", __FUNCTION__); 772 return false; 773} 774 775status_t CameraService::ProClient::submitRequest(camera_metadata_t* request, bool streaming) { 776 ALOGE("%s: not implemented yet", __FUNCTION__); 777 778 free_camera_metadata(request); 779 780 return INVALID_OPERATION; 781} 782 783status_t CameraService::ProClient::cancelRequest(int requestId) { 784 ALOGE("%s: not implemented yet", __FUNCTION__); 785 786 return INVALID_OPERATION; 787} 788 789status_t CameraService::ProClient::requestStream(int streamId) { 790 ALOGE("%s: not implemented yet", __FUNCTION__); 791 792 return INVALID_OPERATION; 793} 794 795status_t CameraService::ProClient::cancelStream(int streamId) { 796 ALOGE("%s: not implemented yet", __FUNCTION__); 797 798 return INVALID_OPERATION; 799} 800 801void CameraService::ProClient::notifyError() { 802 ALOGE("%s: not implemented yet", __FUNCTION__); 803} 804 805// ---------------------------------------------------------------------------- 806 807static const int kDumpLockRetries = 50; 808static const int kDumpLockSleep = 60000; 809 810static bool tryLock(Mutex& mutex) 811{ 812 bool locked = false; 813 for (int i = 0; i < kDumpLockRetries; ++i) { 814 if (mutex.tryLock() == NO_ERROR) { 815 locked = true; 816 break; 817 } 818 usleep(kDumpLockSleep); 819 } 820 return locked; 821} 822 823status_t CameraService::dump(int fd, const Vector<String16>& args) { 824 String8 result; 825 if (checkCallingPermission(String16("android.permission.DUMP")) == false) { 826 result.appendFormat("Permission Denial: " 827 "can't dump CameraService from pid=%d, uid=%d\n", 828 getCallingPid(), 829 getCallingUid()); 830 write(fd, result.string(), result.size()); 831 } else { 832 bool locked = tryLock(mServiceLock); 833 // failed to lock - CameraService is probably deadlocked 834 if (!locked) { 835 result.append("CameraService may be deadlocked\n"); 836 write(fd, result.string(), result.size()); 837 } 838 839 bool hasClient = false; 840 if (!mModule) { 841 result = String8::format("No camera module available!\n"); 842 write(fd, result.string(), result.size()); 843 return NO_ERROR; 844 } 845 846 result = String8::format("Camera module HAL API version: 0x%x\n", 847 mModule->common.hal_api_version); 848 result.appendFormat("Camera module API version: 0x%x\n", 849 mModule->common.module_api_version); 850 result.appendFormat("Camera module name: %s\n", 851 mModule->common.name); 852 result.appendFormat("Camera module author: %s\n", 853 mModule->common.author); 854 result.appendFormat("Number of camera devices: %d\n\n", mNumberOfCameras); 855 write(fd, result.string(), result.size()); 856 for (int i = 0; i < mNumberOfCameras; i++) { 857 result = String8::format("Camera %d static information:\n", i); 858 camera_info info; 859 860 status_t rc = mModule->get_camera_info(i, &info); 861 if (rc != OK) { 862 result.appendFormat(" Error reading static information!\n"); 863 write(fd, result.string(), result.size()); 864 } else { 865 result.appendFormat(" Facing: %s\n", 866 info.facing == CAMERA_FACING_BACK ? "BACK" : "FRONT"); 867 result.appendFormat(" Orientation: %d\n", info.orientation); 868 int deviceVersion; 869 if (mModule->common.module_api_version < 870 CAMERA_MODULE_API_VERSION_2_0) { 871 deviceVersion = CAMERA_DEVICE_API_VERSION_1_0; 872 } else { 873 deviceVersion = info.device_version; 874 } 875 result.appendFormat(" Device version: 0x%x\n", deviceVersion); 876 if (deviceVersion >= CAMERA_DEVICE_API_VERSION_2_0) { 877 result.appendFormat(" Device static metadata:\n"); 878 write(fd, result.string(), result.size()); 879 dump_indented_camera_metadata(info.static_camera_characteristics, 880 fd, 2, 4); 881 } else { 882 write(fd, result.string(), result.size()); 883 } 884 } 885 886 sp<Client> client = mClient[i].promote(); 887 if (client == 0) { 888 result = String8::format(" Device is closed, no client instance\n"); 889 write(fd, result.string(), result.size()); 890 continue; 891 } 892 hasClient = true; 893 result = String8::format(" Device is open. Client instance dump:\n"); 894 write(fd, result.string(), result.size()); 895 client->dump(fd, args); 896 } 897 if (!hasClient) { 898 result = String8::format("\nNo active camera clients yet.\n"); 899 write(fd, result.string(), result.size()); 900 } 901 902 if (locked) mServiceLock.unlock(); 903 904 // change logging level 905 int n = args.size(); 906 for (int i = 0; i + 1 < n; i++) { 907 String16 verboseOption("-v"); 908 if (args[i] == verboseOption) { 909 String8 levelStr(args[i+1]); 910 int level = atoi(levelStr.string()); 911 result = String8::format("\nSetting log level to %d.\n", level); 912 setLogLevel(level); 913 write(fd, result.string(), result.size()); 914 } 915 } 916 917 } 918 return NO_ERROR; 919} 920 921/*virtual*/void CameraService::binderDied( 922 const wp<IBinder> &who) { 923 924 /** 925 * While tempting to promote the wp<IBinder> into a sp, 926 * it's actually not supported by the binder driver 927 */ 928 929 ALOGV("java clients' binder died"); 930 931 sp<BasicClient> cameraClient = getClientByRemote(who); 932 933 if (cameraClient == 0) { 934 ALOGV("java clients' binder death already cleaned up (normal case)"); 935 return; 936 } 937 938 ALOGW("Disconnecting camera client %p since the binder for it " 939 "died (this pid %d)", cameraClient.get(), getCallingPid()); 940 941 cameraClient->disconnect(); 942 943} 944 945}; // namespace android 946