Merge "Add GnssAssistanceInterface AIDL HAL" into main
diff --git a/audio/aidl/default/CapEngineConfigXmlConverter.cpp b/audio/aidl/default/CapEngineConfigXmlConverter.cpp
index 8210664..a6e78b9 100644
--- a/audio/aidl/default/CapEngineConfigXmlConverter.cpp
+++ b/audio/aidl/default/CapEngineConfigXmlConverter.cpp
@@ -69,29 +69,36 @@
     std::string criterionName = xsdcRule.getSelectionCriterion();
     std::string criterionValue = xsdcRule.getValue();
     if (iequals(criterionName, toString(Tag::availableInputDevices))) {
-        rule.criterion = AudioHalCapCriterionV2::make<Tag::availableInputDevices>();
-        rule.criterionTypeValue =
-                VALUE_OR_RETURN(convertDeviceTypeToAidl(gLegacyInputDevicePrefix + criterionValue));
+        AudioHalCapCriterionV2::AvailableDevices value;
+        value.values.emplace_back(VALUE_OR_RETURN(
+                convertDeviceTypeToAidl(gLegacyInputDevicePrefix + criterionValue)));
+        rule.criterionAndValue = AudioHalCapCriterionV2::make<Tag::availableInputDevices>(value);
+
     } else if (iequals(criterionName, toString(Tag::availableOutputDevices))) {
-        rule.criterion = AudioHalCapCriterionV2::make<Tag::availableOutputDevices>();
-        rule.criterionTypeValue = VALUE_OR_RETURN(
-                convertDeviceTypeToAidl(gLegacyOutputDevicePrefix + criterionValue));
+        AudioHalCapCriterionV2::AvailableDevices value;
+        value.values.emplace_back(VALUE_OR_RETURN(
+                convertDeviceTypeToAidl(gLegacyOutputDevicePrefix + criterionValue)));
+        rule.criterionAndValue = AudioHalCapCriterionV2::make<Tag::availableOutputDevices>(value);
     } else if (iequals(criterionName, toString(Tag::availableInputDevicesAddresses))) {
-        rule.criterion = AudioHalCapCriterionV2::make<Tag::availableInputDevicesAddresses>();
-        rule.criterionTypeValue =
-                AudioDeviceAddress::make<AudioDeviceAddress::Tag::id>(criterionValue);
+        AudioHalCapCriterionV2::AvailableDevicesAddresses value;
+        value.values.emplace_back(criterionValue);
+        rule.criterionAndValue =
+                AudioHalCapCriterionV2::make<Tag::availableInputDevicesAddresses>(value);
     } else if (iequals(criterionName, toString(Tag::availableOutputDevicesAddresses))) {
-        rule.criterion = AudioHalCapCriterionV2::make<Tag::availableOutputDevicesAddresses>();
-        rule.criterionTypeValue =
-                AudioDeviceAddress::make<AudioDeviceAddress::Tag::id>(criterionValue);
+        AudioHalCapCriterionV2::AvailableDevicesAddresses value;
+        value.values.emplace_back(criterionValue);
+        rule.criterionAndValue =
+                AudioHalCapCriterionV2::make<Tag::availableOutputDevicesAddresses>(value);
     } else if (iequals(criterionName, toString(Tag::telephonyMode))) {
-        rule.criterion = AudioHalCapCriterionV2::make<Tag::telephonyMode>();
-        rule.criterionTypeValue = VALUE_OR_RETURN(convertTelephonyModeToAidl(criterionValue));
+        AudioHalCapCriterionV2::TelephonyMode value;
+        value.values.emplace_back(VALUE_OR_RETURN(convertTelephonyModeToAidl(criterionValue)));
+        rule.criterionAndValue = AudioHalCapCriterionV2::make<Tag::telephonyMode>(value);
     } else if (!fastcmp<strncmp>(criterionName.c_str(), kXsdcForceConfigForUse,
             strlen(kXsdcForceConfigForUse))) {
-        rule.criterion = AudioHalCapCriterionV2::make<Tag::forceConfigForUse>(
-                VALUE_OR_RETURN(convertForceUseCriterionToAidl(criterionName)));
-        rule.criterionTypeValue = VALUE_OR_RETURN(convertForcedConfigToAidl(criterionValue));
+        AudioHalCapCriterionV2::ForceConfigForUse value;
+        value.forceUse = VALUE_OR_RETURN(convertForceUseCriterionToAidl(criterionName));
+        value.values.emplace_back(VALUE_OR_RETURN(convertForcedConfigToAidl(criterionValue)));
+        rule.criterionAndValue = AudioHalCapCriterionV2::make<Tag::forceConfigForUse>(value);
     } else {
         LOG(ERROR) << __func__ << " unrecognized criterion " << criterionName;
         return unexpected(BAD_VALUE);
diff --git a/audio/aidl/default/Module.cpp b/audio/aidl/default/Module.cpp
index a2a357c..51b6085 100644
--- a/audio/aidl/default/Module.cpp
+++ b/audio/aidl/default/Module.cpp
@@ -467,58 +467,132 @@
             fillConnectionsHelper(connections, patch.sinkPortConfigIds, patch.sourcePortConfigIds);
         }  // Otherwise, there are no streams to notify.
     };
-    fillConnections(oldConnections, oldPatch);
-    fillConnections(newConnections, newPatch);
-
-    std::for_each(oldConnections.begin(), oldConnections.end(), [&](const auto& connectionPair) {
-        const int32_t mixPortConfigId = connectionPair.first;
-        if (auto it = newConnections.find(mixPortConfigId);
-            it == newConnections.end() || it->second != connectionPair.second) {
-            if (auto status = mStreams.setStreamConnectedDevices(mixPortConfigId, {});
-                status.isOk()) {
-                LOG(DEBUG) << "updateStreamsConnectedState: The stream on port config id "
-                           << mixPortConfigId << " has been disconnected";
-            } else {
-                // Disconnection is tricky to roll back, just register a failure.
-                maybeFailure = std::move(status);
+    auto restoreOldConnections = [&](const std::set<int32_t>& mixPortIds,
+                                     const bool continueWithEmptyDevices) {
+        for (const auto mixPort : mixPortIds) {
+            if (auto it = oldConnections.find(mixPort);
+                continueWithEmptyDevices || it != oldConnections.end()) {
+                const std::vector<AudioDevice> d =
+                        it != oldConnections.end() ? getDevicesFromDevicePortConfigIds(it->second)
+                                                   : std::vector<AudioDevice>();
+                if (auto status = mStreams.setStreamConnectedDevices(mixPort, d); status.isOk()) {
+                    LOG(WARNING) << ":updateStreamsConnectedState: rollback: mix port config:"
+                                 << mixPort
+                                 << (d.empty() ? "; not connected"
+                                               : std::string("; connected to ") +
+                                                         ::android::internal::ToString(d));
+                } else {
+                    // can't do much about rollback failures
+                    LOG(ERROR)
+                            << ":updateStreamsConnectedState: rollback: failed for mix port config:"
+                            << mixPort;
+                }
             }
         }
-    });
-    if (!maybeFailure.isOk()) return maybeFailure;
-    std::set<int32_t> idsToDisconnectOnFailure;
-    std::for_each(newConnections.begin(), newConnections.end(), [&](const auto& connectionPair) {
-        const int32_t mixPortConfigId = connectionPair.first;
-        if (auto it = oldConnections.find(mixPortConfigId);
-            it == oldConnections.end() || it->second != connectionPair.second) {
-            const auto connectedDevices = getDevicesFromDevicePortConfigIds(connectionPair.second);
+    };
+    fillConnections(oldConnections, oldPatch);
+    fillConnections(newConnections, newPatch);
+    /**
+     * Illustration of oldConnections and newConnections
+     *
+     * oldConnections {
+     * a : {A,B,C},
+     * b : {D},
+     * d : {H,I,J},
+     * e : {N,O,P},
+     * f : {Q,R},
+     * g : {T,U,V},
+     * }
+     *
+     * newConnections {
+     * a : {A,B,C},
+     * c : {E,F,G},
+     * d : {K,L,M},
+     * e : {N,P},
+     * f : {Q,R,S},
+     * g : {U,V,W},
+     * }
+     *
+     * Expected routings:
+     *      'a': is ignored both in disconnect step and connect step,
+     *           due to same devices both in oldConnections and newConnections.
+     *      'b': handled only in disconnect step with empty devices because 'b' is only present
+     *           in oldConnections.
+     *      'c': handled only in connect step with {E,F,G} devices because 'c' is only present
+     *           in newConnections.
+     *      'd': handled only in connect step with {K,L,M} devices because 'd' is also present
+     *           in newConnections and it is ignored in disconnected step.
+     *      'e': handled only in connect step with {N,P} devices because 'e' is also present
+     *           in newConnections and it is ignored in disconnect step. please note that there
+     *           is no exclusive disconnection for device {O}.
+     *      'f': handled only in connect step with {Q,R,S} devices because 'f' is also present
+     *           in newConnections and it is ignored in disconnect step. Even though stream is
+     *           already connected with {Q,R} devices and connection happens with {Q,R,S}.
+     *      'g': handled only in connect step with {U,V,W} devices because 'g' is also present
+     *           in newConnections and it is ignored in disconnect step. There is no exclusive
+     *           disconnection with devices {T,U,V}.
+     *
+     *       If, any failure, will lead to restoreOldConnections (rollback).
+     *       The aim of the restoreOldConnections is to make connections back to oldConnections.
+     *       Failures in restoreOldConnections aren't handled.
+     */
+
+    std::set<int32_t> idsToConnectBackOnFailure;
+    // disconnection step
+    for (const auto& [oldMixPortConfigId, oldDevicePortConfigIds] : oldConnections) {
+        if (auto it = newConnections.find(oldMixPortConfigId); it == newConnections.end()) {
+            idsToConnectBackOnFailure.insert(oldMixPortConfigId);
+            if (auto status = mStreams.setStreamConnectedDevices(oldMixPortConfigId, {});
+                status.isOk()) {
+                LOG(DEBUG) << __func__ << ": The stream on port config id " << oldMixPortConfigId
+                           << " has been disconnected";
+            } else {
+                maybeFailure = std::move(status);
+                // proceed to rollback even on one failure
+                break;
+            }
+        }
+    }
+
+    if (!maybeFailure.isOk()) {
+        restoreOldConnections(idsToConnectBackOnFailure, false /*continueWithEmptyDevices*/);
+        LOG(WARNING) << __func__ << ": failed to disconnect from old patch. attempted rollback";
+        return maybeFailure;
+    }
+
+    std::set<int32_t> idsToRollbackOnFailure;
+    // connection step
+    for (const auto& [newMixPortConfigId, newDevicePortConfigIds] : newConnections) {
+        if (auto it = oldConnections.find(newMixPortConfigId);
+            it == oldConnections.end() || it->second != newDevicePortConfigIds) {
+            const auto connectedDevices = getDevicesFromDevicePortConfigIds(newDevicePortConfigIds);
+            idsToRollbackOnFailure.insert(newMixPortConfigId);
             if (connectedDevices.empty()) {
                 // This is important as workers use the vector size to derive the connection status.
-                LOG(FATAL) << "updateStreamsConnectedState: No connected devices found for port "
-                              "config id "
-                           << mixPortConfigId;
+                LOG(FATAL) << __func__ << ": No connected devices found for port config id "
+                           << newMixPortConfigId;
             }
-            if (auto status = mStreams.setStreamConnectedDevices(mixPortConfigId, connectedDevices);
+            if (auto status =
+                        mStreams.setStreamConnectedDevices(newMixPortConfigId, connectedDevices);
                 status.isOk()) {
-                LOG(DEBUG) << "updateStreamsConnectedState: The stream on port config id "
-                           << mixPortConfigId << " has been connected to: "
+                LOG(DEBUG) << __func__ << ": The stream on port config id " << newMixPortConfigId
+                           << " has been connected to: "
                            << ::android::internal::ToString(connectedDevices);
             } else {
                 maybeFailure = std::move(status);
-                idsToDisconnectOnFailure.insert(mixPortConfigId);
+                // proceed to rollback even on one failure
+                break;
             }
         }
-    });
+    }
+
     if (!maybeFailure.isOk()) {
-        LOG(WARNING) << __func__ << ": " << mType
-                     << ": Due to a failure, disconnecting streams on port config ids "
-                     << ::android::internal::ToString(idsToDisconnectOnFailure);
-        std::for_each(idsToDisconnectOnFailure.begin(), idsToDisconnectOnFailure.end(),
-                      [&](const auto& portConfigId) {
-                          auto status = mStreams.setStreamConnectedDevices(portConfigId, {});
-                          (void)status.isOk();  // Can't do much about a failure here.
-                      });
+        restoreOldConnections(idsToConnectBackOnFailure, false /*continueWithEmptyDevices*/);
+        restoreOldConnections(idsToRollbackOnFailure, true /*continueWithEmptyDevices*/);
+        LOG(WARNING) << __func__ << ": failed to connect for new patch. attempted rollback";
         return maybeFailure;
     }
+
     return ndk::ScopedAStatus::ok();
 }
 
diff --git a/audio/aidl/default/apex/com.android.hardware.audio/Android.bp b/audio/aidl/default/apex/com.android.hardware.audio/Android.bp
index ee92512..8fa429a 100644
--- a/audio/aidl/default/apex/com.android.hardware.audio/Android.bp
+++ b/audio/aidl/default/apex/com.android.hardware.audio/Android.bp
@@ -48,4 +48,11 @@
         "android.hardware.audio.service-aidl.xml",
         "android.hardware.bluetooth.audio.xml",
     ],
+    required: [
+        "aidl_audio_set_configurations_bfbs",
+        "aidl_default_audio_set_configurations_json",
+        "aidl_audio_set_scenarios_bfbs",
+        "aidl_default_audio_set_scenarios_json",
+        "hfp_codec_capabilities_xml",
+    ],
 }
diff --git a/audio/aidl/vts/Android.bp b/audio/aidl/vts/Android.bp
index 9ebe518..b025637 100644
--- a/audio/aidl/vts/Android.bp
+++ b/audio/aidl/vts/Android.bp
@@ -31,6 +31,7 @@
     ],
     header_libs: [
         "libaudioaidl_headers",
+        "libaudioutils_headers",
         "libexpectedutils_headers",
     ],
     cflags: [
diff --git a/audio/aidl/vts/EffectHelper.h b/audio/aidl/vts/EffectHelper.h
index 01f73fc..e073ece 100644
--- a/audio/aidl/vts/EffectHelper.h
+++ b/audio/aidl/vts/EffectHelper.h
@@ -84,6 +84,7 @@
 }
 
 static constexpr float kMaxAudioSampleValue = 1;
+static constexpr int kSamplingFrequency = 44100;
 
 class EffectHelper {
   public:
@@ -428,19 +429,28 @@
         }
     }
 
-    // Generate multitone input between -1 to +1 using testFrequencies
-    void generateMultiTone(const std::vector<int>& testFrequencies, std::vector<float>& input,
-                           const int samplingFrequency) {
+    // Generate multitone input between -amplitude to +amplitude using testFrequencies
+    // All test frequencies are considered having the same amplitude
+    void generateSineWave(const std::vector<int>& testFrequencies, std::vector<float>& input,
+                          const float amplitude = 1.0,
+                          const int samplingFrequency = kSamplingFrequency) {
         for (size_t i = 0; i < input.size(); i++) {
             input[i] = 0;
 
             for (size_t j = 0; j < testFrequencies.size(); j++) {
                 input[i] += sin(2 * M_PI * testFrequencies[j] * i / samplingFrequency);
             }
-            input[i] /= testFrequencies.size();
+            input[i] *= amplitude / testFrequencies.size();
         }
     }
 
+    // Generate single tone input between -amplitude to +amplitude using testFrequency
+    void generateSineWave(const int testFrequency, std::vector<float>& input,
+                          const float amplitude = 1.0,
+                          const int samplingFrequency = kSamplingFrequency) {
+        generateSineWave(std::vector<int>{testFrequency}, input, amplitude, samplingFrequency);
+    }
+
     // Use FFT transform to convert the buffer to frequency domain
     // Compute its magnitude at binOffsets
     std::vector<float> calculateMagnitude(const std::vector<float>& buffer,
diff --git a/audio/aidl/vts/VtsHalAudioCoreConfigTargetTest.cpp b/audio/aidl/vts/VtsHalAudioCoreConfigTargetTest.cpp
index 25fcd46..583143c 100644
--- a/audio/aidl/vts/VtsHalAudioCoreConfigTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioCoreConfigTargetTest.cpp
@@ -355,7 +355,6 @@
             const AudioHalCapRule& rule,
             const std::vector<std::optional<AudioHalCapCriterionV2>>& criteria) {
         const auto& compoundRule = rule.compoundRule;
-        using TypeTag = AudioHalCapCriterionV2::Type::Tag;
         if (rule.nestedRules.empty() && rule.criterionRules.empty()) {
             EXPECT_EQ(compoundRule, AudioHalCapRule::CompoundRule::ALL);
         }
@@ -365,8 +364,8 @@
             ValidateAudioHalConfigurationRule(nestedRule, criteria);
         }
         for (const auto& criterionRule : rule.criterionRules) {
-            auto selectionCriterion = criterionRule.criterion;
-            auto criterionValue = criterionRule.criterionTypeValue;
+            auto selectionCriterion = criterionRule.criterionAndValue;
+            auto criterionValue = criterionRule.criterionAndValue;
             auto matchesWhen = criterionRule.matchingRule;
             auto criteriaIt = find_if(criteria.begin(), criteria.end(), [&](const auto& criterion) {
                 return criterion.has_value() &&
@@ -377,50 +376,65 @@
             AudioHalCapCriterionV2 matchingCriterion = (*criteriaIt).value();
             switch (selectionCriterion.getTag()) {
                 case AudioHalCapCriterionV2::availableInputDevices: {
-                    EXPECT_EQ(criterionValue.getTag(), TypeTag::availableDevicesType);
+                    const auto& values =
+                            criterionValue.get<AudioHalCapCriterionV2::availableInputDevices>()
+                                    .values;
+                    ASSERT_FALSE(values.empty());
                     validateAudioHalCapRule(
                             matchingCriterion.get<AudioHalCapCriterionV2::availableInputDevices>(),
-                            criterionValue.get<TypeTag::availableDevicesType>(), matchesWhen);
+                            values[0], matchesWhen);
                     break;
                 }
                 case AudioHalCapCriterionV2::availableOutputDevices: {
-                    EXPECT_EQ(criterionValue.getTag(), TypeTag::availableDevicesType);
+                    const auto& values =
+                            criterionValue.get<AudioHalCapCriterionV2::availableOutputDevices>()
+                                    .values;
+                    ASSERT_FALSE(values.empty());
                     validateAudioHalCapRule(
                             matchingCriterion.get<AudioHalCapCriterionV2::availableOutputDevices>(),
-                            criterionValue.get<TypeTag::availableDevicesType>(), matchesWhen);
+                            values[0], matchesWhen);
                     break;
                 }
                 case AudioHalCapCriterionV2::availableInputDevicesAddresses: {
-                    EXPECT_EQ(criterionValue.getTag(), TypeTag::availableDevicesAddressesType);
+                    const auto& values =
+                            criterionValue
+                                    .get<AudioHalCapCriterionV2::availableInputDevicesAddresses>()
+                                    .values;
+                    ASSERT_FALSE(values.empty());
                     validateAudioHalCapRule(
                             matchingCriterion
                                     .get<AudioHalCapCriterionV2::availableInputDevicesAddresses>(),
-                            criterionValue.get<TypeTag::availableDevicesAddressesType>(),
-                            matchesWhen);
+                            values[0], matchesWhen);
                     break;
                 }
                 case AudioHalCapCriterionV2::availableOutputDevicesAddresses: {
-                    EXPECT_EQ(criterionValue.getTag(), TypeTag::availableDevicesAddressesType);
+                    const auto& values =
+                            criterionValue
+                                    .get<AudioHalCapCriterionV2::availableOutputDevicesAddresses>()
+                                    .values;
+                    ASSERT_FALSE(values.empty());
                     validateAudioHalCapRule(
                             matchingCriterion
                                     .get<AudioHalCapCriterionV2::availableOutputDevicesAddresses>(),
-                            criterionValue.get<TypeTag::availableDevicesAddressesType>(),
-                            matchesWhen);
+                            values[0], matchesWhen);
                     break;
                 }
                 case AudioHalCapCriterionV2::telephonyMode: {
-                    EXPECT_EQ(criterionValue.getTag(), TypeTag::telephonyModeType);
+                    const auto& values =
+                            criterionValue.get<AudioHalCapCriterionV2::telephonyMode>().values;
+                    ASSERT_FALSE(values.empty());
                     validateAudioHalCapRule(
                             matchingCriterion.get<AudioHalCapCriterionV2::telephonyMode>(),
-                            criterionValue.get<TypeTag::telephonyModeType>(), matchesWhen);
+                            values[0], matchesWhen);
                     break;
                 }
                 case AudioHalCapCriterionV2::forceConfigForUse: {
-                    EXPECT_EQ(criterionValue.getTag(), TypeTag::forcedConfigType);
+                    const auto& values =
+                            criterionValue.get<AudioHalCapCriterionV2::forceConfigForUse>().values;
+                    ASSERT_FALSE(values.empty());
                     validateAudioHalCapRule(
-                            matchingCriterion
-                                    .get<AudioHalCapCriterionV2::forceConfigForUse>(),
-                            criterionValue.get<TypeTag::forcedConfigType>(), matchesWhen);
+                            matchingCriterion.get<AudioHalCapCriterionV2::forceConfigForUse>(),
+                            values[0], matchesWhen);
                     break;
                 }
                 default:
diff --git a/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
index 9fe5801..6bfba65 100644
--- a/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
@@ -80,6 +80,7 @@
 using aidl::android::hardware::audio::core::VendorParameter;
 using aidl::android::hardware::audio::core::sounddose::ISoundDose;
 using aidl::android::hardware::common::fmq::SynchronizedReadWrite;
+using aidl::android::media::audio::common::AudioChannelLayout;
 using aidl::android::media::audio::common::AudioContentType;
 using aidl::android::media::audio::common::AudioDevice;
 using aidl::android::media::audio::common::AudioDeviceAddress;
@@ -1514,7 +1515,7 @@
     const int defaultDeviceFlag = 1 << AudioPortDeviceExt::FLAG_INDEX_DEFAULT_DEVICE;
     for (const auto& port : ports) {
         if (port.ext.getTag() != AudioPortExt::Tag::device) continue;
-        const auto& devicePort = port.ext.get<AudioPortExt::Tag::device>();
+        const AudioPortDeviceExt& devicePort = port.ext.get<AudioPortExt::Tag::device>();
         EXPECT_NE(AudioDeviceType::NONE, devicePort.device.type.type);
         EXPECT_NE(AudioDeviceType::IN_DEFAULT, devicePort.device.type.type);
         EXPECT_NE(AudioDeviceType::OUT_DEFAULT, devicePort.device.type.type);
@@ -1549,6 +1550,15 @@
                 FAIL() << "Invalid AudioIoFlags Tag: " << toString(port.flags.getTag());
             }
         }
+        // Speaker layout can be null or layoutMask variant.
+        if (devicePort.speakerLayout.has_value()) {
+            // Should only be set for output ports.
+            EXPECT_EQ(AudioIoFlags::Tag::output, port.flags.getTag());
+            const auto speakerLayoutTag = devicePort.speakerLayout.value().getTag();
+            EXPECT_EQ(AudioChannelLayout::Tag::layoutMask, speakerLayoutTag)
+                    << "If set, speaker layout must be layoutMask.  Received: "
+                    << toString(speakerLayoutTag);
+        }
     }
 }
 
diff --git a/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp b/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp
index 5ce2a20..5a24be7 100644
--- a/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp
@@ -113,7 +113,6 @@
         }
     }
 
-    static constexpr int kSamplingFrequency = 44100;
     static constexpr int kDurationMilliSec = 720;
     static constexpr int kInputSize = kSamplingFrequency * kDurationMilliSec / 1000;
     long mInputFrameCount, mOutputFrameCount;
@@ -188,18 +187,6 @@
         }
     }
 
-    // Generate multitone input between -1 to +1 using testFrequencies
-    void generateMultiTone(const std::vector<int>& testFrequencies, std::vector<float>& input) {
-        for (auto i = 0; i < kInputSize; i++) {
-            input[i] = 0;
-
-            for (size_t j = 0; j < testFrequencies.size(); j++) {
-                input[i] += sin(2 * M_PI * testFrequencies[j] * i / kSamplingFrequency);
-            }
-            input[i] /= testFrequencies.size();
-        }
-    }
-
     // Use FFT transform to convert the buffer to frequency domain
     // Compute its magnitude at binOffsets
     std::vector<float> calculateMagnitude(const std::vector<float>& buffer,
@@ -252,7 +239,8 @@
 
     roundToFreqCenteredToFftBin(testFrequencies, binOffsets);
 
-    generateMultiTone(testFrequencies, input);
+    // Generate multitone input
+    generateSineWave(testFrequencies, input);
 
     inputMag = calculateMagnitude(input, binOffsets);
 
diff --git a/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp b/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp
index e31aae6..a29920e 100644
--- a/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp
@@ -224,13 +224,6 @@
                                                output.size());
     }
 
-    void generateSineWaveInput(std::vector<float>& input) {
-        int frequency = 1000;
-        size_t kSamplingFrequency = 44100;
-        for (size_t i = 0; i < input.size(); i++) {
-            input[i] = sin(2 * M_PI * frequency * i / kSamplingFrequency);
-        }
-    }
     using Maker = EnvironmentalReverb (*)(int);
 
     static constexpr std::array<Maker, static_cast<int>(EnvironmentalReverb::bypass) + 1>
@@ -286,9 +279,9 @@
         }
     }
 
-    static constexpr int kSamplingFrequency = 44100;
     static constexpr int kDurationMilliSec = 500;
     static constexpr int kBufferSize = kSamplingFrequency * kDurationMilliSec / 1000;
