/* Copyright 2016 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "hal/usb/metadata_handler.h"

#include <cmath>
#include <limits>
#include <map>
#include <set>
#include <unordered_map>
#include <vector>

#include "cros-camera/common.h"
#include "cros-camera/utils/camera_config.h"
#include "hal/usb/quirks.h"
#include "hal/usb/stream_format.h"
#include "hal/usb/v4l2_camera_device.h"
#include "hal/usb/vendor_tag.h"
#include "mojo/cros_camera_enum.mojom.h"

namespace {

constexpr int32_t kMinFps = 1;

class MetadataUpdater {
 public:
  explicit MetadataUpdater(android::CameraMetadata* metadata)
      : metadata_(metadata), ok_(true) {}

  bool ok() { return ok_; }

  template <typename T>
  void operator()(int tag, const std::vector<T>& data) {
    if (!ok_) {
      return;
    }
    if (metadata_->update(tag, data) != 0) {
      ok_ = false;
      LOGF(ERROR) << "Update metadata with tag " << tag << " failed";
    }
  }

  template <typename T>
  std::enable_if_t<std::is_enum<T>::value> operator()(int tag, const T& data) {
    static const std::set<int> kInt32EnumTags = {
        ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS,
        ANDROID_SCALER_AVAILABLE_FORMATS,
        ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
        ANDROID_SENSOR_TEST_PATTERN_MODE,
        ANDROID_SYNC_MAX_LATENCY,
    };
    if (kInt32EnumTags.find(tag) != kInt32EnumTags.end()) {
      operator()(tag, std::vector<int32_t>{static_cast<int32_t>(data)});
    } else {
      operator()(tag, std::vector<uint8_t>{base::checked_cast<uint8_t>(data)});
    }
  }

  template <typename T>
  std::enable_if_t<!std::is_enum<T>::value> operator()(int tag, const T& data) {
    operator()(tag, std::vector<T>{data});
  }

 private:
  android::CameraMetadata* metadata_;
  bool ok_;
};

}  // namespace

namespace cros {

MetadataHandler::MetadataHandler(const camera_metadata_t& static_metadata,
                                 const camera_metadata_t& request_template,
                                 const DeviceInfo& device_info,
                                 V4L2CameraDevice* device,
                                 const SupportedFormats& supported_formats)
    : device_info_(device_info), device_(device), af_trigger_(false) {
  // MetadataBase::operator= will make a copy of camera_metadata_t.
  static_metadata_ = &static_metadata;
  request_template_ = &request_template;

  max_supported_fps_ = 0;
  for (const auto& format : supported_formats) {
    for (const float& frame_rate : format.frame_rates) {
      // Since the |frame_rate| is a float, we need to round here.
      int fps = std::round(frame_rate);
      if (fps > max_supported_fps_) {
        max_supported_fps_ = fps;
      }
    }
  }

  // camera3_request_template_t starts at 1.
  for (int i = 1; i < CAMERA3_TEMPLATE_COUNT; i++) {
    template_settings_[i] = CreateDefaultRequestSettings(i);
  }

  sensor_handler_ = SensorHandler::Create(device_info, supported_formats);

  thread_checker_.DetachFromThread();
}

MetadataHandler::~MetadataHandler() {}

int MetadataHandler::FillDefaultMetadata(
    android::CameraMetadata* static_metadata,
    android::CameraMetadata* request_metadata) {
  MetadataUpdater update_static(static_metadata);
  MetadataUpdater update_request(request_metadata);

  // android.colorCorrection
  update_static(ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
                std::vector<uint8_t>{
                    ANDROID_COLOR_CORRECTION_ABERRATION_MODE_FAST,
                    ANDROID_COLOR_CORRECTION_ABERRATION_MODE_HIGH_QUALITY});
  update_request(ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
                 ANDROID_COLOR_CORRECTION_ABERRATION_MODE_FAST);

  // android.control
  // We don't support AE compensation.
  update_static(ANDROID_CONTROL_AE_COMPENSATION_RANGE,
                std::vector<int32_t>{0, 0});

  update_static(ANDROID_CONTROL_AE_COMPENSATION_STEP,
                camera_metadata_rational_t{0, 1});

  update_static(ANDROID_CONTROL_MAX_REGIONS,
                std::vector<int32_t>{/*AE*/ 0, /*AWB*/ 0, /*AF*/ 0});

  update_static(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
                ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF);
  update_request(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
                 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF);

  update_static(ANDROID_CONTROL_AWB_AVAILABLE_MODES,
                ANDROID_CONTROL_AWB_MODE_AUTO);
  update_request(ANDROID_CONTROL_AWB_MODE, ANDROID_CONTROL_AWB_MODE_AUTO);

  update_static(ANDROID_CONTROL_AE_AVAILABLE_MODES, ANDROID_CONTROL_AE_MODE_ON);
  // ON means auto-exposure is active with no flash control.
  update_request(ANDROID_CONTROL_AE_MODE, ANDROID_CONTROL_AE_MODE_ON);

  update_request(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION, int32_t{0});

  update_request(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
                 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE);

  update_request(ANDROID_CONTROL_AF_TRIGGER, ANDROID_CONTROL_AF_TRIGGER_IDLE);

  update_static(ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
                ANDROID_CONTROL_SCENE_MODE_DISABLED);
  update_request(ANDROID_CONTROL_SCENE_MODE,
                 ANDROID_CONTROL_SCENE_MODE_DISABLED);

  update_static(ANDROID_CONTROL_AVAILABLE_EFFECTS,
                ANDROID_CONTROL_EFFECT_MODE_OFF);
  update_request(ANDROID_CONTROL_EFFECT_MODE, ANDROID_CONTROL_EFFECT_MODE_OFF);

  update_static(ANDROID_CONTROL_AE_LOCK_AVAILABLE,
                ANDROID_CONTROL_AE_LOCK_AVAILABLE_FALSE);

  update_static(ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
                ANDROID_CONTROL_AWB_LOCK_AVAILABLE_FALSE);

  update_static(ANDROID_CONTROL_AVAILABLE_MODES,
                std::vector<uint8_t>{ANDROID_CONTROL_MODE_OFF,
                                     ANDROID_CONTROL_MODE_AUTO});

  // android.flash
  update_static(ANDROID_FLASH_INFO_AVAILABLE,
                ANDROID_FLASH_INFO_AVAILABLE_FALSE);
  update_request(ANDROID_FLASH_STATE, ANDROID_FLASH_STATE_UNAVAILABLE);
  update_request(ANDROID_FLASH_MODE, ANDROID_FLASH_MODE_OFF);

  // android.jpeg
  update_static(ANDROID_JPEG_MAX_SIZE, int32_t{13 << 20});
  update_request(ANDROID_JPEG_QUALITY, uint8_t{90});
  update_request(ANDROID_JPEG_THUMBNAIL_QUALITY, uint8_t{90});
  update_request(ANDROID_JPEG_ORIENTATION, int32_t{0});

  // android.lens
  // This should not be needed.
  update_static(ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE, 0.0f);
  update_static(ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
                ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF);
  update_request(ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
                 ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF);

  // android.noiseReduction
  update_static(ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
                ANDROID_NOISE_REDUCTION_MODE_OFF);
  update_request(ANDROID_NOISE_REDUCTION_MODE,
                 ANDROID_NOISE_REDUCTION_MODE_OFF);

  // android.request
  update_static(ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
                ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE);
  update_static(ANDROID_REQUEST_PARTIAL_RESULT_COUNT, int32_t{1});

  // This means pipeline latency of X frame intervals. The maximum number is 4.
  update_static(ANDROID_REQUEST_PIPELINE_MAX_DEPTH, uint8_t{4});
  update_request(ANDROID_REQUEST_PIPELINE_DEPTH, uint8_t{4});

  // Three numbers represent the maximum numbers of different types of output
  // streams simultaneously. The types are raw sensor, processed (but not
  // stalling), and processed (but stalling). For usb limited mode, raw sensor
  // is not supported. Stalling stream is JPEG. Non-stalling streams are
  // YUV_420_888, NV21, or YV12.
  update_static(ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS,
                std::vector<int32_t>{0, 2, 1});

  // Limited mode doesn't support reprocessing.
  update_static(ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS, int32_t{0});

  // android.scaler
  update_static(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM, 1.0f);

  update_static(ANDROID_SCALER_CROPPING_TYPE,
                ANDROID_SCALER_CROPPING_TYPE_CENTER_ONLY);

  update_static(ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
                std::vector<int32_t>{
                    ANDROID_SENSOR_TEST_PATTERN_MODE_OFF,
                    ANDROID_SENSOR_TEST_PATTERN_MODE_COLOR_BARS_FADE_TO_GRAY});
  update_request(ANDROID_SENSOR_TEST_PATTERN_MODE,
                 ANDROID_SENSOR_TEST_PATTERN_MODE_OFF);

  uint8_t timestamp_source;
  if (V4L2CameraDevice::GetUvcClock() == CLOCK_BOOTTIME) {
    timestamp_source = ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME;
  } else {
    timestamp_source = ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN;
  }
  update_static(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE, timestamp_source);

  // android.shading
  update_static(ANDROID_SHADING_AVAILABLE_MODES, ANDROID_SHADING_MODE_FAST);

  // android.statistics
  update_static(ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
                ANDROID_STATISTICS_FACE_DETECT_MODE_OFF);
  update_request(ANDROID_STATISTICS_FACE_DETECT_MODE,
                 ANDROID_STATISTICS_FACE_DETECT_MODE_OFF);

  update_static(ANDROID_STATISTICS_INFO_MAX_FACE_COUNT, int32_t{0});

  update_static(ANDROID_STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES,
                ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE_OFF);
  update_request(ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE,
                 ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE_OFF);

  update_static(ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES,
                ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF);

  // android.sync
  update_static(ANDROID_SYNC_MAX_LATENCY, ANDROID_SYNC_MAX_LATENCY_UNKNOWN);

  return update_static.ok() || update_request.ok() ? 0 : -EINVAL;
}

