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

#include "camera3_test/camera3_device_impl.h"

namespace camera3_test {

Camera3Device::Camera3Device(int cam_id)
    : impl_(new Camera3DeviceImpl(cam_id)) {}

Camera3Device::~Camera3Device() {}

int Camera3Device::Initialize(Camera3Module* cam_module) {
  DCHECK(impl_);
  return impl_->Initialize(cam_module);
}

void Camera3Device::Destroy() {
  DCHECK(impl_);
  impl_->Destroy();
}

void Camera3Device::RegisterProcessCaptureResultCallback(
    Camera3Device::ProcessCaptureResultCallback cb) {
  DCHECK(impl_);
  impl_->RegisterProcessCaptureResultCallback(cb);
}

void Camera3Device::RegisterNotifyCallback(Camera3Device::NotifyCallback cb) {
  DCHECK(impl_);
  impl_->RegisterNotifyCallback(cb);
}

void Camera3Device::RegisterResultMetadataOutputBufferCallback(
    Camera3Device::ProcessResultMetadataOutputBuffersCallback cb) {
  DCHECK(impl_);
  impl_->RegisterResultMetadataOutputBufferCallback(cb);
}

void Camera3Device::RegisterPartialMetadataCallback(
    Camera3Device::ProcessPartialMetadataCallback cb) {
  DCHECK(impl_);
  impl_->RegisterPartialMetadataCallback(cb);
}

bool Camera3Device::IsTemplateSupported(int32_t type) {
  DCHECK(impl_);
  return impl_->IsTemplateSupported(type);
}

const camera_metadata_t* Camera3Device::ConstructDefaultRequestSettings(
    int type) {
  DCHECK(impl_);
  return impl_->ConstructDefaultRequestSettings(type);
}

void Camera3Device::AddOutputStream(
    int format,
    int width,
    int height,
    camera3_stream_rotation_t crop_rotate_scale_degrees) {
  DCHECK(impl_);
  impl_->AddStream(format, width, height,
                   static_cast<int>(crop_rotate_scale_degrees),
                   CAMERA3_STREAM_OUTPUT);
}

void Camera3Device::AddInputStream(int format, int width, int height) {
  DCHECK(impl_);
  impl_->AddStream(format, width, height, 0, CAMERA3_STREAM_INPUT);
}

void Camera3Device::AddBidirectionalStream(int format, int width, int height) {
  DCHECK(impl_);
  impl_->AddStream(format, width, height, 0, CAMERA3_STREAM_BIDIRECTIONAL);
}

void Camera3Device::AddOutputStreamWithRawDegrees(
    int format, int width, int height, int crop_rotate_scale_degrees) {
  DCHECK(impl_);
  impl_->AddStream(format, width, height, crop_rotate_scale_degrees,
                   CAMERA3_STREAM_OUTPUT);
}

int Camera3Device::ConfigureStreams(
    std::vector<const camera3_stream_t*>* streams) {
  DCHECK(impl_);
  return impl_->ConfigureStreams(streams);
}

int Camera3Device::AllocateOutputStreamBuffers(
    std::vector<camera3_stream_buffer_t>* output_buffers) {
  DCHECK(impl_);
  return impl_->AllocateOutputStreamBuffers(output_buffers);
}

int Camera3Device::AllocateOutputBuffersByStreams(
    const std::vector<const camera3_stream_t*>& streams,
    std::vector<camera3_stream_buffer_t>* output_buffers) {
  DCHECK(impl_);
  return impl_->AllocateOutputBuffersByStreams(streams, output_buffers);
}

int Camera3Device::RegisterOutputBuffer(const camera3_stream_t& stream,
                                        ScopedBufferHandle unique_buffer) {
  DCHECK(impl_);
  return impl_->RegisterOutputBuffer(stream, std::move(unique_buffer));
}

int Camera3Device::ProcessCaptureRequest(
    camera3_capture_request_t* capture_request) {
  DCHECK(impl_);
  return impl_->ProcessCaptureRequest(capture_request);
}

int Camera3Device::WaitShutter(const struct timespec& timeout) {
  DCHECK(impl_);
  return impl_->WaitShutter(timeout);
}

int Camera3Device::WaitCaptureResult(const struct timespec& timeout) {
  DCHECK(impl_);
  return impl_->WaitCaptureResult(timeout);
}

int Camera3Device::Flush() {
  DCHECK(impl_);
  return impl_->Flush();
}

const Camera3Device::StaticInfo* Camera3Device::GetStaticInfo() const {
  DCHECK(impl_);
  return impl_->GetStaticInfo();
}

Camera3Device::StaticInfo::StaticInfo(const camera_info& cam_info)
    : characteristics_(const_cast<camera_metadata_t*>(
          cam_info.static_camera_characteristics)) {}

bool Camera3Device::StaticInfo::IsKeyAvailable(uint32_t tag) const {
  return AreKeysAvailable(std::vector<uint32_t>(1, tag));
}

bool Camera3Device::StaticInfo::AreKeysAvailable(
    std::vector<uint32_t> tags) const {
  for (const auto& tag : tags) {
    camera_metadata_ro_entry_t entry;
    if (find_camera_metadata_ro_entry(characteristics_, tag, &entry)) {
      return false;
    }
  }
  return true;
}

uint8_t Camera3Device::StaticInfo::GetHardwareLevel() const {
  camera_metadata_ro_entry_t entry;
  if (find_camera_metadata_ro_entry(characteristics_,
                                    ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
                                    &entry) != 0) {
    ADD_FAILURE()
        << "Cannot find the metadata ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL";
    return -EINVAL;
  }
  return entry.data.u8[0];
}

bool Camera3Device::StaticInfo::IsHardwareLevelAtLeast(uint8_t level) const {
  return isHardwareLevelSupported(GetHardwareLevel(), level);
}

bool Camera3Device::StaticInfo::IsHardwareLevelAtLeastFull() const {
  return IsHardwareLevelAtLeast(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_FULL);
}

bool Camera3Device::StaticInfo::IsHardwareLevelAtLeastExternal() const {
  return IsHardwareLevelAtLeast(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL);
}

bool Camera3Device::StaticInfo::IsCapabilitySupported(
    uint8_t capability) const {
  EXPECT_GE(capability, 0) << "Capability must be non-negative";

  camera_metadata_ro_entry_t entry;
  if (find_camera_metadata_ro_entry(characteristics_,
                                    ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
                                    &entry) == 0) {
    return std::find(entry.data.u8, entry.data.u8 + entry.count, capability) !=
           entry.data.u8 + entry.count;
  }
  return false;
}

bool Camera3Device::StaticInfo::IsDepthOutputSupported() const {
  return IsCapabilitySupported(
      ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT);
}

bool Camera3Device::StaticInfo::IsColorOutputSupported() const {
  return IsCapabilitySupported(
      ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE);
}

std::set<uint8_t> Camera3Device::StaticInfo::GetAvailableModes(
    int32_t key, int32_t min_value, int32_t max_value) const {
  camera_metadata_ro_entry_t entry;
  if (find_camera_metadata_ro_entry(characteristics_, key, &entry) != 0) {
    ADD_FAILURE() << "Cannot find the metadata "
                  << get_camera_metadata_tag_name(key);
    return std::set<uint8_t>();
  }
  std::set<uint8_t> modes;
  for (size_t i = 0; i < entry.count; i++) {
    uint8_t mode = entry.data.u8[i];
    // Each element must be distinct
    EXPECT_TRUE(modes.find(mode) == modes.end())
        << "Duplicate modes " << mode << " for the metadata "
        << get_camera_metadata_tag_name(key);
    EXPECT_TRUE(mode >= min_value && mode <= max_value)
        << "Mode " << mode << " is outside of [" << min_value << ","
        << max_value << "] for the metadata "
        << get_camera_metadata_tag_name(key);
    modes.insert(mode);
  }
  return modes;
}

std::set<uint8_t> Camera3Device::StaticInfo::GetAvailableEdgeModes() const {
  std::set<uint8_t> modes = GetAvailableModes(
      ANDROID_EDGE_AVAILABLE_EDGE_MODES, ANDROID_EDGE_MODE_OFF,
      ANDROID_EDGE_MODE_ZERO_SHUTTER_LAG);

  // Full device should always include OFF and FAST
  if (IsHardwareLevelAtLeastFull()) {
    EXPECT_TRUE((modes.find(ANDROID_EDGE_MODE_OFF) != modes.end()) &&
                (modes.find(ANDROID_EDGE_MODE_FAST) != modes.end()))
        << "Full device must contain OFF and FAST edge modes";
  }

  // FAST and HIGH_QUALITY mode must be both present or both not present
  EXPECT_TRUE((modes.find(ANDROID_EDGE_MODE_FAST) != modes.end()) ==
              (modes.find(ANDROID_EDGE_MODE_HIGH_QUALITY) != modes.end()))
      << "FAST and HIGH_QUALITY mode must both present or both not present";

  return modes;
}

std::set<uint8_t> Camera3Device::StaticInfo::GetAvailableNoiseReductionModes()
    const {
  std::set<uint8_t> modes =
      GetAvailableModes(ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
                        ANDROID_NOISE_REDUCTION_MODE_OFF,
                        ANDROID_NOISE_REDUCTION_MODE_ZERO_SHUTTER_LAG);

  // Full device should always include OFF and FAST
  if (IsHardwareLevelAtLeastFull()) {
    EXPECT_TRUE((modes.find(ANDROID_NOISE_REDUCTION_MODE_OFF) != modes.end()) &&
                (modes.find(ANDROID_NOISE_REDUCTION_MODE_FAST) != modes.end()))
        << "Full device must contain OFF and FAST noise reduction modes";
  }

  // FAST and HIGH_QUALITY mode must be both present or both not present
  EXPECT_TRUE(
      (modes.find(ANDROID_NOISE_REDUCTION_MODE_FAST) != modes.end()) ==
      (modes.find(ANDROID_NOISE_REDUCTION_MODE_HIGH_QUALITY) != modes.end()))
      << "FAST and HIGH_QUALITY mode must both present or both not present";

  return modes;
}

std::set<uint8_t> Camera3Device::StaticInfo::GetAvailableColorAberrationModes()
    const {
  std::set<uint8_t> modes =
      GetAvailableModes(ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
                        ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF,
                        ANDROID_COLOR_CORRECTION_ABERRATION_MODE_HIGH_QUALITY);

  EXPECT_TRUE((modes.find(ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF) !=
               modes.end()) ||
              (modes.find(ANDROID_COLOR_CORRECTION_ABERRATION_MODE_FAST) !=
               modes.end()))
      << "Camera devices must always support either OFF or FAST mode";

  // FAST and HIGH_QUALITY mode must be both present or both not present
  EXPECT_TRUE(
      (modes.find(ANDROID_COLOR_CORRECTION_ABERRATION_MODE_FAST) !=
       modes.end()) ==
      (modes.find(ANDROID_COLOR_CORRECTION_ABERRATION_MODE_HIGH_QUALITY) !=
       modes.end()))
      << "FAST and HIGH_QUALITY mode must both present or both not present";

  return modes;
}

std::set<uint8_t> Camera3Device::StaticInfo::GetAvailableToneMapModes() const {
  std::set<uint8_t> modes = GetAvailableModes(
      ANDROID_TONEMAP_AVAILABLE_TONE_MAP_MODES,
      ANDROID_TONEMAP_MODE_CONTRAST_CURVE, ANDROID_TONEMAP_MODE_PRESET_CURVE);

  EXPECT_TRUE(modes.find(ANDROID_TONEMAP_MODE_FAST) != modes.end())
      << "Camera devices must always support FAST mode";

  // FAST and HIGH_QUALITY mode must be both present
  EXPECT_TRUE(modes.find(ANDROID_TONEMAP_MODE_HIGH_QUALITY) != modes.end())
      << "FAST and HIGH_QUALITY mode must both present";

  return modes;
}

std::set<std::pair<int32_t, int32_t>>
Camera3Device::StaticInfo::GetAvailableFpsRanges() const {
  camera_metadata_ro_entry_t entry;
  if (find_camera_metadata_ro_entry(
          characteristics_, ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
          &entry) != 0) {
    ADD_FAILURE() << "Cannot find the metadata "
                     "ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES";
    return {};
  }
  if (entry.count % 2 != 0) {
    ADD_FAILURE() << "Unexpected amount of entries of "
                     "ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES";
    return {};
  }
  std::set<std::pair<int32_t, int32_t>> available_fps_ranges;
  for (size_t i = 0; i < entry.count; i += 2) {
    int32_t min_fps = entry.data.i32[i];
    int32_t max_fps = entry.data.i32[i + 1];
    available_fps_ranges.insert({min_fps, max_fps});
  }
  return available_fps_ranges;
}

void Camera3Device::StaticInfo::GetStreamConfigEntry(
    camera_metadata_ro_entry_t* entry) const {
  entry->count = 0;

  camera_metadata_ro_entry_t local_entry = {};
  ASSERT_EQ(
      0, find_camera_metadata_ro_entry(
             characteristics_, ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
             &local_entry))
      << "Fail to find metadata key "
         "ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS";
  ASSERT_NE(0u, local_entry.count) << "Camera stream configuration is empty";
  ASSERT_EQ(0u, local_entry.count % kNumOfElementsInStreamConfigEntry)
      << "Camera stream configuration parsing error";
  *entry = local_entry;
}

std::set<int32_t> Camera3Device::StaticInfo::GetAvailableFormats(
    int32_t direction) const {
  camera_metadata_ro_entry_t available_config = {};
  GetStreamConfigEntry(&available_config);
  std::set<int32_t> formats;
  for (size_t i = 0; i < available_config.count;
       i += kNumOfElementsInStreamConfigEntry) {
    int32_t format = available_config.data.i32[i + STREAM_CONFIG_FORMAT_INDEX];
    int32_t in_or_out =
        available_config.data.i32[i + STREAM_CONFIG_DIRECTION_INDEX];
    if (in_or_out == direction) {
      formats.insert(format);
    }
  }
  return formats;
}

bool Camera3Device::StaticInfo::IsFormatAvailable(int format) const {
  camera_metadata_ro_entry_t available_config = {};
  GetStreamConfigEntry(&available_config);
  for (uint32_t i = 0; i < available_config.count;
       i += kNumOfElementsInStreamConfigEntry) {
    if (available_config.data.i32[i + STREAM_CONFIG_FORMAT_INDEX] == format) {
      return true;
    }
  }
  return false;
}

std::vector<ResolutionInfo>
Camera3Device::StaticInfo::GetSortedOutputResolutions(int32_t format) const {
  return GetSortedResolutions(format, true);
}

std::vector<ResolutionInfo>
Camera3Device::StaticInfo::GetSortedInputResolutions(int32_t format) const {
  return GetSortedResolutions(format, false);
}

std::vector<ResolutionInfo> Camera3Device::StaticInfo::GetSortedResolutions(
    int32_t format, bool is_output) const {
  camera_metadata_ro_entry_t available_config = {};
  GetStreamConfigEntry(&available_config);
  std::vector<ResolutionInfo> available_resolutions;
  const int32_t direction =
      is_output ? ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT
                : ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT;
  for (uint32_t i = 0; i < available_config.count;
       i += kNumOfElementsInStreamConfigEntry) {
    int32_t fmt = available_config.data.i32[i + STREAM_CONFIG_FORMAT_INDEX];
    int32_t width = available_config.data.i32[i + STREAM_CONFIG_WIDTH_INDEX];
    int32_t height = available_config.data.i32[i + STREAM_CONFIG_HEIGHT_INDEX];
    int32_t in_or_out =
        available_config.data.i32[i + STREAM_CONFIG_DIRECTION_INDEX];
    if (fmt == format && in_or_out == direction) {
      available_resolutions.emplace_back(width, height);
    }
  }
  std::sort(available_resolutions.begin(), available_resolutions.end());
  return available_resolutions;
}

bool Camera3Device::StaticInfo::GetInputOutputConfigurationMap(
    std::map<int32_t, std::vector<int32_t>>* config_map) const {
  camera_metadata_ro_entry_t entry = {};
  if (find_camera_metadata_ro_entry(
          characteristics_, ANDROID_SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP,
          &entry)) {
    ADD_FAILURE() << "Cannot find the metadata "
                     "ANDROID_SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP";
    return false;
  }

  /* format of the map is : input format, num_output_formats,
   * outputFormat1,..,outputFormatN */
  uint32_t num_out;
  const int32_t* p = entry.data.i32;
  for (const int32_t* end = p + entry.count; p < end; p += num_out) {
    int32_t in_format = *(p++);
    num_out = *(p++);
    config_map->emplace(std::piecewise_construct,
                        std::forward_as_tuple(in_format),
                        std::forward_as_tuple(p, p + num_out));
  }
  return true;
}

bool Camera3Device::StaticInfo::IsAELockSupported() const {
  camera_metadata_ro_entry_t entry;
  if (find_camera_metadata_ro_entry(
          characteristics_, ANDROID_CONTROL_AE_LOCK_AVAILABLE, &entry) != 0) {
    ADD_FAILURE()
        << "Cannot find the metadata ANDROID_CONTROL_AE_LOCK_AVAILABLE";
    return false;
  }
  return entry.data.u8[0] == ANDROID_CONTROL_AE_LOCK_AVAILABLE_TRUE;
}

bool Camera3Device::StaticInfo::IsAWBLockSupported() const {
  camera_metadata_ro_entry_t entry;
  if (find_camera_metadata_ro_entry(
          characteristics_, ANDROID_CONTROL_AWB_LOCK_AVAILABLE, &entry) != 0) {
    ADD_FAILURE()
        << "Cannot find the metadata ANDROID_CONTROL_AWB_LOCK_AVAILABLE";
    return false;
  }
  return entry.data.u8[0] == ANDROID_CONTROL_AWB_LOCK_AVAILABLE_TRUE;
}

int32_t Camera3Device::StaticInfo::GetPartialResultCount() const {
  camera_metadata_ro_entry_t entry;
  if (find_camera_metadata_ro_entry(characteristics_,
                                    ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
                                    &entry) != 0) {
    // Optional key. Default value is 1 if key is missing.
    return 1;
  }
  return entry.data.i32[0];
}

uint8_t Camera3Device::StaticInfo::GetRequestPipelineMaxDepth() const {
  camera_metadata_ro_entry_t entry;
  if (find_camera_metadata_ro_entry(
          characteristics_, ANDROID_REQUEST_PIPELINE_MAX_DEPTH, &entry) != 0) {
    ADD_FAILURE()
        << "Cannot find the metadata ANDROID_REQUEST_PIPELINE_MAX_DEPTH";
    return -EINVAL;
  }
  return entry.data.u8[0];
}

int32_t Camera3Device::StaticInfo::GetJpegMaxSize() const {
  camera_metadata_ro_entry_t entry;
  if (find_camera_metadata_ro_entry(characteristics_, ANDROID_JPEG_MAX_SIZE,
                                    &entry) != 0) {
    ADD_FAILURE() << "Cannot find the metadata ANDROID_JPEG_MAX_SIZE";
    return -EINVAL;
  }
  return entry.data.i32[0];
}

int32_t Camera3Device::StaticInfo::GetSensorOrientation() const {
  camera_metadata_ro_entry_t entry;
  if (find_camera_metadata_ro_entry(characteristics_,
                                    ANDROID_SENSOR_ORIENTATION, &entry) != 0) {
    ADD_FAILURE() << "Cannot find the metadata ANDROID_SENSOR_ORIENTATION";
    return -EINVAL;
  }
  return entry.data.i32[0];
}

int32_t Camera3Device::StaticInfo::GetAvailableThumbnailSizes(
    std::vector<ResolutionInfo>* resolutions) const {
  const size_t kNumOfEntriesForSize = 2;
  enum { WIDTH_ENTRY_INDEX, HEIGHT_ENTRY_INDEX };
  camera_metadata_ro_entry_t entry;
  if (find_camera_metadata_ro_entry(characteristics_,
                                    ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
                                    &entry) != 0) {
    ADD_FAILURE()
        << "Cannot find the metadata ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES";
    return -EINVAL;
  }
  if (entry.count % kNumOfEntriesForSize) {
    ADD_FAILURE() << "Camera JPEG available thumbnail sizes parsing error";
    return -EINVAL;
  }
  for (size_t i = 0; i < entry.count; i += kNumOfEntriesForSize) {
    resolutions->emplace_back(entry.data.i32[i + WIDTH_ENTRY_INDEX],
                              entry.data.i32[i + HEIGHT_ENTRY_INDEX]);
  }
  return 0;
}

int32_t Camera3Device::StaticInfo::GetAvailableFocalLengths(
    std::vector<float>* focal_lengths) const {
  camera_metadata_ro_entry_t entry;
  if (find_camera_metadata_ro_entry(characteristics_,
                                    ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
                                    &entry) != 0) {
    ADD_FAILURE()
        << "Cannot find the metadata ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS";
    return -EINVAL;
  }
  if (entry.count == 0) {
    ADD_FAILURE() << "There should be at least one available focal length";
    return -EINVAL;
  }
  for (size_t i = 0; i < entry.count; i++) {
    EXPECT_LT(0.0f, entry.data.f[i])
        << "Available focal length " << entry.data.f[i]
        << " should be positive";
    focal_lengths->push_back(entry.data.f[i]);
  }
  EXPECT_EQ(
      focal_lengths->size(),
      std::set<float>(focal_lengths->begin(), focal_lengths->end()).size())
      << "Avaliable focal lengths should be distinct";
  return 0;
}

int32_t Camera3Device::StaticInfo::GetAvailableApertures(
    std::vector<float>* apertures) const {
  camera_metadata_ro_entry_t entry;
  if (find_camera_metadata_ro_entry(characteristics_,
                                    ANDROID_LENS_INFO_AVAILABLE_APERTURES,
                                    &entry) != 0) {
    ADD_FAILURE()
        << "Cannot find the metadata ANDROID_LENS_INFO_AVAILABLE_APERTURES";
    return -EINVAL;
  }
  if (entry.count == 0) {
    ADD_FAILURE() << "There should be at least one available apertures";
    return -EINVAL;
  }
  for (size_t i = 0; i < entry.count; i++) {
    EXPECT_LT(0.0f, entry.data.f[i])
        << "Available apertures " << entry.data.f[i] << " should be positive";
    apertures->push_back(entry.data.f[i]);
  }
  EXPECT_EQ(apertures->size(),
            std::set<float>(apertures->begin(), apertures->end()).size())
      << "Avaliable apertures should be distinct";
  return 0;
}

int32_t Camera3Device::StaticInfo::GetAvailableAFModes(
    std::vector<uint8_t>* af_modes) const {
  camera_metadata_ro_entry_t entry;
  if (find_camera_metadata_ro_entry(
          characteristics_, ANDROID_CONTROL_AF_AVAILABLE_MODES, &entry) == 0) {
    for (size_t i = 0; i < entry.count; i++) {
      af_modes->push_back(entry.data.u8[i]);
    }
  }
  return 0;
}

int32_t Camera3Device::StaticInfo::GetAvailableTestPatternModes(
    std::vector<int32_t>* test_pattern_modes) const {
  camera_metadata_ro_entry_t entry;
  int32_t result = find_camera_metadata_ro_entry(
      characteristics_, ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES, &entry);
  if (result == 0) {
    for (size_t i = 0; i < entry.count; i++) {
      test_pattern_modes->push_back(entry.data.i32[i]);
    }
  }
  return result;
}

int32_t Camera3Device::StaticInfo::GetAeMaxRegions() const {
  constexpr size_t kMaxRegionsAeIdx = 0;
  camera_metadata_ro_entry_t entry;
  int32_t result = find_camera_metadata_ro_entry(
      characteristics_, ANDROID_CONTROL_MAX_REGIONS, &entry);
  return (result == 0 && entry.count > kMaxRegionsAeIdx)
             ? entry.data.i32[kMaxRegionsAeIdx]
             : 0;
}

int32_t Camera3Device::StaticInfo::GetAwbMaxRegions() const {
  constexpr size_t kMaxRegionsAwbIdx = 1;
  camera_metadata_ro_entry_t entry;
  int32_t result = find_camera_metadata_ro_entry(
      characteristics_, ANDROID_CONTROL_MAX_REGIONS, &entry);
  return (result == 0 && entry.count > kMaxRegionsAwbIdx)
             ? entry.data.i32[kMaxRegionsAwbIdx]
             : 0;
}

int32_t Camera3Device::StaticInfo::GetAfMaxRegions() const {
  constexpr size_t kMaxRegionsAfIdx = 2;
  camera_metadata_ro_entry_t entry;
  int32_t result = find_camera_metadata_ro_entry(
      characteristics_, ANDROID_CONTROL_MAX_REGIONS, &entry);
  return (result == 0 && entry.count > kMaxRegionsAfIdx)
             ? entry.data.i32[kMaxRegionsAfIdx]
             : 0;
}

int32_t Camera3Device::StaticInfo::GetSensorPixelArraySize(
    uint32_t* width, uint32_t* height) const {
  if (!width || !height) {
    return -EINVAL;
  }
  camera_metadata_ro_entry_t entry;
  int32_t result = find_camera_metadata_ro_entry(
      characteristics_, ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE, &entry);
  if (result == 0 && entry.count == 2) {
    *width = entry.data.i32[0];
    *height = entry.data.i32[1];
  } else if (result == 0) {
    return -ENOENT;
  }
  return result;
}

std::set<int32_t> Camera3Device::StaticInfo::GetAvailableRequestKeys() const {
  camera_metadata_ro_entry_t entry = {};
  if (find_camera_metadata_ro_entry(characteristics_,
                                    ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS,
                                    &entry) != 0 ||
      entry.count == 0) {
    ADD_FAILURE() << "Fail to find metadata key "
                     "ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS";
    return std::set<int32_t>();
  }
  return std::set<int32_t>(entry.data.i32, entry.data.i32 + entry.count);
}

// Test fixture

void Camera3DeviceFixture::SetUp() {
  ASSERT_EQ(0, cam_device_.Initialize(&cam_module_))
      << "Camera device initialization fails";
  cam_device_.RegisterResultMetadataOutputBufferCallback(
      base::Bind(&Camera3DeviceFixture::ProcessResultMetadataOutputBuffers,
                 base::Unretained(this)));
  cam_device_.RegisterPartialMetadataCallback(base::Bind(
      &Camera3DeviceFixture::ProcessPartialMetadata, base::Unretained(this)));
}

void Camera3DeviceFixture::TearDown() {
  cam_device_.Destroy();
}

// Test cases

// Test spec:
// - Camera ID
class Camera3DeviceSimpleTest : public Camera3DeviceFixture,
                                public ::testing::WithParamInterface<int> {
 public:
  Camera3DeviceSimpleTest() : Camera3DeviceFixture(GetParam()) {}
};

TEST_P(Camera3DeviceSimpleTest, SensorOrientationTest) {
  // Chromebook has a hardware requirement that the top of the camera should
  // match the top of the display in tablet mode.
  ASSERT_EQ(0, cam_device_.GetStaticInfo()->GetSensorOrientation())
      << "Invalid camera sensor orientation";
}

// Test spec:
// - Camera ID
// - Capture type
class Camera3DeviceDefaultSettings
    : public Camera3DeviceFixture,
      public ::testing::WithParamInterface<std::tuple<int, int>> {
 public:
  Camera3DeviceDefaultSettings()
      : Camera3DeviceFixture(std::get<0>(GetParam())) {}
};

static bool IsMetadataKeyAvailable(const camera_metadata_t* settings,
                                   int32_t key) {
  camera_metadata_ro_entry_t entry;
  return find_camera_metadata_ro_entry(settings, key, &entry) == 0;
}

static void ExpectKeyValue(const camera_metadata_t* settings,
                           int32_t key,
                           const char* key_name,
                           int32_t value,
                           int32_t compare_type) {
  camera_metadata_ro_entry_t entry;
  ASSERT_EQ(0, find_camera_metadata_ro_entry(settings, key, &entry))
      << "Cannot find the metadata " << key_name;
  if (compare_type == 0) {
    ASSERT_EQ(value, entry.data.i32[0])
        << "Wrong value of metadata " << key_name;
  } else {
    ASSERT_NE(value, entry.data.i32[0])
        << "Wrong value of metadata " << key_name;
  }
}
#define EXPECT_KEY_VALUE_EQ(settings, key, value) \
  ExpectKeyValue(settings, key, #key, value, 0)
#define EXPECT_KEY_VALUE_NE(settings, key, value) \
  ExpectKeyValue(settings, key, #key, value, 1)

static void ExpectKeyValueNotEqualsI64(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_NE(value, entry.data.i64[0]) << "Wrong value of metadata " << key_name;
}
#define EXPECT_KEY_VALUE_NE_I64(settings, key, value) \
  ExpectKeyValueNotEqualsI64(settings, key, #key, value)

TEST_P(Camera3DeviceDefaultSettings, ConstructDefaultSettings) {
  int type = std::get<1>(GetParam());
  auto static_info = cam_device_.GetStaticInfo();

  const camera_metadata_t* default_settings;
  default_settings = cam_device_.ConstructDefaultRequestSettings(type);
  if (!default_settings) {
    if (type == CAMERA3_TEMPLATE_MANUAL &&
        !static_info->IsCapabilitySupported(
            ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
      return;
    } else if (
        type == CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG &&
        !static_info->IsCapabilitySupported(
            ANDROID_REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING)) {
      return;
    }
  }
  ASSERT_NE(nullptr, default_settings) << "Camera default settings are NULL";

  // Reference: camera2/cts/CameraDeviceTest.java#captureTemplateTestByCamera
  if (!cam_device_.IsTemplateSupported(type)) {
    return;
  } else if (type != CAMERA3_TEMPLATE_PREVIEW &&
             static_info->IsDepthOutputSupported() &&
             !static_info->IsColorOutputSupported()) {
    // Depth-only devices need only support PREVIEW template
    return;
  }

  // Reference: camera2/cts/CameraDeviceTest.java#checkRequestForTemplate
  // 3A settings--control mode
  if (type == CAMERA3_TEMPLATE_MANUAL) {
    EXPECT_KEY_VALUE_EQ(default_settings, ANDROID_CONTROL_MODE,
                        ANDROID_CONTROL_MODE_OFF);
    EXPECT_KEY_VALUE_EQ(default_settings, ANDROID_CONTROL_AE_MODE,
                        ANDROID_CONTROL_AE_MODE_OFF);
    EXPECT_KEY_VALUE_EQ(default_settings, ANDROID_CONTROL_AWB_MODE,
                        ANDROID_CONTROL_AWB_MODE_OFF);
  } else {
    EXPECT_KEY_VALUE_EQ(default_settings, ANDROID_CONTROL_AE_MODE,
                        ANDROID_CONTROL_AE_MODE_ON);

    EXPECT_KEY_VALUE_EQ(default_settings,
                        ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION, 0);

    EXPECT_KEY_VALUE_EQ(default_settings, ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
                        ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE);

    // if AE lock is not supported, expect the control key to be non-existent or
    // false
    if (static_info->IsAELockSupported() ||
        IsMetadataKeyAvailable(default_settings, ANDROID_CONTROL_AE_LOCK)) {
      EXPECT_KEY_VALUE_EQ(default_settings, ANDROID_CONTROL_AE_LOCK,
                          ANDROID_CONTROL_AE_LOCK_OFF);
    }

    EXPECT_KEY_VALUE_EQ(default_settings, ANDROID_CONTROL_AF_TRIGGER,
                        ANDROID_CONTROL_AF_TRIGGER_IDLE);

    EXPECT_KEY_VALUE_EQ(default_settings, ANDROID_CONTROL_AWB_MODE,
                        ANDROID_CONTROL_AWB_MODE_AUTO);

    // if AWB lock is not supported, expect the control key to be non-existent
    // or false
    if (static_info->IsAWBLockSupported() ||
        IsMetadataKeyAvailable(default_settings, ANDROID_CONTROL_AWB_LOCK)) {
      EXPECT_KEY_VALUE_EQ(default_settings, ANDROID_CONTROL_AWB_LOCK,
                          ANDROID_CONTROL_AWB_LOCK_OFF);
    }

    // Check 3A regions
    // TODO(hywu): CONTROL_AE_REGIONS, CONTROL_AWB_REGIONS, CONTROL_AF_REGIONS?
  }

  // Sensor settings
  // TODO(hywu): LENS_APERTURE, LENS_FILTER_DENSITY, LENS_FOCAL_LENGTH,
  //       LENS_OPTICAL_STABILIZATION_MODE?
  //       BLACK_LEVEL_LOCK?

  if (static_info->IsKeyAvailable(ANDROID_BLACK_LEVEL_LOCK)) {
    EXPECT_KEY_VALUE_EQ(default_settings, ANDROID_BLACK_LEVEL_LOCK,
                        ANDROID_BLACK_LEVEL_LOCK_OFF);
  }

  if (static_info->IsKeyAvailable(ANDROID_SENSOR_FRAME_DURATION)) {
    EXPECT_KEY_VALUE_NE_I64(default_settings, ANDROID_SENSOR_FRAME_DURATION, 0);
  }

  if (static_info->IsKeyAvailable(ANDROID_SENSOR_EXPOSURE_TIME)) {
    EXPECT_KEY_VALUE_NE_I64(default_settings, ANDROID_SENSOR_EXPOSURE_TIME, 0);
  }

  if (static_info->IsKeyAvailable(ANDROID_SENSOR_SENSITIVITY)) {
    EXPECT_KEY_VALUE_NE(default_settings, ANDROID_SENSOR_SENSITIVITY, 0);
  }

  // ISP-processing settings
  EXPECT_KEY_VALUE_EQ(default_settings, ANDROID_STATISTICS_FACE_DETECT_MODE,
                      ANDROID_STATISTICS_FACE_DETECT_MODE_OFF);

  EXPECT_KEY_VALUE_EQ(default_settings, ANDROID_FLASH_MODE,
                      ANDROID_FLASH_MODE_OFF);

  if (static_info->IsKeyAvailable(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE)) {
    // If the device doesn't support RAW, all template should have OFF as
    // default
    if (!static_info->IsCapabilitySupported(
            ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW)) {
      EXPECT_KEY_VALUE_EQ(default_settings,
                          ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
                          ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF);
    }
  }

  bool support_reprocessing =
      static_info->IsCapabilitySupported(
          ANDROID_REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING) ||
      static_info->IsCapabilitySupported(
          ANDROID_REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING);

  if (type == CAMERA3_TEMPLATE_STILL_CAPTURE) {
    // Not enforce high quality here, as some devices may not effectively have
    // high quality mode
    if (static_info->IsKeyAvailable(ANDROID_COLOR_CORRECTION_MODE)) {
      EXPECT_KEY_VALUE_NE(default_settings, ANDROID_COLOR_CORRECTION_MODE,
                          ANDROID_COLOR_CORRECTION_MODE_TRANSFORM_MATRIX);
    }

    // Edge enhancement, noise reduction and aberration correction modes.
    EXPECT_EQ(IsMetadataKeyAvailable(default_settings, ANDROID_EDGE_MODE),
              static_info->IsKeyAvailable(ANDROID_EDGE_AVAILABLE_EDGE_MODES))
        << "Edge mode must be present in request if available edge modes are "
           "present in metadata, and vice-versa";
    if (static_info->IsKeyAvailable(ANDROID_EDGE_MODE)) {
      std::set<uint8_t> edge_modes = static_info->GetAvailableEdgeModes();
      // Don't need check fast as fast or high quality must be both present or
      // both not.
      if (edge_modes.find(ANDROID_EDGE_MODE_HIGH_QUALITY) != edge_modes.end()) {
        EXPECT_KEY_VALUE_EQ(default_settings, ANDROID_EDGE_MODE,
                            ANDROID_EDGE_MODE_HIGH_QUALITY);
      } else {
        EXPECT_KEY_VALUE_EQ(default_settings, ANDROID_EDGE_MODE,
                            ANDROID_EDGE_MODE_OFF);
      }
    }

    EXPECT_EQ(
        IsMetadataKeyAvailable(default_settings, ANDROID_NOISE_REDUCTION_MODE),
        static_info->IsKeyAvailable(
            ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES))
        << "Noise reduction mode must be present in request if available noise "
           "reductions are present in metadata, and vice-versa";
    if (static_info->IsKeyAvailable(
            ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES)) {
      std::set<uint8_t> nr_modes =
          static_info->GetAvailableNoiseReductionModes();
      // Don't need check fast as fast or high quality must be both present or
      // both not
      if (nr_modes.find(ANDROID_NOISE_REDUCTION_MODE_HIGH_QUALITY) !=
          nr_modes.end()) {
        EXPECT_KEY_VALUE_EQ(default_settings, ANDROID_NOISE_REDUCTION_MODE,
                            ANDROID_NOISE_REDUCTION_MODE_HIGH_QUALITY);
      } else {
        EXPECT_KEY_VALUE_EQ(default_settings, ANDROID_NOISE_REDUCTION_MODE,
                            ANDROID_NOISE_REDUCTION_MODE_OFF);
      }
    }

    EXPECT_EQ(IsMetadataKeyAvailable(default_settings,
                                     ANDROID_COLOR_CORRECTION_ABERRATION_MODE),
              static_info->IsKeyAvailable(
                  ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES))
        << "Aberration correction mode must be present in request if available "
           "aberration correction reductions are present in metadata, and "
           "vice-versa";
    if (static_info->IsKeyAvailable(ANDROID_COLOR_CORRECTION_ABERRATION_MODE)) {
      std::set<uint8_t> aberration_modes =
          static_info->GetAvailableColorAberrationModes();
      // Don't need check fast as fast or high quality must be both present or
      // both not
      if (aberration_modes.find(
              ANDROID_COLOR_CORRECTION_ABERRATION_MODE_HIGH_QUALITY) !=
          aberration_modes.end()) {
        EXPECT_KEY_VALUE_EQ(
            default_settings, ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
            ANDROID_COLOR_CORRECTION_ABERRATION_MODE_HIGH_QUALITY);
      } else {
        EXPECT_KEY_VALUE_EQ(default_settings,
                            ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
                            ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF);
      }
    }
  } else if (type == CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG &&
             support_reprocessing) {
    EXPECT_KEY_VALUE_EQ(default_settings, ANDROID_EDGE_MODE,
                        ANDROID_EDGE_MODE_ZERO_SHUTTER_LAG);
    EXPECT_KEY_VALUE_EQ(default_settings, ANDROID_NOISE_REDUCTION_MODE,
                        ANDROID_NOISE_REDUCTION_MODE_ZERO_SHUTTER_LAG);
  } else if (type == CAMERA3_TEMPLATE_PREVIEW ||
             type == CAMERA3_TEMPLATE_VIDEO_RECORD) {
    if (static_info->IsKeyAvailable(ANDROID_EDGE_MODE)) {
      std::set<uint8_t> edge_modes = static_info->GetAvailableEdgeModes();
      if (edge_modes.find(ANDROID_EDGE_MODE_FAST) != edge_modes.end()) {
        EXPECT_KEY_VALUE_EQ(default_settings, ANDROID_EDGE_MODE,
                            ANDROID_EDGE_MODE_FAST);
      } else {
        EXPECT_KEY_VALUE_EQ(default_settings, ANDROID_EDGE_MODE,
                            ANDROID_EDGE_MODE_OFF);
      }
    }

    if (static_info->IsKeyAvailable(ANDROID_NOISE_REDUCTION_MODE)) {
      std::set<uint8_t> nr_modes =
          static_info->GetAvailableNoiseReductionModes();
      if (nr_modes.find(ANDROID_NOISE_REDUCTION_MODE_FAST) != nr_modes.end()) {
        EXPECT_KEY_VALUE_EQ(default_settings, ANDROID_NOISE_REDUCTION_MODE,
                            ANDROID_NOISE_REDUCTION_MODE_FAST);
      } else {
        EXPECT_KEY_VALUE_EQ(default_settings, ANDROID_NOISE_REDUCTION_MODE,
                            ANDROID_NOISE_REDUCTION_MODE_OFF);
      }
    }

    if (static_info->IsKeyAvailable(ANDROID_COLOR_CORRECTION_ABERRATION_MODE)) {
      std::set<uint8_t> aberration_modes =
          static_info->GetAvailableColorAberrationModes();
      if (aberration_modes.find(
              ANDROID_COLOR_CORRECTION_ABERRATION_MODE_FAST) !=
          aberration_modes.end()) {
        EXPECT_KEY_VALUE_EQ(default_settings,
                            ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
                            ANDROID_COLOR_CORRECTION_ABERRATION_MODE_FAST);
      } else {
        EXPECT_KEY_VALUE_EQ(default_settings,
                            ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
                            ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF);
      }
    }
  } else {
    if (static_info->IsKeyAvailable(ANDROID_EDGE_MODE)) {
      ASSERT_TRUE(IsMetadataKeyAvailable(default_settings, ANDROID_EDGE_MODE));
    }

    if (static_info->IsKeyAvailable(ANDROID_NOISE_REDUCTION_MODE)) {
      ASSERT_TRUE(IsMetadataKeyAvailable(default_settings,
                                         ANDROID_NOISE_REDUCTION_MODE));
    }

    if (static_info->IsKeyAvailable(ANDROID_COLOR_CORRECTION_ABERRATION_MODE)) {
      ASSERT_TRUE(IsMetadataKeyAvailable(
          default_settings, ANDROID_COLOR_CORRECTION_ABERRATION_MODE));
    }
  }

  // Tone map and lens shading modes.
  if (type == CAMERA3_TEMPLATE_STILL_CAPTURE) {
    EXPECT_EQ(
        IsMetadataKeyAvailable(default_settings, ANDROID_TONEMAP_MODE),
        static_info->IsKeyAvailable(ANDROID_TONEMAP_AVAILABLE_TONE_MAP_MODES))
        << "Tonemap mode must be present in request if available tonemap modes "
           "are present in metadata, and vice-versa";
    if (static_info->IsKeyAvailable(ANDROID_TONEMAP_AVAILABLE_TONE_MAP_MODES)) {
      std::set<uint8_t> tone_map_modes =
          static_info->GetAvailableToneMapModes();
      if (tone_map_modes.find(ANDROID_TONEMAP_MODE_HIGH_QUALITY) !=
          tone_map_modes.end()) {
        EXPECT_KEY_VALUE_EQ(default_settings, ANDROID_TONEMAP_MODE,
                            ANDROID_TONEMAP_MODE_HIGH_QUALITY);
      } else {
        EXPECT_KEY_VALUE_EQ(default_settings, ANDROID_TONEMAP_MODE,
                            ANDROID_TONEMAP_MODE_FAST);
      }
    }

    // Still capture template should have android.statistics.lensShadingMapMode
    // ON when RAW capability is supported.
    if (static_info->IsKeyAvailable(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE) &&
        static_info->IsCapabilitySupported(
            ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW)) {
      EXPECT_KEY_VALUE_EQ(default_settings,
                          ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
                          ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_ON);
    }
  } else {
    if (static_info->IsKeyAvailable(ANDROID_TONEMAP_MODE)) {
      EXPECT_KEY_VALUE_NE(default_settings, ANDROID_TONEMAP_MODE,
                          ANDROID_TONEMAP_MODE_CONTRAST_CURVE);
      EXPECT_KEY_VALUE_NE(default_settings, ANDROID_TONEMAP_MODE,
                          ANDROID_TONEMAP_MODE_GAMMA_VALUE);
      EXPECT_KEY_VALUE_NE(default_settings, ANDROID_TONEMAP_MODE,
                          ANDROID_TONEMAP_MODE_PRESET_CURVE);
    }
    if (static_info->IsKeyAvailable(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE)) {
      EXPECT_KEY_VALUE_NE(default_settings,
                          ANDROID_STATISTICS_LENS_SHADING_MAP_MODE, 0);
    }
  }

  EXPECT_KEY_VALUE_EQ(default_settings, ANDROID_CONTROL_CAPTURE_INTENT, type);
}

// Test spec:
// - Camera ID
// - Capture type
class CreateInvalidTemplate
    : public Camera3DeviceFixture,
      public ::testing::WithParamInterface<std::tuple<int, int>> {
 public:
  CreateInvalidTemplate() : Camera3DeviceFixture(std::get<0>(GetParam())) {}
};

TEST_P(CreateInvalidTemplate, ConstructDefaultSettings) {
  // Reference:
  // camera2/cts/CameraDeviceTest.java#testCameraDeviceCreateCaptureBuilder
  int type = std::get<1>(GetParam());
  ASSERT_EQ(nullptr, cam_device_.ConstructDefaultRequestSettings(type))
      << "Should get error due to an invalid template ID";
}

// Test spec:
// - Camera ID
class Camera3AlgoSandboxIPCErrorTest
    : public Camera3DeviceFixture,
      public ::testing::WithParamInterface<int> {
 public:
  const uint32_t kDefaultTimeoutMs = 1000;

  Camera3AlgoSandboxIPCErrorTest()
      : Camera3DeviceFixture(GetParam()), cam_id_(GetParam()) {}

  void SetUp() override;

 protected:
  void Notify(const camera3_notify_msg* msg);

  int cam_id_;

  sem_t ipc_error_sem_;
};

void Camera3AlgoSandboxIPCErrorTest::SetUp() {
  Camera3DeviceFixture::SetUp();
  cam_device_.RegisterNotifyCallback(base::Bind(
      &Camera3AlgoSandboxIPCErrorTest::Notify, base::Unretained(this)));
  sem_init(&ipc_error_sem_, 0, 0);
}

void Camera3AlgoSandboxIPCErrorTest::Notify(const camera3_notify_msg* msg) {
  VLOGF_ENTER();
  EXPECT_EQ(CAMERA3_MSG_ERROR, msg->type)
      << "Unexpected message type " << msg->type << " is notified";
  EXPECT_EQ(CAMERA3_MSG_ERROR_DEVICE, msg->message.error.error_code)
      << "Unexpected error code " << msg->message.error.error_code
      << " is notified";
  sem_post(&ipc_error_sem_);
}

TEST_P(Camera3AlgoSandboxIPCErrorTest, IPCErrorBeforeOpen) {
  cam_device_.Destroy();
  (void)system("stop cros-camera-algo");
  ASSERT_EQ(nullptr, cam_module_.OpenDevice(cam_id_))
      << "Camera device should not be opened successfully";

  (void)system("start cros-camera-algo");
  ASSERT_EQ(0, cam_device_.Initialize(&cam_module_))
      << "Camera device initialization fails";
}

TEST_P(Camera3AlgoSandboxIPCErrorTest, IPCErrorAfterOpen) {
  (void)system("stop cros-camera-algo");
  struct timespec timeout;
  memset(&timeout, 0, sizeof(timeout));
  if (clock_gettime(CLOCK_REALTIME, &timeout)) {
    LOG(ERROR) << "Failed to get clock time";
  }
  timeout.tv_sec += kDefaultTimeoutMs / 1000;
  timeout.tv_nsec += (kDefaultTimeoutMs % 1000) * 1000;
  ASSERT_EQ(0, sem_timedwait(&ipc_error_sem_, &timeout));

  (void)system("start cros-camera-algo");
  cam_device_.Destroy();
  ASSERT_EQ(0, cam_device_.Initialize(&cam_module_))
      << "Camera device initialization fails";
}

INSTANTIATE_TEST_SUITE_P(Camera3DeviceTest,
                         Camera3DeviceSimpleTest,
                         ::testing::ValuesIn(Camera3Module().GetCameraIds()));

INSTANTIATE_TEST_SUITE_P(
    Camera3DeviceTest,
    Camera3DeviceDefaultSettings,
    ::testing::Combine(::testing::ValuesIn(Camera3Module().GetCameraIds()),
                       ::testing::Values(CAMERA3_TEMPLATE_PREVIEW,
                                         CAMERA3_TEMPLATE_STILL_CAPTURE,
                                         CAMERA3_TEMPLATE_VIDEO_RECORD,
                                         CAMERA3_TEMPLATE_VIDEO_SNAPSHOT,
                                         CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG,
                                         CAMERA3_TEMPLATE_MANUAL)));

INSTANTIATE_TEST_SUITE_P(
    Camera3DeviceTest,
    CreateInvalidTemplate,
    ::testing::Combine(::testing::ValuesIn(Camera3Module().GetCameraIds()),
                       ::testing::Values(CAMERA3_TEMPLATE_PREVIEW - 1,
                                         CAMERA3_TEMPLATE_MANUAL + 1)));

INSTANTIATE_TEST_SUITE_P(Camera3DeviceTest,
                         Camera3AlgoSandboxIPCErrorTest,
                         ::testing::ValuesIn(Camera3Module().GetCameraIds()));

}  // namespace camera3_test