+    static constexpr int kInputFrequency = 1000;
 
     int mStereoChannelCount =
             getChannelCount(AudioChannelLayout::make<AudioChannelLayout::layoutMask>(
@@ -351,7 +344,7 @@
         : EnvironmentalReverbHelper(std::get<DESCRIPTOR_INDEX>(GetParam())) {
         std::tie(mTag, mParamValues) = std::get<TAG_VALUE_PAIR>(GetParam());
         mInput.resize(kBufferSize);
-        generateSineWaveInput(mInput);
+        generateSineWave(kInputFrequency, mInput);
     }
     void SetUp() override {
         SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
@@ -441,7 +434,7 @@
 
 TEST_P(EnvironmentalReverbMinimumParamTest, MinimumValueTest) {
     std::vector<float> input(kBufferSize);
-    generateSineWaveInput(input);
+    generateSineWave(kInputFrequency, input);
     std::vector<float> output(kBufferSize);
     setParameterAndProcess(input, output, mValue, mTag);
     float energy = computeOutputEnergy(input, output);
@@ -477,7 +470,7 @@
         : EnvironmentalReverbHelper(std::get<DESCRIPTOR_INDEX>(GetParam())) {
         std::tie(mTag, mParamValues) = std::get<TAG_VALUE_PAIR>(GetParam());
         mInput.resize(kBufferSize);
-        generateSineWaveInput(mInput);
+        generateSineWave(kInputFrequency, mInput);
     }
     void SetUp() override {
         SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
@@ -556,7 +549,7 @@
         if (mIsInputMute) {
             std::fill(mInput.begin(), mInput.end(), 0);
         } else {
-            generateSineWaveInput(mInput);
+            generateSineWave(kInputFrequency, mInput);
         }
     }
     void SetUp() override {
diff --git a/audio/aidl/vts/VtsHalPresetReverbTargetTest.cpp b/audio/aidl/vts/VtsHalPresetReverbTargetTest.cpp
index 542f0d8..3ce9e53 100644
--- a/audio/aidl/vts/VtsHalPresetReverbTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalPresetReverbTargetTest.cpp
@@ -81,7 +81,6 @@
                                            << "\ngetParam:" << getParam.toString();
     }
 
-    static constexpr int kSamplingFrequency = 44100;
     static constexpr int kDurationMilliSec = 500;
     static constexpr int kBufferSize = kSamplingFrequency * kDurationMilliSec / 1000;
     int mStereoChannelCount =
@@ -133,7 +132,8 @@
   public:
     PresetReverbProcessTest() {
         std::tie(mFactory, mDescriptor) = GetParam();
-        generateSineWaveInput();
+        mInput.resize(kBufferSize);
+        generateSineWave(1000 /*Input Frequency*/, mInput);
     }
 
     void SetUp() override {
@@ -145,13 +145,6 @@
         ASSERT_NO_FATAL_FAILURE(TearDownPresetReverb());
     }
 
-    void generateSineWaveInput() {
-        int frequency = 1000;
-        for (size_t i = 0; i < kBufferSize; i++) {
-            mInput.push_back(sin(2 * M_PI * frequency * i / kSamplingFrequency));
-        }
-    }
-
     bool isAuxiliary() {
         return mDescriptor.common.flags.type ==
                aidl::android::hardware::audio::effect::Flags::Type::AUXILIARY;
diff --git a/audio/aidl/vts/VtsHalVirtualizerTargetTest.cpp b/audio/aidl/vts/VtsHalVirtualizerTargetTest.cpp
index b449f3c..3021370 100644
--- a/audio/aidl/vts/VtsHalVirtualizerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalVirtualizerTargetTest.cpp
@@ -94,7 +94,6 @@
         }
     }
 
-    static constexpr int kSamplingFrequency = 44100;
     static constexpr int kDefaultChannelLayout = AudioChannelLayout::LAYOUT_STEREO;
     static constexpr int kDurationMilliSec = 720;
     static constexpr int kBufferSize = kSamplingFrequency * kDurationMilliSec / 1000;
@@ -164,10 +163,7 @@
         if (mZeroInput) {
             std::fill(buffer.begin(), buffer.end(), 0);
         } else {
-            int frequency = 100;
-            for (size_t i = 0; i < buffer.size(); i++) {
-                buffer[i] = sin(2 * M_PI * frequency * i / kSamplingFrequency);
-            }
+            generateSineWave(1000 /*Input Frequency*/, buffer);
         }
     }
 
diff --git a/audio/aidl/vts/VtsHalVolumeTargetTest.cpp b/audio/aidl/vts/VtsHalVolumeTargetTest.cpp
index 4300801..b58c1c6 100644
--- a/audio/aidl/vts/VtsHalVolumeTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalVolumeTargetTest.cpp
@@ -93,7 +93,6 @@
         }
     }
 
-    static constexpr int kSamplingFrequency = 44100;
     static constexpr int kDurationMilliSec = 720;
     static constexpr int kBufferSize = kSamplingFrequency * kDurationMilliSec / 1000;
     static constexpr int kMinLevel = -96;
@@ -163,7 +162,7 @@
         mInputMag.resize(mTestFrequencies.size());
         mBinOffsets.resize(mTestFrequencies.size());
         roundToFreqCenteredToFftBin(mTestFrequencies, mBinOffsets, kBinWidth);
-        generateMultiTone(mTestFrequencies, mInput, kSamplingFrequency);
+        generateSineWave(mTestFrequencies, mInput);
         mInputMag = calculateMagnitude(mInput, mBinOffsets, kNPointFFT);
     }
 
diff --git a/automotive/audiocontrol/aidl/vts/VtsHalAudioControlTargetTest.cpp b/automotive/audiocontrol/aidl/vts/VtsHalAudioControlTargetTest.cpp
index 6e646a6..c01c0d6 100644
--- a/automotive/audiocontrol/aidl/vts/VtsHalAudioControlTargetTest.cpp
+++ b/automotive/audiocontrol/aidl/vts/VtsHalAudioControlTargetTest.cpp
@@ -125,11 +125,12 @@
     }
     std::set<std::string> contextInRoute;
     for (const auto& context : entry.contextNames) {
-        if (!contextInRoute.contains(ToString(context))) {
-            continue;
+        std::string contextString = ToString(context);
+        if (contextInRoute.contains(contextString)) {
+            message = " Context " + contextString + " repeats for DeviceToContextEntry";
+            return false;
         }
-        message = " Context can not repeat for the same DeviceToContextEntry";
-        return false;
+        groupDevices.insert(contextString);
     }
     audiomediacommon::AudioDeviceDescription description;
     if (!testutils::getAudioPortDeviceDescriptor(entry.device, description)) {
diff --git a/automotive/evs/aidl/impl/default/include/ConfigManager.h b/automotive/evs/aidl/impl/default/include/ConfigManager.h
index 37a17dc..f6ba2f2 100644
--- a/automotive/evs/aidl/impl/default/include/ConfigManager.h
+++ b/automotive/evs/aidl/impl/default/include/ConfigManager.h
@@ -50,6 +50,7 @@
 class ConfigManager final {
   public:
     static std::unique_ptr<ConfigManager> Create();
+    static std::unique_ptr<ConfigManager> Create(const std::string path);
     ConfigManager(const ConfigManager&) = delete;
     ConfigManager& operator=(const ConfigManager&) = delete;
 
@@ -65,6 +66,15 @@
             UNKNOWN = std::numeric_limits<std::underlying_type_t<DeviceType>>::max(),
         };
 
+        enum class PixelFormat : std::int32_t {
+            NV12 = 0,
+            NV21 = 1,
+            YV12 = 2,
+            I420 = 3,
+
+            UNKNOWN = std::numeric_limits<std::underlying_type_t<DeviceType>>::max(),
+        };
+
         CameraInfo() : characteristics(nullptr) {}
 
         virtual ~CameraInfo();
@@ -82,6 +92,8 @@
 
         static DeviceType deviceTypeFromSV(const std::string_view sv);
 
+        static PixelFormat pixelFormatFromSV(const std::string_view sv);
+
         DeviceType deviceType{DeviceType::NONE};
 
         /*
@@ -105,6 +117,11 @@
 
         /* Camera module characteristics */
         camera_metadata_t* characteristics;
+
+        /* Format of media in a given media container. This field is effective
+         * only for DeviceType::VIDEO.
+         */
+        PixelFormat format;
     };
 
     class CameraGroupInfo : public CameraInfo {
@@ -272,7 +289,7 @@
      * @return bool
      *         True if it completes parsing a file successfully.
      */
-    bool readConfigDataFromXML() noexcept;
+    bool readConfigDataFromXML(const std::string path) noexcept;
 
     /*
      * read the information of the vehicle
diff --git a/automotive/evs/aidl/impl/default/include/EvsCameraBase.h b/automotive/evs/aidl/impl/default/include/EvsCameraBase.h
index c3e9dfc..d9180e8 100644
--- a/automotive/evs/aidl/impl/default/include/EvsCameraBase.h
+++ b/automotive/evs/aidl/impl/default/include/EvsCameraBase.h
@@ -30,6 +30,7 @@
 
     ~EvsCameraBase() override = default;
 
+    virtual std::string getId() = 0;
     virtual void shutdown() = 0;
 
   protected:
diff --git a/automotive/evs/aidl/impl/default/include/EvsMockCamera.h b/automotive/evs/aidl/impl/default/include/EvsMockCamera.h
index cd68532..67de8dc 100644
--- a/automotive/evs/aidl/impl/default/include/EvsMockCamera.h
+++ b/automotive/evs/aidl/impl/default/include/EvsMockCamera.h
@@ -65,7 +65,9 @@
     ndk::ScopedAStatus setPrimaryClient() override;
     ndk::ScopedAStatus unsetPrimaryClient() override;
 
-    const evs::CameraDesc& getDesc() { return mDescription; }
+    std::string getId() override { return mDescription.id; }
+
+    const CameraDesc& getDesc() { return mDescription; }
 
     static std::shared_ptr<EvsMockCamera> Create(const char* deviceName);
     static std::shared_ptr<EvsMockCamera> Create(
diff --git a/automotive/evs/aidl/impl/default/include/EvsVideoEmulatedCamera.h b/automotive/evs/aidl/impl/default/include/EvsVideoEmulatedCamera.h
index 9d1610a..dc70a43 100644
--- a/automotive/evs/aidl/impl/default/include/EvsVideoEmulatedCamera.h
+++ b/automotive/evs/aidl/impl/default/include/EvsVideoEmulatedCamera.h
@@ -27,7 +27,6 @@
 #include <aidl/android/hardware/automotive/evs/ParameterRange.h>
 #include <aidl/android/hardware/automotive/evs/Stream.h>
 #include <media/NdkMediaExtractor.h>
-
 #include <ui/GraphicBuffer.h>
 
 #include <cstdint>
@@ -70,6 +69,8 @@
     // Methods from EvsCameraBase follow.
     void shutdown() override;
 
+    std::string getId() override { return mDescription.id; }
+
     const evs::CameraDesc& getDesc() { return mDescription; }
 
     static std::shared_ptr<EvsVideoEmulatedCamera> Create(const char* deviceName);
@@ -117,6 +118,10 @@
     bool postVideoStreamStop_locked(ndk::ScopedAStatus& status,
                                     std::unique_lock<std::mutex>& lck) override;
 
+    int (*mFillBuffer)(const uint8_t* src_y, int src_stride_y, const uint8_t* src_u,
+                       int src_stride_u, const uint8_t* src_v, int src_stride_v, uint8_t* dst_argb,
+                       int dst_stride_argb, int width, int height);
+
     // The properties of this camera.
     CameraDesc mDescription = {};
 
@@ -149,6 +154,10 @@
     uint64_t mUsage = 0;
     // Bytes per line in the buffers
     uint32_t mStride = 0;
+    // Bytes per line in the output buffer
+    uint32_t mDstStride = 0;
+    // Bytes per line of U/V plane
+    uint32_t mUvStride = 0;
 
     // Camera parameters.
     std::unordered_map<CameraParam, std::shared_ptr<CameraParameterDesc>> mParams;
diff --git a/automotive/evs/aidl/impl/default/src/ConfigManager.cpp b/automotive/evs/aidl/impl/default/src/ConfigManager.cpp
index d8961d0..eea80f4 100644
--- a/automotive/evs/aidl/impl/default/src/ConfigManager.cpp
+++ b/automotive/evs/aidl/impl/default/src/ConfigManager.cpp
@@ -52,6 +52,25 @@
     return search == nameToType.end() ? DeviceType::UNKNOWN : search->second;
 }
 
+ConfigManager::CameraInfo::PixelFormat ConfigManager::CameraInfo::pixelFormatFromSV(
+        const std::string_view sv) {
+    using namespace std::string_view_literals;
+    static const std::unordered_map<std::string_view, PixelFormat> nameToFormat = {
+            // Full resolution Y plane followed by 2x2 subsampled U/V
+            // interleaved plane.
+            {"NV12"sv, PixelFormat::NV12},
+            // Full resolution Y plane followed by 2x2 subsampled V/U
+            // interleaved plane.
+            {"NV21"sv, PixelFormat::NV21},
+            // Full resolution Y plane followed by 2x2 subsampled V plane and then U plane.
+            {"YV12"sv, PixelFormat::YV12},
+            // Full resolution Y plane followed by 2x2 subsampled U plane and then V plane.
+            {"I420"sv, PixelFormat::I420},
+    };
+    const auto search = nameToFormat.find(sv);
+    return search == nameToFormat.end() ? PixelFormat::UNKNOWN : search->second;
+}
+
 void ConfigManager::printElementNames(const XMLElement* rootElem, const std::string& prefix) const {
     const XMLElement* curElem = rootElem;
 
@@ -144,6 +163,10 @@
         aCamera->deviceType = CameraInfo::deviceTypeFromSV(typeAttr->Value());
     }
 
+    if (const auto formatAttr = aDeviceElem->FindAttribute("format")) {
+        aCamera->format = CameraInfo::pixelFormatFromSV(formatAttr->Value());
+    }
+
     /* size information to allocate camera_metadata_t */
     size_t totalEntries = 0;
     size_t totalDataSize = 0;
@@ -474,19 +497,16 @@
     return;
 }
 
-bool ConfigManager::readConfigDataFromXML() noexcept {
+bool ConfigManager::readConfigDataFromXML(const std::string path) noexcept {
     XMLDocument xmlDoc;
 
     const int64_t parsingStart = android::elapsedRealtimeNano();
 
     /* load and parse a configuration file */
-    xmlDoc.LoadFile(sConfigOverridePath.data());
+    xmlDoc.LoadFile(path.c_str());
     if (xmlDoc.ErrorID() != tinyxml2::XML_SUCCESS) {
-        xmlDoc.LoadFile(sConfigDefaultPath.data());
-        if (xmlDoc.ErrorID() != tinyxml2::XML_SUCCESS) {
-            LOG(ERROR) << "Failed to load and/or parse a configuration file, " << xmlDoc.ErrorStr();
-            return false;
-        }
+        LOG(ERROR) << "Failed to load and/or parse a configuration file, " << xmlDoc.ErrorStr();
+        return false;
     }
 
     /* retrieve the root element */
@@ -644,8 +664,7 @@
                     p += count * sizeof(camera_metadata_rational_t);
                     break;
                 default:
-                    LOG(WARNING) << "Type " << type << " is unknown; "
-                                 << "data may be corrupted.";
+                    LOG(WARNING) << "Type " << type << " is unknown; " << "data may be corrupted.";
                     break;
             }
         }
@@ -746,8 +765,7 @@
                     p += count * sizeof(camera_metadata_rational_t);
                     break;
                 default:
-                    LOG(WARNING) << "Type " << type << " is unknown; "
-                                 << "data may be corrupted.";
+                    LOG(WARNING) << "Type " << type << " is unknown; " << "data may be corrupted.";
                     break;
             }
         }
@@ -958,6 +976,16 @@
 }
 
 std::unique_ptr<ConfigManager> ConfigManager::Create() {
+    std::unique_ptr<ConfigManager> mgr = Create(std::string(sConfigOverridePath));
+    if (!mgr) {
+        LOG(DEBUG) << "A configuration override file does not exist. Use a default file instead.";
+        mgr = Create(std::string((sConfigDefaultPath)));
+    }
+
+    return mgr;
+}
+
+std::unique_ptr<ConfigManager> ConfigManager::Create(const std::string path) {
     std::unique_ptr<ConfigManager> cfgMgr(new ConfigManager());
 
     /*
@@ -968,7 +996,7 @@
      * to the filesystem and construct CameraInfo instead; this was
      * evaluated as 10x faster.
      */
-    if (!cfgMgr->readConfigDataFromXML()) {
+    if (!cfgMgr->readConfigDataFromXML(path)) {
         return nullptr;
     } else {
         return cfgMgr;
diff --git a/automotive/evs/aidl/impl/default/src/EvsCamera.cpp b/automotive/evs/aidl/impl/default/src/EvsCamera.cpp
index 005c71f..c28f86f 100644
--- a/automotive/evs/aidl/impl/default/src/EvsCamera.cpp
+++ b/automotive/evs/aidl/impl/default/src/EvsCamera.cpp
@@ -205,7 +205,8 @@
         }
 
         if ((!preVideoStreamStop_locked(status, lck) || !stopVideoStreamImpl_locked(status, lck) ||
-             !postVideoStreamStop_locked(status, lck)) && !status.isOk()) {
+             !postVideoStreamStop_locked(status, lck)) &&
+            !status.isOk()) {
             needShutdown = true;
         }
     }
diff --git a/automotive/evs/aidl/impl/default/src/EvsVideoEmulatedCamera.cpp b/automotive/evs/aidl/impl/default/src/EvsVideoEmulatedCamera.cpp
index 480c28d..7574a34 100644
--- a/automotive/evs/aidl/impl/default/src/EvsVideoEmulatedCamera.cpp
+++ b/automotive/evs/aidl/impl/default/src/EvsVideoEmulatedCamera.cpp
@@ -26,6 +26,7 @@
 #include <utils/SystemClock.h>
 
 #include <fcntl.h>
+#include <libyuv.h>
 #include <sys/types.h>
 #include <unistd.h>
 
@@ -35,12 +36,45 @@
 #include <tuple>
 #include <utility>
 
