/*
 * 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 <algorithm>
#include <cmath>
#include <limits>
#include <map>
#include <set>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>

#include <base/no_destructor.h>

#include <chromeos-config/libcros_config/cros_config.h>
#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 cros {

namespace {

constexpr int32_t kMinFps = 1;
constexpr float kDefaultAvailableFocalLength = 1.6f;
constexpr float kDefaultMinimumFocusDistance = 0.3f;
constexpr float kDefaultLensFocusDistance = 0.5f;

const cros::AwbModeToTemperatureMap& GetAwbModeTemperatureMap() {
  // https://source.android.com/devices/camera/camera3_3Amodes#auto-wb
  static const base::NoDestructor<cros::AwbModeToTemperatureMap>
      kAwbModeTemperatureMap({
          {ANDROID_CONTROL_AWB_MODE_INCANDESCENT, 2700},
          {ANDROID_CONTROL_AWB_MODE_FLUORESCENT, 5000},
          {ANDROID_CONTROL_AWB_MODE_WARM_FLUORESCENT, 3000},
          {ANDROID_CONTROL_AWB_MODE_DAYLIGHT, 5500},
          {ANDROID_CONTROL_AWB_MODE_CLOUDY_DAYLIGHT, 6500},
          {ANDROID_CONTROL_AWB_MODE_TWILIGHT, 15000},
          {ANDROID_CONTROL_AWB_MODE_SHADE, 7500},
      });
  return *kAwbModeTemperatureMap;
}

uint32_t GetAwbTemperatureByMode(
    const cros::ControlRange& range,
    camera_metadata_enum_android_control_awb_mode mode) {
  const cros::AwbModeToTemperatureMap& map = GetAwbModeTemperatureMap();

  if (mode == ANDROID_CONTROL_AWB_MODE_AUTO)
    return 0;

  auto it = map.find(mode);
  if (it == map.end()) {
    LOGF(ERROR) << "Can't find mode " << mode;
    return 0;
  }

  // Get acceptable temperature by minimum and step. in case the step is
  // too large.
  uint32_t temperature =
      range.minimum + range.step * ((it->second - range.minimum) / range.step);

  if (temperature < range.minimum || temperature > range.maximum)
    return 0;

  return temperature;
}

std::vector<float> GetPhysicalSize(float horiz_fov,
                                   float vert_fov,
                                   float focal_length,
                                   float array_aspect,
                                   float still_aspect) {
  float angle_to_rad_ratio = M_PI / 180.f;
  float crop_factor = still_aspect / array_aspect;
  float horiz_crop_factor = std::min(1.f, crop_factor);
  float vert_crop_factor = std::min(1.f, 1.f / crop_factor);
  return {2.f * focal_length * std::tan(horiz_fov * angle_to_rad_ratio / 2.f) /
              horiz_crop_factor,
          2.f * focal_length * std::tan(vert_fov * angle_to_rad_ratio / 2.f) /
              vert_crop_factor};
}

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 " << std::hex << std::showbase
                  << tag << " failed" << std::dec;
    }
  }

  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_;
};

// Checks if a fps range can be filled into aeAvailableTargetFpsRanges given a
// list of supported formats.
// Android metadata only reports min frame duration for each format/resolution.
// CTS assumes a fps range is supported if the min frame duration (1/max_fps)
// covers the range. Thus we need to check if the USB camera actually supports
// some fps in the range.
bool IsFpsRangeSupported(const SupportedFormats& supported_formats,
                         int32_t fps_range_min,
                         int32_t fps_range_max) {
  for (const auto& format : supported_formats) {
    const int32_t max_fps = static_cast<int32_t>(*std::max_element(
        format.frame_rates.begin(), format.frame_rates.end()));
    if (max_fps >= fps_range_max) {
      const bool has_fps_in_range = std::any_of(
          format.frame_rates.begin(), format.frame_rates.end(), [&](float x) {
            const int32_t fps = static_cast<int32_t>(x);
            return fps_range_min <= fps && fps <= fps_range_max;
          });
      if (!has_fps_in_range)
        return false;
    }
  }
  return true;
}

Size GetMaxDimensions(const SupportedFormats& formats) {
  uint32_t max_width = 0;
  uint32_t max_height = 0;
  for (const SupportedFormat& format : formats) {
    max_width = std::max(max_width, format.width);
    max_height = std::max(max_height, format.height);
  }
  return Size(max_width, max_height);
}

}  // namespace

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);

  is_awb_control_supported_ = V4L2CameraDevice::IsControlSupported(
      device_info_.device_path, kControlWhiteBalanceTemperature);
  awb_temperature_ = GetAvailableAwbTemperatures(device_info);

  is_brightness_control_supported_ = V4L2CameraDevice::IsControlSupported(
      device_info.device_path, kControlBrightness);
  is_contrast_control_supported_ = V4L2CameraDevice::IsControlSupported(
      device_info.device_path, kControlContrast);
  is_pan_control_supported_ = V4L2CameraDevice::IsControlSupported(
      device_info.device_path, kControlPan);
  is_saturation_control_supported_ = V4L2CameraDevice::IsControlSupported(
      device_info.device_path, kControlSaturation);
  is_sharpness_control_supported_ = V4L2CameraDevice::IsControlSupported(
      device_info.device_path, kControlSharpness);
  is_tilt_control_supported_ = V4L2CameraDevice::IsControlSupported(
      device_info.device_path, kControlTilt);
  is_zoom_control_supported_ = V4L2CameraDevice::IsControlSupported(
      device_info.device_path, kControlZoom);

  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 == LensFacing::kExternal;
  bool is_builtin = !is_external;
  bool is_v1_builtin = device_info.quirks & kQuirkV1Device;

  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_builtin) {
        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);
    }
  }

  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) {
      // The IsFpsRangeSupported() filter should only apply on built-in
      // cameras, otherwise some webcams with fps combinations that cannot be
      // represented in HALv3 API would stop working (b/171845790).
      if (is_external || IsFpsRangeSupported(supported_formats, kMinFps, fps)) {
        available_fps_ranges.push_back(kMinFps);
        available_fps_ranges.push_back(fps);
      }

      if (support_constant_framerate &&
          (is_external || IsFpsRangeSupported(supported_formats, fps, fps))) {
        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);

  const Size max_dimensions = GetMaxDimensions(supported_formats);
  std::vector<int32_t> active_array_size(4);
  if (device_info.sensor_info_active_array_size.is_valid()) {
    const Rect<int32_t>& rect = device_info.sensor_info_active_array_size;
    if (rect.width() < max_dimensions.width ||
        rect.height() < max_dimensions.height) {
      LOGF(ERROR) << "Sensor active array size (" << rect.width() << "x"
                  << rect.height()
                  << ") is smaller than max supported format dimensions ("
                  << max_dimensions.width << "x" << max_dimensions.height
                  << ")";
      return -EINVAL;
    }
    active_array_size[0] = rect.left;
    active_array_size[1] = rect.top;
    active_array_size[2] = rect.right;
    active_array_size[3] = rect.bottom;
  } else {
    active_array_size[0] = 0;
    active_array_size[1] = 0;
    active_array_size[2] = static_cast<int32_t>(max_dimensions.width);
    active_array_size[3] = static_cast<int32_t>(max_dimensions.height);
  }
  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_v1_builtin) {
    if (FillSensorInfo(device_info, static_metadata,
                       static_cast<int32_t>(max_dimensions.width),
                       static_cast<int32_t>(max_dimensions.height)) != 0) {
      LOGF(ERROR) << "Failed to fill sensor info for v1 built-in camera";
      return -EINVAL;
    }
  } else 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() or FillSensorInfo() using the value from the
    // configuration file.
    //
    // The official document for this field:
    // https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics.html#SENSOR_INFO_PIXEL_ARRAY_SIZE
    update_static(
        ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
        std::vector<int32_t>{static_cast<int32_t>(max_dimensions.width),
                             static_cast<int32_t>(max_dimensions.height)});
  }

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

// static
AwbModeToTemperatureMap MetadataHandler::GetAvailableAwbTemperatures(
    const DeviceInfo& device_info) {
  AwbModeToTemperatureMap available_awb_temperatures;

  available_awb_temperatures[ANDROID_CONTROL_AWB_MODE_AUTO] =
      kColorTemperatureAuto;

  if (!V4L2CameraDevice::IsControlSupported(device_info.device_path,
                                            kControlAutoWhiteBalance))
    return available_awb_temperatures;

  ControlInfo info;
  if (V4L2CameraDevice::QueryControl(
          device_info.device_path, kControlWhiteBalanceTemperature, &info) != 0)
    return available_awb_temperatures;

  for (auto& mode_temperature : GetAwbModeTemperatureMap()) {
    uint32_t temperature =
        GetAwbTemperatureByMode(info.range, mode_temperature.first);
    if (!temperature)
      continue;
    available_awb_temperatures[mode_temperature.first] = temperature;
  }

  return available_awb_temperatures;
}

// 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 == LensFacing::kExternal;
  bool is_builtin = !is_external;
  bool is_v1_builtin = device_info.quirks & kQuirkV1Device;
  bool is_v3_builtin = is_builtin && !is_v1_builtin;

  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,
                                  });
  }

  // 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_EXPOSURE_TIME,
      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,
                                 });
  }

  // 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) {
    if (!device_info.lens_info_available_apertures.empty()) {
      // This field is optional. Only list it if it presents in the
      // configuration.
      available_characteristics_keys.insert(
          available_characteristics_keys.end(),
          {
              ANDROID_LENS_INFO_AVAILABLE_APERTURES,
          });
    }
    available_characteristics_keys.insert(
        available_characteristics_keys.end(),
        {
            ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
            ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
            ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
        });
  }

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

  if (is_v3_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 if (is_v1_builtin) {
    update_static(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
                  ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL);

    if (device_info.lens_info_available_apertures.size() > 0) {
      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]);
    }

    if (device_info.lens_info_available_focal_lengths.size() > 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]);
    } else {
      update_static(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
                    kDefaultAvailableFocalLength);
      update_request(ANDROID_LENS_FOCAL_LENGTH, kDefaultAvailableFocalLength);
    }

    if (device_info.lens_info_minimum_focus_distance > 0) {
      update_static(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
                    device_info.lens_info_minimum_focus_distance);
    } else {
      update_static(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
                    kDefaultMinimumFocusDistance);
    }

    if (device_info.lens_info_optimal_focus_distance > 0) {
      update_request(ANDROID_LENS_FOCUS_DISTANCE,
                     device_info.lens_info_optimal_focus_distance);
    } else {
      update_request(ANDROID_LENS_FOCUS_DISTANCE, kDefaultLensFocusDistance);
    }

    if (device_info.sensor_info_pixel_array_size_width > 0 &&
        device_info.sensor_info_pixel_array_size_height > 0) {
      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});
    }
    // For |sensor_info_physical_size|, fill them later with supported formats
    // information.
  } 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);
  }

  ControlInfo info;

  if (V4L2CameraDevice::QueryControl(device_info.device_path,
                                     kControlBrightness, &info) == 0) {
    update_static(kVendorTagControlBrightnessRange,
                  std::vector<int32_t>{info.range.minimum, info.range.maximum,
                                       info.range.step});
  }

  if (V4L2CameraDevice::QueryControl(device_info.device_path, kControlContrast,
                                     &info) == 0) {
    update_static(kVendorTagControlContrastRange,
                  std::vector<int32_t>{info.range.minimum, info.range.maximum,
                                       info.range.step});
  }

  if (V4L2CameraDevice::QueryControl(device_info.device_path, kControlPan,
                                     &info) == 0) {
    update_static(kVendorTagControlPanRange,
                  std::vector<int32_t>{info.range.minimum, info.range.maximum,
                                       info.range.step});
  }

  if (V4L2CameraDevice::QueryControl(device_info.device_path,
                                     kControlSaturation, &info) == 0) {
    update_static(kVendorTagControlSaturationRange,
                  std::vector<int32_t>{info.range.minimum, info.range.maximum,
                                       info.range.step});
  }

  if (V4L2CameraDevice::QueryControl(device_info.device_path, kControlSharpness,
                                     &info) == 0) {
    update_static(kVendorTagControlSharpnessRange,
                  std::vector<int32_t>{info.range.minimum, info.range.maximum,
                                       info.range.step});
  }

  if (V4L2CameraDevice::QueryControl(device_info.device_path, kControlTilt,
                                     &info) == 0) {
    update_static(kVendorTagControlTiltRange,
                  std::vector<int32_t>{info.range.minimum, info.range.maximum,
                                       info.range.step});
  }

  if (V4L2CameraDevice::QueryControl(device_info.device_path, kControlZoom,
                                     &info) == 0) {
    update_static(kVendorTagControlZoomRange,
                  std::vector<int32_t>{info.range.minimum, info.range.maximum,
                                       info.range.step});
  }

  std::vector<uint8_t> available_awb_modes;
  for (auto const& it : GetAvailableAwbTemperatures(device_info))
    available_awb_modes.push_back(it.first);

  update_static(ANDROID_CONTROL_AWB_AVAILABLE_MODES, available_awb_modes);

  // Check if device supports manual exposure control.
  ControlRange range;
  if (V4L2CameraDevice::IsManualExposureTimeSupported(device_info.device_path,
                                                      &range)) {
    update_static(ANDROID_CONTROL_AE_AVAILABLE_MODES,
                  std::vector<uint8_t>{ANDROID_CONTROL_AE_MODE_OFF,
                                       ANDROID_CONTROL_AE_MODE_ON});
    // The unit of the range is 100 us.
    update_static(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
                  std::vector<int64_t>{
                      range.minimum * 100 * 1000 /* ns */,
                      range.maximum * 100 * 1000 /* ns */
                  });
    // CtsCameraTestCases needs it. This control is only effective if
    // android.control.aeMode is set to OFF.
    update_request(
        ANDROID_SENSOR_EXPOSURE_TIME,
        static_cast<int64_t>(range.default_value) * 100 * 1000 /* ns */);
    available_characteristics_keys.push_back(
        ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE);
    available_request_keys.push_back(ANDROID_SENSOR_EXPOSURE_TIME);
  }

  update_static(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS,
                available_characteristics_keys);
  update_static(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS, available_request_keys);
  update_static(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS, available_result_keys);
  return update_static.ok() && update_request.ok() ? 0 : -EINVAL;
}

