/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Contains implementation of a class EmulatedCamera that encapsulates
 * functionality common to all emulated cameras ("fake", "webcam", "video file",
 * etc.). Instances of this class (for each emulated camera) are created during
 * the construction of the EmulatedCameraFactory instance. This class serves as
 * an entry point for all camera API calls that defined by camera_device_ops_t
 * API.
 */

#define LOG_NDEBUG 0
#define LOG_TAG "EmulatedCamera_Camera"
#include <log/log.h>
#include <stdio.h>
#include "EmulatedCamera.h"
//#include "EmulatedFakeCameraDevice.h"
#include "Converters.h"

/* Defines whether we should trace parameter changes. */
#define DEBUG_PARAM 1

namespace android {

static const char* kValidFocusModes[] = {
    CameraParameters::FOCUS_MODE_AUTO,
    CameraParameters::FOCUS_MODE_INFINITY,
    CameraParameters::FOCUS_MODE_MACRO,
    CameraParameters::FOCUS_MODE_FIXED,
    CameraParameters::FOCUS_MODE_EDOF,
    CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO,
    CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE,
};

#if DEBUG_PARAM
/* Calculates and logs parameter changes.
 * Param:
 *  current - Current set of camera parameters.
 *  new_par - String representation of new parameters.
 */
static void PrintParamDiff(const CameraParameters& current, const char* new_par);
#else
#define PrintParamDiff(current, new_par)   (void(0))
#endif  /* DEBUG_PARAM */

/*
 * Check if a given string |value| equals at least one of the strings in |list|
 */
template<size_t N>
static bool IsValueInList(const char* value, const char* const (&list)[N])
{
    for (size_t i = 0; i < N; ++i) {
        if (strcmp(value, list[i]) == 0) {
            return true;
        }
    }
    return false;
}

static bool StringsEqual(const char* str1, const char* str2) {
    if (str1 == nullptr && str2 == nullptr) {
        return true;
    }
    if (str1 == nullptr || str2 == nullptr) {
        return false;
    }
    return strcmp(str1, str2) == 0;
}

static bool GetFourCcFormatFromCameraParam(const char* fmt_str,
                                           uint32_t* fmt_val) {
    if (strcmp(fmt_str, CameraParameters::PIXEL_FORMAT_YUV420P) == 0) {
        // Despite the name above this is a YVU format, specifically YV12
        *fmt_val = V4L2_PIX_FMT_YVU420;
        return true;
    } else if (strcmp(fmt_str, CameraParameters::PIXEL_FORMAT_RGBA8888) == 0) {
        *fmt_val = V4L2_PIX_FMT_RGB32;
        return true;
    } else if (strcmp(fmt_str, CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) {
        *fmt_val = V4L2_PIX_FMT_NV21;
        return true;
    }
    return false;
}

EmulatedCamera::EmulatedCamera(int cameraId,
                               struct hw_module_t* module)
        : EmulatedBaseCamera(cameraId,
                HARDWARE_DEVICE_API_VERSION(1, 0),
                &common,
                module),
          mPreviewWindow(),
          mCallbackNotifier()
{
    /* camera_device v1 fields. */
    common.close = EmulatedCamera::close;
    ops = &mDeviceOps;
    priv = this;
}

EmulatedCamera::~EmulatedCamera()
{
}

/****************************************************************************
 * Public API
 ***************************************************************************/

status_t EmulatedCamera::Initialize()
{
    /* Preview formats supported by this HAL. */
    char preview_formats[1024];
    snprintf(preview_formats, sizeof(preview_formats), "%s,%s,%s",
             CameraParameters::PIXEL_FORMAT_YUV420SP,
             CameraParameters::PIXEL_FORMAT_YUV420P,
             CameraParameters::PIXEL_FORMAT_RGBA8888);

    /*
     * Fake required parameters.
     */

    mParameters.set(CameraParameters::KEY_RECORDING_HINT,
                    CameraParameters::FALSE);
    mParameters.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES, "320x240,0x0");

    mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, "320");
    mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, "240");
    mParameters.set(CameraParameters::KEY_JPEG_QUALITY, "90");
    // Camera values for a Logitech B910 HD Webcam
    //     Focal length: 4.90 mm (from specs)
    //     Horizontal view angle: 61 degrees for 4:3 sizes,
    //         70 degrees for 16:9 sizes (empirical)
    //     Vertical view angle: 45.8 degrees (= 61 * 3 / 4)
    // (The Mac has only "4:3" image sizes; the correct angle
    //  is 51.0 degrees. [MacBook Pro (Retina, 15-inch, Mid 2014)])
    mParameters.set(CameraParameters::KEY_FOCAL_LENGTH, "4.90");
    mParameters.set(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, "61.0");
    mParameters.set(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, "45.8");
    mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, "90");

    /* Preview format settings used here are related to panoramic view only. It's
     * not related to the preview window that works only with RGB frames, which
     * is explicitly stated when set_buffers_geometry is called on the preview
     * window object. */
    mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
                    preview_formats);
    mParameters.setPreviewFormat(CameraParameters::PIXEL_FORMAT_YUV420SP);

    /* We don't rely on the actual frame rates supported by the camera device,
     * since we will emulate them through timeouts in the emulated camera device
     * worker thread. */
    mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
                    "30,24,20,15,10,5");
    mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE, "(30000,30000)");
    mParameters.set(CameraParameters::KEY_PREVIEW_FPS_RANGE, "30000,30000");
    mParameters.setPreviewFrameRate(30);

    /* Only PIXEL_FORMAT_YUV420P is accepted by video framework in emulator! */
    mParameters.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT,
                    CameraParameters::PIXEL_FORMAT_YUV420P);
    mParameters.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
                    CameraParameters::PIXEL_FORMAT_JPEG);
    mParameters.setPictureFormat(CameraParameters::PIXEL_FORMAT_JPEG);

    /* Set exposure compensation. */
    mParameters.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION, "6");
    mParameters.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION, "-6");
    mParameters.set(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP, "0.5");
    mParameters.set(CameraParameters::KEY_EXPOSURE_COMPENSATION, "0");

    /* Sets the white balance modes and the device-dependent scale factors. */
    char supported_white_balance[1024];
    snprintf(supported_white_balance, sizeof(supported_white_balance),
             "%s,%s,%s,%s",
             CameraParameters::WHITE_BALANCE_AUTO,
             CameraParameters::WHITE_BALANCE_INCANDESCENT,
             CameraParameters::WHITE_BALANCE_DAYLIGHT,
             CameraParameters::WHITE_BALANCE_TWILIGHT);
    mParameters.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE,
                    supported_white_balance);
    mParameters.set(CameraParameters::KEY_WHITE_BALANCE,
                    CameraParameters::WHITE_BALANCE_AUTO);
    getCameraDevice()->initializeWhiteBalanceModes(
            CameraParameters::WHITE_BALANCE_AUTO, 1.0f, 1.0f);
    getCameraDevice()->initializeWhiteBalanceModes(
            CameraParameters::WHITE_BALANCE_INCANDESCENT, 1.38f, 0.60f);
    getCameraDevice()->initializeWhiteBalanceModes(
            CameraParameters::WHITE_BALANCE_DAYLIGHT, 1.09f, 0.92f);
    getCameraDevice()->initializeWhiteBalanceModes(
            CameraParameters::WHITE_BALANCE_TWILIGHT, 0.92f, 1.22f);
    getCameraDevice()->setWhiteBalanceMode(CameraParameters::WHITE_BALANCE_AUTO);

    /* Set suported antibanding values */
    mParameters.set(CameraParameters::KEY_SUPPORTED_ANTIBANDING,
                    CameraParameters::ANTIBANDING_AUTO);
    mParameters.set(CameraParameters::KEY_ANTIBANDING,
                    CameraParameters::ANTIBANDING_AUTO);

    /* Set control effect mode
     * Bug: 30862244
     * */
    mParameters.set(CameraParameters::KEY_SUPPORTED_EFFECTS,
                    CameraParameters::EFFECT_NONE);
    mParameters.set(CameraParameters::KEY_EFFECT,
                    CameraParameters::EFFECT_NONE);

    /* Set focus distances for "near,optimal,far" */
    mParameters.set(CameraParameters::KEY_FOCUS_DISTANCES,
                    "Infinity,Infinity,Infinity");

    /* Not supported features
     */
    mParameters.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
                    CameraParameters::FOCUS_MODE_FIXED);
    mParameters.set(CameraParameters::KEY_FOCUS_MODE,
                    CameraParameters::FOCUS_MODE_FIXED);

    return NO_ERROR;
}