+// Uncomment below line to dump decoded frames.
+// #define DUMP_FRAMES (1)
+
 namespace aidl::android::hardware::automotive::evs::implementation {
 
 namespace {
+
 struct FormatDeleter {
     void operator()(AMediaFormat* format) const { AMediaFormat_delete(format); }
 };
+
+int fillRGBAFromNv12(const uint8_t* src_y, int src_stride_y, const uint8_t* src_uv,
+                     int src_stride_uv, const uint8_t*, int, uint8_t* dst_abgr, int dst_stride_abgr,
+                     int width, int height) {
+    return libyuv::NV12ToABGR(src_y, src_stride_y, src_uv, src_stride_uv, dst_abgr, dst_stride_abgr,
+                              width, height);
+}
+
+int fillRGBAFromNv21(const uint8_t* src_y, int src_stride_y, const uint8_t* src_vu,
+                     int src_stride_vu, const uint8_t*, int, uint8_t* dst_abgr, int dst_stride_abgr,
+                     int width, int height) {
+    return libyuv::NV21ToABGR(src_y, src_stride_y, src_vu, src_stride_vu, dst_abgr, dst_stride_abgr,
+                              width, height);
+}
+
+int fillRGBAFromYv12(const uint8_t* src_y, int src_stride_y, const uint8_t* src_u, int src_stride_u,
+                     const uint8_t* src_v, int src_stride_v, uint8_t* dst_abgr, int dst_stride_abgr,
+                     int width, int height) {
+    return libyuv::I420ToABGR(src_y, src_stride_y, src_u, src_stride_u, src_v, src_stride_v,
+                              dst_abgr, dst_stride_abgr, width, height);
+}
+
+int fillRGBAFromI420(const uint8_t* src_y, int src_stride_y, const uint8_t* src_u, int src_stride_u,
+                     const uint8_t* src_v, int src_stride_v, uint8_t* dst_abgr, int dst_stride_abgr,
+                     int width, int height) {
+    return libyuv::I420ToABGR(src_y, src_stride_y, src_u, src_stride_u, src_v, src_stride_v,
+                              dst_abgr, dst_stride_abgr, width, height);
+}
+
 }  // namespace
 
 EvsVideoEmulatedCamera::EvsVideoEmulatedCamera(Sigil, const char* deviceName,
@@ -123,7 +157,7 @@
     mDescription.vendorFlags = 0xFFFFFFFF;  // Arbitrary test value
     mUsage = GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_CAMERA_WRITE |
              GRALLOC_USAGE_SW_READ_RARELY | GRALLOC_USAGE_SW_WRITE_RARELY;
-    mFormat = HAL_PIXEL_FORMAT_YCBCR_420_888;
+    mFormat = HAL_PIXEL_FORMAT_RGBA_8888;
     AMediaFormat_setInt32(format.get(), AMEDIAFORMAT_KEY_COLOR_FORMAT, COLOR_FormatYUV420Flexible);
     {
         const media_status_t status =
@@ -137,6 +171,30 @@
     format.reset(AMediaCodec_getOutputFormat(mVideoCodec.get()));
     AMediaFormat_getInt32(format.get(), AMEDIAFORMAT_KEY_WIDTH, &mWidth);
     AMediaFormat_getInt32(format.get(), AMEDIAFORMAT_KEY_HEIGHT, &mHeight);
+
+    switch (mCameraInfo->format) {
+        default:
+        case ConfigManager::CameraInfo::PixelFormat::NV12:
+            mFillBuffer = fillRGBAFromNv12;
+            mUvStride = mWidth;
+            mDstStride = mWidth * 4;
+            break;
+        case ConfigManager::CameraInfo::PixelFormat::NV21:
+            mFillBuffer = fillRGBAFromNv21;
+            mUvStride = mWidth;
+            mDstStride = mWidth * 4;
+            break;
+        case ConfigManager::CameraInfo::PixelFormat::YV12:
+            mFillBuffer = fillRGBAFromYv12;
+            mUvStride = mWidth / 2;
+            mDstStride = mWidth * 4;
+            break;
+        case ConfigManager::CameraInfo::PixelFormat::I420:
+            mFillBuffer = fillRGBAFromI420;
+            mUvStride = mWidth / 2;
+            mDstStride = mWidth * 4;
+            break;
+    }
     return true;
 }
 
@@ -190,6 +248,28 @@
     uint8_t* const codecOutputBuffer =
             AMediaCodec_getOutputBuffer(mVideoCodec.get(), index, &decodedOutSize) + info.offset;
 
+    int color_format = 0;
+    const auto outFormat = AMediaCodec_getOutputFormat(mVideoCodec.get());
+    if (!AMediaFormat_getInt32(outFormat, AMEDIAFORMAT_KEY_COLOR_FORMAT, &color_format)) {
+        LOG(ERROR) << "Failed to get the color format.";
+        return;
+    }
+
+    int stride = 0;
+    if (!AMediaFormat_getInt32(outFormat, AMEDIAFORMAT_KEY_STRIDE, &stride)) {
+        LOG(WARNING) << "Cannot find stride in format. Set as frame width.";
+        stride = mWidth;
+    }
+
+    int slice_height = 0;
+    if (!AMediaFormat_getInt32(outFormat, AMEDIAFORMAT_KEY_SLICE_HEIGHT, &slice_height)) {
+        LOG(WARNING) << "Cannot find slice-height in format. Set as frame height.";
+        slice_height = mHeight;
+    }
+
+    LOG(DEBUG) << "COLOR FORMAT: " << color_format << " stride: " << stride
+               << " height: " << slice_height;
+
     std::size_t renderBufferId = static_cast<std::size_t>(-1);
     buffer_handle_t renderBufferHandle = nullptr;
     {
@@ -200,7 +280,7 @@
         std::tie(renderBufferId, renderBufferHandle) = useBuffer_unsafe();
     }
     if (!renderBufferHandle) {
-        LOG(ERROR) << __func__ << ": Camera failed to get an available render buffer.";
+        LOG(DEBUG) << __func__ << ": Camera failed to get an available render buffer.";
         return;
     }
     std::vector<BufferDesc> renderBufferDescs;
@@ -236,19 +316,51 @@
         return;
     }
 
-    std::size_t ySize = mHeight * mStride;
+    // Decoded output is in YUV4:2:0.
+    std::size_t ySize = mHeight * mWidth;
     std::size_t uvSize = ySize / 4;
 
-    std::memcpy(pixels, codecOutputBuffer, ySize);
-    pixels += ySize;
-
     uint8_t* u_head = codecOutputBuffer + ySize;
     uint8_t* v_head = u_head + uvSize;
 
-    for (size_t i = 0; i < uvSize; ++i) {
-        *(pixels++) = *(u_head++);
-        *(pixels++) = *(v_head++);
+#if DUMP_FRAMES
+    // TODO: We may want to keep this "dump" option.
+    static int dumpCount = 0;
+    static bool dumpData = ++dumpCount < 10;
+    if (dumpData) {
+        std::string path = "/data/vendor/dump/";
+        path += "dump_" + std::to_string(dumpCount) + ".bin";
+
+        ::android::base::unique_fd fd(
+                open(path.data(), O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP));
+        if (fd < 0) {
+            LOG(ERROR) << "Failed to open " << path;
+        } else {
+            auto len = write(fd.get(), codecOutputBuffer, info.size);
+            LOG(ERROR) << "Write " << len << " to " << path;
+        }
     }
+#endif
+    if (auto result = mFillBuffer(codecOutputBuffer, mWidth, u_head, mUvStride, v_head, mUvStride,
+                                  pixels, mDstStride, mWidth, mHeight);
+        result != 0) {
+        LOG(ERROR) << "Failed to convert I420 to BGRA";
+    }
+#if DUMP_FRAMES
+    else if (dumpData) {
+        std::string path = "/data/vendor/dump/";
+        path += "dump_" + std::to_string(dumpCount) + "_rgba.bin";
+
+        ::android::base::unique_fd fd(
+                open(path.data(), O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP));
+        if (fd < 0) {
+            LOG(ERROR) << "Failed to open " << path;
+        } else {
+            auto len = write(fd.get(), pixels, mStride * mHeight * 4);
+            LOG(ERROR) << "Write " << len << " to " << path;
+        }
+    }
+#endif
 
     // Release our output buffer
     mapper.unlock(renderBufferHandle);
@@ -332,8 +444,8 @@
 ::android::status_t EvsVideoEmulatedCamera::allocateOneFrame(buffer_handle_t* handle) {
     static auto& alloc = ::android::GraphicBufferAllocator::get();
     unsigned pixelsPerLine = 0;
-    const auto result = alloc.allocate(mWidth, mHeight, mFormat, 1, mUsage, handle, &pixelsPerLine,
-                                       0, "EvsVideoEmulatedCamera");
+    const auto result = alloc.allocate(mWidth, mHeight, HAL_PIXEL_FORMAT_RGBA_8888, 1, mUsage,
+                                       handle, &pixelsPerLine, 0, "EvsVideoEmulatedCamera");
     if (mStride == 0) {
         // Gralloc defines stride in terms of pixels per line
         mStride = pixelsPerLine;
@@ -350,7 +462,7 @@
 
     if (auto status = AMediaCodec_start(mVideoCodec.get()); status != AMEDIA_OK) {
         LOG(INFO) << __func__ << ": Received error in starting decoder. "
-                     << "Trying again after resetting this emulated device.";
+                  << "Trying again after resetting this emulated device.";
 
         if (!initializeMediaCodec()) {
             LOG(ERROR) << __func__ << ": Failed to re-configure the media codec.";
@@ -361,7 +473,7 @@
                                AMEDIAEXTRACTOR_SEEK_CLOSEST_SYNC);
         AMediaCodec_flush(mVideoCodec.get());
 
-        if(auto status = AMediaCodec_start(mVideoCodec.get()); status != AMEDIA_OK) {
+        if (auto status = AMediaCodec_start(mVideoCodec.get()); status != AMEDIA_OK) {
             LOG(ERROR) << __func__ << ": Received error again in starting decoder. "
                        << "Error code: " << status;
             return false;
@@ -389,7 +501,9 @@
         return false;
     }
 
-    EvsEventDesc event = { .aType = EvsEventType::STREAM_STOPPED, };
+    EvsEventDesc event = {
+            .aType = EvsEventType::STREAM_STOPPED,
+    };
     if (auto result = mStream->notify(event); !result.isOk()) {
         LOG(WARNING) << "Failed to notify the end of the stream.";
     }
diff --git a/automotive/evs/aidl/impl/default/tests/EvsCameraBufferTest.cpp b/automotive/evs/aidl/impl/default/tests/EvsCameraBufferTest.cpp
index 8b4676e..ce0e776 100644
--- a/automotive/evs/aidl/impl/default/tests/EvsCameraBufferTest.cpp
+++ b/automotive/evs/aidl/impl/default/tests/EvsCameraBufferTest.cpp
@@ -92,6 +92,7 @@
                 (override));
     MOCK_METHOD(bool, stopVideoStreamImpl_locked,
                 (ndk::ScopedAStatus & status, std::unique_lock<std::mutex>& lck), (override));
+    MOCK_METHOD(std::string, getId, (), (override));
 };
 
 TEST(EvsCameraBufferTest, ChangeBufferPoolSize) {
diff --git a/automotive/evs/aidl/impl/default/tests/EvsCameraStateTest.cpp b/automotive/evs/aidl/impl/default/tests/EvsCameraStateTest.cpp
index 1925c79..c517e34 100644
--- a/automotive/evs/aidl/impl/default/tests/EvsCameraStateTest.cpp
+++ b/automotive/evs/aidl/impl/default/tests/EvsCameraStateTest.cpp
@@ -141,6 +141,7 @@
                 (override));
     MOCK_METHOD(::ndk::ScopedAStatus, setPrimaryClient, (), (override));
     MOCK_METHOD(::ndk::ScopedAStatus, unsetPrimaryClient, (), (override));
+    MOCK_METHOD(std::string, getId, (), (override));
 
     bool mStreamStarted = false;
     bool mStreamStopped = false;
@@ -160,7 +161,7 @@
     MOCK_METHOD(::ndk::ScopedAStatus, notify,
                 (const ::aidl::android::hardware::automotive::evs::EvsEventDesc& in_event),
                 (override));
-    MOCK_METHOD(::ndk::ScopedAStatus, getInterfaceVersion, (int32_t * _aidl_return), (override));
+    MOCK_METHOD(::ndk::ScopedAStatus, getInterfaceVersion, (int32_t* _aidl_return), (override));
     MOCK_METHOD(::ndk::ScopedAStatus, getInterfaceHash, (std::string * _aidl_return), (override));
 };
 
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataTag.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataTag.aidl
index 8387c81..2615270 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataTag.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataTag.aidl
@@ -104,6 +104,8 @@
   ANDROID_CONTROL_AUTOFRAMING_STATE,
   ANDROID_CONTROL_LOW_LIGHT_BOOST_INFO_LUMINANCE_RANGE,
   ANDROID_CONTROL_LOW_LIGHT_BOOST_STATE,
+  ANDROID_CONTROL_AE_PRIORITY_MODE = 65597,
+  ANDROID_CONTROL_AE_AVAILABLE_PRIORITY_MODES,
   ANDROID_DEMOSAIC_MODE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_DEMOSAIC_START /* 131072 */,
   ANDROID_EDGE_MODE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_EDGE_START /* 196608 */,
   ANDROID_EDGE_STRENGTH,
@@ -347,10 +349,17 @@
   ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION,
   ANDROID_HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION,
   ANDROID_HEIC_AVAILABLE_HEIC_STALL_DURATIONS_MAXIMUM_RESOLUTION,
+  ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS,
+  ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_MIN_FRAME_DURATIONS,
+  ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STALL_DURATIONS,
+  ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION,
+  ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION,
+  ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STALL_DURATIONS_MAXIMUM_RESOLUTION,
   ANDROID_HEIC_INFO_SUPPORTED = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_HEIC_INFO_START /* 1900544 */,
   ANDROID_HEIC_INFO_MAX_JPEG_APP_SEGMENTS_COUNT,
   ANDROID_AUTOMOTIVE_LOCATION = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_AUTOMOTIVE_START /* 1966080 */,
   ANDROID_AUTOMOTIVE_LENS_FACING = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_AUTOMOTIVE_LENS_START /* 2031616 */,
+  ANDROID_EXTENSION_NIGHT_MODE_INDICATOR = 2097154,
   ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_JPEGR_START /* 2162688 */,
   ANDROID_JPEGR_AVAILABLE_JPEG_R_MIN_FRAME_DURATIONS,
   ANDROID_JPEGR_AVAILABLE_JPEG_R_STALL_DURATIONS,
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAePriorityMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAePriorityMode.aidl
new file mode 100644
index 0000000..eac2147
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAePriorityMode.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2024 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.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.camera.metadata;
+@Backing(type="int") @VintfStability
+enum ControlAePriorityMode {
+  ANDROID_CONTROL_AE_PRIORITY_MODE_OFF,
+  ANDROID_CONTROL_AE_PRIORITY_MODE_SENSOR_SENSITIVITY_PRIORITY,
+  ANDROID_CONTROL_AE_PRIORITY_MODE_SENSOR_EXPOSURE_TIME_PRIORITY,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ExtensionNightModeIndicator.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ExtensionNightModeIndicator.aidl
new file mode 100644
index 0000000..6cfdc02
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ExtensionNightModeIndicator.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2024 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.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.camera.metadata;
+@Backing(type="int") @VintfStability
+enum ExtensionNightModeIndicator {
+  ANDROID_EXTENSION_NIGHT_MODE_INDICATOR_UNKNOWN,
+  ANDROID_EXTENSION_NIGHT_MODE_INDICATOR_OFF,
+  ANDROID_EXTENSION_NIGHT_MODE_INDICATOR_ON,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/HeicAvailableHeicUltraHdrStreamConfigurations.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/HeicAvailableHeicUltraHdrStreamConfigurations.aidl
new file mode 100644
index 0000000..339d2fa
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/HeicAvailableHeicUltraHdrStreamConfigurations.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2024 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.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.camera.metadata;
+@Backing(type="int") @VintfStability
+enum HeicAvailableHeicUltraHdrStreamConfigurations {
+  ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS_OUTPUT,
+  ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS_INPUT,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/HeicAvailableHeicUltraHdrStreamConfigurationsMaximumResolution.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/HeicAvailableHeicUltraHdrStreamConfigurationsMaximumResolution.aidl
new file mode 100644
index 0000000..7755069
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/HeicAvailableHeicUltraHdrStreamConfigurationsMaximumResolution.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2024 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.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.camera.metadata;
+@Backing(type="int") @VintfStability
+enum HeicAvailableHeicUltraHdrStreamConfigurationsMaximumResolution {
+  ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT,
+  ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorReadoutTimestamp.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorReadoutTimestamp.aidl
index 35dc1a9..11be18e 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorReadoutTimestamp.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorReadoutTimestamp.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2024 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataTag.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataTag.aidl
index 98897a2..66ca912 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataTag.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataTag.aidl
@@ -534,6 +534,21 @@
      */
     ANDROID_CONTROL_LOW_LIGHT_BOOST_STATE,
     /**
+     * android.control.aePriorityMode [dynamic, enum, public]
+     *
+     * <p>Turn on AE priority mode.</p>
+     */
+    ANDROID_CONTROL_AE_PRIORITY_MODE = 65597,
+    /**
+     * android.control.aeAvailablePriorityModes [static, byte[], public]
+     *
+     * <p>List of auto-exposure priority modes for ANDROID_CONTROL_AE_PRIORITY_MODE
+     * that are supported by this camera device.</p>
+     *
+     * @see ANDROID_CONTROL_AE_PRIORITY_MODE
+     */
+    ANDROID_CONTROL_AE_AVAILABLE_PRIORITY_MODES,
+    /**
      * android.demosaic.mode [controls, enum, system]
      *
      * <p>Controls the quality of the demosaicing
@@ -2378,6 +2393,62 @@
      */
     ANDROID_HEIC_AVAILABLE_HEIC_STALL_DURATIONS_MAXIMUM_RESOLUTION,
     /**
+     * android.heic.availableHeicUltraHdrStreamConfigurations [static, enum[], ndk_public]
+     *
+     * <p>The available HEIC (ISO/IEC 23008-12/24) UltraHDR stream
+     * configurations that this camera device supports
+     * (i.e. format, width, height, output/input stream).</p>
+     */
+    ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS,
+    /**
+     * android.heic.availableHeicUltraHdrMinFrameDurations [static, int64[], ndk_public]
+     *
+     * <p>This lists the minimum frame duration for each
+     * format/size combination for HEIC UltraHDR output formats.</p>
+     */
+    ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_MIN_FRAME_DURATIONS,
+    /**
+     * android.heic.availableHeicUltraHdrStallDurations [static, int64[], ndk_public]
+     *
+     * <p>This lists the maximum stall duration for each
+     * output format/size combination for HEIC UltraHDR streams.</p>
+     */
+    ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STALL_DURATIONS,
+    /**
+     * android.heic.availableHeicUltraHdrStreamConfigurationsMaximumResolution [static, enum[], ndk_public]
+     *
+     * <p>The available HEIC (ISO/IEC 23008-12/24) UltraHDR stream
+     * configurations that this camera device supports
+     * (i.e. format, width, height, output/input stream) for CaptureRequests where
+     * ANDROID_SENSOR_PIXEL_MODE is set to
+     * <a href="https://developer.android.com/reference/android/hardware/camera2/CameraMetadata.html#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION">CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION</a>.</p>
+     *
+     * @see ANDROID_SENSOR_PIXEL_MODE
+     */
+    ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION,
+    /**
+     * android.heic.availableHeicUltraHdrMinFrameDurationsMaximumResolution [static, int64[], ndk_public]
+     *
+     * <p>This lists the minimum frame duration for each
+     * format/size combination for HEIC UltraHDR output formats for CaptureRequests where
+     * ANDROID_SENSOR_PIXEL_MODE is set to
+     * <a href="https://developer.android.com/reference/android/hardware/camera2/CameraMetadata.html#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION">CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION</a>.</p>
+     *
+     * @see ANDROID_SENSOR_PIXEL_MODE
+     */
+    ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION,
+    /**
+     * android.heic.availableHeicUltraHdrStallDurationsMaximumResolution [static, int64[], ndk_public]
+     *
+     * <p>This lists the maximum stall duration for each
+     * output format/size combination for HEIC UltraHDR streams for CaptureRequests where
+     * ANDROID_SENSOR_PIXEL_MODE is set to
+     * <a href="https://developer.android.com/reference/android/hardware/camera2/CameraMetadata.html#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION">CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION</a>.</p>
+     *
+     * @see ANDROID_SENSOR_PIXEL_MODE
+     */
+    ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STALL_DURATIONS_MAXIMUM_RESOLUTION,
+    /**
      * android.heic.info.supported [static, enum, system]
      *
      * <p>Whether this camera device can support identical set of stream combinations
@@ -2407,6 +2478,13 @@
      */
     ANDROID_AUTOMOTIVE_LENS_FACING = CameraMetadataSectionStart.ANDROID_AUTOMOTIVE_LENS_START,
     /**
+     * android.extension.nightModeIndicator [dynamic, enum, public]
+     *
+     * <p>Indicates when to activate Night Mode Camera Extension for high-quality
+     * still captures in low-light conditions.</p>
+     */
+    ANDROID_EXTENSION_NIGHT_MODE_INDICATOR = 2097154,
+    /**
      * android.jpegr.availableJpegRStreamConfigurations [static, enum[], ndk_public]
      *
      * <p>The available Jpeg/R stream
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ControlAePriorityMode.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAePriorityMode.aidl
new file mode 100644
index 0000000..fd4f531
--- /dev/null
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAePriorityMode.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2024 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.
+ */
+
+/*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+
+package android.hardware.camera.metadata;
+
+/**
+ * android.control.aePriorityMode enumeration values
+ * @see ANDROID_CONTROL_AE_PRIORITY_MODE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
+ */
+@VintfStability
+@Backing(type="int")
+enum ControlAePriorityMode {
+    ANDROID_CONTROL_AE_PRIORITY_MODE_OFF,
+    ANDROID_CONTROL_AE_PRIORITY_MODE_SENSOR_SENSITIVITY_PRIORITY,
+    ANDROID_CONTROL_AE_PRIORITY_MODE_SENSOR_EXPOSURE_TIME_PRIORITY,
+}
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ExtensionNightModeIndicator.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ExtensionNightModeIndicator.aidl
new file mode 100644
index 0000000..3c3bdf5
--- /dev/null
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ExtensionNightModeIndicator.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2024 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.
+ */
+
+/*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+
+package android.hardware.camera.metadata;
+
+/**
+ * android.extension.nightModeIndicator enumeration values
+ * @see ANDROID_EXTENSION_NIGHT_MODE_INDICATOR
+ * See system/media/camera/docs/metadata_definitions.xml for details.
+ */
+@VintfStability
+@Backing(type="int")
+enum ExtensionNightModeIndicator {
+    ANDROID_EXTENSION_NIGHT_MODE_INDICATOR_UNKNOWN,
+    ANDROID_EXTENSION_NIGHT_MODE_INDICATOR_OFF,
+    ANDROID_EXTENSION_NIGHT_MODE_INDICATOR_ON,
+}
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/HeicAvailableHeicUltraHdrStreamConfigurations.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/HeicAvailableHeicUltraHdrStreamConfigurations.aidl
new file mode 100644
index 0000000..56761b9
--- /dev/null
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/HeicAvailableHeicUltraHdrStreamConfigurations.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2024 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.
+ */
+
+/*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+
+package android.hardware.camera.metadata;
+
+/**
+ * android.heic.availableHeicUltraHdrStreamConfigurations enumeration values
+ * @see ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS
+ * See system/media/camera/docs/metadata_definitions.xml for details.
+ */
+@VintfStability
+@Backing(type="int")
+enum HeicAvailableHeicUltraHdrStreamConfigurations {
+    ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS_OUTPUT,
+    ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS_INPUT,
+}
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/HeicAvailableHeicUltraHdrStreamConfigurationsMaximumResolution.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/HeicAvailableHeicUltraHdrStreamConfigurationsMaximumResolution.aidl
new file mode 100644
index 0000000..7fb19dc
--- /dev/null
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/HeicAvailableHeicUltraHdrStreamConfigurationsMaximumResolution.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2024 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.
+ */
+
+/*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+
+package android.hardware.camera.metadata;
+
+/**
+ * android.heic.availableHeicUltraHdrStreamConfigurationsMaximumResolution enumeration values
+ * @see ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION
+ * See system/media/camera/docs/metadata_definitions.xml for details.
+ */
+@VintfStability
+@Backing(type="int")
+enum HeicAvailableHeicUltraHdrStreamConfigurationsMaximumResolution {
+    ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT,
+    ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT,
+}
diff --git a/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp b/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
index 9fa4df2..ec61eec 100644
--- a/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
+++ b/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
@@ -118,7 +118,8 @@
     ScopedAStatus ret = mProvider->setCallback(cb);
     ASSERT_TRUE(ret.isOk());
     ret = mProvider->setCallback(nullptr);
-    ASSERT_EQ(static_cast<int32_t>(Status::ILLEGAL_ARGUMENT), ret.getServiceSpecificError());
+    ASSERT_TRUE(static_cast<int32_t>(Status::ILLEGAL_ARGUMENT) == ret.getServiceSpecificError() ||
+                EX_NULL_POINTER == ret.getExceptionCode());
 }
 
 // Test if ICameraProvider::getCameraDeviceInterface returns Status::OK and non-null device
diff --git a/compatibility_matrices/compatibility_matrix.202504.xml b/compatibility_matrices/compatibility_matrix.202504.xml
index 0a7c188..93bae39 100644
--- a/compatibility_matrices/compatibility_matrix.202504.xml
+++ b/compatibility_matrices/compatibility_matrix.202504.xml
@@ -388,7 +388,7 @@
     </hal>
     <hal format="aidl">
         <name>android.hardware.radio.config</name>
-        <version>3</version>
+        <version>3-4</version>
         <interface>
             <name>IRadioConfig</name>
             <instance>default</instance>
@@ -406,7 +406,7 @@
     </hal>
     <hal format="aidl">
         <name>android.hardware.radio.messaging</name>
-        <version>3</version>
+        <version>3-4</version>
         <interface>
             <name>IRadioMessaging</name>
             <instance>slot1</instance>
@@ -416,7 +416,7 @@
     </hal>
     <hal format="aidl">
         <name>android.hardware.radio.modem</name>
-        <version>3</version>
+        <version>3-4</version>
         <interface>
             <name>IRadioModem</name>
             <instance>slot1</instance>
@@ -426,7 +426,7 @@
     </hal>
     <hal format="aidl">
         <name>android.hardware.radio.network</name>
-        <version>3</version>
+        <version>3-4</version>
         <interface>
             <name>IRadioNetwork</name>
             <instance>slot1</instance>
@@ -436,7 +436,7 @@
     </hal>
     <hal format="aidl">
         <name>android.hardware.radio.sim</name>
-        <version>3</version>
+        <version>3-4</version>
         <interface>
             <name>IRadioSim</name>
             <instance>slot1</instance>
@@ -456,7 +456,7 @@
     </hal>
     <hal format="aidl">
         <name>android.hardware.radio.voice</name>
-        <version>3</version>
+        <version>3-4</version>
         <interface>
             <name>IRadioVoice</name>
             <instance>slot1</instance>
@@ -466,7 +466,7 @@
     </hal>
     <hal format="aidl">
         <name>android.hardware.radio.ims</name>
-        <version>2</version>
+        <version>2-3</version>
         <interface>
             <name>IRadioIms</name>
             <instance>slot1</instance>
diff --git a/contexthub/OWNERS b/contexthub/OWNERS
index f35961a..ccd385b 100644
--- a/contexthub/OWNERS
+++ b/contexthub/OWNERS
@@ -1,2 +1,3 @@
 # Bug component: 156070
 bduddie@google.com
+arthuri@google.com
diff --git a/contexthub/aidl/default/ContextHub.cpp b/contexthub/aidl/default/ContextHub.cpp
index 5713a1b..a915191 100644
--- a/contexthub/aidl/default/ContextHub.cpp
+++ b/contexthub/aidl/default/ContextHub.cpp
@@ -158,8 +158,8 @@
     vendorHub.version = 42;
 
     HubInfo hubInfo2 = {};
-    hubInfo1.hubId = UINT64_C(0x1234567812345678);
-    hubInfo1.hubDetails =
+    hubInfo2.hubId = UINT64_C(0x1234567812345678);
+    hubInfo2.hubDetails =
             HubInfo::HubDetails::make<HubInfo::HubDetails::Tag::vendorHubInfo>(vendorHub);
 
     _aidl_return->push_back(hubInfo1);
diff --git a/graphics/composer/aidl/Android.bp b/graphics/composer/aidl/Android.bp
index bba41da..f4264eb 100644
--- a/graphics/composer/aidl/Android.bp
+++ b/graphics/composer/aidl/Android.bp
@@ -77,7 +77,6 @@
                 "android.hardware.common-V2",
             ],
         },
-
     ],
 
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayCapability.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayCapability.aidl
index 0e2d72b..955ff89 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayCapability.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayCapability.aidl
@@ -43,4 +43,5 @@
   SUSPEND = 6,
   DISPLAY_IDLE_TIMER = 7,
   MULTI_THREADED_PRESENT = 8,
+  PICTURE_PROCESSING = 9,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayCommand.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayCommand.aidl
index cce35e7..9e24a26 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayCommand.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayCommand.aidl
@@ -46,4 +46,5 @@
   boolean presentDisplay;
   boolean presentOrValidateDisplay;
   int frameIntervalNs;
+  long pictureProfileId;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl
index c71c010..55604a6 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl
@@ -87,6 +87,7 @@
   void setRefreshRateChangedCallbackDebugEnabled(long display, boolean enabled);
   android.hardware.graphics.composer3.DisplayConfiguration[] getDisplayConfigurations(long display, int maxFrameIntervalNs);
   oneway void notifyExpectedPresent(long display, in android.hardware.graphics.composer3.ClockMonotonicTimestamp expectedPresentTime, int frameIntervalNs);
+  int getMaxLayerPictureProfiles(long display);
   const int EX_BAD_CONFIG = 1;
   const int EX_BAD_DISPLAY = 2;
   const int EX_BAD_LAYER = 3;
@@ -98,5 +99,6 @@
   const int EX_SEAMLESS_NOT_ALLOWED = 9;
   const int EX_SEAMLESS_NOT_POSSIBLE = 10;
   const int EX_CONFIG_FAILED = 11;
+  const int EX_PICTURE_PROFILE_MAX_EXCEEDED = 12;
   const int INVALID_CONFIGURATION = 0x7fffffff;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerCommand.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerCommand.aidl
index 87c0e1e..c26cb15 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerCommand.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerCommand.aidl
@@ -58,4 +58,5 @@
   android.hardware.graphics.composer3.LayerLifecycleBatchCommandType layerLifecycleBatchCommandType;
   int newBufferSlotCount;
   @nullable android.hardware.graphics.composer3.Luts luts;
+  long pictureProfileId;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCapability.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCapability.aidl
index 7154d74..fa58fb7 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCapability.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCapability.aidl
@@ -96,4 +96,10 @@
      * @see DisplayCommand.validateDisplay
      */
     MULTI_THREADED_PRESENT = 8,
+    /**
+     * Specifies that the display supports a global picture-processing pipeline.
+     *
+     * @see DisplayCommand.pictureProfileId
+     */
+    PICTURE_PROCESSING = 9,
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCommand.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCommand.aidl
index 02c1389..c3fd68e 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCommand.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCommand.aidl
@@ -185,4 +185,21 @@
      * close as possible to the cadence.
      */
     int frameIntervalNs;
+
+    /**
+     * If the display supports DisplayCapability.PICTURE_PROCESSING, then this value is used to look
+     * up a picture profile which defines the parameters used when configuring a picture-processing
+     * pipeline applied to the composition result, enhancing the quality of the entire composed
+     * image. If the server does not recognize the picture profile, it must continue composition
+     * and ignore this value. If the value is zero, then the server's default picture processing,
+     * if possible, must be applied.
+     *
+     * Note that the client will never send a DisplayCommand.pictureProfileId if
+     * IComposerClient.getMaxLayerPictureProfiles is non-zero. Picture profiles will only be
+     * specified on a per-layer basis via LayerCommand.pictureProfileId.
+     *
+     * @see IComposerClient.getMaxLayerPictureProfiles
+     * @see DisplayCommand.pictureProfileId
+     */
+    long pictureProfileId;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl
index 9650334..edbb988 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl
@@ -99,6 +99,14 @@
     const int EX_CONFIG_FAILED = 11;
 
     /**
+     * The number of per-layer picture profiles in use is larger than the number of layer-specific
+     * picture-processing pipelines, as-defined by getMaxLayerPictureProfiles.
+     *
+     * @see LayerCommand.pictureProfileId
+     */
+    const int EX_PICTURE_PROFILE_MAX_EXCEEDED = 12;
+
+    /**
      * Integer.MAX_VALUE is reserved for the invalid configuration.
      * This should not be returned as a valid configuration.
      */
@@ -919,4 +927,15 @@
      */
     oneway void notifyExpectedPresent(
             long display, in ClockMonotonicTimestamp expectedPresentTime, int frameIntervalNs);
+
+    /*
+     * Returns the number of layer-specific picture-processing profiles that can be referenced from
+     * multiple LayerCommand.pictureProfileId. If the client passes in more pictureProfileIds whose
+     * values are larger than zero (indicating none) then the implementation can support, it should
+     * return EX_PICTURE_PROFILE_MAX_EXCEEDED.
+     *
+     * If the implementation only supports one display-wide picture-processing
+     * pipeline, a value of zero should be returned here.
+     */
+    int getMaxLayerPictureProfiles(long display);
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl
index c89887d..d7ef4c1 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl
@@ -285,4 +285,20 @@
      * Sets the lut(s) for the layer.
      */
     @nullable Luts luts;
+
+    /**
+     * If the display has multiple per-layer picture processing pipelines, then this value is used
+     * to look up a picture profile which defines the parameters used when configuring a
+     * picture-processing pipeline for this layer, enhancing the quality of the buffer contents. If
+     * the server doesn't recognize this profile, it must continue with composition and ignore
+     * this value. If the value is zero, then the no picture processing must be applied.
+     *
+     * Note that the client will never send a DisplayCommand.pictureProfileId if
+     * IComposerClient.getMaxLayerPictureProfiles is non-zero. Picture profiles will only be
+     * specified on a per-layer basis.
+     *
+     * @see IComposerClient.getMaxLayerPictureProfiles
+     * @see DisplayCommand.pictureProfileId
+     */
+    long pictureProfileId;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LutProperties.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/LutProperties.aidl
index 1c6fd18..d3dd30e 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/LutProperties.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/LutProperties.aidl
@@ -36,8 +36,8 @@
 
     /**
      * SamplingKey is about how a Lut can be sampled.
-     * A Lut can be sampled in more than one way,
-     * but only one sampling method is used at one time.
+     * A Lut can be sampled in more than one key,
+     * but only one sampling key is used at one time.
      *
      * The implementations should use a sampling strategy
      * at least as good as linear sampling.
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/Luts.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/Luts.aidl
index 5f55f1c..592ac50 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/Luts.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/Luts.aidl
@@ -40,13 +40,15 @@
      * For data precision, 32-bit float is used to specify a Lut by both the HWC and
      * the platform.
      *
-     *
      * For unflattening/flattening 3D Lut(s), the algorithm below should be observed
      * by both the HWC and the platform.
      * Assuming that we have a 3D array `ORIGINAL[WIDTH, HEIGHT, DEPTH]`, we would turn it into
      * `FLAT[WIDTH * HEIGHT * DEPTH]` by
      *
      * `FLAT[z + DEPTH * (y + HEIGHT * x)] = ORIGINAL[x, y, z]`
+     *
+     * Noted that 1D Lut(s) should be gain curve ones
+     * and 3D Lut(s) should be pure color lookup ones.
      */
     @nullable ParcelFileDescriptor pfd;
 
@@ -60,6 +62,8 @@
 
     /**
      * The properties list of the Luts.
+     *
+     * The number of sampling key inside should only be one.
      */
     LutProperties[] lutProperties;
 }
diff --git a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h
index 036460e..71a04f3 100644
--- a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h
+++ b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h
@@ -25,22 +25,20 @@
 #include <string.h>
 
 #include <aidl/android/hardware/graphics/common/BlendMode.h>
+#include <aidl/android/hardware/graphics/common/ColorTransform.h>
+#include <aidl/android/hardware/graphics/common/FRect.h>
+#include <aidl/android/hardware/graphics/common/Rect.h>
+#include <aidl/android/hardware/graphics/common/Transform.h>
 #include <aidl/android/hardware/graphics/composer3/Color.h>
 #include <aidl/android/hardware/graphics/composer3/Composition.h>
 #include <aidl/android/hardware/graphics/composer3/DisplayBrightness.h>
+#include <aidl/android/hardware/graphics/composer3/DisplayCommand.h>
 #include <aidl/android/hardware/graphics/composer3/LayerBrightness.h>
 #include <aidl/android/hardware/graphics/composer3/LayerLifecycleBatchCommandType.h>
 #include <aidl/android/hardware/graphics/composer3/Luts.h>
 #include <aidl/android/hardware/graphics/composer3/PerFrameMetadata.h>
 #include <aidl/android/hardware/graphics/composer3/PerFrameMetadataBlob.h>
 
-#include <aidl/android/hardware/graphics/composer3/DisplayCommand.h>
-
-#include <aidl/android/hardware/graphics/common/ColorTransform.h>
-#include <aidl/android/hardware/graphics/common/FRect.h>
-#include <aidl/android/hardware/graphics/common/Rect.h>
-#include <aidl/android/hardware/graphics/common/Transform.h>
-
 #include <log/log.h>
 #include <sync/sync.h>
 
@@ -59,6 +57,8 @@
 
 namespace aidl::android::hardware::graphics::composer3 {
 
+using PictureProfileId = decltype(LayerCommand().pictureProfileId);
+
 class ComposerClientWriter final {
   public:
     static constexpr std::optional<ClockMonotonicTimestamp> kNoTimestamp = std::nullopt;
@@ -84,6 +84,10 @@
                 DisplayBrightness{.brightness = brightness, .brightnessNits = brightnessNits});
     }
 
+    void setDisplayPictureProfileId(int64_t display, PictureProfileId pictureProfileId) {
+        getDisplayCommand(display).pictureProfileId = pictureProfileId;
+    }
+
     void setClientTarget(int64_t display, uint32_t slot, const native_handle_t* target,
                          int acquireFence, Dataspace dataspace, const std::vector<Rect>& damage,
                          float hdrSdrRatio) {
@@ -250,6 +254,11 @@
         getLayerCommand(display, layer).luts.emplace(std::move(luts));
     }
 
+    void setLayerPictureProfileId(int64_t display, int64_t layer,
+                                  PictureProfileId pictureProfileId) {
+        getLayerCommand(display, layer).pictureProfileId = pictureProfileId;
+    }
+
     std::vector<DisplayCommand> takePendingCommands() {
         flushLayerCommand();
         flushDisplayCommand();
diff --git a/graphics/composer/aidl/vts/VtsComposerClient.cpp b/graphics/composer/aidl/vts/VtsComposerClient.cpp
index 89ba2e6..9b6a005 100644
--- a/graphics/composer/aidl/vts/VtsComposerClient.cpp
+++ b/graphics/composer/aidl/vts/VtsComposerClient.cpp
@@ -690,4 +690,10 @@
     mDisplayResources.clear();
     return true;
 }
+
+std::pair<ScopedAStatus, int32_t> VtsComposerClient::getMaxLayerPictureProfiles(int64_t display) {
+    int32_t outMaxProfiles = 0;
+    return {mComposerClient->getMaxLayerPictureProfiles(display, &outMaxProfiles), outMaxProfiles};
+}
+
 }  // namespace aidl::android::hardware::graphics::composer3::vts
diff --git a/graphics/composer/aidl/vts/VtsComposerClient.h b/graphics/composer/aidl/vts/VtsComposerClient.h
index da6116f..53f5fae 100644
--- a/graphics/composer/aidl/vts/VtsComposerClient.h
+++ b/graphics/composer/aidl/vts/VtsComposerClient.h
@@ -198,6 +198,8 @@
 
     std::vector<RefreshRateChangedDebugData> takeListOfRefreshRateChangedDebugData();
 
+    std::pair<ScopedAStatus, int32_t> getMaxLayerPictureProfiles(int64_t display);
+
     static constexpr int32_t kMaxFrameIntervalNs = 50000000;  // 20fps
     static constexpr int32_t kNoFrameIntervalNs = 0;
 
diff --git a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
index eaf23b5..8006523 100644
--- a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
+++ b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
@@ -28,9 +28,11 @@
 #include <android/hardware/graphics/composer3/ComposerClientReader.h>
 #include <android/hardware/graphics/composer3/ComposerClientWriter.h>
 #include <binder/ProcessState.h>
+#include <cutils/ashmem.h>
 #include <gtest/gtest.h>
 #include <ui/Fence.h>
 #include <ui/GraphicBuffer.h>
+#include <ui/PictureProfileHandle.h>
 #include <ui/PixelFormat.h>
 #include <algorithm>
 #include <iterator>
@@ -118,6 +120,15 @@
                 [&](const Capability& activeCapability) { return activeCapability == capability; });
     }
 