int MetadataHandler::FillMetadataFromSupportedFormats(
    const SupportedFormats& supported_formats,
    const DeviceInfo& device_info,
    android::CameraMetadata* static_metadata,
    android::CameraMetadata* request_metadata) {
  bool is_external = device_info.lens_facing == ANDROID_LENS_FACING_EXTERNAL;

  if (supported_formats.empty()) {
    return -EINVAL;
  }
  std::vector<int32_t> stream_configurations;
  std::vector<int64_t> min_frame_durations;
  std::vector<int64_t> stall_durations;

  // The min fps <= 15 must be supported in CTS.
  const int64_t kOneSecOfNanoUnit = 1000000000LL;
  int32_t max_fps = std::numeric_limits<int32_t>::min();
  int64_t max_frame_duration = kOneSecOfNanoUnit / kMinFps;
  std::set<int32_t> supported_fps;

  std::vector<int> hal_formats{HAL_PIXEL_FORMAT_BLOB,
                               HAL_PIXEL_FORMAT_YCbCr_420_888,
                               HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED};

  std::unordered_map<int, int> max_hal_width_by_format;
  std::unordered_map<int, int> max_hal_height_by_format;
  std::unique_ptr<CameraConfig> camera_config =
      CameraConfig::Create(constants::kCrosCameraConfigPathString);
  max_hal_width_by_format[HAL_PIXEL_FORMAT_BLOB] = camera_config->GetInteger(
      constants::kCrosMaxBlobWidth, std::numeric_limits<int>::max());
  max_hal_width_by_format[HAL_PIXEL_FORMAT_YCbCr_420_888] =
      camera_config->GetInteger(constants::kCrosMaxYuvWidth,
                                std::numeric_limits<int>::max());
  max_hal_width_by_format[HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED] =
      camera_config->GetInteger(constants::kCrosMaxPrivateWidth,
                                std::numeric_limits<int>::max());

  max_hal_height_by_format[HAL_PIXEL_FORMAT_BLOB] = camera_config->GetInteger(
      constants::kCrosMaxBlobHeight, std::numeric_limits<int>::max());
  max_hal_height_by_format[HAL_PIXEL_FORMAT_YCbCr_420_888] =
      camera_config->GetInteger(constants::kCrosMaxYuvHeight,
                                std::numeric_limits<int>::max());
  max_hal_height_by_format[HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED] =
      camera_config->GetInteger(constants::kCrosMaxPrivateHeight,
                                std::numeric_limits<int>::max());

  for (const auto& supported_format : supported_formats) {
    int64_t min_frame_duration = std::numeric_limits<int64_t>::max();
    int32_t per_format_max_fps = std::numeric_limits<int32_t>::min();
    for (const auto& frame_rate : supported_format.frame_rates) {
      // To prevent floating point precision problem we cast the floating point
      // to double here.
      int64_t frame_duration =
          kOneSecOfNanoUnit / static_cast<double>(frame_rate);
      if (frame_duration < min_frame_duration) {
        min_frame_duration = frame_duration;
      }
      if (frame_duration > max_frame_duration) {
        max_frame_duration = frame_duration;
      }
      if (per_format_max_fps < static_cast<int32_t>(frame_rate)) {
        per_format_max_fps = static_cast<int32_t>(frame_rate);
      }
      supported_fps.insert(frame_rate);
    }
    if (per_format_max_fps > max_fps) {
      max_fps = per_format_max_fps;
    }

    for (const auto& format : hal_formats) {
      if (!is_external) {
        if (supported_format.width > max_hal_width_by_format[format]) {
          LOGF(INFO) << "Filter Format: 0x" << std::hex << format << std::dec
                     << "-width " << supported_format.width << ". max is "
                     << max_hal_width_by_format[format];
          continue;
        }
        if (supported_format.height > max_hal_height_by_format[format]) {
          LOGF(INFO) << "Filter Format: 0x" << std::hex << format << std::dec
                     << "-height " << supported_format.height << ". max is "
                     << max_hal_height_by_format[format];
          continue;
        }
        if (format != HAL_PIXEL_FORMAT_BLOB && per_format_max_fps < 30) {
          continue;
        }
      }

      stream_configurations.push_back(format);
      stream_configurations.push_back(supported_format.width);
      stream_configurations.push_back(supported_format.height);
      stream_configurations.push_back(
          ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);

      min_frame_durations.push_back(format);
      min_frame_durations.push_back(supported_format.width);
      min_frame_durations.push_back(supported_format.height);
      min_frame_durations.push_back(min_frame_duration);
    }

    // The stall duration is 0 for non-jpeg formats. For JPEG format, stall
    // duration can be 0 if JPEG is small. 5MP JPEG takes 700ms to decode
    // and encode. Here we choose 1 sec for JPEG.
    for (const auto& format : hal_formats) {
      // For non-jpeg formats, the camera orientation workaround crops,
      // rotates, and scales the frames. Theoretically the stall duration of
      // huge resolution may be bigger than 0. Set it to 0 for now.
      int64_t stall_duration =
          (format == HAL_PIXEL_FORMAT_BLOB) ? 1000000000 : 0;
      stall_durations.push_back(format);
      stall_durations.push_back(supported_format.width);
      stall_durations.push_back(supported_format.height);
      stall_durations.push_back(stall_duration);
    }
  }

  SupportedFormat maximum_format = GetMaximumFormat(supported_formats);
  std::vector<int32_t> active_array_size = {
      0, 0, static_cast<int32_t>(maximum_format.width),
      static_cast<int32_t>(maximum_format.height)};

  MetadataUpdater update_static(static_metadata);
  MetadataUpdater update_request(request_metadata);

  // The document in aeAvailableTargetFpsRanges section says the min fps should
  // not be larger than 15.
  // We enumerate all possible fps and put (min, fps) as available fps range. If
  // the device support constant frame rate, put (fps, fps) into the list as
  // well.
  // TODO(wtlee): Handle non-integer fps when setting controls.
  bool support_constant_framerate = !device_info.constant_framerate_unsupported;
  std::vector<int32_t> available_fps_ranges;

  // For devices that cannot actually meet the fps ranges they report, only
  // report (min, max) and optional (max, max) if they support constant frame
  // rate.
  if (device_info.quirks & kQuirkReportLeastFpsRanges) {
    available_fps_ranges.push_back(kMinFps);
    available_fps_ranges.push_back(max_fps);

    if (support_constant_framerate) {
      available_fps_ranges.push_back(max_fps);
      available_fps_ranges.push_back(max_fps);
    }
  } else {
    for (auto fps : supported_fps) {
      available_fps_ranges.push_back(kMinFps);
      available_fps_ranges.push_back(fps);

      if (support_constant_framerate) {
        available_fps_ranges.push_back(fps);
        available_fps_ranges.push_back(fps);
      }
    }
  }
  update_static(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
                available_fps_ranges);
  update_static(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
                stream_configurations);
  update_static(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
                min_frame_durations);
  update_static(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS, stall_durations);

  std::vector<int32_t> jpeg_available_thumbnail_sizes =
      GetJpegAvailableThumbnailSizes(supported_formats);
  update_static(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
                jpeg_available_thumbnail_sizes);
  update_request(ANDROID_JPEG_THUMBNAIL_SIZE,
                 std::vector<int32_t>(jpeg_available_thumbnail_sizes.end() - 2,
                                      jpeg_available_thumbnail_sizes.end()));
  update_static(ANDROID_SENSOR_INFO_MAX_FRAME_DURATION, max_frame_duration);
  update_static(ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE,
                active_array_size);
  update_static(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE, active_array_size);

  if (is_external) {
    // It's a sensible value for external camera, since it's required on all
    // devices per spec.  For built-in camera, this would be filled in
    // FillMetadataFromDeviceInfo() using the value from the configuration file.
    // References:
    // * The official document for this field
    //   https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics.html#SENSOR_INFO_PIXEL_ARRAY_SIZE
    // * The implementation of external camera in Android P
    //   https://googleplex-android.git.corp.google.com/platform/hardware/interfaces/+/6ad8708bf8b631561fa11eb1f4889907d1772d78/camera/device/3.4/default/ExternalCameraDevice.cpp#687
    update_static(
        ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
        std::vector<int32_t>{static_cast<int32_t>(maximum_format.width),
                             static_cast<int32_t>(maximum_format.height)});
  }

  return update_static.ok() && update_request.ok() ? 0 : -EINVAL;
}