void EmulatedCamera::onNextFrameAvailable(nsecs_t timestamp,
                                          EmulatedCameraDevice* camera_dev)
{
    /* Notify the preview window first. */
    mPreviewWindow.onNextFrameAvailable(timestamp, camera_dev);

    /* Notify callback notifier next. */
    mCallbackNotifier.onNextFrameAvailable(timestamp, camera_dev);
}

void EmulatedCamera::onCameraDeviceError(int err)
{
    /* Errors are reported through the callback notifier */
    mCallbackNotifier.onCameraDeviceError(err);
}

void EmulatedCamera::setTakingPicture(bool takingPicture) {
    mCallbackNotifier.setTakingPicture(takingPicture);
}
/****************************************************************************
 * Camera API implementation.
 ***************************************************************************/

status_t EmulatedCamera::connectCamera(hw_device_t** device)
{
    ALOGV("%s", __FUNCTION__);

    status_t res = EINVAL;
    EmulatedCameraDevice* const camera_dev = getCameraDevice();
    ALOGE_IF(camera_dev == NULL, "%s: No camera device instance.", __FUNCTION__);

    if (camera_dev != NULL) {
        /* Connect to the camera device. */
        res = getCameraDevice()->connectDevice();
        if (res == NO_ERROR) {
            *device = &common;
        }
    }

    return -res;
}

status_t EmulatedCamera::closeCamera()
{
    ALOGV("%s", __FUNCTION__);

    return cleanupCamera();
}

