Added default metadata entries.

Default entries for controls/properties that could theoretically
be queried from/controlled by V4L2, but are not yet implemented
in this HAL.

BUG: 30140438
TEST: unit tests pass
Change-Id: I78264f3f0d37b41614b24ef71000fee175a3bb17
diff --git a/modules/camera/3_4/metadata/control.h b/modules/camera/3_4/metadata/control.h
index c0426c1..6442f90 100644
--- a/modules/camera/3_4/metadata/control.h
+++ b/modules/camera/3_4/metadata/control.h
@@ -120,10 +120,18 @@
 
   // Populate with a default.
   T value;
-  int res = options_->DefaultValueForTemplate(template_type, &value);
+  int res;
+  if (options_) {
+    res = options_->DefaultValueForTemplate(template_type, &value);
+  } else {
+    // If there's no options (and thus no default option),
+    // fall back to whatever the current value is.
+    res = delegate_->GetValue(&value);
+  }
   if (res) {
     return res;
   }
+
   return UpdateMetadata(metadata, delegate_->tag(), value);
 }
 
diff --git a/modules/camera/3_4/metadata/control_factory.h b/modules/camera/3_4/metadata/control_factory.h
index 911b67f..f461cfa 100644
--- a/modules/camera/3_4/metadata/control_factory.h
+++ b/modules/camera/3_4/metadata/control_factory.h
@@ -33,6 +33,12 @@
 
 // Static functions to create controls. Nullptr is returned on failures.
 
+// NoEffectOptionlessControl: A control that accepts any value,
+// and has no effect. A default value is given.
+template <typename T>
+static std::unique_ptr<Control<T>> NoEffectOptionlessControl(
+    int32_t delegate_tag, T default_value);
+
 // NoEffectMenuControl: Some menu options, but they have no effect.
 // The default value will be the first element of |options|.
 template <typename T>
@@ -80,6 +86,18 @@
 // -----------------------------------------------------------------------------
 
 template <typename T>
+std::unique_ptr<Control<T>> NoEffectOptionlessControl(int32_t delegate_tag,
+                                                      T default_value) {
+  HAL_LOG_ENTER();
+
+  return std::make_unique<Control<T>>(
+      std::make_unique<TaggedControlDelegate<T>>(
+          delegate_tag,
+          std::make_unique<NoEffectControlDelegate<T>>(default_value)),
+      nullptr);
+}
+
+template <typename T>
 std::unique_ptr<Control<T>> NoEffectMenuControl(int32_t delegate_tag,
                                                 int32_t options_tag,
                                                 const std::vector<T>& options) {
diff --git a/modules/camera/3_4/metadata/control_test.cpp b/modules/camera/3_4/metadata/control_test.cpp
index a56a110..572f25f 100644
--- a/modules/camera/3_4/metadata/control_test.cpp
+++ b/modules/camera/3_4/metadata/control_test.cpp
@@ -178,6 +178,30 @@
   EXPECT_EQ(control_->PopulateTemplateRequest(template_type, &metadata), err);
 }
 
+TEST_F(ControlTest, PopulateTemplateOptionless) {
+  int template_type = 3;
+  uint8_t value = 12;
+  // Should use delegate instead of options if no options.
+  EXPECT_CALL(*mock_delegate_, GetValue(_))
+      .WillOnce(DoAll(SetArgPointee<0>(value), Return(0)));
+  PrepareControl(false);
+
+  android::CameraMetadata metadata;
+  EXPECT_EQ(control_->PopulateTemplateRequest(template_type, &metadata), 0);
+  ExpectMetadataEq(metadata, delegate_tag_, value);
+}
+
+TEST_F(ControlTest, PopulateTemplateOptionlessFail) {
+  int template_type = 3;
+  int err = 10;
+  // Should use delegate instead of options if no options.
+  EXPECT_CALL(*mock_delegate_, GetValue(_)).WillOnce(Return(err));
+  PrepareControl(false);
+
+  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/scaling_converter.h b/modules/camera/3_4/metadata/scaling_converter.h
index 42b08a7..3087167 100644
--- a/modules/camera/3_4/metadata/scaling_converter.h
+++ b/modules/camera/3_4/metadata/scaling_converter.h
@@ -46,8 +46,7 @@
     TMetadata v4l2_to_metadata_numerator,
     TMetadata v4l2_to_metadata_denominator)
     : v4l2_to_metadata_numerator_(v4l2_to_metadata_numerator),