// static
int MetadataHandler::FillMetadataFromDeviceInfo(
    const DeviceInfo& device_info,
    android::CameraMetadata* static_metadata,
    android::CameraMetadata* request_metadata) {
  MetadataUpdater update_static(static_metadata);
  MetadataUpdater update_request(request_metadata);

  bool is_external = device_info.lens_facing == ANDROID_LENS_FACING_EXTERNAL;
  bool is_builtin = !is_external;

  std::vector<int32_t> available_request_keys = {
      ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
      ANDROID_CONTROL_AE_ANTIBANDING_MODE,
      ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
      ANDROID_CONTROL_AE_LOCK,
      ANDROID_CONTROL_AE_MODE,
      ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
      ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
      ANDROID_CONTROL_AF_MODE,
      ANDROID_CONTROL_AF_TRIGGER,
      ANDROID_CONTROL_AWB_LOCK,
      ANDROID_CONTROL_AWB_MODE,
      ANDROID_CONTROL_CAPTURE_INTENT,
      ANDROID_CONTROL_EFFECT_MODE,
      ANDROID_CONTROL_MODE,
      ANDROID_CONTROL_SCENE_MODE,
      ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
      ANDROID_FLASH_MODE,
      ANDROID_JPEG_ORIENTATION,
      ANDROID_JPEG_QUALITY,
      ANDROID_JPEG_THUMBNAIL_QUALITY,
      ANDROID_JPEG_THUMBNAIL_SIZE,
      ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
      ANDROID_NOISE_REDUCTION_MODE,
      ANDROID_SCALER_CROP_REGION,
      ANDROID_SENSOR_TEST_PATTERN_MODE,
      ANDROID_STATISTICS_FACE_DETECT_MODE,
      ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE,
  };
  if (is_builtin) {
    available_request_keys.insert(available_request_keys.end(),
                                  {
                                      ANDROID_LENS_APERTURE,
                                      ANDROID_LENS_FOCAL_LENGTH,
                                      ANDROID_LENS_FOCUS_DISTANCE,
                                  });
  }
  update_static(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS, available_request_keys);

  // TODO(shik): All properties listed for capture requests can also be queried
  // on the capture result, to determine the final values used for capture. We
  // shuold build this list from |available_request_keys|.
  // ref:
  // https://developer.android.com/reference/android/hardware/camera2/CaptureResult
  std::vector<int32_t> available_result_keys = {
      ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
      ANDROID_CONTROL_AE_ANTIBANDING_MODE,
      ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
      ANDROID_CONTROL_AE_LOCK,
      ANDROID_CONTROL_AE_MODE,
      ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
      ANDROID_CONTROL_AE_STATE,
      ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
      ANDROID_CONTROL_AF_MODE,
      ANDROID_CONTROL_AF_STATE,
      ANDROID_CONTROL_AF_TRIGGER,
      ANDROID_CONTROL_AWB_LOCK,
      ANDROID_CONTROL_AWB_MODE,
      ANDROID_CONTROL_AWB_STATE,
      ANDROID_CONTROL_CAPTURE_INTENT,
      ANDROID_CONTROL_EFFECT_MODE,
      ANDROID_CONTROL_MODE,
      ANDROID_CONTROL_SCENE_MODE,
      ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
      ANDROID_FLASH_MODE,
      ANDROID_FLASH_STATE,
      ANDROID_JPEG_ORIENTATION,
      ANDROID_JPEG_QUALITY,
      ANDROID_JPEG_THUMBNAIL_QUALITY,
      ANDROID_JPEG_THUMBNAIL_SIZE,
      ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
      ANDROID_LENS_STATE,
      ANDROID_NOISE_REDUCTION_MODE,
      ANDROID_REQUEST_PIPELINE_DEPTH,
      ANDROID_SCALER_CROP_REGION,
      ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
      ANDROID_SENSOR_TEST_PATTERN_MODE,
      ANDROID_SENSOR_TIMESTAMP,
      ANDROID_STATISTICS_FACE_DETECT_MODE,
      ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE,
      ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
      ANDROID_STATISTICS_SCENE_FLICKER,
  };
  if (is_builtin) {
    available_result_keys.insert(available_result_keys.end(),
                                 {
                                     ANDROID_LENS_APERTURE,
                                     ANDROID_LENS_FOCAL_LENGTH,
                                     ANDROID_LENS_FOCUS_DISTANCE,
                                 });
  }
  update_static(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS, available_result_keys);

  // TODO(shik): The HAL must not have any tags in its static info that are not
  // listed either here or in the vendor tag list.  Some request/result metadata
  // entries are also presented in the static info now, and we should fix it.
  // ref:
  // https://android.googlesource.com/platform/system/media/+/a8cff157ff0ed02fa7e29438f4889a9933c37768/camera/docs/docs.html#16298
  std::vector<int32_t> available_characteristics_keys = {
      ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
      ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
      ANDROID_CONTROL_AE_AVAILABLE_MODES,
      ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
      ANDROID_CONTROL_AE_COMPENSATION_RANGE,
      ANDROID_CONTROL_AE_COMPENSATION_STEP,
      ANDROID_CONTROL_AE_LOCK_AVAILABLE,
      ANDROID_CONTROL_AF_AVAILABLE_MODES,
      ANDROID_CONTROL_AVAILABLE_EFFECTS,
      ANDROID_CONTROL_AVAILABLE_MODES,
      ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
      ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
      ANDROID_CONTROL_AWB_AVAILABLE_MODES,
      ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
      ANDROID_CONTROL_MAX_REGIONS,
      ANDROID_FLASH_INFO_AVAILABLE,
      ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
      ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
      ANDROID_JPEG_MAX_SIZE,
      ANDROID_LENS_FACING,
      ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
      ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION,
      ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,
      ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
      ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
      ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
      ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS,
      ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
      ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
      ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
      ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
      ANDROID_SCALER_CROPPING_TYPE,
      ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
      ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
      ANDROID_SENSOR_INFO_MAX_FRAME_DURATION,
      ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
      ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE,
      ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
      ANDROID_SENSOR_ORIENTATION,
      ANDROID_SHADING_AVAILABLE_MODES,
      ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
      ANDROID_STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES,
      ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES,
      ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
      ANDROID_SYNC_MAX_LATENCY,
  };
  if (is_builtin) {
    available_characteristics_keys.insert(
        available_characteristics_keys.end(),
        {
            ANDROID_LENS_INFO_AVAILABLE_APERTURES,
            ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
            ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
            ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
        });
  }
  update_static(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS,
                available_characteristics_keys);

  update_static(ANDROID_SENSOR_ORIENTATION, device_info.sensor_orientation);
  update_static(ANDROID_LENS_FACING,
                static_cast<uint8_t>(device_info.lens_facing));

  if (is_builtin) {
    update_static(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
                  ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED);

    update_static(ANDROID_LENS_INFO_AVAILABLE_APERTURES,
                  device_info.lens_info_available_apertures);

    update_request(ANDROID_LENS_APERTURE,
                   device_info.lens_info_available_apertures[0]);

    update_static(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
                  device_info.lens_info_available_focal_lengths);

    update_request(ANDROID_LENS_FOCAL_LENGTH,
                   device_info.lens_info_available_focal_lengths[0]);

    update_static(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
                  device_info.lens_info_minimum_focus_distance);

    update_request(ANDROID_LENS_FOCUS_DISTANCE,
                   device_info.lens_info_optimal_focus_distance);

    update_static(
        ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
        std::vector<float>{device_info.sensor_info_physical_size_width,
                           device_info.sensor_info_physical_size_height});

    update_static(
        ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
        std::vector<int32_t>{device_info.sensor_info_pixel_array_size_width,
                             device_info.sensor_info_pixel_array_size_height});
  } else {
    update_static(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
                  ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL);
  }

  update_static(ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION,
                ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION_UNCALIBRATED);

  update_static(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
                ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO);
  update_request(ANDROID_CONTROL_AE_ANTIBANDING_MODE,
                 ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO);

  bool support_af =
      V4L2CameraDevice::IsAutoFocusSupported(device_info.device_path);
  if (support_af) {
    update_static(ANDROID_CONTROL_AF_AVAILABLE_MODES,
                  std::vector<uint8_t>{ANDROID_CONTROL_AF_MODE_OFF,
                                       ANDROID_CONTROL_AF_MODE_AUTO});
    update_request(ANDROID_CONTROL_AF_MODE, ANDROID_CONTROL_AF_MODE_AUTO);
  } else {
    update_static(ANDROID_CONTROL_AF_AVAILABLE_MODES,
                  ANDROID_CONTROL_AF_MODE_OFF);
    update_request(ANDROID_CONTROL_AF_MODE, ANDROID_CONTROL_AF_MODE_OFF);
    // If auto focus is not supported, the minimum focus distance should be 0.
    // Overwrite the value here since there are many camera modules have wrong
    // config.
    update_static(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE, 0.0f);
  }

  // Set vendor tags for specified boards.
  if (device_info.quirks & kQuirkMonocle) {
    int32_t timestamp_sync =
        static_cast<int32_t>(mojom::CameraSensorSyncTimestamp::NEAREST);
    update_static(kVendorTagTimestampSync, timestamp_sync);
  }

  return 0;
}

