Add default template initialization.

Adds a flow for Metadata to initialize templates.
PartialMetadataInterfaces expose another populate method,
which use a default value getter from ControlOptionsInterfaces.

BUG: 30140438
TEST: unit tests pass

Change-Id: I1c01469dcf4d06f7c4c62ebe2acd3d9b2294a161
diff --git a/modules/camera/3_4/format_metadata_factory.h b/modules/camera/3_4/format_metadata_factory.h
index f9eb8b2..0c6ae32 100644
--- a/modules/camera/3_4/format_metadata_factory.h
+++ b/modules/camera/3_4/format_metadata_factory.h
@@ -29,6 +29,8 @@
 
 namespace v4l2_camera_hal {
 
+// A factory method to construct all the format-related
+// partial metadata for a V4L2 device.
 int AddFormatComponents(
     std::shared_ptr<V4L2Wrapper> device,
     std::insert_iterator<PartialMetadataSet> insertion_point);
diff --git a/modules/camera/3_4/metadata/control.h b/modules/camera/3_4/metadata/control.h
index 7c8c6bf..c0426c1 100644
--- a/modules/camera/3_4/metadata/control.h
+++ b/modules/camera/3_4/metadata/control.h
@@ -45,6 +45,8 @@
       android::CameraMetadata* metadata) const override;
   virtual int PopulateDynamicFields(
       android::CameraMetadata* metadata) const override;
+  virtual int PopulateTemplateRequest(
+      int template_type, android::CameraMetadata* metadata) const override;
   virtual bool SupportsRequestValues(
       const android::CameraMetadata& metadata) const override;
   virtual int SetRequestValues(
@@ -112,6 +114,20 @@
 }
 
 template <typename T>
+int Control<T>::PopulateTemplateRequest(
+    int template_type, android::CameraMetadata* metadata) const {
+  HAL_LOG_ENTER();
+
+  // Populate with a default.
+  T value;
+  int res = options_->DefaultValueForTemplate(template_type, &value);
+  if (res) {
+    return res;
+  }
+  return UpdateMetadata(metadata, delegate_->tag(), value);
+}
+
+template <typename T>
 bool Control<T>::SupportsRequestValues(
     const android::CameraMetadata& metadata) const {
   HAL_LOG_ENTER();
diff --git a/modules/camera/3_4/metadata/control_options_interface.h b/modules/camera/3_4/metadata/control_options_interface.h
index 49b7653..438cefa 100644
--- a/modules/camera/3_4/metadata/control_options_interface.h
+++ b/modules/camera/3_4/metadata/control_options_interface.h
@@ -33,6 +33,10 @@
   virtual std::vector<T> MetadataRepresentation() = 0;
   // Get whether or not a given value is acceptable.
   virtual bool IsSupported(const T& option);
+  // Get a default option for a given template type, from the available options.
+  // Because a default must be available, any ControlOptions should have at
+  // least one supported value.
+  virtual int DefaultValueForTemplate(int template_type, T* default_value);
 };
 
 }  // namespace v4l2_camera_hal
diff --git a/modules/camera/3_4/metadata/control_options_interface_mock.h b/modules/camera/3_4/metadata/control_options_interface_mock.h
index 7d33629..ab8f6ee 100644
--- a/modules/camera/3_4/metadata/control_options_interface_mock.h
+++ b/modules/camera/3_4/metadata/control_options_interface_mock.h
@@ -31,6 +31,7 @@
   ControlOptionsInterfaceMock(){};
   MOCK_METHOD0_T(MetadataRepresentation, std::vector<T>());
   MOCK_METHOD1_T(IsSupported, bool(const T&));
+  MOCK_METHOD2_T(DefaultValueForTemplate, int(int, T*));
 };
 
 }  // 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 5297a01..a56a110 100644
--- a/modules/camera/3_4/metadata/control_test.cpp
+++ b/modules/camera/3_4/metadata/control_test.cpp
@@ -155,6 +155,29 @@
   EXPECT_TRUE(metadata.isEmpty());
 }
 
