// 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::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,
                                        BufferHandleUniquePtr 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(int32_t level) const {
  int32_t dev_level = GetHardwareLevel();
  if (dev_level == ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY) {
    return dev_level == level;
  }
  // Level is not LEGACY, can use numerical sort
  return dev_level >= level;
}

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

bool Camera3Device::StaticInfo::IsHardwareLevelAtLeastLimited() const {
  return IsHardwareLevelAtLeast(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED);
}

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

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::unordered_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 {
  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 {
  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 {
  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;
}

// Test fixture

void Camera3DeviceFixture::SetUp() {
  ASSERT_EQ(0, cam_module_.Initialize())
      << "Camera module initialization fails";

  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_CASE_P(Camera3DeviceTest,
                        Camera3DeviceSimpleTest,
                        ::testing::ValuesIn(Camera3Module().GetCameraIds()));

INSTANTIATE_TEST_CASE_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_CASE_P(
    Camera3DeviceTest,
    CreateInvalidTemplate,
    ::testing::Combine(::testing::ValuesIn(Camera3Module().GetCameraIds()),
                       ::testing::Values(CAMERA3_TEMPLATE_PREVIEW - 1,
                                         CAMERA3_TEMPLATE_MANUAL + 1)));

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

}  // namespace camera3_test
