// 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_device_impl.h"

#include <utility>

#include <sync/sync.h>

#include "camera3_test/camera3_perf_log.h"

namespace camera3_test {

static void ExpectKeyValueGreaterThanI64(const camera_metadata_t* settings,
                                         int32_t key,
                                         const char* key_name,
                                         int64_t value) {
  camera_metadata_ro_entry_t entry;
  ASSERT_EQ(0, find_camera_metadata_ro_entry(settings, key, &entry))
      << "Cannot find the metadata " << key_name;
  ASSERT_GT(entry.data.i64[0], value) << "Wrong value of metadata " << key_name;
}
#define EXPECT_KEY_VALUE_GT_I64(settings, key, value) \
  ExpectKeyValueGreaterThanI64(settings, key, #key, value)

Camera3DeviceImpl::Camera3DeviceImpl(int cam_id)
    : cam_id_(cam_id),
      hal_thread_(GetThreadName(cam_id).c_str()),
      initialized_(false),
      cam_device_(NULL),
      cam_stream_idx_(0),
      gralloc_(Camera3TestGralloc::GetInstance()),
      request_frame_number_(kInitialFrameNumber) {
  thread_checker_.DetachFromThread();
}

int Camera3DeviceImpl::Initialize(Camera3Module* cam_module) {
  VLOGF_ENTER();
  if (!cam_module || !hal_thread_.Start()) {
    return -EINVAL;
  }
  int result = -EIO;
  hal_thread_.PostTaskSync(
      FROM_HERE, base::Bind(&Camera3DeviceImpl::InitializeOnThread,
                            base::Unretained(this), cam_module, &result));
  return result;
}

void Camera3DeviceImpl::Destroy() {
  VLOGF_ENTER();
  int result = -EIO;
  hal_thread_.PostTaskSync(FROM_HERE,
                           base::Bind(&Camera3DeviceImpl::DestroyOnThread,
                                      base::Unretained(this), &result));
  EXPECT_EQ(0, result) << "Camera device close failed";
  hal_thread_.Stop();
}

void Camera3DeviceImpl::RegisterProcessCaptureResultCallback(
    Camera3Device::ProcessCaptureResultCallback cb) {
  hal_thread_.PostTaskSync(
      FROM_HERE,
      base::Bind(
          &Camera3DeviceImpl::RegisterProcessCaptureResultCallbackOnThread,
          base::Unretained(this), cb));
}

void Camera3DeviceImpl::RegisterNotifyCallback(
    Camera3Device::NotifyCallback cb) {
  hal_thread_.PostTaskSync(
      FROM_HERE, base::Bind(&Camera3DeviceImpl::RegisterNotifyCallbackOnThread,
                            base::Unretained(this), cb));
}

void Camera3DeviceImpl::RegisterResultMetadataOutputBufferCallback(
    Camera3Device::ProcessResultMetadataOutputBuffersCallback cb) {
  hal_thread_.PostTaskSync(
      FROM_HERE,
      base::Bind(&Camera3DeviceImpl::
                     RegisterResultMetadataOutputBufferCallbackOnThread,
                 base::Unretained(this), cb));
}

void Camera3DeviceImpl::RegisterPartialMetadataCallback(
    Camera3Device::ProcessPartialMetadataCallback cb) {
  hal_thread_.PostTaskSync(
      FROM_HERE,
      base::Bind(&Camera3DeviceImpl::RegisterPartialMetadataCallbackOnThread,
                 base::Unretained(this), cb));
}

bool Camera3DeviceImpl::IsTemplateSupported(int32_t type) {
  bool result = false;
  hal_thread_.PostTaskSync(
      FROM_HERE, base::Bind(&Camera3DeviceImpl::IsTemplateSupportedOnThread,
                            base::Unretained(this), type, &result));
  return result;
}

const camera_metadata_t* Camera3DeviceImpl::ConstructDefaultRequestSettings(
    int type) {
  const camera_metadata_t* metadata = nullptr;
  hal_thread_.PostTaskSync(
      FROM_HERE,
      base::Bind(&Camera3DeviceImpl::ConstructDefaultRequestSettingsOnThread,
                 base::Unretained(this), type, &metadata));
  return metadata;
}

void Camera3DeviceImpl::AddStream(int format,
                                  int width,
                                  int height,
                                  int crop_rotate_scale_degrees,
                                  camera3_stream_type_t type) {
  VLOGF_ENTER();
  hal_thread_.PostTaskSync(
      FROM_HERE,
      base::Bind(&Camera3DeviceImpl::AddStreamOnThread, base::Unretained(this),
                 format, width, height, crop_rotate_scale_degrees, type));
}

int Camera3DeviceImpl::ConfigureStreams(
    std::vector<const camera3_stream_t*>* streams) {
  VLOGF_ENTER();
  int32_t result = -EIO;
  hal_thread_.PostTaskSync(
      FROM_HERE, base::Bind(&Camera3DeviceImpl::ConfigureStreamsOnThread,
                            base::Unretained(this), streams, &result));
  return result;
}

int Camera3DeviceImpl::AllocateOutputStreamBuffers(
    std::vector<camera3_stream_buffer_t>* output_buffers) {
  VLOGF_ENTER();
  int32_t result = -EIO;
  hal_thread_.PostTaskSync(
      FROM_HERE,
      base::Bind(&Camera3DeviceImpl::AllocateOutputStreamBuffersOnThread,
                 base::Unretained(this), output_buffers, &result));
  return result;
}

int Camera3DeviceImpl::AllocateOutputBuffersByStreams(
    const std::vector<const camera3_stream_t*>& streams,
    std::vector<camera3_stream_buffer_t>* output_buffers) {
  VLOGF_ENTER();
  int32_t result = -EIO;
  hal_thread_.PostTaskSync(
      FROM_HERE,
      base::Bind(&Camera3DeviceImpl::AllocateOutputBuffersByStreamsOnThread,
                 base::Unretained(this), &streams, output_buffers, &result));
  return result;
}

int Camera3DeviceImpl::RegisterOutputBuffer(
    const camera3_stream_t& stream, BufferHandleUniquePtr unique_buffer) {
  VLOGF_ENTER();
  int32_t result = -EIO;
  hal_thread_.PostTaskSync(
      FROM_HERE, base::Bind(&Camera3DeviceImpl::RegisterOutputBufferOnThread,
                            base::Unretained(this), &stream,
                            base::Passed(&unique_buffer), &result));
  return result;
}

int Camera3DeviceImpl::ProcessCaptureRequest(
    camera3_capture_request_t* capture_request) {
  VLOGF_ENTER();
  int32_t result = -EIO;
  hal_thread_.PostTaskSync(
      FROM_HERE, base::Bind(&Camera3DeviceImpl::ProcessCaptureRequestOnThread,
                            base::Unretained(this), capture_request, &result));
  return result;
}

int Camera3DeviceImpl::WaitShutter(const struct timespec& timeout) {
  if (!initialized_) {
    return -ENODEV;
  }
  if (!process_capture_result_cb_.is_null()) {
    LOG(ERROR) << "Test has registered its own process_capture_result callback "
                  "function and thus must provide its own "
               << __func__;
    return -EINVAL;
  }
  return sem_timedwait(&shutter_sem_, &timeout);
}

int Camera3DeviceImpl::WaitCaptureResult(const struct timespec& timeout) {
  if (!initialized_) {
    return -ENODEV;
  }
  if (!process_capture_result_cb_.is_null()) {
    LOG(ERROR) << "Test has registered its own process_capture_result callback "
                  "function and thus must provide its own "
               << __func__;
    return -EINVAL;
  }
  return sem_timedwait(&capture_result_sem_, &timeout);
}

int Camera3DeviceImpl::Flush() {
  DCHECK(cam_device_);
  VLOGF_ENTER();
  return cam_device_->ops->flush(cam_device_);
}

void Camera3DeviceImpl::InitializeOnThread(Camera3Module* cam_module,
                                           int* result) {
  DCHECK(thread_checker_.CalledOnValidThread());
  if (initialized_) {
    LOG(ERROR) << "Device " << cam_id_ << " is already initialized";
    *result = -EINVAL;
    return;
  }
  // Open camera device
  Camera3PerfLog::GetInstance()->Update(
      cam_id_, Camera3PerfLog::Key::DEVICE_OPENING, base::TimeTicks::Now());
  *result = -ENODEV;
  cam_device_ = cam_module->OpenDevice(cam_id_);
  ASSERT_NE(nullptr, cam_device_) << "Failed to open device " << cam_id_;

  *result = -EINVAL;
  ASSERT_GE(((const hw_device_t*)cam_device_)->version,
            (uint16_t)HARDWARE_MODULE_API_VERSION(3, 3))
      << "The device must support at least HALv3.3";

  ASSERT_NE(nullptr, gralloc_) << "Gralloc initialization fails";

  camera_info cam_info;
  ASSERT_EQ(0, cam_module->GetCameraInfo(cam_id_, &cam_info));
  static_info_.reset(new Camera3Device::StaticInfo(cam_info));
  ASSERT_TRUE(static_info_->IsHardwareLevelAtLeastLimited())
      << "The device must support at least LIMITED hardware level";

  // Initialize camera device
  Camera3DeviceImpl::notify = Camera3DeviceImpl::NotifyForwarder;
  Camera3DeviceImpl::process_capture_result =
      Camera3DeviceImpl::ProcessCaptureResultForwarder;
  *result = cam_device_->ops->initialize(cam_device_, this);
  ASSERT_EQ(0, *result) << "Camera device initialization fails";
  Camera3PerfLog::GetInstance()->Update(
      cam_id_, Camera3PerfLog::Key::DEVICE_OPENED, base::TimeTicks::Now());

  sem_init(&shutter_sem_, 0, 0);
  sem_init(&capture_result_sem_, 0, 0);
  initialized_ = true;
}

void Camera3DeviceImpl::RegisterProcessCaptureResultCallbackOnThread(
    Camera3Device::ProcessCaptureResultCallback cb) {
  DCHECK(thread_checker_.CalledOnValidThread());
  process_capture_result_cb_ = cb;
}

void Camera3DeviceImpl::RegisterNotifyCallbackOnThread(
    Camera3Device::NotifyCallback cb) {
  DCHECK(thread_checker_.CalledOnValidThread());
  notify_cb_ = cb;
}

void Camera3DeviceImpl::RegisterResultMetadataOutputBufferCallbackOnThread(
    Camera3Device::ProcessResultMetadataOutputBuffersCallback cb) {
  DCHECK(thread_checker_.CalledOnValidThread());
  process_result_metadata_output_buffers_cb_ = cb;
}

void Camera3DeviceImpl::RegisterPartialMetadataCallbackOnThread(
    Camera3Device::ProcessPartialMetadataCallback cb) {
  DCHECK(thread_checker_.CalledOnValidThread());
  process_partial_metadata_cb_ = cb;
}

void Camera3DeviceImpl::IsTemplateSupportedOnThread(int32_t type,
                                                    bool* result) {
  if (initialized_) {
    *result =
        (type != CAMERA3_TEMPLATE_MANUAL ||
         static_info_->IsCapabilitySupported(
             ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) &&
        (type != CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG ||
         static_info_->IsCapabilitySupported(
             ANDROID_REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING));
  }
}

void Camera3DeviceImpl::ConstructDefaultRequestSettingsOnThread(
    int type, const camera_metadata_t** result) {
  DCHECK(thread_checker_.CalledOnValidThread());
  if (initialized_) {
    *result =
        cam_device_->ops->construct_default_request_settings(cam_device_, type);
  }
}

void Camera3DeviceImpl::AddStreamOnThread(int format,
                                          int width,
                                          int height,
                                          int crop_rotate_scale_degrees,
                                          camera3_stream_type_t type) {
  DCHECK(thread_checker_.CalledOnValidThread());
  if (initialized_) {
    auto& cur_stream = cam_stream_[!cam_stream_idx_];
    // Push to the bin that is not used currently
    camera3_stream_t stream = {};
    stream.stream_type = type;
    stream.width = width;
    stream.height = height;
    stream.format = format;
    stream.crop_rotate_scale_degrees = crop_rotate_scale_degrees;
    cur_stream.push_back(stream);
  }
}

void Camera3DeviceImpl::ConfigureStreamsOnThread(
    std::vector<const camera3_stream_t*>* streams, int* result) {
  DCHECK(thread_checker_.CalledOnValidThread());
  *result = -EINVAL;
  if (!initialized_) {
    *result = -ENODEV;
    return;
  }

  // Check whether there are streams
  if (cam_stream_[!cam_stream_idx_].size() == 0) {
    return;
  }

  // Prepare stream configuration
  std::vector<camera3_stream_t*> cam_streams;
  camera3_stream_configuration_t cam_stream_config = {};
  for (size_t i = 0; i < cam_stream_[!cam_stream_idx_].size(); i++) {
    cam_streams.push_back(&cam_stream_[!cam_stream_idx_][i]);
  }
  cam_stream_config.num_streams = cam_streams.size();
  cam_stream_config.streams = cam_streams.data();
  cam_stream_config.operation_mode = CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE;

  // Configure streams now
  *result =
      cam_device_->ops->configure_streams(cam_device_, &cam_stream_config);
  if (*result == 0) {
    for (const auto& it : cam_stream_[!cam_stream_idx_]) {
      if (it.max_buffers == 0) {
        LOGF(ERROR) << "Max number of buffers equal to zero is invalid";
        *result = -EINVAL;
        return;
      }
    }
  }

  // Swap to the other bin
  cam_stream_[cam_stream_idx_].clear();
  cam_stream_idx_ = !cam_stream_idx_;

  if (*result == 0 && streams) {
    streams->clear();
    for (auto const& it : cam_stream_[cam_stream_idx_]) {
      streams->push_back(&it);
    }
  }
}

void Camera3DeviceImpl::AllocateOutputStreamBuffersOnThread(
    std::vector<camera3_stream_buffer_t>* output_buffers, int32_t* result) {
  DCHECK(thread_checker_.CalledOnValidThread());
  std::vector<const camera3_stream_t*> streams;
  for (const auto& it : cam_stream_[cam_stream_idx_]) {
    if (it.stream_type == CAMERA3_STREAM_OUTPUT ||
        it.stream_type == CAMERA3_STREAM_BIDIRECTIONAL) {
      streams.push_back(&it);
    }
  }
  AllocateOutputBuffersByStreamsOnThread(&streams, output_buffers, result);
}

void Camera3DeviceImpl::AllocateOutputBuffersByStreamsOnThread(
    const std::vector<const camera3_stream_t*>* streams,
    std::vector<camera3_stream_buffer_t>* output_buffers,
    int32_t* result) {
  DCHECK(thread_checker_.CalledOnValidThread());
  *result = -EINVAL;
  if (!initialized_) {
    *result = -ENODEV;
    return;
  }

  if (!output_buffers || streams->empty()) {
    return;
  }
  int32_t jpeg_max_size = 0;
  if (std::find_if(streams->begin(), streams->end(),
                   [](const camera3_stream_t* stream) {
                     return stream->format == HAL_PIXEL_FORMAT_BLOB;
                   }) != streams->end()) {
    jpeg_max_size = static_info_->GetJpegMaxSize();
    if (jpeg_max_size <= 0) {
      return;
    }
  }

  for (const auto& it : *streams) {
    BufferHandleUniquePtr buffer = gralloc_->Allocate(
        (it->format == HAL_PIXEL_FORMAT_BLOB) ? jpeg_max_size : it->width,
        (it->format == HAL_PIXEL_FORMAT_BLOB) ? 1 : it->height, it->format,
        GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_HW_CAMERA_WRITE);
    if (!buffer) {
      LOG(ERROR) << "Gralloc allocation fails";
      *result = -ENOMEM;
      return;
    }

    camera3_stream_buffer_t stream_buffer;
    camera3_stream_t* stream = const_cast<camera3_stream_t*>(it);

    stream_buffer = {.stream = stream,
                     .buffer = buffer.get(),
                     .status = CAMERA3_BUFFER_STATUS_OK,
                     .acquire_fence = -1,
                     .release_fence = -1};
    stream_buffer_map_[stream].push_back(std::move(buffer));
    output_buffers->push_back(stream_buffer);
  }
  *result = 0;
}

void Camera3DeviceImpl::RegisterOutputBufferOnThread(
    const camera3_stream_t* stream,
    BufferHandleUniquePtr unique_buffer,
    int32_t* result) {
  DCHECK(thread_checker_.CalledOnValidThread());
  VLOGF_ENTER();
  if (!initialized_) {
    *result = -ENODEV;
    return;
  }
  if (!unique_buffer) {
    *result = -EINVAL;
    return;
  }
  stream_buffer_map_[stream].emplace_back(std::move(unique_buffer));
  *result = 0;
}

void Camera3DeviceImpl::ProcessCaptureRequestOnThread(
    camera3_capture_request_t* request, int* result) {
  DCHECK(thread_checker_.CalledOnValidThread());
  VLOGF_ENTER();
  if (!initialized_) {
    *result = -ENODEV;
    return;
  }
  if (request) {
    capture_request_map_[request_frame_number_] = *request;
    capture_request_map_[request_frame_number_].frame_number =
        request_frame_number_;
    for (uint32_t i = 0; i < request->num_output_buffers; i++) {
      stream_output_buffer_map_[request->output_buffers[i].stream].push_back(
          *request->output_buffers[i].buffer);
    }
  }
  *result = cam_device_->ops->process_capture_request(
      cam_device_,
      request ? &capture_request_map_[request_frame_number_] : request);
  if (*result == 0) {
    request->frame_number = request_frame_number_;
    request_frame_number_++;
  }
}

Camera3DeviceImpl::StreamBuffer::StreamBuffer(
    const camera3_stream_buffer_t& stream_buffer)
    : camera3_stream_buffer_t(stream_buffer) {
  buffer_handle = *stream_buffer.buffer;
}

Camera3DeviceImpl::CaptureResult::CaptureResult(
    const camera3_capture_result_t& result)
    : camera3_capture_result_t(result) {
  if (result.result) {
    metadata_result.reset(clone_camera_metadata(result.result));
  }
  for (uint32_t i = 0; i < result.num_output_buffers; i++) {
    stream_buffers.emplace_back(result.output_buffers[i]);
  }
}

void Camera3DeviceImpl::ProcessCaptureResultOnThread(
    std::unique_ptr<CaptureResult> result) {
  VLOGF_ENTER();
  DCHECK(thread_checker_.CalledOnValidThread());
  ASSERT_NE(nullptr, result) << "Capture result is null";
  // At least one of metadata or output buffers or input buffer should be
  // returned
  ASSERT_TRUE((result->metadata_result != nullptr) ||
              (result->num_output_buffers != 0) ||
              (result->input_buffer != NULL))
      << "No result data provided by HAL for frame " << result->frame_number;
  if (result->num_output_buffers) {
    ASSERT_NE(nullptr, result->output_buffers)
        << "No output buffer is returned while " << result->num_output_buffers
        << " are expected";
  }
  ASSERT_NE(capture_request_map_.end(),
            capture_request_map_.find(result->frame_number))
      << "A result is received for nonexistent request (frame number "
      << result->frame_number << ")";

  // For HAL3.2 or above, If HAL doesn't support partial, it must always set
  // partial_result to 1 when metadata is included in this result.
  ASSERT_TRUE(UsePartialResult() || !result->metadata_result ||
              result->partial_result == 1)
      << "Result is malformed: partial_result must be 1 if partial result is "
         "not supported";
  // If partial_result > 0, there should be metadata returned in this result;
  // otherwise, there should be none.
  ASSERT_TRUE((result->partial_result > 0) ==
              (result->metadata_result != nullptr));

  if (result->metadata_result) {
    ProcessPartialResult(result.get());
  }

  for (const auto& stream_buffer : result->stream_buffers) {
    ASSERT_NE(nullptr, stream_buffer.buffer)
        << "Capture result output buffer is null";
    // An error may be expected while flushing
    EXPECT_EQ(CAMERA3_BUFFER_STATUS_OK, stream_buffer.status)
        << "Capture result buffer status error";
    ASSERT_EQ(-1, stream_buffer.acquire_fence)
        << "Capture result buffer fence error";

    // Check buffers for a given streams are returned in order
    ASSERT_FALSE(stream_output_buffer_map_[stream_buffer.stream].empty());
    ASSERT_EQ(stream_output_buffer_map_[stream_buffer.stream].front(),
              stream_buffer.buffer_handle)
        << "Buffers of the same stream are delivered out of order";
    stream_output_buffer_map_[stream_buffer.stream].pop_front();
    if (stream_buffer.release_fence != -1) {
      ASSERT_EQ(0, sync_wait(stream_buffer.release_fence, 1000))
          << "Error waiting on buffer acquire fence";
      close(stream_buffer.release_fence);
    }
  }
  capture_result_info_map_[result->frame_number].output_buffers_.insert(
      capture_result_info_map_[result->frame_number].output_buffers_.end(),
      result->stream_buffers.begin(), result->stream_buffers.end());

  capture_result_info_map_[result->frame_number].num_output_buffers_ +=
      result->num_output_buffers;
  ASSERT_LE(capture_result_info_map_[result->frame_number].num_output_buffers_,
            capture_request_map_[result->frame_number].num_output_buffers);
  if (capture_result_info_map_[result->frame_number].num_output_buffers_ ==
          capture_request_map_[result->frame_number].num_output_buffers &&
      capture_result_info_map_[result->frame_number].have_result_metadata_) {
    ASSERT_EQ(completed_request_set_.end(),
              completed_request_set_.find(result->frame_number))
        << "Multiple results are received for the same request";
    completed_request_set_.insert(result->frame_number);

    // Process all received metadata and output buffers
    std::vector<BufferHandleUniquePtr> unique_buffers;
    if (GetOutputStreamBufferHandles(
            capture_result_info_map_[result->frame_number].output_buffers_,
            &unique_buffers)) {
      ADD_FAILURE() << "Failed to get output buffers";
    }
    CameraMetadataUniquePtr final_metadata(
        capture_result_info_map_[result->frame_number].MergePartialMetadata());
    EXPECT_KEY_VALUE_GT_I64(final_metadata.get(), ANDROID_SENSOR_TIMESTAMP, 0);
    if (!process_result_metadata_output_buffers_cb_.is_null()) {
      process_result_metadata_output_buffers_cb_.Run(result->frame_number,
                                                     std::move(final_metadata),
                                                     std::move(unique_buffers));
    }
    std::vector<CameraMetadataUniquePtr> partial_metadata;
    partial_metadata.swap(
        capture_result_info_map_[result->frame_number].partial_metadata_);
    if (!process_partial_metadata_cb_.is_null()) {
      process_partial_metadata_cb_.Run(&partial_metadata);
    }

    capture_request_map_.erase(result->frame_number);
    capture_result_info_map_.erase(result->frame_number);

    // Everything looks fine. Post it now.
    sem_post(&capture_result_sem_);
  }
}

void Camera3DeviceImpl::NotifyOnThread(camera3_notify_msg_t msg) {
  DCHECK(thread_checker_.CalledOnValidThread());
  EXPECT_EQ(CAMERA3_MSG_SHUTTER, msg.type)
      << "Shutter error = " << msg.message.error.error_code;

  if (msg.type == CAMERA3_MSG_SHUTTER) {
    sem_post(&shutter_sem_);
  }
}

void Camera3DeviceImpl::DestroyOnThread(int* result) {
  DCHECK(thread_checker_.CalledOnValidThread());
  *result = -EINVAL;
  if (!initialized_) {
    *result = -ENODEV;
    return;
  }
  ASSERT_NE(nullptr, cam_device_->common.close)
      << "Camera close() is not implemented";
  *result = cam_device_->common.close(&cam_device_->common);

  sem_destroy(&shutter_sem_);
  sem_destroy(&capture_result_sem_);
  initialized_ = false;
}

const Camera3Device::StaticInfo* Camera3DeviceImpl::GetStaticInfo() const {
  return static_info_.get();
}

void Camera3DeviceImpl::ProcessCaptureResultForwarder(
    const camera3_callback_ops* cb, const camera3_capture_result_t* result) {
  // Forward to callback of instance
  Camera3DeviceImpl* d =
      const_cast<Camera3DeviceImpl*>(static_cast<const Camera3DeviceImpl*>(cb));
  d->ProcessCaptureResult(result);
}

void Camera3DeviceImpl::NotifyForwarder(const camera3_callback_ops* cb,
                                        const camera3_notify_msg_t* msg) {
  // Forward to callback of instance
  Camera3DeviceImpl* d =
      const_cast<Camera3DeviceImpl*>(static_cast<const Camera3DeviceImpl*>(cb));
  d->Notify(msg);
}

void Camera3DeviceImpl::ProcessCaptureResult(
    const camera3_capture_result_t* result) {
  VLOGF_ENTER();
  if (!process_capture_result_cb_.is_null()) {
    process_capture_result_cb_.Run(result);
    return;
  }
  std::unique_ptr<CaptureResult> unique_result(new CaptureResult(*result));
  hal_thread_.PostTaskAsync(
      FROM_HERE,
      base::Bind(&Camera3DeviceImpl::ProcessCaptureResultOnThread,
                 base::Unretained(this), base::Passed(&unique_result)));
}

void Camera3DeviceImpl::Notify(const camera3_notify_msg_t* msg) {
  VLOGF_ENTER();
  if (!notify_cb_.is_null()) {
    notify_cb_.Run(msg);
    return;
  }
  hal_thread_.PostTaskAsync(FROM_HERE,
                            base::Bind(&Camera3DeviceImpl::NotifyOnThread,
                                       base::Unretained(this), *msg));
}

int Camera3DeviceImpl::GetOutputStreamBufferHandles(
    const std::vector<StreamBuffer>& output_buffers,
    std::vector<BufferHandleUniquePtr>* unique_buffers) {
  DCHECK(thread_checker_.CalledOnValidThread());
  VLOGF_ENTER();

  for (const auto& output_buffer : output_buffers) {
    if (!output_buffer.buffer ||
        stream_buffer_map_.find(output_buffer.stream) ==
            stream_buffer_map_.end()) {
      LOG(ERROR) << "Failed to find configured stream or buffer is invalid";
      return -EINVAL;
    }

    auto stream_buffers = &stream_buffer_map_[output_buffer.stream];
    auto it = std::find_if(stream_buffers->begin(), stream_buffers->end(),
                           [=](const BufferHandleUniquePtr& buffer) {
                             return *buffer == output_buffer.buffer_handle;
                           });
    if (it != stream_buffers->end()) {
      unique_buffers->push_back(std::move(*it));
      stream_buffers->erase(it);
    } else {
      LOG(ERROR) << "Failed to find output buffer";
      return -EINVAL;
    }
  }
  return 0;
}

bool Camera3DeviceImpl::UsePartialResult() const {
  DCHECK(thread_checker_.CalledOnValidThread());
  return static_info_->GetPartialResultCount() > 1;
}

void Camera3DeviceImpl::ProcessPartialResult(CaptureResult* result) {
  DCHECK(thread_checker_.CalledOnValidThread());
  // True if this partial result is the final one. If HAL does not use partial
  // result, the value is True by default.
  bool is_final_partial_result = !UsePartialResult();
  // Check if this result carries only partial metadata
  if (UsePartialResult() && result->metadata_result != nullptr) {
    EXPECT_LE(result->partial_result, static_info_->GetPartialResultCount());
    EXPECT_GE(result->partial_result, 1);
    is_final_partial_result =
        (result->partial_result == static_info_->GetPartialResultCount());
  }

  // Did we get the (final) result metadata for this capture?
  if (result->metadata_result != nullptr && is_final_partial_result) {
    EXPECT_FALSE(
        capture_result_info_map_[result->frame_number].have_result_metadata_)
        << "Called multiple times with final metadata";
    capture_result_info_map_[result->frame_number].have_result_metadata_ = true;
  }

  capture_result_info_map_[result->frame_number].partial_metadata_.push_back(
      std::move(result->metadata_result));
}

Camera3DeviceImpl::CaptureResultInfo::CaptureResultInfo()
    : num_output_buffers_(0), have_result_metadata_(false) {
  thread_checker_.DetachFromThread();
}

bool Camera3DeviceImpl::CaptureResultInfo::IsMetadataKeyAvailable(
    int32_t key) const {
  DCHECK(thread_checker_.CalledOnValidThread());
  return GetMetadataKeyEntry(key, nullptr);
}

int32_t Camera3DeviceImpl::CaptureResultInfo::GetMetadataKeyValue(
    int32_t key) const {
  DCHECK(thread_checker_.CalledOnValidThread());
  camera_metadata_ro_entry_t entry;
  return GetMetadataKeyEntry(key, &entry) ? entry.data.i32[0] : -EINVAL;
}

int64_t Camera3DeviceImpl::CaptureResultInfo::GetMetadataKeyValue64(
    int32_t key) const {
  DCHECK(thread_checker_.CalledOnValidThread());
  camera_metadata_ro_entry_t entry;
  return GetMetadataKeyEntry(key, &entry) ? entry.data.i64[0] : -EINVAL;
}

CameraMetadataUniquePtr
Camera3DeviceImpl::CaptureResultInfo::MergePartialMetadata() {
  DCHECK(thread_checker_.CalledOnValidThread());
  size_t entry_count = 0;
  size_t data_count = 0;
  for (const auto& it : partial_metadata_) {
    entry_count += get_camera_metadata_entry_count(it.get());
    data_count += get_camera_metadata_data_count(it.get());
  }
  camera_metadata_t* metadata =
      allocate_camera_metadata(entry_count, data_count);
  if (!metadata) {
    ADD_FAILURE() << "Can't allocate larger metadata buffer";
    return nullptr;
  }
  for (const auto& it : partial_metadata_) {
    append_camera_metadata(metadata, it.get());
  }
  return CameraMetadataUniquePtr(metadata);
}

bool Camera3DeviceImpl::CaptureResultInfo::GetMetadataKeyEntry(
    int32_t key, camera_metadata_ro_entry_t* entry) const {
  DCHECK(thread_checker_.CalledOnValidThread());
  camera_metadata_ro_entry_t local_entry;
  entry = entry ? entry : &local_entry;
  for (const auto& it : partial_metadata_) {
    if (find_camera_metadata_ro_entry(it.get(), key, entry) == 0) {
      return true;
    }
  }
  return false;
}

const std::string Camera3DeviceImpl::GetThreadName(int cam_id) {
  const size_t kThreadNameLength = 30;
  char thread_name[kThreadNameLength];
  snprintf(thread_name, kThreadNameLength, "Camera3 Test Device %d Thread",
           cam_id);
  return std::string(thread_name);
}

}  // namespace camera3_test