+TEST_F(ControlTest, PopulateTemplate) {
+  int template_type = 3;
+  uint8_t default_value = 123;
+  EXPECT_CALL(*mock_options_, DefaultValueForTemplate(template_type, _))
+      .WillOnce(DoAll(SetArgPointee<1>(default_value), Return(0)));
+  PrepareControl();
+
+  android::CameraMetadata metadata;
+  EXPECT_EQ(control_->PopulateTemplateRequest(template_type, &metadata), 0);
+  ExpectMetadataEq(metadata, delegate_tag_, default_value);
+}
+
+TEST_F(ControlTest, PopulateTemplateFail) {
+  int template_type = 3;
+  int err = 10;
+  EXPECT_CALL(*mock_options_, DefaultValueForTemplate(template_type, _))
+      .WillOnce(Return(err));
+  PrepareControl();
+
+  android::CameraMetadata metadata;
+  EXPECT_EQ(control_->PopulateTemplateRequest(template_type, &metadata), err);
+}
+
 TEST_F(ControlTest, SupportsRequest) {
   android::CameraMetadata metadata;
   uint8_t test_option = 123;
diff --git a/modules/camera/3_4/metadata/menu_control_options.h b/modules/camera/3_4/metadata/menu_control_options.h
index 9f009b7..95ed3b6 100644
--- a/modules/camera/3_4/metadata/menu_control_options.h
+++ b/modules/camera/3_4/metadata/menu_control_options.h
@@ -17,6 +17,9 @@
 #ifndef V4L2_CAMERA_HAL_METADATA_MENU_CONTROL_OPTIONS_H_
 #define V4L2_CAMERA_HAL_METADATA_MENU_CONTROL_OPTIONS_H_
 
+#include <errno.h>
+
+#include "../common.h"
 #include "control_options_interface.h"
 
 namespace v4l2_camera_hal {
@@ -25,6 +28,7 @@
 template <typename T>
 class MenuControlOptions : public ControlOptionsInterface<T> {
  public:
+  // |options| must be non-empty.
   MenuControlOptions(std::vector<T> options) : options_(options) {}
 
   virtual std::vector<T> MetadataRepresentation() override { return options_; };
@@ -32,6 +36,17 @@
     return (std::find(options_.begin(), options_.end(), option) !=
             options_.end());
   };
+  virtual int DefaultValueForTemplate(int template_type,
+                                      T* default_value) override {
+    // TODO(b/31017806): More complex logic, depend on template_type.
+    // Default to the first option.
+    if (options_.empty()) {
+      HAL_LOGE("Can't get default value, options are empty.");
+      return -ENODEV;
+    }
+    *default_value = options_[0];
+    return 0;
+  }
 
  private:
   std::vector<T> options_;
diff --git a/modules/camera/3_4/metadata/menu_control_options_test.cpp b/modules/camera/3_4/metadata/menu_control_options_test.cpp
index 8bd385c..24582f6 100644
--- a/modules/camera/3_4/metadata/menu_control_options_test.cpp
+++ b/modules/camera/3_4/metadata/menu_control_options_test.cpp
@@ -19,6 +19,7 @@
 #include <memory>
 
 #include <gtest/gtest.h>
+#include <hardware/camera3.h>
 
 using testing::Test;
 
@@ -46,4 +47,23 @@
   EXPECT_FALSE(dut_->IsSupported(99));
 }
 
+TEST_F(MenuControlOptionsTest, DefaultValue) {
+  // All default values should be supported.
+  // For some reason, the templates have values in the range [1, COUNT).
+  for (int i = 1; i < CAMERA3_TEMPLATE_COUNT; ++i) {
+    int value = -1;
+    EXPECT_EQ(dut_->DefaultValueForTemplate(i, &value), 0);
+    EXPECT_TRUE(dut_->IsSupported(value));
+  }
+}
+
+TEST_F(MenuControlOptionsTest, NoDefaultValue) {
+  // Invalid options don't have a valid default.
+  MenuControlOptions<int> bad_options({});
+  for (int i = 1; i < CAMERA3_TEMPLATE_COUNT; ++i) {
+    int value = -1;
+    EXPECT_EQ(bad_options.DefaultValueForTemplate(i, &value), -ENODEV);
+  }
+}
+
 }  // namespace v4l2_camera_hal
diff --git a/modules/camera/3_4/metadata/metadata.cpp b/modules/camera/3_4/metadata/metadata.cpp
index 976a77d..ddd73c1 100644
--- a/modules/camera/3_4/metadata/metadata.cpp
+++ b/modules/camera/3_4/metadata/metadata.cpp
@@ -17,6 +17,7 @@
 #include "metadata.h"
 
 #include <camera/CameraMetadata.h>
+#include <hardware/camera3.h>
 
 #include "../common.h"
 #include "metadata_common.h"
@@ -96,6 +97,7 @@
     return -ENODEV;
   }
 
+  // TODO(b/31018853): cache result.
   return 0;
 }
 
@@ -118,6 +120,39 @@
   return true;
 }
 
