Add tagged control delegates/options.

Simple wrappers that associate a control delegate
or set of control options with a corresponding
metadata tag.

BUG: 30140438
TEST: unit tests pass

Change-Id: Ib4d769f4a860d661128c8af47d317937d96feb96
diff --git a/modules/camera/3_4/Android.mk b/modules/camera/3_4/Android.mk
index 8766582..7c8f430 100644
--- a/modules/camera/3_4/Android.mk
+++ b/modules/camera/3_4/Android.mk
@@ -63,6 +63,8 @@
   metadata/optioned_control_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 \
 
diff --git a/modules/camera/3_4/metadata/control_delegate_interface_mock.h b/modules/camera/3_4/metadata/control_delegate_interface_mock.h
new file mode 100644
index 0000000..7ed05ed
--- /dev/null
+++ b/modules/camera/3_4/metadata/control_delegate_interface_mock.h
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+// Mock for control delegate interfaces.
+
+#ifndef V4L2_CAMERA_HAL_METADATA_CONTROL_DELEGATE_INTERFACE_MOCK_H_
+#define V4L2_CAMERA_HAL_METADATA_CONTROL_DELEGATE_INTERFACE_MOCK_H_
+
+#include <gmock/gmock.h>
+
+#include "control_delegate_interface.h"
+
+namespace v4l2_camera_hal {
+
+template <typename T>
+class ControlDelegateInterfaceMock : public ControlDelegateInterface<T> {
+ public:
+  ControlDelegateInterfaceMock(){};
+  MOCK_METHOD1_T(GetValue, int(T*));
+  MOCK_METHOD1_T(SetValue, int(const T&));
+};
+
+}  // namespace v4l2_camera_hal
+
+#endif  // V4L2_CAMERA_HAL_METADATA_CONTROL_DELEGATE_INTERFACE_MOCK_H_
diff --git a/modules/camera/3_4/metadata/control_options_interface_mock.h b/modules/camera/3_4/metadata/control_options_interface_mock.h
new file mode 100644
index 0000000..7d33629
--- /dev/null
+++ b/modules/camera/3_4/metadata/control_options_interface_mock.h
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+// Mock for control options interfaces.
+
+#ifndef V4L2_CAMERA_HAL_METADATA_CONTROL_OPTIONS_INTERFACE_MOCK_H_
+#define V4L2_CAMERA_HAL_METADATA_CONTROL_OPTIONS_INTERFACE_MOCK_H_
+
+#include <gmock/gmock.h>
+
+#include "control_options_interface.h"
+
+namespace v4l2_camera_hal {
+
+template <typename T>
+class ControlOptionsInterfaceMock : public ControlOptionsInterface<T> {
+ public:
+  ControlOptionsInterfaceMock(){};
+  MOCK_METHOD0_T(MetadataRepresentation, std::vector<T>());
+  MOCK_METHOD1_T(IsSupported, bool(const T&));
+};
+
+}  // namespace v4l2_camera_hal
+
+#endif  // V4L2_CAMERA_HAL_METADATA_CONTROL_OPTIONS_INTERFACE_MOCK_H_
diff --git a/modules/camera/3_4/metadata/tagged_control_delegate.h b/modules/camera/3_4/metadata/tagged_control_delegate.h
new file mode 100644
index 0000000..40677f9
--- /dev/null
+++ b/modules/camera/3_4/metadata/tagged_control_delegate.h
@@ -0,0 +1,50 @@
+/*
+ * 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_CONTROL_DELEGATE_H_
+#define V4L2_CAMERA_HAL_METADATA_TAGGED_CONTROL_DELEGATE_H_
+
+#include <memory>
+
+#include "control_delegate_interface.h"
+
+namespace v4l2_camera_hal {
+
+// A TaggedControlDelegate wraps a ControlDelegate and adds a tag.
+template <typename T>
+class TaggedControlDelegate : public ControlDelegateInterface<T> {
+ public:
+  TaggedControlDelegate(int32_t tag,
+                        std::unique_ptr<ControlDelegateInterface<T>> delegate)
+      : tag_(tag), delegate_(std::move(delegate)){};
+
+  int32_t tag() { return tag_; };
+
+  virtual int GetValue(T* value) override {
+    return delegate_->GetValue(value);
+  };
+  virtual int SetValue(const T& value) override {
+    return delegate_->SetValue(value);
+  };
+
+ private:
+  const int32_t tag_;
+  std::unique_ptr<ControlDelegateInterface<T>> delegate_;
+};
+
+}  // namespace v4l2_camera_hal
+
+#endif  // V4L2_CAMERA_HAL_METADATA_CONTROL_DELEGATE_INTERFACE_H_
diff --git a/modules/camera/3_4/metadata/tagged_control_delegate_test.cpp b/modules/camera/3_4/metadata/tagged_control_delegate_test.cpp
new file mode 100644
index 0000000..ba29ab7
--- /dev/null
+++ b/modules/camera/3_4/metadata/tagged_control_delegate_test.cpp
@@ -0,0 +1,90 @@
+/*
+ * 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 "tagged_control_delegate.h"
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include "control_delegate_interface_mock.h"
+
+using testing::Return;
+using testing::SetArgPointee;
+using testing::Test;
+using testing::_;
+
+namespace v4l2_camera_hal {
+
+class TaggedControlDelegateTest : public Test {
+ protected:
+  virtual void SetUp() {
+    mock_delegate_.reset(new ControlDelegateInterfaceMock<uint8_t>());
+    // Nullify dut so an error will be thrown if a test doesn't call PrepareDUT.
+    dut_.reset();
+  }
+
+  virtual void PrepareDUT() {
+    // Use this method after all the EXPECT_CALLs to pass ownership of the
+    // delegate
+    // to the device.
+    dut_.reset(
+        new TaggedControlDelegate<uint8_t>(tag_, std::move(mock_delegate_)));
+  }
+
+  std::unique_ptr<TaggedControlDelegate<uint8_t>> dut_;
+  std::unique_ptr<ControlDelegateInterfaceMock<uint8_t>> mock_delegate_;
+  const int32_t tag_ = 123;
+};
+
+TEST_F(TaggedControlDelegateTest, GetTag) {
+  PrepareDUT();
+  EXPECT_EQ(dut_->tag(), tag_);
+}
+
+TEST_F(TaggedControlDelegateTest, GetSuccess) {
+  uint8_t expected = 3;
+  EXPECT_CALL(*mock_delegate_, GetValue(_))
+      .WillOnce(DoAll(SetArgPointee<0>(expected), Return(0)));
+  PrepareDUT();
+  uint8_t actual = expected + 1;  // Initialize to an incorrect value.
+  ASSERT_EQ(dut_->GetValue(&actual), 0);
+  EXPECT_EQ(actual, expected);
+}
+
+TEST_F(TaggedControlDelegateTest, GetFailure) {
+  int err = 3;
+  EXPECT_CALL(*mock_delegate_, GetValue(_)).WillOnce(Return(err));
+  PrepareDUT();
+  uint8_t unused = 0;
+  ASSERT_EQ(dut_->GetValue(&unused), err);
+}
+
+TEST_F(TaggedControlDelegateTest, SetSuccess) {
+  uint8_t value = 3;
+  EXPECT_CALL(*mock_delegate_, SetValue(value)).WillOnce(Return(0));
+  PrepareDUT();
+  ASSERT_EQ(dut_->SetValue(value), 0);
+}
+
+TEST_F(TaggedControlDelegateTest, SetFailure) {
+  int err = 3;
+  uint8_t value = 12;
+  EXPECT_CALL(*mock_delegate_, SetValue(value)).WillOnce(Return(err));
+  PrepareDUT();
+  ASSERT_EQ(dut_->SetValue(value), err);
+}
+
+}  // namespace v4l2_camera_hal
diff --git a/modules/camera/3_4/metadata/tagged_control_options.h b/modules/camera/3_4/metadata/tagged_control_options.h
new file mode 100644
index 0000000..d208c4a
--- /dev/null
+++ b/modules/camera/3_4/metadata/tagged_control_options.h
@@ -0,0 +1,50 @@
+/*
+ * 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_CONTROL_OPTIONS_H_
+#define V4L2_CAMERA_HAL_METADATA_TAGGED_CONTROL_OPTIONS_H_
+
+#include <memory>
+
+#include "control_options_interface.h"
+
+namespace v4l2_camera_hal {
+
+// A TaggedControlOptions wraps a ControlOptions and adds a tag.
+template <typename T>
+class TaggedControlOptions : public ControlOptionsInterface<T> {
+ public:
+  TaggedControlOptions(int32_t tag,
+                       std::unique_ptr<ControlOptionsInterface<T>> options)
+      : tag_(tag), options_(std::move(options)){};
+
+  int32_t tag() { return tag_; };
+
+  virtual std::vector<T> MetadataRepresentation() override {
+    return options_->MetadataRepresentation();
+  };
+  virtual bool IsSupported(const T& value) override {
+    return options_->IsSupported(value);
+  };
+
+ private:
+  const int32_t tag_;
+  std::unique_ptr<ControlOptionsInterface<T>> options_;
+};
+
+}  // namespace v4l2_camera_hal
+
+#endif  // V4L2_CAMERA_HAL_METADATA_CONTROL_OPTIONS_INTERFACE_H_
diff --git a/modules/camera/3_4/metadata/tagged_control_options_test.cpp b/modules/camera/3_4/metadata/tagged_control_options_test.cpp
new file mode 100644
index 0000000..08eefea
--- /dev/null
+++ b/modules/camera/3_4/metadata/tagged_control_options_test.cpp
@@ -0,0 +1,81 @@
+/*
+ * 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 "tagged_control_options.h"
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include "control_options_interface_mock.h"
+
+using testing::Return;
+using testing::SetArgPointee;
+using testing::Test;
+using testing::_;
+
+namespace v4l2_camera_hal {
+
+class TaggedControlOptionsTest : public Test {
+ protected:
+  virtual void SetUp() {
+    mock_options_.reset(new ControlOptionsInterfaceMock<uint8_t>());
+    // Nullify dut so an error will be thrown if a test doesn't call PrepareDUT.
+    dut_.reset();
+  }
+
+  virtual void PrepareDUT() {
+    // Use this method after all the EXPECT_CALLs to pass ownership of the
+    // options
+    // to the device.
+    dut_.reset(
+        new TaggedControlOptions<uint8_t>(tag_, std::move(mock_options_)));
+  }
+
+  std::unique_ptr<TaggedControlOptions<uint8_t>> dut_;
+  std::unique_ptr<ControlOptionsInterfaceMock<uint8_t>> mock_options_;
+  const int32_t tag_ = 123;
+};
+
+TEST_F(TaggedControlOptionsTest, GetTag) {
+  PrepareDUT();
+  EXPECT_EQ(dut_->tag(), tag_);
+}
+
+TEST_F(TaggedControlOptionsTest, MetadataRepresentation) {
+  std::vector<uint8_t> expected{3, 4, 5};
+  EXPECT_CALL(*mock_options_, MetadataRepresentation())
+      .WillOnce(Return(expected));
+  PrepareDUT();
+  ASSERT_EQ(dut_->MetadataRepresentation(), expected);
+}
+
+TEST_F(TaggedControlOptionsTest, IsSupportedTrue) {
+  bool supported = true;
+  uint8_t value = 3;
+  EXPECT_CALL(*mock_options_, IsSupported(value)).WillOnce(Return(supported));
+  PrepareDUT();
+  ASSERT_EQ(dut_->IsSupported(value), supported);
+}
+
+TEST_F(TaggedControlOptionsTest, IsSupportedFalse) {
+  bool supported = false;
+  uint8_t value = 3;
+  EXPECT_CALL(*mock_options_, IsSupported(value)).WillOnce(Return(supported));
+  PrepareDUT();
+  ASSERT_EQ(dut_->IsSupported(value), supported);
+}
+
+}  // namespace v4l2_camera_hal