// Copyright 2018 The Chromium 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 "media/capture/video/chromeos/camera_3a_controller.h"

#include <utility>

#include "base/bind.h"
#include "base/containers/contains.h"
#include "base/cxx17_backports.h"

#include "media/capture/video/chromeos/camera_metadata_utils.h"

namespace media {

namespace {

template <typename EntryType>
bool Get3AEntry(const cros::mojom::CameraMetadataPtr& metadata,
                cros::mojom::CameraMetadataTag control,
                EntryType* result) {
  const auto* entry = GetMetadataEntry(metadata, control);
  if (entry) {
    *result = static_cast<EntryType>((*entry)->data[0]);
    return true;
  } else {
    return false;
  }
}

}  // namespace

Camera3AController::Camera3AController(
    const cros::mojom::CameraMetadataPtr& static_metadata,
    CaptureMetadataDispatcher* capture_metadata_dispatcher,
    scoped_refptr<base::SingleThreadTaskRunner> task_runner)
    : static_metadata_(static_metadata),
      capture_metadata_dispatcher_(capture_metadata_dispatcher),
      task_runner_(std::move(task_runner)),
      af_mode_(cros::mojom::AndroidControlAfMode::ANDROID_CONTROL_AF_MODE_OFF),
      af_state_(cros::mojom::AndroidControlAfState::
                    ANDROID_CONTROL_AF_STATE_INACTIVE),
      af_mode_set_(false),
      ae_mode_(cros::mojom::AndroidControlAeMode::ANDROID_CONTROL_AE_MODE_ON),
      ae_state_(cros::mojom::AndroidControlAeState::
                    ANDROID_CONTROL_AE_STATE_INACTIVE),
      ae_mode_set_(false),
      awb_mode_(
          cros::mojom::AndroidControlAwbMode::ANDROID_CONTROL_AWB_MODE_AUTO),
      awb_state_(cros::mojom::AndroidControlAwbState::
                     ANDROID_CONTROL_AWB_STATE_INACTIVE),
      awb_mode_set_(false),
      set_point_of_interest_running_(false),
      ae_locked_for_point_of_interest_(false) {
  DCHECK(task_runner_->BelongsToCurrentThread());

  capture_metadata_dispatcher_->AddResultMetadataObserver(this);

  auto max_regions = GetMetadataEntryAsSpan<int32_t>(
      static_metadata_,
      cros::mojom::CameraMetadataTag::ANDROID_CONTROL_MAX_REGIONS);
  if (max_regions.empty()) {
    ae_region_supported_ = false;
    af_region_supported_ = false;
  } else {
    DCHECK_EQ(max_regions.size(), 3u);
    ae_region_supported_ = max_regions[0] > 0;
    af_region_supported_ = max_regions[2] > 0;
  }

  auto* af_modes = GetMetadataEntry(
      static_metadata_,
      cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AF_AVAILABLE_MODES);
  if (af_modes) {
    for (const auto& m : (*af_modes)->data) {
      available_af_modes_.insert(
          static_cast<cros::mojom::AndroidControlAfMode>(m));
    }
  }
  auto* ae_modes = GetMetadataEntry(
      static_metadata_,
      cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AE_AVAILABLE_MODES);
  if (ae_modes) {
    for (const auto& m : (*ae_modes)->data) {
      available_ae_modes_.insert(
          static_cast<cros::mojom::AndroidControlAeMode>(m));
    }
  }
  auto* awb_modes = GetMetadataEntry(
      static_metadata_,
      cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AWB_AVAILABLE_MODES);
  if (awb_modes) {
    for (const auto& m : (*awb_modes)->data) {
      available_awb_modes_.insert(
          static_cast<cros::mojom::AndroidControlAwbMode>(m));
    }
  }

  point_of_interest_supported_ = [&]() {
    // Because of line wrapping, multiple if-statements is more readable than a
    // super long boolean expression.
    auto available_modes = GetMetadataEntryAsSpan<uint8_t>(
        static_metadata_,
        cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AVAILABLE_MODES);
    if (available_modes.empty()) {
      return false;
    }
    if (std::find(
            available_modes.begin(), available_modes.end(),
            base::checked_cast<uint8_t>(
                cros::mojom::AndroidControlMode::ANDROID_CONTROL_MODE_AUTO)) ==
        available_modes.end()) {
      return false;
    }
    if (!available_ae_modes_.count(
            cros::mojom::AndroidControlAeMode::ANDROID_CONTROL_AE_MODE_ON)) {
      return false;
    }
    if (!available_af_modes_.count(
            cros::mojom::AndroidControlAfMode::ANDROID_CONTROL_AF_MODE_AUTO)) {
      return false;
    }
    if (!ae_region_supported_ && !af_region_supported_) {
      return false;
    }
    auto ae_lock_available = GetMetadataEntryAsSpan<uint8_t>(
        static_metadata_,
        cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AE_LOCK_AVAILABLE);
    if (ae_lock_available.empty()) {
      return false;
    }
    DCHECK_EQ(ae_lock_available.size(), 1u);
    if (ae_lock_available[0] !=
        base::checked_cast<uint8_t>(
            cros::mojom::AndroidControlAeLockAvailable::
                ANDROID_CONTROL_AE_LOCK_AVAILABLE_TRUE)) {
      return false;
    }
    return true;
  }();

  // Enable AF if supported.  MODE_AUTO is always supported on auto-focus camera
  // modules; fixed focus camera modules always has MODE_OFF.
  if (available_af_modes_.count(
          cros::mojom::AndroidControlAfMode::ANDROID_CONTROL_AF_MODE_AUTO)) {
    af_mode_ = cros::mojom::AndroidControlAfMode::ANDROID_CONTROL_AF_MODE_AUTO;
  }
  // AE should always be MODE_ON unless we enable manual sensor control.  Since
  // we don't have flash on any of our devices we don't care about the
  // flash-related AE modes.
  //
  // AWB should always be MODE_AUTO unless we enable manual sensor control.
  Set3AMode(cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AF_MODE,
            base::checked_cast<uint8_t>(af_mode_));
  Set3AMode(cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AE_MODE,
            base::checked_cast<uint8_t>(ae_mode_));
  Set3AMode(cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AWB_MODE,
            base::checked_cast<uint8_t>(awb_mode_));

  // Enable face detection if it's available.
  auto face_modes = GetMetadataEntryAsSpan<uint8_t>(
      static_metadata, cros::mojom::CameraMetadataTag::
                           ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES);
  // We don't need face landmarks and ids, so using SIMPLE mode instead of FULL
  // mode should be enough.
  const auto face_mode_simple = cros::mojom::AndroidStatisticsFaceDetectMode::
      ANDROID_STATISTICS_FACE_DETECT_MODE_SIMPLE;
  if (base::Contains(face_modes,
                     base::checked_cast<uint8_t>(face_mode_simple))) {
    SetRepeatingCaptureMetadata(
        cros::mojom::CameraMetadataTag::ANDROID_STATISTICS_FACE_DETECT_MODE,
        face_mode_simple);
  }

  auto request_keys = GetMetadataEntryAsSpan<int32_t>(
      static_metadata_,
      cros::mojom::CameraMetadataTag::ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS);
  zero_shutter_lag_supported_ = base::Contains(
      request_keys,
      static_cast<int32_t>(
          cros::mojom::CameraMetadataTag::ANDROID_CONTROL_ENABLE_ZSL));
}

Camera3AController::~Camera3AController() {
  DCHECK(task_runner_->BelongsToCurrentThread());

  ClearRepeatingCaptureMetadata();
  capture_metadata_dispatcher_->RemoveResultMetadataObserver(this);
}

void Camera3AController::Stabilize3AForStillCapture(
    base::OnceClosure on_3a_stabilized_callback) {
  DCHECK(task_runner_->BelongsToCurrentThread());

  if (set_point_of_interest_running_) {
    // Use the settings from point of interest.
    if (!on_ae_locked_for_point_of_interest_callback_) {
      on_ae_locked_for_point_of_interest_callback_ =
          std::move(on_3a_stabilized_callback);
    }
    return;
  }

  if (on_3a_stabilized_callback_ || on_3a_mode_set_callback_) {
    // Already stabilizing 3A.
    return;
  }

  if (Is3AStabilized() || zero_shutter_lag_supported_) {
    std::move(on_3a_stabilized_callback).Run();
    return;
  }

  // Wait until all the 3A modes are set in the HAL; otherwise the AF trigger
  // and AE precapture trigger may be invalidated during mode transition.
  if (!af_mode_set_ || !ae_mode_set_ || !awb_mode_set_) {
    on_3a_mode_set_callback_ =
        base::BindOnce(&Camera3AController::Stabilize3AForStillCapture,
                       GetWeakPtr(), std::move(on_3a_stabilized_callback));
    return;
  }

  Set3aStabilizedCallback(std::move(on_3a_stabilized_callback),
                          base::Seconds(2));

  if (af_mode_ !=
      cros::mojom::AndroidControlAfMode::ANDROID_CONTROL_AF_MODE_OFF) {
    DVLOG(1) << "Start AF trigger to lock focus";
    SetCaptureMetadata(
        cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AF_TRIGGER,
        cros::mojom::AndroidControlAfTrigger::ANDROID_CONTROL_AF_TRIGGER_START);
  }

  if (ae_mode_ !=
      cros::mojom::AndroidControlAeMode::ANDROID_CONTROL_AE_MODE_OFF) {
    DVLOG(1) << "Start AE precapture trigger to converge exposure";
    SetCaptureMetadata(
        cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
        cros::mojom::AndroidControlAePrecaptureTrigger::
            ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_START);
  }
}

void Camera3AController::OnResultMetadataAvailable(
    uint32_t frame_number,
    const cros::mojom::CameraMetadataPtr& result_metadata) {
  DCHECK(task_runner_->BelongsToCurrentThread());

  auto sensor_timestamp = GetMetadataEntryAsSpan<int64_t>(
      result_metadata,
      cros::mojom::CameraMetadataTag::ANDROID_SENSOR_TIMESTAMP);
  if (!sensor_timestamp.empty()) {
    DCHECK_EQ(sensor_timestamp.size(), 1u);
    // The sensor timestamp might not be monotonically increasing. The result
    // metadata from zero-shutter-lag request may be out of order compared to
    // previous regular requests.
    // https://developer.android.com/reference/android/hardware/camera2/CaptureResult#CONTROL_ENABLE_ZSL
    latest_sensor_timestamp_ = std::max(latest_sensor_timestamp_,
                                        base::Nanoseconds(sensor_timestamp[0]));
  }

  if (!af_mode_set_) {
    cros::mojom::AndroidControlAfMode af_mode;
    if (Get3AEntry(result_metadata,
                   cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AF_MODE,
                   &af_mode)) {
      af_mode_set_ = (af_mode == af_mode_);
    } else {
      DVLOG(2) << "AF mode is not available in the metadata";
    }
  }

  if (!Get3AEntry(result_metadata,
                  cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AF_STATE,
                  &af_state_)) {
    DVLOG(2) << "AF state is not available in the metadata";
  }

  if (!ae_mode_set_) {
    cros::mojom::AndroidControlAeMode ae_mode;
    if (Get3AEntry(result_metadata,
                   cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AE_MODE,
                   &ae_mode)) {
      ae_mode_set_ = (ae_mode == ae_mode_);
    } else {
      DVLOG(2) << "AE mode is not available in the metadata";
    }
  }
  if (!Get3AEntry(result_metadata,
                  cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AE_STATE,
                  &ae_state_)) {
    DVLOG(2) << "AE state is not available in the metadata";
  }

  if (!awb_mode_set_) {
    cros::mojom::AndroidControlAwbMode awb_mode;
    if (Get3AEntry(result_metadata,
                   cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AWB_MODE,
                   &awb_mode)) {
      awb_mode_set_ = (awb_mode == awb_mode_);
    } else {
      DVLOG(2) << "AWB mode is not available in the metadata";
    }
  }
  if (!Get3AEntry(result_metadata,
                  cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AWB_STATE,
                  &awb_state_)) {
    DVLOG(2) << "AWB state is not available in the metadata";
  }

  DVLOG(2) << "AF mode: " << af_mode_;
  DVLOG(2) << "AF state: " << af_state_;
  DVLOG(2) << "AE mode: " << ae_mode_;
  DVLOG(2) << "AE state: " << ae_state_;
  DVLOG(2) << "AWB mode: " << awb_mode_;
  DVLOG(2) << "AWB state: " << awb_state_;

  if (on_3a_mode_set_callback_ && af_mode_set_ && ae_mode_set_ &&
      awb_mode_set_) {
    task_runner_->PostTask(FROM_HERE, std::move(on_3a_mode_set_callback_));
  }

  bool should_run_3a_stabilized_callback = [&]() {
    if (!on_3a_stabilized_callback_) {
      return false;
    }
    if (Is3AStabilized()) {
      return true;
    }
    if (latest_sensor_timestamp_ > artificial_3a_stabilized_deadline_) {
      LOG(WARNING)
          << "Timed out stabilizing 3A, fire the callback artificially";
      return true;
    }
    return false;
  }();
  if (should_run_3a_stabilized_callback) {
    std::move(on_3a_stabilized_callback_).Run();
  }

  bool should_run_trigger_cancelled_callback = [&]() {
    if (!on_af_trigger_cancelled_callback_) {
      return false;
    }
    auto af_trigger = GetMetadataEntryAsSpan<uint8_t>(
        result_metadata,
        cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AF_TRIGGER);
    if (af_trigger.empty()) {
      return false;
    }
    return af_trigger[0] ==
           base::checked_cast<uint8_t>(cros::mojom::AndroidControlAfTrigger::
                                           ANDROID_CONTROL_AF_TRIGGER_CANCEL);
  }();
  if (should_run_trigger_cancelled_callback) {
    std::move(on_af_trigger_cancelled_callback_).Run();
  }
}

void Camera3AController::SetAutoFocusModeForStillCapture() {
  DCHECK(task_runner_->BelongsToCurrentThread());

  if (set_point_of_interest_running_ || ae_locked_for_point_of_interest_) {
    return;
  }

  SetCaptureMetadata(
      cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AF_TRIGGER,
      cros::mojom::AndroidControlAfTrigger::ANDROID_CONTROL_AF_TRIGGER_CANCEL);

  if (available_af_modes_.count(
          cros::mojom::AndroidControlAfMode::
              ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE)) {
    af_mode_ = cros::mojom::AndroidControlAfMode::
        ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE;
  }
  Set3AMode(cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AF_MODE,
            base::checked_cast<uint8_t>(af_mode_));
  DVLOG(1) << "Setting AF mode to: " << af_mode_;
}

void Camera3AController::SetAutoFocusModeForVideoRecording() {
  DCHECK(task_runner_->BelongsToCurrentThread());

  if (set_point_of_interest_running_ || ae_locked_for_point_of_interest_) {
    return;
  }

  SetCaptureMetadata(
      cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AF_TRIGGER,
      cros::mojom::AndroidControlAfTrigger::ANDROID_CONTROL_AF_TRIGGER_CANCEL);

  if (available_af_modes_.count(cros::mojom::AndroidControlAfMode::
                                    ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO)) {
    af_mode_ = cros::mojom::AndroidControlAfMode::
        ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO;
  }
  Set3AMode(cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AF_MODE,
            base::checked_cast<uint8_t>(af_mode_));
  DVLOG(1) << "Setting AF mode to: " << af_mode_;
}

void Camera3AController::SetAutoWhiteBalanceMode(
    cros::mojom::AndroidControlAwbMode mode) {
  DCHECK(task_runner_->BelongsToCurrentThread());

  if (!available_awb_modes_.count(mode)) {
    LOG(WARNING) << "Don't support awb mode:" << mode;
    return;
  }

  SetCaptureMetadata(
      cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AWB_LOCK,
      cros::mojom::AndroidControlAwbLock::ANDROID_CONTROL_AWB_LOCK_OFF);
  awb_mode_ = mode;
  Set3AMode(cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AWB_MODE,
            base::checked_cast<uint8_t>(awb_mode_));
  DVLOG(1) << "Setting AWB mode to: " << awb_mode_;
}

void Camera3AController::SetExposureTime(bool enable_auto,
                                         int64_t exposure_time_nanoseconds) {
  DCHECK(task_runner_->BelongsToCurrentThread());

  if (enable_auto) {
    if (!available_ae_modes_.count(
            cros::mojom::AndroidControlAeMode::ANDROID_CONTROL_AE_MODE_ON)) {
      LOG(WARNING) << "Don't support ANDROID_CONTROL_AE_MODE_ON";
      return;
    }
    ae_mode_ = cros::mojom::AndroidControlAeMode::ANDROID_CONTROL_AE_MODE_ON;
    capture_metadata_dispatcher_->UnsetRepeatingCaptureMetadata(
        cros::mojom::CameraMetadataTag::ANDROID_SENSOR_EXPOSURE_TIME);
  } else {
    if (!available_ae_modes_.count(
            cros::mojom::AndroidControlAeMode::ANDROID_CONTROL_AE_MODE_OFF)) {
      LOG(WARNING) << "Don't support ANDROID_CONTROL_AE_MODE_OFF";
      return;
    }
    ae_mode_ = cros::mojom::AndroidControlAeMode::ANDROID_CONTROL_AE_MODE_OFF;
    SetRepeatingCaptureMetadata(
        cros::mojom::CameraMetadataTag::ANDROID_SENSOR_EXPOSURE_TIME,
        exposure_time_nanoseconds);
  }

  Set3AMode(cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AE_MODE,
            base::checked_cast<uint8_t>(ae_mode_));
  DVLOG(1) << "Setting AE mode to: " << ae_mode_;
}

void Camera3AController::SetFocusDistance(bool enable_auto,
                                          float focus_distance_diopters) {
  DCHECK(task_runner_->BelongsToCurrentThread());

  if (enable_auto) {
    if (!available_af_modes_.count(
            cros::mojom::AndroidControlAfMode::ANDROID_CONTROL_AF_MODE_AUTO)) {
      LOG(WARNING) << "Don't support ANDROID_CONTROL_AF_MODE_AUTO";
      return;
    }
    af_mode_ = cros::mojom::AndroidControlAfMode::ANDROID_CONTROL_AF_MODE_AUTO;
    capture_metadata_dispatcher_->UnsetRepeatingCaptureMetadata(
        cros::mojom::CameraMetadataTag::ANDROID_LENS_FOCUS_DISTANCE);
  } else {
    if (!available_af_modes_.count(
            cros::mojom::AndroidControlAfMode::ANDROID_CONTROL_AF_MODE_OFF)) {
      LOG(WARNING) << "Don't support ANDROID_CONTROL_AE_MODE_OFF";
      return;
    }
    af_mode_ = cros::mojom::AndroidControlAfMode::ANDROID_CONTROL_AF_MODE_OFF;
    SetRepeatingCaptureMetadata(
        cros::mojom::CameraMetadataTag::ANDROID_LENS_FOCUS_DISTANCE,
        focus_distance_diopters);
  }

  Set3AMode(cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AF_MODE,
            base::checked_cast<uint8_t>(af_mode_));
  DVLOG(1) << "Setting AF mode to: " << af_mode_;
}

bool Camera3AController::IsPointOfInterestSupported() {
  return point_of_interest_supported_;
}

void Camera3AController::SetPointOfInterest(gfx::Point point) {
  DCHECK(task_runner_->BelongsToCurrentThread());
  DVLOG(1) << "Setting point of interest to " << point.x() << ", " << point.y();

  if (!IsPointOfInterestSupported()) {
    return;
  }

  if (set_point_of_interest_running_ || ae_locked_for_point_of_interest_ ||
      on_af_trigger_cancelled_callback_) {
    // Cancel the current running one.
    // TODO(shik): Technically we can make the still capture hang if we keep
    // clicking the app quickly enough while taking the picture.
    set_point_of_interest_running_ = false;
    on_3a_mode_set_callback_.Reset();
    on_3a_stabilized_callback_.Reset();
    delayed_ae_unlock_callback_.Cancel();
    SetPointOfInterestUnlockAe();
    SetCaptureMetadata(
        cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AF_TRIGGER,
        cros::mojom::AndroidControlAfTrigger::
            ANDROID_CONTROL_AF_TRIGGER_CANCEL);
    // Due to pipeline dalay, we need to wait until AF_TRIGGER_CANCEL fired to
    // prevent the race condition.
    on_af_trigger_cancelled_callback_ = base::BindOnce(
        &Camera3AController::SetPointOfInterest, GetWeakPtr(), point);
    return;
  } else if (on_3a_stabilized_callback_ || on_3a_mode_set_callback_) {
    // Already stabilizing 3A for other things.
    return;
  }

  set_point_of_interest_running_ = true;

  auto active_array_size = [&]() {
    auto rect = GetMetadataEntryAsSpan<int32_t>(
        static_metadata_,
        cros::mojom::CameraMetadataTag::ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE);
    DCHECK(!rect.empty());
    // (xmin, ymin, width, height)
    return gfx::Rect(rect[0], rect[1], rect[2], rect[3]);
  }();

  // Mimic the behavior of regionForNormalizedCoord() in GCA.
  int roi_radius =
      static_cast<int>(0.06125 * std::min(active_array_size.width(),
                                          active_array_size.height()));

  // (xmin, ymin, xmax, ymax, weight)
  std::vector<int32_t> region = {
      base::clamp(point.x() - roi_radius, 0, active_array_size.width() - 1),
      base::clamp(point.y() - roi_radius, 0, active_array_size.height() - 1),
      base::clamp(point.x() + roi_radius, 0, active_array_size.width() - 1),
      base::clamp(point.y() + roi_radius, 0, active_array_size.height() - 1),
      1,
  };

  SetRepeatingCaptureMetadata(
      cros::mojom::CameraMetadataTag::ANDROID_CONTROL_MODE,
      cros::mojom::AndroidControlMode::ANDROID_CONTROL_MODE_AUTO);

  if (ae_region_supported_) {
    SetRepeatingCaptureMetadata(
        cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AE_REGIONS, region);
  }
  if (af_region_supported_) {
    SetRepeatingCaptureMetadata(
        cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AF_REGIONS, region);
  }

  ae_mode_ = cros::mojom::AndroidControlAeMode::ANDROID_CONTROL_AE_MODE_ON;
  ae_mode_set_ = false;
  SetRepeatingCaptureMetadata(
      cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AE_MODE, ae_mode_);
  af_mode_ = cros::mojom::AndroidControlAfMode::ANDROID_CONTROL_AF_MODE_AUTO;
  af_mode_set_ = false;
  SetRepeatingCaptureMetadata(
      cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AF_MODE, af_mode_);
  on_3a_mode_set_callback_ = base::BindOnce(
      &Camera3AController::SetPointOfInterestOn3AModeSet, GetWeakPtr());
}

void Camera3AController::SetPointOfInterestOn3AModeSet() {
  DCHECK(task_runner_->BelongsToCurrentThread());
  Set3aStabilizedCallback(
      base::BindOnce(&Camera3AController::SetPointOfInterestOn3AStabilized,
                     GetWeakPtr()),
      base::Seconds(2));
  SetCaptureMetadata(
      cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AF_TRIGGER,
      cros::mojom::AndroidControlAfTrigger::ANDROID_CONTROL_AF_TRIGGER_START);
}

void Camera3AController::SetPointOfInterestOn3AStabilized() {
  DCHECK(task_runner_->BelongsToCurrentThread());
  set_point_of_interest_running_ = false;
  SetRepeatingCaptureMetadata(
      cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AE_LOCK,
      cros::mojom::AndroidControlAeLock::ANDROID_CONTROL_AE_LOCK_ON);
  ae_locked_for_point_of_interest_ = true;
  if (on_ae_locked_for_point_of_interest_callback_) {
    std::move(on_ae_locked_for_point_of_interest_callback_).Run();
  }
  delayed_ae_unlock_callback_.Reset(base::BindOnce(
      &Camera3AController::SetPointOfInterestUnlockAe, GetWeakPtr()));
  // TODO(shik): Apply different delays for image capture / video recording.
  task_runner_->PostDelayedTask(
      FROM_HERE, delayed_ae_unlock_callback_.callback(), base::Seconds(4));
}

void Camera3AController::SetPointOfInterestUnlockAe() {
  DCHECK(task_runner_->BelongsToCurrentThread());

  ae_locked_for_point_of_interest_ = false;
  ClearRepeatingCaptureMetadata();
}

base::WeakPtr<Camera3AController> Camera3AController::GetWeakPtr() {
  DCHECK(task_runner_->BelongsToCurrentThread());

  return weak_ptr_factory_.GetWeakPtr();
}

void Camera3AController::Set3AMode(cros::mojom::CameraMetadataTag tag,
                                   uint8_t target_mode) {
  DCHECK(task_runner_->BelongsToCurrentThread());
  DCHECK(tag == cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AF_MODE ||
         tag == cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AE_MODE ||
         tag == cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AWB_MODE);

  SetRepeatingCaptureMetadata(tag, target_mode);

  switch (tag) {
    case cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AF_MODE:
      af_mode_set_ = false;
      break;
    case cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AE_MODE:
      ae_mode_set_ = false;
      break;
    case cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AWB_MODE:
      awb_mode_set_ = false;
      break;
    default:
      NOTREACHED() << "Invalid 3A mode: " << tag;
  }
}

void Camera3AController::Set3aStabilizedCallback(base::OnceClosure callback,
                                                 base::TimeDelta time_limit) {
  on_3a_stabilized_callback_ = std::move(callback);
  // TODO(shik): If this function is called before the first capture result
  // metadata is received, |latest_sensor_timestamp_| would be zero.
  artificial_3a_stabilized_deadline_ = latest_sensor_timestamp_ + time_limit;
}

bool Camera3AController::Is3AStabilized() {
  DCHECK(task_runner_->BelongsToCurrentThread());

  if (af_mode_ !=
      cros::mojom::AndroidControlAfMode::ANDROID_CONTROL_AF_MODE_OFF) {
    if (af_state_ != cros::mojom::AndroidControlAfState::
                         ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED &&
        af_state_ != cros::mojom::AndroidControlAfState::
                         ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED) {
      return false;
    }
  }

  if (ae_mode_ !=
      cros::mojom::AndroidControlAeMode::ANDROID_CONTROL_AE_MODE_OFF) {
    if (ae_state_ != cros::mojom::AndroidControlAeState::
                         ANDROID_CONTROL_AE_STATE_CONVERGED &&
        ae_state_ != cros::mojom::AndroidControlAeState::
                         ANDROID_CONTROL_AE_STATE_FLASH_REQUIRED &&
        ae_state_ != cros::mojom::AndroidControlAeState::
                         ANDROID_CONTROL_AE_STATE_LOCKED) {
      return false;
    }
  }

  if (awb_mode_ ==
      cros::mojom::AndroidControlAwbMode::ANDROID_CONTROL_AWB_MODE_AUTO) {
    if (awb_state_ != cros::mojom::AndroidControlAwbState::
                          ANDROID_CONTROL_AWB_STATE_CONVERGED &&
        awb_state_ != cros::mojom::AndroidControlAwbState::
                          ANDROID_CONTROL_AWB_STATE_LOCKED) {
      return false;
    }
  }

  DVLOG(1) << "3A stabilized";
  return true;
}

template <typename T>
void Camera3AController::SetCaptureMetadata(cros::mojom::CameraMetadataTag tag,
                                            T value) {
  SetCaptureMetadata(tag, std::vector<T>{value});
}

template <typename T>
void Camera3AController::SetCaptureMetadata(cros::mojom::CameraMetadataTag tag,
                                            const std::vector<T>& value) {
  capture_metadata_dispatcher_->SetCaptureMetadata(
      tag, entry_type_of<T>::value, value.size(),
      SerializeMetadataValueFromSpan(base::make_span(value)));
}

template <typename T>
void Camera3AController::SetRepeatingCaptureMetadata(
    cros::mojom::CameraMetadataTag tag,
    T value) {
  SetRepeatingCaptureMetadata(tag, std::vector<T>{value});
}

template <typename T>
void Camera3AController::SetRepeatingCaptureMetadata(
    cros::mojom::CameraMetadataTag tag,
    const std::vector<T>& value) {
  repeating_metadata_tags_.insert(tag);
  capture_metadata_dispatcher_->SetRepeatingCaptureMetadata(
      tag, entry_type_of<T>::value, value.size(),
      SerializeMetadataValueFromSpan(base::make_span(value)));
}

void Camera3AController::ClearRepeatingCaptureMetadata() {
  for (const auto& tag : repeating_metadata_tags_) {
    capture_metadata_dispatcher_->UnsetRepeatingCaptureMetadata(tag);
  }
  repeating_metadata_tags_.clear();
}

}  // namespace media
