Home | History | Annotate | Download | only in camera
      1 /*
      2  * Copyright (C) 2011 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 /*
     18  * Contains implementation of a class EmulatedCamera that encapsulates
     19  * functionality common to all emulated cameras ("fake", "webcam", "video file",
     20  * etc.). Instances of this class (for each emulated camera) are created during
     21  * the construction of the EmulatedCameraFactory instance. This class serves as
     22  * an entry point for all camera API calls that defined by camera_device_ops_t
     23  * API.
     24  */
     25 
     26 #define LOG_NDEBUG 0
     27 #define LOG_TAG "EmulatedCamera_Camera"
     28 #include <cutils/log.h>
     29 #include <ui/Rect.h>
     30 #include "EmulatedCamera.h"
     31 #include "EmulatedFakeCameraDevice.h"
     32 #include "Converters.h"
     33 
     34 /* Defines whether we should trace parameter changes. */
     35 #define DEBUG_PARAM 1
     36 
     37 namespace android {
     38 
     39 #if DEBUG_PARAM
     40 /* Calculates and logs parameter changes.
     41  * Param:
     42  *  current - Current set of camera parameters.
     43  *  new_par - String representation of new parameters.
     44  */
     45 static void PrintParamDiff(const CameraParameters& current, const char* new_par);
     46 #else
     47 #define PrintParamDiff(current, new_par)   (void(0))
     48 #endif  /* DEBUG_PARAM */
     49 
     50 /* A helper routine that adds a value to the camera parameter.
     51  * Param:
     52  *  param - Camera parameter to add a value to.
     53  *  val - Value to add.
     54  * Return:
     55  *  A new string containing parameter with the added value on success, or NULL on
     56  *  a failure. If non-NULL string is returned, the caller is responsible for
     57  *  freeing it with 'free'.
     58  */
     59 static char* AddValue(const char* param, const char* val);
     60 
     61 EmulatedCamera::EmulatedCamera(int cameraId, struct hw_module_t* module)
     62         : mPreviewWindow(),
     63           mCallbackNotifier(),
     64           mCameraID(cameraId)
     65 {
     66     /*
     67      * Initialize camera_device descriptor for this object.
     68      */
     69 
     70     /* Common header */
     71     common.tag = HARDWARE_DEVICE_TAG;
     72     common.version = 0;
     73     common.module = module;
     74     common.close = EmulatedCamera::close;
     75 
     76     /* camera_device fields. */
     77     ops = &mDeviceOps;
     78     priv = this;
     79 }
     80 
     81 EmulatedCamera::~EmulatedCamera()
     82 {
     83 }
     84 
     85 /****************************************************************************
     86  * Public API
     87  ***************************************************************************/
     88 
     89 status_t EmulatedCamera::Initialize()
     90 {
     91     /* Preview formats supported by this HAL. */
     92     char preview_formats[1024];
     93     snprintf(preview_formats, sizeof(preview_formats), "%s,%s,%s",
     94              CameraParameters::PIXEL_FORMAT_YUV420SP,
     95              CameraParameters::PIXEL_FORMAT_YUV420P,
     96              CameraParameters::PIXEL_FORMAT_RGBA8888);
     97 
     98     /*
     99      * Fake required parameters.
    100      */
    101 
    102     mParameters.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES,
    103                     "320x240,0x0");
    104     mParameters.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION, "6");
    105     mParameters.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION, "-6");
    106     mParameters.set(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP, "0.5");
    107     mParameters.set(CameraParameters::KEY_EXPOSURE_COMPENSATION, "0");
    108     mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, "512");
    109     mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, "384");
    110     mParameters.set(CameraParameters::KEY_JPEG_QUALITY, "90");
    111     mParameters.set(CameraParameters::KEY_FOCAL_LENGTH, "4.31");
    112     mParameters.set(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, "54.8");
    113     mParameters.set(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, "42.5");
    114     mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, "90");
    115 
    116     /* Preview format settings used here are related to panoramic view only. It's
    117      * not related to the preview window that works only with RGB frames, which
    118      * is explicitly stated when set_buffers_geometry is called on the preview
    119      * window object. */
    120     mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
    121                     preview_formats);
    122     mParameters.setPreviewFormat(CameraParameters::PIXEL_FORMAT_YUV420SP);
    123 
    124     /* We don't relay on the actual frame rates supported by the camera device,
    125      * since we will emulate them through timeouts in the emulated camera device
    126      * worker thread. */
    127     mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
    128                     "30,24,20,15,10,5");
    129     mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE, "(5,30)");
    130     mParameters.set(CameraParameters::KEY_PREVIEW_FPS_RANGE, "5,30");
    131     mParameters.setPreviewFrameRate(24);
    132 
    133     /* Only PIXEL_FORMAT_YUV420P is accepted by video framework in emulator! */
    134     mParameters.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT,
    135                     CameraParameters::PIXEL_FORMAT_YUV420P);
    136     mParameters.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
    137                     CameraParameters::PIXEL_FORMAT_JPEG);
    138     mParameters.setPictureFormat(CameraParameters::PIXEL_FORMAT_JPEG);
    139 
    140     /*
    141      * Not supported features
    142      */
    143 
    144     mParameters.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
    145                     CameraParameters::FOCUS_MODE_FIXED);
    146     mParameters.set(CameraParameters::KEY_FOCUS_MODE,
    147                     CameraParameters::FOCUS_MODE_FIXED);
    148 
    149     return NO_ERROR;
    150 }
    151 
    152 void EmulatedCamera::onNextFrameAvailable(const void* frame,
    153                                           nsecs_t timestamp,
    154                                           EmulatedCameraDevice* camera_dev)
    155 {
    156     /* Notify the preview window first. */
    157     mPreviewWindow.onNextFrameAvailable(frame, timestamp, camera_dev);
    158 
    159     /* Notify callback notifier next. */
    160     mCallbackNotifier.onNextFrameAvailable(frame, timestamp, camera_dev);
    161 }
    162 
    163 void EmulatedCamera::onCameraDeviceError(int err)
    164 {
    165     /* Errors are reported through the callback notifier */
    166     mCallbackNotifier.onCameraDeviceError(err);
    167 }
    168 
    169 /****************************************************************************
    170  * Camera API implementation.
    171  ***************************************************************************/
    172 
    173 status_t EmulatedCamera::connectCamera(hw_device_t** device)
    174 {
    175     LOGV("%s", __FUNCTION__);
    176 
    177     status_t res = EINVAL;
    178     EmulatedCameraDevice* const camera_dev = getCameraDevice();
    179     LOGE_IF(camera_dev == NULL, "%s: No camera device instance.", __FUNCTION__);
    180 
    181     if (camera_dev != NULL) {
    182         /* Connect to the camera device. */
    183         res = getCameraDevice()->connectDevice();
    184         if (res == NO_ERROR) {
    185             *device = &common;
    186         }
    187     }
    188 
    189     return -res;
    190 }
    191 
    192 status_t EmulatedCamera::closeCamera()
    193 {
    194     LOGV("%s", __FUNCTION__);
    195 
    196     return cleanupCamera();
    197 }
    198 
    199 status_t EmulatedCamera::getCameraInfo(struct camera_info* info)
    200 {
    201     LOGV("%s", __FUNCTION__);
    202 
    203     const char* valstr = NULL;
    204 
    205     valstr = mParameters.get(EmulatedCamera::FACING_KEY);
    206     if (valstr != NULL) {
    207         if (strcmp(valstr, EmulatedCamera::FACING_FRONT) == 0) {
    208             info->facing = CAMERA_FACING_FRONT;
    209         }
    210         else if (strcmp(valstr, EmulatedCamera::FACING_BACK) == 0) {
    211             info->facing = CAMERA_FACING_BACK;
    212         }
    213     } else {
    214         info->facing = CAMERA_FACING_BACK;
    215     }
    216 
    217     valstr = mParameters.get(EmulatedCamera::ORIENTATION_KEY);
    218     if (valstr != NULL) {
    219         info->orientation = atoi(valstr);
    220     } else {
    221         info->orientation = 0;
    222     }
    223 
    224     return NO_ERROR;
    225 }
    226 
    227 status_t EmulatedCamera::setPreviewWindow(struct preview_stream_ops* window)
    228 {
    229     /* Callback should return a negative errno. */
    230     return -mPreviewWindow.setPreviewWindow(window,
    231                                              mParameters.getPreviewFrameRate());
    232 }
    233 
    234 void EmulatedCamera::setCallbacks(camera_notify_callback notify_cb,
    235                                   camera_data_callback data_cb,
    236                                   camera_data_timestamp_callback data_cb_timestamp,
    237                                   camera_request_memory get_memory,
    238                                   void* user)
    239 {
    240     mCallbackNotifier.setCallbacks(notify_cb, data_cb, data_cb_timestamp,
    241                                     get_memory, user);
    242 }
    243 
    244 void EmulatedCamera::enableMsgType(int32_t msg_type)
    245 {
    246     mCallbackNotifier.enableMessage(msg_type);
    247 }
    248 
    249 void EmulatedCamera::disableMsgType(int32_t msg_type)
    250 {
    251     mCallbackNotifier.disableMessage(msg_type);
    252 }
    253 
    254 int EmulatedCamera::isMsgTypeEnabled(int32_t msg_type)
    255 {
    256     return mCallbackNotifier.isMessageEnabled(msg_type);
    257 }
    258 
    259 status_t EmulatedCamera::startPreview()
    260 {
    261     /* Callback should return a negative errno. */
    262     return -doStartPreview();
    263 }
    264 
    265 void EmulatedCamera::stopPreview()
    266 {
    267     doStopPreview();
    268 }
    269 
    270 int EmulatedCamera::isPreviewEnabled()
    271 {
    272     return mPreviewWindow.isPreviewEnabled();
    273 }
    274 
    275 status_t EmulatedCamera::storeMetaDataInBuffers(int enable)
    276 {
    277     /* Callback should return a negative errno. */
    278     return -mCallbackNotifier.storeMetaDataInBuffers(enable);
    279 }
    280 
    281 status_t EmulatedCamera::startRecording()
    282 {
    283     /* Callback should return a negative errno. */
    284     return -mCallbackNotifier.enableVideoRecording(mParameters.getPreviewFrameRate());
    285 }
    286 
    287 void EmulatedCamera::stopRecording()
    288 {
    289     mCallbackNotifier.disableVideoRecording();
    290 }
    291 
    292 int EmulatedCamera::isRecordingEnabled()
    293 {
    294     return mCallbackNotifier.isVideoRecordingEnabled();
    295 }
    296 
    297 void EmulatedCamera::releaseRecordingFrame(const void* opaque)
    298 {
    299     mCallbackNotifier.releaseRecordingFrame(opaque);
    300 }
    301 
    302 status_t EmulatedCamera::setAutoFocus()
    303 {
    304     LOGV("%s", __FUNCTION__);
    305 
    306     /* TODO: Future enhancements. */
    307     return NO_ERROR;
    308 }
    309 
    310 status_t EmulatedCamera::cancelAutoFocus()
    311 {
    312     LOGV("%s", __FUNCTION__);
    313 
    314     /* TODO: Future enhancements. */
    315     return NO_ERROR;
    316 }
    317 
    318 status_t EmulatedCamera::takePicture()
    319 {
    320     LOGV("%s", __FUNCTION__);
    321 
    322     status_t res;
    323     int width, height;
    324     uint32_t org_fmt;
    325 
    326     /* Collect frame info for the picture. */
    327     mParameters.getPictureSize(&width, &height);
    328     const char* pix_fmt = mParameters.getPictureFormat();
    329     if (strcmp(pix_fmt, CameraParameters::PIXEL_FORMAT_YUV420P) == 0) {
    330         org_fmt = V4L2_PIX_FMT_YUV420;
    331     } else if (strcmp(pix_fmt, CameraParameters::PIXEL_FORMAT_RGBA8888) == 0) {
    332         org_fmt = V4L2_PIX_FMT_RGB32;
    333     } else if (strcmp(pix_fmt, CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) {
    334         org_fmt = V4L2_PIX_FMT_NV21;
    335     } else if (strcmp(pix_fmt, CameraParameters::PIXEL_FORMAT_JPEG) == 0) {
    336         /* We only have JPEG converted for NV21 format. */
    337         org_fmt = V4L2_PIX_FMT_NV21;
    338     } else {
    339         LOGE("%s: Unsupported pixel format %s", __FUNCTION__, pix_fmt);
    340         return EINVAL;
    341     }
    342     /* Get JPEG quality. */
    343     int jpeg_quality = mParameters.getInt(CameraParameters::KEY_JPEG_QUALITY);
    344     if (jpeg_quality <= 0) {
    345         jpeg_quality = 90;  /* Fall back to default. */
    346     }
    347 
    348     /*
    349      * Make sure preview is not running, and device is stopped before taking
    350      * picture.
    351      */
    352 
    353     const bool preview_on = mPreviewWindow.isPreviewEnabled();
    354     if (preview_on) {
    355         doStopPreview();
    356     }
    357 
    358     /* Camera device should have been stopped when the shutter message has been
    359      * enabled. */
    360     EmulatedCameraDevice* const camera_dev = getCameraDevice();
    361     if (camera_dev->isStarted()) {
    362         LOGW("%s: Camera device is started", __FUNCTION__);
    363         camera_dev->stopDeliveringFrames();
    364         camera_dev->stopDevice();
    365     }
    366 
    367     /*
    368      * Take the picture now.
    369      */
    370 
    371     /* Start camera device for the picture frame. */
    372     LOGD("Starting camera for picture: %.4s(%s)[%dx%d]",
    373          reinterpret_cast<const char*>(&org_fmt), pix_fmt, width, height);
    374     res = camera_dev->startDevice(width, height, org_fmt);
    375     if (res != NO_ERROR) {
    376         if (preview_on) {
    377             doStartPreview();
    378         }
    379         return res;
    380     }
    381 
    382     /* Deliver one frame only. */
    383     mCallbackNotifier.setJpegQuality(jpeg_quality);
    384     mCallbackNotifier.setTakingPicture(true);
    385     res = camera_dev->startDeliveringFrames(true);
    386     if (res != NO_ERROR) {
    387         mCallbackNotifier.setTakingPicture(false);
    388         if (preview_on) {
    389             doStartPreview();
    390         }
    391     }
    392     return res;
    393 }
    394 
    395 status_t EmulatedCamera::cancelPicture()
    396 {
    397     LOGV("%s", __FUNCTION__);
    398 
    399     return NO_ERROR;
    400 }
    401 
    402 status_t EmulatedCamera::setParameters(const char* parms)
    403 {
    404     LOGV("%s", __FUNCTION__);
    405     PrintParamDiff(mParameters, parms);
    406 
    407     CameraParameters new_param;
    408     String8 str8_param(parms);
    409     new_param.unflatten(str8_param);
    410 
    411     int new_exposure_compensation = new_param.getInt(
    412             CameraParameters::KEY_EXPOSURE_COMPENSATION);
    413     const int min_exposure_compensation = new_param.getInt(
    414             CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION);
    415     const int max_exposure_compensation = new_param.getInt(
    416             CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION);
    417 
    418     // Checks if the exposure compensation change is supported.
    419     if ((min_exposure_compensation != 0) || (max_exposure_compensation != 0)) {
    420         if (new_exposure_compensation > max_exposure_compensation) {
    421             new_exposure_compensation = max_exposure_compensation;
    422         }
    423         if (new_exposure_compensation < min_exposure_compensation) {
    424             new_exposure_compensation = min_exposure_compensation;
    425         }
    426 
    427         const int current_exposure_compensation = mParameters.getInt(
    428                 CameraParameters::KEY_EXPOSURE_COMPENSATION);
    429         if (current_exposure_compensation != new_exposure_compensation) {
    430             const float exposure_value = new_exposure_compensation *
    431                     new_param.getFloat(
    432                             CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP);
    433 
    434             getCameraDevice()->setExposureCompensation(
    435                     exposure_value);
    436         }
    437     }
    438     mParameters = new_param;
    439 
    440     return NO_ERROR;
    441 }
    442 
    443 /* A dumb variable indicating "no params" / error on the exit from
    444  * EmulatedCamera::getParameters(). */
    445 static char lNoParam = '\0';
    446 char* EmulatedCamera::getParameters()
    447 {
    448     String8 params(mParameters.flatten());
    449     char* ret_str =
    450         reinterpret_cast<char*>(malloc(sizeof(char) * (params.length()+1)));
    451     memset(ret_str, 0, params.length()+1);
    452     if (ret_str != NULL) {
    453         strncpy(ret_str, params.string(), params.length()+1);
    454         return ret_str;
    455     } else {
    456         LOGE("%s: Unable to allocate string for %s", __FUNCTION__, params.string());
    457         /* Apparently, we can't return NULL fron this routine. */
    458         return &lNoParam;
    459     }
    460 }
    461 
    462 void EmulatedCamera::putParameters(char* params)
    463 {
    464     /* This method simply frees parameters allocated in getParameters(). */
    465     if (params != NULL && params != &lNoParam) {
    466         free(params);
    467     }
    468 }
    469 
    470 status_t EmulatedCamera::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
    471 {
    472     LOGV("%s: cmd = %d, arg1 = %d, arg2 = %d", __FUNCTION__, cmd, arg1, arg2);
    473 
    474     /* TODO: Future enhancements. */
    475     return 0;
    476 }
    477 
    478 void EmulatedCamera::releaseCamera()
    479 {
    480     LOGV("%s", __FUNCTION__);
    481 
    482     cleanupCamera();
    483 }
    484 
    485 status_t EmulatedCamera::dumpCamera(int fd)
    486 {
    487     LOGV("%s", __FUNCTION__);
    488 
    489     /* TODO: Future enhancements. */
    490     return -EINVAL;
    491 }
    492 
    493 /****************************************************************************
    494  * Preview management.
    495  ***************************************************************************/
    496 
    497 status_t EmulatedCamera::doStartPreview()
    498 {
    499     LOGV("%s", __FUNCTION__);
    500 
    501     EmulatedCameraDevice* camera_dev = getCameraDevice();
    502     if (camera_dev->isStarted()) {
    503         camera_dev->stopDeliveringFrames();
    504         camera_dev->stopDevice();
    505     }
    506 
    507     status_t res = mPreviewWindow.startPreview();
    508     if (res != NO_ERROR) {
    509         return res;
    510     }
    511 
    512     /* Make sure camera device is connected. */
    513     if (!camera_dev->isConnected()) {
    514         res = camera_dev->connectDevice();
    515         if (res != NO_ERROR) {
    516             mPreviewWindow.stopPreview();
    517             return res;
    518         }
    519     }
    520 
    521     int width, height;
    522     /* Lets see what should we use for frame width, and height. */
    523     if (mParameters.get(CameraParameters::KEY_VIDEO_SIZE) != NULL) {
    524         mParameters.getVideoSize(&width, &height);
    525     } else {
    526         mParameters.getPreviewSize(&width, &height);
    527     }
    528     /* Lets see what should we use for the frame pixel format. Note that there
    529      * are two parameters that define pixel formats for frames sent to the
    530      * application via notification callbacks:
    531      * - KEY_VIDEO_FRAME_FORMAT, that is used when recording video, and
    532      * - KEY_PREVIEW_FORMAT, that is used for preview frame notification.
    533      * We choose one or the other, depending on "recording-hint" property set by
    534      * the framework that indicating intention: video, or preview. */
    535     const char* pix_fmt = NULL;
    536     const char* is_video = mParameters.get(EmulatedCamera::RECORDING_HINT_KEY);
    537     if (is_video == NULL) {
    538         is_video = CameraParameters::FALSE;
    539     }
    540     if (strcmp(is_video, CameraParameters::TRUE) == 0) {
    541         /* Video recording is requested. Lets see if video frame format is set. */
    542         pix_fmt = mParameters.get(CameraParameters::KEY_VIDEO_FRAME_FORMAT);
    543     }
    544     /* If this was not video recording, or video frame format is not set, lets
    545      * use preview pixel format for the main framebuffer. */
    546     if (pix_fmt == NULL) {
    547         pix_fmt = mParameters.getPreviewFormat();
    548     }
    549     if (pix_fmt == NULL) {
    550         LOGE("%s: Unable to obtain video format", __FUNCTION__);
    551         mPreviewWindow.stopPreview();
    552         return EINVAL;
    553     }
    554 
    555     /* Convert framework's pixel format to the FOURCC one. */
    556     uint32_t org_fmt;
    557     if (strcmp(pix_fmt, CameraParameters::PIXEL_FORMAT_YUV420P) == 0) {
    558         org_fmt = V4L2_PIX_FMT_YUV420;
    559     } else if (strcmp(pix_fmt, CameraParameters::PIXEL_FORMAT_RGBA8888) == 0) {
    560         org_fmt = V4L2_PIX_FMT_RGB32;
    561     } else if (strcmp(pix_fmt, CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) {
    562         org_fmt = V4L2_PIX_FMT_NV21;
    563     } else {
    564         LOGE("%s: Unsupported pixel format %s", __FUNCTION__, pix_fmt);
    565         mPreviewWindow.stopPreview();
    566         return EINVAL;
    567     }
    568     LOGD("Starting camera: %dx%d -> %.4s(%s)",
    569          width, height, reinterpret_cast<const char*>(&org_fmt), pix_fmt);
    570     res = camera_dev->startDevice(width, height, org_fmt);
    571     if (res != NO_ERROR) {
    572         mPreviewWindow.stopPreview();
    573         return res;
    574     }
    575 
    576     res = camera_dev->startDeliveringFrames(false);
    577     if (res != NO_ERROR) {
    578         camera_dev->stopDevice();
    579         mPreviewWindow.stopPreview();
    580     }
    581 
    582     return res;
    583 }
    584 
    585 status_t EmulatedCamera::doStopPreview()
    586 {
    587     LOGV("%s", __FUNCTION__);
    588 
    589     status_t res = NO_ERROR;
    590     if (mPreviewWindow.isPreviewEnabled()) {
    591         /* Stop the camera. */
    592         if (getCameraDevice()->isStarted()) {
    593             getCameraDevice()->stopDeliveringFrames();
    594             res = getCameraDevice()->stopDevice();
    595         }
    596 
    597         if (res == NO_ERROR) {
    598             /* Disable preview as well. */
    599             mPreviewWindow.stopPreview();
    600         }
    601     }
    602 
    603     return NO_ERROR;
    604 }
    605 
    606 /****************************************************************************
    607  * Private API.
    608  ***************************************************************************/
    609 
    610 status_t EmulatedCamera::cleanupCamera()
    611 {
    612     status_t res = NO_ERROR;
    613 
    614     /* If preview is running - stop it. */
    615     res = doStopPreview();
    616     if (res != NO_ERROR) {
    617         return -res;
    618     }
    619 
    620     /* Stop and disconnect the camera device. */
    621     EmulatedCameraDevice* const camera_dev = getCameraDevice();
    622     if (camera_dev != NULL) {
    623         if (camera_dev->isStarted()) {
    624             camera_dev->stopDeliveringFrames();
    625             res = camera_dev->stopDevice();
    626             if (res != NO_ERROR) {
    627                 return -res;
    628             }
    629         }
    630         if (camera_dev->isConnected()) {
    631             res = camera_dev->disconnectDevice();
    632             if (res != NO_ERROR) {
    633                 return -res;
    634             }
    635         }
    636     }
    637 
    638     mCallbackNotifier.cleanupCBNotifier();
    639 
    640     return NO_ERROR;
    641 }
    642 
    643 /****************************************************************************
    644  * Camera API callbacks as defined by camera_device_ops structure.
    645  *
    646  * Callbacks here simply dispatch the calls to an appropriate method inside
    647  * EmulatedCamera instance, defined by the 'dev' parameter.
    648  ***************************************************************************/
    649 
    650 int EmulatedCamera::set_preview_window(struct camera_device* dev,
    651                                        struct preview_stream_ops* window)
    652 {
    653     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    654     if (ec == NULL) {
    655         LOGE("%s: Unexpected NULL camera device", __FUNCTION__);
    656         return -EINVAL;
    657     }
    658     return ec->setPreviewWindow(window);
    659 }
    660 
    661 void EmulatedCamera::set_callbacks(
    662         struct camera_device* dev,
    663         camera_notify_callback notify_cb,
    664         camera_data_callback data_cb,
    665         camera_data_timestamp_callback data_cb_timestamp,
    666         camera_request_memory get_memory,
    667         void* user)
    668 {
    669     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    670     if (ec == NULL) {
    671         LOGE("%s: Unexpected NULL camera device", __FUNCTION__);
    672         return;
    673     }
    674     ec->setCallbacks(notify_cb, data_cb, data_cb_timestamp, get_memory, user);
    675 }
    676 
    677 void EmulatedCamera::enable_msg_type(struct camera_device* dev, int32_t msg_type)
    678 {
    679     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    680     if (ec == NULL) {
    681         LOGE("%s: Unexpected NULL camera device", __FUNCTION__);
    682         return;
    683     }
    684     ec->enableMsgType(msg_type);
    685 }
    686 
    687 void EmulatedCamera::disable_msg_type(struct camera_device* dev, int32_t msg_type)
    688 {
    689     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    690     if (ec == NULL) {
    691         LOGE("%s: Unexpected NULL camera device", __FUNCTION__);
    692         return;
    693     }
    694     ec->disableMsgType(msg_type);
    695 }
    696 
    697 int EmulatedCamera::msg_type_enabled(struct camera_device* dev, int32_t msg_type)
    698 {
    699     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    700     if (ec == NULL) {
    701         LOGE("%s: Unexpected NULL camera device", __FUNCTION__);
    702         return -EINVAL;
    703     }
    704     return ec->isMsgTypeEnabled(msg_type);
    705 }
    706 
    707 int EmulatedCamera::start_preview(struct camera_device* dev)
    708 {
    709     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    710     if (ec == NULL) {
    711         LOGE("%s: Unexpected NULL camera device", __FUNCTION__);
    712         return -EINVAL;
    713     }
    714     return ec->startPreview();
    715 }
    716 
    717 void EmulatedCamera::stop_preview(struct camera_device* dev)
    718 {
    719     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    720     if (ec == NULL) {
    721         LOGE("%s: Unexpected NULL camera device", __FUNCTION__);
    722         return;
    723     }
    724     ec->stopPreview();
    725 }
    726 
    727 int EmulatedCamera::preview_enabled(struct camera_device* dev)
    728 {
    729     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    730     if (ec == NULL) {
    731         LOGE("%s: Unexpected NULL camera device", __FUNCTION__);
    732         return -EINVAL;
    733     }
    734     return ec->isPreviewEnabled();
    735 }
    736 
    737 int EmulatedCamera::store_meta_data_in_buffers(struct camera_device* dev,
    738                                                int enable)
    739 {
    740     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    741     if (ec == NULL) {
    742         LOGE("%s: Unexpected NULL camera device", __FUNCTION__);
    743         return -EINVAL;
    744     }
    745     return ec->storeMetaDataInBuffers(enable);
    746 }
    747 
    748 int EmulatedCamera::start_recording(struct camera_device* dev)
    749 {
    750     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    751     if (ec == NULL) {
    752         LOGE("%s: Unexpected NULL camera device", __FUNCTION__);
    753         return -EINVAL;
    754     }
    755     return ec->startRecording();
    756 }
    757 
    758 void EmulatedCamera::stop_recording(struct camera_device* dev)
    759 {
    760     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    761     if (ec == NULL) {
    762         LOGE("%s: Unexpected NULL camera device", __FUNCTION__);
    763         return;
    764     }
    765     ec->stopRecording();
    766 }
    767 
    768 int EmulatedCamera::recording_enabled(struct camera_device* dev)
    769 {
    770     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    771     if (ec == NULL) {
    772         LOGE("%s: Unexpected NULL camera device", __FUNCTION__);
    773         return -EINVAL;
    774     }
    775     return ec->isRecordingEnabled();
    776 }
    777 
    778 void EmulatedCamera::release_recording_frame(struct camera_device* dev,
    779                                              const void* opaque)
    780 {
    781     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    782     if (ec == NULL) {
    783         LOGE("%s: Unexpected NULL camera device", __FUNCTION__);
    784         return;
    785     }
    786     ec->releaseRecordingFrame(opaque);
    787 }
    788 
    789 int EmulatedCamera::auto_focus(struct camera_device* dev)
    790 {
    791     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    792     if (ec == NULL) {
    793         LOGE("%s: Unexpected NULL camera device", __FUNCTION__);
    794         return -EINVAL;
    795     }
    796     return ec->setAutoFocus();
    797 }
    798 
    799 int EmulatedCamera::cancel_auto_focus(struct camera_device* dev)
    800 {
    801     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    802     if (ec == NULL) {
    803         LOGE("%s: Unexpected NULL camera device", __FUNCTION__);
    804         return -EINVAL;
    805     }
    806     return ec->cancelAutoFocus();
    807 }
    808 
    809 int EmulatedCamera::take_picture(struct camera_device* dev)
    810 {
    811     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    812     if (ec == NULL) {
    813         LOGE("%s: Unexpected NULL camera device", __FUNCTION__);
    814         return -EINVAL;
    815     }
    816     return ec->takePicture();
    817 }
    818 
    819 int EmulatedCamera::cancel_picture(struct camera_device* dev)
    820 {
    821     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    822     if (ec == NULL) {
    823         LOGE("%s: Unexpected NULL camera device", __FUNCTION__);
    824         return -EINVAL;
    825     }
    826     return ec->cancelPicture();
    827 }
    828 
    829 int EmulatedCamera::set_parameters(struct camera_device* dev, const char* parms)
    830 {
    831     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    832     if (ec == NULL) {
    833         LOGE("%s: Unexpected NULL camera device", __FUNCTION__);
    834         return -EINVAL;
    835     }
    836     return ec->setParameters(parms);
    837 }
    838 
    839 char* EmulatedCamera::get_parameters(struct camera_device* dev)
    840 {
    841     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    842     if (ec == NULL) {
    843         LOGE("%s: Unexpected NULL camera device", __FUNCTION__);
    844         return NULL;
    845     }
    846     return ec->getParameters();
    847 }
    848 
    849 void EmulatedCamera::put_parameters(struct camera_device* dev, char* params)
    850 {
    851     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    852     if (ec == NULL) {
    853         LOGE("%s: Unexpected NULL camera device", __FUNCTION__);
    854         return;
    855     }
    856     ec->putParameters(params);
    857 }
    858 
    859 int EmulatedCamera::send_command(struct camera_device* dev,
    860                                  int32_t cmd,
    861                                  int32_t arg1,
    862                                  int32_t arg2)
    863 {
    864     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    865     if (ec == NULL) {
    866         LOGE("%s: Unexpected NULL camera device", __FUNCTION__);
    867         return -EINVAL;
    868     }
    869     return ec->sendCommand(cmd, arg1, arg2);
    870 }
    871 
    872 void EmulatedCamera::release(struct camera_device* dev)
    873 {
    874     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    875     if (ec == NULL) {
    876         LOGE("%s: Unexpected NULL camera device", __FUNCTION__);
    877         return;
    878     }
    879     ec->releaseCamera();
    880 }
    881 
    882 int EmulatedCamera::dump(struct camera_device* dev, int fd)
    883 {
    884     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    885     if (ec == NULL) {
    886         LOGE("%s: Unexpected NULL camera device", __FUNCTION__);
    887         return -EINVAL;
    888     }
    889     return ec->dumpCamera(fd);
    890 }
    891 
    892 int EmulatedCamera::close(struct hw_device_t* device)
    893 {
    894     EmulatedCamera* ec =
    895         reinterpret_cast<EmulatedCamera*>(reinterpret_cast<struct camera_device*>(device)->priv);
    896     if (ec == NULL) {
    897         LOGE("%s: Unexpected NULL camera device", __FUNCTION__);
    898         return -EINVAL;
    899     }
    900     return ec->closeCamera();
    901 }
    902 
    903 /****************************************************************************
    904  * Static initializer for the camera callback API
    905  ****************************************************************************/
    906 
    907 camera_device_ops_t EmulatedCamera::mDeviceOps = {
    908     EmulatedCamera::set_preview_window,
    909     EmulatedCamera::set_callbacks,
    910     EmulatedCamera::enable_msg_type,
    911     EmulatedCamera::disable_msg_type,
    912     EmulatedCamera::msg_type_enabled,
    913     EmulatedCamera::start_preview,
    914     EmulatedCamera::stop_preview,
    915     EmulatedCamera::preview_enabled,
    916     EmulatedCamera::store_meta_data_in_buffers,
    917     EmulatedCamera::start_recording,
    918     EmulatedCamera::stop_recording,
    919     EmulatedCamera::recording_enabled,
    920     EmulatedCamera::release_recording_frame,
    921     EmulatedCamera::auto_focus,
    922     EmulatedCamera::cancel_auto_focus,
    923     EmulatedCamera::take_picture,
    924     EmulatedCamera::cancel_picture,
    925     EmulatedCamera::set_parameters,
    926     EmulatedCamera::get_parameters,
    927     EmulatedCamera::put_parameters,
    928     EmulatedCamera::send_command,
    929     EmulatedCamera::release,
    930     EmulatedCamera::dump
    931 };
    932 
    933 /****************************************************************************
    934  * Common keys
    935  ***************************************************************************/
    936 
    937 const char EmulatedCamera::FACING_KEY[]         = "prop-facing";
    938 const char EmulatedCamera::ORIENTATION_KEY[]    = "prop-orientation";
    939 const char EmulatedCamera::RECORDING_HINT_KEY[] = "recording-hint";
    940 
    941 /****************************************************************************
    942  * Common string values
    943  ***************************************************************************/
    944 
    945 const char EmulatedCamera::FACING_BACK[]      = "back";
    946 const char EmulatedCamera::FACING_FRONT[]     = "front";
    947 
    948 /****************************************************************************
    949  * Helper routines
    950  ***************************************************************************/
    951 
    952 static char* AddValue(const char* param, const char* val)
    953 {
    954     const size_t len1 = strlen(param);
    955     const size_t len2 = strlen(val);
    956     char* ret = reinterpret_cast<char*>(malloc(len1 + len2 + 2));
    957     LOGE_IF(ret == NULL, "%s: Memory failure", __FUNCTION__);
    958     if (ret != NULL) {
    959         memcpy(ret, param, len1);
    960         ret[len1] = ',';
    961         memcpy(ret + len1 + 1, val, len2);
    962         ret[len1 + len2 + 1] = '\0';
    963     }
    964     return ret;
    965 }
    966 
    967 /****************************************************************************
    968  * Parameter debugging helpers
    969  ***************************************************************************/
    970 
    971 #if DEBUG_PARAM
    972 static void PrintParamDiff(const CameraParameters& current,
    973                             const char* new_par)
    974 {
    975     char tmp[2048];
    976     const char* wrk = new_par;
    977 
    978     /* Divided with ';' */
    979     const char* next = strchr(wrk, ';');
    980     while (next != NULL) {
    981         snprintf(tmp, sizeof(tmp), "%.*s", next-wrk, wrk);
    982         /* in the form key=value */
    983         char* val = strchr(tmp, '=');
    984         if (val != NULL) {
    985             *val = '\0'; val++;
    986             const char* in_current = current.get(tmp);
    987             if (in_current != NULL) {
    988                 if (strcmp(in_current, val)) {
    989                     LOGD("=== Value changed: %s: %s -> %s", tmp, in_current, val);
    990                 }
    991             } else {
    992                 LOGD("+++ New parameter: %s=%s", tmp, val);
    993             }
    994         } else {
    995             LOGW("No value separator in %s", tmp);
    996         }
    997         wrk = next + 1;
    998         next = strchr(wrk, ';');
    999     }
   1000 }
   1001 #endif  /* DEBUG_PARAM */
   1002 
   1003 }; /* namespace android */
   1004