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