-      v4l2_to_metadata_denominator_(v4l2_to_metadata_denominator),
-{
+      v4l2_to_metadata_denominator_(v4l2_to_metadata_denominator) {
   HAL_LOG_ENTER();
 }
 
diff --git a/modules/camera/3_4/v4l2_metadata_factory.cpp b/modules/camera/3_4/v4l2_metadata_factory.cpp
index 86c9a4d..6a7220b 100644
--- a/modules/camera/3_4/v4l2_metadata_factory.cpp
+++ b/modules/camera/3_4/v4l2_metadata_factory.cpp
@@ -25,9 +25,18 @@
 #include "metadata/enum_converter.h"
 #include "metadata/metadata_common.h"
 #include "metadata/property.h"
+#include "metadata/scaling_converter.h"
+#include "v4l2_gralloc.h"
 
 namespace v4l2_camera_hal {
 
+// According to spec, each unit of V4L2_CID_AUTO_EXPOSURE_BIAS is 0.001 EV.
+const camera_metadata_rational_t kAeCompensationUnit = {1, 1000};
+// According to spec, each unit of V4L2_CID_EXPOSURE_ABSOLUTE is 100 us.
+const int64_t kV4L2ExposureTimeStepNs = 100000;
+// According to spec, each unit of V4L2_CID_ISO_SENSITIVITY is ISO/1000.
+const int32_t kV4L2SensitivityDenominator = 1000;
+
 int GetV4L2Metadata(std::shared_ptr<V4L2Wrapper> device,
                     std::unique_ptr<Metadata>* result) {
   HAL_LOG_ENTER();
@@ -54,6 +63,26 @@
   components.insert(std::unique_ptr<PartialMetadataInterface>(
       new Property<std::array<int32_t, 3>>(ANDROID_CONTROL_MAX_REGIONS,
                                            {{/*AE*/ 0, /*AWB*/ 0, /*AF*/ 0}})));
+  // TODO(b/30921166): V4L2_CID_AUTO_EXPOSURE_BIAS is an int menu, so
+  // this will be falling back to NoEffect until int menu support is added.
+  components.insert(V4L2ControlOrDefault<int32_t>(
+      ControlType::kSlider,
+      ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
+      ANDROID_CONTROL_AE_COMPENSATION_RANGE,
+      device,
+      V4L2_CID_AUTO_EXPOSURE_BIAS,
+      // No scaling necessary, AE_COMPENSATION_STEP handles this.
+      std::make_shared<ScalingConverter<int32_t, int32_t>>(1, 1),
+      0));
+  components.insert(std::unique_ptr<PartialMetadataInterface>(
+      new Property<camera_metadata_rational_t>(
+          ANDROID_CONTROL_AE_COMPENSATION_STEP, kAeCompensationUnit)));
+  // TODO(b/31021522): Autofocus subcomponent, AFTrigger.
+  components.insert(
+      NoEffectMenuControl<uint8_t>(ANDROID_CONTROL_AF_MODE,
+                                   ANDROID_CONTROL_AF_AVAILABLE_MODES,
+                                   {ANDROID_CONTROL_AF_MODE_OFF}));
+  // TODO(b/31022735): AE & AF triggers.
   components.insert(V4L2ControlOrDefault<uint8_t>(
       ControlType::kMenu,
       ANDROID_CONTROL_AE_MODE,
@@ -80,6 +109,34 @@
                              {V4L2_CID_POWER_LINE_FREQUENCY_AUTO,
                               ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO}})),
       ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO));
+  std::unique_ptr<PartialMetadataInterface> exposure_time =
+      V4L2Control<int64_t>(ControlType::kSlider,
+                           ANDROID_SENSOR_EXPOSURE_TIME,
+                           ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
+                           device,
+                           V4L2_CID_EXPOSURE_ABSOLUTE,
+                           std::make_shared<ScalingConverter<int64_t, int32_t>>(
+                               kV4L2ExposureTimeStepNs, 1));
+  // TODO(b/31037072): Sensitivity has additional V4L2 controls
+  // (V4L2_CID_ISO_SENSITIVITY_AUTO), so this control currently has
+  // undefined behavior.
+  // TODO(b/30921166): V4L2_CID_ISO_SENSITIVITY is an int menu, so
+  // this will return nullptr until that is added.
+  std::unique_ptr<PartialMetadataInterface> sensitivity =
+      V4L2Control<int32_t>(ControlType::kSlider,
+                           ANDROID_SENSOR_SENSITIVITY,
+                           ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
+                           device,
+                           V4L2_CID_ISO_SENSITIVITY,
+                           std::make_shared<ScalingConverter<int32_t, int32_t>>(
+                               1, kV4L2SensitivityDenominator));
+  if (exposure_time && sensitivity) {
+    // TODO(b/30510395): as part of coordinated 3A component,
+    // if these aren't available don't advertise AE mode OFF, only AUTO.
+    components.insert(std::move(exposure_time));
+    components.insert(std::move(sensitivity));
+  }
+
   // V4L2 offers multiple white balance interfaces. Try the advanced one before
   // falling
   // back to the simpler version.