status_t EmulatedCamera::getCameraInfo(struct camera_info* info)
{
    ALOGV("%s", __FUNCTION__);

    const char* valstr = NULL;

    valstr = mParameters.get(EmulatedCamera::FACING_KEY);
    if (valstr != NULL) {
        if (strcmp(valstr, EmulatedCamera::FACING_FRONT) == 0) {
            info->facing = CAMERA_FACING_FRONT;
        }
        else if (strcmp(valstr, EmulatedCamera::FACING_BACK) == 0) {
            info->facing = CAMERA_FACING_BACK;
        }
    } else {
        info->facing = CAMERA_FACING_BACK;
    }

    valstr = mParameters.get(EmulatedCamera::ORIENTATION_KEY);
    if (valstr != NULL) {
        info->orientation = atoi(valstr);
    } else {
        info->orientation = 0;
    }

    return EmulatedBaseCamera::getCameraInfo(info);
}

void EmulatedCamera::autoFocusComplete() {
    mCallbackNotifier.autoFocusComplete();
}

status_t EmulatedCamera::setPreviewWindow(struct preview_stream_ops* window)
{
    /* Callback should return a negative errno. */
    return -mPreviewWindow.setPreviewWindow(window,
                                             mParameters.getPreviewFrameRate());
}

void EmulatedCamera::setCallbacks(camera_notify_callback notify_cb,
                                  camera_data_callback data_cb,
                                  camera_data_timestamp_callback data_cb_timestamp,
                                  camera_request_memory get_memory,
                                  void* user)
{
    mCallbackNotifier.setCallbacks(notify_cb, data_cb, data_cb_timestamp,
                                    get_memory, user);
}

void EmulatedCamera::enableMsgType(int32_t msg_type)
{
    mCallbackNotifier.enableMessage(msg_type);
}

void EmulatedCamera::disableMsgType(int32_t msg_type)
{
    mCallbackNotifier.disableMessage(msg_type);
}

int EmulatedCamera::isMsgTypeEnabled(int32_t msg_type)
{
    return mCallbackNotifier.isMessageEnabled(msg_type);
}

status_t EmulatedCamera::startPreview()
{
    /* Callback should return a negative errno. */
    return -doStartPreview();
}

void EmulatedCamera::stopPreview()
{
    /* The camera client will not pass on calls to set the preview window to
     * NULL if the preview is not enabled. If preview is not enabled the camera
     * client will instead simply destroy the preview window without notifying
     * the HAL. Later on when preview is enabled again that means the HAL will
     * attempt to use the old, destroyed window which will cause a crash.
     * Instead we need to clear the preview window here, the client will set
     * a preview window when needed. The preview window is cleared here instead
     * of inside doStopPreview to prevent the window from being cleared when
     * restarting the preview because of a parameter change. */
    mPreviewWindow.setPreviewWindow(nullptr, 0);

    doStopPreview();
}

int EmulatedCamera::isPreviewEnabled()
{
    return mPreviewWindow.isPreviewEnabled();
}

status_t EmulatedCamera::storeMetaDataInBuffers(int enable)
{
    /* Callback should return a negative errno. */
    return mCallbackNotifier.storeMetaDataInBuffers(enable);
}

status_t EmulatedCamera::startRecording()
{
    /* This callback should return a negative errno, hence all the negations */
    if (!mPreviewWindow.isPreviewEnabled()) {
        ALOGE("%s: start recording without preview enabled",
              __FUNCTION__);
        return INVALID_OPERATION;
    }
    int frameRate = mParameters.getPreviewFrameRate();
    status_t res = mCallbackNotifier.enableVideoRecording(frameRate);
    if (res != NO_ERROR) {
        ALOGE("%s: CallbackNotifier failed to enable video recording",
              __FUNCTION__);
        stopRecording();
        return -res;
    }
    EmulatedCameraDevice* const camera_dev = getCameraDevice();
    if (camera_dev == nullptr || !camera_dev->isStarted()) {
        // No need for restarts, the next preview start will use correct params
        return NO_ERROR;
    }

    // If the camera is running we might have to restart it to accomodate
    // whatever pixel format and frame size the caller wants.
    uint32_t conf_fmt = 0;
    res = getConfiguredPixelFormat(&conf_fmt);
    if (res != NO_ERROR) {
        stopRecording();
        return -res;
    }
    uint32_t cur_fmt = camera_dev->getOriginalPixelFormat();
    int conf_width = -1, conf_height = -1;
    res = getConfiguredFrameSize(&conf_width, &conf_height);
    if (res != NO_ERROR) {
        stopRecording();
        return -res;
    }
    int cur_width = camera_dev->getFrameWidth();
    int cur_height = camera_dev->getFrameHeight();

    if (cur_fmt != conf_fmt ||
            cur_width != conf_width ||
            cur_height != conf_height) {
        // We need to perform a restart to use the new format or size and it
        // has to be an asynchronous restart or this might block if the camera
        // thread is currently delivering a frame.
        if (!camera_dev->requestRestart(conf_width, conf_height, conf_fmt,
                                        false /* takingPicture */,
                                        false /* oneBurst */)) {
            ALOGE("%s: Could not restart preview with new pixel format",
                  __FUNCTION__);
            stopRecording();
            return -EINVAL;
        }
    }
    ALOGD("go all the way to the end");
    return NO_ERROR;
}