+    bool hasDisplayCapability(int64_t displayId, DisplayCapability capability) {
+        const auto& [status, capabilities] = mComposerClient->getDisplayCapabilities(displayId);
+        EXPECT_TRUE(status.isOk());
+        return std::any_of(capabilities.begin(), capabilities.end(),
+                           [&](const DisplayCapability& activeCapability) {
+                               return activeCapability == capability;
+                           });
+    }
+
     int getInterfaceVersion() {
         const auto& [versionStatus, version] = mComposerClient->getInterfaceVersion();
         EXPECT_TRUE(versionStatus.isOk());
@@ -1388,6 +1399,14 @@
     }
 }
 
+TEST_P(GraphicsComposerAidlV3Test, GetMaxLayerPictureProfiles) {
+    for (const auto& display : mDisplays) {
+        const auto& [status, maxPorfiles] =
+                mComposerClient->getMaxLayerPictureProfiles(display.getDisplayId());
+        EXPECT_TRUE(status.isOk());
+    }
+}
+
 // Tests for Command.
 class GraphicsComposerAidlCommandTest : public GraphicsComposerAidlTest {
   protected:
@@ -2048,6 +2067,7 @@
     EXPECT_TRUE(layerStatus.isOk());
     writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle, /*acquireFence*/ -1);
     execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SetLayerBufferMultipleTimes) {
@@ -3219,6 +3239,140 @@
     });
 }
 
+TEST_P(GraphicsComposerAidlCommandV3Test, getMaxLayerPictureProfiles_success) {
+    for (auto& display : mDisplays) {
+        int64_t displayId = display.getDisplayId();
+        if (!hasDisplayCapability(displayId, DisplayCapability::PICTURE_PROCESSING)) {
+            continue;
+        }
+        const auto& [status, maxProfiles] =
+                mComposerClient->getMaxLayerPictureProfiles(getPrimaryDisplayId());
+        EXPECT_TRUE(status.isOk());
+    }
+}
+
+TEST_P(GraphicsComposerAidlCommandV3Test, setDisplayPictureProfileId_success) {
+    for (auto& display : mDisplays) {
+        int64_t displayId = display.getDisplayId();
+        if (!hasDisplayCapability(displayId, DisplayCapability::PICTURE_PROCESSING)) {
+            continue;
+        }
+
+        auto& writer = getWriter(displayId);
+        const auto layer = createOnScreenLayer(display);
+        const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
+        ASSERT_NE(nullptr, buffer->handle);
+        // TODO(b/337330263): Lookup profile IDs from PictureProfileService
+        writer.setDisplayPictureProfileId(displayId, PictureProfileId(1));
+        writer.setLayerBuffer(displayId, layer, /*slot*/ 0, buffer->handle,
+                              /*acquireFence*/ -1);
+        execute();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+    }
+}
+
+TEST_P(GraphicsComposerAidlCommandV3Test, setLayerPictureProfileId_success) {
+    for (auto& display : mDisplays) {
+        int64_t displayId = display.getDisplayId();
+        if (!hasDisplayCapability(displayId, DisplayCapability::PICTURE_PROCESSING)) {
+            continue;
+        }
+        const auto& [status, maxProfiles] = mComposerClient->getMaxLayerPictureProfiles(displayId);
+        EXPECT_TRUE(status.isOk());
+        if (maxProfiles == 0) {
+            continue;
+        }
+
+        auto& writer = getWriter(displayId);
+        const auto layer = createOnScreenLayer(display);
+        const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
+        ASSERT_NE(nullptr, buffer->handle);
+        writer.setLayerBuffer(displayId, layer, /*slot*/ 0, buffer->handle,
+                              /*acquireFence*/ -1);
+        // TODO(b/337330263): Lookup profile IDs from PictureProfileService
+        writer.setLayerPictureProfileId(displayId, layer, PictureProfileId(1));
+        execute();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+    }
+}
+
+TEST_P(GraphicsComposerAidlCommandV3Test, setLayerPictureProfileId_failsWithTooManyProfiles) {
+    for (auto& display : mDisplays) {
+        int64_t displayId = display.getDisplayId();
+        if (!hasDisplayCapability(displayId, DisplayCapability::PICTURE_PROCESSING)) {
+            continue;
+        }
+        const auto& [status, maxProfiles] = mComposerClient->getMaxLayerPictureProfiles(displayId);
+        EXPECT_TRUE(status.isOk());
+        if (maxProfiles == 0) {
+            continue;
+        }
+
+        auto& writer = getWriter(displayId);
+        for (int profileId = 1; profileId <= maxProfiles + 1; ++profileId) {
+            const auto layer = createOnScreenLayer(display);
+            const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
+            ASSERT_NE(nullptr, buffer->handle);
+            writer.setLayerBuffer(displayId, layer, /*slot*/ 0, buffer->handle,
+                                  /*acquireFence*/ -1);
+            // TODO(b/337330263): Lookup profile IDs from PictureProfileService
+            writer.setLayerPictureProfileId(displayId, layer, PictureProfileId(profileId));
+        }
+        execute();
+        const auto errors = mReader.takeErrors();
+        ASSERT_TRUE(errors.size() == 1 &&
+                    errors[0].errorCode == IComposerClient::EX_PICTURE_PROFILE_MAX_EXCEEDED);
+    }
+}
+
+class GraphicsComposerAidlCommandV4Test : public GraphicsComposerAidlCommandTest {
+  protected:
+    void SetUp() override {
+        GraphicsComposerAidlTest::SetUp();
+        if (getInterfaceVersion() <= 3) {
+            GTEST_SKIP() << "Device interface version is expected to be >= 4";
+        }
+    }
+};
+
+TEST_P(GraphicsComposerAidlCommandV4Test, SetUnsupportedLayerLuts) {
+    auto& writer = getWriter(getPrimaryDisplayId());
+    const auto& [layerStatus, layer] =
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
+    EXPECT_TRUE(layerStatus.isOk());
+    const auto& [status, properties] = mComposerClient->getOverlaySupport();
+    if (!status.isOk() && status.getExceptionCode() == EX_SERVICE_SPECIFIC &&
+        status.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED) {
+        GTEST_SUCCEED() << "getOverlaySupport is not supported";
+        return;
+    }
+    ASSERT_TRUE(status.isOk());
+
+    // TODO (b/362319189): add Lut VTS enforcement
+    if (!properties.lutProperties) {
+        int32_t size = 7;
+        size_t bufferSize = static_cast<size_t>(size) * sizeof(float);
+        int32_t fd = ashmem_create_region("lut_shared_mem", bufferSize);
+        void* ptr = mmap(nullptr, bufferSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+        std::vector<float> buffers = {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f};
+        memcpy(ptr, buffers.data(), bufferSize);
+        munmap(ptr, bufferSize);
+        Luts luts;
+        luts.offsets = {0};
+        luts.lutProperties = {
+                {LutProperties::Dimension::ONE_D, size, {LutProperties::SamplingKey::RGB}}};
+        luts.pfd = ndk::ScopedFileDescriptor(fd);
+
+        writer.setLayerLuts(getPrimaryDisplayId(), layer, luts);
+        writer.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
+                               VtsComposerClient::kNoFrameIntervalNs);
+        execute();
+        // change to client composition
+        ASSERT_FALSE(mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty());
+        ASSERT_TRUE(mReader.takeErrors().empty());
+    }
+}
+
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerAidlCommandTest);
 INSTANTIATE_TEST_SUITE_P(
         PerInstance, GraphicsComposerAidlCommandTest,
@@ -3249,6 +3403,11 @@
         PerInstance, GraphicsComposerAidlCommandV3Test,
         testing::ValuesIn(::android::getAidlHalInstanceNames(IComposer::descriptor)),
         ::android::PrintInstanceNameToString);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerAidlCommandV4Test);
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, GraphicsComposerAidlCommandV4Test,
+        testing::ValuesIn(::android::getAidlHalInstanceNames(IComposer::descriptor)),
+        ::android::PrintInstanceNameToString);
 }  // namespace aidl::android::hardware::graphics::composer3::vts
 
 int main(int argc, char** argv) {
diff --git a/health/storage/1.0/vts/functional/Android.bp b/health/storage/1.0/vts/functional/Android.bp
index ccf22ce..e78e044 100644
--- a/health/storage/1.0/vts/functional/Android.bp
+++ b/health/storage/1.0/vts/functional/Android.bp
@@ -15,6 +15,7 @@
 //
 
 package {
+    default_team: "trendy_team_android_kernel",
     // See: http://go/android-license-faq
     // A large-scale-change added 'default_applicable_licenses' to import
     // all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/health/storage/aidl/vts/functional/Android.bp b/health/storage/aidl/vts/functional/Android.bp
index fe15170..083ec37 100644
--- a/health/storage/aidl/vts/functional/Android.bp
+++ b/health/storage/aidl/vts/functional/Android.bp
@@ -13,6 +13,7 @@
 // limitations under the License.
 
 package {
+    default_team: "trendy_team_android_kernel",
     // See: http://go/android-license-faq
     // A large-scale-change added 'default_applicable_licenses' to import
     // all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/power/OWNERS b/power/OWNERS
index 7229b22..95778a4 100644
--- a/power/OWNERS
+++ b/power/OWNERS
@@ -3,3 +3,4 @@
 # ADPF virtual team
 lpy@google.com
 wvw@google.com
+file:platform/frameworks/base:/ADPF_OWNERS
diff --git a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/CpuHeadroomParams.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/CpuHeadroomParams.aidl
new file mode 100644
index 0000000..09a2ace
--- /dev/null
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/CpuHeadroomParams.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2024 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.power;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable CpuHeadroomParams {
+  android.hardware.power.CpuHeadroomParams.CalculationType calculationType;
+  android.hardware.power.CpuHeadroomParams.SelectionType selectionType;
+  int pid;
+  enum CalculationType {
+    MIN,
+    AVERAGE,
+  }
+  enum SelectionType {
+    ALL,
+    PER_CORE,
+  }
+}
diff --git a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/GpuHeadroomParams.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/GpuHeadroomParams.aidl
new file mode 100644
index 0000000..64bb4a4
--- /dev/null
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/GpuHeadroomParams.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2024 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.power;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable GpuHeadroomParams {
+  android.hardware.power.GpuHeadroomParams.CalculationType calculationType;
+  enum CalculationType {
+    MIN,
+    AVERAGE,
+  }
+}
diff --git a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPower.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPower.aidl
index 8d8fb88..10456cb 100644
--- a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPower.aidl
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPower.aidl
@@ -44,4 +44,8 @@
   android.hardware.power.ChannelConfig getSessionChannel(in int tgid, in int uid);
   oneway void closeSessionChannel(in int tgid, in int uid);
   android.hardware.power.SupportInfo getSupportInfo();
+  float[] getCpuHeadroom(in android.hardware.power.CpuHeadroomParams params);
+  float getGpuHeadroom(in android.hardware.power.GpuHeadroomParams params);
+  long getCpuHeadroomMinIntervalMillis();
+  long getGpuHeadroomMinIntervalMillis();
 }
diff --git a/power/aidl/android/hardware/power/CpuHeadroomParams.aidl b/power/aidl/android/hardware/power/CpuHeadroomParams.aidl
new file mode 100644
index 0000000..cf71b67
--- /dev/null
+++ b/power/aidl/android/hardware/power/CpuHeadroomParams.aidl
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2024 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.
+ */
+
+package android.hardware.power;
+
+@VintfStability
+@JavaDerive(equals=true, toString=true)
+parcelable CpuHeadroomParams {
+    /**
+     * Defines how to calculate the headroom.
+     */
+    enum CalculationType {
+        // Default to return the minimum headroom in a window.
+        MIN,
+        // Returns the average headroom in a window.
+        AVERAGE,
+    }
+
+    /**
+     * The calculation type.
+     */
+    CalculationType calculationType;
+
+    /**
+     * Defines how to select the CPU.
+     */
+    enum SelectionType {
+        // Default to return a single value for all cores.
+        ALL,
+        // Returns per-core headroom in a list.
+        PER_CORE,
+    }
+
+    /**
+     * The CPU selection type.
+     */
+    SelectionType selectionType;
+
+    /**
+     * The caller thread's PID.
+     *
+     * If pid is positive, return the headroom only for cores that are available
+     * to the given pid, otherwise return the headroom(s) for all cores.
+     *
+     * This should handle all the cases including but not limited to thread core
+     * affinity and app cpuset that change the available CPU cores for the caller.
+     */
+    int pid;
+}
diff --git a/power/aidl/android/hardware/power/GpuHeadroomParams.aidl b/power/aidl/android/hardware/power/GpuHeadroomParams.aidl
new file mode 100644
index 0000000..972adbc
--- /dev/null
+++ b/power/aidl/android/hardware/power/GpuHeadroomParams.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2024 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.
+ */
+
+package android.hardware.power;
+
+@VintfStability
+@JavaDerive(equals=true, toString=true)
+parcelable GpuHeadroomParams {
+    /**
+     * Defines how to calculate the headroom.
+     */
+    enum CalculationType {
+        // Default to return the minimum headroom in a window.
+        MIN,
+        // Returns the average headroom in a window.
+        AVERAGE,
+    }
+
+    /**
+     * The calculation type.
+     */
+    CalculationType calculationType;
+}
diff --git a/power/aidl/android/hardware/power/IPower.aidl b/power/aidl/android/hardware/power/IPower.aidl
index 2f15648..e2f121c 100644
--- a/power/aidl/android/hardware/power/IPower.aidl
+++ b/power/aidl/android/hardware/power/IPower.aidl
@@ -18,6 +18,8 @@
 
 import android.hardware.power.Boost;
 import android.hardware.power.ChannelConfig;
+import android.hardware.power.CpuHeadroomParams;
+import android.hardware.power.GpuHeadroomParams;
 import android.hardware.power.IPowerHintSession;
 import android.hardware.power.Mode;
 import android.hardware.power.SessionConfig;
@@ -155,4 +157,47 @@
      *          not supported.
      */
     SupportInfo getSupportInfo();
+
+    /**
+     * Provides an estimate of available CPU headroom the device based on past history.
+     * <p>
+     * @param params params to customize the CPU headroom calculation
+     * @return a single value or an array of values depending on selection type of params.
+     *         Each value is ranged from [0, 100], and 0 indicates no CPU resources were left
+     *         during the calculation interval and the app may expect low resources to be granted.
+     * @throws EX_UNSUPPORTED_OPERATION if the API is unsupported or the request params can't be
+     *         served.
+     */
+    float[] getCpuHeadroom(in CpuHeadroomParams params);
+
+    /**
+     * Provides an estimate of available GPU headroom the device based on past history.
+     * <p>
+     * @param params params to customize the GPU headroom calculation
+     * @return Value is ranged from [0, 100], and 0 indicates no GPU resources were left
+     *         during the calculation interval and the app may expect low resources to be granted.
+     * @throws EX_UNSUPPORTED_OPERATION if the API is unsupported or the request params can't be
+     *         served.
+     */
+    float getGpuHeadroom(in GpuHeadroomParams params);
+
+    /**
+     * Minimum polling interval for calling getCpuHeadroom in milliseconds.
+     *
+     * The getCpuHeadroom API may return cached result if called more frequent
+     * than the interval.
+     *
+     * @throws EX_UNSUPPORTED_OPERATION if the API is unsupported.
+     */
+    long getCpuHeadroomMinIntervalMillis();
+
+    /**
+     * Minimum polling interval for calling getGpuHeadroom in milliseconds.
+     *
+     * The getGpuHeadroom API may return cached result if called more frequent
+     * than the interval.
+     *
+     * @throws EX_UNSUPPORTED_OPERATION if the API is unsupported.
+     */
+    long getGpuHeadroomMinIntervalMillis();
 }
diff --git a/power/aidl/default/Power.cpp b/power/aidl/default/Power.cpp
index 36d0055..1fc0a0a 100644
--- a/power/aidl/default/Power.cpp
+++ b/power/aidl/default/Power.cpp
@@ -69,6 +69,27 @@
     return ScopedAStatus::ok();
 }
 