@@ -118,6 +175,13 @@
                                {1, ANDROID_CONTROL_AWB_MODE_AUTO}})),
         ANDROID_CONTROL_AWB_MODE_AUTO));
   }
+  // TODO(b/31022153): 3A locks.
+  components.insert(std::unique_ptr<PartialMetadataInterface>(
+      new Property<uint8_t>(ANDROID_CONTROL_AE_LOCK_AVAILABLE,
+                            ANDROID_CONTROL_AE_LOCK_AVAILABLE_FALSE)));
+  components.insert(std::unique_ptr<PartialMetadataInterface>(
+      new Property<uint8_t>(ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
+                            ANDROID_CONTROL_AWB_LOCK_AVAILABLE_FALSE)));
   // TODO(b/30510395): subcomponents of scene modes
   // (may itself be a subcomponent of 3A).
   // Modes from each API that don't match up:
@@ -143,6 +207,7 @@
            {V4L2_SCENE_MODE_SPORTS, ANDROID_CONTROL_SCENE_MODE_SPORTS},
            {V4L2_SCENE_MODE_SUNSET, ANDROID_CONTROL_SCENE_MODE_SUNSET}})),
       ANDROID_CONTROL_SCENE_MODE_DISABLED));
+  // TODO(b/31022612): Scene mode overrides.
   // Modes from each API that don't match up:
   // Android: POSTERIZE, WHITEBOARD, BLACKBOARD.
   // V4L2: ANTIQUE, ART_FREEZE, EMBOSS, GRASS_GREEN, SKETCH, SKIN_WHITEN,
@@ -161,6 +226,11 @@
            {V4L2_COLORFX_SEPIA, ANDROID_CONTROL_EFFECT_MODE_SEPIA},
            {V4L2_COLORFX_AQUA, ANDROID_CONTROL_EFFECT_MODE_AQUA}})),
       ANDROID_CONTROL_EFFECT_MODE_OFF));
+  // TODO(b/31021654): This should behave as a top level switch, not no effect.
+  components.insert(
+      NoEffectMenuControl<uint8_t>(ANDROID_CONTROL_MODE,
+                                   ANDROID_CONTROL_AVAILABLE_MODES,
+                                   {ANDROID_CONTROL_MODE_AUTO}));
 
   // 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
@@ -170,6 +240,12 @@
                                    ANDROID_EDGE_AVAILABLE_EDGE_MODES,
                                    {ANDROID_EDGE_MODE_FAST}));
 
+  // TODO(b/31023454): subcomponents of flash.
+  // Missing android.flash.mode control, since it uses a different enum.
+  components.insert(
+      std::unique_ptr<PartialMetadataInterface>(new Property<uint8_t>(
+          ANDROID_FLASH_INFO_AVAILABLE, ANDROID_FLASH_INFO_AVAILABLE_FALSE)));
+
   // TODO(30510395): subcomponents of hotpixel.
   // No known V4L2 hot pixel correction. But it might be happening,
   // so we report FAST/HIGH_QUALITY.
@@ -190,6 +266,10 @@
       NoEffectMenuControl<float>(ANDROID_LENS_APERTURE,
                                  ANDROID_LENS_INFO_AVAILABLE_APERTURES,
                                  {2.0}));  // RPi camera v2 is f/2.0.
+  // Always assume external-facing.
+  components.insert(
+      std::unique_ptr<PartialMetadataInterface>(new Property<uint8_t>(
+          ANDROID_LENS_FACING, ANDROID_LENS_FACING_EXTERNAL)));
   components.insert(
       NoEffectMenuControl<float>(ANDROID_LENS_FOCAL_LENGTH,
                                  ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
@@ -205,6 +285,15 @@
       std::unique_ptr<PartialMetadataInterface>(new Property<uint8_t>(
           ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION,
           ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION_UNCALIBRATED)));
+  // TODO(b/31022711): Focus distance component.
+  // Using a NoEffectMenuControl for now because for
+  // fixed-focus it meets expectations. Framework may allow
+  // setting any value and expect it to be clamped to 0, in which
+  // case this will have unexpected behavior (failing on non-0 settings).
+  components.insert(
+      NoEffectMenuControl<float>(ANDROID_LENS_FOCUS_DISTANCE,
+                                 ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
+                                 {0}));
   // info.hyperfocalDistance not required for UNCALIBRATED.
   // No known V4L2 lens shading. But it might be happening,
   // so report FAST/HIGH_QUALITY.
@@ -233,6 +322,11 @@
       ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
       ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
       {ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF}));
