Merge "trivial: fix various spelling and grammatical errors in AIDL definitions." into main
diff --git a/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp b/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
index d4b0528..7f5e06d 100644
--- a/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
+++ b/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
@@ -96,6 +96,10 @@
 static constexpr char ANNOTATION_SUPPORTED_VALUES_IN_CONFIG[] = "legacy_supported_values_in_config";
 static constexpr char ANNOTATIONS_DATA_ENUM[] = "data_enum";
 
+inline VehiclePropertyType getPropertyType(int32_t propId) {
+    return static_cast<VehiclePropertyType>(propId & toInt(VehiclePropertyType::MASK));
+}
+
 struct ServiceDescriptor {
     std::string name;
     bool isAidlService;
@@ -181,10 +185,12 @@
     void testGetMinMaxSupportedValueForPropIdAreaId(int32_t propId,
                                                     const IHalAreaConfig& areaConfig,
                                                     bool minMaxValueRequired);
+    void testGetSupportedValuesListsForPropIdAreaId(int32_t propId,
+                                                    const IHalAreaConfig& areaConfig,
+                                                    bool supportedValuesRequired);
 
     static bool isBooleanGlobalProp(int32_t property) {
-        return (property & toInt(VehiclePropertyType::MASK)) ==
-                       toInt(VehiclePropertyType::BOOLEAN) &&
+        return getPropertyType(property) == VehiclePropertyType::BOOLEAN &&
                (property & toInt(VehicleArea::MASK)) == toInt(VehicleArea::GLOBAL);
     }
 
@@ -810,39 +816,36 @@
     }
 }
 