+ndk::ScopedAStatus Power::getCpuHeadroom(const CpuHeadroomParams& _,
+                                         std::vector<float>* _aidl_return) {
+    *_aidl_return = {0.5f};
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Power::getGpuHeadroom(const GpuHeadroomParams& _, float* _aidl_return) {
+    *_aidl_return = 0.5f;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Power::getCpuHeadroomMinIntervalMillis(int64_t* _aidl_return) {
+    *_aidl_return = 1000;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Power::getGpuHeadroomMinIntervalMillis(int64_t* _aidl_return) {
+    *_aidl_return = 1000;
+    return ndk::ScopedAStatus::ok();
+}
+
 ScopedAStatus Power::createHintSession(int32_t, int32_t, const std::vector<int32_t>& tids, int64_t,
                                        std::shared_ptr<IPowerHintSession>* _aidl_return) {
     if (tids.size() == 0) {
diff --git a/power/aidl/default/Power.h b/power/aidl/default/Power.h
index ef524e1..a77a514 100644
--- a/power/aidl/default/Power.h
+++ b/power/aidl/default/Power.h
@@ -45,6 +45,12 @@
                                          ChannelConfig* _aidl_return) override;
     ndk::ScopedAStatus closeSessionChannel(int32_t tgid, int32_t uid) override;
     ndk::ScopedAStatus getSupportInfo(SupportInfo* _aidl_return) override;
+    ndk::ScopedAStatus getCpuHeadroom(const CpuHeadroomParams& params,
+                                      std::vector<float>* _aidl_return) override;
+    ndk::ScopedAStatus getGpuHeadroom(const GpuHeadroomParams& params,
+                                      float* _aidl_return) override;
+    ndk::ScopedAStatus getCpuHeadroomMinIntervalMillis(int64_t* _aidl_return) override;
+    ndk::ScopedAStatus getGpuHeadroomMinIntervalMillis(int64_t* _aidl_return) override;
 
   private:
     std::vector<std::shared_ptr<IPowerHintSession>> mPowerHintSessions;
diff --git a/power/aidl/vts/VtsHalPowerTargetTest.cpp b/power/aidl/vts/VtsHalPowerTargetTest.cpp
index 9684c38..5e3ddd5 100644
--- a/power/aidl/vts/VtsHalPowerTargetTest.cpp
+++ b/power/aidl/vts/VtsHalPowerTargetTest.cpp
@@ -30,6 +30,8 @@
 #include <unistd.h>
 #include <cstdint>
 #include "aidl/android/hardware/common/fmq/SynchronizedReadWrite.h"
+#include "aidl/android/hardware/power/CpuHeadroomParams.h"
+#include "aidl/android/hardware/power/GpuHeadroomParams.h"
 
 namespace aidl::android::hardware::power {
 namespace {
@@ -40,6 +42,8 @@
 using android::hardware::power::Boost;
 using android::hardware::power::ChannelConfig;
 using android::hardware::power::ChannelMessage;
+using android::hardware::power::CpuHeadroomParams;
+using android::hardware::power::GpuHeadroomParams;
 using android::hardware::power::IPower;
 using android::hardware::power::IPowerHintSession;
 using android::hardware::power::Mode;
@@ -291,6 +295,43 @@
     ASSERT_NE(nullptr, session);
 }
 
+TEST_P(PowerAidl, getCpuHeadroom) {
+    if (mServiceVersion < 6) {
+        GTEST_SKIP() << "DEVICE not launching with Power V6 and beyond.";
+    }
+    CpuHeadroomParams params;
+    std::vector<float> headroom;
+    auto ret = power->getCpuHeadroom(params, &headroom);
+    if (ret.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
+        GTEST_SKIP() << "power->getCpuHeadroom is not supported";
+    }
+    ASSERT_TRUE(ret.isOk());
+    int64_t minIntervalMillis;
+    ASSERT_TRUE(power->getCpuHeadroomMinIntervalMillis(&minIntervalMillis).isOk());
+    ASSERT_GE(minIntervalMillis, 0);
+    ASSERT_GE(headroom.size(), 1);
+    ASSERT_GE(headroom[0], 0.0f);
+    ASSERT_LE(headroom[0], 100.00f);
+}
+
+TEST_P(PowerAidl, getGpuHeadroom) {
+    if (mServiceVersion < 6) {
+        GTEST_SKIP() << "DEVICE not launching with Power V6 and beyond.";
+    }
+    GpuHeadroomParams params;
+    float headroom;
+    auto ret = power->getGpuHeadroom(params, &headroom);
+    if (ret.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
+        GTEST_SKIP() << "power->getGpuHeadroom is not supported";
+    }
+    ASSERT_TRUE(ret.isOk());
+    int64_t minIntervalMillis;
+    ASSERT_TRUE(power->getGpuHeadroomMinIntervalMillis(&minIntervalMillis).isOk());
+    ASSERT_GE(minIntervalMillis, 0);
+    ASSERT_GE(headroom, 0.0f);
+    ASSERT_LE(headroom, 100.00f);
+}
+
 // FIXED_PERFORMANCE mode is required for all devices which ship on Android 11
 // or later
 TEST_P(PowerAidl, hasFixedPerformance) {
diff --git a/radio/aidl/Android.bp b/radio/aidl/Android.bp
index 517ad86..eca9a27 100644
--- a/radio/aidl/Android.bp
+++ b/radio/aidl/Android.bp
@@ -37,7 +37,7 @@
         },
 
     ],
-    frozen: true,
+    frozen: false,
 
 }
 
@@ -47,7 +47,7 @@
     host_supported: true,
     srcs: ["android/hardware/radio/config/*.aidl"],
     stability: "vintf",
-    imports: ["android.hardware.radio-V3"],
+    imports: ["android.hardware.radio-V4"],
     backend: {
         cpp: {
             enabled: true,
@@ -71,7 +71,7 @@
         },
 
     ],
-    frozen: true,
+    frozen: false,
 
 }
 
@@ -81,7 +81,7 @@
     host_supported: true,
     srcs: ["android/hardware/radio/data/*.aidl"],
     stability: "vintf",
-    imports: ["android.hardware.radio-V3"],
+    imports: ["android.hardware.radio-V4"],
     backend: {
         cpp: {
             enabled: true,
@@ -114,7 +114,7 @@
     host_supported: true,
     srcs: ["android/hardware/radio/messaging/*.aidl"],
     stability: "vintf",
-    imports: ["android.hardware.radio-V3"],
+    imports: ["android.hardware.radio-V4"],
     backend: {
         cpp: {
             enabled: true,
@@ -138,7 +138,7 @@
         },
 
     ],
-    frozen: true,
+    frozen: false,
 }
 
 aidl_interface {
@@ -147,7 +147,7 @@
     host_supported: true,
     srcs: ["android/hardware/radio/modem/*.aidl"],
     stability: "vintf",
-    imports: ["android.hardware.radio-V3"],
+    imports: ["android.hardware.radio-V4"],
     backend: {
         cpp: {
             enabled: true,
@@ -171,7 +171,7 @@
         },
 
     ],
-    frozen: true,
+    frozen: false,
 }
 
 aidl_interface {
@@ -180,7 +180,7 @@
     host_supported: true,
     srcs: ["android/hardware/radio/network/*.aidl"],
     stability: "vintf",
-    imports: ["android.hardware.radio-V3"],
+    imports: ["android.hardware.radio-V4"],
     backend: {
         cpp: {
             enabled: true,
@@ -204,7 +204,7 @@
         },
 
     ],
-    frozen: true,
+    frozen: false,
 }
 
 aidl_interface {
@@ -242,8 +242,8 @@
     srcs: ["android/hardware/radio/sim/*.aidl"],
     stability: "vintf",
     imports: [
-        "android.hardware.radio-V3",
-        "android.hardware.radio.config-V3",
+        "android.hardware.radio-V4",
+        "android.hardware.radio.config-V4",
     ],
     backend: {
         cpp: {
@@ -277,7 +277,7 @@
         },
 
     ],
-    frozen: true,
+    frozen: false,
 }
 
 aidl_interface {
@@ -286,7 +286,7 @@
     host_supported: true,
     srcs: ["android/hardware/radio/voice/*.aidl"],
     stability: "vintf",
-    imports: ["android.hardware.radio-V3"],
+    imports: ["android.hardware.radio-V4"],
     backend: {
         cpp: {
             enabled: true,
@@ -310,7 +310,7 @@
         },
 
     ],
-    frozen: true,
+    frozen: false,
 }
 
 aidl_interface {
@@ -319,7 +319,7 @@
     srcs: ["android/hardware/radio/ims/media/*.aidl"],
     stability: "vintf",
     imports: [
-        "android.hardware.radio-V3",
+        "android.hardware.radio-V4",
         "android.hardware.radio.data-V4",
     ],
     backend: {
@@ -355,7 +355,7 @@
     vendor_available: true,
     srcs: ["android/hardware/radio/ims/*.aidl"],
     stability: "vintf",
-    imports: ["android.hardware.radio-V3"],
+    imports: ["android.hardware.radio-V4"],
     backend: {
         cpp: {
             enabled: false,
@@ -375,5 +375,5 @@
         },
 
     ],
-    frozen: true,
+    frozen: false,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrSignalStrength.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrSignalStrength.aidl
index 11e7356..45e6ccf 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrSignalStrength.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrSignalStrength.aidl
@@ -43,5 +43,5 @@
   int csiSinr;
   int csiCqiTableIndex;
   byte[] csiCqiReport;
-  int timingAdvance = 0x7FFFFFFF;
+  int timingAdvance = android.hardware.radio.RadioConst.VALUE_UNAVAILABLE /* 2147483647 */;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioConst.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioConst.aidl
index 970cd1e..e24a35d 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioConst.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioConst.aidl
@@ -35,6 +35,9 @@
 /* @hide */
 @JavaDerive(toString=true) @VintfStability
 parcelable RadioConst {
+  const int VALUE_UNAVAILABLE = 0x7FFFFFFF;
+  const long VALUE_UNAVAILABLE_LONG = 0x7FFFFFFFFFFFFFFF;
+  const byte VALUE_UNAVAILABLE_BYTE = 0xFFu8;
   const int MAX_RILDS = 3;
   const int MAX_UUID_LENGTH = 64;
   const int CARD_MAX_APPS = 8;
diff --git a/radio/aidl/android/hardware/radio/RadioConst.aidl b/radio/aidl/android/hardware/radio/RadioConst.aidl
index 7b923b9..df27526 100644
--- a/radio/aidl/android/hardware/radio/RadioConst.aidl
+++ b/radio/aidl/android/hardware/radio/RadioConst.aidl
@@ -20,6 +20,9 @@
 @VintfStability
 @JavaDerive(toString=true)
 parcelable RadioConst {
+    const int VALUE_UNAVAILABLE = 0x7FFFFFFF;
+    const long VALUE_UNAVAILABLE_LONG = 0x7FFFFFFFFFFFFFFF;
+    const byte VALUE_UNAVAILABLE_BYTE = 0xFFu8;
     const int MAX_RILDS = 3;
     const int MAX_UUID_LENGTH = 64;
     const int CARD_MAX_APPS = 8;
diff --git a/radio/aidl/android/hardware/radio/data/KeepaliveRequest.aidl b/radio/aidl/android/hardware/radio/data/KeepaliveRequest.aidl
index 1838f2e..90c4454 100644
--- a/radio/aidl/android/hardware/radio/data/KeepaliveRequest.aidl
+++ b/radio/aidl/android/hardware/radio/data/KeepaliveRequest.aidl
@@ -40,7 +40,7 @@
     byte[] sourceAddress;
     /**
      * Source port if relevant for the given type
-     * INT_MAX: 0x7FFFFFFF denotes that the field is unused
+     * RadioConst:VALUE_UNAVAILABLE denotes that the field is unused
      */
     int sourcePort;
     /**
@@ -49,7 +49,7 @@
     byte[] destinationAddress;
     /**
      * Destination if relevant for the given type
-     * INT_MAX: 0x7FFFFFFF denotes that the field is unused
+     * RadioConst:VALUE_UNAVAILABLE denotes that the field is unused
      */
     int destinationPort;
     /**
diff --git a/radio/aidl/android/hardware/radio/data/LinkAddress.aidl b/radio/aidl/android/hardware/radio/data/LinkAddress.aidl
index 957973d..7ac560f 100644
--- a/radio/aidl/android/hardware/radio/data/LinkAddress.aidl
+++ b/radio/aidl/android/hardware/radio/data/LinkAddress.aidl
@@ -44,14 +44,14 @@
      * The time, as reported by SystemClock.elapsedRealtime(), when this link address will be or
      * was deprecated. -1 indicates this information is not available. At the time existing
      * connections can still use this address until it expires, but new connections should use the
-     * new address. LONG_MAX(0x7FFFFFFFFFFFFFFF) indicates this link address will never be
+     * new address. RadioConst:VALUE_UNAVAILABLE_LONG indicates this link address will never be
      * deprecated.
      */
     long deprecationTime;
     /**
      * The time, as reported by SystemClock.elapsedRealtime(), when this link address will expire
      * and be removed from the interface. -1 indicates this information is not available.
-     * LONG_MAX(0x7FFFFFFFFFFFFFFF) indicates this link address will never expire.
+     * RadioConst:VALUE_UNAVAILABLE_LONG indicates this link address will never expire.
      */
     long expirationTime;
 }
diff --git a/radio/aidl/android/hardware/radio/data/SetupDataCallResult.aidl b/radio/aidl/android/hardware/radio/data/SetupDataCallResult.aidl
index b8f01c0..31fb14c 100644
--- a/radio/aidl/android/hardware/radio/data/SetupDataCallResult.aidl
+++ b/radio/aidl/android/hardware/radio/data/SetupDataCallResult.aidl
@@ -68,10 +68,10 @@
     /**
      * If cause is not DataCallFailCause.NONE, this field indicates the network suggested data
      * retry back-off time in milliseconds. Negative value indicates network does not give any
-     * suggestion. 0 indicates retry should be performed immediately. 0x7fffffffffffffff indicates
-     * the device should not retry data setup anymore. During this time, no calls to
-     * IRadioData.setupDataCall for this APN will be made unless IRadioDataIndication.unthrottleApn
-     * is sent with the same APN.
+     * suggestion. 0 indicates retry should be performed immediately.
+     * RadioConst:VALUE_UNAVAILABLE_LONG indicates the device should not retry data setup anymore.
+     * During this time, no calls to IRadioData.setupDataCall for this APN will be made unless
+     * IRadioDataIndication.unthrottleApn is sent with the same APN.
      */
     long suggestedRetryTime;
     /**
diff --git a/radio/aidl/android/hardware/radio/network/CdmaSignalStrength.aidl b/radio/aidl/android/hardware/radio/network/CdmaSignalStrength.aidl
index ae7aa93..0e241d3 100644
--- a/radio/aidl/android/hardware/radio/network/CdmaSignalStrength.aidl
+++ b/radio/aidl/android/hardware/radio/network/CdmaSignalStrength.aidl
@@ -22,12 +22,12 @@
 parcelable CdmaSignalStrength {
     /**
      * This value is the actual RSSI value multiplied by -1. Example: If the actual RSSI is -75,
-     * then this response value will be 75. INT_MAX means invalid/unreported.
+     * then this response value will be 75. RadioConst:VALUE_UNAVAILABLE means invalid/unreported.
      */
     int dbm;
     /**
      * This value is the actual Ec/Io multiplied by -10. Example: If the actual Ec/Io is -12.5 dB,
-     * then this response value will be 125. INT_MAX means invalid/unreported.
+     * then this response value will be 125. RadioConst:VALUE_UNAVAILABLE means invalid/unreported.
      */
     int ecio;
 }
diff --git a/radio/aidl/android/hardware/radio/network/CellIdentityCdma.aidl b/radio/aidl/android/hardware/radio/network/CellIdentityCdma.aidl
index b93988f..acf3db1 100644
--- a/radio/aidl/android/hardware/radio/network/CellIdentityCdma.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellIdentityCdma.aidl
@@ -23,27 +23,27 @@
 @JavaDerive(toString=true)
 parcelable CellIdentityCdma {
     /**
-     * Network Id 0..65535, INT_MAX if unknown
+     * Network Id 0..65535, RadioConst:VALUE_UNAVAILABLE if unknown
      */
     int networkId;
     /**
-     * CDMA System Id 0..32767, INT_MAX if unknown
+     * CDMA System Id 0..32767, RadioConst:VALUE_UNAVAILABLE if unknown
      */
     int systemId;
     /**
-     * Base Station Id 0..65535, INT_MAX if unknown
+     * Base Station Id 0..65535, RadioConst:VALUE_UNAVAILABLE if unknown
      */
     int baseStationId;
     /**
      * Longitude is a decimal number as specified in 3GPP2 C.S0005-A v6.0. It is represented in
      * units of 0.25 seconds and ranges from -2592000 to 2592000, both values inclusive
-     * (corresponding to a range of -180 to +180 degrees). INT_MAX if unknown
+     * (corresponding to a range of -180 to +180 degrees). RadioConst:VALUE_UNAVAILABLE if unknown
      */
     int longitude;
     /**
      * Latitude is a decimal number as specified in 3GPP2 C.S0005-A v6.0. It is represented in
      * units of 0.25 seconds and ranges from -1296000 to 1296000, both values inclusive
-     * (corresponding to a range of -90 to +90 degrees). INT_MAX if unknown
+     * (corresponding to a range of -90 to +90 degrees). RadioConst:VALUE_UNAVAILABLE if unknown
      */
     int latitude;
     /**
diff --git a/radio/aidl/android/hardware/radio/network/CellIdentityGsm.aidl b/radio/aidl/android/hardware/radio/network/CellIdentityGsm.aidl
index bc02adc..fe39a0e 100644
--- a/radio/aidl/android/hardware/radio/network/CellIdentityGsm.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellIdentityGsm.aidl
@@ -31,11 +31,12 @@
      */
     String mnc;
     /**
-     * 16-bit Location Area Code, 0..65535, INT_MAX if unknown
+     * 16-bit Location Area Code, 0..65535, RadioConst:VALUE_UNAVAILABLE if unknown
      */
     int lac;
     /**
-     * 16-bit GSM Cell Identity described in TS 27.007, 0..65535, INT_MAX if unknown
+     * 16-bit GSM Cell Identity described in TS 27.007, 0..65535,
+     * RadioConst:VALUE_UNAVAILABLE if unknown
      */
     int cid;
     /**
@@ -43,7 +44,7 @@
      */
     int arfcn;
     /**
-     * 6-bit Base Station Identity Code, 0xFF if unknown
+     * 6-bit Base Station Identity Code, RadioConst:VALUE_UNAVAILABLE_BYTE if unknown
      */
     byte bsic;
     /**
diff --git a/radio/aidl/android/hardware/radio/network/CellIdentityLte.aidl b/radio/aidl/android/hardware/radio/network/CellIdentityLte.aidl
index 6912e02..9c4fc3c 100644
--- a/radio/aidl/android/hardware/radio/network/CellIdentityLte.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellIdentityLte.aidl
@@ -33,7 +33,7 @@
      */
     String mnc;
     /**
-     * 28-bit Cell Identity described in TS 27.007, INT_MAX if unknown
+     * 28-bit Cell Identity described in TS 27.007, RadioConst:VALUE_UNAVAILABLE if unknown
      */
     int ci;
     /**
@@ -41,7 +41,7 @@
      */
     int pci;
     /**
-     * 16-bit tracking area code, INT_MAX if unknown
+     * 16-bit tracking area code, RadioConst:VALUE_UNAVAILABLE if unknown
      */
     int tac;
     /**
diff --git a/radio/aidl/android/hardware/radio/network/CellIdentityNr.aidl b/radio/aidl/android/hardware/radio/network/CellIdentityNr.aidl
index 4192845..7ebc0cd 100644
--- a/radio/aidl/android/hardware/radio/network/CellIdentityNr.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellIdentityNr.aidl
@@ -29,12 +29,12 @@
 parcelable CellIdentityNr {
     /**
      * 3-digit Mobile Country Code, in range[0, 999]; This value must be valid for registered or
-     *  camped cells; INT_MAX means invalid/unreported.
+     *  camped cells; Empty string means invalid/unreported.
      */
     String mcc;
     /**
      * 2 or 3-digit Mobile Network Code, in range [0, 999], This value must be valid for
-     * registered or camped cells; INT_MAX means invalid/unreported.
+     * registered or camped cells; Empty string means invalid/unreported.
      */
     String mnc;
     /**
@@ -48,7 +48,7 @@
      */
     int pci;
     /**
-     * 16-bit tracking area code, INT_MAX means invalid/unreported.
+     * 16-bit tracking area code, RadioConst:VALUE_UNAVAILABLE means invalid/unreported.
      */
     int tac;
     /**
diff --git a/radio/aidl/android/hardware/radio/network/CellIdentityTdscdma.aidl b/radio/aidl/android/hardware/radio/network/CellIdentityTdscdma.aidl
index 33ffc6f..8373493 100644
--- a/radio/aidl/android/hardware/radio/network/CellIdentityTdscdma.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellIdentityTdscdma.aidl
@@ -32,15 +32,17 @@
      */
     String mnc;
     /**
-     * 16-bit Location Area Code, 0..65535, INT_MAX if unknown.
+     * 16-bit Location Area Code, 0..65535, RadioConst:VALUE_UNAVAILABLE if unknown.
      */
     int lac;
     /**
-     * 28-bit UMTS Cell Identity described in TS 25.331, 0..268435455, INT_MAX if unknown.
+     * 28-bit UMTS Cell Identity described in TS 25.331, 0..268435455, RadioConst:VALUE_UNAVAILABLE
+     * if unknown.
      */
     int cid;
     /**
-     * 8-bit Cell Parameters ID described in TS 25.331, 0..127, INT_MAX if unknown.
+     * 8-bit Cell Parameters ID described in TS 25.331, 0..127, RadioConst:VALUE_UNAVAILABLE if
+     * unknown.
      */
     int cpid;
     /**
diff --git a/radio/aidl/android/hardware/radio/network/CellIdentityWcdma.aidl b/radio/aidl/android/hardware/radio/network/CellIdentityWcdma.aidl
index b6e328a..ab703f1 100644
--- a/radio/aidl/android/hardware/radio/network/CellIdentityWcdma.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellIdentityWcdma.aidl
@@ -32,11 +32,12 @@
      */
     String mnc;
     /**
-     * 16-bit Location Area Code, 0..65535, INT_MAX if unknown.
+     * 16-bit Location Area Code, 0..65535, RadioConst:VALUE_UNAVAILABLE if unknown.
      */
     int lac;
     /**
-     * 28-bit UMTS Cell Identity described in TS 25.331, 0..268435455, INT_MAX if unknown.
+     * 28-bit UMTS Cell Identity described in TS 25.331, 0..268435455, RadioConst:VALUE_UNAVAILABLE
+     * if unknown.
      */
     int cid;
     /**
diff --git a/radio/aidl/android/hardware/radio/network/EvdoSignalStrength.aidl b/radio/aidl/android/hardware/radio/network/EvdoSignalStrength.aidl
index fc7cc1b..ac6928e 100644
--- a/radio/aidl/android/hardware/radio/network/EvdoSignalStrength.aidl
+++ b/radio/aidl/android/hardware/radio/network/EvdoSignalStrength.aidl
@@ -22,17 +22,17 @@
 parcelable EvdoSignalStrength {
     /**
      * This value is the actual RSSI value multiplied by -1. Example: If the actual RSSI is -75,
-     * then this response value will be 75; INT_MAX means invalid/unreported.
+     * then this response value will be 75; RadioConst:VALUE_UNAVAILABLE means invalid/unreported.
      */
     int dbm;
     /**
      * This value is the actual Ec/Io multiplied by -10. Example: If the actual Ec/Io is -12.5 dB,
-     * then this response value will be 125; INT_MAX means invalid/unreported.
+     * then this response value will be 125; RadioConst:VALUE_UNAVAILABLE means invalid/unreported.
      */
     int ecio;
     /**
-     * Valid values are 0-8. 8 is the highest signal to noise ratio; INT_MAX means
-     * invalid/unreported.
+     * Valid values are 0-8. 8 is the highest signal to noise ratio; RadioConst:VALUE_UNAVAILABLE
+     * means invalid/unreported.
      */
     int signalNoiseRatio;
 }
diff --git a/radio/aidl/android/hardware/radio/network/GsmSignalStrength.aidl b/radio/aidl/android/hardware/radio/network/GsmSignalStrength.aidl
index d569cf7..4a99646 100644
--- a/radio/aidl/android/hardware/radio/network/GsmSignalStrength.aidl
+++ b/radio/aidl/android/hardware/radio/network/GsmSignalStrength.aidl
@@ -21,15 +21,18 @@
 @JavaDerive(toString=true)
 parcelable GsmSignalStrength {
     /**
-     * Valid values are (0-61, 99) as defined in TS 27.007 8.69; INT_MAX means invalid/unreported.
+     * Valid values are (0-61, 99) as defined in TS 27.007 8.69; RadioConst:VALUE_UNAVAILABLE means
+     * invalid/unreported.
      */
     int signalStrength;
     /**
-     * Bit error rate (0-7, 99) as defined in TS 27.007 8.5; INT_MAX means invalid/unreported.
+     * Bit error rate (0-7, 99) as defined in TS 27.007 8.5; RadioConst:VALUE_UNAVAILABLE means
+     * invalid/unreported.
      */
     int bitErrorRate;
     /**
-     * Timing advance in bit periods. 1 bit period = 48/13 us. INT_MAX means invalid/unreported.
+     * Timing advance in bit periods. 1 bit period = 48/13 us. RadioConst:VALUE_UNAVAILABLE means
+     * invalid/unreported.
      */
     int timingAdvance;
 }
diff --git a/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl b/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl
index 5f26195..a4f97e3 100644
--- a/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl
+++ b/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl
@@ -278,7 +278,7 @@
     /**
      * Sets the minimum time between when unsolicited cellInfoList() must be invoked.
      * A value of 0, means invoke cellInfoList() when any of the reported information changes.
-     * Setting the value to INT_MAX(0x7fffffff) means never issue a unsolicited cellInfoList().
+     * Value of RadioConst:VALUE_UNAVAILABLE means never issue a unsolicited cellInfoList().
      *
      * @param serial Serial number of request.
      * @param rate minimum time in milliseconds to indicate time between unsolicited cellInfoList()
diff --git a/radio/aidl/android/hardware/radio/network/IRadioNetworkIndication.aidl b/radio/aidl/android/hardware/radio/network/IRadioNetworkIndication.aidl
index da82b78..34948fb 100644
--- a/radio/aidl/android/hardware/radio/network/IRadioNetworkIndication.aidl
+++ b/radio/aidl/android/hardware/radio/network/IRadioNetworkIndication.aidl
@@ -221,6 +221,12 @@
      * - If a device uses a 2G network to send a AUTHENTICATION_AND_CIPHERING_RESPONSE message on
      * the NAS and the message includes an IMEISV.
      *
+     * cellularIdentifierDisclosure indications must be sent to Android regardless of the screen
+     * state. If the screen is off, the indications must still be sent to Android.
+     *
+     * Note: in the NRSA scenario, only a SUCI generated by a null scheme should be considered as a
+     * plain-text identifier.
+     *
      * @param type Type of radio indication
      * @param disclosure A CellularIdentifierDisclosure as specified by
      *         IRadioNetwork.setCellularIdentifierTransparencyEnabled.
@@ -232,23 +238,78 @@
     /*
      * Indicates that a new ciphering or integrity algorithm was used for a particular voice,
      * signaling, or data connection for a given PLMN and/or access network. Due to power
-     * concerns, once a connection type has been reported on, follow-up reports about that
-     * connection type are only generated if there is any change to the most-recently reported
-     * encryption or integrity, or if the value of SecurityAlgorithmUpdate#isUnprotectedEmergency
-     * changes. A change only in cell ID should not trigger an update, as the design is intended
-     * to be agnostic to dual connectivity ("secondary serving cells").
+     * concerns, once a ConnectionEvent has been reported on, follow-up reports about that
+     * ConnectionEvent are only generated if there is any change to the most-recently reported
+     * encryption or integrity, if there is a RAT change, or if the value of
+     * SecurityAlgorithmUpdate#isUnprotectedEmergency changes. A change only in cell ID should not
+     * trigger an update, as the design is intended to be agnostic to dual connectivity ("secondary
+     * serving cells").
      *
-     * Sample scenario to further clarify "most-recently reported":
+     * Example to further clarify "most-recently reported":
+     * 1. After booting up, the UE is in ENDC with LTE. Modem reports NAS_SIGNALLING_LTE and
+     *    AS_SIGNALLING_LTE are well-ciphered but AS_SIGNALLING_5G is null-ciphered.
+     * 2. UE moves to 3G and enters the connected mode. Modem reports indications of PS_SERVICE_3G
+     *    and SIGNALLING_3G to Android.
+     * 3. UE moves to LTE. UE enters the connected mode and there is no ENDC. The algorithms of
+     *    NAS_SIGNALLING_LTE and AS_SIGNALLING_LTE are the same as in Step 1. The UE should send
+     *    this indication to AP as it’s a RAT switch.
+     * 4. Later, UE establishes ENDC. AS_SIGNALLING_5G is null-ciphered. The UE should send this
+     *    indication as well, as it is a RAT switch.
+     * 5. The UE enter IDLE mode, and later connected mode in ENDC. There are no changes to security
+     *    algorithms, so the modem does not need to send any updates.
      *
-     * 1. Modem reports user is connected to a null-ciphered 3G network.
-     * 2. User then moves and connects to a well-ciphered 5G network, and modem reports this.
-     * 3. User returns to original location and reconnects to the null-ciphered 3G network. Modem
-     *    should report this as it's different than the most-recently reported data from step (2).
+     * Most recently reported state is reset when (1) RadioState is transitioned to ON from any
+     * other state (e.g. radio is turned on during device boot, or modem boot), and (2) when
+     * CardState is transitioned to PRESENT from any other state (e.g. when SIM is inserted), or (3)
+     * if there is a change in access network (PLMN) or RAT.
      *
-     * State is reset when (1) RadioState is transitioned to ON from any other state (e.g. radio
-     * is turned on during device boot, or modem boot), and (2) when CardState is transitioned
-     * to PRESENT from any other state (e.g. when SIM is inserted), or (3) if there is a change in
-     * access network (PLMN).
+     * securityAlgorithmUpdate indications must be sent to Android regardless of the screen state.
+     * If the screen is off, the indications must still be sent to Android.
+     *
+     *
+     * 5G TS 38.331 cipheringDisabled and integrityProtection
+     * ======================================================
+     * For most connections, generally what is reported by the network is what ends up being used.
+     * There are two significant cases where this may not be the case. In 5G, per the introduction
+     * of network configuration options cipheringDisabled and integrityProtection (TS 38.331), the
+     * network can have declared certain security algorithms to be used while also requiring a null
+     * algorithm via those parameters.
+     *
+     *
+     * Exceptions for DRBs with null integrity (pre-5G Rel 16)
+     * =======================================================
+     * When reporting the SecurityAlgorithm for a ConnectionType which includes a DRB, there is an
+     * exception where a DRB with null integrity is not to be considered/included in reporting
+     * except for 5G Rel 16 connections and newer. Because DRBs almost always use null integrity in
+     * practice, and thus if included the report would always be null, rendering the report
+     * useless. For anything 5G Rel 16 or newer, accurate reporting for the DRB's integrity is
+     * required.
+     *
+     *
+     * NRDC MCG and SCGs
+     * =================
+     * In the NRDC case, there can be two sets of algorithms, one for the MCG (Master Cell Group)
+     * and one for the SCG (Secondary Cell Group). In this case, always send a combined update that
+     * reflects the weaker of the algorithms, e.g. (weakest) NEA0 < NEA1 < NEA2 < NEA3 (strongest).
+     * This applies to both the ciphering and integrity algorithms.
+     *
+     *
+     * Determining the value of isUnprotectedEmergency
+     * ===============================================
+     * 2G: isUnprotectedEmergency is true if the ciphering algorithm is NULL.
+     * 3G: isUnprotectedEmergency is true if the ciphering and integrity algorithm are NULL.
+     * 4G: isUnprotectedEmergency is true if the ciphering algorithm is NULL.
+     * 5G: isUnprotectedEmergency is true if the ciphering algorithm is NULL.
+     * Notes:
+     *    - On integrity: In 4G, PDCP can be LTE-based or NR-based. Starting from 5G Rel 17, only
+     *      the NR-based PDCP supports DRB integrity. As the PDCP version can change during a DRB's
+     *      operation, it becomes complicated when integrity is used to determine whether an
+     *      emergency call is protected or not, hence its exclusion to simplify implementation.
+     *    - 4G and 5G with multiple DRBs : emergency calls are protected under that RAT only if all
+     *      DRBs are protected (including IMS DRB).
+     *    - 4G and 5G DRB integrity: Since DRB integrity is not enabled in most networks, if both
+     *      ciphering and integrity are taken into account to determine the value of
+     *      isUnprotectedEmergency, the value will mostly be false, hence why it is excluded.
      *
      * @param type Type of radio indication
      * @param securityAlgorithmUpdate SecurityAlgorithmUpdate encapsulates details of security
diff --git a/radio/aidl/android/hardware/radio/network/LteSignalStrength.aidl b/radio/aidl/android/hardware/radio/network/LteSignalStrength.aidl
index 21d3ec7..785db0b 100644
--- a/radio/aidl/android/hardware/radio/network/LteSignalStrength.aidl
+++ b/radio/aidl/android/hardware/radio/network/LteSignalStrength.aidl
@@ -21,41 +21,43 @@
 @JavaDerive(toString=true)
 parcelable LteSignalStrength {
     /**
-     * Valid values are (0-31, 99) as defined in TS 27.007 8.5; INT_MAX means invalid/unreported.
+     * Valid values are (0-31, 99) as defined in TS 27.007 8.5;
+     * RadioConst:VALUE_UNAVAILABLE means invalid/unreported.
      */
     int signalStrength;
     /**
      * The current Reference Signal Receive Power in dBm multiplied by -1. Range: 44 to 140 dBm;
-     * INT_MAX: 0x7FFFFFFF denotes invalid/unreported value. Reference: 3GPP TS 36.133 9.1.4
+     * RadioConst:VALUE_UNAVAILABLE denotes invalid/unreported value. Ref: 3GPP TS 36.133 9.1.4
      */
     int rsrp;
     /**
      * The current Reference Signal Receive Quality in dB multiplied by -1. Range: 20 to 3 dB;
-     * INT_MAX: 0x7FFFFFFF denotes invalid/unreported value. Reference: 3GPP TS 36.133 9.1.7
+     * RadioConst:VALUE_UNAVAILABLE denotes invalid/unreported value. Ref: 3GPP TS 36.133 9.1.7
      */
     int rsrq;
     /**
      * The current reference signal signal-to-noise ratio in 0.1 dB units.
      * Range: -200 to +300 (-200 = -20.0 dB, +300 = 30dB).
-     * INT_MAX: 0x7FFFFFFF denotes invalid/unreported value. Reference: 3GPP TS 36.101 8.1.1
+     * RadioConst:VALUE_UNAVAILABLE denotes invalid/unreported value. Ref: 3GPP TS 36.101 8.1.1
      */
     int rssnr;
     /**
      * The current Channel Quality Indicator. Range: 0 to 15.
-     * INT_MAX: 0x7FFFFFFF denotes invalid/unreported value. Reference: 3GPP TS 36.101 9.2, 9.3, A.4
+     * RadioConst:VALUE_UNAVAILABLE denotes invalid/unreported value.
+     * Ref: 3GPP TS 36.101 9.2, 9.3, A.4
      */
     int cqi;
     /**
      * Timing advance in micro seconds for a one way trip from cell to device. Approximate distance
      * is calculated using 300m/us * timingAdvance. Range: 0 to 1282 inclusive.
-     * INT_MAX: 0x7FFFFFFF denotes invalid/unreported value. Reference: 3GPP 36.213 section 4.2.3
+     * RadioConst:VALUE_UNAVAILABLE denotes invalid/unreported value. Ref: 3GPP 36.213 section 4.2.3
      */
     int timingAdvance;
     /**
      * CSI channel quality indicator (CQI) table index. There are multiple CQI tables.
      * The definition of CQI in each table is different.
      * Reference: 3GPP TS 136.213 section 7.2.3.
-     * Range [1, 6], INT_MAX means invalid/unreported.
+     * Range [1, 6], RadioConst:VALUE_UNAVAILABLE means invalid/unreported.
      */
     int cqiTableIndex;
 }
diff --git a/radio/aidl/android/hardware/radio/network/NrSignalStrength.aidl b/radio/aidl/android/hardware/radio/network/NrSignalStrength.aidl
index 65daf36..a0db2d5 100644
--- a/radio/aidl/android/hardware/radio/network/NrSignalStrength.aidl
+++ b/radio/aidl/android/hardware/radio/network/NrSignalStrength.aidl
@@ -16,6 +16,8 @@
 
 package android.hardware.radio.network;
 
+import android.hardware.radio.RadioConst;
+
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
@@ -23,44 +25,44 @@
     /**
      * SS reference signal received power, multiplied by -1.
      * Reference: 3GPP TS 38.215.
-     * Range [44, 140], INT_MAX means invalid/unreported.
+     * Range [44, 140], RadioConst:VALUE_UNAVAILABLE means invalid/unreported.
      */
     int ssRsrp;
     /**
      * SS reference signal received quality, multiplied by -1.
      * Reference: 3GPP TS 38.215, 3GPP TS 38.133 section 10.
-     * Range [-20 dB, 43 dB], INT_MAX means invalid/unreported.
+     * Range [-20 dB, 43 dB], RadioConst:VALUE_UNAVAILABLE means invalid/unreported.
      */
     int ssRsrq;
     /**
      * SS signal-to-noise and interference ratio.
      * Reference: 3GPP TS 38.215 section 5.1.*, 3GPP TS 38.133 section 10.1.16.1.
-     * Range [-23, 40], INT_MAX means invalid/unreported.
+     * Range [-23, 40], RadioConst:VALUE_UNAVAILABLE means invalid/unreported.
      */
     int ssSinr;
     /**
      * CSI reference signal received power, multiplied by -1.
      * Reference: 3GPP TS 38.215.
-     * Range [44, 140], INT_MAX means invalid/unreported.
+     * Range [44, 140], RadioConst:VALUE_UNAVAILABLE means invalid/unreported.
      */
     int csiRsrp;
     /**
      * CSI reference signal received quality, multiplied by -1.
      * Reference: 3GPP TS 38.215.
-     * Range [3, 20], INT_MAX means invalid/unreported.
+     * Range [3, 20], RadioConst:VALUE_UNAVAILABLE means invalid/unreported.
      */
     int csiRsrq;
     /**
      * CSI signal-to-noise and interference ratio.
      * Reference: 3GPP TS 138.215 section 5.1.*, 3GPP TS 38.133 section 10.1.16.1.
-     * Range [-23, 40], INT_MAX means invalid/unreported.
+     * Range [-23, 40], RadioConst:VALUE_UNAVAILABLE means invalid/unreported.
      */
     int csiSinr;
     /**
      * CSI channel quality indicator (CQI) table index. There are multiple CQI tables.
      * The definition of CQI in each table is different.
      * Reference: 3GPP TS 138.214 section 5.2.2.1.
-     * Range [1, 3], INT_MAX means invalid/unreported.
+     * Range [1, 3], RadioConst:VALUE_UNAVAILABLE means invalid/unreported.
      */
     int csiCqiTableIndex;
     /**
@@ -69,14 +71,14 @@
      * index is provided for each subband, in ascending order of subband index. If CQI is not
      * available, the CQI report is empty.
      * Reference: 3GPP TS 138.214 section 5.2.2.1.
-     * Range [0, 15], 0xFF means invalid/unreported.
+     * Range [0, 15], RadioConst:VALUE_UNAVAILABLE_BYTE means invalid/unreported.
      */
     byte[] csiCqiReport;
     /**
      * Timing advance in micro seconds for a one way trip from cell to device. Approximate distance
      * is calculated using 300m/us * timingAdvance. Range: 0 to 1282 inclusive.
-     * INT_MAX: 0x7FFFFFFF denotes invalid/unreported value.
+     * RadioConst:VALUE_UNAVAILABLE denotes invalid/unreported value.
      * Reference: 3GPP 36.213 section 4.2.3
      */
-    int timingAdvance = 0x7FFFFFFF;
+    int timingAdvance = RadioConst.VALUE_UNAVAILABLE;
 }
diff --git a/radio/aidl/android/hardware/radio/network/SignalStrength.aidl b/radio/aidl/android/hardware/radio/network/SignalStrength.aidl
index 5fed522..fbe3be2 100644
--- a/radio/aidl/android/hardware/radio/network/SignalStrength.aidl
+++ b/radio/aidl/android/hardware/radio/network/SignalStrength.aidl
@@ -30,37 +30,37 @@
 parcelable SignalStrength {
     /**
      * If GSM measurements are provided, this structure must contain valid measurements; otherwise
-     * all fields should be set to INT_MAX to mark them as invalid.
+     * all fields should be set to RadioConst:VALUE_UNAVAILABLE to mark them as invalid.
      */
     GsmSignalStrength gsm;
     /**
      * If CDMA measurements are provided, this structure must contain valid measurements; otherwise
-     * all fields should be set to INT_MAX to mark them as invalid.
+     * all fields should be set to RadioConst:VALUE_UNAVAILABLE to mark them as invalid.
      */
     CdmaSignalStrength cdma;
     /**
      * If EvDO measurements are provided, this structure must contain valid measurements; otherwise
-     * all fields should be set to INT_MAX to mark them as invalid.
+     * all fields should be set to RadioConst:VALUE_UNAVAILABLE to mark them as invalid.
      */
     EvdoSignalStrength evdo;
     /**
      * If LTE measurements are provided, this structure must contain valid measurements; otherwise
-     * all fields should be set to INT_MAX to mark them as invalid.
+     * all fields should be set to RadioConst:VALUE_UNAVAILABLE to mark them as invalid.
      */
     LteSignalStrength lte;
     /**
      * If TD-SCDMA measurements are provided, this structure must contain valid measurements;
-     * otherwise all fields should be set to INT_MAX to mark them as invalid.
+     * otherwise all fields should be set to RadioConst:VALUE_UNAVAILABLE to mark them as invalid.
      */
     TdscdmaSignalStrength tdscdma;
     /**
      * If WCDMA measurements are provided, this structure must contain valid measurements; otherwise
-     * all fields should be set to INT_MAX to mark them as invalid.
+     * all fields should be set to RadioConst:VALUE_UNAVAILABLE to mark them as invalid.
      */
     WcdmaSignalStrength wcdma;
     /**
      * If NR 5G measurements are provided, this structure must contain valid measurements; otherwise
-     * all fields should be set to INT_MAX to mark them as invalid.
+     * all fields should be set to RadioConst:VALUE_UNAVAILABLE to mark them as invalid.
      */
     NrSignalStrength nr;
 }
diff --git a/radio/aidl/android/hardware/radio/network/TdscdmaSignalStrength.aidl b/radio/aidl/android/hardware/radio/network/TdscdmaSignalStrength.aidl
index 4afdd0f..87c6baa 100644
--- a/radio/aidl/android/hardware/radio/network/TdscdmaSignalStrength.aidl
+++ b/radio/aidl/android/hardware/radio/network/TdscdmaSignalStrength.aidl
@@ -22,17 +22,17 @@
 parcelable TdscdmaSignalStrength {
     /**
      * UTRA carrier RSSI as defined in TS 25.225 5.1.4. Valid values are (0-31, 99) as defined in
-     * TS 27.007 8.5. INT_MAX denotes that the value is invalid/unreported.
+     * TS 27.007 8.5. RadioConst:VALUE_UNAVAILABLE denotes that the value is invalid/unreported.
      */
     int signalStrength;
     /**
      * Transport Channel BER as defined in TS 25.225 5.2.5. Valid values are (0-7, 99) as defined in
-     * TS 27.007 8.5. INT_MAX denotes that the value is invalid/unreported.
+     * TS 27.007 8.5. RadioConst:VALUE_UNAVAILABLE denotes that the value is invalid/unreported.
      */
     int bitErrorRate;
     /**
      * P-CCPCH RSCP as defined in TS 25.225 5.1.1. Valid values are (0-96, 255) as defined in
-     * TS 27.007 8.69. INT_MAX denotes that the value is invalid/unreported.
+     * TS 27.007 8.69. RadioConst:VALUE_UNAVAILABLE denotes that the value is invalid/unreported.
      */
     int rscp;
 }
diff --git a/radio/aidl/android/hardware/radio/network/WcdmaSignalStrength.aidl b/radio/aidl/android/hardware/radio/network/WcdmaSignalStrength.aidl
index ace89ed..8bc7fb8 100644
--- a/radio/aidl/android/hardware/radio/network/WcdmaSignalStrength.aidl
+++ b/radio/aidl/android/hardware/radio/network/WcdmaSignalStrength.aidl
@@ -21,21 +21,23 @@
 @JavaDerive(toString=true)
 parcelable WcdmaSignalStrength {
     /**
-     * Valid values are (0-31, 99) as defined in TS 27.007 8.5; INT_MAX means unreported.
+     * Valid values are (0-31, 99) as defined in TS 27.007 8.5; RadioConst:VALUE_UNAVAILABLE means
+     * unreported.
      */
     int signalStrength;
     /**
-     * Bit error rate (0-7, 99) as defined in TS 27.007 8.5; INT_MAX means invalid/unreported.
+     * Bit error rate (0-7, 99) as defined in TS 27.007 8.5; RadioConst:VALUE_UNAVAILABLE means
+     * invalid/unreported.
      */
     int bitErrorRate;
     /**
      * CPICH RSCP as defined in TS 25.215 5.1.1. Valid values are (0-96, 255) as defined in
-     * TS 27.007 8.69. INT_MAX denotes that the value is invalid/unreported.
+     * TS 27.007 8.69. RadioConst:VALUE_UNAVAILABLE denotes that the value is invalid/unreported.
      */
     int rscp;
     /**
      * Ec/No value as defined in TS 25.215 5.1.5. Valid values are (0-49, 255) as defined in
-     * TS 27.007 8.69. INT_MAX denotes that the value is invalid/unreported.
+     * TS 27.007 8.69. RadioConst:VALUE_UNAVAILABLE denotes that the value is invalid/unreported.
      */
     int ecno;
 }
diff --git a/radio/aidl/android/hardware/radio/sim/IRadioSim.aidl b/radio/aidl/android/hardware/radio/sim/IRadioSim.aidl
index 7870a74..1e010b9 100644
--- a/radio/aidl/android/hardware/radio/sim/IRadioSim.aidl
+++ b/radio/aidl/android/hardware/radio/sim/IRadioSim.aidl
@@ -257,7 +257,7 @@
      * Request APDU exchange on the basic channel. This command reflects TS 27.007
      * "generic SIM access" operation (+CSIM). The modem must ensure proper function of GSM/CDMA,
      * and filter commands appropriately. It must filter channel management and SELECT by DF
-     * name commands. "sessionid" field must be ignored.
+     * name commands. "sessionId" field is always 0 (for aid="") and may be ignored.
      *
      * @param serial Serial number of request.
      * @param message SimApdu to be sent
diff --git a/radio/aidl/android/hardware/radio/sim/IRadioSimResponse.aidl b/radio/aidl/android/hardware/radio/sim/IRadioSimResponse.aidl
index 63134c1..8666e03 100644
--- a/radio/aidl/android/hardware/radio/sim/IRadioSimResponse.aidl
+++ b/radio/aidl/android/hardware/radio/sim/IRadioSimResponse.aidl
@@ -263,6 +263,8 @@
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:INTERNAL_ERR
+     *   RadioError:INVALID_ARGUMENTS when given channel is invalid or basic (channel 0)
+     *   RadioError:MISSING_RESOURCE when given channel is not open
      *   RadioError:NO_MEMORY
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
@@ -325,6 +327,7 @@
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:INTERNAL_ERR
+     *   RadioError:INVALID_ARGUMENTS
      *   RadioError:NO_MEMORY
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
diff --git a/radio/aidl/compat/libradiocompat/Android.bp b/radio/aidl/compat/libradiocompat/Android.bp
index 3fbd398..a3a8c20 100644
--- a/radio/aidl/compat/libradiocompat/Android.bp
+++ b/radio/aidl/compat/libradiocompat/Android.bp
@@ -25,16 +25,16 @@
 cc_defaults {
     name: "android.hardware.radio-library.aidl_deps",
     shared_libs: [
-        "android.hardware.radio.config-V3-ndk",
+        "android.hardware.radio.config-V4-ndk",
         "android.hardware.radio.data-V4-ndk",
-        "android.hardware.radio.ims-V2-ndk",
+        "android.hardware.radio.ims-V3-ndk",
         "android.hardware.radio.ims.media-V3-ndk",
-        "android.hardware.radio.messaging-V3-ndk",
-        "android.hardware.radio.modem-V3-ndk",
-        "android.hardware.radio.network-V3-ndk",
+        "android.hardware.radio.messaging-V4-ndk",
+        "android.hardware.radio.modem-V4-ndk",
+        "android.hardware.radio.network-V4-ndk",
         "android.hardware.radio.sap-V1-ndk",
-        "android.hardware.radio.sim-V3-ndk",
-        "android.hardware.radio.voice-V3-ndk",
+        "android.hardware.radio.sim-V4-ndk",
+        "android.hardware.radio.voice-V4-ndk",
     ],
 }
 
diff --git a/radio/aidl/vts/Android.bp b/radio/aidl/vts/Android.bp
index 37e0ba8..6e8ce8b 100644
--- a/radio/aidl/vts/Android.bp
+++ b/radio/aidl/vts/Android.bp
@@ -77,17 +77,17 @@
         "server_configurable_flags",
     ],
     static_libs: [
-        "android.hardware.radio-V3-ndk",
-        "android.hardware.radio.config-V3-ndk",
+        "android.hardware.radio-V4-ndk",
+        "android.hardware.radio.config-V4-ndk",
         "android.hardware.radio.data-V4-ndk",
-        "android.hardware.radio.ims-V2-ndk",
+        "android.hardware.radio.ims-V3-ndk",
         "android.hardware.radio.ims.media-V3-ndk",
-        "android.hardware.radio.messaging-V3-ndk",
-        "android.hardware.radio.modem-V3-ndk",
-        "android.hardware.radio.network-V3-ndk",
+        "android.hardware.radio.messaging-V4-ndk",
+        "android.hardware.radio.modem-V4-ndk",
+        "android.hardware.radio.network-V4-ndk",
         "android.hardware.radio.sap-V1-ndk",
-        "android.hardware.radio.sim-V3-ndk",
-        "android.hardware.radio.voice-V3-ndk",
+        "android.hardware.radio.sim-V4-ndk",
+        "android.hardware.radio.voice-V4-ndk",
         "telephony_flags_c_lib",
     ],
     test_suites: [
diff --git a/security/keymint/aidl/default/Android.bp b/security/keymint/aidl/default/Android.bp
index a7066de..ff2393c 100644
--- a/security/keymint/aidl/default/Android.bp
+++ b/security/keymint/aidl/default/Android.bp
@@ -111,6 +111,13 @@
     src: "android.hardware.hardware_keystore.xml",
 }
 
+prebuilt_etc {
+    name: "android.hardware.hardware_keystore_V3.xml",
+    sub_dir: "permissions",
+    vendor: true,
+    src: "android.hardware.hardware_keystore_V3.xml",
+}
+
 rust_library {
     name: "libkmr_hal_nonsecure",
     crate_name: "kmr_hal_nonsecure",
diff --git a/security/keymint/aidl/default/android.hardware.hardware_keystore_V3.xml b/security/keymint/aidl/default/android.hardware.hardware_keystore_V3.xml
new file mode 100644
index 0000000..4c75596
--- /dev/null
+++ b/security/keymint/aidl/default/android.hardware.hardware_keystore_V3.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2021 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.
+-->
+<permissions>
+  <feature name="android.hardware.hardware_keystore" version="300" />
+</permissions>
diff --git a/security/keymint/aidl/vts/functional/BootloaderStateTest.cpp b/security/keymint/aidl/vts/functional/BootloaderStateTest.cpp
index c1f6aee..083a9aa 100644
--- a/security/keymint/aidl/vts/functional/BootloaderStateTest.cpp
+++ b/security/keymint/aidl/vts/functional/BootloaderStateTest.cpp
@@ -109,7 +109,7 @@
     }
 }
 
-// Check that attested vbmeta digest is correct.
+// Check that the attested VBMeta digest is correct.
 TEST_P(BootloaderStateTest, VbmetaDigest) {
     AvbSlotVerifyData* avbSlotData;
     auto suffix = fs_mgr_get_slot_suffix();
@@ -125,21 +125,29 @@
                                   AVB_HASHTREE_ERROR_MODE_EIO, &avbSlotData);
     ASSERT_TRUE(avb_slot_data_loaded(result)) << "Failed to load avb slot data";
 
-    // Unfortunately, bootloader is not required to report the algorithm used
-    // to calculate the digest. There are only two supported options though,
-    // SHA256 and SHA512. Attested VBMeta digest must match one of these.
-    vector<uint8_t> digest256(AVB_SHA256_DIGEST_SIZE);
-    vector<uint8_t> digest512(AVB_SHA512_DIGEST_SIZE);
-
+    vector<uint8_t> sha256Digest(AVB_SHA256_DIGEST_SIZE);
     avb_slot_verify_data_calculate_vbmeta_digest(avbSlotData, AVB_DIGEST_TYPE_SHA256,
-                                                 digest256.data());
-    avb_slot_verify_data_calculate_vbmeta_digest(avbSlotData, AVB_DIGEST_TYPE_SHA512,
-                                                 digest512.data());
+                                                 sha256Digest.data());
 
