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 static const char* kValidFocusModes[] = {
     40     CameraParameters::FOCUS_MODE_AUTO,
     41     CameraParameters::FOCUS_MODE_INFINITY,
     42     CameraParameters::FOCUS_MODE_MACRO,
     43     CameraParameters::FOCUS_MODE_FIXED,
     44     CameraParameters::FOCUS_MODE_EDOF,
     45     CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO,
     46     CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE,
     47 };
     48 
     49 #if DEBUG_PARAM
     50 /* Calculates and logs parameter changes.
     51  * Param:
     52  *  current - Current set of camera parameters.
     53  *  new_par - String representation of new parameters.
     54  */
     55 static void PrintParamDiff(const CameraParameters& current, const char* new_par);
     56 #else
     57 #define PrintParamDiff(current, new_par)   (void(0))
     58 #endif  /* DEBUG_PARAM */
     59 
     60 /* A helper routine that adds a value to the camera parameter.
     61  * Param:
     62  *  param - Camera parameter to add a value to.
     63  *  val - Value to add.
     64  * Return:
     65  *  A new string containing parameter with the added value on success, or NULL on
     66  *  a failure. If non-NULL string is returned, the caller is responsible for
     67  *  freeing it with 'free'.
     68  */
     69 static char* AddValue(const char* param, const char* val);
     70 
     71 /*
     72  * Check if a given string |value| equals at least one of the strings in |list|
     73  */
     74 template<size_t N>
     75 static bool IsValueInList(const char* value, const char* const (&list)[N])
     76 {
     77     for (size_t i = 0; i < N; ++i) {
     78         if (strcmp(value, list[i]) == 0) {
     79             return true;
     80         }
     81     }
     82     return false;
     83 }
     84 
     85 static bool StringsEqual(const char* str1, const char* str2) {
     86     if (str1 == nullptr && str2 == nullptr) {
     87         return true;
     88     }
     89     if (str1 == nullptr || str2 == nullptr) {
     90         return false;
     91     }
     92     return strcmp(str1, str2) == 0;
     93 }
     94 
     95 static bool GetFourCcFormatFromCameraParam(const char* fmt_str,
     96                                            uint32_t* fmt_val) {
     97     if (strcmp(fmt_str, CameraParameters::PIXEL_FORMAT_YUV420P) == 0) {
     98         // Despite the name above this is a YVU format, specifically YV12
     99         *fmt_val = V4L2_PIX_FMT_YVU420;
    100         return true;
    101     } else if (strcmp(fmt_str, CameraParameters::PIXEL_FORMAT_RGBA8888) == 0) {
    102         *fmt_val = V4L2_PIX_FMT_RGB32;
    103         return true;
    104     } else if (strcmp(fmt_str, CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) {
    105         *fmt_val = V4L2_PIX_FMT_NV21;
    106         return true;
    107     }
    108     return false;
    109 }
    110 
    111 EmulatedCamera::EmulatedCamera(int cameraId,
    112                                struct hw_module_t* module)
    113         : EmulatedBaseCamera(cameraId,
    114                 HARDWARE_DEVICE_API_VERSION(1, 0),
    115                 &common,
    116                 module),
    117           mPreviewWindow(),
    118           mCallbackNotifier()
    119 {
    120     /* camera_device v1 fields. */
    121     common.close = EmulatedCamera::close;
    122     ops = &mDeviceOps;
    123     priv = this;
    124 }
    125 
    126 EmulatedCamera::~EmulatedCamera()
    127 {
    128 }
    129 
    130 /****************************************************************************
    131  * Public API
    132  ***************************************************************************/
    133 
    134 status_t EmulatedCamera::Initialize()
    135 {
    136     /* Preview formats supported by this HAL. */
    137     char preview_formats[1024];
    138     snprintf(preview_formats, sizeof(preview_formats), "%s,%s,%s",
    139              CameraParameters::PIXEL_FORMAT_YUV420SP,
    140              CameraParameters::PIXEL_FORMAT_YUV420P,
    141              CameraParameters::PIXEL_FORMAT_RGBA8888);
    142 
    143     /*
    144      * Fake required parameters.
    145      */
    146 
    147     mParameters.set(CameraParameters::KEY_RECORDING_HINT,
    148                     CameraParameters::FALSE);
    149     mParameters.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES, "320x240,0x0");
    150 
    151     mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, "320");
    152     mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, "240");
    153     mParameters.set(CameraParameters::KEY_JPEG_QUALITY, "90");
    154     // Camera values for a Logitech B910 HD Webcam
    155     //     Focal length: 4.90 mm (from specs)
    156     //     Horizontal view angle: 61 degrees for 4:3 sizes,
    157     //         70 degrees for 16:9 sizes (empirical)
    158     //     Vertical view angle: 45.8 degrees (= 61 * 3 / 4)
    159     // (The Mac has only "4:3" image sizes; the correct angle
    160     //  is 51.0 degrees. [MacBook Pro (Retina, 15-inch, Mid 2014)])
    161     mParameters.set(CameraParameters::KEY_FOCAL_LENGTH, "4.90");
    162     mParameters.set(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, "61.0");
    163     mParameters.set(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, "45.8");
    164     mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, "90");
    165 
    166     /* Preview format settings used here are related to panoramic view only. It's
    167      * not related to the preview window that works only with RGB frames, which
    168      * is explicitly stated when set_buffers_geometry is called on the preview
    169      * window object. */
    170     mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
    171                     preview_formats);
    172     mParameters.setPreviewFormat(CameraParameters::PIXEL_FORMAT_YUV420SP);
    173 
    174     /* We don't rely on the actual frame rates supported by the camera device,
    175      * since we will emulate them through timeouts in the emulated camera device
    176      * worker thread. */
    177     mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
    178                     "30,24,20,15,10,5");
    179     mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE, "(24000,24000)");
    180     mParameters.set(CameraParameters::KEY_PREVIEW_FPS_RANGE, "24000,24000");
    181     mParameters.setPreviewFrameRate(24);
    182 
    183     /* Only PIXEL_FORMAT_YUV420P is accepted by video framework in emulator! */
    184     mParameters.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT,
    185                     CameraParameters::PIXEL_FORMAT_YUV420P);
    186     mParameters.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
    187                     CameraParameters::PIXEL_FORMAT_JPEG);
    188     mParameters.setPictureFormat(CameraParameters::PIXEL_FORMAT_JPEG);
    189 
    190     /* Set exposure compensation. */
    191     mParameters.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION, "6");
    192     mParameters.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION, "-6");
    193     mParameters.set(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP, "0.5");
    194     mParameters.set(CameraParameters::KEY_EXPOSURE_COMPENSATION, "0");
    195 
    196     /* Sets the white balance modes and the device-dependent scale factors. */
    197     char supported_white_balance[1024];
    198     snprintf(supported_white_balance, sizeof(supported_white_balance),
    199              "%s,%s,%s,%s",
    200              CameraParameters::WHITE_BALANCE_AUTO,
    201              CameraParameters::WHITE_BALANCE_INCANDESCENT,
    202              CameraParameters::WHITE_BALANCE_DAYLIGHT,
    203              CameraParameters::WHITE_BALANCE_TWILIGHT);
    204     mParameters.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE,
    205                     supported_white_balance);
    206     mParameters.set(CameraParameters::KEY_WHITE_BALANCE,
    207                     CameraParameters::WHITE_BALANCE_AUTO);
    208     getCameraDevice()->initializeWhiteBalanceModes(
    209             CameraParameters::WHITE_BALANCE_AUTO, 1.0f, 1.0f);
    210     getCameraDevice()->initializeWhiteBalanceModes(
    211             CameraParameters::WHITE_BALANCE_INCANDESCENT, 1.38f, 0.60f);
    212     getCameraDevice()->initializeWhiteBalanceModes(
    213             CameraParameters::WHITE_BALANCE_DAYLIGHT, 1.09f, 0.92f);
    214     getCameraDevice()->initializeWhiteBalanceModes(
    215             CameraParameters::WHITE_BALANCE_TWILIGHT, 0.92f, 1.22f);
    216     getCameraDevice()->setWhiteBalanceMode(CameraParameters::WHITE_BALANCE_AUTO);
    217 
    218     /* Set suported antibanding values */
    219     mParameters.set(CameraParameters::KEY_SUPPORTED_ANTIBANDING,
    220                     CameraParameters::ANTIBANDING_AUTO);
    221     mParameters.set(CameraParameters::KEY_ANTIBANDING,
    222                     CameraParameters::ANTIBANDING_AUTO);
    223 
    224     /* Set control effect mode
    225      * Bug: 30862244
    226      * */
    227     mParameters.set(CameraParameters::KEY_SUPPORTED_EFFECTS,
    228                     CameraParameters::EFFECT_NONE);
    229     mParameters.set(CameraParameters::KEY_EFFECT,
    230                     CameraParameters::EFFECT_NONE);
    231 
    232     /* Set focus distances for "near,optimal,far" */
    233     mParameters.set(CameraParameters::KEY_FOCUS_DISTANCES,
    234                     "Infinity,Infinity,Infinity");
    235 
    236     /* Not supported features
    237      */
    238     mParameters.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
    239                     CameraParameters::FOCUS_MODE_FIXED);
    240     mParameters.set(CameraParameters::KEY_FOCUS_MODE,
    241                     CameraParameters::FOCUS_MODE_FIXED);
    242 
    243     return NO_ERROR;
    244 }
    245 
    246 void EmulatedCamera::onNextFrameAvailable(nsecs_t timestamp,
    247                                           EmulatedCameraDevice* camera_dev)
    248 {
    249     /* Notify the preview window first. */
    250     mPreviewWindow.onNextFrameAvailable(timestamp, camera_dev);
    251 
    252     /* Notify callback notifier next. */
    253     mCallbackNotifier.onNextFrameAvailable(timestamp, camera_dev);
    254 }
    255 
    256 void EmulatedCamera::onCameraDeviceError(int err)
    257 {
    258     /* Errors are reported through the callback notifier */
    259     mCallbackNotifier.onCameraDeviceError(err);
    260 }
    261 
    262 void EmulatedCamera::setTakingPicture(bool takingPicture) {
    263     mCallbackNotifier.setTakingPicture(takingPicture);
    264 }
    265 /****************************************************************************
    266  * Camera API implementation.
    267  ***************************************************************************/
    268 
    269 status_t EmulatedCamera::connectCamera(hw_device_t** device)
    270 {
    271     ALOGV("%s", __FUNCTION__);
    272 
    273     status_t res = EINVAL;
    274     EmulatedCameraDevice* const camera_dev = getCameraDevice();
    275     ALOGE_IF(camera_dev == NULL, "%s: No camera device instance.", __FUNCTION__);
    276 
    277     if (camera_dev != NULL) {
    278         /* Connect to the camera device. */
    279         res = getCameraDevice()->connectDevice();
    280         if (res == NO_ERROR) {
    281             *device = &common;
    282         }
    283     }
    284 
    285     return -res;
    286 }
    287 
    288 status_t EmulatedCamera::closeCamera()
    289 {
    290     ALOGV("%s", __FUNCTION__);
    291 
    292     return cleanupCamera();
    293 }
    294 
    295 status_t EmulatedCamera::getCameraInfo(struct camera_info* info)
    296 {
    297     ALOGV("%s", __FUNCTION__);
    298 
    299     const char* valstr = NULL;
    300 
    301     valstr = mParameters.get(EmulatedCamera::FACING_KEY);
    302     if (valstr != NULL) {
    303         if (strcmp(valstr, EmulatedCamera::FACING_FRONT) == 0) {
    304             info->facing = CAMERA_FACING_FRONT;
    305         }
    306         else if (strcmp(valstr, EmulatedCamera::FACING_BACK) == 0) {
    307             info->facing = CAMERA_FACING_BACK;
    308         }
    309     } else {
    310         info->facing = CAMERA_FACING_BACK;
    311     }
    312 
    313     valstr = mParameters.get(EmulatedCamera::ORIENTATION_KEY);
    314     if (valstr != NULL) {
    315         info->orientation = atoi(valstr);
    316     } else {
    317         info->orientation = 0;
    318     }
    319 
    320     return EmulatedBaseCamera::getCameraInfo(info);
    321 }
    322 
    323 void EmulatedCamera::autoFocusComplete() {
    324     mCallbackNotifier.autoFocusComplete();
    325 }
    326 
    327 status_t EmulatedCamera::setPreviewWindow(struct preview_stream_ops* window)
    328 {
    329     /* Callback should return a negative errno. */
    330     return -mPreviewWindow.setPreviewWindow(window,
    331                                              mParameters.getPreviewFrameRate());
    332 }
    333 
    334 void EmulatedCamera::setCallbacks(camera_notify_callback notify_cb,
    335                                   camera_data_callback data_cb,
    336                                   camera_data_timestamp_callback data_cb_timestamp,
    337                                   camera_request_memory get_memory,
    338                                   void* user)
    339 {
    340     mCallbackNotifier.setCallbacks(notify_cb, data_cb, data_cb_timestamp,
    341                                     get_memory, user);
    342 }
    343 
    344 void EmulatedCamera::enableMsgType(int32_t msg_type)
    345 {
    346     mCallbackNotifier.enableMessage(msg_type);
    347 }
    348 
    349 void EmulatedCamera::disableMsgType(int32_t msg_type)
    350 {
    351     mCallbackNotifier.disableMessage(msg_type);
    352 }
    353 
    354 int EmulatedCamera::isMsgTypeEnabled(int32_t msg_type)
    355 {
    356     return mCallbackNotifier.isMessageEnabled(msg_type);
    357 }
    358 
    359 status_t EmulatedCamera::startPreview()
    360 {
    361     /* Callback should return a negative errno. */
    362     return -doStartPreview();
    363 }
    364 
    365 void EmulatedCamera::stopPreview()
    366 {
    367     /* The camera client will not pass on calls to set the preview window to
    368      * NULL if the preview is not enabled. If preview is not enabled the camera
    369      * client will instead simply destroy the preview window without notifying
    370      * the HAL. Later on when preview is enabled again that means the HAL will
    371      * attempt to use the old, destroyed window which will cause a crash.
    372      * Instead we need to clear the preview window here, the client will set
    373      * a preview window when needed. The preview window is cleared here instead
    374      * of inside doStopPreview to prevent the window from being cleared when
    375      * restarting the preview because of a parameter change. */
    376     mPreviewWindow.setPreviewWindow(nullptr, 0);
    377 
    378     doStopPreview();
    379 }
    380 
    381 int EmulatedCamera::isPreviewEnabled()
    382 {
    383     return mPreviewWindow.isPreviewEnabled();
    384 }
    385 
    386 status_t EmulatedCamera::storeMetaDataInBuffers(int enable)
    387 {
    388     /* Callback should return a negative errno. */
    389     return -mCallbackNotifier.storeMetaDataInBuffers(enable);
    390 }
    391 
    392 status_t EmulatedCamera::startRecording()
    393 {
    394     /* This callback should return a negative errno, hence all the negations */
    395     int frameRate = mParameters.getPreviewFrameRate();
    396     status_t res = mCallbackNotifier.enableVideoRecording(frameRate);
    397     if (res != NO_ERROR) {
    398         ALOGE("%s: CallbackNotifier failed to enable video recording",
    399               __FUNCTION__);
    400         stopRecording();
    401         return -res;
    402     }
    403     EmulatedCameraDevice* const camera_dev = getCameraDevice();
    404     if (camera_dev == nullptr || !camera_dev->isStarted()) {
    405         // No need for restarts, the next preview start will use correct params
    406         return NO_ERROR;
    407     }
    408 
    409     // If the camera is running we might have to restart it to accomodate
    410     // whatever pixel format and frame size the caller wants.
    411     uint32_t conf_fmt = 0;
    412     res = getConfiguredPixelFormat(&conf_fmt);
    413     if (res != NO_ERROR) {
    414         stopRecording();
    415         return -res;
    416     }
    417     uint32_t cur_fmt = camera_dev->getOriginalPixelFormat();
    418     int conf_width = -1, conf_height = -1;
    419     res = getConfiguredFrameSize(&conf_width, &conf_height);
    420     if (res != NO_ERROR) {
    421         stopRecording();
    422         return -res;
    423     }
    424     int cur_width = camera_dev->getFrameWidth();
    425     int cur_height = camera_dev->getFrameHeight();
    426 
    427     if (cur_fmt != conf_fmt ||
    428             cur_width != conf_width ||
    429             cur_height != conf_height) {
    430         // We need to perform a restart to use the new format or size and it
    431         // has to be an asynchronous restart or this might block if the camera
    432         // thread is currently delivering a frame.
    433         if (!camera_dev->requestRestart(conf_width, conf_height, conf_fmt,
    434                                         false /* takingPicture */,
    435                                         false /* oneBurst */)) {
    436             ALOGE("%s: Could not restart preview with new pixel format",
    437                   __FUNCTION__);
    438             stopRecording();
    439             return -EINVAL;
    440         }
    441     }
    442     return NO_ERROR;
    443 }
    444 
    445 void EmulatedCamera::stopRecording()
    446 {
    447     mCallbackNotifier.disableVideoRecording();
    448 }
    449 
    450 int EmulatedCamera::isRecordingEnabled()
    451 {
    452     return mCallbackNotifier.isVideoRecordingEnabled();
    453 }
    454 
    455 void EmulatedCamera::releaseRecordingFrame(const void* opaque)
    456 {
    457     mCallbackNotifier.releaseRecordingFrame(opaque);
    458 }
    459 
    460 status_t EmulatedCamera::setAutoFocus()
    461 {
    462     // Make sure to check that a preview is in progress. Otherwise this will
    463     // silently fail because no callback will be called until the preview starts
    464     // which might be never.
    465     if (!isPreviewEnabled()) {
    466         return EINVAL;
    467     }
    468     EmulatedCameraDevice* const camera_dev = getCameraDevice();
    469     if (camera_dev && camera_dev->isStarted()) {
    470         return camera_dev->setAutoFocus();
    471     }
    472     return EINVAL;
    473 }
    474 
    475 status_t EmulatedCamera::cancelAutoFocus()
    476 {
    477     // In this case we don't check if a preview is in progress or not. Unlike
    478     // setAutoFocus this call will not silently fail without the check. If an
    479     // auto-focus request is somehow pending without having preview enabled this
    480     // will correctly cancel that pending auto-focus which seems reasonable.
    481     EmulatedCameraDevice* const camera_dev = getCameraDevice();
    482     if (camera_dev && camera_dev->isStarted()) {
    483         return camera_dev->cancelAutoFocus();
    484     }
    485     return EINVAL;
    486 }
    487 
    488 status_t EmulatedCamera::takePicture()
    489 {
    490     ALOGV("%s", __FUNCTION__);
    491 
    492     status_t res;
    493     int width, height;
    494     uint32_t org_fmt;
    495 
    496     /* Collect frame info for the picture. */
    497     mParameters.getPictureSize(&width, &height);
    498     const char* pix_fmt = mParameters.getPictureFormat();
    499     if (!GetFourCcFormatFromCameraParam(pix_fmt, &org_fmt)) {
    500         // Also check for JPEG here, the function above does not do this since
    501         // this is very specific to this use case.
    502         if (strcmp(pix_fmt, CameraParameters::PIXEL_FORMAT_JPEG) == 0) {
    503             /* We only have JPEG converted for NV21 format. */
    504             org_fmt = V4L2_PIX_FMT_NV21;
    505         } else {
    506             ALOGE("%s: Unsupported pixel format %s", __FUNCTION__, pix_fmt);
    507             return EINVAL;
    508         }
    509     }
    510 
    511     /* Get JPEG quality. */
    512     int jpeg_quality = mParameters.getInt(CameraParameters::KEY_JPEG_QUALITY);
    513     if (jpeg_quality <= 0) {
    514         jpeg_quality = 90;  /* Fall back to default. */
    515     }
    516 
    517     /*
    518      * Make sure preview is not running, and device is stopped before taking
    519      * picture.
    520      */
    521 
    522     EmulatedCameraDevice* const camera_dev = getCameraDevice();
    523     mCallbackNotifier.setJpegQuality(jpeg_quality);
    524     mCallbackNotifier.setCameraParameters(mParameters);
    525 
    526     ALOGD("Starting camera for picture: %.4s(%s)[%dx%d]",
    527           reinterpret_cast<const char*>(&org_fmt), pix_fmt, width, height);
    528     if (mPreviewWindow.isPreviewEnabled()) {
    529         mPreviewWindow.stopPreview();
    530         /* If the camera preview is enabled we need to perform an asynchronous
    531          * restart. A blocking restart could deadlock this thread as it's
    532          * currently holding the camera client lock and the frame delivery could
    533          * be stuck on waiting for that lock. If this was synchronous then this
    534          * thread would in turn get stuck on waiting for the delivery thread. */
    535         if (!camera_dev->requestRestart(width, height, org_fmt,
    536                                         true /* takingPicture */,
    537                                         true /* oneBurst */)) {
    538             return UNKNOWN_ERROR;
    539         }
    540         return NO_ERROR;
    541     } else {
    542         /* Start camera device for the picture frame. */
    543         res = camera_dev->startDevice(width, height, org_fmt);
    544         if (res != NO_ERROR) {
    545             return res;
    546         }
    547 
    548         /* Deliver one frame only. */
    549         mCallbackNotifier.setTakingPicture(true);
    550         res = camera_dev->startDeliveringFrames(true);
    551         if (res != NO_ERROR) {
    552             mCallbackNotifier.setTakingPicture(false);
    553         }
    554         return res;
    555     }
    556 }
    557 
    558 status_t EmulatedCamera::cancelPicture()
    559 {
    560     ALOGV("%s", __FUNCTION__);
    561 
    562     return NO_ERROR;
    563 }
    564 
    565 status_t EmulatedCamera::setParameters(const char* parms)
    566 {
    567     ALOGV("%s", __FUNCTION__);
    568     PrintParamDiff(mParameters, parms);
    569 
    570     CameraParameters new_param;
    571     String8 str8_param(parms);
    572     new_param.unflatten(str8_param);
    573     bool restartPreview = false;
    574 
    575     /*
    576      * Check for new exposure compensation parameter.
    577      */
    578     int new_exposure_compensation = new_param.getInt(
    579             CameraParameters::KEY_EXPOSURE_COMPENSATION);
    580     const int min_exposure_compensation = new_param.getInt(
    581             CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION);
    582     const int max_exposure_compensation = new_param.getInt(
    583             CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION);
    584 
    585     // Checks if the exposure compensation change is supported.
    586     if ((min_exposure_compensation != 0) || (max_exposure_compensation != 0)) {
    587         if (new_exposure_compensation > max_exposure_compensation) {
    588             new_exposure_compensation = max_exposure_compensation;
    589         }
    590         if (new_exposure_compensation < min_exposure_compensation) {
    591             new_exposure_compensation = min_exposure_compensation;
    592         }
    593 
    594         const int current_exposure_compensation = mParameters.getInt(
    595                 CameraParameters::KEY_EXPOSURE_COMPENSATION);
    596         if (current_exposure_compensation != new_exposure_compensation) {
    597             const float exposure_value = new_exposure_compensation *
    598                     new_param.getFloat(
    599                             CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP);
    600 
    601             getCameraDevice()->setExposureCompensation(
    602                     exposure_value);
    603         }
    604     }
    605 
    606     const char* new_white_balance = new_param.get(
    607             CameraParameters::KEY_WHITE_BALANCE);
    608     const char* supported_white_balance = new_param.get(
    609             CameraParameters::KEY_SUPPORTED_WHITE_BALANCE);
    610 
    611     if ((supported_white_balance != NULL) && (new_white_balance != NULL) &&
    612         (strstr(supported_white_balance, new_white_balance) != NULL)) {
    613 
    614         const char* current_white_balance = mParameters.get(
    615                 CameraParameters::KEY_WHITE_BALANCE);
    616         if ((current_white_balance == NULL) ||
    617             (strcmp(current_white_balance, new_white_balance) != 0)) {
    618             ALOGV("Setting white balance to %s", new_white_balance);
    619             getCameraDevice()->setWhiteBalanceMode(new_white_balance);
    620         }
    621     }
    622     int old_frame_rate = mParameters.getPreviewFrameRate();
    623     int new_frame_rate = new_param.getPreviewFrameRate();
    624     if (old_frame_rate != new_frame_rate) {
    625         getCameraDevice()->setPreviewFrameRate(new_frame_rate);
    626     }
    627 
    628     // Validate focus mode
    629     const char* focus_mode = new_param.get(CameraParameters::KEY_FOCUS_MODE);
    630     if (focus_mode && !IsValueInList(focus_mode, kValidFocusModes)) {
    631         return BAD_VALUE;
    632     }
    633 
    634     // Validate preview size, if there is no preview size the initial values of
    635     // the integers below will be preserved thus intentionally failing the test
    636     int new_preview_width = -1, new_preview_height = -1;
    637     new_param.getPreviewSize(&new_preview_width, &new_preview_height);
    638     if (new_preview_width < 0 || new_preview_height < 0) {
    639         return BAD_VALUE;
    640     }
    641     // If the preview size has changed we have to restart the preview to make
    642     // sure we provide frames of the correct size. The receiver assumes the
    643     // frame size is correct and will copy all data provided into a buffer whose
    644     // size is determined by the preview size without checks, potentially
    645     // causing buffer overruns or underruns if there is a size mismatch.
    646     int old_preview_width = -1, old_preview_height = -1;
    647     mParameters.getPreviewSize(&old_preview_width, &old_preview_height);
    648     if (old_preview_width != new_preview_width ||
    649             old_preview_height != new_preview_height) {
    650         restartPreview = true;
    651     }
    652 
    653     // For the same reasons as with the preview size we have to look for changes
    654     // in video size and restart the preview if the size has changed.
    655     int old_video_width = -1, old_video_height = -1;
    656     int new_video_width = -1, new_video_height = -1;
    657     mParameters.getVideoSize(&old_video_width, &old_video_height);
    658     new_param.getVideoSize(&new_video_width, &new_video_height);
    659     if (old_video_width != new_video_width ||
    660         old_video_height != new_video_height) {
    661         restartPreview = true;
    662     }
    663     // Restart the preview if the pixel format changes to make sure we serve
    664     // the selected encoding to the client.
    665     const char* old_format = mParameters.getPreviewFormat();
    666     const char* new_format = new_param.getPreviewFormat();
    667     if (!StringsEqual(old_format, new_format)) {
    668         restartPreview = true;
    669     }
    670 
    671     const char* old_hint =
    672         mParameters.get(CameraParameters::KEY_RECORDING_HINT);
    673     const char* new_hint = new_param.get(CameraParameters::KEY_RECORDING_HINT);
    674     if (!StringsEqual(old_hint, new_hint)) {
    675         // The recording hint changed, this indicates we transitioned from
    676         // recording to non-recording or the other way around. We need to look
    677         // at a new pixel format for this and that requires a restart.
    678         restartPreview = true;
    679     }
    680 
    681     mParameters = new_param;
    682 
    683     // Now that the parameters have been assigned check if the preview needs to
    684     // be restarted. If necessary this will then use the new parameters to set
    685     // up the preview as requested by the caller.
    686     if (restartPreview && isPreviewEnabled()) {
    687         status_t status = doStopPreview();
    688         if (status != NO_ERROR) {
    689             ALOGE("%s: Stopping preview failed: %d", __FUNCTION__, status);
    690             return status;
    691         }
    692         status = doStartPreview();
    693         if (status != NO_ERROR) {
    694             ALOGE("%s: Starting preview failed: %d", __FUNCTION__, status);
    695             return status;
    696         }
    697     }
    698     return NO_ERROR;
    699 }
    700 
    701 /* A dumb variable indicating "no params" / error on the exit from
    702  * EmulatedCamera::getParameters(). */
    703 static char lNoParam = '\0';
    704 char* EmulatedCamera::getParameters()
    705 {
    706     // Read the image size and set the camera's Field of View.
    707     // These values are valid for a Logitech B910 HD Webcam.
    708     int width=0, height=0;
    709     mParameters.getPictureSize(&width, &height);
    710     if (height > 0) {
    711         if (((double)width / height) < 1.55) {
    712             // Closer to 4:3 (1.33), set the FOV to 61.0 degrees
    713             mParameters.set(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, "61.0");
    714         } else {
    715             // Closer to 16:9 (1.77), set the FOV to 70.0 degrees
    716             mParameters.set(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, "70.0");
    717         }
    718     }
    719 
    720     String8 params(mParameters.flatten());
    721     char* ret_str =
    722         reinterpret_cast<char*>(malloc(sizeof(char) * (params.length()+1)));
    723     memset(ret_str, 0, params.length()+1);
    724     if (ret_str != NULL) {
    725         strncpy(ret_str, params.string(), params.length()+1);
    726         return ret_str;
    727     } else {
    728         ALOGE("%s: Unable to allocate string for %s", __FUNCTION__, params.string());
    729         /* Apparently, we can't return NULL fron this routine. */
    730         return &lNoParam;
    731     }
    732 }
    733 
    734 void EmulatedCamera::putParameters(char* params)
    735 {
    736     /* This method simply frees parameters allocated in getParameters(). */
    737     if (params != NULL && params != &lNoParam) {
    738         free(params);
    739     }
    740 }
    741 
    742 status_t EmulatedCamera::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
    743 {
    744     ALOGV("%s: cmd = %d, arg1 = %d, arg2 = %d", __FUNCTION__, cmd, arg1, arg2);
    745 
    746     switch (cmd) {
    747         case CAMERA_CMD_START_FACE_DETECTION:
    748         case CAMERA_CMD_STOP_FACE_DETECTION:
    749             // We do not support hardware face detection so we need to indicate
    750             // that any attempt to start/stop face detection is invalid
    751             return BAD_VALUE;
    752     }
    753     /* TODO: Future enhancements. */
    754     return 0;
    755 }
    756 
    757 void EmulatedCamera::releaseCamera()
    758 {
    759     ALOGV("%s", __FUNCTION__);
    760 
    761     cleanupCamera();
    762 }
    763 
    764 status_t EmulatedCamera::dumpCamera(int fd)
    765 {
    766     ALOGV("%s", __FUNCTION__);
    767 
    768     /* TODO: Future enhancements. */
    769     return -EINVAL;
    770 }
    771 
    772 status_t EmulatedCamera::getConfiguredPixelFormat(uint32_t* pixelFormat) const {
    773     const char* pix_fmt = nullptr;
    774     const char* recordingHint =
    775         mParameters.get(CameraParameters::KEY_RECORDING_HINT);
    776     bool recordingHintOn = recordingHint && strcmp(recordingHint,
    777                                                    CameraParameters::TRUE) == 0;
    778     bool recordingEnabled = mCallbackNotifier.isVideoRecordingEnabled();
    779     if (recordingHintOn || recordingEnabled) {
    780         // We're recording a video, use the video pixel format
    781         pix_fmt = mParameters.get(CameraParameters::KEY_VIDEO_FRAME_FORMAT);
    782     }
    783     if (pix_fmt == nullptr) {
    784         pix_fmt = mParameters.getPreviewFormat();
    785     }
    786     if (pix_fmt == nullptr) {
    787         ALOGE("%s: Unable to obtain configured pixel format", __FUNCTION__);
    788         return EINVAL;
    789     }
    790     /* Convert framework's pixel format to the FOURCC one. */
    791     if (!GetFourCcFormatFromCameraParam(pix_fmt, pixelFormat)) {
    792         ALOGE("%s: Unsupported pixel format %s", __FUNCTION__, pix_fmt);
    793         return EINVAL;
    794     }
    795     return NO_ERROR;
    796 }
    797 
    798 status_t EmulatedCamera::getConfiguredFrameSize(int* outWidth,
    799                                                 int* outHeight) const {
    800     int width = -1, height = -1;
    801     if (mParameters.get(CameraParameters::KEY_VIDEO_SIZE) != nullptr) {
    802         mParameters.getVideoSize(&width, &height);
    803     } else {
    804         mParameters.getPreviewSize(&width, &height);
    805     }
    806     if (width < 0 || height < 0) {
    807         ALOGE("%s: No frame size configured for camera", __FUNCTION__);
    808         return EINVAL;
    809     }
    810     // Only modify the out parameters once we know we succeeded
    811     *outWidth = width;
    812     *outHeight = height;
    813     return NO_ERROR;
    814 }
    815 
    816 /****************************************************************************
    817  * Preview management.
    818  ***************************************************************************/
    819 
    820 status_t EmulatedCamera::doStartPreview()
    821 {
    822     ALOGV("%s", __FUNCTION__);
    823 
    824     EmulatedCameraDevice* camera_dev = getCameraDevice();
    825     if (camera_dev->isStarted()) {
    826         camera_dev->stopDeliveringFrames();
    827         camera_dev->stopDevice();
    828     }
    829 
    830     status_t res = mPreviewWindow.startPreview();
    831     if (res != NO_ERROR) {
    832         return res;
    833     }
    834 
    835     /* Make sure camera device is connected. */
    836     if (!camera_dev->isConnected()) {
    837         res = camera_dev->connectDevice();
    838         if (res != NO_ERROR) {
    839             mPreviewWindow.stopPreview();
    840             return res;
    841         }
    842     }
    843 
    844     /* Lets see what should we use for frame width, and height. */
    845     int width, height;
    846     res = getConfiguredFrameSize(&width, &height);
    847     if (res != NO_ERROR) {
    848         mPreviewWindow.stopPreview();
    849         return res;
    850     }
    851 
    852     uint32_t org_fmt = 0;
    853     res = getConfiguredPixelFormat(&org_fmt);
    854     if (res != NO_ERROR) {
    855         mPreviewWindow.stopPreview();
    856         return res;
    857     }
    858 
    859     camera_dev->setPreviewFrameRate(mParameters.getPreviewFrameRate());
    860     ALOGD("Starting camera: %dx%d -> %.4s",
    861          width, height, reinterpret_cast<const char*>(&org_fmt));
    862     res = camera_dev->startDevice(width, height, org_fmt);
    863     if (res != NO_ERROR) {
    864         mPreviewWindow.stopPreview();
    865         return res;
    866     }
    867 
    868     res = camera_dev->startDeliveringFrames(false);
    869     if (res != NO_ERROR) {
    870         camera_dev->stopDevice();
    871         mPreviewWindow.stopPreview();
    872     }
    873 
    874     return res;
    875 }
    876 
    877 status_t EmulatedCamera::doStopPreview()
    878 {
    879     ALOGV("%s", __FUNCTION__);
    880 
    881     status_t res = NO_ERROR;
    882     if (mPreviewWindow.isPreviewEnabled()) {
    883         /* Stop the camera. */
    884         if (getCameraDevice()->isStarted()) {
    885             getCameraDevice()->stopDeliveringFrames();
    886             res = getCameraDevice()->stopDevice();
    887         }
    888 
    889         if (res == NO_ERROR) {
    890             /* Disable preview as well. */
    891             mPreviewWindow.stopPreview();
    892         }
    893     }
    894 
    895     return NO_ERROR;
    896 }
    897 
    898 /****************************************************************************
    899  * Private API.
    900  ***************************************************************************/
    901 
    902 status_t EmulatedCamera::cleanupCamera()
    903 {
    904     status_t res = NO_ERROR;
    905 
    906     /* If preview is running - stop it. */
    907     res = doStopPreview();
    908     if (res != NO_ERROR) {
    909         return -res;
    910     }
    911 
    912     /* Stop and disconnect the camera device. */
    913     EmulatedCameraDevice* const camera_dev = getCameraDevice();
    914     if (camera_dev != NULL) {
    915         if (camera_dev->isStarted()) {
    916             camera_dev->stopDeliveringFrames();
    917             res = camera_dev->stopDevice();
    918             if (res != NO_ERROR) {
    919                 return -res;
    920             }
    921         }
    922         if (camera_dev->isConnected()) {
    923             res = camera_dev->disconnectDevice();
    924             if (res != NO_ERROR) {
    925                 return -res;
    926             }
    927         }
    928     }
    929 
    930     mCallbackNotifier.cleanupCBNotifier();
    931 
    932     /* Re-init the camera settings in case settings were changed */
    933     Initialize();
    934 
    935     return NO_ERROR;
    936 }
    937 
    938 /****************************************************************************
    939  * Camera API callbacks as defined by camera_device_ops structure.
    940  *
    941  * Callbacks here simply dispatch the calls to an appropriate method inside
    942  * EmulatedCamera instance, defined by the 'dev' parameter.
    943  ***************************************************************************/
    944 
    945 int EmulatedCamera::set_preview_window(struct camera_device* dev,
    946                                        struct preview_stream_ops* window)
    947 {
    948     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    949     if (ec == NULL) {
    950         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
    951         return -EINVAL;
    952     }
    953     return ec->setPreviewWindow(window);
    954 }
    955 
    956 void EmulatedCamera::set_callbacks(
    957         struct camera_device* dev,
    958         camera_notify_callback notify_cb,
    959         camera_data_callback data_cb,
    960         camera_data_timestamp_callback data_cb_timestamp,
    961         camera_request_memory get_memory,
    962         void* user)
    963 {
    964     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    965     if (ec == NULL) {
    966         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
    967         return;
    968     }
    969     ec->setCallbacks(notify_cb, data_cb, data_cb_timestamp, get_memory, user);
    970 }
    971 
    972 void EmulatedCamera::enable_msg_type(struct camera_device* dev, int32_t msg_type)
    973 {
    974     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    975     if (ec == NULL) {
    976         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
    977         return;
    978     }
    979     ec->enableMsgType(msg_type);
    980 }
    981 
    982 void EmulatedCamera::disable_msg_type(struct camera_device* dev, int32_t msg_type)
    983 {
    984     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    985     if (ec == NULL) {
    986         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
    987         return;
    988     }
    989     ec->disableMsgType(msg_type);
    990 }
    991 
    992 int EmulatedCamera::msg_type_enabled(struct camera_device* dev, int32_t msg_type)
    993 {
    994     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    995     if (ec == NULL) {
    996         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
    997         return -EINVAL;
    998     }
    999     return ec->isMsgTypeEnabled(msg_type);
   1000 }
   1001 
   1002 int EmulatedCamera::start_preview(struct camera_device* dev)
   1003 {
   1004     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
   1005     if (ec == NULL) {
   1006         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
   1007         return -EINVAL;
   1008     }
   1009     return ec->startPreview();
   1010 }
   1011 
   1012 void EmulatedCamera::stop_preview(struct camera_device* dev)
   1013 {
   1014     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
   1015     if (ec == NULL) {
   1016         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
   1017         return;
   1018     }
   1019     ec->stopPreview();
   1020 }
   1021 
   1022 int EmulatedCamera::preview_enabled(struct camera_device* dev)
   1023 {
   1024     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
   1025     if (ec == NULL) {
   1026         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
   1027         return -EINVAL;
   1028     }
   1029     return ec->isPreviewEnabled();
   1030 }
   1031 
   1032 int EmulatedCamera::store_meta_data_in_buffers(struct camera_device* dev,
   1033                                                int enable)
   1034 {
   1035     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
   1036     if (ec == NULL) {
   1037         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
   1038         return -EINVAL;
   1039     }
   1040     return ec->storeMetaDataInBuffers(enable);
   1041 }
   1042 
   1043 int EmulatedCamera::start_recording(struct camera_device* dev)
   1044 {
   1045     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
   1046     if (ec == NULL) {
   1047         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
   1048         return -EINVAL;
   1049     }
   1050     return ec->startRecording();
   1051 }
   1052 
   1053 void EmulatedCamera::stop_recording(struct camera_device* dev)
   1054 {
   1055     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
   1056     if (ec == NULL) {
   1057         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
   1058         return;
   1059     }
   1060     ec->stopRecording();
   1061 }
   1062 
   1063 int EmulatedCamera::recording_enabled(struct camera_device* dev)
   1064 {
   1065     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
   1066     if (ec == NULL) {
   1067         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
   1068         return -EINVAL;
   1069     }
   1070     return ec->isRecordingEnabled();
   1071 }
   1072 
   1073 void EmulatedCamera::release_recording_frame(struct camera_device* dev,
   1074                                              const void* opaque)
   1075 {
   1076     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
   1077     if (ec == NULL) {
   1078         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
   1079         return;
   1080     }
   1081     ec->releaseRecordingFrame(opaque);
   1082 }
   1083 
   1084 int EmulatedCamera::auto_focus(struct camera_device* dev)
   1085 {
   1086     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
   1087     if (ec == NULL) {
   1088         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
   1089         return -EINVAL;
   1090     }
   1091     return ec->setAutoFocus();
   1092 }
   1093 
   1094 int EmulatedCamera::cancel_auto_focus(struct camera_device* dev)
   1095 {
   1096     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
   1097     if (ec == NULL) {
   1098         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
   1099         return -EINVAL;
   1100     }
   1101     return ec->cancelAutoFocus();
   1102 }
   1103 
   1104 int EmulatedCamera::take_picture(struct camera_device* dev)
   1105 {
   1106     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
   1107     if (ec == NULL) {
   1108         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
   1109         return -EINVAL;
   1110     }
   1111     return ec->takePicture();
   1112 }
   1113 
   1114 int EmulatedCamera::cancel_picture(struct camera_device* dev)
   1115 {
   1116     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
   1117     if (ec == NULL) {
   1118         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
   1119         return -EINVAL;
   1120     }
   1121     return ec->cancelPicture();
   1122 }
   1123 
   1124 int EmulatedCamera::set_parameters(struct camera_device* dev, const char* parms)
   1125 {
   1126     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
   1127     if (ec == NULL) {
   1128         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
   1129         return -EINVAL;
   1130     }
   1131     return ec->setParameters(parms);
   1132 }
   1133 
   1134 char* EmulatedCamera::get_parameters(struct camera_device* dev)
   1135 {
   1136     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
   1137     if (ec == NULL) {
   1138         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
   1139         return NULL;
   1140     }
   1141     return ec->getParameters();
   1142 }
   1143 
   1144 void EmulatedCamera::put_parameters(struct camera_device* dev, char* params)
   1145 {
   1146     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
   1147     if (ec == NULL) {
   1148         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
   1149         return;
   1150     }
   1151     ec->putParameters(params);
   1152 }
   1153 
   1154 int EmulatedCamera::send_command(struct camera_device* dev,
   1155                                  int32_t cmd,
   1156                                  int32_t arg1,
   1157                                  int32_t arg2)
   1158 {
   1159     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
   1160     if (ec == NULL) {
   1161         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
   1162         return -EINVAL;
   1163     }
   1164     return ec->sendCommand(cmd, arg1, arg2);
   1165 }
   1166 
   1167 void EmulatedCamera::release(struct camera_device* dev)
   1168 {
   1169     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
   1170     if (ec == NULL) {
   1171         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
   1172         return;
   1173     }
   1174     ec->releaseCamera();
   1175 }
   1176 
   1177 int EmulatedCamera::dump(struct camera_device* dev, int fd)
   1178 {
   1179     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
   1180     if (ec == NULL) {
   1181         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
   1182         return -EINVAL;
   1183     }
   1184     return ec->dumpCamera(fd);
   1185 }
   1186 
   1187 int EmulatedCamera::close(struct hw_device_t* device)
   1188 {
   1189     EmulatedCamera* ec =
   1190         reinterpret_cast<EmulatedCamera*>(reinterpret_cast<struct camera_device*>(device)->priv);
   1191     if (ec == NULL) {
   1192         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
   1193         return -EINVAL;
   1194     }
   1195     return ec->closeCamera();
   1196 }
   1197 
   1198 /****************************************************************************
   1199  * Static initializer for the camera callback API
   1200  ****************************************************************************/
   1201 
   1202 camera_device_ops_t EmulatedCamera::mDeviceOps = {
   1203     EmulatedCamera::set_preview_window,
   1204     EmulatedCamera::set_callbacks,
   1205     EmulatedCamera::enable_msg_type,
   1206     EmulatedCamera::disable_msg_type,
   1207     EmulatedCamera::msg_type_enabled,
   1208     EmulatedCamera::start_preview,
   1209     EmulatedCamera::stop_preview,
   1210     EmulatedCamera::preview_enabled,
   1211     EmulatedCamera::store_meta_data_in_buffers,
   1212     EmulatedCamera::start_recording,
   1213     EmulatedCamera::stop_recording,
   1214     EmulatedCamera::recording_enabled,
   1215     EmulatedCamera::release_recording_frame,
   1216     EmulatedCamera::auto_focus,
   1217     EmulatedCamera::cancel_auto_focus,
   1218     EmulatedCamera::take_picture,
   1219     EmulatedCamera::cancel_picture,
   1220     EmulatedCamera::set_parameters,
   1221     EmulatedCamera::get_parameters,
   1222     EmulatedCamera::put_parameters,
   1223     EmulatedCamera::send_command,
   1224     EmulatedCamera::release,
   1225     EmulatedCamera::dump
   1226 };
   1227 
   1228 /****************************************************************************
   1229  * Common keys
   1230  ***************************************************************************/
   1231 
   1232 const char EmulatedCamera::FACING_KEY[]         = "prop-facing";
   1233 const char EmulatedCamera::ORIENTATION_KEY[]    = "prop-orientation";
   1234 const char EmulatedCamera::RECORDING_HINT_KEY[] = "recording-hint";
   1235 
   1236 /****************************************************************************
   1237  * Common string values
   1238  ***************************************************************************/
   1239 
   1240 const char EmulatedCamera::FACING_BACK[]      = "back";
   1241 const char EmulatedCamera::FACING_FRONT[]     = "front";
   1242 
   1243 /****************************************************************************
   1244  * Helper routines
   1245  ***************************************************************************/
   1246 
   1247 static char* AddValue(const char* param, const char* val)
   1248 {
   1249     const size_t len1 = strlen(param);
   1250     const size_t len2 = strlen(val);
   1251     char* ret = reinterpret_cast<char*>(malloc(len1 + len2 + 2));
   1252     ALOGE_IF(ret == NULL, "%s: Memory failure", __FUNCTION__);
   1253     if (ret != NULL) {
   1254         memcpy(ret, param, len1);
   1255         ret[len1] = ',';
   1256         memcpy(ret + len1 + 1, val, len2);
   1257         ret[len1 + len2 + 1] = '\0';
   1258     }
   1259     return ret;
   1260 }
   1261 
   1262 /****************************************************************************
   1263  * Parameter debugging helpers
   1264  ***************************************************************************/
   1265 
   1266 #if DEBUG_PARAM
   1267 static void PrintParamDiff(const CameraParameters& current,
   1268                             const char* new_par)
   1269 {
   1270     char tmp[2048];
   1271     const char* wrk = new_par;
   1272 
   1273     /* Divided with ';' */
   1274     const char* next = strchr(wrk, ';');
   1275     while (next != NULL) {
   1276         snprintf(tmp, sizeof(tmp), "%.*s", (int)(intptr_t)(next-wrk), wrk);
   1277         /* in the form key=value */
   1278         char* val = strchr(tmp, '=');
   1279         if (val != NULL) {
   1280             *val = '\0'; val++;
   1281             const char* in_current = current.get(tmp);
   1282             if (in_current != NULL) {
   1283                 if (strcmp(in_current, val)) {
   1284                     ALOGD("=== Value changed: %s: %s -> %s", tmp, in_current, val);
   1285                 }
   1286             } else {
   1287                 ALOGD("+++ New parameter: %s=%s", tmp, val);
   1288             }
   1289         } else {
   1290             ALOGW("No value separator in %s", tmp);
   1291         }
   1292         wrk = next + 1;
   1293         next = strchr(wrk, ';');
   1294     }
   1295 }
   1296 #endif  /* DEBUG_PARAM */
   1297 
   1298 }; /* namespace android */
   1299