void EmulatedCamera::stopRecording()
{
    mCallbackNotifier.disableVideoRecording();
}

int EmulatedCamera::isRecordingEnabled()
{
    return mCallbackNotifier.isVideoRecordingEnabled();
}

void EmulatedCamera::releaseRecordingFrame(const void* opaque)
{
    mCallbackNotifier.releaseRecordingFrame(opaque);
}

status_t EmulatedCamera::setAutoFocus()
{
    // Make sure to check that a preview is in progress. Otherwise this will
    // silently fail because no callback will be called until the preview starts
    // which might be never.
    if (!isPreviewEnabled()) {
        return EINVAL;
    }
    EmulatedCameraDevice* const camera_dev = getCameraDevice();
    if (camera_dev && camera_dev->isStarted()) {
        return camera_dev->setAutoFocus();
    }
    return EINVAL;
}

status_t EmulatedCamera::cancelAutoFocus()
{
    // In this case we don't check if a preview is in progress or not. Unlike
    // setAutoFocus this call will not silently fail without the check. If an
    // auto-focus request is somehow pending without having preview enabled this
    // will correctly cancel that pending auto-focus which seems reasonable.
    EmulatedCameraDevice* const camera_dev = getCameraDevice();
    if (camera_dev && camera_dev->isStarted()) {
        return camera_dev->cancelAutoFocus();
    }
    return EINVAL;
}

status_t EmulatedCamera::takePicture()
{
    ALOGV("%s", __FUNCTION__);

    int width, height;
    uint32_t org_fmt;

    /* Collect frame info for the picture. */
    mParameters.getPictureSize(&width, &height);
    const char* pix_fmt = mParameters.getPictureFormat();
    if (!GetFourCcFormatFromCameraParam(pix_fmt, &org_fmt)) {
        // Also check for JPEG here, the function above does not do this since
        // this is very specific to this use case.
        if (strcmp(pix_fmt, CameraParameters::PIXEL_FORMAT_JPEG) == 0) {
            /* We only have JPEG converted for NV21 format. */
            org_fmt = V4L2_PIX_FMT_NV21;
        } else {
            ALOGE("%s: Unsupported pixel format %s", __FUNCTION__, pix_fmt);
            return EINVAL;
        }
    }

    /* Get JPEG quality. */
    int jpeg_quality = mParameters.getInt(CameraParameters::KEY_JPEG_QUALITY);
    if (jpeg_quality <= 0) {
        jpeg_quality = 90;  /* Fall back to default. */
    }

    /*
     * Make sure preview is not running, and device is stopped before taking
     * picture.
     */

    EmulatedCameraDevice* const camera_dev = getCameraDevice();
    mCallbackNotifier.setJpegQuality(jpeg_quality);
    mCallbackNotifier.setCameraParameters(mParameters);

    ALOGD("Starting camera for picture: %.4s(%s)[%dx%d]",
          reinterpret_cast<const char*>(&org_fmt), pix_fmt, width, height);
    if (mPreviewWindow.isPreviewEnabled()) {
        mPreviewWindow.stopPreview();
        /* If the camera preview is enabled we need to perform an asynchronous
         * restart. A blocking restart could deadlock this thread as it's
         * currently holding the camera client lock and the frame delivery could
         * be stuck on waiting for that lock. If this was synchronous then this
         * thread would in turn get stuck on waiting for the delivery thread. */
        if (!camera_dev->requestRestart(width, height, org_fmt,
                                        true /* takingPicture */,
                                        true /* oneBurst */)) {
            return UNKNOWN_ERROR;
        }
        return NO_ERROR;
    } else {
        ALOGE("%s: preview has not been enabled", __FUNCTION__);
        return EINVAL;
    }
}

status_t EmulatedCamera::cancelPicture()
{
    ALOGV("%s", __FUNCTION__);
    return NO_ERROR;
}