int MetadataHandler::FillSensorInfo(const DeviceInfo& device_info,
                                    android::CameraMetadata* metadata,
                                    int32_t array_width,
                                    int32_t array_height) {
  MetadataUpdater update_static(metadata);

  if (device_info.sensor_info_pixel_array_size_width <= 0 ||
      device_info.sensor_info_pixel_array_size_height <= 0) {
    update_static(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
                  std::vector<int32_t>{array_width, array_height});
  }

  float focal_length = device_info.lens_info_available_focal_lengths.size() > 0
                           ? device_info.lens_info_available_focal_lengths[0]
                           : kDefaultAvailableFocalLength;

  float aspect_ratio = 1.f * array_width / array_height;
  bool is_closer_to_16_9 = std::fabs(aspect_ratio - 16.f / 9.f) <
                           std::fabs(aspect_ratio - 4.f / 3.f);
  bool has_fov_info_16_9 = device_info.horizontal_view_angle_16_9 > 0.f &&
                           device_info.vertical_view_angle_16_9 > 0.f;
  bool has_fov_info_4_3 = device_info.horizontal_view_angle_4_3 > 0.f &&
                          device_info.vertical_view_angle_4_3 > 0.f;

  // Use the FOV information (16:9 or 4:3) whose aspect ratio is closer to the
  // ratio of sensor array size to calculate the sensor physical size.
  if (has_fov_info_16_9 && (is_closer_to_16_9 || !has_fov_info_4_3)) {
    update_static(ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
                  GetPhysicalSize(device_info.horizontal_view_angle_16_9,
                                  device_info.vertical_view_angle_16_9,
                                  focal_length, aspect_ratio, 16.f / 9.f));
  } else if (has_fov_info_4_3) {
    update_static(ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
                  GetPhysicalSize(device_info.horizontal_view_angle_4_3,
                                  device_info.vertical_view_angle_4_3,
                                  focal_length, aspect_ratio, 4.f / 3.f));
  } else if (device_info.sensor_info_physical_size_width > 0.f &&
             device_info.sensor_info_physical_size_height > 0.f) {
    // Since the sensor physical size might be incorrect, only use these values
    // when there are no view angle information.
    update_static(
        ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
        std::vector<float>{device_info.sensor_info_physical_size_width,
                           device_info.sensor_info_physical_size_height});
  } else {
    LOGF(ERROR)
        << "Neither sensor physical size nor view angle information is found";
    return -EINVAL;
  }
  return update_static.ok() ? 0 : -EINVAL;
}

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();
}