+int Metadata::GetRequestTemplate(int template_type,
+                                 android::CameraMetadata* template_metadata) {
+  HAL_LOG_ENTER();
+
+  // Templates are numbered 1 through COUNT-1 for some reason.
+  if (template_type < 1 || template_type >= CAMERA3_TEMPLATE_COUNT) {
+    HAL_LOGE("Unrecognized template type %d.", template_type);
+    return -EINVAL;
+  }
+
+  for (auto& component : components_) {
+    // Prevent components from potentially overriding others.
+    android::CameraMetadata additional_metadata;
+    int res =
+        component->PopulateTemplateRequest(template_type, &additional_metadata);
+    if (res) {
+      HAL_LOGE("Failed to get all default request fields.");
+      return res;
+    }
+    // Add it to the overall result.
+    if (!additional_metadata.isEmpty()) {
+      res = template_metadata->append(additional_metadata);
+      if (res != android::OK) {
+        HAL_LOGE("Failed to append all default request fields.");
+        return res;
+      }
+    }
+  }
+
+  // TODO(b/31018853): cache result.
+  return 0;
+}
+
 int Metadata::SetRequestSettings(const android::CameraMetadata& metadata) {
   HAL_LOG_ENTER();
 
@@ -128,7 +163,6 @@
   for (auto& component : components_) {
     int res = component->SetRequestValues(metadata);
     if (res) {
-      // Exit early if possible.
       HAL_LOGE("Failed to set all requested settings.");
       return res;
     }
@@ -143,7 +177,6 @@
     android::CameraMetadata additional_metadata;
     int res = component->PopulateDynamicFields(&additional_metadata);
     if (res) {
-      // Exit early if possible.
       HAL_LOGE("Failed to get all dynamic result fields.");
       return res;
     }
diff --git a/modules/camera/3_4/metadata/metadata.h b/modules/camera/3_4/metadata/metadata.h
index 0683df2..e2232b5 100644
--- a/modules/camera/3_4/metadata/metadata.h
+++ b/modules/camera/3_4/metadata/metadata.h
@@ -33,6 +33,8 @@
 
   int FillStaticMetadata(android::CameraMetadata* metadata);
   bool IsValidRequest(const android::CameraMetadata& metadata);
+  int GetRequestTemplate(int template_type,
+                         android::CameraMetadata* template_metadata);
   int SetRequestSettings(const android::CameraMetadata& metadata);
   int FillResultMetadata(android::CameraMetadata* metadata);
 
diff --git a/modules/camera/3_4/metadata/metadata_test.cpp b/modules/camera/3_4/metadata/metadata_test.cpp
index e6fb70f..e97e60b 100644
--- a/modules/camera/3_4/metadata/metadata_test.cpp
+++ b/modules/camera/3_4/metadata/metadata_test.cpp
@@ -200,6 +200,45 @@
   EXPECT_TRUE(dut_->IsValidRequest(*metadata_));
 }
 
+TEST_F(MetadataTest, GetTemplateSuccess) {
+  int template_type = 3;
+
+  // Should check if all the components fill the template successfully.
+  EXPECT_CALL(*component1_, PopulateTemplateRequest(template_type, _))
+      .WillOnce(Return(0));
+  EXPECT_CALL(*component2_, PopulateTemplateRequest(template_type, _))
+      .WillOnce(Return(0));
+
+  AddComponents();
+  // Should succeed.
+  EXPECT_EQ(dut_->GetRequestTemplate(template_type, metadata_.get()), 0);
+}
+
+TEST_F(MetadataTest, GetTemplateFail) {
+  int err = -99;
+  int template_type = 3;
+
+  // Should check if all the components fill the template successfully.
+  // Order undefined, and may or may not exit early; use AtMost.
+  EXPECT_CALL(*component1_, PopulateTemplateRequest(template_type, _))
+      .Times(AtMost(1))
+      .WillOnce(Return(0));
+  EXPECT_CALL(*component2_, PopulateTemplateRequest(template_type, _))
+      .WillOnce(Return(err));
+
+  AddComponents();
+  // Should fail since one of the components failed.
+  EXPECT_EQ(dut_->GetRequestTemplate(template_type, metadata_.get()), err);
+}
+
+TEST_F(MetadataTest, GetTemplateInvalid) {
+  int template_type = 99;  // Invalid template type.
+
+  AddComponents();
+  // Should fail fast since template type is invalid.
+  EXPECT_EQ(dut_->GetRequestTemplate(template_type, metadata_.get()), -EINVAL);
+}
+
 TEST_F(MetadataTest, SetSettingsSuccess) {
   // Should check if all the components set successfully.
   EXPECT_CALL(*component1_, SetRequestValues(_)).WillOnce(Return(0));
diff --git a/modules/camera/3_4/metadata/partial_metadata_interface.h b/modules/camera/3_4/metadata/partial_metadata_interface.h
index cc1f9db..f6e9138 100644
--- a/modules/camera/3_4/metadata/partial_metadata_interface.h
+++ b/modules/camera/3_4/metadata/partial_metadata_interface.h
@@ -45,6 +45,10 @@
   // is responsible for to |metadata|.
   virtual int PopulateDynamicFields(
       android::CameraMetadata* metadata) const = 0;
+  // Add default request values for a given template type for all the controls
+  // this partial metadata owns.
+  virtual int PopulateTemplateRequest(
+      int template_type, android::CameraMetadata* metadata) const = 0;
   // Check if the requested control values from |metadata| (for controls
   // this partial metadata owns) are supported. Empty/null values for owned
   // control tags indicate no change, and are thus inherently supported.
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 e380dee..9e822a1 100644
--- a/modules/camera/3_4/metadata/partial_metadata_interface_mock.h
+++ b/modules/camera/3_4/metadata/partial_metadata_interface_mock.h
@@ -31,13 +31,13 @@
   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,
-                     int(android::CameraMetadata* metadata));
+  MOCK_CONST_METHOD1(PopulateStaticFields, int(android::CameraMetadata*));
+  MOCK_CONST_METHOD1(PopulateDynamicFields, int(android::CameraMetadata*));
+  MOCK_CONST_METHOD2(PopulateTemplateRequest,
+                     int(int, android::CameraMetadata*));
   MOCK_CONST_METHOD1(SupportsRequestValues,
-                     bool(const android::CameraMetadata& metadata));
-  MOCK_METHOD1(SetRequestValues, int(const android::CameraMetadata& metadata));
+                     bool(const android::CameraMetadata&));
+  MOCK_METHOD1(SetRequestValues, int(const android::CameraMetadata&));
 };
 
 }  // namespace v4l2_camera_hal