const camera_metadata_t* MetadataHandler::GetDefaultRequestSettings(
    int template_type) {
  if (!IsValidTemplateType(template_type)) {
    LOGF(ERROR) << "Invalid template request type: " << template_type;
    return nullptr;
  }
  return template_settings_[template_type].get();
}

int MetadataHandler::PreHandleRequest(int frame_number,
                                      const Size& resolution,
                                      android::CameraMetadata* metadata) {
  DCHECK(thread_checker_.CalledOnValidThread());
  MetadataUpdater update_request(metadata);

  if (metadata->exists(ANDROID_CONTROL_AF_TRIGGER)) {
    camera_metadata_entry entry = metadata->find(ANDROID_CONTROL_AF_TRIGGER);
    if (entry.data.u8[0] == ANDROID_CONTROL_AF_TRIGGER_START) {
      af_trigger_ = true;
    } else if (entry.data.u8[0] == ANDROID_CONTROL_AF_TRIGGER_CANCEL) {
      af_trigger_ = false;
    }
  }

  if (metadata->exists(ANDROID_CONTROL_AF_MODE)) {
    camera_metadata_entry entry = metadata->find(ANDROID_CONTROL_AF_MODE);
    if (entry.data.u8[0] == ANDROID_CONTROL_AF_MODE_OFF) {
      device_->SetAutoFocus(false);
    } else if (entry.data.u8[0] == ANDROID_CONTROL_AF_MODE_AUTO) {
      device_->SetAutoFocus(true);
    }
  }

  const int64_t rolling_shutter_skew =
      sensor_handler_->GetRollingShutterSkew(resolution);
  update_request(ANDROID_SENSOR_ROLLING_SHUTTER_SKEW, rolling_shutter_skew);

  const int64_t exposure_time = sensor_handler_->GetExposureTime(resolution);
  update_request(ANDROID_SENSOR_EXPOSURE_TIME, exposure_time);

  current_frame_number_ = frame_number;
  return 0;
}