-void verifyRawPropValues(const RawPropValues& rawPropValues, int32_t propertyType) {
+void verifyRawPropValues(const RawPropValues& rawPropValues, VehiclePropertyType propertyType) {
     switch (propertyType) {
-        case toInt(VehiclePropertyType::INT32):
+        case VehiclePropertyType::INT32:
             ASSERT_THAT(rawPropValues.int32Values, ::testing::SizeIs(1))
                     << "int32Values field must contain exactly one element for INT32 type";
             break;
-        case toInt(VehiclePropertyType::FLOAT):
+        case VehiclePropertyType::FLOAT:
             ASSERT_THAT(rawPropValues.floatValues, ::testing::SizeIs(1))
                     << "floatValues field must contain exactly one element for FLOAT type";
             break;
-        case toInt(VehiclePropertyType::INT64):
+        case VehiclePropertyType::INT64:
             ASSERT_THAT(rawPropValues.int64Values, ::testing::SizeIs(1))
                     << "int64Values field must contain exactly one element for INT64 type";
             break;
         default:
-            // This must not happen since we already checked this condition in
-            // verifyPropertyConfigMinMaxValue
-            FAIL() << "minSupportedValue or maxSupportedValue must only be specified for "
-                      "INT32, INT64 or FLOAT type property";
+            // We do not check for other types.
             break;
     }
 }
 
 void VtsHalAutomotiveTest::testGetMinMaxSupportedValueForPropIdAreaId(
         int32_t propId, const IHalAreaConfig& areaConfig, bool minMaxValueRequired) {
-    int areaId = areaConfig.getAreaId();
-    int propertyType = propId & toInt(VehiclePropertyType::MASK);
+    int32_t areaId = areaConfig.getAreaId();
+    VehiclePropertyType propertyType = getPropertyType(propId);
     std::optional<HasSupportedValueInfo> maybeHasSupportedValueInfo =
             areaConfig.getHasSupportedValueInfo();
     if (!maybeHasSupportedValueInfo.has_value()) {
         return;
     }
-    if (!maybeHasSupportedValueInfo->hasMaxSupportedValue &&
+    if (!maybeHasSupportedValueInfo->hasMinSupportedValue &&
         !maybeHasSupportedValueInfo->hasMaxSupportedValue) {
         return;
     }
@@ -859,8 +862,7 @@
     const MinMaxSupportedValueResult& individualResult = (*result)[0];
     if (minMaxValueRequired) {
         ASSERT_EQ(individualResult.status, StatusCode::OK)
-                << "getMinMaxSupportedValue must return okay status if min/max value is required "
-                   "for";
+                << "getMinMaxSupportedValue must return okay status if min/max value is required";
     }
     if (individualResult.status != StatusCode::OK) {
         return;
@@ -895,19 +897,19 @@
         int64_t minInt64Value;
         int64_t maxInt64Value;
         switch (propertyType) {
-            case toInt(VehiclePropertyType::INT32):
+            case VehiclePropertyType::INT32:
                 minInt32Value = (individualResult.minSupportedValue)->int32Values[0];
                 maxInt32Value = (individualResult.maxSupportedValue)->int32Values[0];
                 ASSERT_LE(minInt32Value, maxInt32Value)
                         << "minSupportedValue must be less or equal to maxSupportedValue";
                 break;
-            case toInt(VehiclePropertyType::FLOAT):
+            case VehiclePropertyType::FLOAT:
                 minFloatValue = (individualResult.minSupportedValue)->floatValues[0];
                 maxFloatValue = (individualResult.maxSupportedValue)->floatValues[0];
                 ASSERT_LE(minFloatValue, maxFloatValue)
                         << "minSupportedValue must be less or equal to maxSupportedValue";
                 break;
-            case toInt(VehiclePropertyType::INT64):
+            case VehiclePropertyType::INT64:
                 minInt64Value = (individualResult.minSupportedValue)->int64Values[0];
                 maxInt64Value = (individualResult.maxSupportedValue)->int64Values[0];
                 ASSERT_LE(minInt64Value, maxInt64Value)
@@ -923,12 +925,12 @@
     }
 }
 
-// Test the getMinMaxSupportedValues API. We use this one test case to cover all properties that
+// Test the getMinMaxSupportedValue API. We use this one test case to cover all properties that
 // may support this API.
 TEST_P(VtsHalAutomotiveVehicleTargetTest, testGetMinMaxSupportedValue) {
     if (!mVhalClient->isAidlVhal() || mVhalClient->getRemoteInterfaceVersion() < 4) {
-        GTEST_SKIP() << "Skip checking testGetMinMaxSupportedValues the behavior is not supported "
-                        "for current VHAL version";
+        GTEST_SKIP() << "Skip checking getMinMaxSupportedValue because the behavior is not "
+                        "supported for current VHAL version";
     }
 
     auto configsResult = mVhalClient->getAllPropConfigs();
@@ -956,12 +958,93 @@
     }
 }
 
-void verifyPropertyConfigMinMaxValue(const IHalPropConfig* config, int32_t propertyType) {
+void VtsHalAutomotiveTest::testGetSupportedValuesListsForPropIdAreaId(
+        int32_t propId, const IHalAreaConfig& areaConfig, bool supportedValuesRequired) {
+    int32_t areaId = areaConfig.getAreaId();
+    VehiclePropertyType propertyType = getPropertyType(propId);
+    std::optional<HasSupportedValueInfo> maybeHasSupportedValueInfo =
+            areaConfig.getHasSupportedValueInfo();
+    if (!maybeHasSupportedValueInfo.has_value()) {
+        return;
+    }
+    if (!maybeHasSupportedValueInfo->hasSupportedValuesList) {
+        return;
+    }
+    VhalClientResult<std::vector<SupportedValuesListResult>> result =
+            mVhalClient->getSupportedValuesLists({PropIdAreaId{
+                    .propId = propId,
+                    .areaId = areaId,
+            }});
+    ASSERT_RESULT_OK(result)
+            << "getSupportedValuesLists must return okay result if hasSupportedValuesList is true";
+    ASSERT_THAT(*result, ::testing::SizeIs(1))
+            << "getSupportedValuesLists result list size must be 1 for 1 request";
+    const SupportedValuesListResult& individualResult = (*result)[0];
+    if (supportedValuesRequired) {
+        ASSERT_EQ(individualResult.status, StatusCode::OK)
+                << "getSupportedValuesLists must return okay status if supported values are "
+                   "required";
+    }
+    if (individualResult.status != StatusCode::OK) {
+        return;
+    }
+    ASSERT_TRUE(individualResult.supportedValuesList.has_value())
+            << "supportedValuesList field must not be null if hasSupportedValuesList is true";
+    const std::vector<std::optional<RawPropValues>>& supportedValuesList =
+            individualResult.supportedValuesList.value();
+    if (supportedValuesRequired) {
+        ASSERT_THAT(supportedValuesList, ::testing::Not(::testing::IsEmpty()))
+                << "supportedValuesList must not be empty if supported values are required";
+    }
+    for (const std::optional<RawPropValues>& supportedValue : supportedValuesList) {
+        ASSERT_TRUE(supportedValue.has_value())
+                << "Each item in supportedValuesList must not be null";
+        ASSERT_NO_FATAL_FAILURE(verifyRawPropValues(*supportedValue, propertyType))
+                << "one of supported value is not a valid RawPropValues for "
+                << "the property type, value: " << supportedValue->toString();
+    }
+}
+
+// Test the getSupportedValues API. We use this one test case to cover all properties that
+// may support this API.
+TEST_P(VtsHalAutomotiveVehicleTargetTest, testGetSupportedValuesLists) {
+    if (!mVhalClient->isAidlVhal() || mVhalClient->getRemoteInterfaceVersion() < 4) {
+        GTEST_SKIP() << "Skip checking getSupportedValuesLists because the behavior is not "
+                        "supported for current VHAL version";
+    }
+
+    auto configsResult = mVhalClient->getAllPropConfigs();
+    ASSERT_TRUE(configsResult.ok())
+            << "Failed to get all property configs, error: " << configsResult.error().message();
+
+    for (const auto& cfgPtr : configsResult.value()) {
+        int32_t propId = cfgPtr->getPropId();
+        bool supportedValuesRequired = false;
+        std::unordered_set<std::string> annotations;
+        auto it = AnnotationsForVehicleProperty.find(static_cast<VehicleProperty>(propId));
+        if (it != AnnotationsForVehicleProperty.end()) {
+            annotations = it->second;
+        }
+        if (annotations.find(ANNOTATION_REQUIRE_SUPPORTED_VALUES) != annotations.end()) {
+            supportedValuesRequired = true;
+        }
+        const std::vector<std::unique_ptr<IHalAreaConfig>>& areaConfigs = cfgPtr->getAreaConfigs();
+        for (const auto& areaCfgPtr : areaConfigs) {
+            EXPECT_NO_FATAL_FAILURE(testGetSupportedValuesListsForPropIdAreaId(
+                    propId, *areaCfgPtr, supportedValuesRequired))
+                    << "test getSupportedValues failed for property: " << propIdToString(propId)
+                    << ", areaId: " << areaCfgPtr->getAreaId();
+        }
+    }
+}
+
+void verifyPropertyConfigMinMaxValue(const IHalPropConfig* config,
+                                     VehiclePropertyType propertyType) {
     for (const auto& areaConfig : config->getAreaConfigs()) {
         std::optional<HasSupportedValueInfo> maybeHasSupportedValueInfo =
                 areaConfig->getHasSupportedValueInfo();
         if (areaConfig->getMinInt32Value() != 0 || areaConfig->getMaxInt32Value() != 0) {
-            EXPECT_EQ(propertyType, toInt(VehiclePropertyType::INT32))
+            EXPECT_EQ(propertyType, VehiclePropertyType::INT32)
                     << "minInt32Value and maxInt32Value must not be specified for INT32 type "
                        "property";
             EXPECT_THAT(areaConfig->getMinInt32Value(),
@@ -977,7 +1060,7 @@
             }
         }
         if (areaConfig->getMinFloatValue() != 0 || areaConfig->getMaxFloatValue() != 0) {
-            EXPECT_EQ(propertyType, toInt(VehiclePropertyType::FLOAT))
+            EXPECT_EQ(propertyType, VehiclePropertyType::FLOAT)
                     << "minFloatValue and maxFloatValue must not be specified for FLOAT type "
                        "property";
             EXPECT_THAT(areaConfig->getMinFloatValue(),
@@ -993,7 +1076,7 @@
             }
         }
         if (areaConfig->getMinInt64Value() != 0 || areaConfig->getMaxInt64Value() != 0) {
-            EXPECT_EQ(propertyType, toInt(VehiclePropertyType::INT64))
+            EXPECT_EQ(propertyType, VehiclePropertyType::INT64)
                     << "minInt64Value and maxInt64Value must not be specified for INT64 type "
                        "property";
             EXPECT_THAT(areaConfig->getMinInt64Value(),
@@ -1011,9 +1094,9 @@
         if (maybeHasSupportedValueInfo.has_value() &&
             (maybeHasSupportedValueInfo->hasMinSupportedValue ||
              maybeHasSupportedValueInfo->hasMaxSupportedValue)) {
-            EXPECT_THAT(propertyType, ::testing::AnyOf(toInt(VehiclePropertyType::INT32),
-                                                       toInt(VehiclePropertyType::INT64),
-                                                       toInt(VehiclePropertyType::FLOAT)))
+            EXPECT_THAT(propertyType,
+                        ::testing::AnyOf(VehiclePropertyType::INT32, VehiclePropertyType::INT64,
+                                         VehiclePropertyType::FLOAT))
                     << "HasSupportedValueInfo.hasMinSupportedValue and "
                        "HasSupportedValueInfo.hasMaxSupportedValue is only allowed to be set to "
                        "true "
@@ -1022,27 +1105,31 @@
     }
 }
 
-void verifyPropertyConfigRequireMinMaxValue(const IHalPropConfig* config, int propertyType) {
+void verifyPropertyConfigRequireMinMaxValue(const IHalPropConfig* config,
+                                            VehiclePropertyType propertyType) {
     for (const auto& areaConfig : config->getAreaConfigs()) {
         switch (propertyType) {
-            case toInt(VehiclePropertyType::INT32):
+            case VehiclePropertyType::INT32:
                 EXPECT_FALSE(areaConfig->getMinInt32Value() == 0 &&
                              areaConfig->getMaxInt32Value() == 0)
                         << "minInt32Value and maxInt32Value must not both be 0 because "
                            "min and max value is required for this property";
                 break;
-            case toInt(VehiclePropertyType::FLOAT):
+            case VehiclePropertyType::FLOAT:
                 EXPECT_FALSE(areaConfig->getMinFloatValue() == 0 &&
                              areaConfig->getMaxFloatValue() == 0)
                         << "minFloatValue and maxFloatValue must not both be 0 because "
                            "min and max value is required for this property";
                 break;
-            case toInt(VehiclePropertyType::INT64):
+            case VehiclePropertyType::INT64:
                 EXPECT_FALSE(areaConfig->getMinInt64Value() == 0 &&
                              areaConfig->getMaxInt64Value() == 0)
                         << "minInt64Value and maxInt64Value must not both be 0 because "
                            "min and max value is required for this property";
                 break;
+            default:
+                // Do nothing.
+                break;
         }
 
         std::optional<HasSupportedValueInfo> maybeHasSupportedValueInfo =
@@ -1171,7 +1258,7 @@
         annotations = it->second;
     }
 
-    int propertyType = expectedPropId & toInt(VehiclePropertyType::MASK);
+    VehiclePropertyType propertyType = getPropertyType(expectedPropId);
     verifyPropertyConfigMinMaxValue(config.get(), propertyType);
     if (annotations.find(ANNOTATION_REQUIRE_MIN_MAX_VALUE) != annotations.end()) {
         verifyPropertyConfigRequireMinMaxValue(config.get(), propertyType);
@@ -1215,6 +1302,7 @@
 }
 
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VtsHalAutomotiveVehicleTargetTest);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VtsHalAutomotivePropertyConfigTest);
 
 INSTANTIATE_TEST_SUITE_P(PerInstance, VtsHalAutomotiveVehicleTargetTest,
                          testing::ValuesIn(getDescriptors()),
diff --git a/gnss/aidl/android/hardware/gnss/gnss_assistance/AuxiliaryInformation.aidl b/gnss/aidl/android/hardware/gnss/gnss_assistance/AuxiliaryInformation.aidl
index f6c6cb9..61b510b 100644
--- a/gnss/aidl/android/hardware/gnss/gnss_assistance/AuxiliaryInformation.aidl
+++ b/gnss/aidl/android/hardware/gnss/gnss_assistance/AuxiliaryInformation.aidl
@@ -21,6 +21,8 @@
 /**
  * Contains parameters to provide additional information dependent on the GNSS constellation.
  *
+ * If svid is -1, the AuxiliaryInformation is not available.
+ *
  * @hide
  */
 @VintfStability
@@ -49,6 +51,8 @@
      * - QZSS:    183-206
      * - Galileo: 1-36
      * - Beidou:  1-63
+     *
+     * If it is -1, the AuxiliaryInformation is not available.
      */
     int svid;
 
diff --git a/gnss/aidl/android/hardware/gnss/gnss_assistance/GalileoIonosphericModel.aidl b/gnss/aidl/android/hardware/gnss/gnss_assistance/GalileoIonosphericModel.aidl
index ced8917..65f840c 100644
--- a/gnss/aidl/android/hardware/gnss/gnss_assistance/GalileoIonosphericModel.aidl
+++ b/gnss/aidl/android/hardware/gnss/gnss_assistance/GalileoIonosphericModel.aidl
@@ -18,7 +18,9 @@
 
 /**
  * Contains Galileo ionospheric model.
- * This is Defined in Galileo-OS-SIS-ICD-v2.1, 5.1.6.
+ * This is defined in Galileo-OS-SIS-ICD-v2.1, 5.1.6.
+ *
+ * If all coefficients are 0, the GalileoIonosphericModel is not available.
  *
  * @hide
  */
diff --git a/gnss/aidl/android/hardware/gnss/gnss_assistance/GlonassAlmanac.aidl b/gnss/aidl/android/hardware/gnss/gnss_assistance/GlonassAlmanac.aidl
index ebf6c05..25e8c4b 100644
--- a/gnss/aidl/android/hardware/gnss/gnss_assistance/GlonassAlmanac.aidl
+++ b/gnss/aidl/android/hardware/gnss/gnss_assistance/GlonassAlmanac.aidl
@@ -20,6 +20,8 @@
  * Contains Glonass almanac data.
  * This is defined in Glonass ICD v5.1, section 4.5.
  *
+ * If issueDateMs is -1, the GlonassAlmanac is not available.
+ *
  * @hide
  */
 @VintfStability
@@ -77,7 +79,10 @@
         double omega;
     }
 
-    /** Almanac issue date in milliseconds (UTC). */
+    /**
+     * Almanac issue date in milliseconds (UTC).
+     * If it is -1, the GlonassAlmanac is not available.
+     */
     long issueDateMs;
 
     /** Array of GlonassSatelliteAlmanac. */
diff --git a/gnss/aidl/android/hardware/gnss/gnss_assistance/GnssAlmanac.aidl b/gnss/aidl/android/hardware/gnss/gnss_assistance/GnssAlmanac.aidl
index f12378b..e03bbf0 100644
--- a/gnss/aidl/android/hardware/gnss/gnss_assistance/GnssAlmanac.aidl
+++ b/gnss/aidl/android/hardware/gnss/gnss_assistance/GnssAlmanac.aidl
@@ -24,6 +24,8 @@
  * For QZSS, this is defined in IS-QZSS-PNT section 4.1.2.6.
  * For Galileo, this is defined in Galileo-OS-SIS-ICD-v2.1 section 5.1.10.
  *
+ * If weekNumber is -1, the GnssAlmanac is not available.
+ *
  * @hide
  */
 @VintfStability
@@ -44,6 +46,7 @@
 
     /**
      * Almanac reference week number.
+     * If it is -1, the GnssAlmanac is not available.
      *
      * For GPS and QZSS, this is GPS week number (modulo 1024).
      * For Beidou, this is Baidou week number (modulo 8192).
diff --git a/gnss/aidl/android/hardware/gnss/gnss_assistance/KlobucharIonosphericModel.aidl b/gnss/aidl/android/hardware/gnss/gnss_assistance/KlobucharIonosphericModel.aidl
index e261e97..c1dba78 100644
--- a/gnss/aidl/android/hardware/gnss/gnss_assistance/KlobucharIonosphericModel.aidl
+++ b/gnss/aidl/android/hardware/gnss/gnss_assistance/KlobucharIonosphericModel.aidl
@@ -20,6 +20,8 @@
  * Contains Klobuchar ionospheric model coefficients used by GPS, BDS, QZSS.
  * This is defined in IS-GPS-200 20.3.3.5.1.7.
  *
+ * If all coefficients are 0, the KlobucharIonosphericModel is not available.
+ *
  * @hide
  */
 @VintfStability
diff --git a/gnss/aidl/android/hardware/gnss/gnss_assistance/LeapSecondsModel.aidl b/gnss/aidl/android/hardware/gnss/gnss_assistance/LeapSecondsModel.aidl
index 0ebd46d..d05fba8 100644
--- a/gnss/aidl/android/hardware/gnss/gnss_assistance/LeapSecondsModel.aidl
+++ b/gnss/aidl/android/hardware/gnss/gnss_assistance/LeapSecondsModel.aidl
@@ -20,11 +20,16 @@
  * Contains the leap seconds set of parameters needed for GNSS time.
  * This is defined in RINEX 3.05 "LEAP SECONDS" in table A2.
  *
+ * If leapSeconds is -1, the LeapSecondsModel is not available.
+ *
  * @hide
  */
 @VintfStability
 parcelable LeapSecondsModel {
-    /** Time difference due to leap seconds before the event in seconds. */
+    /**
+     * Time difference due to leap seconds before the event in seconds.
+     * If it is -1, the LeapSecondsModel is not available.
+     */
     int leapSeconds;
 
     /** Time difference due to leap seconds after the event in seconds. */
diff --git a/gnss/aidl/android/hardware/gnss/gnss_assistance/UtcModel.aidl b/gnss/aidl/android/hardware/gnss/gnss_assistance/UtcModel.aidl
index c16a711..2b291f0 100644
--- a/gnss/aidl/android/hardware/gnss/gnss_assistance/UtcModel.aidl
+++ b/gnss/aidl/android/hardware/gnss/gnss_assistance/UtcModel.aidl
@@ -20,6 +20,8 @@
  * Contains parameters to convert from current GNSS time to UTC time.
  * This is defined in RINEX 3.05 "TIME SYSTEM CORR" in table A5.
  *
+ * If weekNumber is -1, the UtcModel is not available.
+ *
  * @hide
  */
 @VintfStability
@@ -33,6 +35,6 @@
     /** Reference GNSS time of week in seconds. */
     int timeOfWeek;
 
-    /** Reference GNSS week number. */
+    /** Reference GNSS week number. If it is -1, the UTC model is not available. */
     int weekNumber;
 }
diff --git a/power/aidl/vts/VtsHalPowerTargetTest.cpp b/power/aidl/vts/VtsHalPowerTargetTest.cpp
index 87797ae..93b7c38 100644
--- a/power/aidl/vts/VtsHalPowerTargetTest.cpp
+++ b/power/aidl/vts/VtsHalPowerTargetTest.cpp
@@ -317,6 +317,9 @@
     }
     ASSERT_TRUE(ret.isOk());
     ASSERT_GE(mSupportInfo->headroom.cpuMinIntervalMillis, 0);
+    ASSERT_LE(mSupportInfo->headroom.cpuMinCalculationWindowMillis, 50);
+    ASSERT_GE(mSupportInfo->headroom.cpuMaxCalculationWindowMillis, 10000);
+    ASSERT_GE(mSupportInfo->headroom.cpuMaxTidCount, 5);
     ASSERT_EQ(headroom.getTag(), CpuHeadroomResult::globalHeadroom);
     ASSERT_GE(headroom.get<CpuHeadroomResult::globalHeadroom>(), 0.0f);
     ASSERT_LE(headroom.get<CpuHeadroomResult::globalHeadroom>(), 100.00f);
@@ -335,6 +338,8 @@
     }
     ASSERT_TRUE(ret.isOk());
     ASSERT_GE(mSupportInfo->headroom.gpuMinIntervalMillis, 0);
+    ASSERT_LE(mSupportInfo->headroom.gpuMinCalculationWindowMillis, 50);
+    ASSERT_GE(mSupportInfo->headroom.gpuMaxCalculationWindowMillis, 10000);
     ASSERT_EQ(headroom.getTag(), GpuHeadroomResult::globalHeadroom);
     ASSERT_GE(headroom.get<GpuHeadroomResult::globalHeadroom>(), 0.0f);
     ASSERT_LE(headroom.get<GpuHeadroomResult::globalHeadroom>(), 100.00f);
diff --git a/security/see/authmgr/aidl/README.md b/security/see/authmgr/aidl/README.md
new file mode 100644
index 0000000..97b2b1d
--- /dev/null
+++ b/security/see/authmgr/aidl/README.md
@@ -0,0 +1,21 @@
+# AuthMgr
+
+The AuthMgr protocol authenticates and authorizes clients before they can
+access trusted HALs, AIDL-defined services in trusted execution environments.
+Version 1 was designed to allow applications running in a protected virtual
+machine (pVM) to access services running in a TEE in ARM TrustZone. An
+implementation of `IAuthMgrAuthorization` is referred to as an AuthMgr Backend.
+An implementation of a client of the AuthMgr Backend is referred to as an
+AuthMgr Frontend.
+
+
+## Additional Requirements by Android Version
+
+The comments on `IAuthMgrAuthorization` describe the requirements for implementing
+an AuthMgr Backend (implementor of the interface) itself. There are some additional
+requirements that are specific to Android release versions.
+
+### Android 16
+If implementing `IAuthMgrAuthorization` in Android 16 only one AuthMgr Backend is
+supported and dynamic service discovery is not supported. The AuthMgr Backend
+service must be exposed on secure partition ID 0x8001 over VSOCK port 1.
\ No newline at end of file