blob: 2bcb096e968ea3b51b8332c9f979e8c2c6ad1d64 [file] [log] [blame]
// 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