int MetadataHandler::PostHandleRequest(int frame_number,
                                       int64_t timestamp,
                                       android::CameraMetadata* metadata) {
  DCHECK(thread_checker_.CalledOnValidThread());
  if (current_frame_number_ != frame_number) {
    LOGF(ERROR)
        << "Frame number mismatch in PreHandleRequest and PostHandleRequest";
    return -EINVAL;
  }

  MetadataUpdater update_request(metadata);
  // android.control
  // For USB camera, we don't know the AE state. Set the state to converged to
  // indicate the frame should be good to use. Then apps don't have to wait the
  // AE state.
  update_request(ANDROID_CONTROL_AE_STATE, ANDROID_CONTROL_AE_STATE_CONVERGED);
  update_request(ANDROID_CONTROL_AE_LOCK, ANDROID_CONTROL_AE_LOCK_OFF);

  // For USB camera, the USB camera handles everything and we don't have control
  // over AF. We only simply fake the AF metadata based on the request
  // received here.
  uint8_t af_state;
  if (af_trigger_) {
    af_state = ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED;
  } else {
    af_state = ANDROID_CONTROL_AF_STATE_INACTIVE;
  }
  update_request(ANDROID_CONTROL_AF_STATE, af_state);

  // Set AWB state to converged to indicate the frame should be good to use.
  update_request(ANDROID_CONTROL_AWB_STATE,
                 ANDROID_CONTROL_AWB_STATE_CONVERGED);

  update_request(ANDROID_CONTROL_AWB_LOCK, ANDROID_CONTROL_AWB_LOCK_OFF);

  camera_metadata_entry active_array_size =
      static_metadata_.find(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE);

  if (active_array_size.count == 0) {
    LOGF(ERROR) << "Active array size is not found.";
    return -EINVAL;
  }

  // android.lens
  // Since android.lens.focalLength, android.lens.focusDistance and
  // android.lens.aperture are all fixed. And we don't support
  // android.lens.filterDensity so we can set the state to stationary.
  update_request(ANDROID_LENS_STATE, ANDROID_LENS_STATE_STATIONARY);

  // android.scaler
  update_request(ANDROID_SCALER_CROP_REGION, std::vector<int32_t>{
                                                 active_array_size.data.i32[0],
                                                 active_array_size.data.i32[1],
                                                 active_array_size.data.i32[2],
                                                 active_array_size.data.i32[3],
                                             });

  // android.sensor
  update_request(ANDROID_SENSOR_TIMESTAMP, timestamp);

  // android.statistics
  update_request(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
                 ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF);

  update_request(ANDROID_STATISTICS_SCENE_FLICKER,
                 ANDROID_STATISTICS_SCENE_FLICKER_NONE);
  return 0;
}

