Add states to metadata.

States are dynamically changing values. For now
none of them have implementations; they're all fixed
values.

BUG: 30140438
TEST: unit tests pass
Change-Id: I60f97fce5db4542e6b77694bb323934e32eab9f6
diff --git a/modules/camera/3_4/Android.mk b/modules/camera/3_4/Android.mk
index 140e73b..bf888be 100644
--- a/modules/camera/3_4/Android.mk
+++ b/modules/camera/3_4/Android.mk
@@ -52,7 +52,6 @@
 
 v4l2_test_files := \
   format_metadata_factory_test.cpp \
-  metadata/control_factory_test.cpp \
   metadata/control_test.cpp \
   metadata/enum_converter_test.cpp \
   metadata/ignored_control_delegate_test.cpp \
@@ -60,9 +59,11 @@
   metadata/menu_control_options_test.cpp \
   metadata/metadata_test.cpp \
   metadata/no_effect_control_delegate_test.cpp \
+  metadata/partial_metadata_factory_test.cpp \
   metadata/property_test.cpp \
   metadata/ranged_converter_test.cpp \
   metadata/slider_control_options_test.cpp \
+  metadata/state_test.cpp \
   metadata/tagged_control_delegate_test.cpp \
   metadata/tagged_control_options_test.cpp \
   metadata/v4l2_control_delegate_test.cpp \
diff --git a/modules/camera/3_4/format_metadata_factory.cpp b/modules/camera/3_4/format_metadata_factory.cpp
index 83cf5cc..673477b 100644
--- a/modules/camera/3_4/format_metadata_factory.cpp
+++ b/modules/camera/3_4/format_metadata_factory.cpp
@@ -17,6 +17,8 @@
 #include "format_metadata_factory.h"
 
 #include "metadata/array_vector.h"
