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