bool MetadataHandler::IsValidTemplateType(int template_type) {
  return template_type > 0 && template_type < CAMERA3_TEMPLATE_COUNT;
}

ScopedCameraMetadata MetadataHandler::CreateDefaultRequestSettings(
    int template_type) {
  android::CameraMetadata data(request_template_);

  int ret;
  switch (template_type) {
    case CAMERA3_TEMPLATE_PREVIEW:
      ret = FillDefaultPreviewSettings(&data);
      break;
    case CAMERA3_TEMPLATE_STILL_CAPTURE:
      ret = FillDefaultStillCaptureSettings(&data);
      break;
    case CAMERA3_TEMPLATE_VIDEO_RECORD:
      ret = FillDefaultVideoRecordSettings(&data);
      break;
    case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
      ret = FillDefaultVideoSnapshotSettings(&data);
      break;
    case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
      ret = FillDefaultZeroShutterLagSettings(&data);
      break;
    case CAMERA3_TEMPLATE_MANUAL:
      ret = FillDefaultManualSettings(&data);
      break;
    default:
      LOGF(ERROR) << "Invalid template request type: " << template_type;
      return NULL;
  }

  if (ret) {
    return ScopedCameraMetadata();
  }
  return ScopedCameraMetadata(data.release());
}

int MetadataHandler::FillDefaultPreviewSettings(
    android::CameraMetadata* metadata) {
  MetadataUpdater update_request(metadata);

  // android.control
  update_request(ANDROID_CONTROL_CAPTURE_INTENT,
                 ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW);
  update_request(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
                 std::vector<int32_t>{kMinFps, max_supported_fps_});

  update_request(ANDROID_CONTROL_MODE, ANDROID_CONTROL_MODE_AUTO);
  return 0;
}

