Home | History | Annotate | Download | only in api1
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #define LOG_TAG "CameraClient"
     18 //#define LOG_NDEBUG 0
     19 
     20 #include <cutils/properties.h>
     21 #include <gui/Surface.h>
     22 
     23 #include "api1/CameraClient.h"
     24 #include "device1/CameraHardwareInterface.h"
     25 #include "CameraService.h"
     26 
     27 namespace android {
     28 
     29 #define LOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__);
     30 #define LOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__);
     31 
     32 static int getCallingPid() {
     33     return IPCThreadState::self()->getCallingPid();
     34 }
     35 
     36 CameraClient::CameraClient(const sp<CameraService>& cameraService,
     37         const sp<ICameraClient>& cameraClient,
     38         const String16& clientPackageName,
     39         int cameraId, int cameraFacing,
     40         int clientPid, int clientUid,
     41         int servicePid):
     42         Client(cameraService, cameraClient, clientPackageName,
     43                 cameraId, cameraFacing, clientPid, clientUid, servicePid)
     44 {
     45     int callingPid = getCallingPid();
     46     LOG1("CameraClient::CameraClient E (pid %d, id %d)", callingPid, cameraId);
     47 
     48     mHardware = NULL;
     49     mMsgEnabled = 0;
     50     mSurface = 0;
     51     mPreviewWindow = 0;
     52     mDestructionStarted = false;
     53 
     54     // Callback is disabled by default
     55     mPreviewCallbackFlag = CAMERA_FRAME_CALLBACK_FLAG_NOOP;
     56     mOrientation = getOrientation(0, mCameraFacing == CAMERA_FACING_FRONT);
     57     mPlayShutterSound = true;
     58     LOG1("CameraClient::CameraClient X (pid %d, id %d)", callingPid, cameraId);
     59 }
     60 
     61 status_t CameraClient::initialize(camera_module_t *module) {
     62     int callingPid = getCallingPid();
     63     status_t res;
     64 
     65     LOG1("CameraClient::initialize E (pid %d, id %d)", callingPid, mCameraId);
     66 
     67     // Verify ops permissions
     68     res = startCameraOps();
     69     if (res != OK) {
     70         return res;
     71     }
     72 
     73     char camera_device_name[10];
     74     snprintf(camera_device_name, sizeof(camera_device_name), "%d", mCameraId);
     75 
     76     mHardware = new CameraHardwareInterface(camera_device_name);
     77     res = mHardware->initialize(&module->common);
     78     if (res != OK) {
     79         ALOGE("%s: Camera %d: unable to initialize device: %s (%d)",
     80                 __FUNCTION__, mCameraId, strerror(-res), res);
     81         mHardware.clear();
     82         return NO_INIT;
     83     }
     84 
     85     mHardware->setCallbacks(notifyCallback,
     86             dataCallback,
     87             dataCallbackTimestamp,
     88             (void *)mCameraId);
     89 
     90     // Enable zoom, error, focus, and metadata messages by default
     91     enableMsgType(CAMERA_MSG_ERROR | CAMERA_MSG_ZOOM | CAMERA_MSG_FOCUS |
     92                   CAMERA_MSG_PREVIEW_METADATA | CAMERA_MSG_FOCUS_MOVE);
     93 
     94     LOG1("CameraClient::initialize X (pid %d, id %d)", callingPid, mCameraId);
     95     return OK;
     96 }
     97 
     98 
     99 // tear down the client
    100 CameraClient::~CameraClient() {
    101     // this lock should never be NULL
    102     Mutex* lock = mCameraService->getClientLockById(mCameraId);
    103     lock->lock();
    104     mDestructionStarted = true;
    105     // client will not be accessed from callback. should unlock to prevent dead-lock in disconnect
    106     lock->unlock();
    107     int callingPid = getCallingPid();
    108     LOG1("CameraClient::~CameraClient E (pid %d, this %p)", callingPid, this);
    109 
    110     disconnect();
    111     LOG1("CameraClient::~CameraClient X (pid %d, this %p)", callingPid, this);
    112 }
    113 
    114 status_t CameraClient::dump(int fd, const Vector<String16>& args) {
    115     const size_t SIZE = 256;
    116     char buffer[SIZE];
    117 
    118     size_t len = snprintf(buffer, SIZE, "Client[%d] (%p) PID: %d\n",
    119             mCameraId,
    120             getRemoteCallback()->asBinder().get(),
    121             mClientPid);
    122     len = (len > SIZE - 1) ? SIZE - 1 : len;
    123     write(fd, buffer, len);
    124     return mHardware->dump(fd, args);
    125 }
    126 
    127 // ----------------------------------------------------------------------------
    128 
    129 status_t CameraClient::checkPid() const {
    130     int callingPid = getCallingPid();
    131     if (callingPid == mClientPid) return NO_ERROR;
    132 
    133     ALOGW("attempt to use a locked camera from a different process"
    134          " (old pid %d, new pid %d)", mClientPid, callingPid);
    135     return EBUSY;
    136 }
    137 
    138 status_t CameraClient::checkPidAndHardware() const {
    139     status_t result = checkPid();
    140     if (result != NO_ERROR) return result;
    141     if (mHardware == 0) {
    142         ALOGE("attempt to use a camera after disconnect() (pid %d)", getCallingPid());
    143         return INVALID_OPERATION;
    144     }
    145     return NO_ERROR;
    146 }
    147 
    148 status_t CameraClient::lock() {
    149     int callingPid = getCallingPid();
    150     LOG1("lock (pid %d)", callingPid);
    151     Mutex::Autolock lock(mLock);
    152 
    153     // lock camera to this client if the the camera is unlocked
    154     if (mClientPid == 0) {
    155         mClientPid = callingPid;
    156         return NO_ERROR;
    157     }
    158 
    159     // returns NO_ERROR if the client already owns the camera, EBUSY otherwise
    160     return checkPid();
    161 }
    162 
    163 status_t CameraClient::unlock() {
    164     int callingPid = getCallingPid();
    165     LOG1("unlock (pid %d)", callingPid);
    166     Mutex::Autolock lock(mLock);
    167 
    168     // allow anyone to use camera (after they lock the camera)
    169     status_t result = checkPid();
    170     if (result == NO_ERROR) {
    171         if (mHardware->recordingEnabled()) {
    172             ALOGE("Not allowed to unlock camera during recording.");
    173             return INVALID_OPERATION;
    174         }
    175         mClientPid = 0;
    176         LOG1("clear mRemoteCallback (pid %d)", callingPid);
    177         // we need to remove the reference to ICameraClient so that when the app
    178         // goes away, the reference count goes to 0.
    179         mRemoteCallback.clear();
    180     }
    181     return result;
    182 }
    183 
    184 // connect a new client to the camera
    185 status_t CameraClient::connect(const sp<ICameraClient>& client) {
    186     int callingPid = getCallingPid();
    187     LOG1("connect E (pid %d)", callingPid);
    188     Mutex::Autolock lock(mLock);
    189 
    190     if (mClientPid != 0 && checkPid() != NO_ERROR) {
    191         ALOGW("Tried to connect to a locked camera (old pid %d, new pid %d)",
    192                 mClientPid, callingPid);
    193         return EBUSY;
    194     }
    195 
    196     if (mRemoteCallback != 0 &&
    197         (client->asBinder() == mRemoteCallback->asBinder())) {
    198         LOG1("Connect to the same client");
    199         return NO_ERROR;
    200     }
    201 
    202     mPreviewCallbackFlag = CAMERA_FRAME_CALLBACK_FLAG_NOOP;
    203     mClientPid = callingPid;
    204     mRemoteCallback = client;
    205 
    206     LOG1("connect X (pid %d)", callingPid);
    207     return NO_ERROR;
    208 }
    209 
    210 static void disconnectWindow(const sp<ANativeWindow>& window) {
    211     if (window != 0) {
    212         status_t result = native_window_api_disconnect(window.get(),
    213                 NATIVE_WINDOW_API_CAMERA);
    214         if (result != NO_ERROR) {
    215             ALOGW("native_window_api_disconnect failed: %s (%d)", strerror(-result),
    216                     result);
    217         }
    218     }
    219 }
    220 
    221 void CameraClient::disconnect() {
    222     int callingPid = getCallingPid();
    223     LOG1("disconnect E (pid %d)", callingPid);
    224     Mutex::Autolock lock(mLock);
    225 
    226     // Allow both client and the media server to disconnect at all times
    227     if (callingPid != mClientPid && callingPid != mServicePid) {
    228         ALOGW("different client - don't disconnect");
    229         return;
    230     }
    231 
    232     if (mClientPid <= 0) {
    233         LOG1("camera is unlocked (mClientPid = %d), don't tear down hardware", mClientPid);
    234         return;
    235     }
    236 
    237     // Make sure disconnect() is done once and once only, whether it is called
    238     // from the user directly, or called by the destructor.
    239     if (mHardware == 0) return;
    240 
    241     LOG1("hardware teardown");
    242     // Before destroying mHardware, we must make sure it's in the
    243     // idle state.
    244     // Turn off all messages.
    245     disableMsgType(CAMERA_MSG_ALL_MSGS);
    246     mHardware->stopPreview();
    247     mHardware->cancelPicture();
    248     // Release the hardware resources.
    249     mHardware->release();
    250 
    251     // Release the held ANativeWindow resources.
    252     if (mPreviewWindow != 0) {
    253         disconnectWindow(mPreviewWindow);
    254         mPreviewWindow = 0;
    255         mHardware->setPreviewWindow(mPreviewWindow);
    256     }
    257     mHardware.clear();
    258 
    259     CameraService::Client::disconnect();
    260 
    261     LOG1("disconnect X (pid %d)", callingPid);
    262 }
    263 
    264 // ----------------------------------------------------------------------------
    265 
    266 status_t CameraClient::setPreviewWindow(const sp<IBinder>& binder,
    267         const sp<ANativeWindow>& window) {
    268     Mutex::Autolock lock(mLock);
    269     status_t result = checkPidAndHardware();
    270     if (result != NO_ERROR) return result;
    271 
    272     // return if no change in surface.
    273     if (binder == mSurface) {
    274         return NO_ERROR;
    275     }
    276 
    277     if (window != 0) {
    278         result = native_window_api_connect(window.get(), NATIVE_WINDOW_API_CAMERA);
    279         if (result != NO_ERROR) {
    280             ALOGE("native_window_api_connect failed: %s (%d)", strerror(-result),
    281                     result);
    282             return result;
    283         }
    284     }
    285 
    286     // If preview has been already started, register preview buffers now.
    287     if (mHardware->previewEnabled()) {
    288         if (window != 0) {
    289             native_window_set_scaling_mode(window.get(),
    290                     NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
    291             native_window_set_buffers_transform(window.get(), mOrientation);
    292             result = mHardware->setPreviewWindow(window);
    293         }
    294     }
    295 
    296     if (result == NO_ERROR) {
    297         // Everything has succeeded.  Disconnect the old window and remember the
    298         // new window.
    299         disconnectWindow(mPreviewWindow);
    300         mSurface = binder;
    301         mPreviewWindow = window;
    302     } else {
    303         // Something went wrong after we connected to the new window, so
    304         // disconnect here.
    305         disconnectWindow(window);
    306     }
    307 
    308     return result;
    309 }
    310 
    311 // set the buffer consumer that the preview will use
    312 status_t CameraClient::setPreviewTarget(
    313         const sp<IGraphicBufferProducer>& bufferProducer) {
    314     LOG1("setPreviewTarget(%p) (pid %d)", bufferProducer.get(),
    315             getCallingPid());
    316 
    317     sp<IBinder> binder;
    318     sp<ANativeWindow> window;
    319     if (bufferProducer != 0) {
    320         binder = bufferProducer->asBinder();
    321         // Using controlledByApp flag to ensure that the buffer queue remains in
    322         // async mode for the old camera API, where many applications depend
    323         // on that behavior.
    324         window = new Surface(bufferProducer, /*controlledByApp*/ true);
    325     }
    326     return setPreviewWindow(binder, window);
    327 }
    328 
    329 // set the preview callback flag to affect how the received frames from
    330 // preview are handled.
    331 void CameraClient::setPreviewCallbackFlag(int callback_flag) {
    332     LOG1("setPreviewCallbackFlag(%d) (pid %d)", callback_flag, getCallingPid());
    333     Mutex::Autolock lock(mLock);
    334     if (checkPidAndHardware() != NO_ERROR) return;
    335 
    336     mPreviewCallbackFlag = callback_flag;
    337     if (mPreviewCallbackFlag & CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) {
    338         enableMsgType(CAMERA_MSG_PREVIEW_FRAME);
    339     } else {
    340         disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
    341     }
    342 }
    343 
    344 status_t CameraClient::setPreviewCallbackTarget(
    345         const sp<IGraphicBufferProducer>& callbackProducer) {
    346     (void)callbackProducer;
    347     ALOGE("%s: Unimplemented!", __FUNCTION__);
    348     return INVALID_OPERATION;
    349 }
    350 
    351 // start preview mode
    352 status_t CameraClient::startPreview() {
    353     LOG1("startPreview (pid %d)", getCallingPid());
    354     return startCameraMode(CAMERA_PREVIEW_MODE);
    355 }
    356 
    357 // start recording mode
    358 status_t CameraClient::startRecording() {
    359     LOG1("startRecording (pid %d)", getCallingPid());
    360     return startCameraMode(CAMERA_RECORDING_MODE);
    361 }
    362 
    363 // start preview or recording
    364 status_t CameraClient::startCameraMode(camera_mode mode) {
    365     LOG1("startCameraMode(%d)", mode);
    366     Mutex::Autolock lock(mLock);
    367     status_t result = checkPidAndHardware();
    368     if (result != NO_ERROR) return result;
    369 
    370     switch(mode) {
    371         case CAMERA_PREVIEW_MODE:
    372             if (mSurface == 0 && mPreviewWindow == 0) {
    373                 LOG1("mSurface is not set yet.");
    374                 // still able to start preview in this case.
    375             }
    376             return startPreviewMode();
    377         case CAMERA_RECORDING_MODE:
    378             if (mSurface == 0 && mPreviewWindow == 0) {
    379                 ALOGE("mSurface or mPreviewWindow must be set before startRecordingMode.");
    380                 return INVALID_OPERATION;
    381             }
    382             return startRecordingMode();
    383         default:
    384             return UNKNOWN_ERROR;
    385     }
    386 }
    387 
    388 status_t CameraClient::startPreviewMode() {
    389     LOG1("startPreviewMode");
    390     status_t result = NO_ERROR;
    391 
    392     // if preview has been enabled, nothing needs to be done
    393     if (mHardware->previewEnabled()) {
    394         return NO_ERROR;
    395     }
    396 
    397     if (mPreviewWindow != 0) {
    398         native_window_set_scaling_mode(mPreviewWindow.get(),
    399                 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
    400         native_window_set_buffers_transform(mPreviewWindow.get(),
    401                 mOrientation);
    402     }
    403     mHardware->setPreviewWindow(mPreviewWindow);
    404     result = mHardware->startPreview();
    405 
    406     return result;
    407 }
    408 
    409 status_t CameraClient::startRecordingMode() {
    410     LOG1("startRecordingMode");
    411     status_t result = NO_ERROR;
    412 
    413     // if recording has been enabled, nothing needs to be done
    414     if (mHardware->recordingEnabled()) {
    415         return NO_ERROR;
    416     }
    417 
    418     // if preview has not been started, start preview first
    419     if (!mHardware->previewEnabled()) {
    420         result = startPreviewMode();
    421         if (result != NO_ERROR) {
    422             return result;
    423         }
    424     }
    425 
    426     // start recording mode
    427     enableMsgType(CAMERA_MSG_VIDEO_FRAME);
    428     mCameraService->playSound(CameraService::SOUND_RECORDING);
    429     result = mHardware->startRecording();
    430     if (result != NO_ERROR) {
    431         ALOGE("mHardware->startRecording() failed with status %d", result);
    432     }
    433     return result;
    434 }
    435 
    436 // stop preview mode
    437 void CameraClient::stopPreview() {
    438     LOG1("stopPreview (pid %d)", getCallingPid());
    439     Mutex::Autolock lock(mLock);
    440     if (checkPidAndHardware() != NO_ERROR) return;
    441 
    442 
    443     disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
    444     mHardware->stopPreview();
    445 
    446     mPreviewBuffer.clear();
    447 }
    448 
    449 // stop recording mode
    450 void CameraClient::stopRecording() {
    451     LOG1("stopRecording (pid %d)", getCallingPid());
    452     Mutex::Autolock lock(mLock);
    453     if (checkPidAndHardware() != NO_ERROR) return;
    454 
    455     disableMsgType(CAMERA_MSG_VIDEO_FRAME);
    456     mHardware->stopRecording();
    457     mCameraService->playSound(CameraService::SOUND_RECORDING);
    458 
    459     mPreviewBuffer.clear();
    460 }
    461 
    462 // release a recording frame
    463 void CameraClient::releaseRecordingFrame(const sp<IMemory>& mem) {
    464     Mutex::Autolock lock(mLock);
    465     if (checkPidAndHardware() != NO_ERROR) return;
    466     mHardware->releaseRecordingFrame(mem);
    467 }
    468 
    469 status_t CameraClient::storeMetaDataInBuffers(bool enabled)
    470 {
    471     LOG1("storeMetaDataInBuffers: %s", enabled? "true": "false");
    472     Mutex::Autolock lock(mLock);
    473     if (checkPidAndHardware() != NO_ERROR) {
    474         return UNKNOWN_ERROR;
    475     }
    476     return mHardware->storeMetaDataInBuffers(enabled);
    477 }
    478 
    479 bool CameraClient::previewEnabled() {
    480     LOG1("previewEnabled (pid %d)", getCallingPid());
    481 
    482     Mutex::Autolock lock(mLock);
    483     if (checkPidAndHardware() != NO_ERROR) return false;
    484     return mHardware->previewEnabled();
    485 }
    486 
    487 bool CameraClient::recordingEnabled() {
    488     LOG1("recordingEnabled (pid %d)", getCallingPid());
    489 
    490     Mutex::Autolock lock(mLock);
    491     if (checkPidAndHardware() != NO_ERROR) return false;
    492     return mHardware->recordingEnabled();
    493 }
    494 
    495 status_t CameraClient::autoFocus() {
    496     LOG1("autoFocus (pid %d)", getCallingPid());
    497 
    498     Mutex::Autolock lock(mLock);
    499     status_t result = checkPidAndHardware();
    500     if (result != NO_ERROR) return result;
    501 
    502     return mHardware->autoFocus();
    503 }
    504 
    505 status_t CameraClient::cancelAutoFocus() {
    506     LOG1("cancelAutoFocus (pid %d)", getCallingPid());
    507 
    508     Mutex::Autolock lock(mLock);
    509     status_t result = checkPidAndHardware();
    510     if (result != NO_ERROR) return result;
    511 
    512     return mHardware->cancelAutoFocus();
    513 }
    514 
    515 // take a picture - image is returned in callback
    516 status_t CameraClient::takePicture(int msgType) {
    517     LOG1("takePicture (pid %d): 0x%x", getCallingPid(), msgType);
    518 
    519     Mutex::Autolock lock(mLock);
    520     status_t result = checkPidAndHardware();
    521     if (result != NO_ERROR) return result;
    522 
    523     if ((msgType & CAMERA_MSG_RAW_IMAGE) &&
    524         (msgType & CAMERA_MSG_RAW_IMAGE_NOTIFY)) {
    525         ALOGE("CAMERA_MSG_RAW_IMAGE and CAMERA_MSG_RAW_IMAGE_NOTIFY"
    526                 " cannot be both enabled");
    527         return BAD_VALUE;
    528     }
    529 
    530     // We only accept picture related message types
    531     // and ignore other types of messages for takePicture().
    532     int picMsgType = msgType
    533                         & (CAMERA_MSG_SHUTTER |
    534                            CAMERA_MSG_POSTVIEW_FRAME |
    535                            CAMERA_MSG_RAW_IMAGE |
    536                            CAMERA_MSG_RAW_IMAGE_NOTIFY |
    537                            CAMERA_MSG_COMPRESSED_IMAGE);
    538 
    539     enableMsgType(picMsgType);
    540 
    541     return mHardware->takePicture();
    542 }
    543 
    544 // set preview/capture parameters - key/value pairs
    545 status_t CameraClient::setParameters(const String8& params) {
    546     LOG1("setParameters (pid %d) (%s)", getCallingPid(), params.string());
    547 
    548     Mutex::Autolock lock(mLock);
    549     status_t result = checkPidAndHardware();
    550     if (result != NO_ERROR) return result;
    551 
    552     CameraParameters p(params);
    553     return mHardware->setParameters(p);
    554 }
    555 
    556 // get preview/capture parameters - key/value pairs
    557 String8 CameraClient::getParameters() const {
    558     Mutex::Autolock lock(mLock);
    559     if (checkPidAndHardware() != NO_ERROR) return String8();
    560 
    561     String8 params(mHardware->getParameters().flatten());
    562     LOG1("getParameters (pid %d) (%s)", getCallingPid(), params.string());
    563     return params;
    564 }
    565 
    566 // enable shutter sound
    567 status_t CameraClient::enableShutterSound(bool enable) {
    568     LOG1("enableShutterSound (pid %d)", getCallingPid());
    569 
    570     status_t result = checkPidAndHardware();
    571     if (result != NO_ERROR) return result;
    572 
    573     if (enable) {
    574         mPlayShutterSound = true;
    575         return OK;
    576     }
    577 
    578     // Disabling shutter sound may not be allowed. In that case only
    579     // allow the mediaserver process to disable the sound.
    580     char value[PROPERTY_VALUE_MAX];
    581     property_get("ro.camera.sound.forced", value, "0");
    582     if (strcmp(value, "0") != 0) {
    583         // Disabling shutter sound is not allowed. Deny if the current
    584         // process is not mediaserver.
    585         if (getCallingPid() != getpid()) {
    586             ALOGE("Failed to disable shutter sound. Permission denied (pid %d)", getCallingPid());
    587             return PERMISSION_DENIED;
    588         }
    589     }
    590 
    591     mPlayShutterSound = false;
    592     return OK;
    593 }
    594 
    595 status_t CameraClient::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
    596     LOG1("sendCommand (pid %d)", getCallingPid());
    597     int orientation;
    598     Mutex::Autolock lock(mLock);
    599     status_t result = checkPidAndHardware();
    600     if (result != NO_ERROR) return result;
    601 
    602     if (cmd == CAMERA_CMD_SET_DISPLAY_ORIENTATION) {
    603         // Mirror the preview if the camera is front-facing.
    604         orientation = getOrientation(arg1, mCameraFacing == CAMERA_FACING_FRONT);
    605         if (orientation == -1) return BAD_VALUE;
    606 
    607         if (mOrientation != orientation) {
    608             mOrientation = orientation;
    609             if (mPreviewWindow != 0) {
    610                 native_window_set_buffers_transform(mPreviewWindow.get(),
    611                         mOrientation);
    612             }
    613         }
    614         return OK;
    615     } else if (cmd == CAMERA_CMD_ENABLE_SHUTTER_SOUND) {
    616         switch (arg1) {
    617             case 0:
    618                 return enableShutterSound(false);
    619             case 1:
    620                 return enableShutterSound(true);
    621             default:
    622                 return BAD_VALUE;
    623         }
    624         return OK;
    625     } else if (cmd == CAMERA_CMD_PLAY_RECORDING_SOUND) {
    626         mCameraService->playSound(CameraService::SOUND_RECORDING);
    627     } else if (cmd == CAMERA_CMD_SET_VIDEO_BUFFER_COUNT) {
    628         // Silently ignore this command
    629         return INVALID_OPERATION;
    630     } else if (cmd == CAMERA_CMD_PING) {
    631         // If mHardware is 0, checkPidAndHardware will return error.
    632         return OK;
    633     }
    634 
    635     return mHardware->sendCommand(cmd, arg1, arg2);
    636 }
    637 
    638 // ----------------------------------------------------------------------------
    639 
    640 void CameraClient::enableMsgType(int32_t msgType) {
    641     android_atomic_or(msgType, &mMsgEnabled);
    642     mHardware->enableMsgType(msgType);
    643 }
    644 
    645 void CameraClient::disableMsgType(int32_t msgType) {
    646     android_atomic_and(~msgType, &mMsgEnabled);
    647     mHardware->disableMsgType(msgType);
    648 }
    649 
    650 #define CHECK_MESSAGE_INTERVAL 10 // 10ms
    651 bool CameraClient::lockIfMessageWanted(int32_t msgType) {
    652     int sleepCount = 0;
    653     while (mMsgEnabled & msgType) {
    654         if (mLock.tryLock() == NO_ERROR) {
    655             if (sleepCount > 0) {
    656                 LOG1("lockIfMessageWanted(%d): waited for %d ms",
    657                     msgType, sleepCount * CHECK_MESSAGE_INTERVAL);
    658             }
    659             return true;
    660         }
    661         if (sleepCount++ == 0) {
    662             LOG1("lockIfMessageWanted(%d): enter sleep", msgType);
    663         }
    664         usleep(CHECK_MESSAGE_INTERVAL * 1000);
    665     }
    666     ALOGW("lockIfMessageWanted(%d): dropped unwanted message", msgType);
    667     return false;
    668 }
    669 
    670 // Callback messages can be dispatched to internal handlers or pass to our
    671 // client's callback functions, depending on the message type.
    672 //
    673 // notifyCallback:
    674 //      CAMERA_MSG_SHUTTER              handleShutter
    675 //      (others)                        c->notifyCallback
    676 // dataCallback:
    677 //      CAMERA_MSG_PREVIEW_FRAME        handlePreviewData
    678 //      CAMERA_MSG_POSTVIEW_FRAME       handlePostview
    679 //      CAMERA_MSG_RAW_IMAGE            handleRawPicture
    680 //      CAMERA_MSG_COMPRESSED_IMAGE     handleCompressedPicture
    681 //      (others)                        c->dataCallback
    682 // dataCallbackTimestamp
    683 //      (others)                        c->dataCallbackTimestamp
    684 //
    685 // NOTE: the *Callback functions grab mLock of the client before passing
    686 // control to handle* functions. So the handle* functions must release the
    687 // lock before calling the ICameraClient's callbacks, so those callbacks can
    688 // invoke methods in the Client class again (For example, the preview frame
    689 // callback may want to releaseRecordingFrame). The handle* functions must
    690 // release the lock after all accesses to member variables, so it must be
    691 // handled very carefully.
    692 
    693 void CameraClient::notifyCallback(int32_t msgType, int32_t ext1,
    694         int32_t ext2, void* user) {
    695     LOG2("notifyCallback(%d)", msgType);
    696 
    697     Mutex* lock = getClientLockFromCookie(user);
    698     if (lock == NULL) return;
    699     Mutex::Autolock alock(*lock);
    700 
    701     CameraClient* client =
    702             static_cast<CameraClient*>(getClientFromCookie(user));
    703     if (client == NULL) return;
    704 
    705     if (!client->lockIfMessageWanted(msgType)) return;
    706 
    707     switch (msgType) {
    708         case CAMERA_MSG_SHUTTER:
    709             // ext1 is the dimension of the yuv picture.
    710             client->handleShutter();
    711             break;
    712         default:
    713             client->handleGenericNotify(msgType, ext1, ext2);
    714             break;
    715     }
    716 }
    717 
    718 void CameraClient::dataCallback(int32_t msgType,
    719         const sp<IMemory>& dataPtr, camera_frame_metadata_t *metadata, void* user) {
    720     LOG2("dataCallback(%d)", msgType);
    721 
    722     Mutex* lock = getClientLockFromCookie(user);
    723     if (lock == NULL) return;
    724     Mutex::Autolock alock(*lock);
    725 
    726     CameraClient* client =
    727             static_cast<CameraClient*>(getClientFromCookie(user));
    728     if (client == NULL) return;
    729 
    730     if (!client->lockIfMessageWanted(msgType)) return;
    731     if (dataPtr == 0 && metadata == NULL) {
    732         ALOGE("Null data returned in data callback");
    733         client->handleGenericNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
    734         return;
    735     }
    736 
    737     switch (msgType & ~CAMERA_MSG_PREVIEW_METADATA) {
    738         case CAMERA_MSG_PREVIEW_FRAME:
    739             client->handlePreviewData(msgType, dataPtr, metadata);
    740             break;
    741         case CAMERA_MSG_POSTVIEW_FRAME:
    742             client->handlePostview(dataPtr);
    743             break;
    744         case CAMERA_MSG_RAW_IMAGE:
    745             client->handleRawPicture(dataPtr);
    746             break;
    747         case CAMERA_MSG_COMPRESSED_IMAGE:
    748             client->handleCompressedPicture(dataPtr);
    749             break;
    750         default:
    751             client->handleGenericData(msgType, dataPtr, metadata);
    752             break;
    753     }
    754 }
    755 
    756 void CameraClient::dataCallbackTimestamp(nsecs_t timestamp,
    757         int32_t msgType, const sp<IMemory>& dataPtr, void* user) {
    758     LOG2("dataCallbackTimestamp(%d)", msgType);
    759 
    760     Mutex* lock = getClientLockFromCookie(user);
    761     if (lock == NULL) return;
    762     Mutex::Autolock alock(*lock);
    763 
    764     CameraClient* client =
    765             static_cast<CameraClient*>(getClientFromCookie(user));
    766     if (client == NULL) return;
    767 
    768     if (!client->lockIfMessageWanted(msgType)) return;
    769 
    770     if (dataPtr == 0) {
    771         ALOGE("Null data returned in data with timestamp callback");
    772         client->handleGenericNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
    773         return;
    774     }
    775 
    776     client->handleGenericDataTimestamp(timestamp, msgType, dataPtr);
    777 }
    778 
    779 // snapshot taken callback
    780 void CameraClient::handleShutter(void) {
    781     if (mPlayShutterSound) {
    782         mCameraService->playSound(CameraService::SOUND_SHUTTER);
    783     }
    784 
    785     sp<ICameraClient> c = mRemoteCallback;
    786     if (c != 0) {
    787         mLock.unlock();
    788         c->notifyCallback(CAMERA_MSG_SHUTTER, 0, 0);
    789         if (!lockIfMessageWanted(CAMERA_MSG_SHUTTER)) return;
    790     }
    791     disableMsgType(CAMERA_MSG_SHUTTER);
    792 
    793     mLock.unlock();
    794 }
    795 
    796 // preview callback - frame buffer update
    797 void CameraClient::handlePreviewData(int32_t msgType,
    798                                               const sp<IMemory>& mem,
    799                                               camera_frame_metadata_t *metadata) {
    800     ssize_t offset;
    801     size_t size;
    802     sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
    803 
    804     // local copy of the callback flags
    805     int flags = mPreviewCallbackFlag;
    806 
    807     // is callback enabled?
    808     if (!(flags & CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK)) {
    809         // If the enable bit is off, the copy-out and one-shot bits are ignored
    810         LOG2("frame callback is disabled");
    811         mLock.unlock();
    812         return;
    813     }
    814 
    815     // hold a strong pointer to the client
    816     sp<ICameraClient> c = mRemoteCallback;
    817 
    818     // clear callback flags if no client or one-shot mode
    819     if (c == 0 || (mPreviewCallbackFlag & CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK)) {
    820         LOG2("Disable preview callback");
    821         mPreviewCallbackFlag &= ~(CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK |
    822                                   CAMERA_FRAME_CALLBACK_FLAG_COPY_OUT_MASK |
    823                                   CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK);
    824         disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
    825     }
    826 
    827     if (c != 0) {
    828         // Is the received frame copied out or not?
    829         if (flags & CAMERA_FRAME_CALLBACK_FLAG_COPY_OUT_MASK) {
    830             LOG2("frame is copied");
    831             copyFrameAndPostCopiedFrame(msgType, c, heap, offset, size, metadata);
    832         } else {
    833             LOG2("frame is forwarded");
    834             mLock.unlock();
    835             c->dataCallback(msgType, mem, metadata);
    836         }
    837     } else {
    838         mLock.unlock();
    839     }
    840 }
    841 
    842 // picture callback - postview image ready
    843 void CameraClient::handlePostview(const sp<IMemory>& mem) {
    844     disableMsgType(CAMERA_MSG_POSTVIEW_FRAME);
    845 
    846     sp<ICameraClient> c = mRemoteCallback;
    847     mLock.unlock();
    848     if (c != 0) {
    849         c->dataCallback(CAMERA_MSG_POSTVIEW_FRAME, mem, NULL);
    850     }
    851 }
    852 
    853 // picture callback - raw image ready
    854 void CameraClient::handleRawPicture(const sp<IMemory>& mem) {
    855     disableMsgType(CAMERA_MSG_RAW_IMAGE);
    856 
    857     ssize_t offset;
    858     size_t size;
    859     sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
    860 
    861     sp<ICameraClient> c = mRemoteCallback;
    862     mLock.unlock();
    863     if (c != 0) {
    864         c->dataCallback(CAMERA_MSG_RAW_IMAGE, mem, NULL);
    865     }
    866 }
    867 
    868 // picture callback - compressed picture ready
    869 void CameraClient::handleCompressedPicture(const sp<IMemory>& mem) {
    870     disableMsgType(CAMERA_MSG_COMPRESSED_IMAGE);
    871 
    872     sp<ICameraClient> c = mRemoteCallback;
    873     mLock.unlock();
    874     if (c != 0) {
    875         c->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE, mem, NULL);
    876     }
    877 }
    878 
    879 
    880 void CameraClient::handleGenericNotify(int32_t msgType,
    881     int32_t ext1, int32_t ext2) {
    882     sp<ICameraClient> c = mRemoteCallback;
    883     mLock.unlock();
    884     if (c != 0) {
    885         c->notifyCallback(msgType, ext1, ext2);
    886     }
    887 }
    888 
    889 void CameraClient::handleGenericData(int32_t msgType,
    890     const sp<IMemory>& dataPtr, camera_frame_metadata_t *metadata) {
    891     sp<ICameraClient> c = mRemoteCallback;
    892     mLock.unlock();
    893     if (c != 0) {
    894         c->dataCallback(msgType, dataPtr, metadata);
    895     }
    896 }
    897 
    898 void CameraClient::handleGenericDataTimestamp(nsecs_t timestamp,
    899     int32_t msgType, const sp<IMemory>& dataPtr) {
    900     sp<ICameraClient> c = mRemoteCallback;
    901     mLock.unlock();
    902     if (c != 0) {
    903         c->dataCallbackTimestamp(timestamp, msgType, dataPtr);
    904     }
    905 }
    906 
    907 void CameraClient::copyFrameAndPostCopiedFrame(
    908         int32_t msgType, const sp<ICameraClient>& client,
    909         const sp<IMemoryHeap>& heap, size_t offset, size_t size,
    910         camera_frame_metadata_t *metadata) {
    911     LOG2("copyFrameAndPostCopiedFrame");
    912     // It is necessary to copy out of pmem before sending this to
    913     // the callback. For efficiency, reuse the same MemoryHeapBase
    914     // provided it's big enough. Don't allocate the memory or
    915     // perform the copy if there's no callback.
    916     // hold the preview lock while we grab a reference to the preview buffer
    917     sp<MemoryHeapBase> previewBuffer;
    918 
    919     if (mPreviewBuffer == 0) {
    920         mPreviewBuffer = new MemoryHeapBase(size, 0, NULL);
    921     } else if (size > mPreviewBuffer->virtualSize()) {
    922         mPreviewBuffer.clear();
    923         mPreviewBuffer = new MemoryHeapBase(size, 0, NULL);
    924     }
    925     if (mPreviewBuffer == 0) {
    926         ALOGE("failed to allocate space for preview buffer");
    927         mLock.unlock();
    928         return;
    929     }
    930     previewBuffer = mPreviewBuffer;
    931 
    932     memcpy(previewBuffer->base(), (uint8_t *)heap->base() + offset, size);
    933 
    934     sp<MemoryBase> frame = new MemoryBase(previewBuffer, 0, size);
    935     if (frame == 0) {
    936         ALOGE("failed to allocate space for frame callback");
    937         mLock.unlock();
    938         return;
    939     }
    940 
    941     mLock.unlock();
    942     client->dataCallback(msgType, frame, metadata);
    943 }
    944 
    945 int CameraClient::getOrientation(int degrees, bool mirror) {
    946     if (!mirror) {
    947         if (degrees == 0) return 0;
    948         else if (degrees == 90) return HAL_TRANSFORM_ROT_90;
    949         else if (degrees == 180) return HAL_TRANSFORM_ROT_180;
    950         else if (degrees == 270) return HAL_TRANSFORM_ROT_270;
    951     } else {  // Do mirror (horizontal flip)
    952         if (degrees == 0) {           // FLIP_H and ROT_0
    953             return HAL_TRANSFORM_FLIP_H;
    954         } else if (degrees == 90) {   // FLIP_H and ROT_90
    955             return HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90;
    956         } else if (degrees == 180) {  // FLIP_H and ROT_180
    957             return HAL_TRANSFORM_FLIP_V;
    958         } else if (degrees == 270) {  // FLIP_H and ROT_270
    959             return HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90;
    960         }
    961     }
    962     ALOGE("Invalid setDisplayOrientation degrees=%d", degrees);
    963     return -1;
    964 }
    965 
    966 }; // namespace android
    967