-    ASSERT_TRUE((attestedVbmetaDigest_ == digest256) || (attestedVbmetaDigest_ == digest512))
-            << "Attested vbmeta digest (" << bin2hex(attestedVbmetaDigest_)
-            << ") does not match computed digest (sha256: " << bin2hex(digest256)
-            << ", sha512: " << bin2hex(digest512) << ").";
+    if (get_vsr_api_level() >= __ANDROID_API_V__) {
+        ASSERT_TRUE(attestedVbmetaDigest_ == sha256Digest)
+                << "Attested VBMeta digest (" << bin2hex(attestedVbmetaDigest_)
+                << ") does not match the expected SHA-256 digest (" << bin2hex(sha256Digest)
+                << ").";
+    } else {
+        // Prior to VSR-V, there was no MUST requirement for the algorithm used by the bootloader
+        // to calculate the VBMeta digest. However, the only two supported options are SHA-256 and
+        // SHA-512, so we expect the attested VBMeta digest to match one of these.
+        vector<uint8_t> sha512Digest(AVB_SHA512_DIGEST_SIZE);
+        avb_slot_verify_data_calculate_vbmeta_digest(avbSlotData, AVB_DIGEST_TYPE_SHA512,
+                                                     sha512Digest.data());
+
+        ASSERT_TRUE((attestedVbmetaDigest_ == sha256Digest) ||
+                    (attestedVbmetaDigest_ == sha512Digest))
+                << "Attested VBMeta digest (" << bin2hex(attestedVbmetaDigest_)
+                << ") does not match the expected digest (SHA-256: " << bin2hex(sha256Digest)
+                << " or SHA-512: " << bin2hex(sha512Digest) << ").";
+    }
 }
 
 INSTANTIATE_KEYMINT_AIDL_TEST(BootloaderStateTest);
diff --git a/security/keymint/aidl/vts/performance/KeyMintBenchmark.cpp b/security/keymint/aidl/vts/performance/KeyMintBenchmark.cpp
index 49fd0c9..781b7a6 100644
--- a/security/keymint/aidl/vts/performance/KeyMintBenchmark.cpp
+++ b/security/keymint/aidl/vts/performance/KeyMintBenchmark.cpp
@@ -294,6 +294,7 @@
     ErrorCode DeleteKey() {
         Status result = keymint_->deleteKey(key_blob_);
         key_blob_ = vector<uint8_t>();
+        key_transform_ = "";
         return GetReturnErrorCode(result);
     }
 
