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