+  // TODO(b/31017806): This should definitely have a different default depending
+  // on template.
+  components.insert(NoEffectOptionlessControl<uint8_t>(
+      ANDROID_CONTROL_CAPTURE_INTENT,
+      ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE));
 
   // Unable to control noise reduction in V4L2 devices,
   // but FAST is allowed to be the same as OFF.
@@ -249,6 +343,11 @@
       ANDROID_JPEG_THUMBNAIL_SIZE,
       ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
       {{{0, 0}}}));
+  // TODO(b/31022752): Get this from the device,
+  // not constant (from V4L2Gralloc.h).
+  components.insert(std::unique_ptr<PartialMetadataInterface>(
+      new Property<int32_t>(ANDROID_JPEG_MAX_SIZE, V4L2_MAX_JPEG_SIZE)));
+  // TODO(b/31021672): Other JPEG controls (GPS, quality, orientation).
   // TODO(b/29939583): V4L2 can only support 1 stream at a time.
   // For now, just reporting minimum allowable for LIMITED devices.
   components.insert(std::unique_ptr<PartialMetadataInterface>(
@@ -271,14 +370,29 @@
       std::unique_ptr<PartialMetadataInterface>(new Property<int32_t>(
           ANDROID_SYNC_MAX_LATENCY, ANDROID_SYNC_MAX_LATENCY_UNKNOWN)));
 
-  // TODO(30510395): subcomponents of cropping/sensors.
+  // TODO(b/31022480): subcomponents of cropping/sensors.
+  // Need ANDROID_SCALER_CROP_REGION control support.
   // 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.
   components.insert(std::unique_ptr<PartialMetadataInterface>(
+      new Property<float>(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM, 1)));
+  components.insert(std::unique_ptr<PartialMetadataInterface>(
       new Property<uint8_t>(ANDROID_SCALER_CROPPING_TYPE,
                             ANDROID_SCALER_CROPPING_TYPE_FREEFORM)));
+  // Spoof pixel array size for now, eventually get from CROPCAP.
+  std::array<int32_t, 2> pixel_array_size = {{640, 480}};
+  components.insert(std::unique_ptr<PartialMetadataInterface>(
+      new Property<std::array<int32_t, 2>>(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
+                                           pixel_array_size)));
+  // Active array size is {x-offset, y-offset, width, height}, relative to
+  // the pixel array size, with {0, 0} being the top left. Since there's no way
+  // to get this in V4L2, assume the full pixel array is the active array.
+  components.insert(std::unique_ptr<PartialMetadataInterface>(
+      new Property<std::array<int32_t, 4>>(
+          ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
+          {{0, 0, pixel_array_size[0], pixel_array_size[1]}})));
   // 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.
@@ -290,9 +404,13 @@
   components.insert(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.
+  // No way to actually get orientation from V4L2.
   components.insert(std::unique_ptr<PartialMetadataInterface>(
       new Property<int32_t>(ANDROID_SENSOR_ORIENTATION, 0)));
+  // TODO(b/31023611): Should actually do something for this, and range should
+  // be dependent on the stream configuration being used.
+  components.insert(NoEffectOptionlessControl<int64_t>(
+      ANDROID_SENSOR_FRAME_DURATION, 33333333L));  // 1/30 s.
 
   // TODO(30510395): subcomponents of face detection.
   // Face detection not supported.
@@ -303,6 +421,12 @@
   components.insert(std::unique_ptr<PartialMetadataInterface>(
       new Property<int32_t>(ANDROID_STATISTICS_INFO_MAX_FACE_COUNT, 0)));
 
+  // TOOD(b/31023265): V4L2_CID_FLASH_INDICATOR_INTENSITY could be queried
+  // to see if there's a transmit LED. Would need to translate HAL off/on
+  // enum to slider min/max value. For now, no LEDs available.
+  components.insert(std::unique_ptr<PartialMetadataInterface>(
+      new Property<uint8_t>(ANDROID_LED_AVAILABLE_LEDS, {})));
+
   /* Capabilities. */
   // The V4L2Metadata pretends to at least meet the
   // "LIMITED" and "BACKWARD_COMPATIBLE" functionality requirements.
@@ -314,6 +438,10 @@
           ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
           {ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE})));
 
+  // Request is unused, and can be any value,
+  // but that value needs to be propagated.
+  components.insert(NoEffectOptionlessControl<int32_t>(ANDROID_REQUEST_ID, 0));
+
   int res =
       AddFormatComponents(device, std::inserter(components, components.end()));
   if (res) {