status_t EmulatedCamera::setParameters(const char* parms)
{
    ALOGV("%s", __FUNCTION__);
    PrintParamDiff(mParameters, parms);

    CameraParameters new_param;
    String8 str8_param(parms);
    new_param.unflatten(str8_param);
    bool restartPreview = false;

    /*
     * Check for new exposure compensation parameter.
     */
    int new_exposure_compensation = new_param.getInt(
            CameraParameters::KEY_EXPOSURE_COMPENSATION);
    const int min_exposure_compensation = new_param.getInt(
            CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION);
    const int max_exposure_compensation = new_param.getInt(
            CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION);

    // Checks if the exposure compensation change is supported.
    if ((min_exposure_compensation != 0) || (max_exposure_compensation != 0)) {
        if (new_exposure_compensation > max_exposure_compensation) {
            new_exposure_compensation = max_exposure_compensation;
        }
        if (new_exposure_compensation < min_exposure_compensation) {
            new_exposure_compensation = min_exposure_compensation;
        }

        const int current_exposure_compensation = mParameters.getInt(
                CameraParameters::KEY_EXPOSURE_COMPENSATION);
        if (current_exposure_compensation != new_exposure_compensation) {
            const float exposure_value = new_exposure_compensation *
                    new_param.getFloat(
                            CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP);

            getCameraDevice()->setExposureCompensation(
                    exposure_value);
        }
    }

    const char* new_white_balance = new_param.get(
            CameraParameters::KEY_WHITE_BALANCE);
    const char* supported_white_balance = new_param.get(
            CameraParameters::KEY_SUPPORTED_WHITE_BALANCE);

    if ((supported_white_balance != NULL) && (new_white_balance != NULL) &&
        (strstr(supported_white_balance, new_white_balance) != NULL)) {

        const char* current_white_balance = mParameters.get(
                CameraParameters::KEY_WHITE_BALANCE);
        if ((current_white_balance == NULL) ||
            (strcmp(current_white_balance, new_white_balance) != 0)) {
            ALOGV("Setting white balance to %s", new_white_balance);
            getCameraDevice()->setWhiteBalanceMode(new_white_balance);
        }
    }
    int old_frame_rate = mParameters.getPreviewFrameRate();
    int new_frame_rate = new_param.getPreviewFrameRate();
    if (old_frame_rate != new_frame_rate) {
        getCameraDevice()->setPreviewFrameRate(new_frame_rate);
    }

    // Validate KEY_PREVIEW_FPS_RANGE i.e., "preview-fps-range"
    const char* preview_fps_range = new_param.get(CameraParameters::KEY_PREVIEW_FPS_RANGE);
    if (preview_fps_range) {
        char tmp[1024];
        snprintf(tmp, sizeof(tmp), "%s", preview_fps_range);
        int low=-1, high=-1;
        if (sscanf(tmp, "%d,%d", &low, &high) != 2) {
            ALOGE("incorrect preview-fps-range %s", tmp);
            return BAD_VALUE;
        }
        if (low < 0 || high < 0) {
            ALOGE("negative preview_fps_range in %s", tmp);
            return BAD_VALUE;
        }
        if (low > high) {
            ALOGE("invalid preview_fps_range in %s", tmp);
            return BAD_VALUE;
        }
    }

    // Validate focus mode
    const char* focus_mode = new_param.get(CameraParameters::KEY_FOCUS_MODE);
    if (focus_mode && !IsValueInList(focus_mode, kValidFocusModes)) {
        return BAD_VALUE;
    }

    // Validate preview size, if there is no preview size the initial values of
    // the integers below will be preserved thus intentionally failing the test
    int new_preview_width = -1, new_preview_height = -1;
    new_param.getPreviewSize(&new_preview_width, &new_preview_height);
    if (new_preview_width < 0 || new_preview_height < 0) {
        return BAD_VALUE;
    }
    // If the preview size has changed we have to restart the preview to make
    // sure we provide frames of the correct size. The receiver assumes the
    // frame size is correct and will copy all data provided into a buffer whose
    // size is determined by the preview size without checks, potentially
    // causing buffer overruns or underruns if there is a size mismatch.
    int old_preview_width = -1, old_preview_height = -1;
    mParameters.getPreviewSize(&old_preview_width, &old_preview_height);
    if (old_preview_width != new_preview_width ||
            old_preview_height != new_preview_height) {
        restartPreview = true;
    }

    // For the same reasons as with the preview size we have to look for changes
    // in video size and restart the preview if the size has changed.
    int old_video_width = -1, old_video_height = -1;
    int new_video_width = -1, new_video_height = -1;
    mParameters.getVideoSize(&old_video_width, &old_video_height);
    new_param.getVideoSize(&new_video_width, &new_video_height);
    if (old_video_width != new_video_width ||
        old_video_height != new_video_height) {
        restartPreview = true;
    }
    // Restart the preview if the pixel format changes to make sure we serve
    // the selected encoding to the client.
    const char* old_format = mParameters.getPreviewFormat();
    const char* new_format = new_param.getPreviewFormat();
    if (!StringsEqual(old_format, new_format)) {
        restartPreview = true;
    }

    const char* old_hint =
        mParameters.get(CameraParameters::KEY_RECORDING_HINT);
    const char* new_hint = new_param.get(CameraParameters::KEY_RECORDING_HINT);
    if (!StringsEqual(old_hint, new_hint)) {
        // The recording hint changed, this indicates we transitioned from
        // recording to non-recording or the other way around. We need to look
        // at a new pixel format for this and that requires a restart.
        restartPreview = true;
    }

    mParameters = new_param;

    // Now that the parameters have been assigned check if the preview needs to
    // be restarted. If necessary this will then use the new parameters to set
    // up the preview as requested by the caller.
    if (restartPreview && isPreviewEnabled()) {
        status_t status = doStopPreview();
        if (status != NO_ERROR) {
            ALOGE("%s: Stopping preview failed: %d", __FUNCTION__, status);
            return status;
        }
        status = doStartPreview();
        if (status != NO_ERROR) {
            ALOGE("%s: Starting preview failed: %d", __FUNCTION__, status);
            return status;
        }
    }
    return NO_ERROR;
}

/* A dumb variable indicating "no params" / error on the exit from
 * EmulatedCamera::getParameters(). */
