Home | History | Annotate | Download | only in camera
      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_NDEBUG 0
     19 #define LOG_TAG "Camera"
     20 #include <utils/Log.h>
     21 #include <utils/threads.h>
     22 #include <binder/IPCThreadState.h>
     23 #include <binder/IServiceManager.h>
     24 #include <binder/IMemory.h>
     25 
     26 #include <camera/Camera.h>
     27 #include <camera/ICameraRecordingProxyListener.h>
     28 #include <camera/ICameraService.h>
     29 
     30 #include <gui/ISurfaceTexture.h>
     31 #include <gui/Surface.h>
     32 
     33 namespace android {
     34 
     35 // client singleton for camera service binder interface
     36 Mutex Camera::mLock;
     37 sp<ICameraService> Camera::mCameraService;
     38 sp<Camera::DeathNotifier> Camera::mDeathNotifier;
     39 
     40 // establish binder interface to camera service
     41 const sp<ICameraService>& Camera::getCameraService()
     42 {
     43     Mutex::Autolock _l(mLock);
     44     if (mCameraService.get() == 0) {
     45         sp<IServiceManager> sm = defaultServiceManager();
     46         sp<IBinder> binder;
     47         do {
     48             binder = sm->getService(String16("media.camera"));
     49             if (binder != 0)
     50                 break;
     51             ALOGW("CameraService not published, waiting...");
     52             usleep(500000); // 0.5 s
     53         } while(true);
     54         if (mDeathNotifier == NULL) {
     55             mDeathNotifier = new DeathNotifier();
     56         }
     57         binder->linkToDeath(mDeathNotifier);
     58         mCameraService = interface_cast<ICameraService>(binder);
     59     }
     60     ALOGE_IF(mCameraService==0, "no CameraService!?");
     61     return mCameraService;
     62 }
     63 
     64 // ---------------------------------------------------------------------------
     65 
     66 Camera::Camera()
     67 {
     68     init();
     69 }
     70 
     71 // construct a camera client from an existing camera remote
     72 sp<Camera> Camera::create(const sp<ICamera>& camera)
     73 {
     74      ALOGV("create");
     75      if (camera == 0) {
     76          ALOGE("camera remote is a NULL pointer");
     77          return 0;
     78      }
     79 
     80     sp<Camera> c = new Camera();
     81     if (camera->connect(c) == NO_ERROR) {
     82         c->mStatus = NO_ERROR;
     83         c->mCamera = camera;
     84         camera->asBinder()->linkToDeath(c);
     85         return c;
     86     }
     87     return 0;
     88 }
     89 
     90 void Camera::init()
     91 {
     92     mStatus = UNKNOWN_ERROR;
     93 }
     94 
     95 Camera::~Camera()
     96 {
     97     // We don't need to call disconnect() here because if the CameraService
     98     // thinks we are the owner of the hardware, it will hold a (strong)
     99     // reference to us, and we can't possibly be here. We also don't want to
    100     // call disconnect() here if we are in the same process as mediaserver,
    101     // because we may be invoked by CameraService::Client::connect() and will
    102     // deadlock if we call any method of ICamera here.
    103 }
    104 
    105 int32_t Camera::getNumberOfCameras()
    106 {
    107     const sp<ICameraService>& cs = getCameraService();
    108     if (cs == 0) return 0;
    109     return cs->getNumberOfCameras();
    110 }
    111 
    112 status_t Camera::getCameraInfo(int cameraId,
    113                                struct CameraInfo* cameraInfo) {
    114     const sp<ICameraService>& cs = getCameraService();
    115     if (cs == 0) return UNKNOWN_ERROR;
    116     return cs->getCameraInfo(cameraId, cameraInfo);
    117 }
    118 
    119 sp<Camera> Camera::connect(int cameraId)
    120 {
    121     ALOGV("connect");
    122     sp<Camera> c = new Camera();
    123     const sp<ICameraService>& cs = getCameraService();
    124     if (cs != 0) {
    125         c->mCamera = cs->connect(c, cameraId);
    126     }
    127     if (c->mCamera != 0) {
    128         c->mCamera->asBinder()->linkToDeath(c);
    129         c->mStatus = NO_ERROR;
    130     } else {
    131         c.clear();
    132     }
    133     return c;
    134 }
    135 
    136 void Camera::disconnect()
    137 {
    138     ALOGV("disconnect");
    139     if (mCamera != 0) {
    140         mCamera->disconnect();
    141         mCamera->asBinder()->unlinkToDeath(this);
    142         mCamera = 0;
    143     }
    144 }
    145 
    146 status_t Camera::reconnect()
    147 {
    148     ALOGV("reconnect");
    149     sp <ICamera> c = mCamera;
    150     if (c == 0) return NO_INIT;
    151     return c->connect(this);
    152 }
    153 
    154 sp<ICamera> Camera::remote()
    155 {
    156     return mCamera;
    157 }
    158 
    159 status_t Camera::lock()
    160 {
    161     sp <ICamera> c = mCamera;
    162     if (c == 0) return NO_INIT;
    163     return c->lock();
    164 }
    165 
    166 status_t Camera::unlock()
    167 {
    168     sp <ICamera> c = mCamera;
    169     if (c == 0) return NO_INIT;
    170     return c->unlock();
    171 }
    172 
    173 // pass the buffered Surface to the camera service
    174 status_t Camera::setPreviewDisplay(const sp<Surface>& surface)
    175 {
    176     ALOGV("setPreviewDisplay(%p)", surface.get());
    177     sp <ICamera> c = mCamera;
    178     if (c == 0) return NO_INIT;
    179     if (surface != 0) {
    180         return c->setPreviewDisplay(surface);
    181     } else {
    182         ALOGD("app passed NULL surface");
    183         return c->setPreviewDisplay(0);
    184     }
    185 }
    186 
    187 // pass the buffered ISurfaceTexture to the camera service
    188 status_t Camera::setPreviewTexture(const sp<ISurfaceTexture>& surfaceTexture)
    189 {
    190     ALOGV("setPreviewTexture(%p)", surfaceTexture.get());
    191     sp <ICamera> c = mCamera;
    192     if (c == 0) return NO_INIT;
    193     if (surfaceTexture != 0) {
    194         return c->setPreviewTexture(surfaceTexture);
    195     } else {
    196         ALOGD("app passed NULL surface");
    197         return c->setPreviewTexture(0);
    198     }
    199 }
    200 
    201 // start preview mode
    202 status_t Camera::startPreview()
    203 {
    204     ALOGV("startPreview");
    205     sp <ICamera> c = mCamera;
    206     if (c == 0) return NO_INIT;
    207     return c->startPreview();
    208 }
    209 
    210 status_t Camera::storeMetaDataInBuffers(bool enabled)
    211 {
    212     ALOGV("storeMetaDataInBuffers: %s",
    213             enabled? "true": "false");
    214     sp <ICamera> c = mCamera;
    215     if (c == 0) return NO_INIT;
    216     return c->storeMetaDataInBuffers(enabled);
    217 }
    218 
    219 // start recording mode, must call setPreviewDisplay first
    220 status_t Camera::startRecording()
    221 {
    222     ALOGV("startRecording");
    223     sp <ICamera> c = mCamera;
    224     if (c == 0) return NO_INIT;
    225     return c->startRecording();
    226 }
    227 
    228 // stop preview mode
    229 void Camera::stopPreview()
    230 {
    231     ALOGV("stopPreview");
    232     sp <ICamera> c = mCamera;
    233     if (c == 0) return;
    234     c->stopPreview();
    235 }
    236 
    237 // stop recording mode
    238 void Camera::stopRecording()
    239 {
    240     ALOGV("stopRecording");
    241     {
    242         Mutex::Autolock _l(mLock);
    243         mRecordingProxyListener.clear();
    244     }
    245     sp <ICamera> c = mCamera;
    246     if (c == 0) return;
    247     c->stopRecording();
    248 }
    249 
    250 // release a recording frame
    251 void Camera::releaseRecordingFrame(const sp<IMemory>& mem)
    252 {
    253     ALOGV("releaseRecordingFrame");
    254     sp <ICamera> c = mCamera;
    255     if (c == 0) return;
    256     c->releaseRecordingFrame(mem);
    257 }
    258 
    259 // get preview state
    260 bool Camera::previewEnabled()
    261 {
    262     ALOGV("previewEnabled");
    263     sp <ICamera> c = mCamera;
    264     if (c == 0) return false;
    265     return c->previewEnabled();
    266 }
    267 
    268 // get recording state
    269 bool Camera::recordingEnabled()
    270 {
    271     ALOGV("recordingEnabled");
    272     sp <ICamera> c = mCamera;
    273     if (c == 0) return false;
    274     return c->recordingEnabled();
    275 }
    276 
    277 status_t Camera::autoFocus()
    278 {
    279     ALOGV("autoFocus");
    280     sp <ICamera> c = mCamera;
    281     if (c == 0) return NO_INIT;
    282     return c->autoFocus();
    283 }
    284 
    285 status_t Camera::cancelAutoFocus()
    286 {
    287     ALOGV("cancelAutoFocus");
    288     sp <ICamera> c = mCamera;
    289     if (c == 0) return NO_INIT;
    290     return c->cancelAutoFocus();
    291 }
    292 
    293 // take a picture
    294 status_t Camera::takePicture(int msgType)
    295 {
    296     ALOGV("takePicture: 0x%x", msgType);
    297     sp <ICamera> c = mCamera;
    298     if (c == 0) return NO_INIT;
    299     return c->takePicture(msgType);
    300 }
    301 
    302 // set preview/capture parameters - key/value pairs
    303 status_t Camera::setParameters(const String8& params)
    304 {
    305     ALOGV("setParameters");
    306     sp <ICamera> c = mCamera;
    307     if (c == 0) return NO_INIT;
    308     return c->setParameters(params);
    309 }
    310 
    311 // get preview/capture parameters - key/value pairs
    312 String8 Camera::getParameters() const
    313 {
    314     ALOGV("getParameters");
    315     String8 params;
    316     sp <ICamera> c = mCamera;
    317     if (c != 0) params = mCamera->getParameters();
    318     return params;
    319 }
    320 
    321 // send command to camera driver
    322 status_t Camera::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
    323 {
    324     ALOGV("sendCommand");
    325     sp <ICamera> c = mCamera;
    326     if (c == 0) return NO_INIT;
    327     return c->sendCommand(cmd, arg1, arg2);
    328 }
    329 
    330 void Camera::setListener(const sp<CameraListener>& listener)
    331 {
    332     Mutex::Autolock _l(mLock);
    333     mListener = listener;
    334 }
    335 
    336 void Camera::setRecordingProxyListener(const sp<ICameraRecordingProxyListener>& listener)
    337 {
    338     Mutex::Autolock _l(mLock);
    339     mRecordingProxyListener = listener;
    340 }
    341 
    342 void Camera::setPreviewCallbackFlags(int flag)
    343 {
    344     ALOGV("setPreviewCallbackFlags");
    345     sp <ICamera> c = mCamera;
    346     if (c == 0) return;
    347     mCamera->setPreviewCallbackFlag(flag);
    348 }
    349 
    350 // callback from camera service
    351 void Camera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2)
    352 {
    353     sp<CameraListener> listener;
    354     {
    355         Mutex::Autolock _l(mLock);
    356         listener = mListener;
    357     }
    358     if (listener != NULL) {
    359         listener->notify(msgType, ext1, ext2);
    360     }
    361 }
    362 
    363 // callback from camera service when frame or image is ready
    364 void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr,
    365                           camera_frame_metadata_t *metadata)
    366 {
    367     sp<CameraListener> listener;
    368     {
    369         Mutex::Autolock _l(mLock);
    370         listener = mListener;
    371     }
    372     if (listener != NULL) {
    373         listener->postData(msgType, dataPtr, metadata);
    374     }
    375 }
    376 
    377 // callback from camera service when timestamped frame is ready
    378 void Camera::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr)
    379 {
    380     // If recording proxy listener is registered, forward the frame and return.
    381     // The other listener (mListener) is ignored because the receiver needs to
    382     // call releaseRecordingFrame.
    383     sp<ICameraRecordingProxyListener> proxylistener;
    384     {
    385         Mutex::Autolock _l(mLock);
    386         proxylistener = mRecordingProxyListener;
    387     }
    388     if (proxylistener != NULL) {
    389         proxylistener->dataCallbackTimestamp(timestamp, msgType, dataPtr);
    390         return;
    391     }
    392 
    393     sp<CameraListener> listener;
    394     {
    395         Mutex::Autolock _l(mLock);
    396         listener = mListener;
    397     }
    398     if (listener != NULL) {
    399         listener->postDataTimestamp(timestamp, msgType, dataPtr);
    400     } else {
    401         ALOGW("No listener was set. Drop a recording frame.");
    402         releaseRecordingFrame(dataPtr);
    403     }
    404 }
    405 
    406 void Camera::binderDied(const wp<IBinder>& who) {
    407     ALOGW("ICamera died");
    408     notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_SERVER_DIED, 0);
    409 }
    410 
    411 void Camera::DeathNotifier::binderDied(const wp<IBinder>& who) {
    412     ALOGV("binderDied");
    413     Mutex::Autolock _l(Camera::mLock);
    414     Camera::mCameraService.clear();
    415     ALOGW("Camera server died!");
    416 }
    417 
    418 sp<ICameraRecordingProxy> Camera::getRecordingProxy() {
    419     ALOGV("getProxy");
    420     return new RecordingProxy(this);
    421 }
    422 
    423 status_t Camera::RecordingProxy::startRecording(const sp<ICameraRecordingProxyListener>& listener)
    424 {
    425     ALOGV("RecordingProxy::startRecording");
    426     mCamera->setRecordingProxyListener(listener);
    427     mCamera->reconnect();
    428     return mCamera->startRecording();
    429 }
    430 
    431 void Camera::RecordingProxy::stopRecording()
    432 {
    433     ALOGV("RecordingProxy::stopRecording");
    434     mCamera->stopRecording();
    435 }
    436 
    437 void Camera::RecordingProxy::releaseRecordingFrame(const sp<IMemory>& mem)
    438 {
    439     ALOGV("RecordingProxy::releaseRecordingFrame");
    440     mCamera->releaseRecordingFrame(mem);
    441 }
    442 
    443 Camera::RecordingProxy::RecordingProxy(const sp<Camera>& camera)
    444 {
    445     mCamera = camera;
    446 }
    447 
    448 }; // namespace android
    449