Home | History | Annotate | Download | only in libcameraservice
      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 <hardware/hardware.h>
     33 #include <media/AudioSystem.h>
     34 #include <media/mediaplayer.h>
     35 #include <surfaceflinger/ISurface.h>
     36 #include <utils/Errors.h>
     37 #include <utils/Log.h>
     38 #include <utils/String16.h>
     39 
     40 #include "CameraService.h"
     41 #include "CameraHardwareInterface.h"
     42 
     43 namespace android {
     44 
     45 // ----------------------------------------------------------------------------
     46 // Logging support -- this is for debugging only
     47 // Use "adb shell dumpsys media.camera -v 1" to change it.
     48 static volatile int32_t gLogLevel = 0;
     49 
     50 #define LOG1(...) LOGD_IF(gLogLevel >= 1, __VA_ARGS__);
     51 #define LOG2(...) LOGD_IF(gLogLevel >= 2, __VA_ARGS__);
     52 
     53 static void setLogLevel(int level) {
     54     android_atomic_write(level, &gLogLevel);
     55 }
     56 
     57 // ----------------------------------------------------------------------------
     58 
     59 static int getCallingPid() {
     60     return IPCThreadState::self()->getCallingPid();
     61 }
     62 
     63 static 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.
     71 static CameraService *gCameraService;
     72 
     73 CameraService::CameraService()
     74 :mSoundRef(0), mModule(0)
     75 {
     76     LOGI("CameraService started (pid=%d)", getpid());
     77     gCameraService = this;
     78 }
     79 
     80 void CameraService::onFirstRef()
     81 {
     82     BnCameraService::onFirstRef();
     83 
     84     if (hw_get_module(CAMERA_HARDWARE_MODULE_ID,
     85                 (const hw_module_t **)&mModule) < 0) {
     86         LOGE("Could not load camera HAL module");
     87         mNumberOfCameras = 0;
     88     }
     89     else {
     90         mNumberOfCameras = mModule->get_number_of_cameras();
     91         if (mNumberOfCameras > MAX_CAMERAS) {
     92             LOGE("Number of cameras(%d) > MAX_CAMERAS(%d).",
     93                     mNumberOfCameras, MAX_CAMERAS);
     94             mNumberOfCameras = MAX_CAMERAS;
     95         }
     96         for (int i = 0; i < mNumberOfCameras; i++) {
     97             setCameraFree(i);
     98         }
     99     }
    100 }
    101 
    102 CameraService::~CameraService() {
    103     for (int i = 0; i < mNumberOfCameras; i++) {
    104         if (mBusy[i]) {
    105             LOGE("camera %d is still in use in destructor!", i);
    106         }
    107     }
    108 
    109     gCameraService = NULL;
    110 }
    111 
    112 int32_t CameraService::getNumberOfCameras() {
    113     return mNumberOfCameras;
    114 }
    115 
    116 status_t CameraService::getCameraInfo(int cameraId,
    117                                       struct CameraInfo* cameraInfo) {
    118     if (!mModule) {
    119         return NO_INIT;
    120     }
    121 
    122     if (cameraId < 0 || cameraId >= mNumberOfCameras) {
    123         return BAD_VALUE;
    124     }
    125 
    126     struct camera_info info;
    127     status_t rc = mModule->get_camera_info(cameraId, &info);
    128     cameraInfo->facing = info.facing;
    129     cameraInfo->orientation = info.orientation;
    130     return rc;
    131 }
    132 
    133 sp<ICamera> CameraService::connect(
    134         const sp<ICameraClient>& cameraClient, int cameraId) {
    135     int callingPid = getCallingPid();
    136     sp<CameraHardwareInterface> hardware = NULL;
    137 
    138     LOG1("CameraService::connect E (pid %d, id %d)", callingPid, cameraId);
    139 
    140     if (!mModule) {
    141         LOGE("Camera HAL module not loaded");
    142         return NULL;
    143     }
    144 
    145     sp<Client> client;
    146     if (cameraId < 0 || cameraId >= mNumberOfCameras) {
    147         LOGE("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         LOGI("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                 LOGW("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         LOGW("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         LOGE("Invalid camera id %d", cameraId);
    186         return NULL;
    187     }
    188 
    189     char camera_device_name[10];
    190     snprintf(camera_device_name, sizeof(camera_device_name), "%d", cameraId);
    191 
    192     hardware = new CameraHardwareInterface(camera_device_name);
    193     if (hardware->initialize(&mModule->common) != OK) {
    194         hardware.clear();
    195         return NULL;
    196     }
    197 
    198     client = new Client(this, cameraClient, hardware, cameraId, info.facing, callingPid);
    199     mClient[cameraId] = client;
    200     LOG1("CameraService::connect X");
    201     return client;
    202 }
    203 
    204 void CameraService::removeClient(const sp<ICameraClient>& cameraClient) {
    205     int callingPid = getCallingPid();
    206     LOG1("CameraService::removeClient E (pid %d)", callingPid);
    207 
    208     for (int i = 0; i < mNumberOfCameras; i++) {
    209         // Declare this before the lock to make absolutely sure the
    210         // destructor won't be called with the lock held.
    211         sp<Client> client;
    212 
    213         Mutex::Autolock lock(mServiceLock);
    214 
    215         // This happens when we have already disconnected (or this is
    216         // just another unused camera).
    217         if (mClient[i] == 0) continue;
    218 
    219         // Promote mClient. It can fail if we are called from this path:
    220         // Client::~Client() -> disconnect() -> removeClient().
    221         client = mClient[i].promote();
    222 
    223         if (client == 0) {
    224             mClient[i].clear();
    225             continue;
    226         }
    227 
    228         if (cameraClient->asBinder() == client->getCameraClient()->asBinder()) {
    229             // Found our camera, clear and leave.
    230             LOG1("removeClient: clear camera %d", i);
    231             mClient[i].clear();
    232             break;
    233         }
    234     }
    235 
    236     LOG1("CameraService::removeClient X (pid %d)", callingPid);
    237 }
    238 
    239 sp<CameraService::Client> CameraService::getClientById(int cameraId) {
    240     if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
    241     return mClient[cameraId].promote();
    242 }
    243 
    244 status_t CameraService::onTransact(
    245     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
    246     // Permission checks
    247     switch (code) {
    248         case BnCameraService::CONNECT:
    249             const int pid = getCallingPid();
    250             const int self_pid = getpid();
    251             if (pid != self_pid) {
    252                 // we're called from a different process, do the real check
    253                 if (!checkCallingPermission(
    254                         String16("android.permission.CAMERA"))) {
    255                     const int uid = getCallingUid();
    256                     LOGE("Permission Denial: "
    257                          "can't use the camera pid=%d, uid=%d", pid, uid);
    258                     return PERMISSION_DENIED;
    259                 }
    260             }
    261             break;
    262     }
    263 
    264     return BnCameraService::onTransact(code, data, reply, flags);
    265 }
    266 
    267 // The reason we need this busy bit is a new CameraService::connect() request
    268 // may come in while the previous Client's destructor has not been run or is
    269 // still running. If the last strong reference of the previous Client is gone
    270 // but the destructor has not been finished, we should not allow the new Client
    271 // to be created because we need to wait for the previous Client to tear down
    272 // the hardware first.
    273 void CameraService::setCameraBusy(int cameraId) {
    274     android_atomic_write(1, &mBusy[cameraId]);
    275 }
    276 
    277 void CameraService::setCameraFree(int cameraId) {
    278     android_atomic_write(0, &mBusy[cameraId]);
    279 }
    280 
    281 // We share the media players for shutter and recording sound for all clients.
    282 // A reference count is kept to determine when we will actually release the
    283 // media players.
    284 
    285 MediaPlayer* CameraService::newMediaPlayer(const char *file) {
    286     MediaPlayer* mp = new MediaPlayer();
    287     if (mp->setDataSource(file, NULL) == NO_ERROR) {
    288         mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE);
    289         mp->prepare();
    290     } else {
    291         LOGE("Failed to load CameraService sounds: %s", file);
    292         return NULL;
    293     }
    294     return mp;
    295 }
    296 
    297 void CameraService::loadSound() {
    298     Mutex::Autolock lock(mSoundLock);
    299     LOG1("CameraService::loadSound ref=%d", mSoundRef);
    300     if (mSoundRef++) return;
    301 
    302     mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
    303     mSoundPlayer[SOUND_RECORDING] = newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");
    304 }
    305 
    306 void CameraService::releaseSound() {
    307     Mutex::Autolock lock(mSoundLock);
    308     LOG1("CameraService::releaseSound ref=%d", mSoundRef);
    309     if (--mSoundRef) return;
    310 
    311     for (int i = 0; i < NUM_SOUNDS; i++) {
    312         if (mSoundPlayer[i] != 0) {
    313             mSoundPlayer[i]->disconnect();
    314             mSoundPlayer[i].clear();
    315         }
    316     }
    317 }
    318 
    319 void CameraService::playSound(sound_kind kind) {
    320     LOG1("playSound(%d)", kind);
    321     Mutex::Autolock lock(mSoundLock);
    322     sp<MediaPlayer> player = mSoundPlayer[kind];
    323     if (player != 0) {
    324         player->seekTo(0);
    325         player->start();
    326     }
    327 }
    328 
    329 // ----------------------------------------------------------------------------
    330 
    331 CameraService::Client::Client(const sp<CameraService>& cameraService,
    332         const sp<ICameraClient>& cameraClient,
    333         const sp<CameraHardwareInterface>& hardware,
    334         int cameraId, int cameraFacing, int clientPid) {
    335     int callingPid = getCallingPid();
    336     LOG1("Client::Client E (pid %d)", callingPid);
    337 
    338     mCameraService = cameraService;
    339     mCameraClient = cameraClient;
    340     mHardware = hardware;
    341     mCameraId = cameraId;
    342     mCameraFacing = cameraFacing;
    343     mClientPid = clientPid;
    344     mMsgEnabled = 0;
    345     mSurface = 0;
    346     mPreviewWindow = 0;
    347     mHardware->setCallbacks(notifyCallback,
    348                             dataCallback,
    349                             dataCallbackTimestamp,
    350                             (void *)cameraId);
    351 
    352     // Enable zoom, error, focus, and metadata messages by default
    353     enableMsgType(CAMERA_MSG_ERROR | CAMERA_MSG_ZOOM | CAMERA_MSG_FOCUS |
    354                   CAMERA_MSG_PREVIEW_METADATA);
    355 
    356     // Callback is disabled by default
    357     mPreviewCallbackFlag = CAMERA_FRAME_CALLBACK_FLAG_NOOP;
    358     mOrientation = getOrientation(0, mCameraFacing == CAMERA_FACING_FRONT);
    359     mPlayShutterSound = true;
    360     cameraService->setCameraBusy(cameraId);
    361     cameraService->loadSound();
    362     LOG1("Client::Client X (pid %d)", callingPid);
    363 }
    364 
    365 // tear down the client
    366 CameraService::Client::~Client() {
    367     int callingPid = getCallingPid();
    368     LOG1("Client::~Client E (pid %d, this %p)", callingPid, this);
    369 
    370     // set mClientPid to let disconnet() tear down the hardware
    371     mClientPid = callingPid;
    372     disconnect();
    373     mCameraService->releaseSound();
    374     LOG1("Client::~Client X (pid %d, this %p)", callingPid, this);
    375 }
    376 
    377 // ----------------------------------------------------------------------------
    378 
    379 status_t CameraService::Client::checkPid() const {
    380     int callingPid = getCallingPid();
    381     if (callingPid == mClientPid) return NO_ERROR;
    382 
    383     LOGW("attempt to use a locked camera from a different process"
    384          " (old pid %d, new pid %d)", mClientPid, callingPid);
    385     return EBUSY;
    386 }
    387 
    388 status_t CameraService::Client::checkPidAndHardware() const {
    389     status_t result = checkPid();
    390     if (result != NO_ERROR) return result;
    391     if (mHardware == 0) {
    392         LOGE("attempt to use a camera after disconnect() (pid %d)", getCallingPid());
    393         return INVALID_OPERATION;
    394     }
    395     return NO_ERROR;
    396 }
    397 
    398 status_t CameraService::Client::lock() {
    399     int callingPid = getCallingPid();
    400     LOG1("lock (pid %d)", callingPid);
    401     Mutex::Autolock lock(mLock);
    402 
    403     // lock camera to this client if the the camera is unlocked
    404     if (mClientPid == 0) {
    405         mClientPid = callingPid;
    406         return NO_ERROR;
    407     }
    408 
    409     // returns NO_ERROR if the client already owns the camera, EBUSY otherwise
    410     return checkPid();
    411 }
    412 
    413 status_t CameraService::Client::unlock() {
    414     int callingPid = getCallingPid();
    415     LOG1("unlock (pid %d)", callingPid);
    416     Mutex::Autolock lock(mLock);
    417 
    418     // allow anyone to use camera (after they lock the camera)
    419     status_t result = checkPid();
    420     if (result == NO_ERROR) {
    421         if (mHardware->recordingEnabled()) {
    422             LOGE("Not allowed to unlock camera during recording.");
    423             return INVALID_OPERATION;
    424         }
    425         mClientPid = 0;
    426         LOG1("clear mCameraClient (pid %d)", callingPid);
    427         // we need to remove the reference to ICameraClient so that when the app
    428         // goes away, the reference count goes to 0.
    429         mCameraClient.clear();
    430     }
    431     return result;
    432 }
    433 
    434 // connect a new client to the camera
    435 status_t CameraService::Client::connect(const sp<ICameraClient>& client) {
    436     int callingPid = getCallingPid();
    437     LOG1("connect E (pid %d)", callingPid);
    438     Mutex::Autolock lock(mLock);
    439 
    440     if (mClientPid != 0 && checkPid() != NO_ERROR) {
    441         LOGW("Tried to connect to a locked camera (old pid %d, new pid %d)",
    442                 mClientPid, callingPid);
    443         return EBUSY;
    444     }
    445 
    446     if (mCameraClient != 0 && (client->asBinder() == mCameraClient->asBinder())) {
    447         LOG1("Connect to the same client");
    448         return NO_ERROR;
    449     }
    450 
    451     mPreviewCallbackFlag = CAMERA_FRAME_CALLBACK_FLAG_NOOP;
    452     mClientPid = callingPid;
    453     mCameraClient = client;
    454 
    455     LOG1("connect X (pid %d)", callingPid);
    456     return NO_ERROR;
    457 }
    458 
    459 static void disconnectWindow(const sp<ANativeWindow>& window) {
    460     if (window != 0) {
    461         status_t result = native_window_api_disconnect(window.get(),
    462                 NATIVE_WINDOW_API_CAMERA);
    463         if (result != NO_ERROR) {
    464             LOGW("native_window_api_disconnect failed: %s (%d)", strerror(-result),
    465                     result);
    466         }
    467     }
    468 }
    469 
    470 void CameraService::Client::disconnect() {
    471     int callingPid = getCallingPid();
    472     LOG1("disconnect E (pid %d)", callingPid);
    473     Mutex::Autolock lock(mLock);
    474 
    475     if (checkPid() != NO_ERROR) {
    476         LOGW("different client - don't disconnect");
    477         return;
    478     }
    479 
    480     if (mClientPid <= 0) {
    481         LOG1("camera is unlocked (mClientPid = %d), don't tear down hardware", mClientPid);
    482         return;
    483     }
    484 
    485     // Make sure disconnect() is done once and once only, whether it is called
    486     // from the user directly, or called by the destructor.
    487     if (mHardware == 0) return;
    488 
    489     LOG1("hardware teardown");
    490     // Before destroying mHardware, we must make sure it's in the
    491     // idle state.
    492     // Turn off all messages.
    493     disableMsgType(CAMERA_MSG_ALL_MSGS);
    494     mHardware->stopPreview();
    495     mHardware->cancelPicture();
    496     // Release the hardware resources.
    497     mHardware->release();
    498 
    499     // Release the held ANativeWindow resources.
    500     if (mPreviewWindow != 0) {
    501         disconnectWindow(mPreviewWindow);
    502         mPreviewWindow = 0;
    503         mHardware->setPreviewWindow(mPreviewWindow);
    504     }
    505     mHardware.clear();
    506 
    507     mCameraService->removeClient(mCameraClient);
    508     mCameraService->setCameraFree(mCameraId);
    509 
    510     LOG1("disconnect X (pid %d)", callingPid);
    511 }
    512 
    513 // ----------------------------------------------------------------------------
    514 
    515 status_t CameraService::Client::setPreviewWindow(const sp<IBinder>& binder,
    516         const sp<ANativeWindow>& window) {
    517     Mutex::Autolock lock(mLock);
    518     status_t result = checkPidAndHardware();
    519     if (result != NO_ERROR) return result;
    520 
    521     // return if no change in surface.
    522     if (binder == mSurface) {
    523         return NO_ERROR;
    524     }
    525 
    526     if (window != 0) {
    527         result = native_window_api_connect(window.get(), NATIVE_WINDOW_API_CAMERA);
    528         if (result != NO_ERROR) {
    529             LOGE("native_window_api_connect failed: %s (%d)", strerror(-result),
    530                     result);
    531             return result;
    532         }
    533     }
    534 
    535     // If preview has been already started, register preview buffers now.
    536     if (mHardware->previewEnabled()) {
    537         if (window != 0) {
    538             native_window_set_scaling_mode(window.get(),
    539                     NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
    540             native_window_set_buffers_transform(window.get(), mOrientation);
    541             result = mHardware->setPreviewWindow(window);
    542         }
    543     }
    544 
    545     if (result == NO_ERROR) {
    546         // Everything has succeeded.  Disconnect the old window and remember the
    547         // new window.
    548         disconnectWindow(mPreviewWindow);
    549         mSurface = binder;
    550         mPreviewWindow = window;
    551     } else {
    552         // Something went wrong after we connected to the new window, so
    553         // disconnect here.
    554         disconnectWindow(window);
    555     }
    556 
    557     return result;
    558 }
    559 
    560 // set the Surface that the preview will use
    561 status_t CameraService::Client::setPreviewDisplay(const sp<Surface>& surface) {
    562     LOG1("setPreviewDisplay(%p) (pid %d)", surface.get(), getCallingPid());
    563 
    564     sp<IBinder> binder(surface != 0 ? surface->asBinder() : 0);
    565     sp<ANativeWindow> window(surface);
    566     return setPreviewWindow(binder, window);
    567 }
    568 
    569 // set the SurfaceTexture that the preview will use
    570 status_t CameraService::Client::setPreviewTexture(
    571         const sp<ISurfaceTexture>& surfaceTexture) {
    572     LOG1("setPreviewTexture(%p) (pid %d)", surfaceTexture.get(),
    573             getCallingPid());
    574 
    575     sp<IBinder> binder;
    576     sp<ANativeWindow> window;
    577     if (surfaceTexture != 0) {
    578         binder = surfaceTexture->asBinder();
    579         window = new SurfaceTextureClient(surfaceTexture);
    580     }
    581     return setPreviewWindow(binder, window);
    582 }
    583 
    584 // set the preview callback flag to affect how the received frames from
    585 // preview are handled.
    586 void CameraService::Client::setPreviewCallbackFlag(int callback_flag) {
    587     LOG1("setPreviewCallbackFlag(%d) (pid %d)", callback_flag, getCallingPid());
    588     Mutex::Autolock lock(mLock);
    589     if (checkPidAndHardware() != NO_ERROR) return;
    590 
    591     mPreviewCallbackFlag = callback_flag;
    592     if (mPreviewCallbackFlag & CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) {
    593         enableMsgType(CAMERA_MSG_PREVIEW_FRAME);
    594     } else {
    595         disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
    596     }
    597 }
    598 
    599 // start preview mode
    600 status_t CameraService::Client::startPreview() {
    601     LOG1("startPreview (pid %d)", getCallingPid());
    602     return startCameraMode(CAMERA_PREVIEW_MODE);
    603 }
    604 
    605 // start recording mode
    606 status_t CameraService::Client::startRecording() {
    607     LOG1("startRecording (pid %d)", getCallingPid());
    608     return startCameraMode(CAMERA_RECORDING_MODE);
    609 }
    610 
    611 // start preview or recording
    612 status_t CameraService::Client::startCameraMode(camera_mode mode) {
    613     LOG1("startCameraMode(%d)", mode);
    614     Mutex::Autolock lock(mLock);
    615     status_t result = checkPidAndHardware();
    616     if (result != NO_ERROR) return result;
    617 
    618     switch(mode) {
    619         case CAMERA_PREVIEW_MODE:
    620             if (mSurface == 0 && mPreviewWindow == 0) {
    621                 LOG1("mSurface is not set yet.");
    622                 // still able to start preview in this case.
    623             }
    624             return startPreviewMode();
    625         case CAMERA_RECORDING_MODE:
    626             if (mSurface == 0 && mPreviewWindow == 0) {
    627                 LOGE("mSurface or mPreviewWindow must be set before startRecordingMode.");
    628                 return INVALID_OPERATION;
    629             }
    630             return startRecordingMode();
    631         default:
    632             return UNKNOWN_ERROR;
    633     }
    634 }
    635 
    636 status_t CameraService::Client::startPreviewMode() {
    637     LOG1("startPreviewMode");
    638     status_t result = NO_ERROR;
    639 
    640     // if preview has been enabled, nothing needs to be done
    641     if (mHardware->previewEnabled()) {
    642         return NO_ERROR;
    643     }
    644 
    645     if (mPreviewWindow != 0) {
    646         native_window_set_scaling_mode(mPreviewWindow.get(),
    647                 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
    648         native_window_set_buffers_transform(mPreviewWindow.get(),
    649                 mOrientation);
    650     }
    651     mHardware->setPreviewWindow(mPreviewWindow);
    652     result = mHardware->startPreview();
    653 
    654     return result;
    655 }
    656 
    657 status_t CameraService::Client::startRecordingMode() {
    658     LOG1("startRecordingMode");
    659     status_t result = NO_ERROR;
    660 
    661     // if recording has been enabled, nothing needs to be done
    662     if (mHardware->recordingEnabled()) {
    663         return NO_ERROR;
    664     }
    665 
    666     // if preview has not been started, start preview first
    667     if (!mHardware->previewEnabled()) {
    668         result = startPreviewMode();
    669         if (result != NO_ERROR) {
    670             return result;
    671         }
    672     }
    673 
    674     // start recording mode
    675     enableMsgType(CAMERA_MSG_VIDEO_FRAME);
    676     mCameraService->playSound(SOUND_RECORDING);
    677     result = mHardware->startRecording();
    678     if (result != NO_ERROR) {
    679         LOGE("mHardware->startRecording() failed with status %d", result);
    680     }
    681     return result;
    682 }
    683 
    684 // stop preview mode
    685 void CameraService::Client::stopPreview() {
    686     LOG1("stopPreview (pid %d)", getCallingPid());
    687     Mutex::Autolock lock(mLock);
    688     if (checkPidAndHardware() != NO_ERROR) return;
    689 
    690 
    691     disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
    692     mHardware->stopPreview();
    693 
    694     mPreviewBuffer.clear();
    695 }
    696 
    697 // stop recording mode
    698 void CameraService::Client::stopRecording() {
    699     LOG1("stopRecording (pid %d)", getCallingPid());
    700     Mutex::Autolock lock(mLock);
    701     if (checkPidAndHardware() != NO_ERROR) return;
    702 
    703     mCameraService->playSound(SOUND_RECORDING);
    704     disableMsgType(CAMERA_MSG_VIDEO_FRAME);
    705     mHardware->stopRecording();
    706 
    707     mPreviewBuffer.clear();
    708 }
    709 
    710 // release a recording frame
    711 void CameraService::Client::releaseRecordingFrame(const sp<IMemory>& mem) {
    712     Mutex::Autolock lock(mLock);
    713     if (checkPidAndHardware() != NO_ERROR) return;
    714     mHardware->releaseRecordingFrame(mem);
    715 }
    716 
    717 status_t CameraService::Client::storeMetaDataInBuffers(bool enabled)
    718 {
    719     LOG1("storeMetaDataInBuffers: %s", enabled? "true": "false");
    720     Mutex::Autolock lock(mLock);
    721     if (checkPidAndHardware() != NO_ERROR) {
    722         return UNKNOWN_ERROR;
    723     }
    724     return mHardware->storeMetaDataInBuffers(enabled);
    725 }
    726 
    727 bool CameraService::Client::previewEnabled() {
    728     LOG1("previewEnabled (pid %d)", getCallingPid());
    729 
    730     Mutex::Autolock lock(mLock);
    731     if (checkPidAndHardware() != NO_ERROR) return false;
    732     return mHardware->previewEnabled();
    733 }
    734 
    735 bool CameraService::Client::recordingEnabled() {
    736     LOG1("recordingEnabled (pid %d)", getCallingPid());
    737 
    738     Mutex::Autolock lock(mLock);
    739     if (checkPidAndHardware() != NO_ERROR) return false;
    740     return mHardware->recordingEnabled();
    741 }
    742 
    743 status_t CameraService::Client::autoFocus() {
    744     LOG1("autoFocus (pid %d)", getCallingPid());
    745 
    746     Mutex::Autolock lock(mLock);
    747     status_t result = checkPidAndHardware();
    748     if (result != NO_ERROR) return result;
    749 
    750     return mHardware->autoFocus();
    751 }
    752 
    753 status_t CameraService::Client::cancelAutoFocus() {
    754     LOG1("cancelAutoFocus (pid %d)", getCallingPid());
    755 
    756     Mutex::Autolock lock(mLock);
    757     status_t result = checkPidAndHardware();
    758     if (result != NO_ERROR) return result;
    759 
    760     return mHardware->cancelAutoFocus();
    761 }
    762 
    763 // take a picture - image is returned in callback
    764 status_t CameraService::Client::takePicture(int msgType) {
    765     LOG1("takePicture (pid %d): 0x%x", getCallingPid(), msgType);
    766 
    767     Mutex::Autolock lock(mLock);
    768     status_t result = checkPidAndHardware();
    769     if (result != NO_ERROR) return result;
    770 
    771     if ((msgType & CAMERA_MSG_RAW_IMAGE) &&
    772         (msgType & CAMERA_MSG_RAW_IMAGE_NOTIFY)) {
    773         LOGE("CAMERA_MSG_RAW_IMAGE and CAMERA_MSG_RAW_IMAGE_NOTIFY"
    774                 " cannot be both enabled");
    775         return BAD_VALUE;
    776     }
    777 
    778     // We only accept picture related message types
    779     // and ignore other types of messages for takePicture().
    780     int picMsgType = msgType
    781                         & (CAMERA_MSG_SHUTTER |
    782                            CAMERA_MSG_POSTVIEW_FRAME |
    783                            CAMERA_MSG_RAW_IMAGE |
    784                            CAMERA_MSG_RAW_IMAGE_NOTIFY |
    785                            CAMERA_MSG_COMPRESSED_IMAGE);
    786 
    787     enableMsgType(picMsgType);
    788 
    789     return mHardware->takePicture();
    790 }
    791 
    792 // set preview/capture parameters - key/value pairs
    793 status_t CameraService::Client::setParameters(const String8& params) {
    794     LOG1("setParameters (pid %d) (%s)", getCallingPid(), params.string());
    795 
    796     Mutex::Autolock lock(mLock);
    797     status_t result = checkPidAndHardware();
    798     if (result != NO_ERROR) return result;
    799 
    800     CameraParameters p(params);
    801     return mHardware->setParameters(p);
    802 }
    803 
    804 // get preview/capture parameters - key/value pairs
    805 String8 CameraService::Client::getParameters() const {
    806     Mutex::Autolock lock(mLock);
    807     if (checkPidAndHardware() != NO_ERROR) return String8();
    808 
    809     String8 params(mHardware->getParameters().flatten());
    810     LOG1("getParameters (pid %d) (%s)", getCallingPid(), params.string());
    811     return params;
    812 }
    813 
    814 // enable shutter sound
    815 status_t CameraService::Client::enableShutterSound(bool enable) {
    816     LOG1("enableShutterSound (pid %d)", getCallingPid());
    817 
    818     status_t result = checkPidAndHardware();
    819     if (result != NO_ERROR) return result;
    820 
    821     if (enable) {
    822         mPlayShutterSound = true;
    823         return OK;
    824     }
    825 
    826     // Disabling shutter sound may not be allowed. In that case only
    827     // allow the mediaserver process to disable the sound.
    828     char value[PROPERTY_VALUE_MAX];
    829     property_get("ro.camera.sound.forced", value, "0");
    830     if (strcmp(value, "0") != 0) {
    831         // Disabling shutter sound is not allowed. Deny if the current
    832         // process is not mediaserver.
    833         if (getCallingPid() != getpid()) {
    834             LOGE("Failed to disable shutter sound. Permission denied (pid %d)", getCallingPid());
    835             return PERMISSION_DENIED;
    836         }
    837     }
    838 
    839     mPlayShutterSound = false;
    840     return OK;
    841 }
    842 
    843 status_t CameraService::Client::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
    844     LOG1("sendCommand (pid %d)", getCallingPid());
    845     int orientation;
    846     Mutex::Autolock lock(mLock);
    847     status_t result = checkPidAndHardware();
    848     if (result != NO_ERROR) return result;
    849 
    850     if (cmd == CAMERA_CMD_SET_DISPLAY_ORIENTATION) {
    851         // Mirror the preview if the camera is front-facing.
    852         orientation = getOrientation(arg1, mCameraFacing == CAMERA_FACING_FRONT);
    853         if (orientation == -1) return BAD_VALUE;
    854 
    855         if (mOrientation != orientation) {
    856             mOrientation = orientation;
    857             if (mPreviewWindow != 0) {
    858                 native_window_set_buffers_transform(mPreviewWindow.get(),
    859                         mOrientation);
    860             }
    861         }
    862         return OK;
    863     } else if (cmd == CAMERA_CMD_ENABLE_SHUTTER_SOUND) {
    864         switch (arg1) {
    865             case 0:
    866                 enableShutterSound(false);
    867                 break;
    868             case 1:
    869                 enableShutterSound(true);
    870                 break;
    871             default:
    872                 return BAD_VALUE;
    873         }
    874         return OK;
    875     } else if (cmd == CAMERA_CMD_PLAY_RECORDING_SOUND) {
    876         mCameraService->playSound(SOUND_RECORDING);
    877     }
    878 
    879     return mHardware->sendCommand(cmd, arg1, arg2);
    880 }
    881 
    882 // ----------------------------------------------------------------------------
    883 
    884 void CameraService::Client::enableMsgType(int32_t msgType) {
    885     android_atomic_or(msgType, &mMsgEnabled);
    886     mHardware->enableMsgType(msgType);
    887 }
    888 
    889 void CameraService::Client::disableMsgType(int32_t msgType) {
    890     android_atomic_and(~msgType, &mMsgEnabled);
    891     mHardware->disableMsgType(msgType);
    892 }
    893 
    894 #define CHECK_MESSAGE_INTERVAL 10 // 10ms
    895 bool CameraService::Client::lockIfMessageWanted(int32_t msgType) {
    896     int sleepCount = 0;
    897     while (mMsgEnabled & msgType) {
    898         if (mLock.tryLock() == NO_ERROR) {
    899             if (sleepCount > 0) {
    900                 LOG1("lockIfMessageWanted(%d): waited for %d ms",
    901                     msgType, sleepCount * CHECK_MESSAGE_INTERVAL);
    902             }
    903             return true;
    904         }
    905         if (sleepCount++ == 0) {
    906             LOG1("lockIfMessageWanted(%d): enter sleep", msgType);
    907         }
    908         usleep(CHECK_MESSAGE_INTERVAL * 1000);
    909     }
    910     LOGW("lockIfMessageWanted(%d): dropped unwanted message", msgType);
    911     return false;
    912 }
    913 
    914 // ----------------------------------------------------------------------------
    915 
    916 // Converts from a raw pointer to the client to a strong pointer during a
    917 // hardware callback. This requires the callbacks only happen when the client
    918 // is still alive.
    919 sp<CameraService::Client> CameraService::Client::getClientFromCookie(void* user) {
    920     sp<Client> client = gCameraService->getClientById((int) user);
    921 
    922     // This could happen if the Client is in the process of shutting down (the
    923     // last strong reference is gone, but the destructor hasn't finished
    924     // stopping the hardware).
    925     if (client == 0) return NULL;
    926 
    927     // The checks below are not necessary and are for debugging only.
    928     if (client->mCameraService.get() != gCameraService) {
    929         LOGE("mismatch service!");
    930         return NULL;
    931     }
    932 
    933     if (client->mHardware == 0) {
    934         LOGE("mHardware == 0: callback after disconnect()?");
    935         return NULL;
    936     }
    937 
    938     return client;
    939 }
    940 
    941 // Callback messages can be dispatched to internal handlers or pass to our
    942 // client's callback functions, depending on the message type.
    943 //
    944 // notifyCallback:
    945 //      CAMERA_MSG_SHUTTER              handleShutter
    946 //      (others)                        c->notifyCallback
    947 // dataCallback:
    948 //      CAMERA_MSG_PREVIEW_FRAME        handlePreviewData
    949 //      CAMERA_MSG_POSTVIEW_FRAME       handlePostview
    950 //      CAMERA_MSG_RAW_IMAGE            handleRawPicture
    951 //      CAMERA_MSG_COMPRESSED_IMAGE     handleCompressedPicture
    952 //      (others)                        c->dataCallback
    953 // dataCallbackTimestamp
    954 //      (others)                        c->dataCallbackTimestamp
    955 //
    956 // NOTE: the *Callback functions grab mLock of the client before passing
    957 // control to handle* functions. So the handle* functions must release the
    958 // lock before calling the ICameraClient's callbacks, so those callbacks can
    959 // invoke methods in the Client class again (For example, the preview frame
    960 // callback may want to releaseRecordingFrame). The handle* functions must
    961 // release the lock after all accesses to member variables, so it must be
    962 // handled very carefully.
    963 
    964 void CameraService::Client::notifyCallback(int32_t msgType, int32_t ext1,
    965         int32_t ext2, void* user) {
    966     LOG2("notifyCallback(%d)", msgType);
    967 
    968     sp<Client> client = getClientFromCookie(user);
    969     if (client == 0) return;
    970     if (!client->lockIfMessageWanted(msgType)) return;
    971 
    972     switch (msgType) {
    973         case CAMERA_MSG_SHUTTER:
    974             // ext1 is the dimension of the yuv picture.
    975             client->handleShutter();
    976             break;
    977         default:
    978             client->handleGenericNotify(msgType, ext1, ext2);
    979             break;
    980     }
    981 }
    982 
    983 void CameraService::Client::dataCallback(int32_t msgType,
    984         const sp<IMemory>& dataPtr, camera_frame_metadata_t *metadata, void* user) {
    985     LOG2("dataCallback(%d)", msgType);
    986 
    987     sp<Client> client = getClientFromCookie(user);
    988     if (client == 0) return;
    989     if (!client->lockIfMessageWanted(msgType)) return;
    990 
    991     if (dataPtr == 0 && metadata == NULL) {
    992         LOGE("Null data returned in data callback");
    993         client->handleGenericNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
    994         return;
    995     }
    996 
    997     switch (msgType & ~CAMERA_MSG_PREVIEW_METADATA) {
    998         case CAMERA_MSG_PREVIEW_FRAME:
    999             client->handlePreviewData(msgType, dataPtr, metadata);
   1000             break;
   1001         case CAMERA_MSG_POSTVIEW_FRAME:
   1002             client->handlePostview(dataPtr);
   1003             break;
   1004         case CAMERA_MSG_RAW_IMAGE:
   1005             client->handleRawPicture(dataPtr);
   1006             break;
   1007         case CAMERA_MSG_COMPRESSED_IMAGE:
   1008             client->handleCompressedPicture(dataPtr);
   1009             break;
   1010         default:
   1011             client->handleGenericData(msgType, dataPtr, metadata);
   1012             break;
   1013     }
   1014 }
   1015 
   1016 void CameraService::Client::dataCallbackTimestamp(nsecs_t timestamp,
   1017         int32_t msgType, const sp<IMemory>& dataPtr, void* user) {
   1018     LOG2("dataCallbackTimestamp(%d)", msgType);
   1019 
   1020     sp<Client> client = getClientFromCookie(user);
   1021     if (client == 0) return;
   1022     if (!client->lockIfMessageWanted(msgType)) return;
   1023 
   1024     if (dataPtr == 0) {
   1025         LOGE("Null data returned in data with timestamp callback");
   1026         client->handleGenericNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
   1027         return;
   1028     }
   1029 
   1030     client->handleGenericDataTimestamp(timestamp, msgType, dataPtr);
   1031 }
   1032 
   1033 // snapshot taken callback
   1034 void CameraService::Client::handleShutter(void) {
   1035     if (mPlayShutterSound) {
   1036         mCameraService->playSound(SOUND_SHUTTER);
   1037     }
   1038 
   1039     sp<ICameraClient> c = mCameraClient;
   1040     if (c != 0) {
   1041         mLock.unlock();
   1042         c->notifyCallback(CAMERA_MSG_SHUTTER, 0, 0);
   1043         if (!lockIfMessageWanted(CAMERA_MSG_SHUTTER)) return;
   1044     }
   1045     disableMsgType(CAMERA_MSG_SHUTTER);
   1046 
   1047     mLock.unlock();
   1048 }
   1049 
   1050 // preview callback - frame buffer update
   1051 void CameraService::Client::handlePreviewData(int32_t msgType,
   1052                                               const sp<IMemory>& mem,
   1053                                               camera_frame_metadata_t *metadata) {
   1054     ssize_t offset;
   1055     size_t size;
   1056     sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
   1057 
   1058     // local copy of the callback flags
   1059     int flags = mPreviewCallbackFlag;
   1060 
   1061     // is callback enabled?
   1062     if (!(flags & CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK)) {
   1063         // If the enable bit is off, the copy-out and one-shot bits are ignored
   1064         LOG2("frame callback is disabled");
   1065         mLock.unlock();
   1066         return;
   1067     }
   1068 
   1069     // hold a strong pointer to the client
   1070     sp<ICameraClient> c = mCameraClient;
   1071 
   1072     // clear callback flags if no client or one-shot mode
   1073     if (c == 0 || (mPreviewCallbackFlag & CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK)) {
   1074         LOG2("Disable preview callback");
   1075         mPreviewCallbackFlag &= ~(CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK |
   1076                                   CAMERA_FRAME_CALLBACK_FLAG_COPY_OUT_MASK |
   1077                                   CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK);
   1078         disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
   1079     }
   1080 
   1081     if (c != 0) {
   1082         // Is the received frame copied out or not?
   1083         if (flags & CAMERA_FRAME_CALLBACK_FLAG_COPY_OUT_MASK) {
   1084             LOG2("frame is copied");
   1085             copyFrameAndPostCopiedFrame(msgType, c, heap, offset, size, metadata);
   1086         } else {
   1087             LOG2("frame is forwarded");
   1088             mLock.unlock();
   1089             c->dataCallback(msgType, mem, metadata);
   1090         }
   1091     } else {
   1092         mLock.unlock();
   1093     }
   1094 }
   1095 
   1096 // picture callback - postview image ready
   1097 void CameraService::Client::handlePostview(const sp<IMemory>& mem) {
   1098     disableMsgType(CAMERA_MSG_POSTVIEW_FRAME);
   1099 
   1100     sp<ICameraClient> c = mCameraClient;
   1101     mLock.unlock();
   1102     if (c != 0) {
   1103         c->dataCallback(CAMERA_MSG_POSTVIEW_FRAME, mem, NULL);
   1104     }
   1105 }
   1106 
   1107 // picture callback - raw image ready
   1108 void CameraService::Client::handleRawPicture(const sp<IMemory>& mem) {
   1109     disableMsgType(CAMERA_MSG_RAW_IMAGE);
   1110 
   1111     ssize_t offset;
   1112     size_t size;
   1113     sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
   1114 
   1115     sp<ICameraClient> c = mCameraClient;
   1116     mLock.unlock();
   1117     if (c != 0) {
   1118         c->dataCallback(CAMERA_MSG_RAW_IMAGE, mem, NULL);
   1119     }
   1120 }
   1121 
   1122 // picture callback - compressed picture ready
   1123 void CameraService::Client::handleCompressedPicture(const sp<IMemory>& mem) {
   1124     disableMsgType(CAMERA_MSG_COMPRESSED_IMAGE);
   1125 
   1126     sp<ICameraClient> c = mCameraClient;
   1127     mLock.unlock();
   1128     if (c != 0) {
   1129         c->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE, mem, NULL);
   1130     }
   1131 }
   1132 
   1133 
   1134 void CameraService::Client::handleGenericNotify(int32_t msgType,
   1135     int32_t ext1, int32_t ext2) {
   1136     sp<ICameraClient> c = mCameraClient;
   1137     mLock.unlock();
   1138     if (c != 0) {
   1139         c->notifyCallback(msgType, ext1, ext2);
   1140     }
   1141 }
   1142 
   1143 void CameraService::Client::handleGenericData(int32_t msgType,
   1144     const sp<IMemory>& dataPtr, camera_frame_metadata_t *metadata) {
   1145     sp<ICameraClient> c = mCameraClient;
   1146     mLock.unlock();
   1147     if (c != 0) {
   1148         c->dataCallback(msgType, dataPtr, metadata);
   1149     }
   1150 }
   1151 
   1152 void CameraService::Client::handleGenericDataTimestamp(nsecs_t timestamp,
   1153     int32_t msgType, const sp<IMemory>& dataPtr) {
   1154     sp<ICameraClient> c = mCameraClient;
   1155     mLock.unlock();
   1156     if (c != 0) {
   1157         c->dataCallbackTimestamp(timestamp, msgType, dataPtr);
   1158     }
   1159 }
   1160 
   1161 void CameraService::Client::copyFrameAndPostCopiedFrame(
   1162         int32_t msgType, const sp<ICameraClient>& client,
   1163         const sp<IMemoryHeap>& heap, size_t offset, size_t size,
   1164         camera_frame_metadata_t *metadata) {
   1165     LOG2("copyFrameAndPostCopiedFrame");
   1166     // It is necessary to copy out of pmem before sending this to
   1167     // the callback. For efficiency, reuse the same MemoryHeapBase
   1168     // provided it's big enough. Don't allocate the memory or
   1169     // perform the copy if there's no callback.
   1170     // hold the preview lock while we grab a reference to the preview buffer
   1171     sp<MemoryHeapBase> previewBuffer;
   1172 
   1173     if (mPreviewBuffer == 0) {
   1174         mPreviewBuffer = new MemoryHeapBase(size, 0, NULL);
   1175     } else if (size > mPreviewBuffer->virtualSize()) {
   1176         mPreviewBuffer.clear();
   1177         mPreviewBuffer = new MemoryHeapBase(size, 0, NULL);
   1178     }
   1179     if (mPreviewBuffer == 0) {
   1180         LOGE("failed to allocate space for preview buffer");
   1181         mLock.unlock();
   1182         return;
   1183     }
   1184     previewBuffer = mPreviewBuffer;
   1185 
   1186     memcpy(previewBuffer->base(), (uint8_t *)heap->base() + offset, size);
   1187 
   1188     sp<MemoryBase> frame = new MemoryBase(previewBuffer, 0, size);
   1189     if (frame == 0) {
   1190         LOGE("failed to allocate space for frame callback");
   1191         mLock.unlock();
   1192         return;
   1193     }
   1194 
   1195     mLock.unlock();
   1196     client->dataCallback(msgType, frame, metadata);
   1197 }
   1198 
   1199 int CameraService::Client::getOrientation(int degrees, bool mirror) {
   1200     if (!mirror) {
   1201         if (degrees == 0) return 0;
   1202         else if (degrees == 90) return HAL_TRANSFORM_ROT_90;
   1203         else if (degrees == 180) return HAL_TRANSFORM_ROT_180;
   1204         else if (degrees == 270) return HAL_TRANSFORM_ROT_270;
   1205     } else {  // Do mirror (horizontal flip)
   1206         if (degrees == 0) {           // FLIP_H and ROT_0
   1207             return HAL_TRANSFORM_FLIP_H;
   1208         } else if (degrees == 90) {   // FLIP_H and ROT_90
   1209             return HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90;
   1210         } else if (degrees == 180) {  // FLIP_H and ROT_180
   1211             return HAL_TRANSFORM_FLIP_V;
   1212         } else if (degrees == 270) {  // FLIP_H and ROT_270
   1213             return HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90;
   1214         }
   1215     }
   1216     LOGE("Invalid setDisplayOrientation degrees=%d", degrees);
   1217     return -1;
   1218 }
   1219 
   1220 
   1221 // ----------------------------------------------------------------------------
   1222 
   1223 static const int kDumpLockRetries = 50;
   1224 static const int kDumpLockSleep = 60000;
   1225 
   1226 static bool tryLock(Mutex& mutex)
   1227 {
   1228     bool locked = false;
   1229     for (int i = 0; i < kDumpLockRetries; ++i) {
   1230         if (mutex.tryLock() == NO_ERROR) {
   1231             locked = true;
   1232             break;
   1233         }
   1234         usleep(kDumpLockSleep);
   1235     }
   1236     return locked;
   1237 }
   1238 
   1239 status_t CameraService::dump(int fd, const Vector<String16>& args) {
   1240     static const char* kDeadlockedString = "CameraService may be deadlocked\n";
   1241 
   1242     const size_t SIZE = 256;
   1243     char buffer[SIZE];
   1244     String8 result;
   1245     if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
   1246         snprintf(buffer, SIZE, "Permission Denial: "
   1247                 "can't dump CameraService from pid=%d, uid=%d\n",
   1248                 getCallingPid(),
   1249                 getCallingUid());
   1250         result.append(buffer);
   1251         write(fd, result.string(), result.size());
   1252     } else {
   1253         bool locked = tryLock(mServiceLock);
   1254         // failed to lock - CameraService is probably deadlocked
   1255         if (!locked) {
   1256             String8 result(kDeadlockedString);
   1257             write(fd, result.string(), result.size());
   1258         }
   1259 
   1260         bool hasClient = false;
   1261         for (int i = 0; i < mNumberOfCameras; i++) {
   1262             sp<Client> client = mClient[i].promote();
   1263             if (client == 0) continue;
   1264             hasClient = true;
   1265             sprintf(buffer, "Client[%d] (%p) PID: %d\n",
   1266                     i,
   1267                     client->getCameraClient()->asBinder().get(),
   1268                     client->mClientPid);
   1269             result.append(buffer);
   1270             write(fd, result.string(), result.size());
   1271             client->mHardware->dump(fd, args);
   1272         }
   1273         if (!hasClient) {
   1274             result.append("No camera client yet.\n");
   1275             write(fd, result.string(), result.size());
   1276         }
   1277 
   1278         if (locked) mServiceLock.unlock();
   1279 
   1280         // change logging level
   1281         int n = args.size();
   1282         for (int i = 0; i + 1 < n; i++) {
   1283             if (args[i] == String16("-v")) {
   1284                 String8 levelStr(args[i+1]);
   1285                 int level = atoi(levelStr.string());
   1286                 sprintf(buffer, "Set Log Level to %d", level);
   1287                 result.append(buffer);
   1288                 setLogLevel(level);
   1289             }
   1290         }
   1291     }
   1292     return NO_ERROR;
   1293 }
   1294 
   1295 }; // namespace android
   1296