+#include "metadata/partial_metadata_factory.h"
+#include "metadata/property.h"
 
 namespace v4l2_camera_hal {
 
diff --git a/modules/camera/3_4/format_metadata_factory.h b/modules/camera/3_4/format_metadata_factory.h
index 0c6ae32..4cf5952 100644
--- a/modules/camera/3_4/format_metadata_factory.h
+++ b/modules/camera/3_4/format_metadata_factory.h
@@ -22,9 +22,7 @@
 #include <set>
 
 #include "common.h"
-#include "metadata/control_factory.h"
 #include "metadata/metadata_common.h"
-#include "metadata/property.h"
 #include "v4l2_wrapper.h"
 
 namespace v4l2_camera_hal {
diff --git a/modules/camera/3_4/metadata/control_factory.h b/modules/camera/3_4/metadata/partial_metadata_factory.h
similarity index 94%
rename from modules/camera/3_4/metadata/control_factory.h
rename to modules/camera/3_4/metadata/partial_metadata_factory.h
index f461cfa..a554ee7 100644
--- a/modules/camera/3_4/metadata/control_factory.h
+++ b/modules/camera/3_4/metadata/partial_metadata_factory.h
@@ -23,6 +23,7 @@
 #include "no_effect_control_delegate.h"
 #include "ranged_converter.h"
 #include "slider_control_options.h"
+#include "state.h"
 #include "tagged_control_delegate.h"
 #include "tagged_control_options.h"
 #include "v4l2_control_delegate.h"
@@ -31,7 +32,11 @@
 
 enum class ControlType { kMenu, kSlider };
 
-// Static functions to create controls. Nullptr is returned on failures.
+// Static functions to create partial metadata. Nullptr is returned on failures.
+
+// FixedState: A state that doesn't change.
+template <typename T>
+static std::unique_ptr<State<T>> FixedState(int32_t tag, T value);
 
 // NoEffectOptionlessControl: A control that accepts any value,
 // and has no effect. A default value is given.
@@ -86,6 +91,17 @@
 // -----------------------------------------------------------------------------
 
 template <typename T>
+std::unique_ptr<State<T>> FixedState(int32_t tag, T value) {
+  HAL_LOG_ENTER();
+
+  // Take advantage of ControlDelegate inheriting from StateDelegate;
+  // This will only expose GetValue, not SetValue, so the default will
+  // always be returned.
+  return std::make_unique<State<T>>(
+      tag, std::make_unique<NoEffectControlDelegate<T>>(value));
+}
+
+template <typename T>
 std::unique_ptr<Control<T>> NoEffectOptionlessControl(int32_t delegate_tag,
                                                       T default_value) {
   HAL_LOG_ENTER();
diff --git a/modules/camera/3_4/metadata/control_factory_test.cpp b/modules/camera/3_4/metadata/partial_metadata_factory_test.cpp
similarity index 84%
rename from modules/camera/3_4/metadata/control_factory_test.cpp
rename to modules/camera/3_4/metadata/partial_metadata_factory_test.cpp
index 9010879..4c4a1b1 100644
--- a/modules/camera/3_4/metadata/control_factory_test.cpp
+++ b/modules/camera/3_4/metadata/partial_metadata_factory_test.cpp
@@ -19,9 +19,9 @@
 #include <gtest/gtest.h>
 
 #include "../v4l2_wrapper_mock.h"
-#include "control_factory.h"
 #include "converter_interface_mock.h"
 #include "metadata_common.h"
+#include "partial_metadata_factory.h"
 #include "test_common.h"
 
 using testing::AtMost;
@@ -33,7 +33,7 @@
 
 namespace v4l2_camera_hal {
 
-class ControlFactoryTest : public Test {
+class PartialMetadataFactoryTest : public Test {
  protected:
   virtual void SetUp() {
     mock_device_.reset(new V4L2WrapperMock());
@@ -43,7 +43,7 @@
     control_.reset();
   }
 
-  virtual void ExpectTags() {
+  virtual void ExpectControlTags() {
     ASSERT_EQ(control_->StaticTags().size(), 1);
     EXPECT_EQ(control_->StaticTags()[0], options_tag_);
     ASSERT_EQ(control_->ControlTags().size(), 1);
@@ -52,7 +52,7 @@
     EXPECT_EQ(control_->DynamicTags()[0], delegate_tag_);
   }
 
-  virtual void ExpectOptions(const std::vector<uint8_t>& options) {
+  virtual void ExpectControlOptions(const std::vector<uint8_t>& options) {
     // Options should be available.
     android::CameraMetadata metadata;
     ASSERT_EQ(control_->PopulateStaticFields(&metadata), 0);
@@ -60,7 +60,7 @@
     ExpectMetadataEq(metadata, options_tag_, options);
   }
 
-  virtual void ExpectValue(uint8_t value) {
+  virtual void ExpectControlValue(uint8_t value) {
     android::CameraMetadata metadata;
     ASSERT_EQ(control_->PopulateDynamicFields(&metadata), 0);
     EXPECT_EQ(metadata.entryCount(), 1);
@@ -77,63 +77,78 @@
       ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES;
 };
 
-TEST_F(ControlFactoryTest, NoEffectMenu) {
+TEST_F(PartialMetadataFactoryTest, FixedState) {
+  uint8_t value = 13;
+  std::unique_ptr<State<uint8_t>> state = FixedState(delegate_tag_, value);
+
+  ASSERT_EQ(state->StaticTags().size(), 0);
+  ASSERT_EQ(state->ControlTags().size(), 0);
+  ASSERT_EQ(state->DynamicTags().size(), 1);
+  EXPECT_EQ(state->DynamicTags()[0], delegate_tag_);
+
+  android::CameraMetadata metadata;
+  ASSERT_EQ(state->PopulateDynamicFields(&metadata), 0);
+  EXPECT_EQ(metadata.entryCount(), 1);
+  ExpectMetadataEq(metadata, delegate_tag_, value);
+}
+
+TEST_F(PartialMetadataFactoryTest, NoEffectMenu) {
   std::vector<uint8_t> test_options = {9, 8, 12};
   control_ =
       NoEffectMenuControl<uint8_t>(delegate_tag_, options_tag_, test_options);
   ASSERT_NE(control_, nullptr);
 
-  ExpectTags();
+  ExpectControlTags();
 
   // Options should be available.
-  ExpectOptions(test_options);
+  ExpectControlOptions(test_options);
   // Default value should be test_options[0].
-  ExpectValue(test_options[0]);
+  ExpectControlValue(test_options[0]);
 }
 
-TEST_F(ControlFactoryTest, NoEffectGenericMenu) {
+TEST_F(PartialMetadataFactoryTest, NoEffectGenericMenu) {
   uint8_t default_val = 9;
   control_ = NoEffectControl<uint8_t>(
       ControlType::kMenu, delegate_tag_, options_tag_, default_val);
   ASSERT_NE(control_, nullptr);
 
-  ExpectTags();
+  ExpectControlTags();
 
   // Options should be available.
-  ExpectOptions({default_val});
+  ExpectControlOptions({default_val});
   // |default_val| should be default option.
-  ExpectValue(default_val);
+  ExpectControlValue(default_val);
 }
 
-TEST_F(ControlFactoryTest, NoEffectSlider) {
+TEST_F(PartialMetadataFactoryTest, NoEffectSlider) {
   std::vector<uint8_t> test_range = {9, 12};
   control_ = NoEffectSliderControl<uint8_t>(
       delegate_tag_, options_tag_, test_range[0], test_range[1]);
   ASSERT_NE(control_, nullptr);
 
-  ExpectTags();
+  ExpectControlTags();
 
   // Single option should be available.
-  ExpectOptions(test_range);
+  ExpectControlOptions(test_range);
   // Default value should be the minimum (test_range[0]).
-  ExpectValue(test_range[0]);
+  ExpectControlValue(test_range[0]);
 }
 
-TEST_F(ControlFactoryTest, NoEffectGenericSlider) {
+TEST_F(PartialMetadataFactoryTest, NoEffectGenericSlider) {
   uint8_t default_val = 9;
   control_ = NoEffectControl<uint8_t>(
       ControlType::kSlider, delegate_tag_, options_tag_, default_val);
   ASSERT_NE(control_, nullptr);
 
-  ExpectTags();
+  ExpectControlTags();
 
   // Range containing only |default_val| should be available.
-  ExpectOptions({default_val, default_val});
+  ExpectControlOptions({default_val, default_val});
   // |default_val| should be default option.
-  ExpectValue(default_val);
+  ExpectControlValue(default_val);
 }
 
-TEST_F(ControlFactoryTest, V4L2FactoryQueryFail) {
+TEST_F(PartialMetadataFactoryTest, V4L2FactoryQueryFail) {
   int control_id = 55;
   // Should query the device.
   EXPECT_CALL(*mock_device_, QueryControl(control_id, _)).WillOnce(Return(-1));
@@ -147,7 +162,7 @@
   ASSERT_EQ(control_, nullptr);
 }
 
-TEST_F(ControlFactoryTest, V4L2FactoryQueryBadType) {
+TEST_F(PartialMetadataFactoryTest, V4L2FactoryQueryBadType) {
   int control_id = 55;
   v4l2_query_ext_ctrl query_result;
   query_result.type = V4L2_CTRL_TYPE_CTRL_CLASS;
@@ -164,7 +179,7 @@
   ASSERT_EQ(control_, nullptr);
 }
 
-TEST_F(ControlFactoryTest, V4L2FactoryQueryBadRange) {
+TEST_F(PartialMetadataFactoryTest, V4L2FactoryQueryBadRange) {
   int control_id = 55;
   v4l2_query_ext_ctrl query_result;
   query_result.type = V4L2_CTRL_TYPE_MENU;
@@ -183,7 +198,7 @@
   ASSERT_EQ(control_, nullptr);
 }
 
-TEST_F(ControlFactoryTest, V4L2FactoryTypeRequestMenuMismatch) {
+TEST_F(PartialMetadataFactoryTest, V4L2FactoryTypeRequestMenuMismatch) {
   int control_id = 55;
   v4l2_query_ext_ctrl query_result;
   query_result.type = V4L2_CTRL_TYPE_INTEGER;
@@ -207,7 +222,7 @@
   ASSERT_EQ(control_, nullptr);
 }
 
-TEST_F(ControlFactoryTest, V4L2FactoryTypeRequestSliderMismatch) {
+TEST_F(PartialMetadataFactoryTest, V4L2FactoryTypeRequestSliderMismatch) {
   int control_id = 55;
   v4l2_query_ext_ctrl query_result;
   query_result.type = V4L2_CTRL_TYPE_MENU;
@@ -231,7 +246,7 @@
   ASSERT_EQ(control_, nullptr);
 }
 
-TEST_F(ControlFactoryTest, V4L2FactoryMenu) {
+TEST_F(PartialMetadataFactoryTest, V4L2FactoryMenu) {
   int control_id = 55;
   v4l2_query_ext_ctrl query_result;
   query_result.type = V4L2_CTRL_TYPE_MENU;
@@ -262,11 +277,11 @@
                                   mock_converter_);
   ASSERT_NE(control_, nullptr);
 
-  ExpectTags();
-  ExpectOptions(expected_options);
+  ExpectControlTags();
+  ExpectControlOptions(expected_options);
 }
 
-TEST_F(ControlFactoryTest, V4L2FactoryMenuConversionFail) {
+TEST_F(PartialMetadataFactoryTest, V4L2FactoryMenuConversionFail) {
   int control_id = 55;
   v4l2_query_ext_ctrl query_result;
   query_result.type = V4L2_CTRL_TYPE_MENU;
@@ -289,7 +304,7 @@
   ASSERT_EQ(control_, nullptr);
 }
 
-TEST_F(ControlFactoryTest, V4L2FactoryMenuNoConversions) {
+TEST_F(PartialMetadataFactoryTest, V4L2FactoryMenuNoConversions) {
   int control_id = 55;
   v4l2_query_ext_ctrl query_result;
   query_result.type = V4L2_CTRL_TYPE_MENU;
@@ -313,7 +328,7 @@
   ASSERT_EQ(control_, nullptr);
 }
 
-TEST_F(ControlFactoryTest, V4L2FactoryInteger) {
+TEST_F(PartialMetadataFactoryTest, V4L2FactoryInteger) {
   int control_id = 55;
   v4l2_query_ext_ctrl query_result;
   query_result.type = V4L2_CTRL_TYPE_INTEGER;
@@ -342,8 +357,8 @@
                                   mock_converter_);
   ASSERT_NE(control_, nullptr);
 
-  ExpectTags();
-  ExpectOptions(expected_options);
+  ExpectControlTags();
+  ExpectControlOptions(expected_options);
 
   // Should be fitting converted values to steps.
   uint8_t set_val = 10;
@@ -357,7 +372,7 @@
   EXPECT_EQ(control_->SetRequestValues(metadata), 0);
 }
 
-TEST_F(ControlFactoryTest, V4L2FactoryIntegerFailedConversion) {
+TEST_F(PartialMetadataFactoryTest, V4L2FactoryIntegerFailedConversion) {
   int control_id = 55;
   v4l2_query_ext_ctrl query_result;
   query_result.type = V4L2_CTRL_TYPE_INTEGER;
@@ -380,7 +395,7 @@
   ASSERT_EQ(control_, nullptr);
 }
 
-TEST_F(ControlFactoryTest, V4L2FallbackMenu) {
+TEST_F(PartialMetadataFactoryTest, V4L2FallbackMenu) {
   uint8_t default_val = 9;
   int control_id = 55;
 
@@ -397,15 +412,15 @@
                                            default_val);
   ASSERT_NE(control_, nullptr);
 
-  ExpectTags();
+  ExpectControlTags();
 
   // Options should be available.
-  ExpectOptions({default_val});
+  ExpectControlOptions({default_val});
   // |default_val| should be default option.
-  ExpectValue(default_val);
+  ExpectControlValue(default_val);
 }
 
-TEST_F(ControlFactoryTest, V4L2FallbackSlider) {
+TEST_F(PartialMetadataFactoryTest, V4L2FallbackSlider) {
   uint8_t default_val = 9;
   int control_id = 55;
 
@@ -422,12 +437,12 @@
                                            default_val);
   ASSERT_NE(control_, nullptr);
 
-  ExpectTags();
+  ExpectControlTags();
 
   // Range containing only |default_val| should be available.
-  ExpectOptions({default_val, default_val});
+  ExpectControlOptions({default_val, default_val});
   // |default_val| should be default option.
-  ExpectValue(default_val);
+  ExpectControlValue(default_val);
 }
 
 }  // namespace v4l2_camera_hal
diff --git a/modules/camera/3_4/metadata/state.h b/modules/camera/3_4/metadata/state.h
new file mode 100644
index 0000000..54f66e4
--- /dev/null
+++ b/modules/camera/3_4/metadata/state.h
@@ -0,0 +1,96 @@
+/*
+ * 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_STATE_H_
+#define V4L2_CAMERA_HAL_METADATA_STATE_H_
+
+#include "../common.h"
+#include "metadata_common.h"
+#include "partial_metadata_interface.h"
+#include "state_delegate_interface.h"
+
+namespace v4l2_camera_hal {
+
+// A State is a PartialMetadata that only has a single dynamic value.
+template <typename T>
+class State : public PartialMetadataInterface {
+ public:
+  State(int32_t tag, std::unique_ptr<StateDelegateInterface<T>> delegate)
+      : tag_(tag), delegate_(std::move(delegate)){};
+
+  virtual std::vector<int32_t> StaticTags() const override { return {}; };
+  virtual std::vector<int32_t> ControlTags() const override { return {}; };
+  virtual std::vector<int32_t> DynamicTags() const override { return {tag_}; };
+
+  virtual int PopulateStaticFields(
+      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(
+      const android::CameraMetadata& metadata) override;
+
+ private:
+  int32_t tag_;
+  std::unique_ptr<StateDelegateInterface<T>> delegate_;
+};
+
+// -----------------------------------------------------------------------------
+
+template <typename T>
+int State<T>::PopulateStaticFields(android::CameraMetadata* metadata) const {
+  HAL_LOG_ENTER();
+  return 0;
+}
+
+template <typename T>
+int State<T>::PopulateDynamicFields(android::CameraMetadata* metadata) const {
+  HAL_LOG_ENTER();
+
+  T value;
+  int res = delegate_->GetValue(&value);
+  if (res) {
+    return res;
+  }
+  return UpdateMetadata(metadata, tag_, value);
+};
+
+template <typename T>
+int State<T>::PopulateTemplateRequest(int template_type,
+                                      android::CameraMetadata* metadata) const {
+  HAL_LOG_ENTER();
+  return 0;
+};
+
+template <typename T>
+bool State<T>::SupportsRequestValues(
+    const android::CameraMetadata& metadata) const {
+  HAL_LOG_ENTER();
+  return true;
+};
+
+template <typename T>
+int State<T>::SetRequestValues(const android::CameraMetadata& metadata) {
+  HAL_LOG_ENTER();
+  return 0;
+};
+
+}  // namespace v4l2_camera_hal
+
+#endif  // V4L2_CAMERA_HAL_METADATA_STATE_H_
diff --git a/modules/camera/3_4/metadata/state_delegate_interface_mock.h b/modules/camera/3_4/metadata/state_delegate_interface_mock.h
new file mode 100644
index 0000000..5064b83
--- /dev/null
+++ b/modules/camera/3_4/metadata/state_delegate_interface_mock.h
@@ -0,0 +1,37 @@
+/*
+ * 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 state delegate interfaces.
+
+#ifndef V4L2_CAMERA_HAL_METADATA_STATE_DELEGATE_INTERFACE_MOCK_H_
+#define V4L2_CAMERA_HAL_METADATA_STATE_DELEGATE_INTERFACE_MOCK_H_
+
+#include <gmock/gmock.h>
+
+#include "state_delegate_interface.h"
+
+namespace v4l2_camera_hal {
+
+template <typename T>
+class StateDelegateInterfaceMock : public StateDelegateInterface<T> {
+ public:
+  StateDelegateInterfaceMock(){};
+  MOCK_METHOD1_T(GetValue, int(T*));
+};
+
+}  // namespace v4l2_camera_hal
+
+#endif  // V4L2_CAMERA_HAL_METADATA_CONTROL_DELEGATE_INTERFACE_MOCK_H_
diff --git a/modules/camera/3_4/metadata/state_test.cpp b/modules/camera/3_4/metadata/state_test.cpp
new file mode 100644
index 0000000..5c308bc
--- /dev/null
+++ b/modules/camera/3_4/metadata/state_test.cpp
@@ -0,0 +1,116 @@
+/*
+ * 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 "state.h"
+
+#include <camera/CameraMetadata.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include "metadata_common.h"
+#include "state_delegate_interface_mock.h"
+#include "test_common.h"
+
+using testing::AtMost;
+using testing::Expectation;
+using testing::Return;
+using testing::SetArgPointee;
+using testing::Test;
+using testing::_;
+
+namespace v4l2_camera_hal {
+
+class StateTest : public Test {
+ protected:
+  virtual void SetUp() {
+    mock_delegate_.reset(new StateDelegateInterfaceMock<uint8_t>());
+    // Nullify state so an error will be thrown if a test doesn't call
+    // PrepareState.
+    state_.reset();
+  }
+
+  virtual void PrepareState() {
+    // Use this method after all the EXPECT_CALLs to pass ownership of the mocks
+    // to the device.
+    state_.reset(new State<uint8_t>(tag_, std::move(mock_delegate_)));
+  }
+
+  std::unique_ptr<State<uint8_t>> state_;
+  std::unique_ptr<StateDelegateInterfaceMock<uint8_t>> mock_delegate_;
+
+  // Need tag that matches the data type (uint8_t) being passed.
+  const int32_t tag_ = ANDROID_CONTROL_AF_STATE;
+};
+
+TEST_F(StateTest, Tags) {
+  PrepareState();
+  EXPECT_TRUE(state_->StaticTags().empty());
+  EXPECT_TRUE(state_->ControlTags().empty());
+  ASSERT_EQ(state_->DynamicTags().size(), 1);
+  EXPECT_EQ(state_->DynamicTags()[0], tag_);
+}
+
+TEST_F(StateTest, PopulateStatic) {
+  PrepareState();
+  android::CameraMetadata metadata;
+  ASSERT_EQ(state_->PopulateStaticFields(&metadata), 0);
+  EXPECT_TRUE(metadata.isEmpty());
+}
+
+TEST_F(StateTest, PopulateDynamic) {
+  uint8_t expected = 99;
+  EXPECT_CALL(*mock_delegate_, GetValue(_))
+      .WillOnce(DoAll(SetArgPointee<0>(expected), Return(0)));
+
+  PrepareState();
+
+  android::CameraMetadata metadata;
+  ASSERT_EQ(state_->PopulateDynamicFields(&metadata), 0);
+  EXPECT_EQ(metadata.entryCount(), 1);
+  ExpectMetadataEq(metadata, tag_, expected);
+}
+
+TEST_F(StateTest, PopulateDynamicFail) {
+  int err = 123;
+  EXPECT_CALL(*mock_delegate_, GetValue(_)).WillOnce(Return(err));
+
+  PrepareState();
+
+  android::CameraMetadata metadata;
+  ASSERT_EQ(state_->PopulateDynamicFields(&metadata), err);
+}
+
+TEST_F(StateTest, PopulateTemplate) {
+  int template_type = 3;
+  PrepareState();
+  android::CameraMetadata metadata;
+  ASSERT_EQ(state_->PopulateTemplateRequest(template_type, &metadata), 0);
+  EXPECT_TRUE(metadata.isEmpty());
+}
+
+TEST_F(StateTest, SupportsRequest) {
+  PrepareState();
+  android::CameraMetadata metadata;
+  EXPECT_TRUE(state_->SupportsRequestValues(metadata));
+}
+
+TEST_F(StateTest, SetRequest) {
+  PrepareState();
+  android::CameraMetadata metadata;
+  ASSERT_EQ(state_->SetRequestValues(metadata), 0);
+}
+
+}  // namespace v4l2_camera_hal
diff --git a/modules/camera/3_4/v4l2_metadata_factory.cpp b/modules/camera/3_4/v4l2_metadata_factory.cpp
index 6a7220b..412e6d4 100644
--- a/modules/camera/3_4/v4l2_metadata_factory.cpp
+++ b/modules/camera/3_4/v4l2_metadata_factory.cpp
@@ -21,9 +21,9 @@
 #include "common.h"
 #include "format_metadata_factory.h"
 #include "metadata/control.h"
-#include "metadata/control_factory.h"
 #include "metadata/enum_converter.h"
 #include "metadata/metadata_common.h"
+#include "metadata/partial_metadata_factory.h"
 #include "metadata/property.h"
 #include "metadata/scaling_converter.h"
 #include "v4l2_gralloc.h"
@@ -82,6 +82,12 @@
       NoEffectMenuControl<uint8_t>(ANDROID_CONTROL_AF_MODE,
                                    ANDROID_CONTROL_AF_AVAILABLE_MODES,
                                    {ANDROID_CONTROL_AF_MODE_OFF}));
+  // TODO(b/31021522): Should read autofocus state from
+  // V4L2_CID_AUTO_FOCUS_STATUS bitmask. The framework gets a little more
+  // complex than that does; there's a whole state-machine table in
+  // the docs (system/media/camera/docs/docs.html).
+  components.insert(FixedState<uint8_t>(ANDROID_CONTROL_AF_STATE,
+                                        ANDROID_CONTROL_AF_STATE_INACTIVE));
   // TODO(b/31022735): AE & AF triggers.
   components.insert(V4L2ControlOrDefault<uint8_t>(
       ControlType::kMenu,
@@ -136,7 +142,10 @@
     components.insert(std::move(exposure_time));
     components.insert(std::move(sensitivity));
   }
-
+  // Can't get AE status from V4L2.
+  // TODO(b/30510395): If AE mode is OFF, this should switch to INACTIVE.
+  components.insert(FixedState<uint8_t>(ANDROID_CONTROL_AE_STATE,
+                                        ANDROID_CONTROL_AE_STATE_CONVERGED));
   // V4L2 offers multiple white balance interfaces. Try the advanced one before
   // falling
   // back to the simpler version.
@@ -175,6 +184,9 @@
                                {1, ANDROID_CONTROL_AWB_MODE_AUTO}})),
         ANDROID_CONTROL_AWB_MODE_AUTO));
   }
+  // TODO(b/31041577): Handle AWB state machine correctly.
+  components.insert(FixedState<uint8_t>(ANDROID_CONTROL_AWB_STATE,
+                                        ANDROID_CONTROL_AWB_STATE_CONVERGED));
   // TODO(b/31022153): 3A locks.
   components.insert(std::unique_ptr<PartialMetadataInterface>(
       new Property<uint8_t>(ANDROID_CONTROL_AE_LOCK_AVAILABLE,
@@ -245,6 +257,8 @@
   components.insert(
       std::unique_ptr<PartialMetadataInterface>(new Property<uint8_t>(
           ANDROID_FLASH_INFO_AVAILABLE, ANDROID_FLASH_INFO_AVAILABLE_FALSE)));
+  components.insert(FixedState<uint8_t>(ANDROID_FLASH_STATE,
+                                        ANDROID_FLASH_STATE_UNAVAILABLE));
 
   // TODO(30510395): subcomponents of hotpixel.
   // No known V4L2 hot pixel correction. But it might be happening,
@@ -295,6 +309,9 @@
                                  ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
                                  {0}));
   // info.hyperfocalDistance not required for UNCALIBRATED.
+  // No way to know when the lens is moving or not in V4L2.
+  components.insert(
+      FixedState<uint8_t>(ANDROID_LENS_STATE, ANDROID_LENS_STATE_STATIONARY));
   // No known V4L2 lens shading. But it might be happening,
   // so report FAST/HIGH_QUALITY.
   components.insert(NoEffectMenuControl<uint8_t>(
@@ -369,6 +386,9 @@
   components.insert(
       std::unique_ptr<PartialMetadataInterface>(new Property<int32_t>(
           ANDROID_SYNC_MAX_LATENCY, ANDROID_SYNC_MAX_LATENCY_UNKNOWN)));
+  // Never know when controls are synced.
+  components.insert(FixedState<int64_t>(ANDROID_SYNC_FRAME_NUMBER,
+                                        ANDROID_SYNC_FRAME_NUMBER_UNKNOWN));
 
   // TODO(b/31022480): subcomponents of cropping/sensors.
   // Need ANDROID_SCALER_CROP_REGION control support.
@@ -404,6 +424,11 @@
   components.insert(std::unique_ptr<PartialMetadataInterface>(
       new Property<uint8_t>(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
                             ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN)));
+  // TODO(b/29457051): Actually get a timestamp here. For now spoofing as non-0.
+  components.insert(FixedState<int64_t>(ANDROID_SENSOR_TIMESTAMP, 1));
+  // No way to actually get shutter skew from V4L2.
+  components.insert(
+      FixedState<int64_t>(ANDROID_SENSOR_ROLLING_SHUTTER_SKEW, 0));
   // No way to actually get orientation from V4L2.
   components.insert(std::unique_ptr<PartialMetadataInterface>(
       new Property<int32_t>(ANDROID_SENSOR_ORIENTATION, 0)));