Switch to composition over inheritance.
Switches v4l2_metadata over to the updated controls/properties
using inheritance over composition. Slight regression
in that the V4L2-based control factory method was removed,
will be replaced (and improved) in a CL soon.
BUG: 30140438
TEST: unit tests pass
Change-Id: I636fef67cd3ceeb3ebf9853d04b068988c4c4944
diff --git a/modules/camera/3_4/Android.mk b/modules/camera/3_4/Android.mk
index 7c8f430..1e7f4d6 100644
--- a/modules/camera/3_4/Android.mk
+++ b/modules/camera/3_4/Android.mk
@@ -41,7 +41,6 @@
camera.cpp \
metadata/enum_converter.cpp \
metadata/metadata.cpp \
- metadata/v4l2_enum_control.cpp \
stream.cpp \
stream_format.cpp \
v4l2_camera.cpp \
@@ -53,20 +52,17 @@
v4l2_test_files := \
metadata/control_test.cpp \
metadata/enum_converter_test.cpp \
- metadata/fixed_property_test.cpp \
metadata/ignored_control_delegate_test.cpp \
- metadata/ignored_control_test.cpp \
metadata/map_converter_test.cpp \
metadata/menu_control_options_test.cpp \
metadata/metadata_test.cpp \
metadata/no_effect_control_delegate_test.cpp \
- metadata/optioned_control_test.cpp \
+ metadata/property_test.cpp \
metadata/ranged_converter_test.cpp \
metadata/slider_control_options_test.cpp \
metadata/tagged_control_delegate_test.cpp \
metadata/tagged_control_options_test.cpp \
metadata/v4l2_control_delegate_test.cpp \
- metadata/v4l2_enum_control_test.cpp \
# V4L2 Camera HAL.
# ==============================================================================
diff --git a/modules/camera/3_4/metadata/control.h b/modules/camera/3_4/metadata/control.h
index eff8c2f..199ecd0 100644
--- a/modules/camera/3_4/metadata/control.h
+++ b/modules/camera/3_4/metadata/control.h
@@ -22,18 +22,29 @@
#include <system/camera_metadata.h>
#include "../common.h"
+#include "menu_control_options.h"
#include "metadata_common.h"
-#include "tagged_partial_metadata.h"
+#include "no_effect_control_delegate.h"
+#include "partial_metadata_interface.h"
+#include "tagged_control_delegate.h"
+#include "tagged_control_options.h"
namespace v4l2_camera_hal {
// A Control is a PartialMetadata with values that can be gotten/set.
template <typename T>
-class Control : public TaggedPartialMetadata {
+class Control : public PartialMetadataInterface {
public:
- Control(int32_t control_tag, std::vector<int32_t> static_tags = {});
+ // Options are optional (i.e. nullable), delegate is not.
+ Control(std::unique_ptr<TaggedControlDelegate<T>> delegate,
+ std::unique_ptr<TaggedControlOptions<T>> options = nullptr);
- // Child classes still need to implement PopulateStaticFields.
+ virtual std::vector<int32_t> StaticTags() const override;
+ virtual std::vector<int32_t> ControlTags() const override;
+ virtual std::vector<int32_t> DynamicTags() const override;
+
+ virtual int PopulateStaticFields(
+ android::CameraMetadata* metadata) const override;
virtual int PopulateDynamicFields(
android::CameraMetadata* metadata) const override;
virtual bool SupportsRequestValues(
@@ -41,20 +52,15 @@
virtual int SetRequestValues(
const android::CameraMetadata& metadata) override;
- protected:
- // Simpler access to tag.
- inline int32_t ControlTag() const { return ControlTags()[0]; }
+ // Factory methods for some common combinations of delegates & options.
+ // NoEffectMenuControl: Some menu options, but they have no effect.
+ // The default value will be the first element of |options|.
+ static std::unique_ptr<Control<T>> NoEffectMenuControl(
+ int32_t delegate_tag, int32_t options_tag, const std::vector<T>& options);
- // Get/Set the control value. Return non-0 on failure.
- // Controls are allowed to be unreliable, so SetValue is best-effort;
- // GetValue immediately after may not match (SetValue may, for example,
- // automatically replace invalid values with valid ones,
- // or have a delay before setting the requested value).
- // GetValue should always indicate the actual current value of the control.
- virtual int GetValue(T* value) const = 0;
- virtual int SetValue(const T& value) = 0;
- // Helper to check if val is supported by this control.
- virtual bool IsSupported(const T& val) const = 0;
+ protected:
+ std::unique_ptr<TaggedControlDelegate<T>> delegate_;
+ std::unique_ptr<TaggedControlOptions<T>> options_;
DISALLOW_COPY_AND_ASSIGN(Control);
};
@@ -62,24 +68,55 @@
// -----------------------------------------------------------------------------
template <typename T>
-Control<T>::Control(int32_t control_tag, std::vector<int32_t> static_tags)
- // Controls use the same tag for setting the control
- // and getting the dynamic value.
- : TaggedPartialMetadata(static_tags, {control_tag}, {control_tag}) {
+Control<T>::Control(std::unique_ptr<TaggedControlDelegate<T>> delegate,
+ std::unique_ptr<TaggedControlOptions<T>> options)
+ : delegate_(std::move(delegate)), options_(std::move(options)) {
HAL_LOG_ENTER();
}
template <typename T>
+std::vector<int32_t> Control<T>::StaticTags() const {
+ std::vector<int32_t> result;
+ if (options_) {
+ result.push_back(options_->tag());
+ }
+ return result;
+}
+
+template <typename T>
+std::vector<int32_t> Control<T>::ControlTags() const {
+ return {delegate_->tag()};
+}
+
+template <typename T>
+std::vector<int32_t> Control<T>::DynamicTags() const {
+ return {delegate_->tag()};
+}
+
+template <typename T>
+int Control<T>::PopulateStaticFields(android::CameraMetadata* metadata) const {
+ HAL_LOG_ENTER();
+
+ if (!options_) {
+ HAL_LOGV("No options for control, nothing to populate.");
+ return 0;
+ }
+
+ return UpdateMetadata(
+ metadata, options_->tag(), options_->MetadataRepresentation());
+}
+
+template <typename T>
int Control<T>::PopulateDynamicFields(android::CameraMetadata* metadata) const {
HAL_LOG_ENTER();
// Populate the current setting.
T value;
- int res = GetValue(&value);
+ int res = delegate_->GetValue(&value);
if (res) {
return res;
}
- return UpdateMetadata(metadata, ControlTag(), value);
+ return UpdateMetadata(metadata, delegate_->tag(), value);
}
template <typename T>
@@ -91,18 +128,25 @@
return true;
}
- // Check that the requested setting is in the supported options.
+ // Get the requested setting for this control.
T requested;
- int res = SingleTagValue(metadata, ControlTag(), &requested);
+ int res = SingleTagValue(metadata, delegate_->tag(), &requested);
if (res == -ENOENT) {
// Nothing requested of this control, that's fine.
return true;
} else if (res) {
HAL_LOGE("Failure while searching for request value for tag %d",
- ControlTag());
+ delegate_->tag());
return false;
}
- return IsSupported(requested);
+
+ // Check that the requested setting is in the supported options.
+ if (!options_) {
+ HAL_LOGV("No options for control %d; request implicitly supported.",
+ delegate_->tag());
+ return true;
+ }
+ return options_->IsSupported(requested);
}
template <typename T>
@@ -115,17 +159,41 @@
// Get the requested value.
T requested;
- int res = SingleTagValue(metadata, ControlTag(), &requested);
+ int res = SingleTagValue(metadata, delegate_->tag(), &requested);
if (res == -ENOENT) {
// Nothing requested of this control, nothing to do.
return 0;
} else if (res) {
HAL_LOGE("Failure while searching for request value for tag %d",
- ControlTag());
+ delegate_->tag());
return res;
}
- return SetValue(requested);
+ // Check that the value is supported.
+ if (options_ && !options_->IsSupported(requested)) {
+ HAL_LOGE("Unsupported value requested for control %d.", delegate_->tag());
+ return -EINVAL;
+ }
+
+ return delegate_->SetValue(requested);
+}
+
+template <typename T>
+std::unique_ptr<Control<T>> Control<T>::NoEffectMenuControl(
+ int32_t delegate_tag, int32_t options_tag, const std::vector<T>& options) {
+ HAL_LOG_ENTER();
+
+ if (options.empty()) {
+ HAL_LOGE("At least one option must be provided.");
+ return nullptr;
+ }
+
+ return std::make_unique<Control<T>>(
+ std::make_unique<TaggedControlDelegate<T>>(
+ delegate_tag,
+ std::make_unique<NoEffectControlDelegate<T>>(options[0])),
+ std::make_unique<TaggedControlOptions<T>>(
+ options_tag, std::make_unique<MenuControlOptions<T>>(options)));
}
} // namespace v4l2_camera_hal
diff --git a/modules/camera/3_4/metadata/control_test.cpp b/modules/camera/3_4/metadata/control_test.cpp
index ef4b6af..b414ad3 100644
--- a/modules/camera/3_4/metadata/control_test.cpp
+++ b/modules/camera/3_4/metadata/control_test.cpp
@@ -16,16 +16,17 @@
#include "control.h"
-#include <array>
-
#include <camera/CameraMetadata.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
+#include "control_delegate_interface_mock.h"
+#include "control_options_interface_mock.h"
#include "metadata_common.h"
#include "test_common.h"
using testing::AtMost;
+using testing::Expectation;
using testing::Return;
using testing::ReturnRef;
using testing::SetArgPointee;
@@ -36,46 +37,106 @@
class ControlTest : public Test {
protected:
- // A subclass of Control with the pure virtual methods mocked out.
- template <typename T>
- class MockControl : public Control<T> {
- public:
- MockControl(int32_t control_tag) : Control<T>(control_tag){};
- MOCK_CONST_METHOD1_T(PopulateStaticFields,
- int(android::CameraMetadata* metadata));
- MOCK_CONST_METHOD1_T(GetValue, int(T* value));
- MOCK_METHOD1_T(SetValue, int(const T& value));
- MOCK_CONST_METHOD1_T(IsSupported, bool(const T& value));
- };
-
virtual void SetUp() {
- control_.reset(new MockControl<uint8_t>(control_tag_));
+ mock_delegate_.reset(new ControlDelegateInterfaceMock<uint8_t>());
+ mock_options_.reset(new ControlOptionsInterfaceMock<uint8_t>());
+ // Nullify control so an error will be thrown if a test doesn't call
+ // PrepareControl.
+ control_.reset();
}
- std::unique_ptr<MockControl<uint8_t>> control_;
+ virtual void PrepareControl(bool with_options = true) {
+ // Use this method after all the EXPECT_CALLs to pass ownership of the mocks
+ // to the device.
+ std::unique_ptr<TaggedControlDelegate<uint8_t>> delegate =
+ std::make_unique<TaggedControlDelegate<uint8_t>>(
+ delegate_tag_, std::move(mock_delegate_));
+ std::unique_ptr<TaggedControlOptions<uint8_t>> options =
+ std::make_unique<TaggedControlOptions<uint8_t>>(
+ options_tag_, std::move(mock_options_));
+ if (with_options) {
+ control_.reset(
+ new Control<uint8_t>(std::move(delegate), std::move(options)));
+ } else {
+ control_.reset(new Control<uint8_t>(std::move(delegate)));
+ }
+ }
+
+ std::unique_ptr<Control<uint8_t>> control_;
+ std::unique_ptr<ControlDelegateInterfaceMock<uint8_t>> mock_delegate_;
+ std::unique_ptr<ControlOptionsInterfaceMock<uint8_t>> mock_options_;
// Need tags that match the data type (uint8_t) being passed.
- static constexpr int32_t control_tag_ =
- ANDROID_COLOR_CORRECTION_ABERRATION_MODE;
+ const int32_t delegate_tag_ = ANDROID_COLOR_CORRECTION_ABERRATION_MODE;
+ const int32_t options_tag_ =
+ ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES;
};
TEST_F(ControlTest, Tags) {
- // Should have no static tags by default.
- EXPECT_EQ(control_->StaticTags().size(), 0);
- // Controls use the same tag for getting and setting.
- // The macro doesn't like the static variables
- // being passed directly to assertions.
- int32_t expected_tag = control_tag_;
+ PrepareControl();
+ ASSERT_EQ(control_->StaticTags().size(), 1);
+ EXPECT_EQ(control_->StaticTags()[0], options_tag_);
+ // Controls use the same delgate, and thus tag, for getting and setting.
ASSERT_EQ(control_->ControlTags().size(), 1);
- EXPECT_EQ(control_->ControlTags()[0], expected_tag);
+ EXPECT_EQ(control_->ControlTags()[0], delegate_tag_);
ASSERT_EQ(control_->DynamicTags().size(), 1);
- EXPECT_EQ(control_->DynamicTags()[0], expected_tag);
+ EXPECT_EQ(control_->DynamicTags()[0], delegate_tag_);
+}
+
+TEST_F(ControlTest, TagsNoOptions) {
+ PrepareControl(false);
+ // No options, so no options tag.
+ ASSERT_EQ(control_->StaticTags().size(), 0);
+ // Controls use the same delgate, and thus tag, for getting and setting.
+ ASSERT_EQ(control_->ControlTags().size(), 1);
+ EXPECT_EQ(control_->ControlTags()[0], delegate_tag_);
+ ASSERT_EQ(control_->DynamicTags().size(), 1);
+ EXPECT_EQ(control_->DynamicTags()[0], delegate_tag_);
+}
+
+TEST_F(ControlTest, PopulateStatic) {
+ std::vector<uint8_t> expected{1, 10, 20};
+ EXPECT_CALL(*mock_options_, MetadataRepresentation())
+ .WillOnce(Return(expected));
+ PrepareControl();
+
+ android::CameraMetadata metadata;
+ ASSERT_EQ(control_->PopulateStaticFields(&metadata), 0);
+ // Should only have added 1 entry.
+ EXPECT_EQ(metadata.entryCount(), 1);
+ // Should have added the right entry.
+ ExpectMetadataEq(metadata, options_tag_, expected);
+}
+
+TEST_F(ControlTest, PopulateStaticNoOptions) {
+ PrepareControl(false);
+ android::CameraMetadata metadata;
+ ASSERT_EQ(control_->PopulateStaticFields(&metadata), 0);
+ // Should not have added any entry.
+ EXPECT_TRUE(metadata.isEmpty());
}
TEST_F(ControlTest, PopulateDynamic) {
uint8_t test_option = 99;
- EXPECT_CALL(*control_, GetValue(_))
+ EXPECT_CALL(*mock_delegate_, GetValue(_))
.WillOnce(DoAll(SetArgPointee<0>(test_option), Return(0)));
+ PrepareControl();
+
+ android::CameraMetadata metadata;
+ ASSERT_EQ(control_->PopulateDynamicFields(&metadata), 0);
+
+ // Should only have added 1 entry.
+ EXPECT_EQ(metadata.entryCount(), 1);
+ // Should have added the right entry.
+ ExpectMetadataEq(metadata, delegate_tag_, test_option);
+}
+
+TEST_F(ControlTest, PopulateDynamicNoOptions) {
+ // Lack of options shouldn't change anything for PopulateDynamic.
+ uint8_t test_option = 99;
+ EXPECT_CALL(*mock_delegate_, GetValue(_))
+ .WillOnce(DoAll(SetArgPointee<0>(test_option), Return(0)));
+ PrepareControl(false);
android::CameraMetadata metadata;
EXPECT_EQ(control_->PopulateDynamicFields(&metadata), 0);
@@ -83,12 +144,13 @@
// Should only have added 1 entry.
EXPECT_EQ(metadata.entryCount(), 1);
// Should have added the right entry.
- ExpectMetadataEq(metadata, control_tag_, test_option);
+ ExpectMetadataEq(metadata, delegate_tag_, test_option);
}
TEST_F(ControlTest, PopulateDynamicFail) {
int err = -99;
- EXPECT_CALL(*control_, GetValue(_)).WillOnce(Return(err));
+ EXPECT_CALL(*mock_delegate_, GetValue(_)).WillOnce(Return(err));
+ PrepareControl();
android::CameraMetadata metadata;
EXPECT_EQ(control_->PopulateDynamicFields(&metadata), err);
@@ -100,28 +162,31 @@
TEST_F(ControlTest, SupportsRequest) {
android::CameraMetadata metadata;
uint8_t test_option = 123;
- ASSERT_EQ(UpdateMetadata(&metadata, control_tag_, test_option), 0);
+ ASSERT_EQ(UpdateMetadata(&metadata, delegate_tag_, test_option), 0);
- EXPECT_CALL(*control_, IsSupported(test_option)).WillOnce(Return(true));
+ EXPECT_CALL(*mock_options_, IsSupported(test_option)).WillOnce(Return(true));
+ PrepareControl();
+
EXPECT_EQ(control_->SupportsRequestValues(metadata), true);
}
-TEST_F(ControlTest, ArraySupportsRequest) {
+TEST_F(ControlTest, SupportsRequestNoOptions) {
android::CameraMetadata metadata;
- std::array<uint8_t, 2> test_option = {{12, 34}};
- ASSERT_EQ(UpdateMetadata(&metadata, control_tag_, test_option), 0);
+ uint8_t test_option = 123;
+ ASSERT_EQ(UpdateMetadata(&metadata, delegate_tag_, test_option), 0);
+ PrepareControl(false);
- MockControl<std::array<uint8_t, 2>> test_control(control_tag_);
- EXPECT_CALL(test_control, IsSupported(test_option)).WillOnce(Return(true));
- EXPECT_EQ(test_control.SupportsRequestValues(metadata), true);
+ EXPECT_EQ(control_->SupportsRequestValues(metadata), true);
}
TEST_F(ControlTest, SupportsRequestFail) {
android::CameraMetadata metadata;
uint8_t test_option = 123;
- ASSERT_EQ(UpdateMetadata(&metadata, control_tag_, test_option), 0);
+ ASSERT_EQ(UpdateMetadata(&metadata, delegate_tag_, test_option), 0);
- EXPECT_CALL(*control_, IsSupported(test_option)).WillOnce(Return(false));
+ EXPECT_CALL(*mock_options_, IsSupported(test_option)).WillOnce(Return(false));
+ PrepareControl();
+
EXPECT_EQ(control_->SupportsRequestValues(metadata), false);
}
@@ -129,77 +194,140 @@
// Start with a request for multiple values.
android::CameraMetadata metadata;
std::vector<uint8_t> test_data = {1, 2, 3};
- ASSERT_EQ(UpdateMetadata(&metadata, control_tag_, test_data), 0);
+ ASSERT_EQ(UpdateMetadata(&metadata, delegate_tag_, test_data), 0);
+ PrepareControl();
EXPECT_EQ(control_->SupportsRequestValues(metadata), false);
}
-TEST_F(ControlTest, ArraySupportsRequestInvalidNumber) {
- // Start with a request for a single (non-array) value.
+TEST_F(ControlTest, SupportsRequestInvalidNumberNoOptions) {
+ // Start with a request for multiple values.
android::CameraMetadata metadata;
- uint8_t test_data = 1;
- ASSERT_EQ(UpdateMetadata(&metadata, control_tag_, test_data), 0);
-
- MockControl<std::array<uint8_t, 2>> test_control(control_tag_);
- EXPECT_EQ(test_control.SupportsRequestValues(metadata), false);
+ std::vector<uint8_t> test_data = {1, 2, 3};
+ ASSERT_EQ(UpdateMetadata(&metadata, delegate_tag_, test_data), 0);
+ PrepareControl(false);
+ // Not having any explicit options does not exempt a control
+ // from requiring the right number of values.
+ EXPECT_EQ(control_->SupportsRequestValues(metadata), false);
}
TEST_F(ControlTest, SupportsRequestEmpty) {
android::CameraMetadata metadata;
+ PrepareControl();
EXPECT_EQ(control_->SupportsRequestValues(metadata), true);
}
TEST_F(ControlTest, SetRequest) {
- android::CameraMetadata metadata(1);
+ android::CameraMetadata metadata;
uint8_t test_option = 123;
- ASSERT_EQ(UpdateMetadata(&metadata, control_tag_, test_option), 0);
+ ASSERT_EQ(UpdateMetadata(&metadata, delegate_tag_, test_option), 0);
- EXPECT_CALL(*control_, SetValue(test_option)).WillOnce(Return(0));
+ Expectation validation_check =
+ EXPECT_CALL(*mock_options_, IsSupported(test_option))
+ .WillOnce(Return(true));
+ EXPECT_CALL(*mock_delegate_, SetValue(test_option))
+ .After(validation_check)
+ .WillOnce(Return(0));
+ PrepareControl();
+
// Make the request.
ASSERT_EQ(control_->SetRequestValues(metadata), 0);
}
-TEST_F(ControlTest, ArraySetRequest) {
+TEST_F(ControlTest, SetRequestNoOptions) {
android::CameraMetadata metadata;
- std::array<uint8_t, 2> test_option = {{12, 34}};
- ASSERT_EQ(UpdateMetadata(&metadata, control_tag_, test_option), 0);
+ uint8_t test_option = 123;
+ ASSERT_EQ(UpdateMetadata(&metadata, delegate_tag_, test_option), 0);
- MockControl<std::array<uint8_t, 2>> test_control(control_tag_);
- EXPECT_CALL(test_control, SetValue(test_option)).WillOnce(Return(0));
- EXPECT_EQ(test_control.SetRequestValues(metadata), 0);
+ // No options, no validation check.
+ EXPECT_CALL(*mock_delegate_, SetValue(test_option)).WillOnce(Return(0));
+ PrepareControl(false);
+
+ // Make the request.
+ ASSERT_EQ(control_->SetRequestValues(metadata), 0);
}
-TEST_F(ControlTest, SetRequestFail) {
- android::CameraMetadata metadata(1);
+TEST_F(ControlTest, SetRequestSettingFail) {
+ android::CameraMetadata metadata;
uint8_t test_option = 123;
- ASSERT_EQ(UpdateMetadata(&metadata, control_tag_, test_option), 0);
+ ASSERT_EQ(UpdateMetadata(&metadata, delegate_tag_, test_option), 0);
- int err = -99;
- EXPECT_CALL(*control_, SetValue(test_option)).WillOnce(Return(err));
+ int err = 99;
+ Expectation validation_check =
+ EXPECT_CALL(*mock_options_, IsSupported(test_option))
+ .WillOnce(Return(true));
+ EXPECT_CALL(*mock_delegate_, SetValue(test_option))
+ .After(validation_check)
+ .WillOnce(Return(err));
+ PrepareControl();
+
EXPECT_EQ(control_->SetRequestValues(metadata), err);
}
+TEST_F(ControlTest, SetRequestValidationFail) {
+ android::CameraMetadata metadata;
+ uint8_t test_option = 123;
+ ASSERT_EQ(UpdateMetadata(&metadata, delegate_tag_, test_option), 0);
+
+ EXPECT_CALL(*mock_options_, IsSupported(test_option)).WillOnce(Return(false));
+ PrepareControl();
+
+ EXPECT_EQ(control_->SetRequestValues(metadata), -EINVAL);
+}
+
TEST_F(ControlTest, SetRequestInvalidNumber) {
// Start with a request for multiple values.
android::CameraMetadata metadata;
std::vector<uint8_t> test_data = {1, 2, 3};
- ASSERT_EQ(UpdateMetadata(&metadata, control_tag_, test_data), 0);
+ ASSERT_EQ(UpdateMetadata(&metadata, delegate_tag_, test_data), 0);
+
+ PrepareControl();
EXPECT_EQ(control_->SetRequestValues(metadata), -EINVAL);
}
-TEST_F(ControlTest, ArraySetRequestInvalidNumber) {
- // Start with a request for a single (non-array) value.
+TEST_F(ControlTest, SetRequestInvalidNumberNoOptions) {
+ // Start with a request for multiple values.
android::CameraMetadata metadata;
- uint8_t test_data = 1;
- ASSERT_EQ(UpdateMetadata(&metadata, control_tag_, test_data), 0);
+ std::vector<uint8_t> test_data = {1, 2, 3};
+ ASSERT_EQ(UpdateMetadata(&metadata, delegate_tag_, test_data), 0);
- MockControl<std::array<uint8_t, 2>> test_control(control_tag_);
- EXPECT_EQ(test_control.SetRequestValues(metadata), -EINVAL);
+ PrepareControl(false);
+ // Not having explicit options does not change that an incorrect
+ // number of values is invalid.
+ EXPECT_EQ(control_->SetRequestValues(metadata), -EINVAL);
}
TEST_F(ControlTest, SetRequestEmpty) {
// Should do nothing.
android::CameraMetadata metadata;
+ PrepareControl();
EXPECT_EQ(control_->SetRequestValues(metadata), 0);
}
+TEST_F(ControlTest, NoEffectMenuFactory) {
+ std::vector<uint8_t> test_options = {9, 8, 12};
+ std::unique_ptr<Control<uint8_t>> dut = Control<uint8_t>::NoEffectMenuControl(
+ delegate_tag_, options_tag_, test_options);
+ ASSERT_NE(dut, nullptr);
+
+ ASSERT_EQ(dut->StaticTags().size(), 1);
+ EXPECT_EQ(dut->StaticTags()[0], options_tag_);
+ // Controls use the same delgate, and thus tag, for getting and setting.
+ ASSERT_EQ(dut->ControlTags().size(), 1);
+ EXPECT_EQ(dut->ControlTags()[0], delegate_tag_);
+ ASSERT_EQ(dut->DynamicTags().size(), 1);
+ EXPECT_EQ(dut->DynamicTags()[0], delegate_tag_);
+
+ // Options should be available.
+ android::CameraMetadata metadata;
+ ASSERT_EQ(dut->PopulateStaticFields(&metadata), 0);
+ EXPECT_EQ(metadata.entryCount(), 1);
+ ExpectMetadataEq(metadata, options_tag_, test_options);
+
+ // Default value should be test_options[0].
+ metadata.clear();
+ ASSERT_EQ(dut->PopulateDynamicFields(&metadata), 0);
+ EXPECT_EQ(metadata.entryCount(), 1);
+ ExpectMetadataEq(metadata, delegate_tag_, test_options[0]);
+}
+
} // namespace v4l2_camera_hal
diff --git a/modules/camera/3_4/metadata/fixed_property.h b/modules/camera/3_4/metadata/fixed_property.h
deleted file mode 100644
index 31f7a82..0000000
--- a/modules/camera/3_4/metadata/fixed_property.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef V4L2_CAMERA_HAL_METADATA_FIXED_PROPERTY_H_
-#define V4L2_CAMERA_HAL_METADATA_FIXED_PROPERTY_H_
-
-#include "property.h"
-
-namespace v4l2_camera_hal {
-
-// A property with a fixed value set at creation.
-template <typename T>
-class FixedProperty : public Property<T> {
- public:
- FixedProperty(int32_t tag, T value)
- : Property<T>(tag), value_(std::move(value)){};
- virtual ~FixedProperty(){};
-
- private:
- virtual const T& Value() const override { return value_; };
-
- const T value_;
-};
-
-} // namespace v4l2_camera_hal
-
-#endif // V4L2_CAMERA_HAL_METADATA_FIXED_PROPERTY_H_
diff --git a/modules/camera/3_4/metadata/ignored_control.h b/modules/camera/3_4/metadata/ignored_control.h
deleted file mode 100644
index aea8988..0000000
--- a/modules/camera/3_4/metadata/ignored_control.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef V4L2_CAMERA_HAL_METADATA_IGNORED_CONTROL_H_
-#define V4L2_CAMERA_HAL_METADATA_IGNORED_CONTROL_H_
-
-#include <vector>
-
-#include <gtest/gtest_prod.h>
-
-#include "../common.h"
-#include "optioned_control.h"
-
-namespace v4l2_camera_hal {
-
-// A IgnoredControl is a PartialMetadata with a few static options that can
-// be chosen from, but they do nothing.
-template <typename T>
-class IgnoredControl : public OptionedControl<T> {
- public:
- IgnoredControl(int32_t control_tag,
- int32_t options_tag,
- std::vector<T> options,
- T default_option)
- : OptionedControl<T>(control_tag, options_tag, options),
- // Note: default option is not enforced as being in |options|,
- // but it may be confusing if it isn't.
- current_setting_(default_option) {
- HAL_LOG_ENTER();
- };
-
- protected:
- virtual int GetValue(T* value) const override {
- HAL_LOG_ENTER();
- *value = current_setting_;
- return 0;
- };
- virtual int SetValue(const T& value) override {
- HAL_LOG_ENTER();
- if (!OptionedControl<T>::IsSupported(value)) {
- return -EINVAL;
- }
- current_setting_ = value;
- return 0;
- };
-
- private:
- T current_setting_;
-
- FRIEND_TEST(IgnoredControlTest, GetDefaultValue);
- FRIEND_TEST(IgnoredControlTest, SetAndGetValue);
- FRIEND_TEST(IgnoredControlTest, SetAndGetBadValue);
- DISALLOW_COPY_AND_ASSIGN(IgnoredControl);
-};
-
-} // namespace v4l2_camera_hal
-
-#endif // V4L2_CAMERA_HAL_METADATA_IGNORED_CONTROL_H_
diff --git a/modules/camera/3_4/metadata/ignored_control_test.cpp b/modules/camera/3_4/metadata/ignored_control_test.cpp
deleted file mode 100644
index 04408d2..0000000
--- a/modules/camera/3_4/metadata/ignored_control_test.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "ignored_control.h"
-
-#include <array>
-
-#include <camera/CameraMetadata.h>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-#include "array_vector.h"
-
-using testing::AtMost;
-using testing::Return;
-using testing::ReturnRef;
-using testing::Test;
-using testing::_;
-
-namespace v4l2_camera_hal {
-
-class IgnoredControlTest : public Test {
- protected:
- IgnoredControlTest()
- : options_({ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF,
- ANDROID_COLOR_CORRECTION_ABERRATION_MODE_FAST,
- ANDROID_COLOR_CORRECTION_ABERRATION_MODE_HIGH_QUALITY}),
- default_option_(options_[2]) {}
-
- virtual void SetUp() {
- control_.reset(new IgnoredControl<uint8_t>(
- control_tag_, options_tag_, options_, default_option_));
- }
-
- std::unique_ptr<IgnoredControl<uint8_t>> control_;
-
- // Need tags that match the data type (uint8_t) being passed.
- static constexpr int32_t options_tag_ =
- ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES;
- static constexpr int32_t control_tag_ =
- ANDROID_COLOR_CORRECTION_ABERRATION_MODE;
-
- const std::vector<uint8_t> options_;
- const uint8_t default_option_;
-};
-
-TEST_F(IgnoredControlTest, Tags) {
- // The macro doesn't like the static variables
- // being passed directly to assertions.
- int32_t expected_tag = options_tag_;
- ASSERT_EQ(control_->StaticTags().size(), 1);
- EXPECT_EQ(control_->StaticTags()[0], expected_tag);
-
- // Controls use the same tag for getting and setting.
- expected_tag = control_tag_;
- ASSERT_EQ(control_->ControlTags().size(), 1);
- EXPECT_EQ(control_->ControlTags()[0], expected_tag);
- ASSERT_EQ(control_->DynamicTags().size(), 1);
- EXPECT_EQ(control_->DynamicTags()[0], expected_tag);
-}
-
-TEST_F(IgnoredControlTest, GetDefaultValue) {
- uint8_t value;
- EXPECT_EQ(control_->GetValue(&value), 0);
- EXPECT_EQ(value, default_option_);
-}
-
-TEST_F(IgnoredControlTest, SetAndGetValue) {
- uint8_t new_value = options_[0];
- // Make sure this isn't just testing overwriting the default with itself.
- ASSERT_NE(new_value, default_option_);
-
- EXPECT_EQ(control_->SetValue(new_value), 0);
- uint8_t result = new_value + 1; // Initialize to something incorrect.
- EXPECT_EQ(control_->GetValue(&result), 0);
- EXPECT_EQ(result, new_value);
-}
-
-TEST_F(IgnoredControlTest, SetAndGetBadValue) {
- uint8_t unsupported_value = 99;
- // Make sure this is actually unsupported
- ASSERT_FALSE(control_->IsSupported(unsupported_value));
-
- EXPECT_EQ(control_->SetValue(unsupported_value), -EINVAL);
- // Value shouldn't have changed.
- uint8_t result = default_option_ + 1; // Initialize to something incorrect.
- EXPECT_EQ(control_->GetValue(&result), 0);
- EXPECT_EQ(result, default_option_);
-}
-
-} // namespace v4l2_camera_hal
diff --git a/modules/camera/3_4/metadata/metadata.cpp b/modules/camera/3_4/metadata/metadata.cpp
index 61336fe..e18a454 100644
--- a/modules/camera/3_4/metadata/metadata.cpp
+++ b/modules/camera/3_4/metadata/metadata.cpp
@@ -19,6 +19,7 @@
#include <camera/CameraMetadata.h>
#include "../common.h"
+#include "metadata_common.h"
namespace v4l2_camera_hal {
@@ -64,35 +65,38 @@
}
// Note what tags the component adds.
- const std::vector<int32_t>* tags = &component->StaticTags();
- static_tags.insert(static_tags.end(), tags->begin(), tags->end());
- tags = &component->ControlTags();
- control_tags.insert(control_tags.end(), tags->begin(), tags->end());
- tags = &component->DynamicTags();
- dynamic_tags.insert(dynamic_tags.end(), tags->begin(), tags->end());
+ std::vector<int32_t> tags = component->StaticTags();
+ std::move(tags.begin(),
+ tags.end(),
+ std::inserter(static_tags, static_tags.end()));
+ tags = component->ControlTags();
+ std::move(tags.begin(),
+ tags.end(),
+ std::inserter(control_tags, control_tags.end()));
+ tags = component->DynamicTags();
+ std::move(tags.begin(),
+ tags.end(),
+ std::inserter(dynamic_tags, dynamic_tags.end()));
}
// Populate the meta fields.
static_tags.push_back(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS);
- res = metadata->update(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS,
- control_tags.data(),
- control_tags.size());
+ res = UpdateMetadata(
+ metadata, ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS, control_tags);
if (res != android::OK) {
HAL_LOGE("Failed to add request keys meta key.");
return -ENODEV;
}
static_tags.push_back(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS);
- res = metadata->update(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS,
- dynamic_tags.data(),
- dynamic_tags.size());
+ res = UpdateMetadata(
+ metadata, ANDROID_REQUEST_AVAILABLE_RESULT_KEYS, dynamic_tags);
if (res != android::OK) {
HAL_LOGE("Failed to add result keys meta key.");
return -ENODEV;
}
static_tags.push_back(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS);
- res = metadata->update(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS,
- static_tags.data(),
- static_tags.size());
+ res = UpdateMetadata(
+ metadata, ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, static_tags);
if (res != android::OK) {
HAL_LOGE("Failed to add characteristics keys meta key.");
return -ENODEV;
diff --git a/modules/camera/3_4/metadata/metadata_test.cpp b/modules/camera/3_4/metadata/metadata_test.cpp
index 62bb565..3ea94ba 100644
--- a/modules/camera/3_4/metadata/metadata_test.cpp
+++ b/modules/camera/3_4/metadata/metadata_test.cpp
@@ -28,7 +28,6 @@
using testing::AtMost;
using testing::Return;
-using testing::ReturnRef;
using testing::Test;
using testing::_;
@@ -88,12 +87,12 @@
std::vector<int32_t> control_tags_2({7, 8});
std::vector<int32_t> dynamic_tags_1({9, 10});
std::vector<int32_t> dynamic_tags_2({11, 12});
- EXPECT_CALL(*component1_, StaticTags()).WillOnce(ReturnRef(static_tags_1));
- EXPECT_CALL(*component1_, ControlTags()).WillOnce(ReturnRef(control_tags_1));
- EXPECT_CALL(*component1_, DynamicTags()).WillOnce(ReturnRef(dynamic_tags_1));
- EXPECT_CALL(*component2_, StaticTags()).WillOnce(ReturnRef(static_tags_2));
- EXPECT_CALL(*component2_, ControlTags()).WillOnce(ReturnRef(control_tags_2));
- EXPECT_CALL(*component2_, DynamicTags()).WillOnce(ReturnRef(dynamic_tags_2));
+ EXPECT_CALL(*component1_, StaticTags()).WillOnce(Return(static_tags_1));
+ EXPECT_CALL(*component1_, ControlTags()).WillOnce(Return(control_tags_1));
+ EXPECT_CALL(*component1_, DynamicTags()).WillOnce(Return(dynamic_tags_1));
+ EXPECT_CALL(*component2_, StaticTags()).WillOnce(Return(static_tags_2));
+ EXPECT_CALL(*component2_, ControlTags()).WillOnce(Return(control_tags_2));
+ EXPECT_CALL(*component2_, DynamicTags()).WillOnce(Return(dynamic_tags_2));
AddComponents();
// Should succeed. If it didn't, no reason to continue checking output.
@@ -137,22 +136,22 @@
// May or may not exit early, may still try to populate meta tags.
EXPECT_CALL(*component1_, StaticTags())
.Times(AtMost(1))
- .WillOnce(ReturnRef(empty_tags_));
+ .WillOnce(Return(empty_tags_));
EXPECT_CALL(*component1_, ControlTags())
.Times(AtMost(1))
- .WillOnce(ReturnRef(empty_tags_));
+ .WillOnce(Return(empty_tags_));
EXPECT_CALL(*component1_, DynamicTags())
.Times(AtMost(1))
- .WillOnce(ReturnRef(empty_tags_));
+ .WillOnce(Return(empty_tags_));
EXPECT_CALL(*component2_, StaticTags())
.Times(AtMost(1))
- .WillOnce(ReturnRef(empty_tags_));
+ .WillOnce(Return(empty_tags_));
EXPECT_CALL(*component2_, ControlTags())
.Times(AtMost(1))
- .WillOnce(ReturnRef(empty_tags_));
+ .WillOnce(Return(empty_tags_));
EXPECT_CALL(*component2_, DynamicTags())
.Times(AtMost(1))
- .WillOnce(ReturnRef(empty_tags_));
+ .WillOnce(Return(empty_tags_));
AddComponents();
// If any component errors, error should be returned
diff --git a/modules/camera/3_4/metadata/optioned_control.h b/modules/camera/3_4/metadata/optioned_control.h
deleted file mode 100644
index e205a59..0000000
--- a/modules/camera/3_4/metadata/optioned_control.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef V4L2_CAMERA_HAL_METADATA_OPTIONED_CONTROL_H_
-#define V4L2_CAMERA_HAL_METADATA_OPTIONED_CONTROL_H_
-
-#include <algorithm>
-#include <vector>
-
-#include <gtest/gtest_prod.h>
-
-#include "../common.h"
-#include "control.h"
-#include "metadata_common.h"
-
-namespace v4l2_camera_hal {
-
-// An OptionedControl is a Control with a fixed list of options that can be
-// selected from.
-template <typename T>
-class OptionedControl : public Control<T> {
- public:
- OptionedControl(int32_t control_tag,
- int32_t options_tag,
- std::vector<T> options);
-
- virtual int PopulateStaticFields(
- android::CameraMetadata* metadata) const override;
-
- protected:
- // Simpler access to tag.
- inline int32_t OptionsTag() const { return Control<T>::StaticTags()[0]; }
-
- // Child classes still need to implement Get/Set from Control.
- virtual bool IsSupported(const T& val) const override;
-
- private:
- const std::vector<T> options_;
-
- FRIEND_TEST(OptionedControlTest, IsSupported);
-
- DISALLOW_COPY_AND_ASSIGN(OptionedControl);
-};
-
-// -----------------------------------------------------------------------------
-
-template <typename T>
-OptionedControl<T>::OptionedControl(int32_t control_tag,
- int32_t options_tag,
- std::vector<T> options)
- : Control<T>(control_tag, {options_tag}), options_(std::move(options)) {
- HAL_LOG_ENTER();
-}
-
-template <typename T>
-int OptionedControl<T>::PopulateStaticFields(
- android::CameraMetadata* metadata) const {
- HAL_LOG_ENTER();
-
- // Populate the available options.
- return UpdateMetadata(metadata, OptionsTag(), options_);
-}
-
-template <typename T>
-bool OptionedControl<T>::IsSupported(const T& value) const {
- return (std::find(options_.begin(), options_.end(), value) != options_.end());
-}
-
-} // namespace v4l2_camera_hal
-
-#endif // V4L2_CAMERA_HAL_METADATA_OPTIONED_CONTROL_H_
diff --git a/modules/camera/3_4/metadata/optioned_control_test.cpp b/modules/camera/3_4/metadata/optioned_control_test.cpp
deleted file mode 100644
index bd9b705..0000000
--- a/modules/camera/3_4/metadata/optioned_control_test.cpp
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "optioned_control.h"
-
-#include <camera/CameraMetadata.h>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-#include "test_common.h"
-
-using testing::AtMost;
-using testing::Return;
-using testing::ReturnRef;
-using testing::Test;
-using testing::_;
-
-namespace v4l2_camera_hal {
-
-class OptionedControlTest : public Test {
- protected:
- // A subclass of OptionedControl with the pure virtual methods mocked out.
- template <typename T>
- class MockOptionedControl : public OptionedControl<T> {
- public:
- MockOptionedControl(int32_t control_tag,
- int32_t options_tag,
- std::vector<T> options)
- : OptionedControl<T>(control_tag, options_tag, options){};
- MOCK_CONST_METHOD1_T(GetValue, int(T* value));
- MOCK_METHOD1_T(SetValue, int(const T& value));
- };
-
- OptionedControlTest()
- : options_({ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF,
- ANDROID_COLOR_CORRECTION_ABERRATION_MODE_FAST,
- ANDROID_COLOR_CORRECTION_ABERRATION_MODE_HIGH_QUALITY}) {}
-
- virtual void SetUp() {
- control_.reset(
- new MockOptionedControl<uint8_t>(control_tag_, options_tag_, options_));
- }
-
- std::unique_ptr<OptionedControl<uint8_t>> control_;
-
- // Need tags that match the data type (uint8_t) being passed.
- static constexpr int32_t options_tag_ =
- ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES;
- static constexpr int32_t control_tag_ =
- ANDROID_COLOR_CORRECTION_ABERRATION_MODE;
-
- const std::vector<uint8_t> options_;
-};
-
-TEST_F(OptionedControlTest, Tags) {
- // The macro doesn't like the static variables
- // being passed directly to assertions.
- int32_t expected_tag = options_tag_;
- ASSERT_EQ(control_->StaticTags().size(), 1);
- EXPECT_EQ(control_->StaticTags()[0], expected_tag);
-
- // Controls use the same tag for getting and setting.
- expected_tag = control_tag_;
- ASSERT_EQ(control_->ControlTags().size(), 1);
- EXPECT_EQ(control_->ControlTags()[0], expected_tag);
- ASSERT_EQ(control_->DynamicTags().size(), 1);
- EXPECT_EQ(control_->DynamicTags()[0], expected_tag);
-}
-
-TEST_F(OptionedControlTest, PopulateStatic) {
- // Populate static fields.
- android::CameraMetadata metadata;
- ASSERT_EQ(control_->PopulateStaticFields(&metadata), 0);
-
- // Check the results.
- // Should only have added 1 entry.
- EXPECT_EQ(metadata.entryCount(), 1);
- // Should have added the right entry.
- ExpectMetadataEq(metadata, options_tag_, options_);
-}
-
-TEST_F(OptionedControlTest, IsSupported) {
- for (auto option : options_) {
- EXPECT_TRUE(control_->IsSupported(option));
- }
- // And at least one unsupported.
- EXPECT_FALSE(control_->IsSupported(99));
-}
-
-} // namespace v4l2_camera_hal
diff --git a/modules/camera/3_4/metadata/partial_metadata_interface.h b/modules/camera/3_4/metadata/partial_metadata_interface.h
index d1a434f..cc1f9db 100644
--- a/modules/camera/3_4/metadata/partial_metadata_interface.h
+++ b/modules/camera/3_4/metadata/partial_metadata_interface.h
@@ -34,9 +34,9 @@
// The metadata tags this partial metadata is responsible for.
// See system/media/camera/docs/docs.html for descriptions of each tag.
- virtual const std::vector<int32_t>& StaticTags() const = 0;
- virtual const std::vector<int32_t>& ControlTags() const = 0;
- virtual const std::vector<int32_t>& DynamicTags() const = 0;
+ virtual std::vector<int32_t> StaticTags() const = 0;
+ virtual std::vector<int32_t> ControlTags() const = 0;
+ virtual std::vector<int32_t> DynamicTags() const = 0;
// Add all the static properties this partial metadata
// is responsible for to |metadata|.
diff --git a/modules/camera/3_4/metadata/partial_metadata_interface_mock.h b/modules/camera/3_4/metadata/partial_metadata_interface_mock.h
index 63b24db..e380dee 100644
--- a/modules/camera/3_4/metadata/partial_metadata_interface_mock.h
+++ b/modules/camera/3_4/metadata/partial_metadata_interface_mock.h
@@ -28,9 +28,9 @@
class PartialMetadataInterfaceMock : public PartialMetadataInterface {
public:
PartialMetadataInterfaceMock() : PartialMetadataInterface(){};
- MOCK_CONST_METHOD0(StaticTags, const std::vector<int32_t>&());
- MOCK_CONST_METHOD0(ControlTags, const std::vector<int32_t>&());
- MOCK_CONST_METHOD0(DynamicTags, const std::vector<int32_t>&());
+ MOCK_CONST_METHOD0(StaticTags, std::vector<int32_t>());
+ MOCK_CONST_METHOD0(ControlTags, std::vector<int32_t>());
+ MOCK_CONST_METHOD0(DynamicTags, std::vector<int32_t>());
MOCK_CONST_METHOD1(PopulateStaticFields,
int(android::CameraMetadata* metadata));
MOCK_CONST_METHOD1(PopulateDynamicFields,
diff --git a/modules/camera/3_4/metadata/property.h b/modules/camera/3_4/metadata/property.h
index a3ed6bf..1ddd20f 100644
--- a/modules/camera/3_4/metadata/property.h
+++ b/modules/camera/3_4/metadata/property.h
@@ -19,20 +19,26 @@
#include "../common.h"
#include "metadata_common.h"
-#include "tagged_partial_metadata.h"
+#include "partial_metadata_interface.h"
namespace v4l2_camera_hal {
// A Property is a PartialMetadata that only has a single static tag.
template <typename T>
-class Property : public TaggedPartialMetadata {
+class Property : public PartialMetadataInterface {
public:
- Property(int32_t tag) : TaggedPartialMetadata({tag}, {}, {}){};
+ Property(int32_t tag, T value) : tag_(tag), value_(value){};
+
+ virtual std::vector<int32_t> StaticTags() const override { return {tag_}; };
+
+ virtual std::vector<int32_t> ControlTags() const override { return {}; };
+
+ virtual std::vector<int32_t> DynamicTags() const override { return {}; };
virtual int PopulateStaticFields(
android::CameraMetadata* metadata) const override {
HAL_LOG_ENTER();
- return UpdateMetadata(metadata, Tag(), Value());
+ return UpdateMetadata(metadata, tag_, value_);
};
virtual int PopulateDynamicFields(
@@ -53,11 +59,9 @@
return 0;
};
- protected:
- // Simpler access to tag.
- inline int32_t Tag() const { return StaticTags()[0]; }
- // Get the value associated with this property.
- virtual const T& Value() const = 0;
+ private:
+ int32_t tag_;
+ T value_;
};
} // namespace v4l2_camera_hal
diff --git a/modules/camera/3_4/metadata/fixed_property_test.cpp b/modules/camera/3_4/metadata/property_test.cpp
similarity index 80%
rename from modules/camera/3_4/metadata/fixed_property_test.cpp
rename to modules/camera/3_4/metadata/property_test.cpp
index 07a1bce..50b9d4c 100644
--- a/modules/camera/3_4/metadata/fixed_property_test.cpp
+++ b/modules/camera/3_4/metadata/property_test.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include "fixed_property.h"
+#include "property.h"
#include <array>
#include <vector>
@@ -35,7 +35,7 @@
namespace v4l2_camera_hal {
-class FixedPropertyTest : public Test {
+class PropertyTest : public Test {
protected:
// Need tags that match the data types being passed.
static constexpr int32_t byte_tag_ = ANDROID_CONTROL_SCENE_MODE_OVERRIDES;
@@ -44,8 +44,8 @@
static constexpr int32_t int_tag2_ = ANDROID_JPEG_ORIENTATION;
};
-TEST_F(FixedPropertyTest, Tags) {
- FixedProperty<int32_t> property(int_tag_, 1);
+TEST_F(PropertyTest, Tags) {
+ Property<int32_t> property(int_tag_, 1);
// Should have only the single tag it was constructed with.
EXPECT_EQ(property.ControlTags().size(), 0);
@@ -56,10 +56,10 @@
EXPECT_EQ(property.StaticTags()[0], expected_tag);
}
-TEST_F(FixedPropertyTest, PopulateStaticSingleNumber) {
+TEST_F(PropertyTest, PopulateStaticSingleNumber) {
// Set up a fixed property.
int32_t data = 1234;
- FixedProperty<int32_t> property(int_tag_, data);
+ Property<int32_t> property(int_tag_, data);
// Populate static fields.
android::CameraMetadata metadata;
@@ -72,10 +72,12 @@
ExpectMetadataEq(metadata, int_tag_, data);
}
-TEST_F(FixedPropertyTest, PopulateStaticVector) {
+// TODO(b/30839858): These tests are really testing the metadata_common.h
+// UpdateMetadata methods, and shouldn't be conducted here.
+TEST_F(PropertyTest, PopulateStaticVector) {
// Set up a fixed property.
std::vector<float> data({0.1, 2.3, 4.5, 6.7});
- FixedProperty<std::vector<float>> property(float_tag_, data);
+ Property<std::vector<float>> property(float_tag_, data);
// Populate static fields.
android::CameraMetadata metadata;
@@ -88,10 +90,10 @@
ExpectMetadataEq(metadata, float_tag_, data);
}
-TEST_F(FixedPropertyTest, PopulateStaticArray) {
+TEST_F(PropertyTest, PopulateStaticArray) {
// Set up a fixed property.
std::array<float, 4> data({{0.1, 2.3, 4.5, 6.7}});
- FixedProperty<std::array<float, 4>> property(float_tag_, data);
+ Property<std::array<float, 4>> property(float_tag_, data);
// Populate static fields.
android::CameraMetadata metadata;
@@ -104,12 +106,12 @@
ExpectMetadataEq(metadata, float_tag_, data);
}
-TEST_F(FixedPropertyTest, PopulateStaticArrayVector) {
+TEST_F(PropertyTest, PopulateStaticArrayVector) {
// Set up a fixed property.
ArrayVector<uint8_t, 3> data;
data.push_back({{1, 2, 3}});
data.push_back({{4, 5, 6}});
- FixedProperty<ArrayVector<uint8_t, 3>> property(byte_tag_, data);
+ Property<ArrayVector<uint8_t, 3>> property(byte_tag_, data);
// Populate static fields.
android::CameraMetadata metadata;
@@ -122,8 +124,8 @@
ExpectMetadataEq(metadata, byte_tag_, data);
}
-TEST_F(FixedPropertyTest, PopulateDynamic) {
- FixedProperty<int32_t> property(int_tag_, 1);
+TEST_F(PropertyTest, PopulateDynamic) {
+ Property<int32_t> property(int_tag_, 1);
android::CameraMetadata metadata;
EXPECT_EQ(property.PopulateDynamicFields(&metadata), 0);
@@ -132,14 +134,14 @@
EXPECT_TRUE(metadata.isEmpty());
}
-TEST_F(FixedPropertyTest, SupportsRequest) {
- FixedProperty<int32_t> property(int_tag_, 1);
+TEST_F(PropertyTest, SupportsRequest) {
+ Property<int32_t> property(int_tag_, 1);
android::CameraMetadata metadata;
EXPECT_EQ(property.SupportsRequestValues(metadata), true);
}
-TEST_F(FixedPropertyTest, SetRequest) {
- FixedProperty<int32_t> property(int_tag_, 1);
+TEST_F(PropertyTest, SetRequest) {
+ Property<int32_t> property(int_tag_, 1);
android::CameraMetadata metadata;
EXPECT_EQ(property.SetRequestValues(metadata), 0);
}
diff --git a/modules/camera/3_4/metadata/tagged_partial_metadata.h b/modules/camera/3_4/metadata/tagged_partial_metadata.h
deleted file mode 100644
index 0e02c06..0000000
--- a/modules/camera/3_4/metadata/tagged_partial_metadata.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef V4L2_CAMERA_HAL_METADATA_TAGGED_PARTIAL_METADATA_H_
-#define V4L2_CAMERA_HAL_METADATA_TAGGED_PARTIAL_METADATA_H_
-
-#include "partial_metadata_interface.h"
-
-namespace v4l2_camera_hal {
-
-// A simple base class for PartialMetadataInterfaces that tracks tags.
-class TaggedPartialMetadata : public PartialMetadataInterface {
- public:
- TaggedPartialMetadata(std::vector<int32_t> static_tags,
- std::vector<int32_t> control_tags,
- std::vector<int32_t> dynamic_tags)
- : static_tags_(std::move(static_tags)),
- control_tags_(std::move(control_tags)),
- dynamic_tags_(std::move(dynamic_tags)){};
- virtual ~TaggedPartialMetadata(){};
-
- virtual const std::vector<int32_t>& StaticTags() const override {
- return static_tags_;
- };
-
- virtual const std::vector<int32_t>& ControlTags() const override {
- return control_tags_;
- };
-
- virtual const std::vector<int32_t>& DynamicTags() const override {
- return dynamic_tags_;
- };
-
- // Child classes still need to override the Populate/Supported/Set methods.
-
- private:
- const std::vector<int32_t> static_tags_;
- const std::vector<int32_t> control_tags_;
- const std::vector<int32_t> dynamic_tags_;
-};
-
-} // namespace v4l2_camera_hal
-
-#endif // V4L2_CAMERA_HAL_METADATA_TAGGED_PARTIAL_METADATA_H_
diff --git a/modules/camera/3_4/metadata/v4l2_enum_control.cpp b/modules/camera/3_4/metadata/v4l2_enum_control.cpp
deleted file mode 100644
index 9968b0b..0000000
--- a/modules/camera/3_4/metadata/v4l2_enum_control.cpp
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "v4l2_enum_control.h"
-
-#include "../common.h"
-
-namespace v4l2_camera_hal {
-
-V4L2EnumControl* V4L2EnumControl::NewV4L2EnumControl(
- std::shared_ptr<V4L2Wrapper> device,
- int v4l2_control,
- int32_t control_tag,
- int32_t options_tag,
- const std::map<int32_t, uint8_t>& v4l2_to_metadata) {
- HAL_LOG_ENTER();
-
- // Query the device.
- v4l2_query_ext_ctrl control_query;
- int res = device->QueryControl(v4l2_control, &control_query);
- if (res) {
- HAL_LOGE("Failed to query control %d.", v4l2_control);
- return nullptr;
- }
- if (control_query.type != V4L2_CTRL_TYPE_MENU &&
- control_query.type != V4L2_CTRL_TYPE_BOOLEAN) {
- HAL_LOGE(
- "Enum controls can only be constructed from V4L2 menu and boolean "
- "controls (%d is of type %d)",
- v4l2_control,
- control_query.type);
- return nullptr;
- }
-
- // Convert device options to metadata options.
- std::vector<uint8_t> options;
- int32_t control_max = static_cast<int32_t>(control_query.maximum);
- // Query maximum is inclusive.
- for (int32_t i = static_cast<int32_t>(control_query.minimum);
- i <= control_max;
- i += control_query.step) {
- auto map_entry = v4l2_to_metadata.find(i);
- if (map_entry == v4l2_to_metadata.end()) {
- HAL_LOGW("Control %d has unknown option %d.", v4l2_control, i);
- } else {
- options.push_back(map_entry->second);
- }
- }
- if (options.empty()) {
- HAL_LOGE("No supported options for control %d.", v4l2_control);
- return nullptr;
- }
-
- // Construct the device.
- return new V4L2EnumControl(device,
- v4l2_control,
- control_tag,
- options_tag,
- std::move(v4l2_to_metadata),
- std::move(options));
-}
-
-V4L2EnumControl::V4L2EnumControl(
- std::shared_ptr<V4L2Wrapper> device,
- int v4l2_control,
- int32_t control_tag,
- int32_t options_tag,
- const std::map<int32_t, uint8_t> v4l2_to_metadata,
- std::vector<uint8_t> options)
- : OptionedControl<uint8_t>(control_tag, options_tag, std::move(options)),
- device_(device),
- v4l2_control_(v4l2_control),
- v4l2_to_metadata_(std::move(v4l2_to_metadata)) {
- HAL_LOG_ENTER();
-}
-
-int V4L2EnumControl::GetValue(uint8_t* value) const {
- HAL_LOG_ENTER();
-
- // Query the device for V4L2 value.
- int32_t v4l2_value = 0;
- int res = device_->GetControl(v4l2_control_, &v4l2_value);
- if (res) {
- HAL_LOGE("Failed to get value for control %d from device.", v4l2_control_);
- return res;
- }
-
- // Convert to metadata value.
- auto metadata_element = v4l2_to_metadata_.find(v4l2_value);
- if (metadata_element == v4l2_to_metadata_.end()) {
- HAL_LOGE("Unknown value %d for control %d.", v4l2_value, v4l2_control_);
- return -ENODEV;
- }
- *value = metadata_element->second;
- return 0;
-}
-
-int V4L2EnumControl::SetValue(const uint8_t& value) {
- HAL_LOG_ENTER();
-
- if (!IsSupported(value)) {
- HAL_LOGE("Invalid control value %d.", value);
- return -EINVAL;
- }
-
- // Convert to V4L2 value by doing an inverse lookup in the map.
- bool found = false;
- int32_t v4l2_value = -1;
- for (auto kv : v4l2_to_metadata_) {
- if (kv.second == value) {
- v4l2_value = kv.first;
- found = true;
- break;
- }
- }
- if (!found) {
- HAL_LOGE("Couldn't find V4L2 conversion of valid control value %d.", value);
- return -ENODEV;
- }
-
- return device_->SetControl(v4l2_control_, v4l2_value);
-}
-
-} // namespace v4l2_camera_hal
diff --git a/modules/camera/3_4/metadata/v4l2_enum_control.h b/modules/camera/3_4/metadata/v4l2_enum_control.h
deleted file mode 100644
index f4027b8..0000000
--- a/modules/camera/3_4/metadata/v4l2_enum_control.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef V4L2_CAMERA_HAL_METADATA_V4L2_ENUM_CONTROL_H_
-#define V4L2_CAMERA_HAL_METADATA_V4L2_ENUM_CONTROL_H_
-
-#include <map>
-#include <memory>
-#include <vector>
-
-#include <gtest/gtest_prod.h>
-
-#include "../v4l2_wrapper.h"
-#include "optioned_control.h"
-
-namespace v4l2_camera_hal {
-
-// A V4L2EnumControl is a direct mapping between a V4L2 control
-// and an Android metadata control.
-class V4L2EnumControl : public OptionedControl<uint8_t> {
- public:
- // Use this method to create V4L2EnumControl objects.
- // Functionally equivalent to "new V4L2EnumControl"
- // except that it may return nullptr in case of failure.
- static V4L2EnumControl* NewV4L2EnumControl(
- std::shared_ptr<V4L2Wrapper> device,
- int v4l2_control,
- int32_t control_tag,
- int32_t options_tag,
- const std::map<int32_t, uint8_t>& v4l2_to_metadata);
-
- private:
- // Constructor private to allow failing on bad input.
- // Use NewV4L2EnumControl instead.
- // The values in |v4l2_to_metadata| must be a superset of |options|.
- V4L2EnumControl(std::shared_ptr<V4L2Wrapper> device,
- int v4l2_control,
- int32_t control_tag,
- int32_t options_tag,
- const std::map<int32_t, uint8_t> v4l2_to_metadata,
- std::vector<uint8_t> options);
-
- virtual int GetValue(uint8_t* value) const override;
- virtual int SetValue(const uint8_t& value) override;
-
- std::shared_ptr<V4L2Wrapper> device_;
- const int v4l2_control_;
- const std::map<int32_t, uint8_t> v4l2_to_metadata_;
-
- FRIEND_TEST(V4L2EnumControlTest, SetValue);
- FRIEND_TEST(V4L2EnumControlTest, SetValueFail);
- FRIEND_TEST(V4L2EnumControlTest, SetInvalidValue);
- FRIEND_TEST(V4L2EnumControlTest, SetUnmapped);
- FRIEND_TEST(V4L2EnumControlTest, GetValue);
- FRIEND_TEST(V4L2EnumControlTest, GetValueFail);
- FRIEND_TEST(V4L2EnumControlTest, GetUnmapped);
- friend class V4L2EnumControlTest; // Access to private constructor.
-
- DISALLOW_COPY_AND_ASSIGN(V4L2EnumControl);
-};
-
-} // namespace v4l2_camera_hal
-
-#endif // V4L2_CAMERA_HAL_METADATA_V4L2_ENUM_CONTROL_H_
diff --git a/modules/camera/3_4/metadata/v4l2_enum_control_test.cpp b/modules/camera/3_4/metadata/v4l2_enum_control_test.cpp
deleted file mode 100644
index 05257c8..0000000
--- a/modules/camera/3_4/metadata/v4l2_enum_control_test.cpp
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "v4l2_enum_control.h"
-
-#include <array>
-
-#include <camera/CameraMetadata.h>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-#include "../v4l2_wrapper_mock.h"
-#include "array_vector.h"
-#include "test_common.h"
-
-using testing::AtMost;
-using testing::Return;
-using testing::SetArgPointee;
-using testing::Test;
-using testing::_;
-
-namespace v4l2_camera_hal {
-
-class V4L2EnumControlTest : public Test {
- protected:
- V4L2EnumControlTest()
- : options_({10, 20, 30, 50}), // Subset of the full map.
- options_map_(
- {{0, 0}, {1, 10}, {2, 20}, {3, 30}, {4, 40}, {5, 50}, {6, 60}}) {}
-
- virtual void SetUp() {
- device_.reset(new V4L2WrapperMock());
- control_.reset(new V4L2EnumControl(device_,
- v4l2_control_,
- control_tag_,
- options_tag_,
- options_map_,
- options_));
- }
-
- virtual uint8_t V4L2ToMetadata(int32_t value) {
- return options_map_.at(value);
- }
-
- virtual int32_t MetadataToV4L2(uint8_t value) {
- for (auto kv : options_map_) {
- if (kv.second == value) {
- return kv.first;
- }
- }
- return -1;
- }
-
- std::unique_ptr<V4L2EnumControl> control_;
- std::shared_ptr<V4L2WrapperMock> device_;
-
- static constexpr int v4l2_control_ = 123;
- // Need tags that match the data type (uint8_t) being passed.
- static constexpr int32_t options_tag_ = ANDROID_CONTROL_AVAILABLE_SCENE_MODES;
- static constexpr int32_t control_tag_ = ANDROID_CONTROL_SCENE_MODE;
-
- const std::vector<uint8_t> options_;
- const std::map<int32_t, uint8_t> options_map_;
-};
-
-TEST_F(V4L2EnumControlTest, NewV4L2EnumSuccess) {
- // Should query the device.
- v4l2_query_ext_ctrl query_result;
- query_result.type = V4L2_CTRL_TYPE_MENU;
- query_result.minimum = 1;
- query_result.maximum = 7;
- query_result.step = 2;
- EXPECT_CALL(*device_, QueryControl(v4l2_control_, _))
- .WillOnce(DoAll(SetArgPointee<1>(query_result), Return(0)));
-
- std::unique_ptr<V4L2EnumControl> test_control(
- V4L2EnumControl::NewV4L2EnumControl(
- device_, v4l2_control_, control_tag_, options_tag_, options_map_));
- // Shouldn't be null.
- ASSERT_NE(test_control.get(), nullptr);
-
- // Should pass through tags.
- // The macro doesn't like the static variables
- // being passed directly to assertions.
- int32_t expected_tag = options_tag_;
- ASSERT_EQ(test_control->StaticTags().size(), 1);
- EXPECT_EQ(test_control->StaticTags()[0], expected_tag);
- // Controls use the same tag for getting and setting.
- expected_tag = control_tag_;
- ASSERT_EQ(test_control->ControlTags().size(), 1);
- EXPECT_EQ(test_control->ControlTags()[0], expected_tag);
- ASSERT_EQ(test_control->DynamicTags().size(), 1);
- EXPECT_EQ(test_control->DynamicTags()[0], expected_tag);
-
- // Should populate the options according to capabilities returned.
- android::CameraMetadata metadata;
- ASSERT_EQ(test_control->PopulateStaticFields(&metadata), 0);
- // Min 1, max 7, step 2 means {1,3,5} converted to metadata values.
- // There is no 7 in the map, so it shouldn't be present.
- std::vector<uint8_t> expected_options;
- expected_options.push_back(V4L2ToMetadata(1));
- expected_options.push_back(V4L2ToMetadata(3));
- expected_options.push_back(V4L2ToMetadata(5));
- ExpectMetadataEq(metadata, options_tag_, expected_options);
-}
-
-TEST_F(V4L2EnumControlTest, NewV4L2EnumFailed) {
- // Querying the device fails.
- int err = -99;
- EXPECT_CALL(*device_, QueryControl(v4l2_control_, _)).WillOnce(Return(err));
-
- std::unique_ptr<V4L2EnumControl> test_control(
- V4L2EnumControl::NewV4L2EnumControl(
- device_, v4l2_control_, control_tag_, options_tag_, options_map_));
- // Should return null to indicate error.
- ASSERT_EQ(test_control.get(), nullptr);
-}
-
-TEST_F(V4L2EnumControlTest, NewV4L2EnumInvalid) {
- // Control type is not supported.
- v4l2_query_ext_ctrl query_result;
- query_result.type = V4L2_CTRL_TYPE_INTEGER;
- query_result.minimum = 1;
- query_result.maximum = 5;
- query_result.step = 2;
- EXPECT_CALL(*device_, QueryControl(v4l2_control_, _))
- .WillOnce(DoAll(SetArgPointee<1>(query_result), Return(0)));
-
- std::unique_ptr<V4L2EnumControl> test_control(
- V4L2EnumControl::NewV4L2EnumControl(
- device_, v4l2_control_, control_tag_, options_tag_, options_map_));
- // Should return null to indicate error.
- ASSERT_FALSE(test_control);
-}
-
-TEST_F(V4L2EnumControlTest, SetValue) {
- // Should go through the device.
- uint8_t val = options_[1];
- EXPECT_CALL(*device_, SetControl(v4l2_control_, MetadataToV4L2(val), _))
- .WillOnce(Return(0));
- EXPECT_EQ(control_->SetValue(val), 0);
-}
-
-TEST_F(V4L2EnumControlTest, SetValueFail) {
- // Should go through the device but fail.
- uint8_t val = options_[1];
- int err = -99;
- EXPECT_CALL(*device_, SetControl(v4l2_control_, MetadataToV4L2(val), _))
- .WillOnce(Return(err));
- EXPECT_EQ(control_->SetValue(val), err);
-}
-
-TEST_F(V4L2EnumControlTest, SetInvalidValue) {
- uint8_t val = 99; // Not one of the supported values.
- EXPECT_EQ(control_->SetValue(val), -EINVAL);
-}
-
-TEST_F(V4L2EnumControlTest, SetUnmapped) {
- // If the enum control is validly constructed, this should never happen.
- // Purposefully misconstruct a device for this test (empty map).
- V4L2EnumControl test_control(
- device_, v4l2_control_, control_tag_, options_tag_, {}, options_);
- EXPECT_EQ(test_control.SetValue(options_[0]), -ENODEV);
-}
-
-TEST_F(V4L2EnumControlTest, GetValue) {
- // Should go through the device.
- uint8_t expected = options_[0];
- EXPECT_CALL(*device_, GetControl(v4l2_control_, _))
- .WillOnce(DoAll(SetArgPointee<1>(MetadataToV4L2(expected)), Return(0)));
- uint8_t actual =
- expected + 1; // Initialize to something other than expected.
- EXPECT_EQ(control_->GetValue(&actual), 0);
- EXPECT_EQ(actual, expected);
-}
-
-TEST_F(V4L2EnumControlTest, GetValueFail) {
- // Should go through the device but fail.
- int err = -99;
- EXPECT_CALL(*device_, GetControl(v4l2_control_, _)).WillOnce(Return(err));
- uint8_t unused;
- EXPECT_EQ(control_->GetValue(&unused), err);
-}
-
-TEST_F(V4L2EnumControlTest, GetUnmapped) {
- int32_t invalid = -99; // Not in our map.
- EXPECT_CALL(*device_, GetControl(v4l2_control_, _))
- .WillOnce(DoAll(SetArgPointee<1>(invalid), Return(0)));
- uint8_t unused;
- EXPECT_EQ(control_->GetValue(&unused), -ENODEV);
-}
-
-} // namespace v4l2_camera_hal
diff --git a/modules/camera/3_4/v4l2_metadata.cpp b/modules/camera/3_4/v4l2_metadata.cpp
index 0ad667b..c289a40 100644
--- a/modules/camera/3_4/v4l2_metadata.cpp
+++ b/modules/camera/3_4/v4l2_metadata.cpp
@@ -19,9 +19,8 @@
#include <camera/CameraMetadata.h>
#include "common.h"
-#include "metadata/fixed_property.h"
-#include "metadata/ignored_control.h"
-#include "metadata/v4l2_enum_control.h"
+#include "metadata/control.h"
+#include "metadata/property.h"
namespace v4l2_camera_hal {
@@ -37,20 +36,18 @@
// V4L2 enum controls. Will add the other properties as more PartialMetadata
// subclasses get implemented.
- AddComponent(
- std::unique_ptr<PartialMetadataInterface>(new IgnoredControl<uint8_t>(
- ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
- ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
- {ANDROID_COLOR_CORRECTION_ABERRATION_MODE_FAST,
- ANDROID_COLOR_CORRECTION_ABERRATION_MODE_HIGH_QUALITY},
- ANDROID_COLOR_CORRECTION_ABERRATION_MODE_FAST)));
+ AddComponent(Control<uint8_t>::NoEffectMenuControl(
+ ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
+ ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
+ {ANDROID_COLOR_CORRECTION_ABERRATION_MODE_FAST,
+ ANDROID_COLOR_CORRECTION_ABERRATION_MODE_HIGH_QUALITY}));
// TODO(b/30510395): subcomponents of 3A.
// In general, default to ON/AUTO since they imply pretty much nothing,
// while OFF implies guarantees about not hindering performance.
AddComponent(std::unique_ptr<PartialMetadataInterface>(
- new FixedProperty<std::array<int32_t, 3>>(
- ANDROID_CONTROL_MAX_REGIONS, {{/*AE*/ 0, /*AWB*/ 0, /*AF*/ 0}})));
+ new Property<std::array<int32_t, 3>>(ANDROID_CONTROL_MAX_REGIONS,
+ {{/*AE*/ 0, /*AWB*/ 0, /*AF*/ 0}})));
AddEnumControlOrDefault(V4L2_CID_EXPOSURE_AUTO,
ANDROID_CONTROL_AE_MODE,
ANDROID_CONTROL_AE_AVAILABLE_MODES,
@@ -75,6 +72,7 @@
// Modes from each API that don't match up:
// Android: WARM_FLUORESCENT, TWILIGHT.
// V4L2: FLUORESCENT_H, HORIZON, FLASH.
+ /* TODO(b/30900438): Use v4l2 control factory.
std::unique_ptr<PartialMetadataInterface> awb(
V4L2EnumControl::NewV4L2EnumControl(
device_,
@@ -102,6 +100,7 @@
{{0, ANDROID_CONTROL_AWB_MODE_OFF}, {1, ANDROID_CONTROL_AWB_MODE_AUTO}},
ANDROID_CONTROL_AWB_MODE_AUTO);
}
+ */
// TODO(b/30510395): subcomponents of scene modes
// (may itself be a subcomponent of 3A).
// Modes from each API that don't match up:
@@ -142,70 +141,57 @@
// Not sure if V4L2 does or doesn't do this, but HAL documentation says
// all devices must support FAST, and FAST can be equivalent to OFF, so
// either way it's fine to list.
- AddComponent(std::unique_ptr<PartialMetadataInterface>(
- new IgnoredControl<uint8_t>(ANDROID_EDGE_MODE,
- ANDROID_EDGE_AVAILABLE_EDGE_MODES,
- {ANDROID_EDGE_MODE_FAST},
- ANDROID_EDGE_MODE_FAST)));
+ AddComponent(
+ Control<uint8_t>::NoEffectMenuControl(ANDROID_EDGE_MODE,
+ ANDROID_EDGE_AVAILABLE_EDGE_MODES,
+ {ANDROID_EDGE_MODE_FAST}));
// TODO(30510395): subcomponents of hotpixel.
// No known V4L2 hot pixel correction. But it might be happening,
// so we report FAST/HIGH_QUALITY.
- AddComponent(
- std::unique_ptr<PartialMetadataInterface>(new IgnoredControl<uint8_t>(
- ANDROID_HOT_PIXEL_MODE,
- ANDROID_HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES,
- {ANDROID_HOT_PIXEL_MODE_FAST, ANDROID_HOT_PIXEL_MODE_HIGH_QUALITY},
- ANDROID_HOT_PIXEL_MODE_FAST)));
+ AddComponent(Control<uint8_t>::NoEffectMenuControl(
+ ANDROID_HOT_PIXEL_MODE,
+ ANDROID_HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES,
+ {ANDROID_HOT_PIXEL_MODE_FAST, ANDROID_HOT_PIXEL_MODE_HIGH_QUALITY}));
// ON only needs to be supported for RAW capable devices.
- AddComponent(
- std::unique_ptr<PartialMetadataInterface>(new IgnoredControl<uint8_t>(
- ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE,
- ANDROID_STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES,
- {ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE_OFF},
- ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE_OFF)));
+ AddComponent(Control<uint8_t>::NoEffectMenuControl(
+ ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE,
+ ANDROID_STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES,
+ {ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE_OFF}));
// TODO(30510395): subcomponents focus/lens.
// No way to actually get the aperture and focal length
// in V4L2, but they're required keys, so fake them.
- AddComponent(std::unique_ptr<PartialMetadataInterface>(
- new IgnoredControl<float>(ANDROID_LENS_APERTURE,
- ANDROID_LENS_INFO_AVAILABLE_APERTURES,
- {2.0},
- 2.0))); // RPi camera v2 is f/2.0.
- AddComponent(std::unique_ptr<PartialMetadataInterface>(
- new IgnoredControl<float>(ANDROID_LENS_FOCAL_LENGTH,
- ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
- {3.04},
- 3.04))); // RPi camera v2 is 3.04mm.
+ AddComponent(
+ Control<float>::NoEffectMenuControl(ANDROID_LENS_APERTURE,
+ ANDROID_LENS_INFO_AVAILABLE_APERTURES,
+ {2.0})); // RPi camera v2 is f/2.0.
+ AddComponent(Control<float>::NoEffectMenuControl(
+ ANDROID_LENS_FOCAL_LENGTH,
+ ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
+ {3.04})); // RPi camera v2 is 3.04mm.
// No known way to get filter densities from V4L2,
// report 0 to indicate this control is not supported.
- AddComponent(std::unique_ptr<PartialMetadataInterface>(
- new IgnoredControl<float>(ANDROID_LENS_FILTER_DENSITY,
- ANDROID_LENS_INFO_AVAILABLE_FILTER_DENSITIES,
- {0.0},
- 0.0)));
+ AddComponent(Control<float>::NoEffectMenuControl(
+ ANDROID_LENS_FILTER_DENSITY,
+ ANDROID_LENS_INFO_AVAILABLE_FILTER_DENSITIES,
+ {0.0}));
// V4L2 focal units do not correspond to a particular physical unit.
- AddComponent(
- std::unique_ptr<PartialMetadataInterface>(new FixedProperty<uint8_t>(
- ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION,
- ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION_UNCALIBRATED)));
+ AddComponent(std::unique_ptr<PartialMetadataInterface>(new Property<uint8_t>(
+ ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION,
+ ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION_UNCALIBRATED)));
// info.hyperfocalDistance not required for UNCALIBRATED.
// No known V4L2 lens shading. But it might be happening,
// so report FAST/HIGH_QUALITY.
- AddComponent(
- std::unique_ptr<PartialMetadataInterface>(new IgnoredControl<uint8_t>(
- ANDROID_SHADING_MODE,
- ANDROID_SHADING_AVAILABLE_MODES,
- {ANDROID_SHADING_MODE_FAST, ANDROID_SHADING_MODE_HIGH_QUALITY},
- ANDROID_SHADING_MODE_FAST)));
+ AddComponent(Control<uint8_t>::NoEffectMenuControl(
+ ANDROID_SHADING_MODE,
+ ANDROID_SHADING_AVAILABLE_MODES,
+ {ANDROID_SHADING_MODE_FAST, ANDROID_SHADING_MODE_HIGH_QUALITY}));
// ON only needs to be supported for RAW capable devices.
- AddComponent(
- std::unique_ptr<PartialMetadataInterface>(new IgnoredControl<uint8_t>(
- ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
- ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES,
- {ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF},
- ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF)));
+ AddComponent(Control<uint8_t>::NoEffectMenuControl(
+ ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
+ ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES,
+ {ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF}));
// V4L2 doesn't differentiate between OPTICAL and VIDEO stabilization,
// so only report one (and report the other as OFF).
AddEnumControlOrDefault(V4L2_CID_IMAGE_STABILIZATION,
@@ -214,98 +200,86 @@
{{0, ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF},
{1, ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_ON}},
ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF);
- AddComponent(
- std::unique_ptr<PartialMetadataInterface>(new IgnoredControl<uint8_t>(
- ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
- ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
- {ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF},
- ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF)));
+ AddComponent(Control<uint8_t>::NoEffectMenuControl(
+ ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
+ ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
+ {ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF}));
// Unable to control noise reduction in V4L2 devices,
// but FAST is allowed to be the same as OFF.
- AddComponent(
- std::unique_ptr<PartialMetadataInterface>(new IgnoredControl<uint8_t>(
- ANDROID_NOISE_REDUCTION_MODE,
- ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
- {ANDROID_NOISE_REDUCTION_MODE_FAST},
- ANDROID_NOISE_REDUCTION_MODE_FAST)));
+ AddComponent(Control<uint8_t>::NoEffectMenuControl(
+ ANDROID_NOISE_REDUCTION_MODE,
+ ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
+ {ANDROID_NOISE_REDUCTION_MODE_FAST}));
// TODO(30510395): subcomponents of formats/streams.
// For now, no thumbnails available (only [0,0], the "no thumbnail" size).
// TODO(b/29580107): Could end up with a mismatch between request & result,
// since V4L2 doesn't actually allow for thumbnail size control.
- AddComponent(std::unique_ptr<PartialMetadataInterface>(
- new IgnoredControl<std::array<int32_t, 2>>(
- ANDROID_JPEG_THUMBNAIL_SIZE,
- ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
- {{{0, 0}}},
- {{0, 0}})));
+ AddComponent(Control<std::array<int32_t, 2>>::NoEffectMenuControl(
+ ANDROID_JPEG_THUMBNAIL_SIZE,
+ ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
+ {{{0, 0}}}));
// TODO(b/29939583): V4L2 can only support 1 stream at a time.
// For now, just reporting minimum allowable for LIMITED devices.
AddComponent(std::unique_ptr<PartialMetadataInterface>(
- new FixedProperty<std::array<int32_t, 3>>(
+ new Property<std::array<int32_t, 3>>(
ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS,
{{/* Raw */ 0, /* Non-stalling */ 2, /* Stalling */ 1}})));
// Reprocessing not supported.
AddComponent(std::unique_ptr<PartialMetadataInterface>(
- new FixedProperty<int32_t>(ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS, 0)));
+ new Property<int32_t>(ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS, 0)));
// No way to know pipeline depth for V4L2, so fake with max allowable latency.
// Doesn't mean much without per-frame controls anyways.
AddComponent(std::unique_ptr<PartialMetadataInterface>(
- new FixedProperty<uint8_t>(ANDROID_REQUEST_PIPELINE_MAX_DEPTH, 4)));
+ new Property<uint8_t>(ANDROID_REQUEST_PIPELINE_MAX_DEPTH, 4)));
// "LIMITED devices are strongly encouraged to use a non-negative value.
// If UNKNOWN is used here then app developers do not have a way to know
// when sensor settings have been applied." - Unfortunately, V4L2 doesn't
// really help here either. Could even be that adjusting settings mid-stream
// blocks in V4L2, and should be avoided.
- AddComponent(
- std::unique_ptr<PartialMetadataInterface>(new FixedProperty<int32_t>(
- ANDROID_SYNC_MAX_LATENCY, ANDROID_SYNC_MAX_LATENCY_UNKNOWN)));
+ AddComponent(std::unique_ptr<PartialMetadataInterface>(new Property<int32_t>(
+ ANDROID_SYNC_MAX_LATENCY, ANDROID_SYNC_MAX_LATENCY_UNKNOWN)));
// TODO(30510395): subcomponents of cropping/sensors.
// V4L2 VIDIOC_CROPCAP doesn't give a way to query this;
// it's driver dependent. For now, assume freeform, and
// some cameras may just behave badly.
// TODO(b/29579652): Figure out a way to determine this.
- AddComponent(std::unique_ptr<PartialMetadataInterface>(
- new FixedProperty<uint8_t>(ANDROID_SCALER_CROPPING_TYPE,
- ANDROID_SCALER_CROPPING_TYPE_FREEFORM)));
+ AddComponent(std::unique_ptr<PartialMetadataInterface>(new Property<uint8_t>(
+ ANDROID_SCALER_CROPPING_TYPE, ANDROID_SCALER_CROPPING_TYPE_FREEFORM)));
// No way to get in V4L2, so faked. RPi camera v2 is 3.674 x 2.760 mm.
// Physical size is used in framework calculations (field of view,
// pixel pitch, etc.), so faking it may have unexpected results.
AddComponent(std::unique_ptr<PartialMetadataInterface>(
- new FixedProperty<std::array<float, 2>>(ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
- {{3.674, 2.760}})));
+ new Property<std::array<float, 2>>(ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
+ {{3.674, 2.760}})));
// HAL uses BOOTTIME timestamps.
// TODO(b/29457051): make sure timestamps are consistent throughout the HAL.
- AddComponent(
- std::unique_ptr<PartialMetadataInterface>(new FixedProperty<uint8_t>(
- ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
- ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN)));
+ AddComponent(std::unique_ptr<PartialMetadataInterface>(
+ new Property<uint8_t>(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
+ ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN)));
// Noo way to actually get orientation from V4L2.
AddComponent(std::unique_ptr<PartialMetadataInterface>(
- new FixedProperty<int32_t>(ANDROID_SENSOR_ORIENTATION, 0)));
+ new Property<int32_t>(ANDROID_SENSOR_ORIENTATION, 0)));
// TODO(30510395): subcomponents of face detection.
// Face detection not supported.
- AddComponent(
- std::unique_ptr<PartialMetadataInterface>(new IgnoredControl<uint8_t>(
- ANDROID_STATISTICS_FACE_DETECT_MODE,
- ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
- {ANDROID_STATISTICS_FACE_DETECT_MODE_OFF},
- ANDROID_STATISTICS_FACE_DETECT_MODE_OFF)));
+ AddComponent(Control<uint8_t>::NoEffectMenuControl(
+ ANDROID_STATISTICS_FACE_DETECT_MODE,
+ ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
+ {ANDROID_STATISTICS_FACE_DETECT_MODE_OFF}));
AddComponent(std::unique_ptr<PartialMetadataInterface>(
- new FixedProperty<int32_t>(ANDROID_STATISTICS_INFO_MAX_FACE_COUNT, 0)));
+ new Property<int32_t>(ANDROID_STATISTICS_INFO_MAX_FACE_COUNT, 0)));
/* Capabilities. */
// The V4L2Metadata pretends to at least meet the
// "LIMITED" and "BACKWARD_COMPATIBLE" functionality requirements.
- AddComponent(
- std::unique_ptr<PartialMetadataInterface>(new FixedProperty<uint8_t>(
- ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
- ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED)));
AddComponent(std::unique_ptr<PartialMetadataInterface>(
- new FixedProperty<std::vector<uint8_t>>(
+ new Property<uint8_t>(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
+ ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED)));
+ AddComponent(std::unique_ptr<PartialMetadataInterface>(
+ new Property<std::vector<uint8_t>>(
ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
{ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE})));
}
@@ -321,15 +295,11 @@
const std::map<int32_t, uint8_t>& v4l2_to_metadata,
uint8_t default_value) {
HAL_LOG_ENTER();
+ // TODO(b/30900438): Replace this function with a V4L2 control factory.
std::unique_ptr<PartialMetadataInterface> control(
- V4L2EnumControl::NewV4L2EnumControl(
- device_, v4l2_control, control_tag, options_tag, v4l2_to_metadata));
-
- if (!control) {
- control.reset(new IgnoredControl<uint8_t>(
- control_tag, options_tag, {default_value}, default_value));
- }
+ Control<uint8_t>::NoEffectMenuControl(
+ control_tag, options_tag, {default_value}));
AddComponent(std::move(control));
}