int MetadataHandler::FillDefaultStillCaptureSettings(
    android::CameraMetadata* metadata) {
  MetadataUpdater update_request(metadata);

  // android.colorCorrection
  update_request(ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
                 ANDROID_COLOR_CORRECTION_ABERRATION_MODE_HIGH_QUALITY);

  // android.control
  update_request(ANDROID_CONTROL_CAPTURE_INTENT,
                 ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE);
  update_request(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
                 std::vector<int32_t>{kMinFps, max_supported_fps_});

  update_request(ANDROID_CONTROL_MODE, ANDROID_CONTROL_MODE_AUTO);
  return 0;
}

int MetadataHandler::FillDefaultVideoRecordSettings(
    android::CameraMetadata* metadata) {
  MetadataUpdater update_request(metadata);

  // android.control
  update_request(ANDROID_CONTROL_CAPTURE_INTENT,
                 ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD);
  update_request(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
                 std::vector<int32_t>{max_supported_fps_, max_supported_fps_});

  update_request(ANDROID_CONTROL_MODE, ANDROID_CONTROL_MODE_AUTO);
  return 0;
}

int MetadataHandler::FillDefaultVideoSnapshotSettings(
    android::CameraMetadata* metadata) {
  MetadataUpdater update_request(metadata);

  // android.control
  update_request(ANDROID_CONTROL_CAPTURE_INTENT,
                 ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT);
  update_request(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
                 std::vector<int32_t>{max_supported_fps_, max_supported_fps_});

  update_request(ANDROID_CONTROL_MODE, ANDROID_CONTROL_MODE_AUTO);
  return 0;
}

int MetadataHandler::FillDefaultZeroShutterLagSettings(
    android::CameraMetadata* /*metadata*/) {
  // Do not support ZSL template.
  return -EINVAL;
}

int MetadataHandler::FillDefaultManualSettings(
    android::CameraMetadata* /*metadata*/) {
  // Do not support manual template.
  return -EINVAL;
}

}  // namespace cros