bool MetadataHandler::ShouldEnableConstantFrameRate(
    const android::CameraMetadata* metadata) const {
  if (device_info_.constant_framerate_unsupported) {
    return false;
  }

  // TODO(shik): Add a helper function to do the exists() and find() combo, so
  // it's less likely to have typos in the tag name.

  if (metadata->exists(ANDROID_CONTROL_AE_TARGET_FPS_RANGE)) {
    camera_metadata_ro_entry entry =
        metadata->find(ANDROID_CONTROL_AE_TARGET_FPS_RANGE);
    if (entry.data.i32[0] == entry.data.i32[1]) {
      return true;
    }
  }

  if (metadata->exists(ANDROID_CONTROL_CAPTURE_INTENT)) {
    camera_metadata_ro_entry entry =
        metadata->find(ANDROID_CONTROL_CAPTURE_INTENT);
    switch (entry.data.u8[0]) {
      case ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD:
      case ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT:
        return true;
    }
  }

  return false;
}

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

  if (!device_info_.constant_framerate_unsupported) {
    bool enable = ShouldEnableConstantFrameRate(metadata);
    if (device_->SetControlValue(kControlExposureAutoPriority,
                                 enable ? 0 : 1) != 0) {
      LOGF(WARNING) << "Failed to set constant frame rate to " << std::boolalpha
                    << enable;
    }
  }

  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);
    }
  }

  if (is_awb_control_supported_ && metadata->exists(ANDROID_CONTROL_AWB_MODE)) {
    camera_metadata_entry entry = metadata->find(ANDROID_CONTROL_AWB_MODE);
    auto mode = static_cast<camera_metadata_enum_android_control_awb_mode>(
        entry.data.u8[0]);
    if (awb_temperature_.count(mode))
      device_->SetColorTemperature(awb_temperature_[mode]);
    else
      LOGF(WARNING) << "Unsupported AWB mode:" << mode;
  }

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

  if (metadata->exists(kVendorTagControlBrightness)) {
    camera_metadata_entry entry = metadata->find(kVendorTagControlBrightness);
    device_->SetControlValue(kControlBrightness, entry.data.i32[0]);
  }

  if (metadata->exists(kVendorTagControlContrast)) {
    camera_metadata_entry entry = metadata->find(kVendorTagControlContrast);
    device_->SetControlValue(kControlContrast, entry.data.i32[0]);
  }

  if (metadata->exists(kVendorTagControlPan)) {
    camera_metadata_entry entry = metadata->find(kVendorTagControlPan);
    device_->SetControlValue(kControlPan, entry.data.i32[0]);
  }

  if (metadata->exists(kVendorTagControlSaturation)) {
    camera_metadata_entry entry = metadata->find(kVendorTagControlSaturation);
    device_->SetControlValue(kControlSaturation, entry.data.i32[0]);
  }

  if (metadata->exists(kVendorTagControlSharpness)) {
    camera_metadata_entry entry = metadata->find(kVendorTagControlSharpness);
    device_->SetControlValue(kControlSharpness, entry.data.i32[0]);
  }

  if (metadata->exists(kVendorTagControlTilt)) {
    camera_metadata_entry entry = metadata->find(kVendorTagControlTilt);
    device_->SetControlValue(kControlTilt, entry.data.i32[0]);
  }

  if (metadata->exists(kVendorTagControlZoom)) {
    camera_metadata_entry entry = metadata->find(kVendorTagControlZoom);
    device_->SetControlValue(kControlZoom, entry.data.i32[0]);
  }

  if (metadata->exists(ANDROID_CONTROL_AE_MODE)) {
    camera_metadata_entry entry = metadata->find(ANDROID_CONTROL_AE_MODE);
    int32_t exposure_time;
    switch (entry.data.u8[0]) {
      case ANDROID_CONTROL_AE_MODE_ON:
        device_->SetExposureTimeHundredUs(kExposureTimeAuto);
        update_request(ANDROID_SENSOR_EXPOSURE_TIME,
                       sensor_handler_->GetExposureTime(resolution));
        break;

      case ANDROID_CONTROL_AE_MODE_OFF:
        if (metadata->exists(ANDROID_SENSOR_EXPOSURE_TIME)) {
          entry = metadata->find(ANDROID_SENSOR_EXPOSURE_TIME);
          exposure_time =
              static_cast<int32_t>(entry.data.i64[0] / (100 * 1000));  // ns
          device_->SetExposureTimeHundredUs(exposure_time);
          device_->GetControlValue(kControlExposureTime, &exposure_time);
          update_request(
              ANDROID_SENSOR_EXPOSURE_TIME,
              base::strict_cast<int64_t>(exposure_time) * 100 * 1000);  // ns
        } else {
          LOGF(WARNING) << "There is no ANDROID_SENSOR_EXPOSURE_TIME metadata";
        }
        break;

      default:
        LOGF(WARNING) << "Unsupport AE mode " << entry.data.u8[0];
        break;
    }
  }

  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);

  int32_t value;
  if (is_brightness_control_supported_ &&
      device_->GetControlValue(kControlBrightness, &value) == 0)
    update_request(kVendorTagControlBrightness, value);

  if (is_contrast_control_supported_ &&
      device_->GetControlValue(kControlContrast, &value) == 0)
    update_request(kVendorTagControlContrast, value);

  if (is_pan_control_supported_ &&
      device_->GetControlValue(kControlPan, &value) == 0)
    update_request(kVendorTagControlPan, value);

  if (is_saturation_control_supported_ &&
      device_->GetControlValue(kControlSaturation, &value) == 0)
    update_request(kVendorTagControlSaturation, value);

  if (is_sharpness_control_supported_ &&
      device_->GetControlValue(kControlSharpness, &value) == 0)
    update_request(kVendorTagControlSharpness, value);

  if (is_tilt_control_supported_ &&
      device_->GetControlValue(kControlTilt, &value) == 0)
    update_request(kVendorTagControlTilt, value);

  if (is_zoom_control_supported_ &&
      device_->GetControlValue(kControlZoom, &value) == 0)
    update_request(kVendorTagControlZoom, value);

  if (metadata->exists(ANDROID_CONTROL_AWB_MODE)) {
    update_request(ANDROID_CONTROL_AWB_MODE, ANDROID_CONTROL_AWB_MODE_AUTO);
    if (is_awb_control_supported_ &&
        device_->GetControlValue(kControlAutoWhiteBalance, &value) == 0) {
      if (!value &&  // Not auto white balance.
          device_->GetControlValue(kControlWhiteBalanceTemperature, &value) ==
              0) {
        for (auto& mode_temperature : awb_temperature_) {
          if (value == mode_temperature.second) {
            update_request(ANDROID_CONTROL_AWB_MODE, mode_temperature.first);
            break;
          }
        }
      }
    }
  }

  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);

  // android.jpeg
  update_request(ANDROID_JPEG_THUMBNAIL_SIZE, std::vector<int32_t>{0, 0});
  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);
  if (device_info_.constant_framerate_unsupported) {
    update_request(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
                   std::vector<int32_t>{kMinFps, max_supported_fps_});
  } else {
    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);
  if (device_info_.constant_framerate_unsupported) {
    update_request(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
                   std::vector<int32_t>{kMinFps, max_supported_fps_});
  } else {
    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