static char lNoParam = '\0';
char* EmulatedCamera::getParameters()
{
    // Read the image size and set the camera's Field of View.
    // These values are valid for a Logitech B910 HD Webcam.
    int width=0, height=0;
    mParameters.getPictureSize(&width, &height);
    if (height > 0) {
        if (((double)width / height) < 1.55) {
            // Closer to 4:3 (1.33), set the FOV to 61.0 degrees
            mParameters.set(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, "61.0");
        } else {
            // Closer to 16:9 (1.77), set the FOV to 70.0 degrees
            mParameters.set(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, "70.0");
        }
    }

    String8 params(mParameters.flatten());
    char* ret_str =
        reinterpret_cast<char*>(malloc(sizeof(char) * (params.length()+1)));
    memset(ret_str, 0, params.length()+1);
    if (ret_str != NULL) {
        strncpy(ret_str, params.string(), params.length()+1);
        return ret_str;
    } else {
        ALOGE("%s: Unable to allocate string for %s", __FUNCTION__, params.string());
        /* Apparently, we can't return NULL fron this routine. */
        return &lNoParam;
    }
}

void EmulatedCamera::putParameters(char* params)
{
    /* This method simply frees parameters allocated in getParameters(). */
    if (params != NULL && params != &lNoParam) {
        free(params);
    }
}

status_t EmulatedCamera::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
{
    ALOGV("%s: cmd = %d, arg1 = %d, arg2 = %d", __FUNCTION__, cmd, arg1, arg2);

    switch (cmd) {
        case CAMERA_CMD_START_FACE_DETECTION:
        case CAMERA_CMD_STOP_FACE_DETECTION:
            // We do not support hardware face detection so we need to indicate
            // that any attempt to start/stop face detection is invalid
            return BAD_VALUE;
    }
    /* TODO: Future enhancements. */
    return 0;
}

void EmulatedCamera::releaseCamera()
{
    ALOGV("%s", __FUNCTION__);

    cleanupCamera();
}

status_t EmulatedCamera::dumpCamera(int fd)
{
    ALOGV("%s", __FUNCTION__);

    /* TODO: Future enhancements. */
    dprintf(fd, "dump camera unimplemented\n");
    return 0;
}

status_t EmulatedCamera::getConfiguredPixelFormat(uint32_t* pixelFormat) const {
    const char* pix_fmt = nullptr;
    const char* recordingHint =
        mParameters.get(CameraParameters::KEY_RECORDING_HINT);
    bool recordingHintOn = recordingHint && strcmp(recordingHint,
                                                   CameraParameters::TRUE) == 0;
    bool recordingEnabled = mCallbackNotifier.isVideoRecordingEnabled();
    if (recordingHintOn || recordingEnabled) {
        // We're recording a video, use the video pixel format
        pix_fmt = mParameters.get(CameraParameters::KEY_VIDEO_FRAME_FORMAT);
    }
    if (pix_fmt == nullptr) {
        pix_fmt = mParameters.getPreviewFormat();
    }
    if (pix_fmt == nullptr) {
        ALOGE("%s: Unable to obtain configured pixel format", __FUNCTION__);
        return EINVAL;
    }
    /* Convert framework's pixel format to the FOURCC one. */
    if (!GetFourCcFormatFromCameraParam(pix_fmt, pixelFormat)) {
        ALOGE("%s: Unsupported pixel format %s", __FUNCTION__, pix_fmt);
        return EINVAL;
    }
    return NO_ERROR;
}

status_t EmulatedCamera::getConfiguredFrameSize(int* outWidth,
                                                int* outHeight) const {
    int width = -1, height = -1;
    if (mParameters.get(CameraParameters::KEY_VIDEO_SIZE) != nullptr) {
        mParameters.getVideoSize(&width, &height);
    } else {
        mParameters.getPreviewSize(&width, &height);
    }
    if (width < 0 || height < 0) {
        ALOGE("%s: No frame size configured for camera", __FUNCTION__);
        return EINVAL;
    }
    // Only modify the out parameters once we know we succeeded
    *outWidth = width;
    *outHeight = height;
    return NO_ERROR;
}

/****************************************************************************
 * Preview management.
 ***************************************************************************/

status_t EmulatedCamera::doStartPreview()
{
    ALOGV("%s", __FUNCTION__);

    EmulatedCameraDevice* camera_dev = getCameraDevice();
    if (camera_dev->isStarted()) {
        camera_dev->stopDeliveringFrames();
        camera_dev->stopDevice();
    }

    status_t res = mPreviewWindow.startPreview();
    if (res != NO_ERROR) {
        return res;
    }

    /* Make sure camera device is connected. */
    if (!camera_dev->isConnected()) {
        res = camera_dev->connectDevice();
        if (res != NO_ERROR) {
            mPreviewWindow.stopPreview();
            return res;
        }
    }

    /* Lets see what should we use for frame width, and height. */
    int width, height;
    res = getConfiguredFrameSize(&width, &height);
    if (res != NO_ERROR) {
        mPreviewWindow.stopPreview();
        return res;
    }

    uint32_t org_fmt = 0;
    res = getConfiguredPixelFormat(&org_fmt);
    if (res != NO_ERROR) {
        mPreviewWindow.stopPreview();
        return res;
    }

    camera_dev->setPreviewFrameRate(mParameters.getPreviewFrameRate());
    ALOGD("Starting camera: %dx%d -> %.4s",
         width, height, reinterpret_cast<const char*>(&org_fmt));
    res = camera_dev->startDevice(width, height, org_fmt);
    if (res != NO_ERROR) {
        mPreviewWindow.stopPreview();
        return res;
    }

    res = camera_dev->startDeliveringFrames(false);
    if (res != NO_ERROR) {
        camera_dev->stopDevice();
        mPreviewWindow.stopPreview();
    }

    return res;
}

