Add control delegates.
Part of moving towards composition over inheritance.
Ignored: Requests to set are ignored.
NoEffect: Tracks a value but does nothing.
V4L2: Goes through a V4l2 device.
TEST: unit tests pass
BUG: 30140438
Change-Id: I9ca636556f4a6ddfe4b8ddfbd042371ed56343b9
diff --git a/modules/camera/3_4/Android.mk b/modules/camera/3_4/Android.mk
index 90dcc97..8766582 100644
--- a/modules/camera/3_4/Android.mk
+++ b/modules/camera/3_4/Android.mk
@@ -54,13 +54,16 @@
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/ranged_converter_test.cpp \
metadata/slider_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/ignored_control_delegate.h b/modules/camera/3_4/metadata/ignored_control_delegate.h
new file mode 100644
index 0000000..f1d5da1
--- /dev/null
+++ b/modules/camera/3_4/metadata/ignored_control_delegate.h
@@ -0,0 +1,43 @@
+/*
+ * 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_DELEGATE_H_
+#define V4L2_CAMERA_HAL_METADATA_IGNORED_CONTROL_DELEGATE_H_
+
+#include "control_delegate_interface.h"
+
+namespace v4l2_camera_hal {
+
+// An IgnoredControlDelegate, as the name implies,
+// has a fixed value and ignores all requests to set it.
+template <typename T>
+class IgnoredControlDelegate : public ControlDelegateInterface<T> {
+ public:
+ IgnoredControlDelegate(T value) : value_(value){};
+
+ int GetValue(T* value) override {
+ *value = value_;
+ return 0;
+ };
+ int SetValue(const T& value) override { return 0; };
+
+ private:
+ const T value_;
+};
+
+} // namespace v4l2_camera_hal
+
+#endif // V4L2_CAMERA_HAL_METADATA_IGNORED_CONTROL_DELEGATE_H_
diff --git a/modules/camera/3_4/metadata/ignored_control_delegate_test.cpp b/modules/camera/3_4/metadata/ignored_control_delegate_test.cpp
new file mode 100644
index 0000000..80c30df
--- /dev/null
+++ b/modules/camera/3_4/metadata/ignored_control_delegate_test.cpp
@@ -0,0 +1,44 @@
+/*
+ * 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_delegate.h"
+
+#include <gtest/gtest.h>
+
+using testing::Test;
+
+namespace v4l2_camera_hal {
+
+TEST(IgnoredControlDelegateTest, DefaultGet) {
+ int32_t value = 12;
+ IgnoredControlDelegate<int32_t> control(value);
+ int32_t actual = 0;
+ ASSERT_EQ(control.GetValue(&actual), 0);
+ EXPECT_EQ(actual, value);
+}
+
+TEST(IgnoredControlDelegateTest, GetAndSet) {
+ int32_t value = 12;
+ IgnoredControlDelegate<int32_t> control(value);
+ int32_t new_value = 13;
+ ASSERT_EQ(control.SetValue(new_value), 0);
+ int32_t actual = 0;
+ ASSERT_EQ(control.GetValue(&actual), 0);
+ // Should still be the default.
+ EXPECT_EQ(actual, value);
+}
+
+} // namespace v4l2_camera_hal
diff --git a/modules/camera/3_4/metadata/no_effect_control_delegate.h b/modules/camera/3_4/metadata/no_effect_control_delegate.h
new file mode 100644
index 0000000..e1936f1
--- /dev/null
+++ b/modules/camera/3_4/metadata/no_effect_control_delegate.h
@@ -0,0 +1,46 @@
+/*
+ * 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_NO_EFFECT_CONTROL_DELEGATE_H_
+#define V4L2_CAMERA_HAL_METADATA_NO_EFFECT_CONTROL_DELEGATE_H_
+
+#include "control_delegate_interface.h"
+
+namespace v4l2_camera_hal {
+
+// A NoEffectControlDelegate, as the name implies, has no effect.
+// The value can be gotten and set, but it does nothing.
+template <typename T>
+class NoEffectControlDelegate : public ControlDelegateInterface<T> {
+ public:
+ NoEffectControlDelegate(T default_value) : value_(default_value){};
+
+ int GetValue(T* value) override {
+ *value = value_;
+ return 0;
+ };
+ int SetValue(const T& value) override {
+ value_ = value;
+ return 0;
+ };
+
+ private:
+ T value_;
+};
+
+} // namespace v4l2_camera_hal
+
+#endif // V4L2_CAMERA_HAL_METADATA_NO_EFFECT_CONTROL_DELEGATE_H_
diff --git a/modules/camera/3_4/metadata/no_effect_control_delegate_test.cpp b/modules/camera/3_4/metadata/no_effect_control_delegate_test.cpp
new file mode 100644
index 0000000..0a7a24c
--- /dev/null
+++ b/modules/camera/3_4/metadata/no_effect_control_delegate_test.cpp
@@ -0,0 +1,43 @@
+/*
+ * 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 "no_effect_control_delegate.h"
+
+#include <gtest/gtest.h>
+
+using testing::Test;
+
+namespace v4l2_camera_hal {
+
+TEST(NoEffectControlDelegateTest, DefaultGet) {
+ int32_t value = 12;
+ NoEffectControlDelegate<int32_t> control(value);
+ int32_t actual = 0;
+ ASSERT_EQ(control.GetValue(&actual), 0);
+ EXPECT_EQ(actual, value);
+}
+
+TEST(NoEffectControlDelegateTest, GetAndSet) {
+ int32_t value = 12;
+ NoEffectControlDelegate<int32_t> control(value);
+ int32_t new_value = 13;
+ ASSERT_EQ(control.SetValue(new_value), 0);
+ int32_t actual = 0;
+ ASSERT_EQ(control.GetValue(&actual), 0);
+ EXPECT_EQ(actual, new_value);
+}
+
+} // namespace v4l2_camera_hal
diff --git a/modules/camera/3_4/metadata/v4l2_control_delegate.h b/modules/camera/3_4/metadata/v4l2_control_delegate.h
new file mode 100644
index 0000000..3f45f9c
--- /dev/null
+++ b/modules/camera/3_4/metadata/v4l2_control_delegate.h
@@ -0,0 +1,66 @@
+/*
+ * 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_CONTROL_DELEGATE_H_
+#define V4L2_CAMERA_HAL_METADATA_V4L2_CONTROL_DELEGATE_H_
+
+#include "../v4l2_wrapper.h"
+#include "control_delegate_interface.h"
+#include "converter_interface.h"
+
+namespace v4l2_camera_hal {
+
+// A V4L2ControlDelegate routes getting and setting through V4L2
+template <typename TMetadata, typename TV4L2 = int32_t>
+class V4L2ControlDelegate : public ControlDelegateInterface<TMetadata> {
+ public:
+ V4L2ControlDelegate(
+ std::shared_ptr<V4L2Wrapper> device,
+ int control_id,
+ std::shared_ptr<ConverterInterface<TMetadata, TV4L2>> converter)
+ : device_(std::move(device)),
+ control_id_(control_id),
+ converter_(std::move(converter)){};
+
+ int GetValue(TMetadata* value) override {
+ TV4L2 v4l2_value;
+ int res = device_->GetControl(control_id_, &v4l2_value);
+ if (res) {
+ HAL_LOGE("Failed to get device value for control %d.", control_id_);
+ return res;
+ }
+ return converter_->V4L2ToMetadata(v4l2_value, value);
+ };
+
+ int SetValue(const TMetadata& value) override {
+ TV4L2 v4l2_value;
+ int res = converter_->MetadataToV4L2(value, &v4l2_value);
+ if (res) {
+ HAL_LOGE("Failed to convert metadata value to V4L2.");
+ return res;
+ }
+ return device_->SetControl(control_id_, v4l2_value);
+ };
+
+ private:
+ std::shared_ptr<V4L2Wrapper> device_;
+ int control_id_;
+ std::shared_ptr<ConverterInterface<TMetadata, TV4L2>> converter_;
+};
+
+} // namespace v4l2_camera_hal
+
+#endif // V4L2_CAMERA_HAL_METADATA_V4L2_CONTROL_DELEGATE_H_
diff --git a/modules/camera/3_4/metadata/v4l2_control_delegate_test.cpp b/modules/camera/3_4/metadata/v4l2_control_delegate_test.cpp
new file mode 100644
index 0000000..2f14d6f
--- /dev/null
+++ b/modules/camera/3_4/metadata/v4l2_control_delegate_test.cpp
@@ -0,0 +1,110 @@
+/*
+ * 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_control_delegate.h"
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include "../v4l2_wrapper_mock.h"
+#include "converter_interface_mock.h"
+
+using testing::Return;
+using testing::SetArgPointee;
+using testing::Test;
+using testing::_;
+
+namespace v4l2_camera_hal {
+
+class V4L2ControlDelegateTest : public Test {
+ protected:
+ virtual void SetUp() {
+ mock_device_.reset(new V4L2WrapperMock());
+ mock_converter_.reset(new ConverterInterfaceMock<uint8_t, int32_t>());
+ dut_.reset(new V4L2ControlDelegate<uint8_t>(
+ mock_device_, control_id_, mock_converter_));
+ }
+
+ std::unique_ptr<V4L2ControlDelegate<uint8_t>> dut_;
+ std::shared_ptr<V4L2WrapperMock> mock_device_;
+ std::shared_ptr<ConverterInterfaceMock<uint8_t, int32_t>> mock_converter_;
+ const int control_id_ = 123;
+};
+
+TEST_F(V4L2ControlDelegateTest, GetSuccess) {
+ int32_t device_result = 99;
+ uint8_t conversion_result = 10;
+ EXPECT_CALL(*mock_device_, GetControl(control_id_, _))
+ .WillOnce(DoAll(SetArgPointee<1>(device_result), Return(0)));
+ EXPECT_CALL(*mock_converter_, V4L2ToMetadata(device_result, _))
+ .WillOnce(DoAll(SetArgPointee<1>(conversion_result), Return(0)));
+
+ uint8_t actual = conversion_result + 1; // Something incorrect.
+ ASSERT_EQ(dut_->GetValue(&actual), 0);
+ EXPECT_EQ(actual, conversion_result);
+}
+
+TEST_F(V4L2ControlDelegateTest, GetConverterFailure) {
+ int32_t device_result = 99;
+ EXPECT_CALL(*mock_device_, GetControl(control_id_, _))
+ .WillOnce(DoAll(SetArgPointee<1>(device_result), Return(0)));
+ int err = -99;
+ EXPECT_CALL(*mock_converter_, V4L2ToMetadata(device_result, _))
+ .WillOnce(Return(err));
+
+ uint8_t unused = 1;
+ ASSERT_EQ(dut_->GetValue(&unused), err);
+}
+
+TEST_F(V4L2ControlDelegateTest, GetDeviceFailure) {
+ int err = -99;
+ EXPECT_CALL(*mock_device_, GetControl(control_id_, _)).WillOnce(Return(err));
+
+ uint8_t unused = 1;
+ ASSERT_EQ(dut_->GetValue(&unused), err);
+}
+
+TEST_F(V4L2ControlDelegateTest, SetSuccess) {
+ uint8_t input = 10;
+ int32_t conversion_result = 99;
+ EXPECT_CALL(*mock_converter_, MetadataToV4L2(input, _))
+ .WillOnce(DoAll(SetArgPointee<1>(conversion_result), Return(0)));
+ EXPECT_CALL(*mock_device_, SetControl(control_id_, conversion_result, _))
+ .WillOnce(Return(0));
+
+ ASSERT_EQ(dut_->SetValue(input), 0);
+}
+
+TEST_F(V4L2ControlDelegateTest, SetConverterFailure) {
+ uint8_t input = 10;
+ int err = 12;
+ EXPECT_CALL(*mock_converter_, MetadataToV4L2(input, _)).WillOnce(Return(err));
+ ASSERT_EQ(dut_->SetValue(input), err);
+}
+
+TEST_F(V4L2ControlDelegateTest, SetDeviceFailure) {
+ uint8_t input = 10;
+ int32_t conversion_result = 99;
+ EXPECT_CALL(*mock_converter_, MetadataToV4L2(input, _))
+ .WillOnce(DoAll(SetArgPointee<1>(conversion_result), Return(0)));
+ int err = 66;
+ EXPECT_CALL(*mock_device_, SetControl(control_id_, conversion_result, _))
+ .WillOnce(Return(err));
+
+ ASSERT_EQ(dut_->SetValue(input), err);
+}
+
+} // namespace v4l2_camera_hal