// Copyright 2017 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 "camera3_test/camera3_service.h"

#include <unistd.h>

#include <algorithm>
#include <string>
#include <utility>
#include <vector>

#include <base/bind.h>
#include <base/check.h>
#include <base/command_line.h>
#include <base/strings/string_number_conversions.h>

#include "camera3_test/camera3_perf_log.h"
#include "cros-camera/common.h"

namespace camera3_test {

namespace {

constexpr int kWaitForStopPreviewTimeoutMs = 3000;
constexpr int kWaitForStopRecordingTimeoutMs = 3000;

double Get3ATimeoutMultiplier() {
  static double multiplier = [] {
    constexpr char kSwitch[] = "3a_timeout_multiplier";
    const auto* cl = base::CommandLine::ForCurrentProcess();
    std::string val = cl->GetSwitchValueASCII(kSwitch);
    double out;
    if (val.empty() || !base::StringToDouble(val, &out)) {
      return 1.0;
    }
    return out;
  }();
  return multiplier;
}

int GetWaitForFocusDoneTimeoutMs() {
  return static_cast<int>(6000 * Get3ATimeoutMultiplier());
}

int GetWaitForAWBConvergedTimeoutMs() {
  return static_cast<int>(3000 * Get3ATimeoutMultiplier());
}

}  // namespace

Camera3Service::~Camera3Service() {}

int Camera3Service::Initialize(
    ProcessStillCaptureResultCallback still_capture_cb,
    ProcessRecordingResultCallback recording_cb,
    ProcessPreviewResultCallback preview_cb) {
  base::AutoLock l(lock_);
  if (initialized_) {
    LOGF(ERROR) << "Camera service is already initialized";
    return -EINVAL;
  }
  for (const auto& it : cam_ids_) {
    cam_dev_service_map_[it].reset(new Camera3Service::Camera3DeviceService(
        it, still_capture_cb, recording_cb, preview_cb));
    int result = cam_dev_service_map_[it]->Initialize();
    if (result != 0) {
      LOGF(ERROR) << "Camera device " << it << " service initialization fails";
      cam_dev_service_map_.clear();
      return result;
    }
  }
  initialized_ = true;
  return 0;
}

void Camera3Service::Destroy() {
  base::AutoLock l(lock_);
  if (!initialized_) {
    return;
  }
  for (auto& it : cam_dev_service_map_) {
    it.second->Destroy();
  }
  cam_dev_service_map_.clear();
  initialized_ = false;
}

int Camera3Service::StartPreview(int cam_id,
                                 const ResolutionInfo& preview_resolution,
                                 const ResolutionInfo& still_capture_resolution,
                                 const ResolutionInfo& recording_resolution) {
  base::AutoLock l(lock_);
  if (!initialized_ ||
      cam_dev_service_map_.find(cam_id) == cam_dev_service_map_.end()) {
    return -ENODEV;
  }
  return cam_dev_service_map_[cam_id]->StartPreview(
      preview_resolution, still_capture_resolution, recording_resolution);
}

void Camera3Service::StopPreview(int cam_id) {
  base::AutoLock l(lock_);
  if (initialized_ &&
      cam_dev_service_map_.find(cam_id) != cam_dev_service_map_.end()) {
    cam_dev_service_map_[cam_id]->StopPreview();
  }
}

void Camera3Service::StartAutoFocus(int cam_id) {
  base::AutoLock l(lock_);
  if (initialized_ &&
      cam_dev_service_map_.find(cam_id) != cam_dev_service_map_.end()) {
    cam_dev_service_map_[cam_id]->StartAutoFocus();
  }
}

int Camera3Service::WaitForAutoFocusDone(int cam_id) {
  base::AutoLock l(lock_);
  if (!initialized_ ||
      cam_dev_service_map_.find(cam_id) == cam_dev_service_map_.end()) {
    return -ENODEV;
  }
  return cam_dev_service_map_[cam_id]->WaitForAutoFocusDone();
}

int Camera3Service::WaitForAWBConvergedAndLock(int cam_id) {
  base::AutoLock l(lock_);
  if (!initialized_ ||
      cam_dev_service_map_.find(cam_id) == cam_dev_service_map_.end()) {
    return -ENODEV;
  }
  return cam_dev_service_map_[cam_id]->WaitForAWBConvergedAndLock();
}

void Camera3Service::StartAEPrecapture(int cam_id) {
  base::AutoLock l(lock_);
  if (initialized_ &&
      cam_dev_service_map_.find(cam_id) != cam_dev_service_map_.end()) {
    cam_dev_service_map_[cam_id]->StartAEPrecapture();
  }
}

int Camera3Service::WaitForAEStable(int cam_id) {
  base::AutoLock l(lock_);
  if (!initialized_ ||
      cam_dev_service_map_.find(cam_id) == cam_dev_service_map_.end()) {
    return -ENODEV;
  }
  return cam_dev_service_map_[cam_id]->WaitForAEStable();
}

void Camera3Service::StartFaceDetection(int cam_id) {
  base::AutoLock l(lock_);
  if (initialized_ &&
      cam_dev_service_map_.find(cam_id) != cam_dev_service_map_.end()) {
    cam_dev_service_map_[cam_id]->StartFaceDetection();
  }
}

void Camera3Service::StopFaceDetection(int cam_id) {
  base::AutoLock l(lock_);
  if (initialized_ &&
      cam_dev_service_map_.find(cam_id) != cam_dev_service_map_.end()) {
    cam_dev_service_map_[cam_id]->StopFaceDetection();
  }
}

void Camera3Service::TakeStillCapture(int cam_id,
                                      const camera_metadata_t* metadata) {
  base::AutoLock l(lock_);
  if (initialized_ &&
      cam_dev_service_map_.find(cam_id) != cam_dev_service_map_.end()) {
    cam_dev_service_map_[cam_id]->TakeStillCapture(metadata);
  }
}

int Camera3Service::StartRecording(int cam_id,
                                   const camera_metadata_t* metadata) {
  base::AutoLock l(lock_);
  if (!initialized_ ||
      cam_dev_service_map_.find(cam_id) == cam_dev_service_map_.end()) {
    return -ENODEV;
  }
  return cam_dev_service_map_[cam_id]->StartRecording(metadata);
}

void Camera3Service::StopRecording(int cam_id) {
  base::AutoLock l(lock_);
  if (initialized_ &&
      cam_dev_service_map_.find(cam_id) != cam_dev_service_map_.end()) {
    cam_dev_service_map_[cam_id]->StopRecording();
  }
}

int Camera3Service::WaitForPreviewFrames(int cam_id,
                                         uint32_t num_frames,
                                         uint32_t timeout_ms) {
  base::AutoLock l(lock_);
  if (!initialized_ ||
      cam_dev_service_map_.find(cam_id) == cam_dev_service_map_.end()) {
    return -ENODEV;
  }
  return cam_dev_service_map_[cam_id]->WaitForPreviewFrames(num_frames,
                                                            timeout_ms);
}

const Camera3Device::StaticInfo* Camera3Service::GetStaticInfo(int cam_id) {
  base::AutoLock l(lock_);
  if (initialized_ &&
      cam_dev_service_map_.find(cam_id) != cam_dev_service_map_.end()) {
    return cam_dev_service_map_[cam_id]->GetStaticInfo();
  }
  return nullptr;
}

const camera_metadata_t* Camera3Service::ConstructDefaultRequestSettings(
    int cam_id, int type) {
  base::AutoLock l(lock_);
  if (initialized_ &&
      cam_dev_service_map_.find(cam_id) != cam_dev_service_map_.end()) {
    return cam_dev_service_map_[cam_id]->ConstructDefaultRequestSettings(type);
  }
  return nullptr;
}

int Camera3Service::Camera3DeviceService::Initialize() {
  Camera3Module cam_module;
  if (cam_device_.Initialize(&cam_module) != 0) {
    LOGF(ERROR) << "Camera device initialization fails";
    return -ENODEV;
  }
  if (!service_thread_.Start()) {
    LOGF(ERROR) << "Failed to start thread";
    return -EINVAL;
  }
  cam_device_.RegisterResultMetadataOutputBufferCallback(base::Bind(
      &Camera3Service::Camera3DeviceService::ProcessResultMetadataOutputBuffers,
      base::Unretained(this)));
  repeating_preview_metadata_.reset(clone_camera_metadata(
      cam_device_.ConstructDefaultRequestSettings(CAMERA3_TEMPLATE_PREVIEW)));
  if (!repeating_preview_metadata_) {
    LOGF(ERROR) << "Failed to create preview metadata";
    return -ENOMEM;
  }
  sem_init(&preview_frame_sem_, 0, 0);
  return 0;
}

void Camera3Service::Camera3DeviceService::Destroy() {
  service_thread_.Stop();
  sem_destroy(&preview_frame_sem_);
  cam_device_.Destroy();
}

int Camera3Service::Camera3DeviceService::StartPreview(
    const ResolutionInfo& preview_resolution,
    const ResolutionInfo& still_capture_resolution,
    const ResolutionInfo& recording_resolution) {
  VLOGF_ENTER();
  int result = -EIO;
  service_thread_.PostTaskSync(
      FROM_HERE,
      base::Bind(
          &Camera3Service::Camera3DeviceService::StartPreviewOnServiceThread,
          base::Unretained(this), preview_resolution, still_capture_resolution,
          recording_resolution, &result));
  return result;
}

void Camera3Service::Camera3DeviceService::StopPreview() {
  VLOGF_ENTER();
  auto future = cros::Future<void>::Create(nullptr);
  service_thread_.PostTaskAsync(
      FROM_HERE,
      base::Bind(
          &Camera3Service::Camera3DeviceService::StopPreviewOnServiceThread,
          base::Unretained(this), cros::GetFutureCallback(future)));
  if (!future->Wait(kWaitForStopPreviewTimeoutMs)) {
    LOGF(ERROR) << "Timeout stopping preview";
  }
}

void Camera3Service::Camera3DeviceService::StartAutoFocus() {
  service_thread_.PostTaskAsync(
      FROM_HERE,
      base::Bind(
          &Camera3Service::Camera3DeviceService::StartAutoFocusOnServiceThread,
          base::Unretained(this)));
}

int Camera3Service::Camera3DeviceService::WaitForAutoFocusDone() {
  VLOGF_ENTER();
  auto future = cros::Future<void>::Create(nullptr);
  int32_t result;
  service_thread_.PostTaskAsync(
      FROM_HERE, base::Bind(&Camera3Service::Camera3DeviceService::
                                AddMetadataListenerOnServiceThread,
                            base::Unretained(this), ANDROID_CONTROL_AF_STATE,
                            std::unordered_set<int32_t>(
                                {ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED,
                                 ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED}),
                            cros::GetFutureCallback(future), &result));
  if (!future->Wait(GetWaitForFocusDoneTimeoutMs())) {
    service_thread_.PostTaskSync(
        FROM_HERE,
        base::Bind(&Camera3Service::Camera3DeviceService::
                       DeleteMetadataListenerOnServiceThread,
                   base::Unretained(this), ANDROID_CONTROL_AF_STATE,
                   std::unordered_set<int32_t>(
                       {ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED,
                        ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED})));
    return -ETIMEDOUT;
  }
  if (result == ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED) {
    VLOGF(1) << "Auto-focus did not lock";
  }
  return 0;
}

int Camera3Service::Camera3DeviceService::WaitForAWBConvergedAndLock() {
  VLOGF_ENTER();
  auto future = cros::Future<void>::Create(nullptr);
  service_thread_.PostTaskAsync(
      FROM_HERE, base::Bind(&Camera3Service::Camera3DeviceService::
                                AddMetadataListenerOnServiceThread,
                            base::Unretained(this), ANDROID_CONTROL_AWB_STATE,
                            std::unordered_set<int32_t>(
                                {ANDROID_CONTROL_AWB_STATE_CONVERGED}),
                            cros::GetFutureCallback(future), nullptr));
  if (!future->Wait(GetWaitForAWBConvergedTimeoutMs())) {
    service_thread_.PostTaskSync(
        FROM_HERE, base::Bind(&Camera3Service::Camera3DeviceService::
                                  DeleteMetadataListenerOnServiceThread,
                              base::Unretained(this), ANDROID_CONTROL_AWB_STATE,
                              std::unordered_set<int32_t>(
                                  {ANDROID_CONTROL_AWB_STATE_CONVERGED})));
    return -ETIMEDOUT;
  }

  if (cam_device_.GetStaticInfo()->IsAWBLockSupported()) {
    service_thread_.PostTaskAsync(
        FROM_HERE,
        base::Bind(
            &Camera3Service::Camera3DeviceService::LockAWBOnServiceThread,
            base::Unretained(this)));
  }
  return 0;
}

void Camera3Service::Camera3DeviceService::StartAEPrecapture() {
  VLOGF_ENTER();
  service_thread_.PostTaskAsync(
      FROM_HERE, base::Bind(&Camera3Service::Camera3DeviceService::
                                StartAEPrecaptureOnServiceThread,
                            base::Unretained(this)));
}

int Camera3Service::Camera3DeviceService::WaitForAEStable() {
  VLOGF_ENTER();
  auto future = cros::Future<void>::Create(nullptr);
  int32_t result;
  service_thread_.PostTaskAsync(
      FROM_HERE, base::Bind(&Camera3Service::Camera3DeviceService::
                                AddMetadataListenerOnServiceThread,
                            base::Unretained(this), ANDROID_CONTROL_AE_STATE,
                            std::unordered_set<int32_t>(
                                {ANDROID_CONTROL_AE_STATE_CONVERGED,
                                 ANDROID_CONTROL_AE_STATE_FLASH_REQUIRED}),
                            cros::GetFutureCallback(future), &result));
  if (!future->Wait(GetWaitForFocusDoneTimeoutMs())) {
    service_thread_.PostTaskSync(
        FROM_HERE, base::Bind(&Camera3Service::Camera3DeviceService::
                                  DeleteMetadataListenerOnServiceThread,
                              base::Unretained(this), ANDROID_CONTROL_AE_STATE,
                              std::unordered_set<int32_t>(
                                  {ANDROID_CONTROL_AE_STATE_CONVERGED,
                                   ANDROID_CONTROL_AE_STATE_FLASH_REQUIRED})));
    return -ETIMEDOUT;
  }
  if (result == ANDROID_CONTROL_AE_STATE_FLASH_REQUIRED) {
    VLOGF(1) << "Flash needs to be fired for good quality still capture";
  }
  return 0;
}

void Camera3Service::Camera3DeviceService::StartFaceDetection() {
  VLOGF_ENTER();
  service_thread_.PostTaskAsync(
      FROM_HERE, base::BindRepeating(&Camera3Service::Camera3DeviceService::
                                         StartFaceDetectionOnServiceThread,
                                     base::Unretained(this)));
}

void Camera3Service::Camera3DeviceService::StopFaceDetection() {
  VLOGF_ENTER();
  service_thread_.PostTaskAsync(
      FROM_HERE, base::BindRepeating(&Camera3Service::Camera3DeviceService::
                                         StopFaceDetectionOnServiceThread,
                                     base::Unretained(this)));
}

void Camera3Service::Camera3DeviceService::TakeStillCapture(
    const camera_metadata_t* metadata) {
  VLOGF_ENTER();
  auto future = cros::Future<void>::Create(nullptr);
  service_thread_.PostTaskAsync(
      FROM_HERE, base::Bind(&Camera3Service::Camera3DeviceService::
                                TakeStillCaptureOnServiceThread,
                            base::Unretained(this), metadata,
                            cros::GetFutureCallback(future)));
  // Wait for ProcessPreviewRequestOnServiceThread() to finish processing
  // |metadata|
  future->Wait();
}

int Camera3Service::Camera3DeviceService::StartRecording(
    const camera_metadata_t* metadata) {
  VLOGF_ENTER();
  auto future = cros::Future<int>::Create(nullptr);
  service_thread_.PostTaskSync(
      FROM_HERE,
      base::Bind(
          &Camera3Service::Camera3DeviceService::StartRecordingOnServiceThread,
          base::Unretained(this), metadata, cros::GetFutureCallback(future)));
  return future->Wait();
}

void Camera3Service::Camera3DeviceService::StopRecording() {
  VLOGF_ENTER();
  auto future = cros::Future<void>::Create(nullptr);
  service_thread_.PostTaskAsync(
      FROM_HERE,
      base::Bind(
          &Camera3Service::Camera3DeviceService::StopRecordingOnServiceThread,
          base::Unretained(this), cros::GetFutureCallback(future)));
  if (!future->Wait(kWaitForStopRecordingTimeoutMs)) {
    LOGF(ERROR) << "Timeout stopping preview";
  }
}

int Camera3Service::Camera3DeviceService::WaitForPreviewFrames(
    uint32_t num_frames, uint32_t timeout_ms) {
  VLOGF_ENTER();
  while (sem_trywait(&preview_frame_sem_) == 0) {
  }
  for (uint32_t i = 0; i < num_frames; ++i) {
    struct timespec timeout = {};
    if (clock_gettime(CLOCK_REALTIME, &timeout)) {
      LOGF(ERROR) << "Failed to get clock time";
      return -errno;
    }
    timeout.tv_sec += timeout_ms / 1000;
    timeout.tv_nsec += (timeout_ms % 1000) * 1000;
    if (sem_timedwait(&preview_frame_sem_, &timeout) != 0) {
      return -errno;
    }
  }
  return 0;
}

const Camera3Device::StaticInfo*
Camera3Service::Camera3DeviceService::GetStaticInfo() const {
  return cam_device_.GetStaticInfo();
}

const camera_metadata_t*
Camera3Service::Camera3DeviceService::ConstructDefaultRequestSettings(
    int type) {
  return cam_device_.ConstructDefaultRequestSettings(type);
}

void Camera3Service::Camera3DeviceService::ProcessResultMetadataOutputBuffers(
    uint32_t frame_number,
    ScopedCameraMetadata metadata,
    std::vector<cros::ScopedBufferHandle> buffers) {
  VLOGF_ENTER();
  service_thread_.PostTaskAsync(
      FROM_HERE,
      base::Bind(&Camera3Service::Camera3DeviceService::
                     ProcessResultMetadataOutputBuffersOnServiceThread,
                 base::Unretained(this), frame_number, base::Passed(&metadata),
                 base::Passed(&buffers)));
}

void Camera3Service::Camera3DeviceService::StartPreviewOnServiceThread(
    const ResolutionInfo preview_resolution,
    const ResolutionInfo still_capture_resolution,
    const ResolutionInfo recording_resolution,
    int* result) {
  DCHECK(service_thread_.IsCurrentThread());
  VLOGF_ENTER();
  if (preview_state_ != PREVIEW_STOPPED) {
    LOGF(ERROR) << "Failed to start preview because it is not stopped";
    *result = -EAGAIN;
    return;
  }

  if (still_capture_resolution.Area()) {
    cam_device_.AddOutputStream(
        HAL_PIXEL_FORMAT_BLOB, still_capture_resolution.Width(),
        still_capture_resolution.Height(), CAMERA3_STREAM_ROTATION_0);
  }
  if (recording_resolution.Area()) {
    cam_device_.AddOutputStream(
        HAL_PIXEL_FORMAT_YCbCr_420_888, recording_resolution.Width(),
        recording_resolution.Height(), CAMERA3_STREAM_ROTATION_0);
  }
  cam_device_.AddOutputStream(
      HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, preview_resolution.Width(),
      preview_resolution.Height(), CAMERA3_STREAM_ROTATION_0);
  if (cam_device_.ConfigureStreams(&streams_) != 0) {
    ADD_FAILURE() << "Configuring stream fails";
    *result = -EINVAL;
    return;
  }
  auto GetStream = [this](int format) {
    auto it = std::find_if(streams_.begin(), streams_.end(),
                           [&](const camera3_stream_t* stream) {
                             return (stream->format == format);
                           });
    return (it == streams_.end()) ? nullptr : *it;
  };
  const camera3_stream_t* preview_stream =
      GetStream(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED);
  const camera3_stream_t* record_stream =
      GetStream(HAL_PIXEL_FORMAT_YCbCr_420_888);
  if (!preview_stream || (recording_resolution.Area() && !record_stream)) {
    ADD_FAILURE() << "Failed to find configured stream";
    *result = -EINVAL;
    return;
  }

  number_of_capture_requests_ = preview_stream->max_buffers;
  if (recording_resolution.Area()) {
    number_of_capture_requests_ =
        std::min(number_of_capture_requests_, record_stream->max_buffers);
  }
  capture_requests_.resize(number_of_capture_requests_);
  output_stream_buffers_ = std::vector<std::vector<camera3_stream_buffer_t>>(
      number_of_capture_requests_,
      std::vector<camera3_stream_buffer_t>(kNumberOfOutputStreamBuffers));
  // Submit initial preview capture requests to fill the HAL pipeline first.
  // Then when a result callback is processed, the corresponding capture
  // request (and output buffer) is recycled and submitted again.
  for (uint32_t i = 0; i < number_of_capture_requests_; i++) {
    std::vector<const camera3_stream_t*> streams(1, preview_stream);
    std::vector<camera3_stream_buffer_t> output_buffers;
    if (cam_device_.AllocateOutputBuffersByStreams(streams, &output_buffers) !=
        0) {
      ADD_FAILURE() << "Failed to allocate output buffer";
      *result = -EINVAL;
      return;
    }
    output_stream_buffers_[i][kPreviewOutputStreamIdx] = output_buffers.front();
    capture_requests_[i] = std::make_pair(
        camera3_capture_request_t{
            .frame_number =
                UINT32_MAX,  // Will be overwritten with correct value
            .settings = repeating_preview_metadata_.get(),
            .input_buffer = NULL,
            .num_output_buffers = 1,
            .output_buffers = output_stream_buffers_[i].data(),
            .num_physcam_settings = 0},
        false);
    ProcessPreviewRequestOnServiceThread();
  }
  preview_state_ = PREVIEW_STARTING;
  *result = 0;
}

void Camera3Service::Camera3DeviceService::StopPreviewOnServiceThread(
    base::Callback<void()> cb) {
  DCHECK(service_thread_.IsCurrentThread());
  VLOGF_ENTER();
  if (preview_state_ != PREVIEW_STARTED && preview_state_ != PREVIEW_STARTING) {
    return;
  }
  preview_state_ = PREVIEW_STOPPING;
  stop_preview_cb_ = cb;
}

void Camera3Service::Camera3DeviceService::StartAutoFocusOnServiceThread() {
  DCHECK(service_thread_.IsCurrentThread());
  uint8_t af_mode = ANDROID_CONTROL_AF_MODE_AUTO;
  EXPECT_EQ(0, UpdateMetadata(ANDROID_CONTROL_AF_MODE, &af_mode, 1,
                              &repeating_preview_metadata_));
  if (!oneshot_preview_metadata_.get()) {
    oneshot_preview_metadata_.reset(
        clone_camera_metadata(repeating_preview_metadata_.get()));
  }
  uint8_t af_trigger = ANDROID_CONTROL_AF_TRIGGER_START;
  EXPECT_EQ(0, UpdateMetadata(ANDROID_CONTROL_AF_TRIGGER, &af_trigger, 1,
                              &oneshot_preview_metadata_));
}

void Camera3Service::Camera3DeviceService::AddMetadataListenerOnServiceThread(
    int32_t key,
    std::unordered_set<int32_t> values,
    base::Callback<void()> cb,
    int32_t* result) {
  DCHECK(service_thread_.IsCurrentThread());
  metadata_listener_list_.emplace_back(key, values, cb, result);
}

void Camera3Service::Camera3DeviceService::
    DeleteMetadataListenerOnServiceThread(int32_t key,
                                          std::unordered_set<int32_t> values) {
  DCHECK(service_thread_.IsCurrentThread());
  for (auto it = metadata_listener_list_.begin();
       it != metadata_listener_list_.end(); it++) {
    if (it->key == key && it->values == values) {
      it = metadata_listener_list_.erase(it);
      break;
    }
  }
}

void Camera3Service::Camera3DeviceService::LockAWBOnServiceThread() {
  DCHECK(service_thread_.IsCurrentThread());
  uint8_t awb_lock = ANDROID_CONTROL_AWB_LOCK_ON;
  EXPECT_EQ(0, UpdateMetadata(ANDROID_CONTROL_AWB_LOCK, &awb_lock, 1,
                              &repeating_preview_metadata_));
}

void Camera3Service::Camera3DeviceService::StartAEPrecaptureOnServiceThread() {
  DCHECK(service_thread_.IsCurrentThread());
  if (!oneshot_preview_metadata_.get()) {
    oneshot_preview_metadata_.reset(
        clone_camera_metadata(repeating_preview_metadata_.get()));
  }
  uint8_t ae_trigger = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_START;
  EXPECT_EQ(0, UpdateMetadata(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
                              &ae_trigger, 1, &oneshot_preview_metadata_));
}

void Camera3Service::Camera3DeviceService::StartFaceDetectionOnServiceThread() {
  DCHECK(service_thread_.IsCurrentThread());
  uint8_t fd_mode = ANDROID_STATISTICS_FACE_DETECT_MODE_SIMPLE;
  EXPECT_EQ(0, UpdateMetadata(ANDROID_STATISTICS_FACE_DETECT_MODE, &fd_mode, 1,
                              &repeating_preview_metadata_));
}

void Camera3Service::Camera3DeviceService::StopFaceDetectionOnServiceThread() {
  DCHECK(service_thread_.IsCurrentThread());
  uint8_t fd_mode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
  EXPECT_EQ(0, UpdateMetadata(ANDROID_STATISTICS_FACE_DETECT_MODE, &fd_mode, 1,
                              &repeating_preview_metadata_));
}

void Camera3Service::Camera3DeviceService::TakeStillCaptureOnServiceThread(
    const camera_metadata_t* metadata, base::Callback<void()> cb) {
  DCHECK(service_thread_.IsCurrentThread());
  still_capture_metadata_ = metadata;
  still_capture_cb_ = cb;
}

void Camera3Service::Camera3DeviceService::StartRecordingOnServiceThread(
    const camera_metadata_t* metadata, base::Callback<void(int)> cb) {
  DCHECK(service_thread_.IsCurrentThread());
  VLOGF_ENTER();
  if (!metadata) {
    LOGF(ERROR) << "Invalid metadata settings";
    cb.Run(-EINVAL);
    return;
  }
  if (preview_state_ != PREVIEW_STARTED) {
    VLOGF(2) << "Preview is not started yet. Retrying...";
    usleep(500);
    service_thread_.PostTaskAsync(
        FROM_HERE, base::Bind(&Camera3Service::Camera3DeviceService::
                                  StartRecordingOnServiceThread,
                              base::Unretained(this), metadata, cb));
    return;
  }
  auto it = std::find_if(
      streams_.begin(), streams_.end(), [](const camera3_stream_t* stream) {
        return (stream->format == HAL_PIXEL_FORMAT_YCbCr_420_888);
      });
  if (it == streams_.end()) {
    ADD_FAILURE() << "Failed to find configured recording stream";
    cb.Run(-EINVAL);
    return;
  }
  const camera3_stream_t* record_stream = *it;

  for (uint32_t i = 0; i < number_of_capture_requests_; i++) {
    std::vector<const camera3_stream_t*> streams(1, record_stream);
    std::vector<camera3_stream_buffer_t> output_buffers;
    if (cam_device_.AllocateOutputBuffersByStreams(streams, &output_buffers) !=
        0) {
      ADD_FAILURE() << "Failed to allocate output buffer";
      cb.Run(-EINVAL);
      return;
    }
    output_stream_buffers_[i][kRecordingOutputStreamIdx] =
        output_buffers.front();
  }
  recording_metadata_ = metadata;
  cb.Run(0);
}

void Camera3Service::Camera3DeviceService::StopRecordingOnServiceThread(
    base::Callback<void()> cb) {
  VLOGF_ENTER();
  recording_metadata_ = nullptr;
  stop_recording_cb_ = cb;
}

void Camera3Service::Camera3DeviceService::
    ProcessPreviewRequestOnServiceThread() {
  DCHECK(service_thread_.IsCurrentThread());
  size_t capture_request_idx = 0;
  for (; capture_request_idx < capture_requests_.size();
       capture_request_idx++) {
    if (!capture_requests_[capture_request_idx].second) {
      break;
    }
  }
  ASSERT_NE(capture_request_idx, capture_requests_.size())
      << "Out of captures requests";
  capture_requests_[capture_request_idx].second = true;
  camera3_capture_request_t* request =
      &capture_requests_[capture_request_idx].first;
  // Initially there is preview stream only
  request->num_output_buffers = 1;
  if (recording_metadata_) {
    request->settings = recording_metadata_;
    ++request->num_output_buffers;
  }
  if (still_capture_metadata_) {
    auto it = std::find_if(streams_.begin(), streams_.end(),
                           [](const camera3_stream_t* stream) {
                             return (stream->format == HAL_PIXEL_FORMAT_BLOB);
                           });
    ASSERT_NE(streams_.end(), it)
        << "Failed to find configured still capture stream";
    const camera3_stream_t* still_capture_stream = *it;
    std::vector<const camera3_stream_t*> streams(1, still_capture_stream);
    std::vector<camera3_stream_buffer_t> output_buffers;
    ASSERT_EQ(
        0, cam_device_.AllocateOutputBuffersByStreams(streams, &output_buffers))
        << "Failed to allocate output buffer";
    request->settings = still_capture_metadata_;
    output_stream_buffers_[capture_request_idx][request->num_output_buffers] =
        output_buffers.front();
    ++request->num_output_buffers;
  }
  if (!recording_metadata_ && !still_capture_metadata_) {
    // Request with one-shot metadata if there is one
    request->settings = oneshot_preview_metadata_.get()
                            ? oneshot_preview_metadata_.get()
                            : repeating_preview_metadata_.get();
  }
  ASSERT_EQ(0, cam_device_.ProcessCaptureRequest(request))
      << "Failed to process capture request";
  ++number_of_in_flight_requests_;
  VLOGF(1) << "Capture request";
  VLOGF(1) << "  Frame " << request->frame_number;
  VLOGF(1) << "  Index " << capture_request_idx;
  for (size_t i = 0; i < request->num_output_buffers; i++) {
    VLOGF(1) << "  Buffer " << *request->output_buffers[i].buffer
             << " (format:" << request->output_buffers[i].stream->format << ","
             << request->output_buffers[i].stream->width << "x"
             << request->output_buffers[i].stream->height << ")";
  }
  VLOGF(1) << "  Settings " << request->settings;
  if (still_capture_metadata_) {
    still_capture_metadata_ = nullptr;
    still_capture_cb_.Run();
  } else if (!recording_metadata_ && !still_capture_metadata_ &&
             oneshot_preview_metadata_.get()) {
    oneshot_preview_metadata_.reset(nullptr);
  }
}

void Camera3Service::Camera3DeviceService::
    ProcessResultMetadataOutputBuffersOnServiceThread(
        uint32_t frame_number,
        ScopedCameraMetadata metadata,
        std::vector<cros::ScopedBufferHandle> buffers) {
  DCHECK(service_thread_.IsCurrentThread());
  --number_of_in_flight_requests_;
  size_t capture_request_idx = 0;
  for (; capture_request_idx < capture_requests_.size();
       capture_request_idx++) {
    if (capture_requests_[capture_request_idx].first.frame_number ==
        frame_number) {
      break;
    }
  }
  ASSERT_NE(capture_request_idx, capture_requests_.size())
      << "Failed to find frame " << frame_number << " in the requests";
  VLOGF(1) << "Capture result";
  VLOGF(1) << "  Frame " << frame_number;
  VLOGF(1) << "  Index " << capture_request_idx;
  // Process result metadata according to listeners
  for (auto it = metadata_listener_list_.begin();
       it != metadata_listener_list_.end();) {
    camera_metadata_ro_entry_t entry;
    if (find_camera_metadata_ro_entry(metadata.get(), it->key, &entry) == 0 &&
        it->values.find(entry.data.i32[0]) != it->values.end()) {
      VLOGF(1) << "Metadata listener gets tag "
               << get_camera_metadata_tag_name(it->key) << " value "
               << entry.data.i32[0];
      if (it->result) {
        *it->result = entry.data.i32[0];
      }
      it->cb.Run();
      it = metadata_listener_list_.erase(it);
    } else {
      it++;
    }
  }
  // Process output buffers and record perf logs. We record preview and video
  // perf logs only if there's no still capture in this result since it is
  // expected to take longer time.
  const bool has_still_capture = std::any_of(
      buffers.begin(), buffers.end(),
      [](const cros::ScopedBufferHandle& buffer) {
        return Camera3TestGralloc::GetFormat(*buffer) == HAL_PIXEL_FORMAT_BLOB;
      });
  const bool stopping_preview =
      (preview_state_ == PREVIEW_STOPPING) && !still_capture_metadata_;
  bool have_yuv_buffer = false;
  for (auto& it : buffers) {
    VLOGF(1) << "  Buffer " << *it
             << " (format:" << Camera3TestGralloc::GetFormat(*it) << ")";
    switch (Camera3TestGralloc::GetFormat(*it)) {
      case HAL_PIXEL_FORMAT_BLOB:
        Camera3PerfLog::GetInstance()->UpdateFrameEvent(
            cam_id_, frame_number, FrameEvent::STILL_CAPTURE_RESULT,
            base::TimeTicks::Now());
        if (!process_still_capture_result_cb_.is_null()) {
          process_still_capture_result_cb_.Run(
              cam_id_, frame_number, std::move(metadata), std::move(it));
        }
        break;
      case HAL_PIXEL_FORMAT_YCbCr_420_888:
        have_yuv_buffer = true;
        if (!has_still_capture) {
          Camera3PerfLog::GetInstance()->UpdateFrameEvent(
              cam_id_, frame_number, FrameEvent::VIDEO_RECORD_RESULT,
              base::TimeTicks::Now());
        }
        if (!process_recording_result_cb_.is_null()) {
          process_recording_result_cb_.Run(cam_id_, frame_number,
                                           std::move(metadata));
        }
        if (recording_metadata_ && !stopping_preview) {
          // Register buffer back to be used by future requests
          cam_device_.RegisterOutputBuffer(
              *output_stream_buffers_[capture_request_idx]
                                     [kRecordingOutputStreamIdx]
                                         .stream,
              std::move(it));
        }
        break;
      default:
        if (!process_preview_result_cb_.is_null()) {
          process_preview_result_cb_.Run(cam_id_, frame_number,
                                         std::move(metadata));
        }
        if (!has_still_capture) {
          Camera3PerfLog::GetInstance()->UpdateFrameEvent(
              cam_id_, frame_number, FrameEvent::PREVIEW_RESULT,
              base::TimeTicks::Now());
        }
        if (!stopping_preview) {
          // Register buffer back to be used by future requests
          cam_device_.RegisterOutputBuffer(
              *output_stream_buffers_[capture_request_idx]
                                     [kPreviewOutputStreamIdx]
                                         .stream,
              std::move(it));
        }
    }
  }
  if (preview_state_ == PREVIEW_STARTING) {
    preview_state_ = PREVIEW_STARTED;
    Camera3PerfLog::GetInstance()->UpdateDeviceEvent(
        cam_id_, DeviceEvent::PREVIEW_STARTED, base::TimeTicks::Now());
  }
  sem_post(&preview_frame_sem_);

  if (!stop_recording_cb_.is_null() && !have_yuv_buffer) {
    stop_recording_cb_.Run();
    stop_recording_cb_.Reset();
  }
  if (stopping_preview) {
    VLOGF(1) << "Stopping preview ... (" << number_of_in_flight_requests_
             << " requests in flight";
    if (number_of_in_flight_requests_ == 0) {
      preview_state_ = PREVIEW_STOPPED;
      stop_preview_cb_.Run();
      stop_preview_cb_.Reset();
    }
    return;
  }
  capture_requests_[capture_request_idx].second = false;
  ProcessPreviewRequestOnServiceThread();
}

}  // namespace camera3_test