status_t EmulatedCamera::doStopPreview()
{
    ALOGV("%s", __FUNCTION__);

    status_t res = NO_ERROR;
    if (mPreviewWindow.isPreviewEnabled()) {
        /* Stop the camera. */
        if (getCameraDevice()->isStarted()) {
            getCameraDevice()->stopDeliveringFrames();
            res = getCameraDevice()->stopDevice();
        }

        if (res == NO_ERROR) {
            /* Disable preview as well. */
            mPreviewWindow.stopPreview();
        }
    }

    return NO_ERROR;
}

/****************************************************************************
 * Private API.
 ***************************************************************************/

status_t EmulatedCamera::cleanupCamera()
{
    status_t res = NO_ERROR;

    /* If preview is running - stop it. */
    res = doStopPreview();
    if (res != NO_ERROR) {
        return -res;
    }

    /* Stop and disconnect the camera device. */
    EmulatedCameraDevice* const camera_dev = getCameraDevice();
    if (camera_dev != NULL) {
        if (camera_dev->isStarted()) {
            camera_dev->stopDeliveringFrames();
            res = camera_dev->stopDevice();
            if (res != NO_ERROR) {
                return -res;
            }
        }
        if (camera_dev->isConnected()) {
            res = camera_dev->disconnectDevice();
            if (res != NO_ERROR) {
                return -res;
            }
        }
    }

    mCallbackNotifier.cleanupCBNotifier();

    /* Re-init the camera settings in case settings were changed */
    Initialize();

    return NO_ERROR;
}

/****************************************************************************
 * Camera API callbacks as defined by camera_device_ops structure.
 *
 * Callbacks here simply dispatch the calls to an appropriate method inside
 * EmulatedCamera instance, defined by the 'dev' parameter.
 ***************************************************************************/

int EmulatedCamera::set_preview_window(struct camera_device* dev,
                                       struct preview_stream_ops* window)
{
    EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    if (ec == NULL) {
        ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
        return -EINVAL;
    }
    return ec->setPreviewWindow(window);
}

void EmulatedCamera::set_callbacks(
        struct camera_device* dev,
        camera_notify_callback notify_cb,
        camera_data_callback data_cb,
        camera_data_timestamp_callback data_cb_timestamp,
        camera_request_memory get_memory,
        void* user)
{
    EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    if (ec == NULL) {
        ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
        return;
    }
    ec->setCallbacks(notify_cb, data_cb, data_cb_timestamp, get_memory, user);
}

void EmulatedCamera::enable_msg_type(struct camera_device* dev, int32_t msg_type)
{
    EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    if (ec == NULL) {
        ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
        return;
    }
    ec->enableMsgType(msg_type);
}

void EmulatedCamera::disable_msg_type(struct camera_device* dev, int32_t msg_type)
{
    EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    if (ec == NULL) {
        ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
        return;
    }
    ec->disableMsgType(msg_type);
}

int EmulatedCamera::msg_type_enabled(struct camera_device* dev, int32_t msg_type)
{
    EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    if (ec == NULL) {
        ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
        return -EINVAL;
    }
    return ec->isMsgTypeEnabled(msg_type);
}

int EmulatedCamera::start_preview(struct camera_device* dev)
{
    EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    if (ec == NULL) {
        ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
        return -EINVAL;
    }
    return ec->startPreview();
}

void EmulatedCamera::stop_preview(struct camera_device* dev)
{
    EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    if (ec == NULL) {
        ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
        return;
    }
    ec->stopPreview();
}

int EmulatedCamera::preview_enabled(struct camera_device* dev)
{
    EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    if (ec == NULL) {
        ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
        return -EINVAL;
    }
    return ec->isPreviewEnabled();
}

int EmulatedCamera::store_meta_data_in_buffers(struct camera_device* dev,
                                               int enable)
{
    EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    if (ec == NULL) {
        ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
        return -EINVAL;
    }
    return ec->storeMetaDataInBuffers(enable);
}

int EmulatedCamera::start_recording(struct camera_device* dev)
{
    EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    if (ec == NULL) {
        ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
        return -EINVAL;
    }
    return ec->startRecording();
}

void EmulatedCamera::stop_recording(struct camera_device* dev)
{
    EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    if (ec == NULL) {
        ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
        return;
    }
    ec->stopRecording();
}

int EmulatedCamera::recording_enabled(struct camera_device* dev)
{
    EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    if (ec == NULL) {
        ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
        return -EINVAL;
    }
    return ec->isRecordingEnabled();
}

void EmulatedCamera::release_recording_frame(struct camera_device* dev,
                                             const void* opaque)
{
    EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    if (ec == NULL) {
        ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
        return;
    }
    ec->releaseRecordingFrame(opaque);
}