diff --git a/modules/camera/3_4/metadata/property.h b/modules/camera/3_4/metadata/property.h
index 3ded4c4..03da434 100644
--- a/modules/camera/3_4/metadata/property.h
+++ b/modules/camera/3_4/metadata/property.h
@@ -47,6 +47,12 @@
     return 0;
   };
 
+  virtual int PopulateTemplateRequest(
+      int template_type, android::CameraMetadata* metadata) const override {
+    HAL_LOG_ENTER();
+    return 0;
+  };
+
   virtual bool SupportsRequestValues(
       const android::CameraMetadata& metadata) const override {
     HAL_LOG_ENTER();
diff --git a/modules/camera/3_4/metadata/property_test.cpp b/modules/camera/3_4/metadata/property_test.cpp
index 50b9d4c..8e947ea 100644
--- a/modules/camera/3_4/metadata/property_test.cpp
+++ b/modules/camera/3_4/metadata/property_test.cpp
@@ -22,6 +22,7 @@
 #include <camera/CameraMetadata.h>
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
+#include <hardware/camera3.h>
 
 #include "array_vector.h"
 #include "metadata_common.h"
@@ -134,6 +135,17 @@
   EXPECT_TRUE(metadata.isEmpty());
 }
 
+TEST_F(PropertyTest, PopulateTemplate) {
+  Property<int32_t> property(int_tag_, 1);
+
+  for (int i = 1; i < CAMERA3_TEMPLATE_COUNT; ++i) {
+    android::CameraMetadata metadata;
+    EXPECT_EQ(property.PopulateTemplateRequest(i, &metadata), 0);
+    // Shouldn't have added anything.
+    EXPECT_TRUE(metadata.isEmpty());
+  }
+}
+
 TEST_F(PropertyTest, SupportsRequest) {
   Property<int32_t> property(int_tag_, 1);
   android::CameraMetadata metadata;
diff --git a/modules/camera/3_4/metadata/slider_control_options.h b/modules/camera/3_4/metadata/slider_control_options.h
index 59d1926..2815dad 100644
--- a/modules/camera/3_4/metadata/slider_control_options.h
+++ b/modules/camera/3_4/metadata/slider_control_options.h
@@ -17,8 +17,11 @@
 #ifndef V4L2_CAMERA_HAL_METADATA_SLIDER_CONTROL_OPTIONS_H_
 #define V4L2_CAMERA_HAL_METADATA_SLIDER_CONTROL_OPTIONS_H_
 
+#include <errno.h>
+
 #include <vector>
 
+#include "../common.h"
 #include "control_options_interface.h"
 
 namespace v4l2_camera_hal {
@@ -27,6 +30,7 @@
 template <typename T>
 class SliderControlOptions : public ControlOptionsInterface<T> {
  public:
+  // |min| must be <= |max|.
   SliderControlOptions(T min, T max) : min_(min), max_(max) {}
 
   virtual std::vector<T> MetadataRepresentation() override {
@@ -35,6 +39,17 @@
   virtual bool IsSupported(const T& option) override {
     return option >= min_ && option <= max_;
   };
+  virtual int DefaultValueForTemplate(int template_type,
+                                      T* default_value) override {
+    // TODO(b/31017806): More complex logic, depend on template_type.
+    if (min_ > max_) {
+      HAL_LOGE("No valid default slider option, min is greater than max.");
+      return -ENODEV;
+    }
+    // Default to the min value.
+    *default_value = min_;
+    return 0;
+  }
 
  private:
   T min_;
diff --git a/modules/camera/3_4/metadata/slider_control_options_test.cpp b/modules/camera/3_4/metadata/slider_control_options_test.cpp
index 4a5e763..a241ad6 100644
--- a/modules/camera/3_4/metadata/slider_control_options_test.cpp
+++ b/modules/camera/3_4/metadata/slider_control_options_test.cpp
@@ -19,6 +19,7 @@
 #include <memory>
 
 #include <gtest/gtest.h>
+#include <hardware/camera3.h>
 
 using testing::Test;
 
@@ -51,4 +52,23 @@
   EXPECT_FALSE(dut_->IsSupported(max_ + 1));
 }
 
+TEST_F(SliderControlOptionsTest, DefaultValue) {
+  // All default values should be supported.
+  // For some reason, the templates have values in the range [1, COUNT).
+  for (int i = 1; i < CAMERA3_TEMPLATE_COUNT; ++i) {
+    int value = -1;
+    EXPECT_EQ(dut_->DefaultValueForTemplate(i, &value), 0);
+    EXPECT_TRUE(dut_->IsSupported(value));
+  }
+}
+
+TEST_F(SliderControlOptionsTest, NoDefaultValue) {
+  // Invalid options don't have a valid default.
+  SliderControlOptions<int> bad_options(10, 9);  // min > max.
+  for (int i = 1; i < CAMERA3_TEMPLATE_COUNT; ++i) {
+    int value = -1;
+    EXPECT_EQ(bad_options.DefaultValueForTemplate(i, &value), -ENODEV);
+  }
+}
+
 }  // 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
index d208c4a..9204fea 100644
--- a/modules/camera/3_4/metadata/tagged_control_options.h
+++ b/modules/camera/3_4/metadata/tagged_control_options.h
@@ -39,6 +39,10 @@
   virtual bool IsSupported(const T& value) override {
     return options_->IsSupported(value);
   };
+  virtual int DefaultValueForTemplate(int template_type,
+                                      T* default_value) override {
+    return options_->DefaultValueForTemplate(template_type, default_value);
+  }
 
  private:
   const int32_t tag_;
diff --git a/modules/camera/3_4/metadata/tagged_control_options_test.cpp b/modules/camera/3_4/metadata/tagged_control_options_test.cpp
index 08eefea..845426a 100644
--- a/modules/camera/3_4/metadata/tagged_control_options_test.cpp
+++ b/modules/camera/3_4/metadata/tagged_control_options_test.cpp
@@ -78,4 +78,25 @@
   ASSERT_EQ(dut_->IsSupported(value), supported);
 }
 
+TEST_F(TaggedControlOptionsTest, DefaultValue) {
+  uint8_t value = 99;
+  int template_id = 3;
+  EXPECT_CALL(*mock_options_, DefaultValueForTemplate(template_id, _))
+      .WillOnce(DoAll(SetArgPointee<1>(value), Return(0)));
+  PrepareDUT();
+  uint8_t actual = value + 1;
+  EXPECT_EQ(dut_->DefaultValueForTemplate(template_id, &actual), 0);
+  EXPECT_EQ(actual, value);
+}
+
+TEST_F(TaggedControlOptionsTest, DefaultValueFail) {
+  int err = 12;
+  int template_id = 3;
+  EXPECT_CALL(*mock_options_, DefaultValueForTemplate(template_id, _))
+      .WillOnce(Return(err));
+  PrepareDUT();
+  uint8_t unused;
+  EXPECT_EQ(dut_->DefaultValueForTemplate(template_id, &unused), err);
+}
+
 }  // namespace v4l2_camera_hal