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