/*
 * Copyright (C) 2013 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 EmulatedFakeCamera3 that encapsulates
 * functionality of an advanced fake camera.
 */

#include <cstdint>
#include <inttypes.h>

//#define LOG_NDEBUG 0
//#define LOG_NNDEBUG 0
#define LOG_TAG "EmulatedCamera_FakeCamera3"
#include <cutils/properties.h>
#include <utils/Log.h>

#include <ui/Fence.h>
#include "EmulatedCameraFactory.h"
#include "EmulatedFakeCamera3.h"
#include "GrallocModule.h"

#include <cmath>
#include "fake-pipeline2/JpegCompressor.h"
#include "fake-pipeline2/Sensor.h"

#include <vector>

#if defined(LOG_NNDEBUG) && LOG_NNDEBUG == 0
#define ALOGVV ALOGV
#else
#define ALOGVV(...) ((void)0)
#endif

namespace android {

/**
 * Constants for camera capabilities
 */

const int64_t USEC = 1000LL;
const int64_t MSEC = USEC * 1000LL;
// const int64_t SEC = MSEC * 1000LL;

const int32_t EmulatedFakeCamera3::kAvailableFormats[] = {
    HAL_PIXEL_FORMAT_RAW16, HAL_PIXEL_FORMAT_BLOB, HAL_PIXEL_FORMAT_RGBA_8888,
    HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
    // These are handled by YCbCr_420_888
    //        HAL_PIXEL_FORMAT_YV12,
    //        HAL_PIXEL_FORMAT_YCrCb_420_SP,
    HAL_PIXEL_FORMAT_YCbCr_420_888, HAL_PIXEL_FORMAT_Y16};

/**
 * 3A constants
 */

// Default exposure and gain targets for different scenarios
const nsecs_t EmulatedFakeCamera3::kNormalExposureTime = 10 * MSEC;
const nsecs_t EmulatedFakeCamera3::kFacePriorityExposureTime = 30 * MSEC;
const int EmulatedFakeCamera3::kNormalSensitivity = 100;
const int EmulatedFakeCamera3::kFacePrioritySensitivity = 400;
const float EmulatedFakeCamera3::kExposureTrackRate = 0.1;
const int EmulatedFakeCamera3::kPrecaptureMinFrames = 10;
const int EmulatedFakeCamera3::kStableAeMaxFrames = 100;
const float EmulatedFakeCamera3::kExposureWanderMin = -2;
const float EmulatedFakeCamera3::kExposureWanderMax = 1;

/**
 * Camera device lifecycle methods
 */

EmulatedFakeCamera3::EmulatedFakeCamera3(int cameraId, bool facingBack,
                                         struct hw_module_t *module)
    : EmulatedCamera3(cameraId, module), mFacingBack(facingBack) {
  ALOGI("Constructing emulated fake camera 3: ID %d, facing %s", mCameraID,
        facingBack ? "back" : "front");

  for (size_t i = 0; i < CAMERA3_TEMPLATE_COUNT; i++) {
    mDefaultTemplates[i] = NULL;
  }
}

EmulatedFakeCamera3::~EmulatedFakeCamera3() {
  for (size_t i = 0; i < CAMERA3_TEMPLATE_COUNT; i++) {
    if (mDefaultTemplates[i] != NULL) {
      free_camera_metadata(mDefaultTemplates[i]);
    }
  }
}

status_t EmulatedFakeCamera3::Initialize(const cvd::CameraDefinition &params) {
  ALOGV("%s: E", __FUNCTION__);
  status_t res;

  if (mStatus != STATUS_ERROR) {
    ALOGE("%s: Already initialized!", __FUNCTION__);
    return INVALID_OPERATION;
  }

  res = getCameraCapabilities();
  if (res != OK) {
    ALOGE("%s: Unable to get camera capabilities: %s (%d)", __FUNCTION__,
          strerror(-res), res);
    return res;
  }

  res = constructStaticInfo(params);
  if (res != OK) {
    ALOGE("%s: Unable to allocate static info: %s (%d)", __FUNCTION__,
          strerror(-res), res);
    return res;
  }

  return EmulatedCamera3::Initialize(params);
}

status_t EmulatedFakeCamera3::connectCamera(hw_device_t **device) {
  ALOGV("%s: E", __FUNCTION__);
  Mutex::Autolock l(mLock);
  status_t res;

  if (mStatus != STATUS_CLOSED) {
    ALOGE("%s: Can't connect in state %d", __FUNCTION__, mStatus);
    return INVALID_OPERATION;
  }

  mSensor = new Sensor(mSensorWidth, mSensorHeight);
  mSensor->setSensorListener(this);

  res = mSensor->startUp();
  if (res != NO_ERROR) return res;

  mReadoutThread = new ReadoutThread(this);
  mJpegCompressor = new JpegCompressor();

  res = mReadoutThread->run("EmuCam3::readoutThread");
  if (res != NO_ERROR) return res;

  // Initialize fake 3A

  mControlMode = ANDROID_CONTROL_MODE_AUTO;
  mFacePriority = false;
  mAeMode = ANDROID_CONTROL_AE_MODE_ON;
  mAfMode = ANDROID_CONTROL_AF_MODE_AUTO;
  mAwbMode = ANDROID_CONTROL_AWB_MODE_AUTO;
  mAeState = ANDROID_CONTROL_AE_STATE_INACTIVE;
  mAfState = ANDROID_CONTROL_AF_STATE_INACTIVE;
  mAwbState = ANDROID_CONTROL_AWB_STATE_INACTIVE;
  mAeCounter = 0;
  mAeTargetExposureTime = kNormalExposureTime;
  mAeCurrentExposureTime = kNormalExposureTime;
  mAeCurrentSensitivity = kNormalSensitivity;

  return EmulatedCamera3::connectCamera(device);
}

status_t EmulatedFakeCamera3::closeCamera() {
  ALOGV("%s: E", __FUNCTION__);
  status_t res;
  {
    Mutex::Autolock l(mLock);
    if (mStatus == STATUS_CLOSED) return OK;

    res = mSensor->shutDown();
    if (res != NO_ERROR) {
      ALOGE("%s: Unable to shut down sensor: %d", __FUNCTION__, res);
      return res;
    }
    mSensor.clear();

    mReadoutThread->requestExit();
  }

  mReadoutThread->join();

  {
    Mutex::Autolock l(mLock);
    // Clear out private stream information
    for (StreamIterator s = mStreams.begin(); s != mStreams.end(); s++) {
      PrivateStreamInfo *privStream =
          static_cast<PrivateStreamInfo *>((*s)->priv);
      delete privStream;
      (*s)->priv = NULL;
    }
    mStreams.clear();
    mReadoutThread.clear();
  }

  return EmulatedCamera3::closeCamera();
}

status_t EmulatedFakeCamera3::getCameraInfo(struct camera_info *info) {
  info->facing = mFacingBack ? CAMERA_FACING_BACK : CAMERA_FACING_FRONT;
  info->orientation =
      EmulatedCameraFactory::Instance().getFakeCameraOrientation();
  info->resource_cost = 100;
  info->conflicting_devices = NULL;
  info->conflicting_devices_length = 0;
  return EmulatedCamera3::getCameraInfo(info);
}

status_t EmulatedFakeCamera3::setTorchMode(bool enabled) {
  if (!mFacingBack) {
    ALOGE("%s: Front camera does not have flash unit", __FUNCTION__);
    return INVALID_OPERATION;
  }
  EmulatedCameraFactory::Instance().onTorchModeStatusChanged(
      mCameraID, enabled ? TORCH_MODE_STATUS_AVAILABLE_ON
                         : TORCH_MODE_STATUS_AVAILABLE_OFF);
  return NO_ERROR;
}

/**
 * Camera3 interface methods
 */

status_t EmulatedFakeCamera3::configureStreams(
    camera3_stream_configuration *streamList) {
  Mutex::Autolock l(mLock);
  ALOGV("%s: %d streams", __FUNCTION__, streamList->num_streams);

  if (mStatus != STATUS_OPEN && mStatus != STATUS_READY) {
    ALOGE("%s: Cannot configure streams in state %d", __FUNCTION__, mStatus);
    return NO_INIT;
  }

  /**
   * Sanity-check input list.
   */
  if (streamList == NULL) {
    ALOGE("%s: NULL stream configuration", __FUNCTION__);
    return BAD_VALUE;
  }

  if (streamList->streams == NULL) {
    ALOGE("%s: NULL stream list", __FUNCTION__);
    return BAD_VALUE;
  }

  if (streamList->num_streams < 1) {
    ALOGE("%s: Bad number of streams requested: %d", __FUNCTION__,
          streamList->num_streams);
    return BAD_VALUE;
  }

  camera3_stream_t *inputStream = NULL;
  for (size_t i = 0; i < streamList->num_streams; i++) {
    camera3_stream_t *newStream = streamList->streams[i];

    if (newStream == NULL) {
      ALOGE("%s: Stream index %zu was NULL", __FUNCTION__, i);
      return BAD_VALUE;
    }

    ALOGV("%s: Stream %p (id %zu), type %d, usage 0x%x, format 0x%x",
          __FUNCTION__, newStream, i, newStream->stream_type, newStream->usage,
          newStream->format);

    if (newStream->stream_type == CAMERA3_STREAM_INPUT ||
        newStream->stream_type == CAMERA3_STREAM_BIDIRECTIONAL) {
      if (inputStream != NULL) {
        ALOGE("%s: Multiple input streams requested!", __FUNCTION__);
        return BAD_VALUE;
      }
      inputStream = newStream;
    }

    bool validFormat = false;
    for (size_t f = 0;
         f < sizeof(kAvailableFormats) / sizeof(kAvailableFormats[0]); f++) {
      if (newStream->format == kAvailableFormats[f]) {
        validFormat = true;
        break;
      }
    }
    if (!validFormat) {
      ALOGE("%s: Unsupported stream format 0x%x requested", __FUNCTION__,
            newStream->format);
      return BAD_VALUE;
    }
  }
  mInputStream = inputStream;

  /**
   * Initially mark all existing streams as not alive
   */
  for (StreamIterator s = mStreams.begin(); s != mStreams.end(); ++s) {
    PrivateStreamInfo *privStream =
        static_cast<PrivateStreamInfo *>((*s)->priv);
    privStream->alive = false;
  }

  /**
   * Find new streams and mark still-alive ones
   */
  for (size_t i = 0; i < streamList->num_streams; i++) {
    camera3_stream_t *newStream = streamList->streams[i];
    if (newStream->priv == NULL) {
      // New stream, construct info
      PrivateStreamInfo *privStream = new PrivateStreamInfo();
      privStream->alive = true;

      newStream->max_buffers = kMaxBufferCount;
      newStream->priv = privStream;
      mStreams.push_back(newStream);
    } else {
      // Existing stream, mark as still alive.
      PrivateStreamInfo *privStream =
          static_cast<PrivateStreamInfo *>(newStream->priv);
      privStream->alive = true;
    }
    // Always update usage and max buffers
    newStream->max_buffers = kMaxBufferCount;
    switch (newStream->stream_type) {
      case CAMERA3_STREAM_OUTPUT:
        newStream->usage = GRALLOC_USAGE_HW_CAMERA_WRITE;
        break;
      case CAMERA3_STREAM_INPUT:
        newStream->usage = GRALLOC_USAGE_HW_CAMERA_READ;
        break;
      case CAMERA3_STREAM_BIDIRECTIONAL:
        newStream->usage =
            GRALLOC_USAGE_HW_CAMERA_READ | GRALLOC_USAGE_HW_CAMERA_WRITE;
        break;
    }
  }

  /**
   * Reap the dead streams
   */
  for (StreamIterator s = mStreams.begin(); s != mStreams.end();) {
    PrivateStreamInfo *privStream =
        static_cast<PrivateStreamInfo *>((*s)->priv);
    if (!privStream->alive) {
      (*s)->priv = NULL;
      delete privStream;
      s = mStreams.erase(s);
    } else {
      ++s;
    }
  }

  /**
   * Can't reuse settings across configure call
   */
  mPrevSettings.clear();

  return OK;
}

status_t EmulatedFakeCamera3::registerStreamBuffers(
    const camera3_stream_buffer_set * /*bufferSet*/) {
  ALOGV("%s: E", __FUNCTION__);
  Mutex::Autolock l(mLock);

  // Should not be called in HAL versions >= 3.2

  ALOGE("%s: Should not be invoked on new HALs!", __FUNCTION__);
  return NO_INIT;
}

const camera_metadata_t *EmulatedFakeCamera3::constructDefaultRequestSettings(
    int type) {
  ALOGV("%s: E", __FUNCTION__);
  Mutex::Autolock l(mLock);

  if (type < 0 || type >= CAMERA3_TEMPLATE_COUNT) {
    ALOGE("%s: Unknown request settings template: %d", __FUNCTION__, type);
    return NULL;
  }

  if (!hasCapability(BACKWARD_COMPATIBLE) && type != CAMERA3_TEMPLATE_PREVIEW) {
    ALOGE("%s: Template %d not supported w/o BACKWARD_COMPATIBLE capability",
          __FUNCTION__, type);
    return NULL;
  }

  /**
   * Cache is not just an optimization - pointer returned has to live at
   * least as long as the camera device instance does.
   */
  if (mDefaultTemplates[type] != NULL) {
    return mDefaultTemplates[type];
  }

  CameraMetadata settings;

  /** android.request */

  static const uint8_t metadataMode = ANDROID_REQUEST_METADATA_MODE_FULL;
  settings.update(ANDROID_REQUEST_METADATA_MODE, &metadataMode, 1);

  static const int32_t id = 0;
  settings.update(ANDROID_REQUEST_ID, &id, 1);

  static const int32_t frameCount = 0;
  settings.update(ANDROID_REQUEST_FRAME_COUNT, &frameCount, 1);

  /** android.lens */

  static const float focalLength = 5.0f;
  settings.update(ANDROID_LENS_FOCAL_LENGTH, &focalLength, 1);

  if (hasCapability(BACKWARD_COMPATIBLE)) {
    static const float focusDistance = 0;
    settings.update(ANDROID_LENS_FOCUS_DISTANCE, &focusDistance, 1);

    static const float aperture = 2.8f;
    settings.update(ANDROID_LENS_APERTURE, &aperture, 1);

    static const float filterDensity = 0;
    settings.update(ANDROID_LENS_FILTER_DENSITY, &filterDensity, 1);

    static const uint8_t opticalStabilizationMode =
        ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
    settings.update(ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
                    &opticalStabilizationMode, 1);

    // FOCUS_RANGE set only in frame
  }

  /** android.sensor */

  if (hasCapability(MANUAL_SENSOR)) {
    static const int64_t exposureTime = 10 * MSEC;
    settings.update(ANDROID_SENSOR_EXPOSURE_TIME, &exposureTime, 1);

    static const int64_t frameDuration = 33333333L;  // 1/30 s
    settings.update(ANDROID_SENSOR_FRAME_DURATION, &frameDuration, 1);

    static const int32_t sensitivity = 100;
    settings.update(ANDROID_SENSOR_SENSITIVITY, &sensitivity, 1);
  }

  // TIMESTAMP set only in frame

  /** android.flash */

  if (hasCapability(BACKWARD_COMPATIBLE)) {
    static const uint8_t flashMode = ANDROID_FLASH_MODE_OFF;
    settings.update(ANDROID_FLASH_MODE, &flashMode, 1);

    static const uint8_t flashPower = 10;
    settings.update(ANDROID_FLASH_FIRING_POWER, &flashPower, 1);

    static const int64_t firingTime = 0;
    settings.update(ANDROID_FLASH_FIRING_TIME, &firingTime, 1);
  }

  /** Processing block modes */
  if (hasCapability(MANUAL_POST_PROCESSING)) {
    uint8_t hotPixelMode = 0;
    uint8_t demosaicMode = 0;
    uint8_t noiseMode = 0;
    uint8_t shadingMode = 0;
    uint8_t colorMode = 0;
    uint8_t tonemapMode = 0;
    uint8_t edgeMode = 0;
    switch (type) {
      case CAMERA3_TEMPLATE_STILL_CAPTURE:
        // fall-through
      case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
        // fall-through
      case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
        hotPixelMode = ANDROID_HOT_PIXEL_MODE_HIGH_QUALITY;
        demosaicMode = ANDROID_DEMOSAIC_MODE_HIGH_QUALITY;
        noiseMode = ANDROID_NOISE_REDUCTION_MODE_HIGH_QUALITY;
        shadingMode = ANDROID_SHADING_MODE_HIGH_QUALITY;
        colorMode = ANDROID_COLOR_CORRECTION_MODE_HIGH_QUALITY;
        tonemapMode = ANDROID_TONEMAP_MODE_HIGH_QUALITY;
        edgeMode = ANDROID_EDGE_MODE_HIGH_QUALITY;
        break;
      case CAMERA3_TEMPLATE_PREVIEW:
        // fall-through
      case CAMERA3_TEMPLATE_VIDEO_RECORD:
        // fall-through
      default:
        hotPixelMode = ANDROID_HOT_PIXEL_MODE_FAST;
        demosaicMode = ANDROID_DEMOSAIC_MODE_FAST;
        noiseMode = ANDROID_NOISE_REDUCTION_MODE_FAST;
        shadingMode = ANDROID_SHADING_MODE_FAST;
        colorMode = ANDROID_COLOR_CORRECTION_MODE_FAST;
        tonemapMode = ANDROID_TONEMAP_MODE_FAST;
        edgeMode = ANDROID_EDGE_MODE_FAST;
        break;
    }
    settings.update(ANDROID_HOT_PIXEL_MODE, &hotPixelMode, 1);
    settings.update(ANDROID_DEMOSAIC_MODE, &demosaicMode, 1);
    settings.update(ANDROID_NOISE_REDUCTION_MODE, &noiseMode, 1);
    settings.update(ANDROID_SHADING_MODE, &shadingMode, 1);
    settings.update(ANDROID_COLOR_CORRECTION_MODE, &colorMode, 1);
    settings.update(ANDROID_TONEMAP_MODE, &tonemapMode, 1);
    settings.update(ANDROID_EDGE_MODE, &edgeMode, 1);
  }

  /** android.colorCorrection */

  if (hasCapability(MANUAL_POST_PROCESSING)) {
    static const camera_metadata_rational colorTransform[9] = {
        {1, 1}, {0, 1}, {0, 1}, {0, 1}, {1, 1}, {0, 1}, {0, 1}, {0, 1}, {1, 1}};
    settings.update(ANDROID_COLOR_CORRECTION_TRANSFORM, colorTransform, 9);

    static const float colorGains[4] = {1.0f, 1.0f, 1.0f, 1.0f};
    settings.update(ANDROID_COLOR_CORRECTION_GAINS, colorGains, 4);
  }

  /** android.tonemap */

  if (hasCapability(MANUAL_POST_PROCESSING)) {
    static const float tonemapCurve[4] = {0.f, 0.f, 1.f, 1.f};
    settings.update(ANDROID_TONEMAP_CURVE_RED, tonemapCurve, 4);
    settings.update(ANDROID_TONEMAP_CURVE_GREEN, tonemapCurve, 4);
    settings.update(ANDROID_TONEMAP_CURVE_BLUE, tonemapCurve, 4);
  }

  /** android.scaler */
  if (hasCapability(BACKWARD_COMPATIBLE)) {
    static const int32_t cropRegion[4] = {0, 0, mSensorWidth, mSensorHeight};
    settings.update(ANDROID_SCALER_CROP_REGION, cropRegion, 4);
  }

  /** android.jpeg */
  if (hasCapability(BACKWARD_COMPATIBLE)) {
    static const uint8_t jpegQuality = 80;
    settings.update(ANDROID_JPEG_QUALITY, &jpegQuality, 1);

    static const int32_t thumbnailSize[2] = {640, 480};
    settings.update(ANDROID_JPEG_THUMBNAIL_SIZE, thumbnailSize, 2);

    static const uint8_t thumbnailQuality = 80;
    settings.update(ANDROID_JPEG_THUMBNAIL_QUALITY, &thumbnailQuality, 1);

    static const double gpsCoordinates[2] = {0, 0};
    settings.update(ANDROID_JPEG_GPS_COORDINATES, gpsCoordinates, 2);

    static const uint8_t gpsProcessingMethod[32] = "None";
    settings.update(ANDROID_JPEG_GPS_PROCESSING_METHOD, gpsProcessingMethod,
                    32);

    static const int64_t gpsTimestamp = 0;
    settings.update(ANDROID_JPEG_GPS_TIMESTAMP, &gpsTimestamp, 1);

    static const int32_t jpegOrientation = 0;
    settings.update(ANDROID_JPEG_ORIENTATION, &jpegOrientation, 1);
  }

  /** android.stats */

  if (hasCapability(BACKWARD_COMPATIBLE)) {
    static const uint8_t faceDetectMode =
        ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
    settings.update(ANDROID_STATISTICS_FACE_DETECT_MODE, &faceDetectMode, 1);

    static const uint8_t hotPixelMapMode =
        ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE_OFF;
    settings.update(ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE, &hotPixelMapMode, 1);
  }

  // faceRectangles, faceScores, faceLandmarks, faceIds, histogram,
  // sharpnessMap only in frames

  /** android.control */

  uint8_t controlIntent = 0;
  switch (type) {
    case CAMERA3_TEMPLATE_PREVIEW:
      controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
      break;
    case CAMERA3_TEMPLATE_STILL_CAPTURE:
      controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE;
      break;
    case CAMERA3_TEMPLATE_VIDEO_RECORD:
      controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD;
      break;
    case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
      controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT;
      break;
    case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
      controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG;
      break;
    case CAMERA3_TEMPLATE_MANUAL:
      controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_MANUAL;
      break;
    default:
      controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_CUSTOM;
      break;
  }
  settings.update(ANDROID_CONTROL_CAPTURE_INTENT, &controlIntent, 1);

  const uint8_t controlMode = (type == CAMERA3_TEMPLATE_MANUAL)
                                  ? ANDROID_CONTROL_MODE_OFF
                                  : ANDROID_CONTROL_MODE_AUTO;
  settings.update(ANDROID_CONTROL_MODE, &controlMode, 1);

  int32_t aeTargetFpsRange[2] = {5, 30};
  if (type == CAMERA3_TEMPLATE_VIDEO_RECORD ||
      type == CAMERA3_TEMPLATE_VIDEO_SNAPSHOT) {
    aeTargetFpsRange[0] = 30;
  }
  settings.update(ANDROID_CONTROL_AE_TARGET_FPS_RANGE, aeTargetFpsRange, 2);

  if (hasCapability(BACKWARD_COMPATIBLE)) {
    static const uint8_t effectMode = ANDROID_CONTROL_EFFECT_MODE_OFF;
    settings.update(ANDROID_CONTROL_EFFECT_MODE, &effectMode, 1);

    static const uint8_t sceneMode = ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY;
    settings.update(ANDROID_CONTROL_SCENE_MODE, &sceneMode, 1);

    const uint8_t aeMode = (type == CAMERA3_TEMPLATE_MANUAL)
                               ? ANDROID_CONTROL_AE_MODE_OFF
                               : ANDROID_CONTROL_AE_MODE_ON;
    settings.update(ANDROID_CONTROL_AE_MODE, &aeMode, 1);

    static const uint8_t aeLock = ANDROID_CONTROL_AE_LOCK_OFF;
    settings.update(ANDROID_CONTROL_AE_LOCK, &aeLock, 1);

    static const int32_t controlRegions[5] = {0, 0, 0, 0, 0};
    settings.update(ANDROID_CONTROL_AE_REGIONS, controlRegions, 5);

    static const int32_t aeExpCompensation = 0;
    settings.update(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
                    &aeExpCompensation, 1);

    static const uint8_t aeAntibandingMode =
        ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO;
    settings.update(ANDROID_CONTROL_AE_ANTIBANDING_MODE, &aeAntibandingMode, 1);

    static const uint8_t aePrecaptureTrigger =
        ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE;
    settings.update(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER, &aePrecaptureTrigger,
                    1);

    const uint8_t awbMode = (type == CAMERA3_TEMPLATE_MANUAL)
                                ? ANDROID_CONTROL_AWB_MODE_OFF
                                : ANDROID_CONTROL_AWB_MODE_AUTO;
    settings.update(ANDROID_CONTROL_AWB_MODE, &awbMode, 1);

    static const uint8_t awbLock = ANDROID_CONTROL_AWB_LOCK_OFF;
    settings.update(ANDROID_CONTROL_AWB_LOCK, &awbLock, 1);

    uint8_t afMode = 0;

    if (mFacingBack) {
      switch (type) {
        case CAMERA3_TEMPLATE_PREVIEW:
          afMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE;
          break;
        case CAMERA3_TEMPLATE_STILL_CAPTURE:
          afMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE;
          break;
        case CAMERA3_TEMPLATE_VIDEO_RECORD:
          afMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO;
          break;
        case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
          afMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO;
          break;
        case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
          afMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE;
          break;
        case CAMERA3_TEMPLATE_MANUAL:
          afMode = ANDROID_CONTROL_AF_MODE_OFF;
          break;
        default:
          afMode = ANDROID_CONTROL_AF_MODE_AUTO;
          break;
      }
    } else {
      afMode = ANDROID_CONTROL_AF_MODE_OFF;
    }
    settings.update(ANDROID_CONTROL_AF_MODE, &afMode, 1);

    settings.update(ANDROID_CONTROL_AF_REGIONS, controlRegions, 5);

    static const uint8_t afTrigger = ANDROID_CONTROL_AF_TRIGGER_IDLE;
    settings.update(ANDROID_CONTROL_AF_TRIGGER, &afTrigger, 1);

    static const uint8_t vstabMode =
        ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF;
    settings.update(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE, &vstabMode, 1);

    static const uint8_t blackLevelLock = ANDROID_BLACK_LEVEL_LOCK_OFF;
    settings.update(ANDROID_BLACK_LEVEL_LOCK, &blackLevelLock, 1);

    static const uint8_t lensShadingMapMode =
        ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF;
    settings.update(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
                    &lensShadingMapMode, 1);

    static const uint8_t aberrationMode =
        ANDROID_COLOR_CORRECTION_ABERRATION_MODE_FAST;
    settings.update(ANDROID_COLOR_CORRECTION_ABERRATION_MODE, &aberrationMode,
                    1);

    static const int32_t testPatternMode = ANDROID_SENSOR_TEST_PATTERN_MODE_OFF;
    settings.update(ANDROID_SENSOR_TEST_PATTERN_MODE, &testPatternMode, 1);
  }

  mDefaultTemplates[type] = settings.release();

  return mDefaultTemplates[type];
}

status_t EmulatedFakeCamera3::processCaptureRequest(
    camera3_capture_request *request) {
  Mutex::Autolock l(mLock);
  status_t res;

  /** Validation */

  if (mStatus < STATUS_READY) {
    ALOGE("%s: Can't submit capture requests in state %d", __FUNCTION__,
          mStatus);
    return INVALID_OPERATION;
  }

  if (request == NULL) {
    ALOGE("%s: NULL request!", __FUNCTION__);
    return BAD_VALUE;
  }

  uint32_t frameNumber = request->frame_number;

  if (request->settings == NULL && mPrevSettings.isEmpty()) {
    ALOGE(
        "%s: Request %d: NULL settings for first request after"
        "configureStreams()",
        __FUNCTION__, frameNumber);
    return BAD_VALUE;
  }

  if (request->input_buffer != NULL &&
      request->input_buffer->stream != mInputStream) {
    ALOGE("%s: Request %d: Input buffer not from input stream!", __FUNCTION__,
          frameNumber);
    ALOGV("%s: Bad stream %p, expected: %p", __FUNCTION__,
          request->input_buffer->stream, mInputStream);
    ALOGV("%s: Bad stream type %d, expected stream type %d", __FUNCTION__,
          request->input_buffer->stream->stream_type,
          mInputStream ? mInputStream->stream_type : -1);

    return BAD_VALUE;
  }

  if (request->num_output_buffers < 1 || request->output_buffers == NULL) {
    ALOGE("%s: Request %d: No output buffers provided!", __FUNCTION__,
          frameNumber);
    return BAD_VALUE;
  }

  // Validate all buffers, starting with input buffer if it's given

  ssize_t idx;
  const camera3_stream_buffer_t *b;
  if (request->input_buffer != NULL) {
    idx = -1;
    b = request->input_buffer;
  } else {
    idx = 0;
    b = request->output_buffers;
  }
  do {
    PrivateStreamInfo *priv = static_cast<PrivateStreamInfo *>(b->stream->priv);
    if (priv == NULL) {
      ALOGE("%s: Request %d: Buffer %zu: Unconfigured stream!", __FUNCTION__,
            frameNumber, idx);
      return BAD_VALUE;
    }
    if (!priv->alive) {
      ALOGE("%s: Request %d: Buffer %zu: Dead stream!", __FUNCTION__,
            frameNumber, idx);
      return BAD_VALUE;
    }
    if (b->status != CAMERA3_BUFFER_STATUS_OK) {
      ALOGE("%s: Request %d: Buffer %zu: Status not OK!", __FUNCTION__,
            frameNumber, idx);
      return BAD_VALUE;
    }
    if (b->release_fence != -1) {
      ALOGE("%s: Request %d: Buffer %zu: Has a release fence!", __FUNCTION__,
            frameNumber, idx);
      return BAD_VALUE;
    }
    if (b->buffer == NULL) {
      ALOGE("%s: Request %d: Buffer %zu: NULL buffer handle!", __FUNCTION__,
            frameNumber, idx);
      return BAD_VALUE;
    }
    idx++;
    b = &(request->output_buffers[idx]);
  } while (idx < (ssize_t)request->num_output_buffers);

  // TODO: Validate settings parameters

  /**
   * Start processing this request
   */

  mStatus = STATUS_ACTIVE;

  CameraMetadata settings;

  if (request->settings == NULL) {
    settings.acquire(mPrevSettings);
  } else {
    settings = request->settings;
  }

  res = process3A(settings);
  if (res != OK) {
    return res;
  }

  // TODO: Handle reprocessing

  /**
   * Get ready for sensor config
   */

  nsecs_t exposureTime;
  nsecs_t frameDuration;
  uint32_t sensitivity;
  bool needJpeg = false;
  camera_metadata_entry_t entry;

  entry = settings.find(ANDROID_SENSOR_EXPOSURE_TIME);
  exposureTime =
      (entry.count > 0) ? entry.data.i64[0] : Sensor::kExposureTimeRange[0];
  entry = settings.find(ANDROID_SENSOR_FRAME_DURATION);
  frameDuration =
      (entry.count > 0) ? entry.data.i64[0] : Sensor::kFrameDurationRange[0];
  entry = settings.find(ANDROID_SENSOR_SENSITIVITY);
  sensitivity =
      (entry.count > 0) ? entry.data.i32[0] : Sensor::kSensitivityRange[0];

  if (exposureTime > frameDuration) {
    frameDuration = exposureTime + Sensor::kMinVerticalBlank;
    settings.update(ANDROID_SENSOR_FRAME_DURATION, &frameDuration, 1);
  }

  Buffers *sensorBuffers = new Buffers();
  HalBufferVector *buffers = new HalBufferVector();

  sensorBuffers->setCapacity(request->num_output_buffers);
  buffers->setCapacity(request->num_output_buffers);

  // Process all the buffers we got for output, constructing internal buffer
  // structures for them, and lock them for writing.
  for (size_t i = 0; i < request->num_output_buffers; i++) {
    const camera3_stream_buffer &srcBuf = request->output_buffers[i];
    StreamBuffer destBuf;
    destBuf.streamId = kGenericStreamId;
    destBuf.width = srcBuf.stream->width;
    destBuf.height = srcBuf.stream->height;
    // For GCE, IMPLEMENTATION_DEFINED is always RGBx_8888
    destBuf.format =
        (srcBuf.stream->format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED)
            ? HAL_PIXEL_FORMAT_RGBA_8888
            : srcBuf.stream->format;
    destBuf.stride = srcBuf.stream->width;
    destBuf.dataSpace = srcBuf.stream->data_space;
    destBuf.buffer = srcBuf.buffer;

    if (destBuf.format == HAL_PIXEL_FORMAT_BLOB) {
      needJpeg = true;
    }

    // Wait on fence
    sp<Fence> bufferAcquireFence = new Fence(srcBuf.acquire_fence);
    res = bufferAcquireFence->wait(kFenceTimeoutMs);
    if (res == TIMED_OUT) {
      ALOGE("%s: Request %d: Buffer %zu: Fence timed out after %d ms",
            __FUNCTION__, frameNumber, i, kFenceTimeoutMs);
    }
    if (res == OK) {
      // Lock buffer for writing
      if (srcBuf.stream->format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
        if (destBuf.format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
          android_ycbcr ycbcr = android_ycbcr();
          res = GrallocModule::getInstance().lock_ycbcr(
              *(destBuf.buffer), GRALLOC_USAGE_HW_CAMERA_WRITE, 0, 0,
              destBuf.width, destBuf.height, &ycbcr);
          // This is only valid because we know that emulator's
          // YCbCr_420_888 is really contiguous NV21 under the hood
          destBuf.img = static_cast<uint8_t *>(ycbcr.y);
        } else {
          ALOGE("Unexpected private format for flexible YUV: 0x%x",
                destBuf.format);
          res = INVALID_OPERATION;
        }
      } else {
        res = GrallocModule::getInstance().lock(
            *(destBuf.buffer), GRALLOC_USAGE_HW_CAMERA_WRITE, 0, 0,
            destBuf.width, destBuf.height, (void **)&(destBuf.img));
      }
      if (res != OK) {
        ALOGE("%s: Request %d: Buffer %zu: Unable to lock buffer", __FUNCTION__,
              frameNumber, i);
      }
    }

    if (res != OK) {
      // Either waiting or locking failed. Unlock locked buffers and bail
      // out.
      for (size_t j = 0; j < i; j++) {
        GrallocModule::getInstance().unlock(
            *(request->output_buffers[i].buffer));
      }
      delete sensorBuffers;
      delete buffers;
      return NO_INIT;
    }

    sensorBuffers->push_back(destBuf);
    buffers->push_back(srcBuf);
  }

  /**
   * Wait for JPEG compressor to not be busy, if needed
   */
  if (needJpeg) {
    bool ready = mJpegCompressor->waitForDone(kJpegTimeoutNs);
    if (!ready) {
      ALOGE("%s: Timeout waiting for JPEG compression to complete!",
            __FUNCTION__);
      return NO_INIT;
    }
    res = mJpegCompressor->reserve();
    if (res != OK) {
      ALOGE("%s: Error managing JPEG compressor resources, can't reserve it!",
            __FUNCTION__);
      return NO_INIT;
    }
  }

  /**
   * Wait until the in-flight queue has room
   */
  res = mReadoutThread->waitForReadout();
  if (res != OK) {
    ALOGE("%s: Timeout waiting for previous requests to complete!",
          __FUNCTION__);
    return NO_INIT;
  }

  /**
   * Wait until sensor's ready. This waits for lengthy amounts of time with
   * mLock held, but the interface spec is that no other calls may by done to
   * the HAL by the framework while process_capture_request is happening.
   */
  int syncTimeoutCount = 0;
  while (!mSensor->waitForVSync(kSyncWaitTimeout)) {
    if (mStatus == STATUS_ERROR) {
      return NO_INIT;
    }
    if (syncTimeoutCount == kMaxSyncTimeoutCount) {
      ALOGE("%s: Request %d: Sensor sync timed out after %" PRId64 " ms",
            __FUNCTION__, frameNumber,
            kSyncWaitTimeout * kMaxSyncTimeoutCount / 1000000);
      return NO_INIT;
    }
    syncTimeoutCount++;
  }

  /**
   * Configure sensor and queue up the request to the readout thread
   */
  mSensor->setExposureTime(exposureTime);
  mSensor->setFrameDuration(frameDuration);
  mSensor->setSensitivity(sensitivity);
  mSensor->setDestinationBuffers(sensorBuffers);
  mSensor->setFrameNumber(request->frame_number);

  ReadoutThread::Request r;
  r.frameNumber = request->frame_number;
  r.settings = settings;
  r.sensorBuffers = sensorBuffers;
  r.buffers = buffers;

  mReadoutThread->queueCaptureRequest(r);
  ALOGVV("%s: Queued frame %d", __FUNCTION__, request->frame_number);

  // Cache the settings for next time
  mPrevSettings.acquire(settings);

  return OK;
}

status_t EmulatedFakeCamera3::flush() {
  ALOGW("%s: Not implemented; ignored", __FUNCTION__);
  return OK;
}

/** Debug methods */

void EmulatedFakeCamera3::dump(int /*fd*/) {}

/**
 * Private methods
 */

status_t EmulatedFakeCamera3::getCameraCapabilities() {
  const char *key =
      mFacingBack ? "qemu.sf.back_camera_caps" : "qemu.sf.front_camera_caps";

  /* Defined by 'qemu.sf.*_camera_caps' boot property: if the
   * property doesn't exist, it is assumed to list FULL. */
  char prop[PROPERTY_VALUE_MAX];
  if (property_get(key, prop, NULL) > 0) {
    char *saveptr = nullptr;
    char *cap = strtok_r(prop, " ,", &saveptr);
    while (cap != NULL) {
      for (int i = 0; i < NUM_CAPABILITIES; i++) {
        if (!strcasecmp(cap, sAvailableCapabilitiesStrings[i])) {
          mCapabilities.add(static_cast<AvailableCapabilities>(i));
          break;
        }
      }
      cap = strtok_r(NULL, " ,", &saveptr);
    }
    if (mCapabilities.size() == 0) {
      ALOGE("qemu.sf.back_camera_caps had no valid capabilities: %s", prop);
    }
  }
  // Default to FULL_LEVEL plus RAW if nothing is defined
  if (mCapabilities.size() == 0) {
    mCapabilities.add(FULL_LEVEL);
    mCapabilities.add(RAW);
  }

  // Add level-based caps
  if (hasCapability(FULL_LEVEL)) {
    mCapabilities.add(BURST_CAPTURE);
    mCapabilities.add(READ_SENSOR_SETTINGS);
    mCapabilities.add(MANUAL_SENSOR);
    mCapabilities.add(MANUAL_POST_PROCESSING);
  };

  // Backwards-compatible is required for most other caps
  // Not required for DEPTH_OUTPUT, though.
  if (hasCapability(BURST_CAPTURE) || hasCapability(READ_SENSOR_SETTINGS) ||
      hasCapability(RAW) || hasCapability(MANUAL_SENSOR) ||
      hasCapability(MANUAL_POST_PROCESSING) ||
      hasCapability(PRIVATE_REPROCESSING) || hasCapability(YUV_REPROCESSING) ||
      hasCapability(CONSTRAINED_HIGH_SPEED_VIDEO)) {
    mCapabilities.add(BACKWARD_COMPATIBLE);
  }

  ALOGI("Camera %d capabilities:", mCameraID);
  for (size_t i = 0; i < mCapabilities.size(); i++) {
    ALOGI("  %s", sAvailableCapabilitiesStrings[mCapabilities[i]]);
  }

  return OK;
}

bool EmulatedFakeCamera3::hasCapability(AvailableCapabilities cap) {
  ssize_t idx = mCapabilities.indexOf(cap);
  return idx >= 0;
}

status_t EmulatedFakeCamera3::constructStaticInfo(
    const cvd::CameraDefinition &params) {
  CameraMetadata info;
  Vector<int32_t> availableCharacteristicsKeys;
  status_t res;

  int32_t width = 0, height = 0;

  /* TODO(ender): this currently supports only maximum resolution. */
  for (size_t index = 0; index < params.resolutions.size(); ++index) {
    if (width <= params.resolutions[index].width &&
        height <= params.resolutions[index].height) {
      width = params.resolutions[index].width;
      height = params.resolutions[index].height;
    }
  }

  if (width < 640 || height < 480) {
    width = 640;
    height = 480;
  }

  mSensorWidth = width;
  mSensorHeight = height;

#define ADD_STATIC_ENTRY(name, varptr, count) \
  availableCharacteristicsKeys.add(name);     \
  res = info.update(name, varptr, count);     \
  if (res != OK) return res

  // android.sensor

  if (hasCapability(MANUAL_SENSOR)) {
    ADD_STATIC_ENTRY(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
                     Sensor::kExposureTimeRange, 2);

    ADD_STATIC_ENTRY(ANDROID_SENSOR_INFO_MAX_FRAME_DURATION,
                     &Sensor::kFrameDurationRange[1], 1);

    ADD_STATIC_ENTRY(ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
                     Sensor::kSensitivityRange,
                     sizeof(Sensor::kSensitivityRange) / sizeof(int32_t));

    ADD_STATIC_ENTRY(ANDROID_SENSOR_MAX_ANALOG_SENSITIVITY,
                     &Sensor::kSensitivityRange[1], 1);
  }

  static const float sensorPhysicalSize[2] = {3.20f, 2.40f};  // mm
  ADD_STATIC_ENTRY(ANDROID_SENSOR_INFO_PHYSICAL_SIZE, sensorPhysicalSize, 2);

  const int32_t pixelArray[] = {mSensorWidth, mSensorHeight};
  ADD_STATIC_ENTRY(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE, pixelArray, 2);
  const int32_t activeArray[] = {0, 0, mSensorWidth, mSensorHeight};
  ADD_STATIC_ENTRY(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE, activeArray, 4);

  static const int32_t orientation = 90;  // Aligned with 'long edge'
  ADD_STATIC_ENTRY(ANDROID_SENSOR_ORIENTATION, &orientation, 1);

  static const uint8_t timestampSource =
      ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME;
  ADD_STATIC_ENTRY(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE, &timestampSource, 1);

  if (hasCapability(RAW)) {
    ADD_STATIC_ENTRY(ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
                     &Sensor::kColorFilterArrangement, 1);

    ADD_STATIC_ENTRY(ANDROID_SENSOR_INFO_WHITE_LEVEL,
                     (int32_t *)&Sensor::kMaxRawValue, 1);

    static const int32_t blackLevelPattern[4] = {
        (int32_t)Sensor::kBlackLevel, (int32_t)Sensor::kBlackLevel,
        (int32_t)Sensor::kBlackLevel, (int32_t)Sensor::kBlackLevel};
    ADD_STATIC_ENTRY(ANDROID_SENSOR_BLACK_LEVEL_PATTERN, blackLevelPattern,
                     sizeof(blackLevelPattern) / sizeof(int32_t));
  }

  if (hasCapability(BACKWARD_COMPATIBLE)) {
    static const int32_t availableTestPatternModes[] = {
        ANDROID_SENSOR_TEST_PATTERN_MODE_OFF};
    ADD_STATIC_ENTRY(ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
                     availableTestPatternModes,
                     sizeof(availableTestPatternModes) / sizeof(int32_t));
  }

  // android.lens

  static const float focalLength = 3.30f;  // mm
  ADD_STATIC_ENTRY(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS, &focalLength, 1);

  if (hasCapability(BACKWARD_COMPATIBLE)) {
    // 5 cm min focus distance for back camera, infinity (fixed focus) for front
    const float minFocusDistance = mFacingBack ? 1.0 / 0.05 : 0.0;
    ADD_STATIC_ENTRY(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
                     &minFocusDistance, 1);

    // 5 m hyperfocal distance for back camera, infinity (fixed focus) for front
    const float hyperFocalDistance = mFacingBack ? 1.0 / 5.0 : 0.0;
    ADD_STATIC_ENTRY(ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE, &hyperFocalDistance,
                     1);

    static const float aperture = 2.8f;
    ADD_STATIC_ENTRY(ANDROID_LENS_INFO_AVAILABLE_APERTURES, &aperture, 1);
    static const float filterDensity = 0;
    ADD_STATIC_ENTRY(ANDROID_LENS_INFO_AVAILABLE_FILTER_DENSITIES,
                     &filterDensity, 1);
    static const uint8_t availableOpticalStabilization =
        ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
    ADD_STATIC_ENTRY(ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
                     &availableOpticalStabilization, 1);

    static const int32_t lensShadingMapSize[] = {1, 1};
    ADD_STATIC_ENTRY(ANDROID_LENS_INFO_SHADING_MAP_SIZE, lensShadingMapSize,
                     sizeof(lensShadingMapSize) / sizeof(int32_t));

    static const uint8_t lensFocusCalibration =
        ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION_APPROXIMATE;
    ADD_STATIC_ENTRY(ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION,
                     &lensFocusCalibration, 1);
  }

  if (hasCapability(DEPTH_OUTPUT)) {
    // These could be included for non-DEPTH capability as well, but making this
    // variable for testing coverage

    // 90 degree rotation to align with long edge of a phone device that's by
    // default portrait
    static const float qO[] = {0.707107f, 0.f, 0.f, 0.707107f};

    // Either a 180-degree rotation for back-facing, or no rotation for
    // front-facing
    const float qF[] = {0, (mFacingBack ? 1.f : 0.f), 0,
                        (mFacingBack ? 0.f : 1.f)};

    // Quarternion product, orientation change then facing
    const float lensPoseRotation[] = {
        qO[0] * qF[0] - qO[1] * qF[1] - qO[2] * qF[2] - qO[3] * qF[3],
        qO[0] * qF[1] + qO[1] * qF[0] + qO[2] * qF[3] - qO[3] * qF[2],
        qO[0] * qF[2] + qO[2] * qF[0] + qO[1] * qF[3] - qO[3] * qF[1],
        qO[0] * qF[3] + qO[3] * qF[0] + qO[1] * qF[2] - qO[2] * qF[1]};

    ADD_STATIC_ENTRY(ANDROID_LENS_POSE_ROTATION, lensPoseRotation,
                     sizeof(lensPoseRotation) / sizeof(float));

    // Only one camera facing each way, so 0 translation needed to the center of
    // the 'main' camera
    static const float lensPoseTranslation[] = {0.f, 0.f, 0.f};

    ADD_STATIC_ENTRY(ANDROID_LENS_POSE_TRANSLATION, lensPoseTranslation,
                     sizeof(lensPoseTranslation) / sizeof(float));

    // Intrinsics are 'ideal' (f_x, f_y, c_x, c_y, s) match focal length and
    // active array size
    float f_x = focalLength * mSensorWidth / sensorPhysicalSize[0];
    float f_y = focalLength * mSensorHeight / sensorPhysicalSize[1];
    float c_x = mSensorWidth / 2.f;
    float c_y = mSensorHeight / 2.f;
    float s = 0.f;
    const float lensIntrinsics[] = {f_x, f_y, c_x, c_y, s};

    ADD_STATIC_ENTRY(ANDROID_LENS_INTRINSIC_CALIBRATION, lensIntrinsics,
                     sizeof(lensIntrinsics) / sizeof(float));

    // No radial or tangential distortion

    float lensRadialDistortion[] = {1.0f, 0.f, 0.f, 0.f, 0.f, 0.f};

    ADD_STATIC_ENTRY(ANDROID_LENS_RADIAL_DISTORTION, lensRadialDistortion,
                     sizeof(lensRadialDistortion) / sizeof(float));
  }

  const uint8_t lensFacing =
      mFacingBack ? ANDROID_LENS_FACING_BACK : ANDROID_LENS_FACING_FRONT;
  ADD_STATIC_ENTRY(ANDROID_LENS_FACING, &lensFacing, 1);

  // android.flash

  const uint8_t flashAvailable = mFacingBack;
  ADD_STATIC_ENTRY(ANDROID_FLASH_INFO_AVAILABLE, &flashAvailable, 1);

  // android.tonemap

  if (hasCapability(MANUAL_POST_PROCESSING)) {
    static const int32_t tonemapCurvePoints = 128;
    ADD_STATIC_ENTRY(ANDROID_TONEMAP_MAX_CURVE_POINTS, &tonemapCurvePoints, 1);

    static const uint8_t availableToneMapModes[] = {
        ANDROID_TONEMAP_MODE_CONTRAST_CURVE, ANDROID_TONEMAP_MODE_FAST,
        ANDROID_TONEMAP_MODE_HIGH_QUALITY};
    ADD_STATIC_ENTRY(ANDROID_TONEMAP_AVAILABLE_TONE_MAP_MODES,
                     availableToneMapModes, sizeof(availableToneMapModes));
  }

  // android.scaler

  const std::vector<int32_t> availableStreamConfigurationsBasic = {
      HAL_PIXEL_FORMAT_BLOB,
      width,
      height,
      ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT,
      HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
      320,
      240,
      ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT,
      HAL_PIXEL_FORMAT_YCbCr_420_888,
      320,
      240,
      ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT,
      HAL_PIXEL_FORMAT_BLOB,
      320,
      240,
      ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT,
  };

  // Always need to include 640x480 in basic formats
  const std::vector<int32_t> availableStreamConfigurationsBasic640 = {
      HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
      640,
      480,
      ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT,
      HAL_PIXEL_FORMAT_YCbCr_420_888,
      640,
      480,
      ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT,
      HAL_PIXEL_FORMAT_BLOB,
      640,
      480,
      ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT};

  const std::vector<int32_t> availableStreamConfigurationsRaw = {
      HAL_PIXEL_FORMAT_RAW16,
      width,
      height,
      ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT,
  };

  const std::vector<int32_t> availableStreamConfigurationsBurst = {
      HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
      width,
      height,
      ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT,
      HAL_PIXEL_FORMAT_YCbCr_420_888,
      width,
      height,
      ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT,
      HAL_PIXEL_FORMAT_RGBA_8888,
      width,
      height,
      ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT,
  };

  std::vector<int32_t> availableStreamConfigurations;

  if (hasCapability(BACKWARD_COMPATIBLE)) {
    availableStreamConfigurations.insert(
        availableStreamConfigurations.end(),
        availableStreamConfigurationsBasic.begin(),
        availableStreamConfigurationsBasic.end());
    if (width > 640) {
      availableStreamConfigurations.insert(
          availableStreamConfigurations.end(),
          availableStreamConfigurationsBasic640.begin(),
          availableStreamConfigurationsBasic640.end());
    }
  }
  if (hasCapability(RAW)) {
    availableStreamConfigurations.insert(
        availableStreamConfigurations.end(),
        availableStreamConfigurationsRaw.begin(),
        availableStreamConfigurationsRaw.end());
  }
  if (hasCapability(BURST_CAPTURE)) {
    availableStreamConfigurations.insert(
        availableStreamConfigurations.end(),
        availableStreamConfigurationsBurst.begin(),
        availableStreamConfigurationsBurst.end());
  }

  if (availableStreamConfigurations.size() > 0) {
    ADD_STATIC_ENTRY(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
                     &availableStreamConfigurations[0],
                     availableStreamConfigurations.size());
  }

  const std::vector<int64_t> availableMinFrameDurationsBasic = {
      HAL_PIXEL_FORMAT_BLOB,
      width,
      height,
      Sensor::kFrameDurationRange[0],
      HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
      320,
      240,
      Sensor::kFrameDurationRange[0],
      HAL_PIXEL_FORMAT_YCbCr_420_888,
      320,
      240,
      Sensor::kFrameDurationRange[0],
      HAL_PIXEL_FORMAT_BLOB,
      320,
      240,
      Sensor::kFrameDurationRange[0],
  };

  // Always need to include 640x480 in basic formats
  const std::vector<int64_t> availableMinFrameDurationsBasic640 = {
      HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
      640,
      480,
      Sensor::kFrameDurationRange[0],
      HAL_PIXEL_FORMAT_YCbCr_420_888,
      640,
      480,
      Sensor::kFrameDurationRange[0],
      HAL_PIXEL_FORMAT_BLOB,
      640,
      480,
      Sensor::kFrameDurationRange[0]};

  const std::vector<int64_t> availableMinFrameDurationsRaw = {
      HAL_PIXEL_FORMAT_RAW16,
      width,
      height,
      Sensor::kFrameDurationRange[0],
  };

  const std::vector<int64_t> availableMinFrameDurationsBurst = {
      HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
      width,
      height,
      Sensor::kFrameDurationRange[0],
      HAL_PIXEL_FORMAT_YCbCr_420_888,
      width,
      height,
      Sensor::kFrameDurationRange[0],
      HAL_PIXEL_FORMAT_RGBA_8888,
      width,
      height,
      Sensor::kFrameDurationRange[0],
  };

  std::vector<int64_t> availableMinFrameDurations;

  if (hasCapability(BACKWARD_COMPATIBLE)) {
    availableMinFrameDurations.insert(availableMinFrameDurations.end(),
                                      availableMinFrameDurationsBasic.begin(),
                                      availableMinFrameDurationsBasic.end());
    if (width > 640) {
      availableMinFrameDurations.insert(
          availableMinFrameDurations.end(),
          availableMinFrameDurationsBasic640.begin(),
          availableMinFrameDurationsBasic640.end());
    }
  }
  if (hasCapability(RAW)) {
    availableMinFrameDurations.insert(availableMinFrameDurations.end(),
                                      availableMinFrameDurationsRaw.begin(),
                                      availableMinFrameDurationsRaw.end());
  }
  if (hasCapability(BURST_CAPTURE)) {
    availableMinFrameDurations.insert(availableMinFrameDurations.end(),
                                      availableMinFrameDurationsBurst.begin(),
                                      availableMinFrameDurationsBurst.end());
  }

  if (availableMinFrameDurations.size() > 0) {
    ADD_STATIC_ENTRY(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
                     &availableMinFrameDurations[0],
                     availableMinFrameDurations.size());
  }

  const std::vector<int64_t> availableStallDurationsBasic = {
      HAL_PIXEL_FORMAT_BLOB,
      width,
      height,
      Sensor::kFrameDurationRange[0],
      HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
      320,
      240,
      0,
      HAL_PIXEL_FORMAT_YCbCr_420_888,
      320,
      240,
      0,
      HAL_PIXEL_FORMAT_RGBA_8888,
      320,
      240,
      0,
  };

  // Always need to include 640x480 in basic formats
  const std::vector<int64_t> availableStallDurationsBasic640 = {
      HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
      640,
      480,
      0,
      HAL_PIXEL_FORMAT_YCbCr_420_888,
      640,
      480,
      0,
      HAL_PIXEL_FORMAT_BLOB,
      640,
      480,
      Sensor::kFrameDurationRange[0]};

  const std::vector<int64_t> availableStallDurationsRaw = {
      HAL_PIXEL_FORMAT_RAW16, width, height, Sensor::kFrameDurationRange[0]};
  const std::vector<int64_t> availableStallDurationsBurst = {
      HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
      width,
      height,
      0,
      HAL_PIXEL_FORMAT_YCbCr_420_888,
      width,
      height,
      0,
      HAL_PIXEL_FORMAT_RGBA_8888,
      width,
      height,
      0};

  std::vector<int64_t> availableStallDurations;

  if (hasCapability(BACKWARD_COMPATIBLE)) {
    availableStallDurations.insert(availableStallDurations.end(),
                                   availableStallDurationsBasic.begin(),
                                   availableStallDurationsBasic.end());
    if (width > 640) {
      availableStallDurations.insert(availableStallDurations.end(),
                                     availableStallDurationsBasic640.begin(),
                                     availableStallDurationsBasic640.end());
    }
  }
  if (hasCapability(RAW)) {
    availableStallDurations.insert(availableStallDurations.end(),
                                   availableStallDurationsRaw.begin(),
                                   availableStallDurationsRaw.end());
  }
  if (hasCapability(BURST_CAPTURE)) {
    availableStallDurations.insert(availableStallDurations.end(),
                                   availableStallDurationsBurst.begin(),
                                   availableStallDurationsBurst.end());
  }

  if (availableStallDurations.size() > 0) {
    ADD_STATIC_ENTRY(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
                     &availableStallDurations[0],
                     availableStallDurations.size());
  }

  if (hasCapability(BACKWARD_COMPATIBLE)) {
    static const uint8_t croppingType = ANDROID_SCALER_CROPPING_TYPE_FREEFORM;
    ADD_STATIC_ENTRY(ANDROID_SCALER_CROPPING_TYPE, &croppingType, 1);

    static const float maxZoom = 10;
    ADD_STATIC_ENTRY(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM, &maxZoom, 1);
  }

  // android.jpeg

  if (hasCapability(BACKWARD_COMPATIBLE)) {
    static const int32_t jpegThumbnailSizes[] = {0, 0, 160, 120, 320, 240};
    ADD_STATIC_ENTRY(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES, jpegThumbnailSizes,
                     sizeof(jpegThumbnailSizes) / sizeof(int32_t));

    static const int32_t jpegMaxSize = JpegCompressor::kMaxJpegSize;
    ADD_STATIC_ENTRY(ANDROID_JPEG_MAX_SIZE, &jpegMaxSize, 1);
  }

  // android.stats

  if (hasCapability(BACKWARD_COMPATIBLE)) {
    static const uint8_t availableFaceDetectModes[] = {
        ANDROID_STATISTICS_FACE_DETECT_MODE_OFF,
        ANDROID_STATISTICS_FACE_DETECT_MODE_SIMPLE,
        ANDROID_STATISTICS_FACE_DETECT_MODE_FULL};
    ADD_STATIC_ENTRY(ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
                     availableFaceDetectModes,
                     sizeof(availableFaceDetectModes));

    static const int32_t maxFaceCount = 8;
    ADD_STATIC_ENTRY(ANDROID_STATISTICS_INFO_MAX_FACE_COUNT, &maxFaceCount, 1);

    static const uint8_t availableShadingMapModes[] = {
        ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF};
    ADD_STATIC_ENTRY(ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES,
                     availableShadingMapModes,
                     sizeof(availableShadingMapModes));
  }

  // android.sync

  static const int32_t maxLatency =
      hasCapability(FULL_LEVEL) ? ANDROID_SYNC_MAX_LATENCY_PER_FRAME_CONTROL
                                : 3;
  ADD_STATIC_ENTRY(ANDROID_SYNC_MAX_LATENCY, &maxLatency, 1);

  // android.control

  if (hasCapability(BACKWARD_COMPATIBLE)) {
    static const uint8_t availableControlModes[] = {
        ANDROID_CONTROL_MODE_OFF, ANDROID_CONTROL_MODE_AUTO,
        ANDROID_CONTROL_MODE_USE_SCENE_MODE};
    ADD_STATIC_ENTRY(ANDROID_CONTROL_AVAILABLE_MODES, availableControlModes,
                     sizeof(availableControlModes));
  } else {
    static const uint8_t availableControlModes[] = {ANDROID_CONTROL_MODE_AUTO};
    ADD_STATIC_ENTRY(ANDROID_CONTROL_AVAILABLE_MODES, availableControlModes,
                     sizeof(availableControlModes));
  }

  static const uint8_t availableSceneModes[] = {
    static_cast<uint8_t>(hasCapability(BACKWARD_COMPATIBLE)
                         ? ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY
                         : ANDROID_CONTROL_SCENE_MODE_DISABLED)};
  ADD_STATIC_ENTRY(ANDROID_CONTROL_AVAILABLE_SCENE_MODES, availableSceneModes,
                   sizeof(availableSceneModes));

  if (hasCapability(BACKWARD_COMPATIBLE)) {
    static const uint8_t availableEffects[] = {ANDROID_CONTROL_EFFECT_MODE_OFF};
    ADD_STATIC_ENTRY(ANDROID_CONTROL_AVAILABLE_EFFECTS, availableEffects,
                     sizeof(availableEffects));
  }

  if (hasCapability(BACKWARD_COMPATIBLE)) {
    static const int32_t max3aRegions[] = {/*AE*/ 1, /*AWB*/ 0, /*AF*/ 1};
    ADD_STATIC_ENTRY(ANDROID_CONTROL_MAX_REGIONS, max3aRegions,
                     sizeof(max3aRegions) / sizeof(max3aRegions[0]));

    static const uint8_t availableAeModes[] = {ANDROID_CONTROL_AE_MODE_OFF,
                                               ANDROID_CONTROL_AE_MODE_ON};
    ADD_STATIC_ENTRY(ANDROID_CONTROL_AE_AVAILABLE_MODES, availableAeModes,
                     sizeof(availableAeModes));

    static const camera_metadata_rational exposureCompensationStep = {1, 3};
    ADD_STATIC_ENTRY(ANDROID_CONTROL_AE_COMPENSATION_STEP,
                     &exposureCompensationStep, 1);

    int32_t exposureCompensationRange[] = {-9, 9};
    ADD_STATIC_ENTRY(ANDROID_CONTROL_AE_COMPENSATION_RANGE,
                     exposureCompensationRange,
                     sizeof(exposureCompensationRange) / sizeof(int32_t));
  }

  static const int32_t availableTargetFpsRanges[] = {5,  30, 15, 30,
                                                     15, 15, 30, 30};
  ADD_STATIC_ENTRY(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
                   availableTargetFpsRanges,
                   sizeof(availableTargetFpsRanges) / sizeof(int32_t));

  if (hasCapability(BACKWARD_COMPATIBLE)) {
    static const uint8_t availableAntibandingModes[] = {
        ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF,
        ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO};
    ADD_STATIC_ENTRY(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
                     availableAntibandingModes,
                     sizeof(availableAntibandingModes));
  }

  static const uint8_t aeLockAvailable =
      hasCapability(BACKWARD_COMPATIBLE)
          ? ANDROID_CONTROL_AE_LOCK_AVAILABLE_TRUE
          : ANDROID_CONTROL_AE_LOCK_AVAILABLE_FALSE;

  ADD_STATIC_ENTRY(ANDROID_CONTROL_AE_LOCK_AVAILABLE, &aeLockAvailable, 1);

  if (hasCapability(BACKWARD_COMPATIBLE)) {
    static const uint8_t availableAwbModes[] = {
        ANDROID_CONTROL_AWB_MODE_OFF,
        ANDROID_CONTROL_AWB_MODE_AUTO,
        ANDROID_CONTROL_AWB_MODE_INCANDESCENT,
        ANDROID_CONTROL_AWB_MODE_FLUORESCENT,
        ANDROID_CONTROL_AWB_MODE_DAYLIGHT,
        ANDROID_CONTROL_AWB_MODE_SHADE};
    ADD_STATIC_ENTRY(ANDROID_CONTROL_AWB_AVAILABLE_MODES, availableAwbModes,
                     sizeof(availableAwbModes));
  }

  static const uint8_t awbLockAvailable =
      hasCapability(BACKWARD_COMPATIBLE)
          ? ANDROID_CONTROL_AWB_LOCK_AVAILABLE_TRUE
          : ANDROID_CONTROL_AWB_LOCK_AVAILABLE_FALSE;

  ADD_STATIC_ENTRY(ANDROID_CONTROL_AWB_LOCK_AVAILABLE, &awbLockAvailable, 1);

  static const uint8_t availableAfModesBack[] = {
      ANDROID_CONTROL_AF_MODE_OFF, ANDROID_CONTROL_AF_MODE_AUTO,
      ANDROID_CONTROL_AF_MODE_MACRO, ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO,
      ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE};

  static const uint8_t availableAfModesFront[] = {ANDROID_CONTROL_AF_MODE_OFF};

  if (mFacingBack && hasCapability(BACKWARD_COMPATIBLE)) {
    ADD_STATIC_ENTRY(ANDROID_CONTROL_AF_AVAILABLE_MODES, availableAfModesBack,
                     sizeof(availableAfModesBack));
  } else {
    ADD_STATIC_ENTRY(ANDROID_CONTROL_AF_AVAILABLE_MODES, availableAfModesFront,
                     sizeof(availableAfModesFront));
  }

  static const uint8_t availableVstabModes[] = {
      ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF};
  ADD_STATIC_ENTRY(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
                   availableVstabModes, sizeof(availableVstabModes));

  // android.colorCorrection

  if (hasCapability(BACKWARD_COMPATIBLE)) {
    static const uint8_t availableAberrationModes[] = {
        ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF,
        ANDROID_COLOR_CORRECTION_ABERRATION_MODE_FAST,
        ANDROID_COLOR_CORRECTION_ABERRATION_MODE_HIGH_QUALITY};
    ADD_STATIC_ENTRY(ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
                     availableAberrationModes,
                     sizeof(availableAberrationModes));
  } else {
    static const uint8_t availableAberrationModes[] = {
        ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF,
    };
    ADD_STATIC_ENTRY(ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
                     availableAberrationModes,
                     sizeof(availableAberrationModes));
  }
  // android.edge

  if (hasCapability(BACKWARD_COMPATIBLE)) {
    static const uint8_t availableEdgeModes[] = {
        ANDROID_EDGE_MODE_OFF, ANDROID_EDGE_MODE_FAST,
        ANDROID_EDGE_MODE_HIGH_QUALITY};
    ADD_STATIC_ENTRY(ANDROID_EDGE_AVAILABLE_EDGE_MODES, availableEdgeModes,
                     sizeof(availableEdgeModes));
  } else {
    static const uint8_t availableEdgeModes[] = {ANDROID_EDGE_MODE_OFF};
    ADD_STATIC_ENTRY(ANDROID_EDGE_AVAILABLE_EDGE_MODES, availableEdgeModes,
                     sizeof(availableEdgeModes));
  }

  // android.info

  static const uint8_t supportedHardwareLevel =
      hasCapability(FULL_LEVEL) ? ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_FULL
                                : ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED;
  ADD_STATIC_ENTRY(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
                   &supportedHardwareLevel,
                   /*count*/ 1);

  // android.noiseReduction

  if (hasCapability(BACKWARD_COMPATIBLE)) {
    static const uint8_t availableNoiseReductionModes[] = {
        ANDROID_NOISE_REDUCTION_MODE_OFF, ANDROID_NOISE_REDUCTION_MODE_FAST,
        ANDROID_NOISE_REDUCTION_MODE_HIGH_QUALITY};
    ADD_STATIC_ENTRY(ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
                     availableNoiseReductionModes,
                     sizeof(availableNoiseReductionModes));
  } else {
    static const uint8_t availableNoiseReductionModes[] = {
        ANDROID_NOISE_REDUCTION_MODE_OFF,
    };
    ADD_STATIC_ENTRY(ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
                     availableNoiseReductionModes,
                     sizeof(availableNoiseReductionModes));
  }

  // android.depth

  if (hasCapability(DEPTH_OUTPUT)) {
    static const int32_t maxDepthSamples = 100;
    ADD_STATIC_ENTRY(ANDROID_DEPTH_MAX_DEPTH_SAMPLES, &maxDepthSamples, 1);

    static const int32_t availableDepthStreamConfigurations[] = {
        HAL_PIXEL_FORMAT_Y16,
        160,
        120,
        ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_OUTPUT,
        HAL_PIXEL_FORMAT_BLOB,
        maxDepthSamples,
        1,
        ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_OUTPUT};
    ADD_STATIC_ENTRY(
        ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS,
        availableDepthStreamConfigurations,
        sizeof(availableDepthStreamConfigurations) / sizeof(int32_t));

    static const int64_t availableDepthMinFrameDurations[] = {
        HAL_PIXEL_FORMAT_Y16,
        160,
        120,
        Sensor::kFrameDurationRange[0],
        HAL_PIXEL_FORMAT_BLOB,
        maxDepthSamples,
        1,
        Sensor::kFrameDurationRange[0]};
    ADD_STATIC_ENTRY(ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS,
                     availableDepthMinFrameDurations,
                     sizeof(availableDepthMinFrameDurations) / sizeof(int64_t));

    static const int64_t availableDepthStallDurations[] = {
        HAL_PIXEL_FORMAT_Y16,
        160,
        120,
        Sensor::kFrameDurationRange[0],
        HAL_PIXEL_FORMAT_BLOB,
        maxDepthSamples,
        1,
        Sensor::kFrameDurationRange[0]};
    ADD_STATIC_ENTRY(ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS,
                     availableDepthStallDurations,
                     sizeof(availableDepthStallDurations) / sizeof(int64_t));

    uint8_t depthIsExclusive = ANDROID_DEPTH_DEPTH_IS_EXCLUSIVE_FALSE;
    ADD_STATIC_ENTRY(ANDROID_DEPTH_DEPTH_IS_EXCLUSIVE, &depthIsExclusive, 1);
  }

  // android.shading

  if (hasCapability(BACKWARD_COMPATIBLE)) {
    static const uint8_t availableShadingModes[] = {
        ANDROID_SHADING_MODE_OFF, ANDROID_SHADING_MODE_FAST,
        ANDROID_SHADING_MODE_HIGH_QUALITY};
    ADD_STATIC_ENTRY(ANDROID_SHADING_AVAILABLE_MODES, availableShadingModes,
                     sizeof(availableShadingModes));
  } else {
    static const uint8_t availableShadingModes[] = {ANDROID_SHADING_MODE_OFF};
    ADD_STATIC_ENTRY(ANDROID_SHADING_AVAILABLE_MODES, availableShadingModes,
                     sizeof(availableShadingModes));
  }

  // android.request

  static const int32_t maxNumOutputStreams[] = {
      kMaxRawStreamCount, kMaxProcessedStreamCount, kMaxJpegStreamCount};
  ADD_STATIC_ENTRY(ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS, maxNumOutputStreams,
                   3);

  static const uint8_t maxPipelineDepth = kMaxBufferCount;
  ADD_STATIC_ENTRY(ANDROID_REQUEST_PIPELINE_MAX_DEPTH, &maxPipelineDepth, 1);

  static const int32_t partialResultCount = 1;
  ADD_STATIC_ENTRY(ANDROID_REQUEST_PARTIAL_RESULT_COUNT, &partialResultCount,
                   /*count*/ 1);

  SortedVector<uint8_t> caps;
  for (size_t i = 0; i < mCapabilities.size(); i++) {
    switch (mCapabilities[i]) {
      case BACKWARD_COMPATIBLE:
        caps.add(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE);
        break;
      case MANUAL_SENSOR:
        caps.add(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR);
        break;
      case MANUAL_POST_PROCESSING:
        caps.add(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING);
        break;
      case RAW:
        caps.add(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW);
        break;
      case PRIVATE_REPROCESSING:
        caps.add(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING);
        break;
      case READ_SENSOR_SETTINGS:
        caps.add(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS);
        break;
      case BURST_CAPTURE:
        caps.add(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE);
        break;
      case YUV_REPROCESSING:
        caps.add(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING);
        break;
      case DEPTH_OUTPUT:
        caps.add(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT);
        break;
      case CONSTRAINED_HIGH_SPEED_VIDEO:
        caps.add(
            ANDROID_REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO);
        break;
      default:
        // Ignore LEVELs
        break;
    }
  }
  ADD_STATIC_ENTRY(ANDROID_REQUEST_AVAILABLE_CAPABILITIES, caps.array(),
                   caps.size());

  // Scan a default request template for included request keys
  Vector<int32_t> availableRequestKeys;
  const camera_metadata_t *previewRequest =
      constructDefaultRequestSettings(CAMERA3_TEMPLATE_PREVIEW);
  for (size_t i = 0; i < get_camera_metadata_entry_count(previewRequest); i++) {
    camera_metadata_ro_entry_t entry;
    get_camera_metadata_ro_entry(previewRequest, i, &entry);
    availableRequestKeys.add(entry.tag);
  }
  ADD_STATIC_ENTRY(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS,
                   availableRequestKeys.array(), availableRequestKeys.size());

  // Add a few more result keys. Must be kept up to date with the various places
  // that add these

  Vector<int32_t> availableResultKeys(availableRequestKeys);
  if (hasCapability(BACKWARD_COMPATIBLE)) {
    availableResultKeys.add(ANDROID_CONTROL_AE_STATE);
    availableResultKeys.add(ANDROID_CONTROL_AF_STATE);
    availableResultKeys.add(ANDROID_CONTROL_AWB_STATE);
    availableResultKeys.add(ANDROID_FLASH_STATE);
    availableResultKeys.add(ANDROID_LENS_STATE);
    availableResultKeys.add(ANDROID_LENS_FOCUS_RANGE);
    availableResultKeys.add(ANDROID_SENSOR_ROLLING_SHUTTER_SKEW);
    availableResultKeys.add(ANDROID_STATISTICS_SCENE_FLICKER);
  }

  if (hasCapability(DEPTH_OUTPUT)) {
    availableResultKeys.add(ANDROID_LENS_POSE_ROTATION);
    availableResultKeys.add(ANDROID_LENS_POSE_TRANSLATION);
    availableResultKeys.add(ANDROID_LENS_INTRINSIC_CALIBRATION);
    availableResultKeys.add(ANDROID_LENS_RADIAL_DISTORTION);
  }

  availableResultKeys.add(ANDROID_REQUEST_PIPELINE_DEPTH);
  availableResultKeys.add(ANDROID_SENSOR_TIMESTAMP);

  ADD_STATIC_ENTRY(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS,
                   availableResultKeys.array(), availableResultKeys.size());

  // Needs to be last, to collect all the keys set

  availableCharacteristicsKeys.add(
      ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS);
  info.update(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS,
              availableCharacteristicsKeys);

  mCameraInfo = info.release();

#undef ADD_STATIC_ENTRY
  return OK;
}

status_t EmulatedFakeCamera3::process3A(CameraMetadata &settings) {
  /**
   * Extract top-level 3A controls
   */
  status_t res;

  camera_metadata_entry e;

  e = settings.find(ANDROID_CONTROL_MODE);
  if (e.count == 0) {
    ALOGE("%s: No control mode entry!", __FUNCTION__);
    return BAD_VALUE;
  }
  uint8_t controlMode = e.data.u8[0];

  if (controlMode == ANDROID_CONTROL_MODE_OFF) {
    mAeMode = ANDROID_CONTROL_AE_MODE_OFF;
    mAfMode = ANDROID_CONTROL_AF_MODE_OFF;
    mAwbMode = ANDROID_CONTROL_AWB_MODE_OFF;
    mAeState = ANDROID_CONTROL_AE_STATE_INACTIVE;
    mAfState = ANDROID_CONTROL_AF_STATE_INACTIVE;
    mAwbState = ANDROID_CONTROL_AWB_STATE_INACTIVE;
    update3A(settings);
    return OK;
  } else if (controlMode == ANDROID_CONTROL_MODE_USE_SCENE_MODE) {
    if (!hasCapability(BACKWARD_COMPATIBLE)) {
      ALOGE("%s: Can't use scene mode when BACKWARD_COMPATIBLE not supported!",
            __FUNCTION__);
      return BAD_VALUE;
    }

    e = settings.find(ANDROID_CONTROL_SCENE_MODE);
    if (e.count == 0) {
      ALOGE("%s: No scene mode entry!", __FUNCTION__);
      return BAD_VALUE;
    }
    uint8_t sceneMode = e.data.u8[0];

    switch (sceneMode) {
      case ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY:
        mFacePriority = true;
        break;
      default:
        ALOGE("%s: Emulator doesn't support scene mode %d", __FUNCTION__,
              sceneMode);
        return BAD_VALUE;
    }
  } else {
    mFacePriority = false;
  }

  // controlMode == AUTO or sceneMode = FACE_PRIORITY
  // Process individual 3A controls

  res = doFakeAE(settings);
  if (res != OK) return res;

  res = doFakeAF(settings);
  if (res != OK) return res;

  res = doFakeAWB(settings);
  if (res != OK) return res;

  update3A(settings);
  return OK;
}

status_t EmulatedFakeCamera3::doFakeAE(CameraMetadata &settings) {
  camera_metadata_entry e;

  e = settings.find(ANDROID_CONTROL_AE_MODE);
  if (e.count == 0 && hasCapability(BACKWARD_COMPATIBLE)) {
    ALOGE("%s: No AE mode entry!", __FUNCTION__);
    return BAD_VALUE;
  }
  uint8_t aeMode =
      (e.count > 0) ? e.data.u8[0] : (uint8_t)ANDROID_CONTROL_AE_MODE_ON;
  mAeMode = aeMode;

  switch (aeMode) {
    case ANDROID_CONTROL_AE_MODE_OFF:
      // AE is OFF
      mAeState = ANDROID_CONTROL_AE_STATE_INACTIVE;
      return OK;
    case ANDROID_CONTROL_AE_MODE_ON:
      // OK for AUTO modes
      break;
    default:
      // Mostly silently ignore unsupported modes
      ALOGV("%s: Emulator doesn't support AE mode %d, assuming ON",
            __FUNCTION__, aeMode);
      break;
  }

  e = settings.find(ANDROID_CONTROL_AE_LOCK);
  bool aeLocked =
      (e.count > 0) ? (e.data.u8[0] == ANDROID_CONTROL_AE_LOCK_ON) : false;

  e = settings.find(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER);
  bool precaptureTrigger = false;
  if (e.count != 0) {
    precaptureTrigger =
        (e.data.u8[0] == ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_START);
  }

  if (precaptureTrigger) {
    ALOGV("%s: Pre capture trigger = %d", __FUNCTION__, precaptureTrigger);
  } else if (e.count > 0) {
    ALOGV("%s: Pre capture trigger was present? %zu", __FUNCTION__, e.count);
  }

  if (precaptureTrigger || mAeState == ANDROID_CONTROL_AE_STATE_PRECAPTURE) {
    // Run precapture sequence
    if (mAeState != ANDROID_CONTROL_AE_STATE_PRECAPTURE) {
      mAeCounter = 0;
    }

    if (mFacePriority) {
      mAeTargetExposureTime = kFacePriorityExposureTime;
    } else {
      mAeTargetExposureTime = kNormalExposureTime;
    }

    if (mAeCounter > kPrecaptureMinFrames &&
        (mAeTargetExposureTime - mAeCurrentExposureTime) <
            mAeTargetExposureTime / 10) {
      // Done with precapture
      mAeCounter = 0;
      mAeState = aeLocked ? ANDROID_CONTROL_AE_STATE_LOCKED
                          : ANDROID_CONTROL_AE_STATE_CONVERGED;
    } else {
      // Converge some more
      mAeCurrentExposureTime +=
          (mAeTargetExposureTime - mAeCurrentExposureTime) * kExposureTrackRate;
      mAeCounter++;
      mAeState = ANDROID_CONTROL_AE_STATE_PRECAPTURE;
    }

  } else if (!aeLocked) {
    // Run standard occasional AE scan
    switch (mAeState) {
      case ANDROID_CONTROL_AE_STATE_CONVERGED:
      case ANDROID_CONTROL_AE_STATE_INACTIVE:
        mAeCounter++;
        if (mAeCounter > kStableAeMaxFrames) {
          mAeTargetExposureTime =
              mFacePriority ? kFacePriorityExposureTime : kNormalExposureTime;
          float exposureStep = ((double)rand() / RAND_MAX) *
                                   (kExposureWanderMax - kExposureWanderMin) +
                               kExposureWanderMin;
          mAeTargetExposureTime *= std::pow(2, exposureStep);
          mAeState = ANDROID_CONTROL_AE_STATE_SEARCHING;
        }
        break;
      case ANDROID_CONTROL_AE_STATE_SEARCHING:
        mAeCurrentExposureTime +=
            (mAeTargetExposureTime - mAeCurrentExposureTime) *
            kExposureTrackRate;
        if (llabs(mAeTargetExposureTime - mAeCurrentExposureTime) <
            mAeTargetExposureTime / 10) {
          // Close enough
          mAeState = ANDROID_CONTROL_AE_STATE_CONVERGED;
          mAeCounter = 0;
        }
        break;
      case ANDROID_CONTROL_AE_STATE_LOCKED:
        mAeState = ANDROID_CONTROL_AE_STATE_CONVERGED;
        mAeCounter = 0;
        break;
      default:
        ALOGE("%s: Emulator in unexpected AE state %d", __FUNCTION__, mAeState);
        return INVALID_OPERATION;
    }
  } else {
    // AE is locked
    mAeState = ANDROID_CONTROL_AE_STATE_LOCKED;
  }

  return OK;
}

status_t EmulatedFakeCamera3::doFakeAF(CameraMetadata &settings) {
  camera_metadata_entry e;

  e = settings.find(ANDROID_CONTROL_AF_MODE);
  if (e.count == 0 && hasCapability(BACKWARD_COMPATIBLE)) {
    ALOGE("%s: No AF mode entry!", __FUNCTION__);
    return BAD_VALUE;
  }
  uint8_t afMode =
      (e.count > 0) ? e.data.u8[0] : (uint8_t)ANDROID_CONTROL_AF_MODE_OFF;

  e = settings.find(ANDROID_CONTROL_AF_TRIGGER);
  typedef camera_metadata_enum_android_control_af_trigger af_trigger_t;
  af_trigger_t afTrigger;
  if (e.count != 0) {
    afTrigger = static_cast<af_trigger_t>(e.data.u8[0]);

    ALOGV("%s: AF trigger set to 0x%x", __FUNCTION__, afTrigger);
    ALOGV("%s: AF mode is 0x%x", __FUNCTION__, afMode);
  } else {
    afTrigger = ANDROID_CONTROL_AF_TRIGGER_IDLE;
  }

  switch (afMode) {
    case ANDROID_CONTROL_AF_MODE_OFF:
      mAfState = ANDROID_CONTROL_AF_STATE_INACTIVE;
      return OK;
    case ANDROID_CONTROL_AF_MODE_AUTO:
    case ANDROID_CONTROL_AF_MODE_MACRO:
    case ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO:
    case ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE:
      if (!mFacingBack) {
        ALOGE("%s: Front camera doesn't support AF mode %d", __FUNCTION__,
              afMode);
        return BAD_VALUE;
      }
      // OK, handle transitions lower on
      break;
    default:
      ALOGE("%s: Emulator doesn't support AF mode %d", __FUNCTION__, afMode);
      return BAD_VALUE;
  }

  bool afModeChanged = mAfMode != afMode;
  mAfMode = afMode;

  /**
   * Simulate AF triggers. Transition at most 1 state per frame.
   * - Focusing always succeeds (goes into locked, or PASSIVE_SCAN).
   */

  bool afTriggerStart = false;
  bool afTriggerCancel = false;
  switch (afTrigger) {
    case ANDROID_CONTROL_AF_TRIGGER_IDLE:
      break;
    case ANDROID_CONTROL_AF_TRIGGER_START:
      afTriggerStart = true;
      break;
    case ANDROID_CONTROL_AF_TRIGGER_CANCEL:
      afTriggerCancel = true;
      // Cancel trigger always transitions into INACTIVE
      mAfState = ANDROID_CONTROL_AF_STATE_INACTIVE;

      ALOGV("%s: AF State transition to STATE_INACTIVE", __FUNCTION__);

      // Stay in 'inactive' until at least next frame
      return OK;
    default:
      ALOGE("%s: Unknown af trigger value %d", __FUNCTION__, afTrigger);
      return BAD_VALUE;
  }

  // If we get down here, we're either in an autofocus mode
  //  or in a continuous focus mode (and no other modes)

  int oldAfState = mAfState;
  switch (mAfState) {
    case ANDROID_CONTROL_AF_STATE_INACTIVE:
      if (afTriggerStart) {
        switch (afMode) {
          case ANDROID_CONTROL_AF_MODE_AUTO:
            // fall-through
          case ANDROID_CONTROL_AF_MODE_MACRO:
            mAfState = ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN;
            break;
          case ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO:
            // fall-through
          case ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE:
            mAfState = ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED;
            break;
        }
      } else {
        // At least one frame stays in INACTIVE
        if (!afModeChanged) {
          switch (afMode) {
            case ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO:
              // fall-through
            case ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE:
              mAfState = ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN;
              break;
          }
        }
      }
      break;
    case ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN:
      /**
       * When the AF trigger is activated, the algorithm should finish
       * its PASSIVE_SCAN if active, and then transition into AF_FOCUSED
       * or AF_NOT_FOCUSED as appropriate
       */
      if (afTriggerStart) {
        // Randomly transition to focused or not focused
        if (rand() % 3) {
          mAfState = ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED;
        } else {
          mAfState = ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED;
        }
      }
      /**
       * When the AF trigger is not involved, the AF algorithm should
       * start in INACTIVE state, and then transition into PASSIVE_SCAN
       * and PASSIVE_FOCUSED states
       */
      else if (!afTriggerCancel) {
        // Randomly transition to passive focus
        if (rand() % 3 == 0) {
          mAfState = ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED;
        }
      }

      break;
    case ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED:
      if (afTriggerStart) {
        // Randomly transition to focused or not focused
        if (rand() % 3) {
          mAfState = ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED;
        } else {
          mAfState = ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED;
        }
      }
      // TODO: initiate passive scan (PASSIVE_SCAN)
      break;
    case ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN:
      // Simulate AF sweep completing instantaneously

      // Randomly transition to focused or not focused
      if (rand() % 3) {
        mAfState = ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED;
      } else {
        mAfState = ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED;
      }
      break;
    case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED:
      if (afTriggerStart) {
        switch (afMode) {
          case ANDROID_CONTROL_AF_MODE_AUTO:
            // fall-through
          case ANDROID_CONTROL_AF_MODE_MACRO:
            mAfState = ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN;
            break;
          case ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO:
            // fall-through
          case ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE:
            // continuous autofocus => trigger start has no effect
            break;
        }
      }
      break;
    case ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
      if (afTriggerStart) {
        switch (afMode) {
          case ANDROID_CONTROL_AF_MODE_AUTO:
            // fall-through
          case ANDROID_CONTROL_AF_MODE_MACRO:
            mAfState = ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN;
            break;
          case ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO:
            // fall-through
          case ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE:
            // continuous autofocus => trigger start has no effect
            break;
        }
      }
      break;
    default:
      ALOGE("%s: Bad af state %d", __FUNCTION__, mAfState);
  }

  {
    char afStateString[100] = {
        0,
    };
    camera_metadata_enum_snprint(ANDROID_CONTROL_AF_STATE, oldAfState,
                                 afStateString, sizeof(afStateString));

    char afNewStateString[100] = {
        0,
    };
    camera_metadata_enum_snprint(ANDROID_CONTROL_AF_STATE, mAfState,
                                 afNewStateString, sizeof(afNewStateString));
    ALOGVV("%s: AF state transitioned from %s to %s", __FUNCTION__,
           afStateString, afNewStateString);
  }

  return OK;
}

status_t EmulatedFakeCamera3::doFakeAWB(CameraMetadata &settings) {
  camera_metadata_entry e;

  e = settings.find(ANDROID_CONTROL_AWB_MODE);
  if (e.count == 0 && hasCapability(BACKWARD_COMPATIBLE)) {
    ALOGE("%s: No AWB mode entry!", __FUNCTION__);
    return BAD_VALUE;
  }
  uint8_t awbMode =
      (e.count > 0) ? e.data.u8[0] : (uint8_t)ANDROID_CONTROL_AWB_MODE_AUTO;

  // TODO: Add white balance simulation

  e = settings.find(ANDROID_CONTROL_AWB_LOCK);
  bool awbLocked =
      (e.count > 0) ? (e.data.u8[0] == ANDROID_CONTROL_AWB_LOCK_ON) : false;

  switch (awbMode) {
    case ANDROID_CONTROL_AWB_MODE_OFF:
      mAwbState = ANDROID_CONTROL_AWB_STATE_INACTIVE;
      break;
    case ANDROID_CONTROL_AWB_MODE_AUTO:
    case ANDROID_CONTROL_AWB_MODE_INCANDESCENT:
    case ANDROID_CONTROL_AWB_MODE_FLUORESCENT:
    case ANDROID_CONTROL_AWB_MODE_DAYLIGHT:
    case ANDROID_CONTROL_AWB_MODE_SHADE:
      // Always magically right, or locked
      mAwbState = awbLocked ? ANDROID_CONTROL_AWB_STATE_LOCKED
                            : ANDROID_CONTROL_AWB_STATE_CONVERGED;
      break;
    default:
      ALOGE("%s: Emulator doesn't support AWB mode %d", __FUNCTION__, awbMode);
      return BAD_VALUE;
  }

  return OK;
}

void EmulatedFakeCamera3::update3A(CameraMetadata &settings) {
  if (mAeMode != ANDROID_CONTROL_AE_MODE_OFF) {
    settings.update(ANDROID_SENSOR_EXPOSURE_TIME, &mAeCurrentExposureTime, 1);
    settings.update(ANDROID_SENSOR_SENSITIVITY, &mAeCurrentSensitivity, 1);
  }

  settings.update(ANDROID_CONTROL_AE_STATE, &mAeState, 1);
  settings.update(ANDROID_CONTROL_AF_STATE, &mAfState, 1);
  settings.update(ANDROID_CONTROL_AWB_STATE, &mAwbState, 1);

  uint8_t lensState;
  switch (mAfState) {
    case ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN:
    case ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN:
      lensState = ANDROID_LENS_STATE_MOVING;
      break;
    case ANDROID_CONTROL_AF_STATE_INACTIVE:
    case ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED:
    case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED:
    case ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
    case ANDROID_CONTROL_AF_STATE_PASSIVE_UNFOCUSED:
    default:
      lensState = ANDROID_LENS_STATE_STATIONARY;
      break;
  }
  settings.update(ANDROID_LENS_STATE, &lensState, 1);
}

void EmulatedFakeCamera3::signalReadoutIdle() {
  Mutex::Autolock l(mLock);
  // Need to chek isIdle again because waiting on mLock may have allowed
  // something to be placed in the in-flight queue.
  if (mStatus == STATUS_ACTIVE && mReadoutThread->isIdle()) {
    ALOGV("Now idle");
    mStatus = STATUS_READY;
  }
}

void EmulatedFakeCamera3::onSensorEvent(uint32_t frameNumber, Event e,
                                        nsecs_t timestamp) {
  switch (e) {
    case Sensor::SensorListener::EXPOSURE_START: {
      ALOGVV("%s: Frame %d: Sensor started exposure at %lld", __FUNCTION__,
             frameNumber, timestamp);
      // Trigger shutter notify to framework
      camera3_notify_msg_t msg;
      msg.type = CAMERA3_MSG_SHUTTER;
      msg.message.shutter.frame_number = frameNumber;
      msg.message.shutter.timestamp = timestamp;
      sendNotify(&msg);
      break;
    }
    default:
      ALOGW("%s: Unexpected sensor event %d at %" PRId64, __FUNCTION__, e,
            timestamp);
      break;
  }
}

EmulatedFakeCamera3::ReadoutThread::ReadoutThread(EmulatedFakeCamera3 *parent)
    : mParent(parent), mJpegWaiting(false) {}

EmulatedFakeCamera3::ReadoutThread::~ReadoutThread() {
  for (List<Request>::iterator i = mInFlightQueue.begin();
       i != mInFlightQueue.end(); i++) {
    delete i->buffers;
    delete i->sensorBuffers;
  }
}

void EmulatedFakeCamera3::ReadoutThread::queueCaptureRequest(const Request &r) {
  Mutex::Autolock l(mLock);

  mInFlightQueue.push_back(r);
  mInFlightSignal.signal();
}

bool EmulatedFakeCamera3::ReadoutThread::isIdle() {
  Mutex::Autolock l(mLock);
  return mInFlightQueue.empty() && !mThreadActive;
}

status_t EmulatedFakeCamera3::ReadoutThread::waitForReadout() {
  status_t res;
  Mutex::Autolock l(mLock);
  int loopCount = 0;
  while (mInFlightQueue.size() >= kMaxQueueSize) {
    res = mInFlightSignal.waitRelative(mLock, kWaitPerLoop);
    if (res != OK && res != TIMED_OUT) {
      ALOGE("%s: Error waiting for in-flight queue to shrink", __FUNCTION__);
      return INVALID_OPERATION;
    }
    if (loopCount == kMaxWaitLoops) {
      ALOGE("%s: Timed out waiting for in-flight queue to shrink",
            __FUNCTION__);
      return TIMED_OUT;
    }
    loopCount++;
  }
  return OK;
}

bool EmulatedFakeCamera3::ReadoutThread::threadLoop() {
  status_t res;

  ALOGVV("%s: ReadoutThread waiting for request", __FUNCTION__);

  // First wait for a request from the in-flight queue

  if (mCurrentRequest.settings.isEmpty()) {
    Mutex::Autolock l(mLock);
    if (mInFlightQueue.empty()) {
      res = mInFlightSignal.waitRelative(mLock, kWaitPerLoop);
      if (res == TIMED_OUT) {
        ALOGVV("%s: ReadoutThread: Timed out waiting for request",
               __FUNCTION__);
        return true;
      } else if (res != NO_ERROR) {
        ALOGE("%s: Error waiting for capture requests: %d", __FUNCTION__, res);
        return false;
      }
    }
    mCurrentRequest.frameNumber = mInFlightQueue.begin()->frameNumber;
    mCurrentRequest.settings.acquire(mInFlightQueue.begin()->settings);
    mCurrentRequest.buffers = mInFlightQueue.begin()->buffers;
    mCurrentRequest.sensorBuffers = mInFlightQueue.begin()->sensorBuffers;
    mInFlightQueue.erase(mInFlightQueue.begin());
    mInFlightSignal.signal();
    mThreadActive = true;
    ALOGVV("%s: Beginning readout of frame %d", __FUNCTION__,
           mCurrentRequest.frameNumber);
  }

  // Then wait for it to be delivered from the sensor
  ALOGVV("%s: ReadoutThread: Wait for frame to be delivered from sensor",
         __FUNCTION__);

  nsecs_t captureTime;
  bool gotFrame = mParent->mSensor->waitForNewFrame(kWaitPerLoop, &captureTime);
  if (!gotFrame) {
    ALOGVV("%s: ReadoutThread: Timed out waiting for sensor frame",
           __FUNCTION__);
    return true;
  }

  ALOGVV("Sensor done with readout for frame %d, captured at %lld ",
         mCurrentRequest.frameNumber, captureTime);

  // Check if we need to JPEG encode a buffer, and send it for async
  // compression if so. Otherwise prepare the buffer for return.
  bool needJpeg = false;
  HalBufferVector::iterator buf = mCurrentRequest.buffers->begin();
  while (buf != mCurrentRequest.buffers->end()) {
    bool goodBuffer = true;
    if (buf->stream->format == HAL_PIXEL_FORMAT_BLOB &&
        buf->stream->data_space != HAL_DATASPACE_DEPTH) {
      Mutex::Autolock jl(mJpegLock);
      if (mJpegWaiting) {
        // This shouldn't happen, because processCaptureRequest should
        // be stalling until JPEG compressor is free.
        ALOGE("%s: Already processing a JPEG!", __FUNCTION__);
        goodBuffer = false;
      }
      if (goodBuffer) {
        // Compressor takes ownership of sensorBuffers here
        res = mParent->mJpegCompressor->start(mCurrentRequest.sensorBuffers,
                                              this);
        goodBuffer = (res == OK);
      }
      if (goodBuffer) {
        needJpeg = true;

        mJpegHalBuffer = *buf;
        mJpegFrameNumber = mCurrentRequest.frameNumber;
        mJpegWaiting = true;

        mCurrentRequest.sensorBuffers = NULL;
        buf = mCurrentRequest.buffers->erase(buf);

        continue;
      }
      ALOGE("%s: Error compressing output buffer: %s (%d)", __FUNCTION__,
            strerror(-res), res);
      // fallthrough for cleanup
    }
    GrallocModule::getInstance().unlock(*(buf->buffer));

    buf->status =
        goodBuffer ? CAMERA3_BUFFER_STATUS_OK : CAMERA3_BUFFER_STATUS_ERROR;
    buf->acquire_fence = -1;
    buf->release_fence = -1;

    ++buf;
  }  // end while

  // Construct result for all completed buffers and results

  camera3_capture_result result;

  if (mParent->hasCapability(BACKWARD_COMPATIBLE)) {
    static const uint8_t sceneFlicker = ANDROID_STATISTICS_SCENE_FLICKER_NONE;
    mCurrentRequest.settings.update(ANDROID_STATISTICS_SCENE_FLICKER,
                                    &sceneFlicker, 1);

    static const uint8_t flashState = ANDROID_FLASH_STATE_UNAVAILABLE;
    mCurrentRequest.settings.update(ANDROID_FLASH_STATE, &flashState, 1);

    nsecs_t rollingShutterSkew = Sensor::kFrameDurationRange[0];
    mCurrentRequest.settings.update(ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
                                    &rollingShutterSkew, 1);

    float focusRange[] = {1.0f / 5.0f, 0};  // 5 m to infinity in focus
    mCurrentRequest.settings.update(ANDROID_LENS_FOCUS_RANGE, focusRange,
                                    sizeof(focusRange) / sizeof(float));
  }

  if (mParent->hasCapability(DEPTH_OUTPUT)) {
    camera_metadata_entry_t entry;

    find_camera_metadata_entry(mParent->mCameraInfo,
                               ANDROID_LENS_POSE_TRANSLATION, &entry);
    mCurrentRequest.settings.update(ANDROID_LENS_POSE_TRANSLATION, entry.data.f,
                                    entry.count);

    find_camera_metadata_entry(mParent->mCameraInfo, ANDROID_LENS_POSE_ROTATION,
                               &entry);
    mCurrentRequest.settings.update(ANDROID_LENS_POSE_ROTATION, entry.data.f,
                                    entry.count);

    find_camera_metadata_entry(mParent->mCameraInfo,
                               ANDROID_LENS_INTRINSIC_CALIBRATION, &entry);
    mCurrentRequest.settings.update(ANDROID_LENS_INTRINSIC_CALIBRATION,
                                    entry.data.f, entry.count);

    find_camera_metadata_entry(mParent->mCameraInfo,
                               ANDROID_LENS_RADIAL_DISTORTION, &entry);
    mCurrentRequest.settings.update(ANDROID_LENS_RADIAL_DISTORTION,
                                    entry.data.f, entry.count);
  }

  mCurrentRequest.settings.update(ANDROID_SENSOR_TIMESTAMP, &captureTime, 1);

  // JPEGs take a stage longer
  const uint8_t pipelineDepth =
      needJpeg ? kMaxBufferCount : kMaxBufferCount - 1;
  mCurrentRequest.settings.update(ANDROID_REQUEST_PIPELINE_DEPTH,
                                  &pipelineDepth, 1);

  result.frame_number = mCurrentRequest.frameNumber;
  result.result = mCurrentRequest.settings.getAndLock();
  result.num_output_buffers = mCurrentRequest.buffers->size();
  result.output_buffers = mCurrentRequest.buffers->array();
  result.input_buffer = nullptr;
  result.partial_result = 1;

  // Go idle if queue is empty, before sending result
  bool signalIdle = false;
  {
    Mutex::Autolock l(mLock);
    if (mInFlightQueue.empty()) {
      mThreadActive = false;
      signalIdle = true;
    }
  }
  if (signalIdle) mParent->signalReadoutIdle();

  // Send it off to the framework
  ALOGVV("%s: ReadoutThread: Send result to framework", __FUNCTION__);
  mParent->sendCaptureResult(&result);

  // Clean up
  mCurrentRequest.settings.unlock(result.result);

  delete mCurrentRequest.buffers;
  mCurrentRequest.buffers = NULL;
  if (!needJpeg) {
    delete mCurrentRequest.sensorBuffers;
    mCurrentRequest.sensorBuffers = NULL;
  }
  mCurrentRequest.settings.clear();

  return true;
}

void EmulatedFakeCamera3::ReadoutThread::onJpegDone(
    const StreamBuffer &jpegBuffer, bool success) {
  Mutex::Autolock jl(mJpegLock);

  GrallocModule::getInstance().unlock(*(jpegBuffer.buffer));

  mJpegHalBuffer.status =
      success ? CAMERA3_BUFFER_STATUS_OK : CAMERA3_BUFFER_STATUS_ERROR;
  mJpegHalBuffer.acquire_fence = -1;
  mJpegHalBuffer.release_fence = -1;
  mJpegWaiting = false;

  camera3_capture_result result;

  result.frame_number = mJpegFrameNumber;
  result.result = NULL;
  result.num_output_buffers = 1;
  result.output_buffers = &mJpegHalBuffer;
  result.input_buffer = nullptr;
  result.partial_result = 0;

  if (!success) {
    ALOGE(
        "%s: Compression failure, returning error state buffer to"
        " framework",
        __FUNCTION__);
  } else {
    ALOGV("%s: Compression complete, returning buffer to framework",
          __FUNCTION__);
  }

  mParent->sendCaptureResult(&result);
}

void EmulatedFakeCamera3::ReadoutThread::onJpegInputDone(
    const StreamBuffer & /*inputBuffer*/) {
  // Should never get here, since the input buffer has to be returned
  // by end of processCaptureRequest
  ALOGE("%s: Unexpected input buffer from JPEG compressor!", __FUNCTION__);
}

};  // namespace android