diff --git a/security/keymint/support/Android.bp b/security/keymint/support/Android.bp
index f313cf3..271e36c 100644
--- a/security/keymint/support/Android.bp
+++ b/security/keymint/support/Android.bp
@@ -114,6 +114,7 @@
 
 cc_test {
     name: "libkeymint_remote_prov_support_test",
+    cpp_std: "c++20",
     srcs: ["remote_prov_utils_test.cpp"],
     static_libs: [
         "android.hardware.security.rkp-V3-ndk",
diff --git a/security/keymint/support/fuzzer/keymint_remote_prov_fuzzer.cpp b/security/keymint/support/fuzzer/keymint_remote_prov_fuzzer.cpp
index 9b74fbb..ebccf25 100644
--- a/security/keymint/support/fuzzer/keymint_remote_prov_fuzzer.cpp
+++ b/security/keymint/support/fuzzer/keymint_remote_prov_fuzzer.cpp
@@ -74,16 +74,20 @@
     uint8_t challengeSize = mFdp.ConsumeIntegralInRange<uint8_t>(kMinSize, kChallengeSize);
     std::vector<uint8_t> challenge = mFdp.ConsumeBytes<uint8_t>(challengeSize);
 
+    RpcHardwareInfo rpcHardwareInfo;
+    gRPC->getHardwareInfo(&rpcHardwareInfo);
+
     std::vector<uint8_t> csr;
     gRPC->generateCertificateRequestV2(keysToSign, challenge, &csr);
 
     while (mFdp.remaining_bytes()) {
         auto invokeProvAPI = mFdp.PickValueInArray<const std::function<void()>>({
                 [&]() {
-                    verifyFactoryCsr(cborKeysToSign, csr, gRPC.get(), kServiceName, challenge);
+                    verifyFactoryCsr(cborKeysToSign, csr, rpcHardwareInfo, kServiceName, challenge);
                 },
                 [&]() {
-                    verifyProductionCsr(cborKeysToSign, csr, gRPC.get(), kServiceName, challenge);
+                    verifyProductionCsr(cborKeysToSign, csr, rpcHardwareInfo, kServiceName,
+                                        challenge);
                 },
                 [&]() { isCsrWithProperDiceChain(csr, kServiceName); },
         });
diff --git a/security/keymint/support/include/remote_prov/MockIRemotelyProvisionedComponent.h b/security/keymint/support/include/remote_prov/MockIRemotelyProvisionedComponent.h
deleted file mode 100644
index 4fa39c2..0000000
--- a/security/keymint/support/include/remote_prov/MockIRemotelyProvisionedComponent.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright 2024 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.
- */
-
-#pragma once
-
-#include <aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.h>
-#include <aidl/android/hardware/security/keymint/RpcHardwareInfo.h>
-#include <android-base/properties.h>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-#include <cstdint>
-
-namespace aidl::android::hardware::security::keymint::remote_prov {
-
-using ::ndk::ScopedAStatus;
-
-class MockIRemotelyProvisionedComponent : public IRemotelyProvisionedComponentDefault {
-  public:
-    MOCK_METHOD(ScopedAStatus, getHardwareInfo, (RpcHardwareInfo * _aidl_return), (override));
-    MOCK_METHOD(ScopedAStatus, generateEcdsaP256KeyPair,
-                (bool in_testMode, MacedPublicKey* out_macedPublicKey,
-                 std::vector<uint8_t>* _aidl_return),
-                (override));
-    MOCK_METHOD(ScopedAStatus, generateCertificateRequest,
-                (bool in_testMode, const std::vector<MacedPublicKey>& in_keysToSign,
-                 const std::vector<uint8_t>& in_endpointEncryptionCertChain,
-                 const std::vector<uint8_t>& in_challenge, DeviceInfo* out_deviceInfo,
-                 ProtectedData* out_protectedData, std::vector<uint8_t>* _aidl_return),
-                (override));
-    MOCK_METHOD(ScopedAStatus, generateCertificateRequestV2,
-                (const std::vector<MacedPublicKey>& in_keysToSign,
-                 const std::vector<uint8_t>& in_challenge, std::vector<uint8_t>* _aidl_return),
-                (override));
-    MOCK_METHOD(ScopedAStatus, getInterfaceVersion, (int32_t* _aidl_return), (override));
-    MOCK_METHOD(ScopedAStatus, getInterfaceHash, (std::string * _aidl_return), (override));
-};
-
-}  // namespace aidl::android::hardware::security::keymint::remote_prov
\ No newline at end of file
diff --git a/security/keymint/support/include/remote_prov/remote_prov_utils.h b/security/keymint/support/include/remote_prov/remote_prov_utils.h
index caeb7ff..6cb00f2 100644
--- a/security/keymint/support/include/remote_prov/remote_prov_utils.h
+++ b/security/keymint/support/include/remote_prov/remote_prov_utils.h
@@ -99,7 +99,7 @@
  * e.g. for "android.hardware.security.keymint.IRemotelyProvisionedComponent/avf",
  * it returns "avf".
  */
-std::string deviceSuffix(const std::string& name);
+std::string_view deviceSuffix(std::string_view name);
 
 struct EekChain {
     bytevec chain;
@@ -153,7 +153,7 @@
  * is parsed in the manufacturing process.
  */
 ErrMsgOr<std::unique_ptr<cppbor::Map>> parseAndValidateFactoryDeviceInfo(
-        const std::vector<uint8_t>& deviceInfoBytes, IRemotelyProvisionedComponent* provisionable);
+        const std::vector<uint8_t>& deviceInfoBytes, const RpcHardwareInfo& info);
 
 /**
  * Parses a DeviceInfo structure from the given CBOR data. The parsed data is then validated to
@@ -162,7 +162,7 @@
  * suitable for the end user.
  */
 ErrMsgOr<std::unique_ptr<cppbor::Map>> parseAndValidateProductionDeviceInfo(
-        const std::vector<uint8_t>& deviceInfoBytes, IRemotelyProvisionedComponent* provisionable);
+        const std::vector<uint8_t>& deviceInfoBytes, const RpcHardwareInfo& info);
 
 /**
  * Verify the protected data as if the device is still early in the factory process and may not
@@ -171,36 +171,39 @@
 ErrMsgOr<std::vector<BccEntryData>> verifyFactoryProtectedData(
         const DeviceInfo& deviceInfo, const cppbor::Array& keysToSign,
         const std::vector<uint8_t>& keysToSignMac, const ProtectedData& protectedData,
-        const EekChain& eekChain, const std::vector<uint8_t>& eekId, int32_t supportedEekCurve,
-        IRemotelyProvisionedComponent* provisionable, const std::string& instanceName,
-        const std::vector<uint8_t>& challenge);
+        const EekChain& eekChain, const std::vector<uint8_t>& eekId, const RpcHardwareInfo& info,
+        const std::string& instanceName, const std::vector<uint8_t>& challenge);
 /**
  * Verify the protected data as if the device is a final production sample.
  */
 ErrMsgOr<std::vector<BccEntryData>> verifyProductionProtectedData(
         const DeviceInfo& deviceInfo, const cppbor::Array& keysToSign,
         const std::vector<uint8_t>& keysToSignMac, const ProtectedData& protectedData,
-        const EekChain& eekChain, const std::vector<uint8_t>& eekId, int32_t supportedEekCurve,
-        IRemotelyProvisionedComponent* provisionable, const std::string& instanceName,
-        const std::vector<uint8_t>& challenge, bool allowAnyMode = false);
+        const EekChain& eekChain, const std::vector<uint8_t>& eekId, const RpcHardwareInfo& info,
+        const std::string& instanceName, const std::vector<uint8_t>& challenge,
+        bool allowAnyMode = false);
 
 /**
  * Verify the CSR as if the device is still early in the factory process and may not
  * have all device identifiers provisioned yet.
  */
-ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyFactoryCsr(
-        const cppbor::Array& keysToSign, const std::vector<uint8_t>& csr,
-        IRemotelyProvisionedComponent* provisionable, const std::string& instanceName,
-        const std::vector<uint8_t>& challenge, bool allowDegenerate = true,
-        bool requireUdsCerts = false);
+ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyFactoryCsr(const cppbor::Array& keysToSign,
+                                                          const std::vector<uint8_t>& csr,
+                                                          const RpcHardwareInfo& info,
+                                                          const std::string& instanceName,
+                                                          const std::vector<uint8_t>& challenge,
+                                                          bool allowDegenerate = true,
+                                                          bool requireUdsCerts = false);
 
 /**
  * Verify the CSR as if the device is a final production sample.
  */
-ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyProductionCsr(
-        const cppbor::Array& keysToSign, const std::vector<uint8_t>& csr,
-        IRemotelyProvisionedComponent* provisionable, const std::string& instanceName,
-        const std::vector<uint8_t>& challenge, bool allowAnyMode = false);
+ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyProductionCsr(const cppbor::Array& keysToSign,
+                                                             const std::vector<uint8_t>& csr,
+                                                             const RpcHardwareInfo& info,
+                                                             const std::string& instanceName,
+                                                             const std::vector<uint8_t>& challenge,
+                                                             bool allowAnyMode = false);
 
 /** Checks whether the CSR has a proper DICE chain. */
 ErrMsgOr<bool> isCsrWithProperDiceChain(const std::vector<uint8_t>& csr,
diff --git a/security/keymint/support/remote_prov_utils.cpp b/security/keymint/support/remote_prov_utils.cpp
index 464d912..e11f021 100644
--- a/security/keymint/support/remote_prov_utils.cpp
+++ b/security/keymint/support/remote_prov_utils.cpp
@@ -52,8 +52,8 @@
 using X509_Ptr = bssl::UniquePtr<X509>;
 using CRYPTO_BUFFER_Ptr = bssl::UniquePtr<CRYPTO_BUFFER>;
 
-std::string deviceSuffix(const std::string& name) {
-    size_t pos = name.rfind('/');
+std::string_view deviceSuffix(std::string_view name) {
+    auto pos = name.rfind('/');
     if (pos == std::string::npos) {
         return name;
     }
@@ -483,7 +483,7 @@
 }
 
 ErrMsgOr<std::unique_ptr<cppbor::Map>> parseAndValidateDeviceInfo(
-        const std::vector<uint8_t>& deviceInfoBytes, IRemotelyProvisionedComponent* provisionable,
+        const std::vector<uint8_t>& deviceInfoBytes, const RpcHardwareInfo& rpcHardwareInfo,
         bool isFactory) {
     const cppbor::Array kValidVbStates = {"green", "yellow", "orange"};
     const cppbor::Array kValidBootloaderStates = {"locked", "unlocked"};
@@ -530,9 +530,7 @@
         return "DeviceInfo ordering is non-canonical.";
     }
 
-    RpcHardwareInfo info;
-    provisionable->getHardwareInfo(&info);
-    if (info.versionNumber < 3) {
+    if (rpcHardwareInfo.versionNumber < 3) {
         const std::unique_ptr<cppbor::Item>& version = parsed->get("version");
         if (!version) {
             return "Device info is missing version";
@@ -540,10 +538,10 @@
         if (!version->asUint()) {
             return "version must be an unsigned integer";
         }
-        if (version->asUint()->value() != info.versionNumber) {
+        if (version->asUint()->value() != rpcHardwareInfo.versionNumber) {
             return "DeviceInfo version (" + std::to_string(version->asUint()->value()) +
                    ") does not match the remotely provisioned component version (" +
-                   std::to_string(info.versionNumber) + ").";
+                   std::to_string(rpcHardwareInfo.versionNumber) + ").";
         }
     }
     // Bypasses the device info validation since the device info in AVF is currently
@@ -552,14 +550,14 @@
     // TODO(b/300911665): This check is temporary and will be replaced once the markers
     // on the DICE chain become available. We need to determine if the CSR is from the
     // RKP VM using the markers on the DICE chain.
-    if (info.uniqueId == "AVF Remote Provisioning 1") {
+    if (rpcHardwareInfo.uniqueId == "AVF Remote Provisioning 1") {
         return std::move(parsed);
     }
 
     std::string error;
     std::string tmp;
     std::set<std::string_view> previousKeys;
-    switch (info.versionNumber) {
+    switch (rpcHardwareInfo.versionNumber) {
         case 3:
             if (isTeeDeviceInfo(*parsed) && parsed->size() != kNumTeeDeviceInfoEntries) {
                 error += fmt::format(
@@ -626,7 +624,7 @@
                                    kValidAttIdStates);
             break;
         default:
-            return "Unrecognized version: " + std::to_string(info.versionNumber);
+            return "Unrecognized version: " + std::to_string(rpcHardwareInfo.versionNumber);
     }
 
     if (!error.empty()) {
@@ -637,13 +635,13 @@
 }
 
 ErrMsgOr<std::unique_ptr<cppbor::Map>> parseAndValidateFactoryDeviceInfo(
-        const std::vector<uint8_t>& deviceInfoBytes, IRemotelyProvisionedComponent* provisionable) {
-    return parseAndValidateDeviceInfo(deviceInfoBytes, provisionable, /*isFactory=*/true);
+        const std::vector<uint8_t>& deviceInfoBytes, const RpcHardwareInfo& rpcHardwareInfo) {
+    return parseAndValidateDeviceInfo(deviceInfoBytes, rpcHardwareInfo, /*isFactory=*/true);
 }
 
 ErrMsgOr<std::unique_ptr<cppbor::Map>> parseAndValidateProductionDeviceInfo(
-        const std::vector<uint8_t>& deviceInfoBytes, IRemotelyProvisionedComponent* provisionable) {
-    return parseAndValidateDeviceInfo(deviceInfoBytes, provisionable, /*isFactory=*/false);
+        const std::vector<uint8_t>& deviceInfoBytes, const RpcHardwareInfo& rpcHardwareInfo) {
+    return parseAndValidateDeviceInfo(deviceInfoBytes, rpcHardwareInfo, /*isFactory=*/false);
 }
 
 ErrMsgOr<bytevec> getSessionKey(ErrMsgOr<std::pair<bytevec, bytevec>>& senderPubkey,
@@ -661,8 +659,8 @@
 ErrMsgOr<std::vector<BccEntryData>> verifyProtectedData(
         const DeviceInfo& deviceInfo, const cppbor::Array& keysToSign,
         const std::vector<uint8_t>& keysToSignMac, const ProtectedData& protectedData,
-        const EekChain& eekChain, const std::vector<uint8_t>& eekId, int32_t supportedEekCurve,
-        IRemotelyProvisionedComponent* provisionable, const std::string& instanceName,
+        const EekChain& eekChain, const std::vector<uint8_t>& eekId,
+        const RpcHardwareInfo& rpcHardwareInfo, const std::string& instanceName,
         const std::vector<uint8_t>& challenge, bool isFactory, bool allowAnyMode = false) {
     auto [parsedProtectedData, _, protDataErrMsg] = cppbor::parse(protectedData.protectedData);
     if (!parsedProtectedData) {
@@ -685,7 +683,7 @@
         return "The COSE_encrypt recipient does not match the expected EEK identifier";
     }
 
-    auto sessionKey = getSessionKey(senderPubkey, eekChain, supportedEekCurve);
+    auto sessionKey = getSessionKey(senderPubkey, eekChain, rpcHardwareInfo.supportedEekCurve);
     if (!sessionKey) {
         return sessionKey.message();
     }
@@ -726,7 +724,7 @@
     }
 
     auto deviceInfoResult =
-            parseAndValidateDeviceInfo(deviceInfo.deviceInfo, provisionable, isFactory);
+            parseAndValidateDeviceInfo(deviceInfo.deviceInfo, rpcHardwareInfo, isFactory);
     if (!deviceInfoResult) {
         return deviceInfoResult.message();
     }
@@ -762,22 +760,22 @@
 ErrMsgOr<std::vector<BccEntryData>> verifyFactoryProtectedData(
         const DeviceInfo& deviceInfo, const cppbor::Array& keysToSign,
         const std::vector<uint8_t>& keysToSignMac, const ProtectedData& protectedData,
-        const EekChain& eekChain, const std::vector<uint8_t>& eekId, int32_t supportedEekCurve,
-        IRemotelyProvisionedComponent* provisionable, const std::string& instanceName,
+        const EekChain& eekChain, const std::vector<uint8_t>& eekId,
+        const RpcHardwareInfo& rpcHardwareInfo, const std::string& instanceName,
         const std::vector<uint8_t>& challenge) {
     return verifyProtectedData(deviceInfo, keysToSign, keysToSignMac, protectedData, eekChain,
-                               eekId, supportedEekCurve, provisionable, instanceName, challenge,
+                               eekId, rpcHardwareInfo, instanceName, challenge,
                                /*isFactory=*/true);
 }
 
 ErrMsgOr<std::vector<BccEntryData>> verifyProductionProtectedData(
         const DeviceInfo& deviceInfo, const cppbor::Array& keysToSign,
         const std::vector<uint8_t>& keysToSignMac, const ProtectedData& protectedData,
-        const EekChain& eekChain, const std::vector<uint8_t>& eekId, int32_t supportedEekCurve,
-        IRemotelyProvisionedComponent* provisionable, const std::string& instanceName,
+        const EekChain& eekChain, const std::vector<uint8_t>& eekId,
+        const RpcHardwareInfo& rpcHardwareInfo, const std::string& instanceName,
         const std::vector<uint8_t>& challenge, bool allowAnyMode) {
     return verifyProtectedData(deviceInfo, keysToSign, keysToSignMac, protectedData, eekChain,
-                               eekId, supportedEekCurve, provisionable, instanceName, challenge,
+                               eekId, rpcHardwareInfo, instanceName, challenge,
                                /*isFactory=*/false, allowAnyMode);
 }
 
@@ -912,7 +910,7 @@
 
 ErrMsgOr<std::unique_ptr<cppbor::Array>> parseAndValidateCsrPayload(
         const cppbor::Array& keysToSign, const std::vector<uint8_t>& csrPayload,
-        IRemotelyProvisionedComponent* provisionable, bool isFactory) {
+        const RpcHardwareInfo& rpcHardwareInfo, bool isFactory) {
     auto [parsedCsrPayload, _, errMsg] = cppbor::parse(csrPayload);
     if (!parsedCsrPayload) {
         return errMsg;
@@ -949,7 +947,8 @@
         return "Keys must be an Array.";
     }
 
-    auto result = parseAndValidateDeviceInfo(signedDeviceInfo->encode(), provisionable, isFactory);
+    auto result =
+            parseAndValidateDeviceInfo(signedDeviceInfo->encode(), rpcHardwareInfo, isFactory);
     if (!result) {
         return result.message();
     }
@@ -1100,13 +1099,12 @@
 
 ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyCsr(
         const cppbor::Array& keysToSign, const std::vector<uint8_t>& csr,
-        IRemotelyProvisionedComponent* provisionable, const std::string& instanceName,
+        const RpcHardwareInfo& rpcHardwareInfo, const std::string& instanceName,
         const std::vector<uint8_t>& challenge, bool isFactory, bool allowAnyMode = false,
         bool allowDegenerate = true, bool requireUdsCerts = false) {
-    RpcHardwareInfo info;
-    provisionable->getHardwareInfo(&info);
-    if (info.versionNumber != 3) {
-        return "Remotely provisioned component version (" + std::to_string(info.versionNumber) +
+    if (rpcHardwareInfo.versionNumber != 3) {
+        return "Remotely provisioned component version (" +
+               std::to_string(rpcHardwareInfo.versionNumber) +
                ") does not match expected version (3).";
     }
 
@@ -1117,61 +1115,46 @@
         return csrPayload.message();
     }
 
-    return parseAndValidateCsrPayload(keysToSign, *csrPayload, provisionable, isFactory);
+    return parseAndValidateCsrPayload(keysToSign, *csrPayload, rpcHardwareInfo, isFactory);
 }
 
 ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyFactoryCsr(
         const cppbor::Array& keysToSign, const std::vector<uint8_t>& csr,
-        IRemotelyProvisionedComponent* provisionable, const std::string& instanceName,
+        const RpcHardwareInfo& rpcHardwareInfo, const std::string& instanceName,
         const std::vector<uint8_t>& challenge, bool allowDegenerate, bool requireUdsCerts) {
-    return verifyCsr(keysToSign, csr, provisionable, instanceName, challenge, /*isFactory=*/true,
+    return verifyCsr(keysToSign, csr, rpcHardwareInfo, instanceName, challenge, /*isFactory=*/true,
                      /*allowAnyMode=*/false, allowDegenerate, requireUdsCerts);
 }
 
-ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyProductionCsr(
-        const cppbor::Array& keysToSign, const std::vector<uint8_t>& csr,
-        IRemotelyProvisionedComponent* provisionable, const std::string& instanceName,
-        const std::vector<uint8_t>& challenge, bool allowAnyMode) {
-    return verifyCsr(keysToSign, csr, provisionable, instanceName, challenge, /*isFactory=*/false,
+ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyProductionCsr(const cppbor::Array& keysToSign,
+                                                             const std::vector<uint8_t>& csr,
+                                                             const RpcHardwareInfo& rpcHardwareInfo,
+                                                             const std::string& instanceName,
+                                                             const std::vector<uint8_t>& challenge,
+                                                             bool allowAnyMode) {
+    return verifyCsr(keysToSign, csr, rpcHardwareInfo, instanceName, challenge, /*isFactory=*/false,
                      allowAnyMode);
 }
 
-ErrMsgOr<bool> isCsrWithProperDiceChain(const std::vector<uint8_t>& csr,
+ErrMsgOr<bool> isCsrWithProperDiceChain(const std::vector<uint8_t>& encodedCsr,
                                         const std::string& instanceName) {
-    auto [parsedRequest, _, csrErrMsg] = cppbor::parse(csr);
-    if (!parsedRequest) {
-        return csrErrMsg;
-    }
-    if (!parsedRequest->asArray()) {
-        return "AuthenticatedRequest is not a CBOR array.";
-    }
-    if (parsedRequest->asArray()->size() != 4U) {
-        return "AuthenticatedRequest must contain version, UDS certificates, DICE chain, and "
-               "signed data. However, the parsed AuthenticatedRequest has " +
-               std::to_string(parsedRequest->asArray()->size()) + " entries.";
-    }
-
-    auto version = parsedRequest->asArray()->get(0)->asUint();
-    auto diceCertChain = parsedRequest->asArray()->get(2)->asArray();
-
-    if (!version || version->value() != 1U) {
-        return "AuthenticatedRequest version must be an unsigned integer and must be equal to 1.";
-    }
-    if (!diceCertChain) {
-        return "AuthenticatedRequest DiceCertChain must be an Array.";
-    }
-
-    // DICE chain is [ pubkey, + DiceChainEntry ].
     auto diceChainKind = getDiceChainKind();
     if (!diceChainKind) {
         return diceChainKind.message();
     }
 
-    auto encodedDiceChain = diceCertChain->encode();
-    auto chain = hwtrust::DiceChain::Verify(encodedDiceChain, *diceChainKind,
-                                            /*allowAnyMode=*/false, deviceSuffix(instanceName));
-    if (!chain.ok()) return chain.error().message();
-    return chain->IsProper();
+    auto csr = hwtrust::Csr::validate(encodedCsr, *diceChainKind, false /*allowAnyMode*/,
+                                      deviceSuffix(instanceName));
+    if (!csr.ok()) {
+        return csr.error().message();
+    }
+
+    auto diceChain = csr->getDiceChain();
+    if (!diceChain.ok()) {
+        return diceChain.error().message();
+    }
+
+    return diceChain->IsProper();
 }
 
 }  // namespace aidl::android::hardware::security::keymint::remote_prov
diff --git a/security/keymint/support/remote_prov_utils_test.cpp b/security/keymint/support/remote_prov_utils_test.cpp
index 8ffb149..6f6a2d6 100644
--- a/security/keymint/support/remote_prov_utils_test.cpp
+++ b/security/keymint/support/remote_prov_utils_test.cpp
@@ -25,7 +25,6 @@
 #include <keymaster/logger.h>
 #include <keymaster/remote_provisioning_utils.h>
 #include <openssl/curve25519.h>
-#include <remote_prov/MockIRemotelyProvisionedComponent.h>
 #include <remote_prov/remote_prov_utils.h>
 
 #include <algorithm>
@@ -82,6 +81,76 @@
         0x50, 0x12, 0x82, 0x37, 0xfe, 0xa4, 0x07, 0xc3, 0xd5, 0xc3, 0x78, 0xcc, 0xf9, 0xef, 0xe1,
         0x95, 0x38, 0x9f, 0xb0, 0x79, 0x16, 0x4c, 0x4a, 0x23, 0xc4, 0xdc, 0x35, 0x4e, 0x0f};
 
+inline const std::vector<uint8_t> kCsrWithDegenerateDiceChain{
+        0x85, 0x01, 0xa0, 0x82, 0xa6, 0x01, 0x02, 0x03, 0x26, 0x20, 0x01, 0x21, 0x58, 0x20, 0x65,
+        0xe0, 0x51, 0x62, 0x45, 0x17, 0xcc, 0xa8, 0x40, 0x41, 0x6d, 0xc0, 0x86, 0x7a, 0x15, 0x6e,
+        0xee, 0x04, 0xae, 0xbd, 0x05, 0x13, 0x36, 0xcb, 0xd2, 0x8d, 0xd8, 0x80, 0x16, 0xc1, 0x69,
+        0x0d, 0x22, 0x58, 0x20, 0xea, 0xa1, 0x37, 0xd5, 0x01, 0xbd, 0xe0, 0x25, 0x6a, 0x3d, 0x4c,
+        0xcd, 0x31, 0xa1, 0x4d, 0xa6, 0x80, 0x82, 0x03, 0x40, 0xe2, 0x88, 0x81, 0x53, 0xc3, 0xb3,
+        0x6d, 0xf7, 0xf4, 0x10, 0xde, 0x96, 0x23, 0x58, 0x20, 0x24, 0x69, 0x44, 0x6e, 0xf5, 0xcc,
+        0x18, 0xfe, 0x63, 0xac, 0x5e, 0x85, 0x9c, 0xfc, 0x9d, 0xfa, 0x90, 0xee, 0x6c, 0xc2, 0x22,
+        0x49, 0x02, 0xc7, 0x93, 0xf4, 0x30, 0xf1, 0x51, 0x11, 0x20, 0x33, 0x84, 0x43, 0xa1, 0x01,
+        0x26, 0xa0, 0x58, 0x97, 0xa5, 0x01, 0x66, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x02, 0x67,
+        0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x00, 0x47, 0x44, 0x56, 0x41, 0x01, 0x3a,
+        0x00, 0x47, 0x44, 0x57, 0x58, 0x70, 0xa6, 0x01, 0x02, 0x03, 0x26, 0x20, 0x01, 0x21, 0x58,
+        0x20, 0x65, 0xe0, 0x51, 0x62, 0x45, 0x17, 0xcc, 0xa8, 0x40, 0x41, 0x6d, 0xc0, 0x86, 0x7a,
+        0x15, 0x6e, 0xee, 0x04, 0xae, 0xbd, 0x05, 0x13, 0x36, 0xcb, 0xd2, 0x8d, 0xd8, 0x80, 0x16,
+        0xc1, 0x69, 0x0d, 0x22, 0x58, 0x20, 0xea, 0xa1, 0x37, 0xd5, 0x01, 0xbd, 0xe0, 0x25, 0x6a,
+        0x3d, 0x4c, 0xcd, 0x31, 0xa1, 0x4d, 0xa6, 0x80, 0x82, 0x03, 0x40, 0xe2, 0x88, 0x81, 0x53,
+        0xc3, 0xb3, 0x6d, 0xf7, 0xf4, 0x10, 0xde, 0x96, 0x23, 0x58, 0x20, 0x24, 0x69, 0x44, 0x6e,
+        0xf5, 0xcc, 0x18, 0xfe, 0x63, 0xac, 0x5e, 0x85, 0x9c, 0xfc, 0x9d, 0xfa, 0x90, 0xee, 0x6c,
+        0xc2, 0x22, 0x49, 0x02, 0xc7, 0x93, 0xf4, 0x30, 0xf1, 0x51, 0x11, 0x20, 0x33, 0x3a, 0x00,
+        0x47, 0x44, 0x58, 0x41, 0x20, 0x58, 0x40, 0x16, 0xb9, 0x51, 0xdf, 0x31, 0xad, 0xa0, 0x3d,
+        0x98, 0x40, 0x85, 0xdf, 0xd9, 0xbe, 0xf6, 0x79, 0x62, 0x36, 0x8b, 0x60, 0xaa, 0x79, 0x8e,
+        0x52, 0x04, 0xdd, 0xba, 0x39, 0xa2, 0x58, 0x9c, 0x60, 0xd5, 0x96, 0x51, 0x42, 0xe2, 0xa5,
+        0x57, 0x58, 0xb4, 0x89, 0x2c, 0x94, 0xb9, 0xda, 0xe7, 0x93, 0x85, 0xda, 0x64, 0xa0, 0x52,
+        0xfc, 0x6b, 0xb1, 0x0a, 0xa8, 0x13, 0xd9, 0x84, 0xfb, 0x34, 0x77, 0x84, 0x43, 0xa1, 0x01,
+        0x26, 0xa0, 0x59, 0x02, 0x0f, 0x82, 0x58, 0x20, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+        0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
+        0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x59, 0x01, 0xe9, 0x84, 0x03,
+        0x67, 0x6b, 0x65, 0x79, 0x6d, 0x69, 0x6e, 0x74, 0xae, 0x65, 0x62, 0x72, 0x61, 0x6e, 0x64,
+        0x66, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x65, 0x66, 0x75, 0x73, 0x65, 0x64, 0x01, 0x65,
+        0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x65, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x66, 0x64, 0x65, 0x76,
+        0x69, 0x63, 0x65, 0x66, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x67, 0x70, 0x72, 0x6f, 0x64,
+        0x75, 0x63, 0x74, 0x65, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x68, 0x76, 0x62, 0x5f, 0x73, 0x74,
+        0x61, 0x74, 0x65, 0x65, 0x67, 0x72, 0x65, 0x65, 0x6e, 0x6a, 0x6f, 0x73, 0x5f, 0x76, 0x65,
+        0x72, 0x73, 0x69, 0x6f, 0x6e, 0x62, 0x31, 0x32, 0x6c, 0x6d, 0x61, 0x6e, 0x75, 0x66, 0x61,
+        0x63, 0x74, 0x75, 0x72, 0x65, 0x72, 0x66, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x6d, 0x76,
+        0x62, 0x6d, 0x65, 0x74, 0x61, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x4f, 0x11, 0x22,
+        0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x6e, 0x73,
+        0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x63, 0x74,
+        0x65, 0x65, 0x70, 0x62, 0x6f, 0x6f, 0x74, 0x5f, 0x70, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6c,
+        0x65, 0x76, 0x65, 0x6c, 0x1a, 0x01, 0x34, 0x8c, 0x62, 0x70, 0x62, 0x6f, 0x6f, 0x74, 0x6c,
+        0x6f, 0x61, 0x64, 0x65, 0x72, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x66, 0x6c, 0x6f, 0x63,
+        0x6b, 0x65, 0x64, 0x72, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x70, 0x61, 0x74, 0x63,
+        0x68, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x1a, 0x01, 0x34, 0x8c, 0x61, 0x72, 0x76, 0x65,
+        0x6e, 0x64, 0x6f, 0x72, 0x5f, 0x70, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6c, 0x65, 0x76, 0x65,
+        0x6c, 0x1a, 0x01, 0x34, 0x8c, 0x63, 0x82, 0xa6, 0x01, 0x02, 0x03, 0x26, 0x20, 0x01, 0x21,
+        0x58, 0x20, 0x46, 0xbd, 0xfc, 0xed, 0xa6, 0x94, 0x9a, 0xc4, 0x5e, 0x27, 0xcf, 0x24, 0x25,
+        0xc5, 0x0c, 0x7d, 0xed, 0x8f, 0x21, 0xe0, 0x47, 0x81, 0x5a, 0xdc, 0x3b, 0xd4, 0x9e, 0x13,
+        0xb6, 0x06, 0x36, 0x70, 0x22, 0x58, 0x20, 0x0a, 0xbd, 0xbc, 0x0d, 0x19, 0xba, 0xcc, 0xdc,
+        0x00, 0x64, 0x31, 0x4c, 0x84, 0x66, 0x1d, 0xfb, 0x50, 0xd0, 0xe3, 0xf8, 0x78, 0x9d, 0xf9,
+        0x77, 0x2b, 0x40, 0x6b, 0xb5, 0x8e, 0xd3, 0xf8, 0xa9, 0x23, 0x58, 0x21, 0x00, 0x9c, 0x42,
+        0x3f, 0x79, 0x76, 0xa0, 0xd1, 0x98, 0x58, 0xbb, 0x9b, 0x9e, 0xfb, 0x3b, 0x08, 0xf2, 0xe1,
+        0xa3, 0xfe, 0xf4, 0x21, 0x5b, 0x97, 0x2d, 0xcb, 0x9a, 0x55, 0x1a, 0x7f, 0xa7, 0xc1, 0xa8,
+        0xa6, 0x01, 0x02, 0x03, 0x26, 0x20, 0x01, 0x21, 0x58, 0x20, 0xef, 0xd3, 0x88, 0xc4, 0xbc,
+        0xce, 0x51, 0x4d, 0x4b, 0xd3, 0x81, 0x26, 0xc6, 0xcc, 0x66, 0x3b, 0x12, 0x38, 0xbf, 0x23,
+        0x7a, 0x2e, 0x7f, 0x82, 0xa7, 0x81, 0x74, 0x21, 0xc0, 0x12, 0x79, 0xf4, 0x22, 0x58, 0x20,
+        0xdc, 0x85, 0x6c, 0x1c, 0xcc, 0xf9, 0xf3, 0xe8, 0xff, 0x90, 0xfd, 0x89, 0x03, 0xf5, 0xaf,
+        0x75, 0xa0, 0x79, 0xbb, 0x53, 0x9a, 0x1f, 0x2b, 0x34, 0x86, 0x47, 0x3d, 0x66, 0x2a, 0x07,
+        0x3b, 0x1e, 0x23, 0x58, 0x20, 0x34, 0x7b, 0x15, 0xcc, 0xbf, 0x26, 0xc9, 0x28, 0x0e, 0xee,
+        0xc5, 0x47, 0xac, 0x00, 0xc4, 0x4d, 0x81, 0x2b, 0x1e, 0xac, 0x31, 0xd2, 0x6f, 0x36, 0x85,
+        0xe6, 0xa8, 0xf0, 0x46, 0xfc, 0xd2, 0x83, 0x58, 0x40, 0x55, 0x4c, 0x38, 0xdf, 0xfe, 0x49,
+        0xa8, 0xa0, 0xa5, 0x08, 0xce, 0x2f, 0xe5, 0xf6, 0x6e, 0x2b, 0xc2, 0x95, 0x39, 0xc8, 0xca,
+        0x77, 0xd6, 0xf6, 0x67, 0x24, 0x6b, 0x0e, 0x63, 0x5d, 0x11, 0x97, 0x26, 0x52, 0x30, 0xbc,
+        0x28, 0x1d, 0xbf, 0x2a, 0x3e, 0x8c, 0x90, 0x54, 0xaa, 0xaa, 0xd1, 0x7c, 0x53, 0x7b, 0x48,
+        0x1f, 0x51, 0x50, 0x6c, 0x32, 0xe1, 0x0f, 0x57, 0xea, 0x47, 0x76, 0x85, 0x0c, 0xa1, 0x6b,
+        0x66, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x78, 0x3b, 0x62, 0x72,
+        0x61, 0x6e, 0x64, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x31, 0x2f, 0x64,
+        0x65, 0x76, 0x69, 0x63, 0x65, 0x31, 0x3a, 0x31, 0x31, 0x2f, 0x69, 0x64, 0x2f, 0x32, 0x30,
+        0x32, 0x31, 0x30, 0x38, 0x30, 0x35, 0x2e, 0x34, 0x32, 0x3a, 0x75, 0x73, 0x65, 0x72, 0x2f,
+        0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x2d, 0x6b, 0x65, 0x79, 0x73};
+
 // The challenge that is in kKeysToSignForCsrWithUdsCerts and kCsrWithUdsCerts
 inline const std::vector<uint8_t> kChallenge{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
                                              0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
@@ -328,6 +397,8 @@
         0xa7, 0xb6, 0xc2, 0x40, 0x06, 0x65, 0xc5, 0xff, 0x19, 0xc5, 0xcd, 0x1c, 0xd5, 0x78, 0x01,
         0xd4, 0xb8};
 
+const RpcHardwareInfo kRpcHardwareInfo = {.versionNumber = 3};
+
 inline bool equal_byte_views(const byte_view& view1, const byte_view& view2) {
     return std::equal(view1.begin(), view1.end(), view2.begin(), view2.end());
 }
@@ -557,19 +628,26 @@
                              DEFAULT_INSTANCE_NAME));
 }
 
+TEST(RemoteProvUtils, validateDiceChainProper) {
+    auto result = isCsrWithProperDiceChain(kCsrWithUdsCerts, DEFAULT_INSTANCE_NAME);
+    ASSERT_TRUE(result) << result.message();
+    ASSERT_TRUE(*result) << "DICE Chain is degenerate";
+}
+
+TEST(RemoteProvUtils, validateDiceChainDegenerate) {
+    auto result = isCsrWithProperDiceChain(kCsrWithDegenerateDiceChain, DEFAULT_INSTANCE_NAME);
+    ASSERT_TRUE(result) << result.message();
+    ASSERT_FALSE(*result) << "DICE Chain is proper";
+}
+
 TEST(RemoteProvUtilsTest, requireUdsCertsWhenPresent) {
     auto [keysToSignPtr, _, errMsg] = cppbor::parse(kKeysToSignForCsrWithUdsCerts);
     ASSERT_TRUE(keysToSignPtr) << "Error: " << errMsg;
 
-    auto mockRpc = SharedRefBase::make<MockIRemotelyProvisionedComponent>();
-    EXPECT_CALL(*mockRpc, getHardwareInfo(NotNull())).WillRepeatedly([](RpcHardwareInfo* hwInfo) {
-        hwInfo->versionNumber = 3;
-        return ScopedAStatus::ok();
-    });
-
     const auto keysToSign = keysToSignPtr->asArray();
-    auto csr = verifyFactoryCsr(*keysToSign, kCsrWithUdsCerts, mockRpc.get(), "default", kChallenge,
-                                /*allowDegenerate=*/false, /*requireUdsCerts=*/true);
+    auto csr =
+            verifyFactoryCsr(*keysToSign, kCsrWithUdsCerts, kRpcHardwareInfo, "default", kChallenge,
+                             /*allowDegenerate=*/false, /*requireUdsCerts=*/true);
     ASSERT_TRUE(csr) << csr.message();
 }
 
@@ -577,27 +655,15 @@
     auto [keysToSignPtr, _, errMsg] = cppbor::parse(kKeysToSignForCsrWithUdsCerts);
     ASSERT_TRUE(keysToSignPtr) << "Error: " << errMsg;
 
-    auto mockRpc = SharedRefBase::make<MockIRemotelyProvisionedComponent>();
-    EXPECT_CALL(*mockRpc, getHardwareInfo(NotNull())).WillRepeatedly([](RpcHardwareInfo* hwInfo) {
-        hwInfo->versionNumber = 3;
-        return ScopedAStatus::ok();
-    });
-
     const auto* keysToSign = keysToSignPtr->asArray();
-    auto csr = verifyFactoryCsr(*keysToSign, kCsrWithUdsCerts, mockRpc.get(), DEFAULT_INSTANCE_NAME,
-                                kChallenge,
+    auto csr = verifyFactoryCsr(*keysToSign, kCsrWithUdsCerts, kRpcHardwareInfo,
+                                DEFAULT_INSTANCE_NAME, kChallenge,
                                 /*allowDegenerate=*/false, /*requireUdsCerts=*/false);
     ASSERT_TRUE(csr) << csr.message();
 }
 
 TEST(RemoteProvUtilsTest, requireUdsCertsWhenNotPresent) {
-    auto mockRpc = SharedRefBase::make<MockIRemotelyProvisionedComponent>();
-    EXPECT_CALL(*mockRpc, getHardwareInfo(NotNull())).WillRepeatedly([](RpcHardwareInfo* hwInfo) {
-        hwInfo->versionNumber = 3;
-        return ScopedAStatus::ok();
-    });
-
-    auto csr = verifyFactoryCsr(/*keysToSign=*/Array(), kCsrWithoutUdsCerts, mockRpc.get(),
+    auto csr = verifyFactoryCsr(/*keysToSign=*/Array(), kCsrWithoutUdsCerts, kRpcHardwareInfo,
                                 DEFAULT_INSTANCE_NAME, kChallenge, /*allowDegenerate=*/false,
                                 /*requireUdsCerts=*/true);
     ASSERT_FALSE(csr);
@@ -610,14 +676,8 @@
             kKeysToSignForCsrWithoutUdsCerts.data() + kKeysToSignForCsrWithoutUdsCerts.size());
     ASSERT_TRUE(keysToSignPtr) << "Error: " << errMsg;
 
-    auto mockRpc = SharedRefBase::make<MockIRemotelyProvisionedComponent>();
-    EXPECT_CALL(*mockRpc, getHardwareInfo(NotNull())).WillRepeatedly([](RpcHardwareInfo* hwInfo) {
-        hwInfo->versionNumber = 3;
-        return ScopedAStatus::ok();
-    });
-
     const auto* keysToSign = keysToSignPtr->asArray();
-    auto csr = verifyFactoryCsr(*keysToSign, kCsrWithoutUdsCerts, mockRpc.get(),
+    auto csr = verifyFactoryCsr(*keysToSign, kCsrWithoutUdsCerts, kRpcHardwareInfo,
                                 DEFAULT_INSTANCE_NAME, kChallenge,
                                 /*allowDegenerate=*/false, /*requireUdsCerts=*/false);
     ASSERT_TRUE(csr) << csr.message();
diff --git a/security/rkp/OWNERS b/security/rkp/OWNERS
index 8f854b4..fd43089 100644
--- a/security/rkp/OWNERS
+++ b/security/rkp/OWNERS
@@ -2,3 +2,4 @@
 
 jbires@google.com
 sethmo@google.com
+vikramgaur@google.com
diff --git a/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp b/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
index 8f918af..5467679 100644
--- a/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
+++ b/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
@@ -35,6 +35,7 @@
 #include <remote_prov/remote_prov_utils.h>
 #include <optional>
 #include <set>
+#include <string_view>
 #include <vector>
 
 #include "KeyMintAidlTestBase.h"
@@ -150,22 +151,14 @@
     return corruptChain.encode();
 }
 
-string device_suffix(const string& name) {
-    size_t pos = name.find('/');
-    if (pos == string::npos) {
-        return name;
-    }
-    return name.substr(pos + 1);
-}
-
 bool matching_keymint_device(const string& rp_name, std::shared_ptr<IKeyMintDevice>* keyMint) {
-    string rp_suffix = device_suffix(rp_name);
+    auto rp_suffix = deviceSuffix(rp_name);
 
     vector<string> km_names = ::android::getAidlHalInstanceNames(IKeyMintDevice::descriptor);
     for (const string& km_name : km_names) {
         // If the suffix of the KeyMint instance equals the suffix of the
         // RemotelyProvisionedComponent instance, assume they match.
-        if (device_suffix(km_name) == rp_suffix && AServiceManager_isDeclared(km_name.c_str())) {
+        if (deviceSuffix(km_name) == rp_suffix && AServiceManager_isDeclared(km_name.c_str())) {
             ::ndk::SpAIBinder binder(AServiceManager_waitForService(km_name.c_str()));
             *keyMint = IKeyMintDevice::fromBinder(binder);
             return true;
@@ -489,9 +482,9 @@
                 &protectedData, &keysToSignMac);
         ASSERT_TRUE(status.isOk()) << status.getDescription();
 
-        auto result = verifyProductionProtectedData(
-                deviceInfo, cppbor::Array(), keysToSignMac, protectedData, testEekChain_, eekId_,
-                rpcHardwareInfo.supportedEekCurve, provisionable_.get(), GetParam(), challenge_);
+        auto result = verifyProductionProtectedData(deviceInfo, cppbor::Array(), keysToSignMac,
+                                                    protectedData, testEekChain_, eekId_,
+                                                    rpcHardwareInfo, GetParam(), challenge_);
         ASSERT_TRUE(result) << result.message();
     }
 }
@@ -516,8 +509,7 @@
 
     auto firstBcc = verifyProductionProtectedData(deviceInfo, /*keysToSign=*/cppbor::Array(),
                                                   keysToSignMac, protectedData, testEekChain_,
-                                                  eekId_, rpcHardwareInfo.supportedEekCurve,
-                                                  provisionable_.get(), GetParam(), challenge_);
+                                                  eekId_, rpcHardwareInfo, GetParam(), challenge_);
     ASSERT_TRUE(firstBcc) << firstBcc.message();
 
     status = provisionable_->generateCertificateRequest(
@@ -527,8 +519,7 @@
 
     auto secondBcc = verifyProductionProtectedData(deviceInfo, /*keysToSign=*/cppbor::Array(),
                                                    keysToSignMac, protectedData, testEekChain_,
-                                                   eekId_, rpcHardwareInfo.supportedEekCurve,
-                                                   provisionable_.get(), GetParam(), challenge_);
+                                                   eekId_, rpcHardwareInfo, GetParam(), challenge_);
     ASSERT_TRUE(secondBcc) << secondBcc.message();
 
     // Verify that none of the keys in the first BCC are repeated in the second one.
@@ -576,9 +567,9 @@
                 &keysToSignMac);
         ASSERT_TRUE(status.isOk()) << status.getDescription();
 
-        auto result = verifyProductionProtectedData(
-                deviceInfo, cborKeysToSign_, keysToSignMac, protectedData, testEekChain_, eekId_,
-                rpcHardwareInfo.supportedEekCurve, provisionable_.get(), GetParam(), challenge_);
+        auto result = verifyProductionProtectedData(deviceInfo, cborKeysToSign_, keysToSignMac,
+                                                    protectedData, testEekChain_, eekId_,
+                                                    rpcHardwareInfo, GetParam(), challenge_);
         ASSERT_TRUE(result) << result.message();
     }
 }
@@ -766,7 +757,7 @@
                 provisionable_->generateCertificateRequestV2({} /* keysToSign */, challenge, &csr);
         ASSERT_TRUE(status.isOk()) << status.getDescription();
 
-        auto result = verifyProductionCsr(cppbor::Array(), csr, provisionable_.get(), GetParam(),
+        auto result = verifyProductionCsr(cppbor::Array(), csr, rpcHardwareInfo, GetParam(),
                                           challenge, isRkpVmInstance_);
         ASSERT_TRUE(result) << result.message();
     }
@@ -788,7 +779,7 @@
         auto status = provisionable_->generateCertificateRequestV2(keysToSign_, challenge, &csr);
         ASSERT_TRUE(status.isOk()) << status.getDescription();
 
-        auto result = verifyProductionCsr(cborKeysToSign_, csr, provisionable_.get(), GetParam(),
+        auto result = verifyProductionCsr(cborKeysToSign_, csr, rpcHardwareInfo, GetParam(),
                                           challenge, isRkpVmInstance_);
         ASSERT_TRUE(result) << result.message();
     }
@@ -819,14 +810,14 @@
     auto status = provisionable_->generateCertificateRequestV2(keysToSign_, challenge_, &csr);
     ASSERT_TRUE(status.isOk()) << status.getDescription();
 
-    auto firstCsr = verifyProductionCsr(cborKeysToSign_, csr, provisionable_.get(), GetParam(),
+    auto firstCsr = verifyProductionCsr(cborKeysToSign_, csr, rpcHardwareInfo, GetParam(),
                                         challenge_, isRkpVmInstance_);
     ASSERT_TRUE(firstCsr) << firstCsr.message();
 
     status = provisionable_->generateCertificateRequestV2(keysToSign_, challenge_, &csr);
     ASSERT_TRUE(status.isOk()) << status.getDescription();
 
-    auto secondCsr = verifyProductionCsr(cborKeysToSign_, csr, provisionable_.get(), GetParam(),
+    auto secondCsr = verifyProductionCsr(cborKeysToSign_, csr, rpcHardwareInfo, GetParam(),
                                          challenge_, isRkpVmInstance_);
     ASSERT_TRUE(secondCsr) << secondCsr.message();
 
@@ -845,8 +836,8 @@
     auto status = provisionable_->generateCertificateRequestV2(keysToSign_, challenge_, &csr);
     ASSERT_TRUE(status.isOk()) << status.getDescription();
 
-    auto result = verifyProductionCsr(cborKeysToSign_, csr, provisionable_.get(), GetParam(),
-                                      challenge_, isRkpVmInstance_);
+    auto result = verifyProductionCsr(cborKeysToSign_, csr, rpcHardwareInfo, GetParam(), challenge_,
+                                      isRkpVmInstance_);
     ASSERT_TRUE(result) << result.message();
 }
 
@@ -977,7 +968,7 @@
     ASSERT_TRUE(irpcStatus.isOk()) << irpcStatus.getDescription();
 
     auto result =
-            verifyProductionCsr(cppbor::Array(), csr, provisionable_.get(), GetParam(), challenge_);
+            verifyProductionCsr(cppbor::Array(), csr, rpcHardwareInfo, GetParam(), challenge_);
     ASSERT_TRUE(result) << result.message();
 
     std::unique_ptr<cppbor::Array> csrPayload = std::move(*result);
@@ -1002,7 +993,7 @@
     ASSERT_TRUE(bootPatchLevel);
     ASSERT_TRUE(securityLevel);
 
-    auto kmDeviceName = device_suffix(GetParam());
+    auto kmDeviceName = deviceSuffix(GetParam());
 
     // Compare DeviceInfo against IDs attested by KeyMint.
     ASSERT_TRUE((securityLevel->value() == "tee" && kmDeviceName == "default") ||
diff --git a/usb/1.0/vts/functional/Android.bp b/usb/1.0/vts/functional/Android.bp
index d976a06..09bbeec 100644
--- a/usb/1.0/vts/functional/Android.bp
+++ b/usb/1.0/vts/functional/Android.bp
@@ -15,6 +15,7 @@
 //
 
 package {
+    default_team: "trendy_team_android_usb",
     // See: http://go/android-license-faq
     // A large-scale-change added 'default_applicable_licenses' to import
     // all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/usb/1.1/vts/functional/Android.bp b/usb/1.1/vts/functional/Android.bp
index f514009..48e36f0 100644
--- a/usb/1.1/vts/functional/Android.bp
+++ b/usb/1.1/vts/functional/Android.bp
@@ -15,6 +15,7 @@
 //
 
 package {
+    default_team: "trendy_team_android_usb",
     // See: http://go/android-license-faq
     // A large-scale-change added 'default_applicable_licenses' to import
     // all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/usb/1.2/vts/functional/Android.bp b/usb/1.2/vts/functional/Android.bp
index 688e725..62442be 100644
--- a/usb/1.2/vts/functional/Android.bp
+++ b/usb/1.2/vts/functional/Android.bp
@@ -15,6 +15,7 @@
 //
 
 package {
+    default_team: "trendy_team_android_usb",
     // See: http://go/android-license-faq
     // A large-scale-change added 'default_applicable_licenses' to import
     // all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/usb/1.3/vts/functional/Android.bp b/usb/1.3/vts/functional/Android.bp
index 6a1ce1e..a345128 100644
--- a/usb/1.3/vts/functional/Android.bp
+++ b/usb/1.3/vts/functional/Android.bp
@@ -15,6 +15,7 @@
 //
 
 package {
+    default_team: "trendy_team_android_usb",
     // See: http://go/android-license-faq
     // A large-scale-change added 'default_applicable_licenses' to import
     // all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/usb/OWNERS b/usb/OWNERS
index 3611b4d..647d626 100644
--- a/usb/OWNERS
+++ b/usb/OWNERS
@@ -1,8 +1,8 @@
 # Bug component: 175220
 
-aprasath@google.com
-kumarashishg@google.com
-sarup@google.com
 anothermark@google.com
+febinthattil@google.com
+aprasath@google.com
 albertccwang@google.com
 badhri@google.com
+kumarashishg@google.com
\ No newline at end of file
diff --git a/usb/aidl/vts/Android.bp b/usb/aidl/vts/Android.bp
index cf9299e..d41116a 100644
--- a/usb/aidl/vts/Android.bp
+++ b/usb/aidl/vts/Android.bp
@@ -15,6 +15,7 @@
 //
 
 package {
+    default_team: "trendy_team_android_usb",
     // See: http://go/android-license-faq
     // A large-scale-change added 'default_applicable_licenses' to import
     // all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl
index 09cdc26..d0f1ed9 100644
--- a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl
@@ -36,6 +36,7 @@
 enum UwbVendorCapabilityTlvTypes {
   SUPPORTED_POWER_STATS_QUERY = 0xC0,
   SUPPORTED_ANTENNA_MODES = 0xC1,
+  SUPPORTED_MAX_SESSION_COUNT = 0xEB,
   CCC_SUPPORTED_CHAPS_PER_SLOT = 0xA0,
   CCC_SUPPORTED_SYNC_CODES = 0xA1,
   CCC_SUPPORTED_HOPPING_CONFIG_MODES_AND_SEQUENCES = 0xA2,
diff --git a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl
index 28e44ef..2d81ed2 100644
--- a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl
+++ b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl
@@ -48,6 +48,11 @@
      */
     SUPPORTED_ANTENNA_MODES = 0xC1,
 
+    /**
+     * Int value to indicate max supported session count
+     */
+    SUPPORTED_MAX_SESSION_COUNT = 0xEB,
+
     /*********************************************
      * CCC specific
      ********************************************/
diff --git a/wifi/aidl/default/aidl_callback_util.h b/wifi/aidl/default/aidl_callback_util.h
index f8ba53b..2419db9 100644
--- a/wifi/aidl/default/aidl_callback_util.h
+++ b/wifi/aidl/default/aidl_callback_util.h
@@ -45,6 +45,11 @@
     ~AidlCallbackHandler() { invalidate(); }
 
     bool addCallback(const std::shared_ptr<CallbackType>& cb) {
+        if (cb == nullptr) {
+            LOG(ERROR) << "Unable to register a null callback";
+            return false;
+        }
+
         std::unique_lock<std::mutex> lk(callback_handler_lock_);
         void* cbPtr = reinterpret_cast<void*>(cb->asBinder().get());
         const auto& cbPosition = findCbInSet(cbPtr);
diff --git a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/NetworkParams.aidl b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/NetworkParams.aidl
index 4554223..b6c5cf2 100644
--- a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/NetworkParams.aidl
+++ b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/NetworkParams.aidl
@@ -40,4 +40,5 @@
   String passphrase;
   boolean isMetered;
   byte[] vendorElements;
+  boolean isClientIsolationEnabled;
 }
diff --git a/wifi/hostapd/aidl/android/hardware/wifi/hostapd/NetworkParams.aidl b/wifi/hostapd/aidl/android/hardware/wifi/hostapd/NetworkParams.aidl
index 47d9e6f..acc2cad 100644
--- a/wifi/hostapd/aidl/android/hardware/wifi/hostapd/NetworkParams.aidl
+++ b/wifi/hostapd/aidl/android/hardware/wifi/hostapd/NetworkParams.aidl
@@ -52,4 +52,8 @@
      * one or more elements). Example: byte[]{ 221, 4, 17, 34, 51, 1 }
      */
     byte[] vendorElements;
+    /**
+     * Whether the network uses client isolation.
+     */
+    boolean isClientIsolationEnabled;
 }
diff --git a/wifi/hostapd/aidl/lint-baseline.xml b/wifi/hostapd/aidl/lint-baseline.xml
index 4329e12..23fe690 100644
--- a/wifi/hostapd/aidl/lint-baseline.xml
+++ b/wifi/hostapd/aidl/lint-baseline.xml
@@ -63,4 +63,22 @@
             file="out/soong/.intermediates/hardware/interfaces/wifi/hostapd/aidl/android.hardware.wifi.hostapd-V3-java-source/gen/android/hardware/wifi/hostapd/IHostapdCallback.java"/>
     </issue>
 
-</issues>
\ No newline at end of file
+    <issue
+        id="NewApi"
+        message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+        errorLine1="      this.markVintfStability();"
+        errorLine2="           ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/hardware/interfaces/wifi/hostapd/aidl/android.hardware.wifi.hostapd-V4-java-source/gen/android/hardware/wifi/hostapd/IHostapd.java"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+        errorLine1="      this.markVintfStability();"
+        errorLine2="           ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/hardware/interfaces/wifi/hostapd/aidl/android.hardware.wifi.hostapd-V4-java-source/gen/android/hardware/wifi/hostapd/IHostapdCallback.java"/>
+    </issue>
+
+</issues>