int EmulatedCamera::auto_focus(struct camera_device* dev)
{
    EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    if (ec == NULL) {
        ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
        return -EINVAL;
    }
    return ec->setAutoFocus();
}

int EmulatedCamera::cancel_auto_focus(struct camera_device* dev)
{
    EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    if (ec == NULL) {
        ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
        return -EINVAL;
    }
    return ec->cancelAutoFocus();
}

int EmulatedCamera::take_picture(struct camera_device* dev)
{
    EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    if (ec == NULL) {
        ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
        return -EINVAL;
    }
    return ec->takePicture();
}

int EmulatedCamera::cancel_picture(struct camera_device* dev)
{
    EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    if (ec == NULL) {
        ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
        return -EINVAL;
    }
    return ec->cancelPicture();
}

int EmulatedCamera::set_parameters(struct camera_device* dev, const char* parms)
{
    EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    if (ec == NULL) {
        ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
        return -EINVAL;
    }
    return ec->setParameters(parms);
}

char* EmulatedCamera::get_parameters(struct camera_device* dev)
{
    EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    if (ec == NULL) {
        ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
        return NULL;
    }
    return ec->getParameters();
}

void EmulatedCamera::put_parameters(struct camera_device* dev, char* params)
{
    EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    if (ec == NULL) {
        ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
        return;
    }
    ec->putParameters(params);
}

int EmulatedCamera::send_command(struct camera_device* dev,
                                 int32_t cmd,
                                 int32_t arg1,
                                 int32_t arg2)
{
    EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    if (ec == NULL) {
        ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
        return -EINVAL;
    }
    return ec->sendCommand(cmd, arg1, arg2);
}

void EmulatedCamera::release(struct camera_device* dev)
{
    EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    if (ec == NULL) {
        ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
        return;
    }
    ec->releaseCamera();
}

int EmulatedCamera::dump(struct camera_device* dev, int fd)
{
    EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
    if (ec == NULL) {
        ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
        return -EINVAL;
    }
    return ec->dumpCamera(fd);
}

int EmulatedCamera::close(struct hw_device_t* device)
{
    EmulatedCamera* ec =
        reinterpret_cast<EmulatedCamera*>(reinterpret_cast<struct camera_device*>(device)->priv);
    if (ec == NULL) {
        ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
        return -EINVAL;
    }
    return ec->closeCamera();
}

/****************************************************************************
 * Static initializer for the camera callback API
 ****************************************************************************/

camera_device_ops_t EmulatedCamera::mDeviceOps = {
    EmulatedCamera::set_preview_window,
    EmulatedCamera::set_callbacks,
    EmulatedCamera::enable_msg_type,
    EmulatedCamera::disable_msg_type,
    EmulatedCamera::msg_type_enabled,
    EmulatedCamera::start_preview,
    EmulatedCamera::stop_preview,
    EmulatedCamera::preview_enabled,
    EmulatedCamera::store_meta_data_in_buffers,
    EmulatedCamera::start_recording,
    EmulatedCamera::stop_recording,
    EmulatedCamera::recording_enabled,
    EmulatedCamera::release_recording_frame,
    EmulatedCamera::auto_focus,
    EmulatedCamera::cancel_auto_focus,
    EmulatedCamera::take_picture,
    EmulatedCamera::cancel_picture,
    EmulatedCamera::set_parameters,
    EmulatedCamera::get_parameters,
    EmulatedCamera::put_parameters,
    EmulatedCamera::send_command,
    EmulatedCamera::release,
    EmulatedCamera::dump
};

/****************************************************************************
 * Common keys
 ***************************************************************************/

const char EmulatedCamera::FACING_KEY[]         = "prop-facing";
const char EmulatedCamera::ORIENTATION_KEY[]    = "prop-orientation";
const char EmulatedCamera::RECORDING_HINT_KEY[] = "recording-hint";

/****************************************************************************
 * Common string values
 ***************************************************************************/

const char EmulatedCamera::FACING_BACK[]      = "back";
const char EmulatedCamera::FACING_FRONT[]     = "front";

/****************************************************************************
 * Parameter debugging helpers
 ***************************************************************************/

#if DEBUG_PARAM
static void PrintParamDiff(const CameraParameters& current,
                            const char* new_par)
{
    char tmp[2048];
    const char* wrk = new_par;

    /* Divided with ';' */
    const char* next = strchr(wrk, ';');
    while (next != NULL) {
        snprintf(tmp, sizeof(tmp), "%.*s", (int)(intptr_t)(next-wrk), wrk);
        /* in the form key=value */
        char* val = strchr(tmp, '=');
        if (val != NULL) {
            *val = '\0'; val++;
            const char* in_current = current.get(tmp);
            if (in_current != NULL) {
                if (strcmp(in_current, val)) {
                    ALOGD("=== Value changed: %s: %s -> %s", tmp, in_current, val);
                }
            } else {
                ALOGD("+++ New parameter: %s=%s", tmp, val);
            }
        } else {
            ALOGW("No value separator in %s", tmp);
        }
        wrk = next + 1;
        next = strchr(wrk, ';');
    }
}
#endif  /* DEBUG_PARAM */

}; /* namespace android */
