Merge "Make 'IHalAdapterVendorExtension' unstable again" into main
diff --git a/media/audioaidlconversion/AidlConversionCppNdk.cpp b/media/audioaidlconversion/AidlConversionCppNdk.cpp
index 40d5f5f..0682f65 100644
--- a/media/audioaidlconversion/AidlConversionCppNdk.cpp
+++ b/media/audioaidlconversion/AidlConversionCppNdk.cpp
@@ -76,8 +76,6 @@
 using media::audio::common::AudioOffloadInfo;
 using media::audio::common::AudioOutputFlags;
 using media::audio::common::AudioPlaybackRate;
-using media::audio::common::AudioPolicyForcedConfig;
-using media::audio::common::AudioPolicyForceUse;
 using media::audio::common::AudioPort;
 using media::audio::common::AudioPortConfig;
 using media::audio::common::AudioPortDeviceExt;
@@ -3322,138 +3320,6 @@
     return OK;
 }
 
-ConversionResult<audio_policy_force_use_t>
-aidl2legacy_AudioPolicyForceUse_audio_policy_force_use_t(AudioPolicyForceUse aidl) {
-    switch (aidl) {
-        case AudioPolicyForceUse::COMMUNICATION:
-            return AUDIO_POLICY_FORCE_FOR_COMMUNICATION;
-        case AudioPolicyForceUse::MEDIA:
-            return AUDIO_POLICY_FORCE_FOR_MEDIA;
-        case AudioPolicyForceUse::RECORD:
-            return AUDIO_POLICY_FORCE_FOR_RECORD;
-        case AudioPolicyForceUse::DOCK:
-            return AUDIO_POLICY_FORCE_FOR_DOCK;
-        case AudioPolicyForceUse::SYSTEM:
-            return AUDIO_POLICY_FORCE_FOR_SYSTEM;
-        case AudioPolicyForceUse::HDMI_SYSTEM_AUDIO:
-            return AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO;
-        case AudioPolicyForceUse::ENCODED_SURROUND:
-            return AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND;
-        case AudioPolicyForceUse::VIBRATE_RINGING:
-            return AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING;
-    }
-    return unexpected(BAD_VALUE);
-}
-
-ConversionResult<AudioPolicyForceUse>
-legacy2aidl_audio_policy_force_use_t_AudioPolicyForceUse(audio_policy_force_use_t legacy) {
-    switch (legacy) {
-        case AUDIO_POLICY_FORCE_FOR_COMMUNICATION:
-            return AudioPolicyForceUse::COMMUNICATION;
-        case AUDIO_POLICY_FORCE_FOR_MEDIA:
-            return AudioPolicyForceUse::MEDIA;
-        case AUDIO_POLICY_FORCE_FOR_RECORD:
-            return AudioPolicyForceUse::RECORD;
-        case AUDIO_POLICY_FORCE_FOR_DOCK:
-            return AudioPolicyForceUse::DOCK;
-        case AUDIO_POLICY_FORCE_FOR_SYSTEM:
-            return AudioPolicyForceUse::SYSTEM;
-        case AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO:
-            return AudioPolicyForceUse::HDMI_SYSTEM_AUDIO;
-        case AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND:
-            return AudioPolicyForceUse::ENCODED_SURROUND;
-        case AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING:
-            return AudioPolicyForceUse::VIBRATE_RINGING;
-        case AUDIO_POLICY_FORCE_USE_CNT:
-            break;
-    }
-    return unexpected(BAD_VALUE);
-}
-
-ConversionResult<audio_policy_forced_cfg_t>
-aidl2legacy_AudioPolicyForcedConfig_audio_policy_forced_cfg_t(AudioPolicyForcedConfig aidl) {
-    switch (aidl) {
-        case AudioPolicyForcedConfig::NONE:
-            return AUDIO_POLICY_FORCE_NONE;
-        case AudioPolicyForcedConfig::SPEAKER:
-            return AUDIO_POLICY_FORCE_SPEAKER;
-        case AudioPolicyForcedConfig::HEADPHONES:
-            return AUDIO_POLICY_FORCE_HEADPHONES;
-        case AudioPolicyForcedConfig::BT_SCO:
-            return AUDIO_POLICY_FORCE_BT_SCO;
-        case AudioPolicyForcedConfig::BT_A2DP:
-            return AUDIO_POLICY_FORCE_BT_A2DP;
-        case AudioPolicyForcedConfig::WIRED_ACCESSORY:
-            return AUDIO_POLICY_FORCE_WIRED_ACCESSORY;
-        case AudioPolicyForcedConfig::BT_CAR_DOCK:
-            return AUDIO_POLICY_FORCE_BT_CAR_DOCK;
-        case AudioPolicyForcedConfig::BT_DESK_DOCK:
-            return AUDIO_POLICY_FORCE_BT_DESK_DOCK;
-        case AudioPolicyForcedConfig::ANALOG_DOCK:
-            return AUDIO_POLICY_FORCE_ANALOG_DOCK;
-        case AudioPolicyForcedConfig::DIGITAL_DOCK:
-            return AUDIO_POLICY_FORCE_DIGITAL_DOCK;
-        case AudioPolicyForcedConfig::NO_BT_A2DP:
-            return AUDIO_POLICY_FORCE_NO_BT_A2DP;
-        case AudioPolicyForcedConfig::SYSTEM_ENFORCED:
-            return AUDIO_POLICY_FORCE_SYSTEM_ENFORCED;
-        case AudioPolicyForcedConfig::HDMI_SYSTEM_AUDIO_ENFORCED:
-            return AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED;
-        case AudioPolicyForcedConfig::ENCODED_SURROUND_NEVER:
-            return AUDIO_POLICY_FORCE_ENCODED_SURROUND_NEVER;
-        case AudioPolicyForcedConfig::ENCODED_SURROUND_ALWAYS:
-            return AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS;
-        case AudioPolicyForcedConfig::ENCODED_SURROUND_MANUAL:
-            return AUDIO_POLICY_FORCE_ENCODED_SURROUND_MANUAL;
-        case AudioPolicyForcedConfig::BT_BLE:
-            return AUDIO_POLICY_FORCE_BT_BLE;
-    }
-    return unexpected(BAD_VALUE);
-}
-
-ConversionResult<AudioPolicyForcedConfig>
-legacy2aidl_audio_policy_forced_cfg_t_AudioPolicyForcedConfig(audio_policy_forced_cfg_t legacy) {
-    switch (legacy) {
-        case AUDIO_POLICY_FORCE_NONE:
-            return AudioPolicyForcedConfig::NONE;
-        case AUDIO_POLICY_FORCE_SPEAKER:
-            return AudioPolicyForcedConfig::SPEAKER;
-        case AUDIO_POLICY_FORCE_HEADPHONES:
-            return AudioPolicyForcedConfig::HEADPHONES;
-        case AUDIO_POLICY_FORCE_BT_SCO:
-            return AudioPolicyForcedConfig::BT_SCO;
-        case AUDIO_POLICY_FORCE_BT_A2DP:
-            return AudioPolicyForcedConfig::BT_A2DP;
-        case AUDIO_POLICY_FORCE_WIRED_ACCESSORY:
-            return AudioPolicyForcedConfig::WIRED_ACCESSORY;
-        case AUDIO_POLICY_FORCE_BT_CAR_DOCK:
-            return AudioPolicyForcedConfig::BT_CAR_DOCK;
-        case AUDIO_POLICY_FORCE_BT_DESK_DOCK:
-            return AudioPolicyForcedConfig::BT_DESK_DOCK;
-        case AUDIO_POLICY_FORCE_ANALOG_DOCK:
-            return AudioPolicyForcedConfig::ANALOG_DOCK;
-        case AUDIO_POLICY_FORCE_DIGITAL_DOCK:
-            return AudioPolicyForcedConfig::DIGITAL_DOCK;
-        case AUDIO_POLICY_FORCE_NO_BT_A2DP:
-            return AudioPolicyForcedConfig::NO_BT_A2DP;
-        case AUDIO_POLICY_FORCE_SYSTEM_ENFORCED:
-            return AudioPolicyForcedConfig::SYSTEM_ENFORCED;
-        case AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED:
-            return AudioPolicyForcedConfig::HDMI_SYSTEM_AUDIO_ENFORCED;
-        case AUDIO_POLICY_FORCE_ENCODED_SURROUND_NEVER:
-            return AudioPolicyForcedConfig::ENCODED_SURROUND_NEVER;
-        case AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS:
-            return AudioPolicyForcedConfig::ENCODED_SURROUND_ALWAYS;
-        case AUDIO_POLICY_FORCE_ENCODED_SURROUND_MANUAL:
-            return AudioPolicyForcedConfig::ENCODED_SURROUND_MANUAL;
-        case AUDIO_POLICY_FORCE_BT_BLE:
-            return AudioPolicyForcedConfig::BT_BLE;
-        case AUDIO_POLICY_FORCE_CFG_CNT:
-            break;
-    }
-    return unexpected(BAD_VALUE);
-}
-
 }  // namespace android
 
 #undef GET_DEVICE_DESC_CONNECTION
diff --git a/media/audioaidlconversion/include/media/AidlConversionCppNdk-impl.h b/media/audioaidlconversion/include/media/AidlConversionCppNdk-impl.h
index 9dfb7e7..7268464 100644
--- a/media/audioaidlconversion/include/media/AidlConversionCppNdk-impl.h
+++ b/media/audioaidlconversion/include/media/AidlConversionCppNdk-impl.h
@@ -58,8 +58,6 @@
 #include PREFIX(android/media/audio/common/AudioMode.h)
 #include PREFIX(android/media/audio/common/AudioOffloadInfo.h)
 #include PREFIX(android/media/audio/common/AudioOutputFlags.h)
-#include PREFIX(android/media/audio/common/AudioPolicyForceUse.h)
-#include PREFIX(android/media/audio/common/AudioPolicyForcedConfig.h)
 #include PREFIX(android/media/audio/common/AudioPort.h)
 #include PREFIX(android/media/audio/common/AudioPortConfig.h)
 #include PREFIX(android/media/audio/common/AudioPortExt.h)
@@ -78,7 +76,6 @@
 
 #include <system/audio.h>
 #include <system/audio_effect.h>
-#include <system/audio_policy.h>
 
 #if defined(BACKEND_NDK_IMPL)
 namespace aidl {
@@ -457,18 +454,6 @@
         media::audio::common::MicrophoneInfo* aidlInfo,
         media::audio::common::MicrophoneDynamicInfo* aidlDynamic);
 
-ConversionResult<audio_policy_forced_cfg_t>
-aidl2legacy_AudioPolicyForcedConfig_audio_policy_forced_cfg_t(
-        media::audio::common::AudioPolicyForcedConfig aidl);
-ConversionResult<media::audio::common::AudioPolicyForcedConfig>
-legacy2aidl_audio_policy_forced_cfg_t_AudioPolicyForcedConfig(audio_policy_forced_cfg_t legacy);
-
-ConversionResult<audio_policy_force_use_t>
-aidl2legacy_AudioPolicyForceUse_audio_policy_force_use_t(
-        media::audio::common::AudioPolicyForceUse aidl);
-ConversionResult<media::audio::common::AudioPolicyForceUse>
-legacy2aidl_audio_policy_force_use_t_AudioPolicyForceUse(audio_policy_force_use_t legacy);
-
 }  // namespace android
 
 #if defined(BACKEND_NDK_IMPL)
diff --git a/media/libaudioclient/Android.bp b/media/libaudioclient/Android.bp
index 61204ae..6dfb327 100644
--- a/media/libaudioclient/Android.bp
+++ b/media/libaudioclient/Android.bp
@@ -359,6 +359,8 @@
         "aidl/android/media/AudioMixerBehavior.aidl",
         "aidl/android/media/AudioOffloadMode.aidl",
         "aidl/android/media/AudioPolicyDeviceState.aidl",
+        "aidl/android/media/AudioPolicyForceUse.aidl",
+        "aidl/android/media/AudioPolicyForcedConfig.aidl",
         "aidl/android/media/AudioProductStrategy.aidl",
         "aidl/android/media/AudioVolumeGroup.aidl",
         "aidl/android/media/DeviceRole.aidl",
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index 85f4a86..3f4fcfd 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -60,8 +60,6 @@
 using media::audio::common::AudioMMapPolicyInfo;
 using media::audio::common::AudioMMapPolicyType;
 using media::audio::common::AudioOffloadInfo;
-using media::audio::common::AudioPolicyForceUse;
-using media::audio::common::AudioPolicyForcedConfig;
 using media::audio::common::AudioSource;
 using media::audio::common::AudioStreamType;
 using media::audio::common::AudioUsage;
@@ -1061,9 +1059,9 @@
     if (aps == 0) return AUDIO_POLICY_FORCE_NONE;
 
     auto result = [&]() -> ConversionResult<audio_policy_forced_cfg_t> {
-        AudioPolicyForceUse usageAidl = VALUE_OR_RETURN(
+        media::AudioPolicyForceUse usageAidl = VALUE_OR_RETURN(
                 legacy2aidl_audio_policy_force_use_t_AudioPolicyForceUse(usage));
-        AudioPolicyForcedConfig configAidl;
+        media::AudioPolicyForcedConfig configAidl;
         RETURN_IF_ERROR(statusTFromBinderStatus(
                 aps->getForceUse(usageAidl, &configAidl)));
         return aidl2legacy_AudioPolicyForcedConfig_audio_policy_forced_cfg_t(configAidl);
diff --git a/media/libaudioclient/PolicyAidlConversion.cpp b/media/libaudioclient/PolicyAidlConversion.cpp
index a414cb7..163a359 100644
--- a/media/libaudioclient/PolicyAidlConversion.cpp
+++ b/media/libaudioclient/PolicyAidlConversion.cpp
@@ -296,6 +296,138 @@
     return unexpected(BAD_VALUE);
 }
 
+ConversionResult<audio_policy_force_use_t>
+aidl2legacy_AudioPolicyForceUse_audio_policy_force_use_t(media::AudioPolicyForceUse aidl) {
+    switch (aidl) {
+        case media::AudioPolicyForceUse::COMMUNICATION:
+            return AUDIO_POLICY_FORCE_FOR_COMMUNICATION;
+        case media::AudioPolicyForceUse::MEDIA:
+            return AUDIO_POLICY_FORCE_FOR_MEDIA;
+        case media::AudioPolicyForceUse::RECORD:
+            return AUDIO_POLICY_FORCE_FOR_RECORD;
+        case media::AudioPolicyForceUse::DOCK:
+            return AUDIO_POLICY_FORCE_FOR_DOCK;
+        case media::AudioPolicyForceUse::SYSTEM:
+            return AUDIO_POLICY_FORCE_FOR_SYSTEM;
+        case media::AudioPolicyForceUse::HDMI_SYSTEM_AUDIO:
+            return AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO;
+        case media::AudioPolicyForceUse::ENCODED_SURROUND:
+            return AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND;
+        case media::AudioPolicyForceUse::VIBRATE_RINGING:
+            return AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING;
+    }
+    return unexpected(BAD_VALUE);
+}
+
+ConversionResult<media::AudioPolicyForceUse>
+legacy2aidl_audio_policy_force_use_t_AudioPolicyForceUse(audio_policy_force_use_t legacy) {
+    switch (legacy) {
+        case AUDIO_POLICY_FORCE_FOR_COMMUNICATION:
+            return media::AudioPolicyForceUse::COMMUNICATION;
+        case AUDIO_POLICY_FORCE_FOR_MEDIA:
+            return media::AudioPolicyForceUse::MEDIA;
+        case AUDIO_POLICY_FORCE_FOR_RECORD:
+            return media::AudioPolicyForceUse::RECORD;
+        case AUDIO_POLICY_FORCE_FOR_DOCK:
+            return media::AudioPolicyForceUse::DOCK;
+        case AUDIO_POLICY_FORCE_FOR_SYSTEM:
+            return media::AudioPolicyForceUse::SYSTEM;
+        case AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO:
+            return media::AudioPolicyForceUse::HDMI_SYSTEM_AUDIO;
+        case AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND:
+            return media::AudioPolicyForceUse::ENCODED_SURROUND;
+        case AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING:
+            return media::AudioPolicyForceUse::VIBRATE_RINGING;
+        case AUDIO_POLICY_FORCE_USE_CNT:
+            break;
+    }
+    return unexpected(BAD_VALUE);
+}
+
+ConversionResult<audio_policy_forced_cfg_t>
+aidl2legacy_AudioPolicyForcedConfig_audio_policy_forced_cfg_t(media::AudioPolicyForcedConfig aidl) {
+    switch (aidl) {
+        case media::AudioPolicyForcedConfig::NONE:
+            return AUDIO_POLICY_FORCE_NONE;
+        case media::AudioPolicyForcedConfig::SPEAKER:
+            return AUDIO_POLICY_FORCE_SPEAKER;
+        case media::AudioPolicyForcedConfig::HEADPHONES:
+            return AUDIO_POLICY_FORCE_HEADPHONES;
+        case media::AudioPolicyForcedConfig::BT_SCO:
+            return AUDIO_POLICY_FORCE_BT_SCO;
+        case media::AudioPolicyForcedConfig::BT_A2DP:
+            return AUDIO_POLICY_FORCE_BT_A2DP;
+        case media::AudioPolicyForcedConfig::WIRED_ACCESSORY:
+            return AUDIO_POLICY_FORCE_WIRED_ACCESSORY;
+        case media::AudioPolicyForcedConfig::BT_CAR_DOCK:
+            return AUDIO_POLICY_FORCE_BT_CAR_DOCK;
+        case media::AudioPolicyForcedConfig::BT_DESK_DOCK:
+            return AUDIO_POLICY_FORCE_BT_DESK_DOCK;
+        case media::AudioPolicyForcedConfig::ANALOG_DOCK:
+            return AUDIO_POLICY_FORCE_ANALOG_DOCK;
+        case media::AudioPolicyForcedConfig::DIGITAL_DOCK:
+            return AUDIO_POLICY_FORCE_DIGITAL_DOCK;
+        case media::AudioPolicyForcedConfig::NO_BT_A2DP:
+            return AUDIO_POLICY_FORCE_NO_BT_A2DP;
+        case media::AudioPolicyForcedConfig::SYSTEM_ENFORCED:
+            return AUDIO_POLICY_FORCE_SYSTEM_ENFORCED;
+        case media::AudioPolicyForcedConfig::HDMI_SYSTEM_AUDIO_ENFORCED:
+            return AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED;
+        case media::AudioPolicyForcedConfig::ENCODED_SURROUND_NEVER:
+            return AUDIO_POLICY_FORCE_ENCODED_SURROUND_NEVER;
+        case media::AudioPolicyForcedConfig::ENCODED_SURROUND_ALWAYS:
+            return AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS;
+        case media::AudioPolicyForcedConfig::ENCODED_SURROUND_MANUAL:
+            return AUDIO_POLICY_FORCE_ENCODED_SURROUND_MANUAL;
+        case media::AudioPolicyForcedConfig::BT_BLE:
+            return AUDIO_POLICY_FORCE_BT_BLE;
+    }
+    return unexpected(BAD_VALUE);
+}
+
+ConversionResult<media::AudioPolicyForcedConfig>
+legacy2aidl_audio_policy_forced_cfg_t_AudioPolicyForcedConfig(audio_policy_forced_cfg_t legacy) {
+    switch (legacy) {
+        case AUDIO_POLICY_FORCE_NONE:
+            return media::AudioPolicyForcedConfig::NONE;
+        case AUDIO_POLICY_FORCE_SPEAKER:
+            return media::AudioPolicyForcedConfig::SPEAKER;
+        case AUDIO_POLICY_FORCE_HEADPHONES:
+            return media::AudioPolicyForcedConfig::HEADPHONES;
+        case AUDIO_POLICY_FORCE_BT_SCO:
+            return media::AudioPolicyForcedConfig::BT_SCO;
+        case AUDIO_POLICY_FORCE_BT_A2DP:
+            return media::AudioPolicyForcedConfig::BT_A2DP;
+        case AUDIO_POLICY_FORCE_WIRED_ACCESSORY:
+            return media::AudioPolicyForcedConfig::WIRED_ACCESSORY;
+        case AUDIO_POLICY_FORCE_BT_CAR_DOCK:
+            return media::AudioPolicyForcedConfig::BT_CAR_DOCK;
+        case AUDIO_POLICY_FORCE_BT_DESK_DOCK:
+            return media::AudioPolicyForcedConfig::BT_DESK_DOCK;
+        case AUDIO_POLICY_FORCE_ANALOG_DOCK:
+            return media::AudioPolicyForcedConfig::ANALOG_DOCK;
+        case AUDIO_POLICY_FORCE_DIGITAL_DOCK:
+            return media::AudioPolicyForcedConfig::DIGITAL_DOCK;
+        case AUDIO_POLICY_FORCE_NO_BT_A2DP:
+            return media::AudioPolicyForcedConfig::NO_BT_A2DP;
+        case AUDIO_POLICY_FORCE_SYSTEM_ENFORCED:
+            return media::AudioPolicyForcedConfig::SYSTEM_ENFORCED;
+        case AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED:
+            return media::AudioPolicyForcedConfig::HDMI_SYSTEM_AUDIO_ENFORCED;
+        case AUDIO_POLICY_FORCE_ENCODED_SURROUND_NEVER:
+            return media::AudioPolicyForcedConfig::ENCODED_SURROUND_NEVER;
+        case AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS:
+            return media::AudioPolicyForcedConfig::ENCODED_SURROUND_ALWAYS;
+        case AUDIO_POLICY_FORCE_ENCODED_SURROUND_MANUAL:
+            return media::AudioPolicyForcedConfig::ENCODED_SURROUND_MANUAL;
+        case AUDIO_POLICY_FORCE_BT_BLE:
+            return media::AudioPolicyForcedConfig::BT_BLE;
+        case AUDIO_POLICY_FORCE_CFG_CNT:
+            break;
+    }
+    return unexpected(BAD_VALUE);
+}
+
 ConversionResult<device_role_t>
 aidl2legacy_DeviceRole_device_role_t(media::DeviceRole aidl) {
     switch (aidl) {
diff --git a/media/libaudioclient/aidl/android/media/AudioPolicyForceUse.aidl b/media/libaudioclient/aidl/android/media/AudioPolicyForceUse.aidl
new file mode 100644
index 0000000..9bb0605
--- /dev/null
+++ b/media/libaudioclient/aidl/android/media/AudioPolicyForceUse.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 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.
+ */
+package android.media;
+
+/**
+ * {@hide}
+ */
+@Backing(type="int")
+enum AudioPolicyForceUse {
+    COMMUNICATION = 0,
+    MEDIA = 1,
+    RECORD = 2,
+    DOCK = 3,
+    SYSTEM = 4,
+    HDMI_SYSTEM_AUDIO = 5,
+    ENCODED_SURROUND = 6,
+    VIBRATE_RINGING = 7,
+}
diff --git a/media/libaudioclient/aidl/android/media/AudioPolicyForcedConfig.aidl b/media/libaudioclient/aidl/android/media/AudioPolicyForcedConfig.aidl
new file mode 100644
index 0000000..111bb2f
--- /dev/null
+++ b/media/libaudioclient/aidl/android/media/AudioPolicyForcedConfig.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 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.
+ */
+package android.media;
+
+/**
+ * {@hide}
+ */
+@Backing(type="int")
+enum AudioPolicyForcedConfig {
+    NONE = 0,
+    SPEAKER = 1,
+    HEADPHONES = 2,
+    BT_SCO = 3,
+    BT_A2DP = 4,
+    WIRED_ACCESSORY = 5,
+    BT_CAR_DOCK = 6,
+    BT_DESK_DOCK = 7,
+    ANALOG_DOCK = 8,
+    DIGITAL_DOCK = 9,
+    NO_BT_A2DP = 10, /* A2DP sink is not preferred to speaker or wired HS */
+    SYSTEM_ENFORCED = 11,
+    HDMI_SYSTEM_AUDIO_ENFORCED = 12,
+    ENCODED_SURROUND_NEVER = 13,
+    ENCODED_SURROUND_ALWAYS = 14,
+    ENCODED_SURROUND_MANUAL = 15,
+    BT_BLE = 16,
+}
diff --git a/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl b/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl
index 7f5e8e2..ac42ea9 100644
--- a/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl
+++ b/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl
@@ -25,6 +25,8 @@
 import android.media.AudioOffloadMode;
 import android.media.AudioPatchFw;
 import android.media.AudioPolicyDeviceState;
+import android.media.AudioPolicyForcedConfig;
+import android.media.AudioPolicyForceUse;
 import android.media.AudioPortFw;
 import android.media.AudioPortConfigFw;
 import android.media.AudioPortRole;
@@ -47,8 +49,6 @@
 import android.media.audio.common.AudioDeviceDescription;
 import android.media.audio.common.AudioFormatDescription;
 import android.media.audio.common.AudioMode;
-import android.media.audio.common.AudioPolicyForcedConfig;
-import android.media.audio.common.AudioPolicyForceUse;
 import android.media.audio.common.AudioProfile;
 import android.media.audio.common.AudioOffloadInfo;
 import android.media.audio.common.AudioPort;
diff --git a/media/libaudioclient/include/media/PolicyAidlConversion.h b/media/libaudioclient/include/media/PolicyAidlConversion.h
index 1b90d6b..ed9ddd6 100644
--- a/media/libaudioclient/include/media/PolicyAidlConversion.h
+++ b/media/libaudioclient/include/media/PolicyAidlConversion.h
@@ -28,6 +28,8 @@
 #include <android/media/AudioMixRouteFlag.h>
 #include <android/media/AudioMixType.h>
 #include <android/media/AudioOffloadMode.h>
+#include <android/media/AudioPolicyForceUse.h>
+#include <android/media/AudioPolicyForcedConfig.h>
 #include <android/media/DeviceRole.h>
 
 #include <media/AidlConversionUtil.h>
@@ -82,6 +84,16 @@
 ConversionResult<media::AudioPolicyDeviceState>
 legacy2aidl_audio_policy_dev_state_t_AudioPolicyDeviceState(audio_policy_dev_state_t legacy);
 
+ConversionResult<audio_policy_force_use_t>
+aidl2legacy_AudioPolicyForceUse_audio_policy_force_use_t(media::AudioPolicyForceUse aidl);
+ConversionResult<media::AudioPolicyForceUse>
+legacy2aidl_audio_policy_force_use_t_AudioPolicyForceUse(audio_policy_force_use_t legacy);
+
+ConversionResult<audio_policy_forced_cfg_t>
+aidl2legacy_AudioPolicyForcedConfig_audio_policy_forced_cfg_t(media::AudioPolicyForcedConfig aidl);
+ConversionResult<media::AudioPolicyForcedConfig>
+legacy2aidl_audio_policy_forced_cfg_t_AudioPolicyForcedConfig(audio_policy_forced_cfg_t legacy);
+
 ConversionResult<device_role_t>
 aidl2legacy_DeviceRole_device_role_t(media::DeviceRole aidl);
 ConversionResult<media::DeviceRole>
diff --git a/media/libmedia/Android.bp b/media/libmedia/Android.bp
index ac9bf91..ee6ad00 100644
--- a/media/libmedia/Android.bp
+++ b/media/libmedia/Android.bp
@@ -260,6 +260,7 @@
     srcs: [
         "AudioCapabilities.cpp",
         "CodecCapabilities.cpp",
+        "EncoderCapabilities.cpp",
         "VideoCapabilities.cpp",
         "CodecCapabilitiesUtils.cpp",
     ],
diff --git a/media/libmedia/CodecCapabilities.cpp b/media/libmedia/CodecCapabilities.cpp
index 87eb4bc..407d376 100644
--- a/media/libmedia/CodecCapabilities.cpp
+++ b/media/libmedia/CodecCapabilities.cpp
@@ -17,6 +17,7 @@
 //#define LOG_NDEBUG 0
 #define LOG_TAG "CodecCapabilities"
 
+#include <android-base/strings.h>
 #include <utils/Log.h>
 #include <media/CodecCapabilities.h>
 #include <media/CodecCapabilitiesUtils.h>
@@ -25,6 +26,58 @@
 
 namespace android {
 
+static const int32_t HEVCHighTierLevels =
+        HEVCHighTierLevel1 | HEVCHighTierLevel2 | HEVCHighTierLevel21 | HEVCHighTierLevel3 |
+        HEVCHighTierLevel31 | HEVCHighTierLevel4 | HEVCHighTierLevel41 | HEVCHighTierLevel5 |
+        HEVCHighTierLevel51 | HEVCHighTierLevel52 | HEVCHighTierLevel6 | HEVCHighTierLevel61 |
+        HEVCHighTierLevel62;
+
+static const int32_t DEFAULT_MAX_SUPPORTED_INSTANCES = 32;
+static const int32_t MAX_SUPPORTED_INSTANCES_LIMIT = 256;
+
+// must not contain KEY_PROFILE
+static const std::set<std::pair<std::string, AMessage::Type>> AUDIO_LEVEL_CRITICAL_FORMAT_KEYS = {
+    // We don't set level-specific limits for audio codecs today. Key candidates would
+    // be sample rate, bit rate or channel count.
+    // MediaFormat.KEY_SAMPLE_RATE,
+    // MediaFormat.KEY_CHANNEL_COUNT,
+    // MediaFormat.KEY_BIT_RATE,
+    { KEY_MIME, AMessage::kTypeString }
+};
+
+// CodecCapabilities Features
+static const std::vector<Feature> DECODER_FEATURES = {
+    Feature(FEATURE_AdaptivePlayback, (1 << 0), true),
+    Feature(FEATURE_SecurePlayback,   (1 << 1), false),
+    Feature(FEATURE_TunneledPlayback, (1 << 2), false),
+    Feature(FEATURE_PartialFrame,     (1 << 3), false),
+    Feature(FEATURE_FrameParsing,     (1 << 4), false),
+    Feature(FEATURE_MultipleFrames,   (1 << 5), false),
+    Feature(FEATURE_DynamicTimestamp, (1 << 6), false),
+    Feature(FEATURE_LowLatency,       (1 << 7), true),
+    // feature to exclude codec from REGULAR codec list
+    Feature(FEATURE_SpecialCodec,     (1 << 30), false, true),
+};
+static const std::vector<Feature> ENCODER_FEATURES = {
+    Feature(FEATURE_IntraRefresh, (1 << 0), false),
+    Feature(FEATURE_MultipleFrames, (1 << 1), false),
+    Feature(FEATURE_DynamicTimestamp, (1 << 2), false),
+    Feature(FEATURE_QpBounds, (1 << 3), false),
+    Feature(FEATURE_EncodingStatistics, (1 << 4), false),
+    Feature(FEATURE_HdrEditing, (1 << 5), false),
+    // feature to exclude codec from REGULAR codec list
+    Feature(FEATURE_SpecialCodec,     (1 << 30), false, true),
+};
+
+// must not contain KEY_PROFILE
+static const std::set<std::pair<std::string, AMessage::Type>> VIDEO_LEVEL_CRITICAL_FORMAT_KEYS = {
+    { KEY_WIDTH, AMessage::kTypeInt32 },
+    { KEY_HEIGHT, AMessage::kTypeInt32 },
+    { KEY_FRAME_RATE, AMessage::kTypeInt32 },
+    { KEY_BIT_RATE, AMessage::kTypeInt32 },
+    { KEY_MIME, AMessage::kTypeString }
+};
+
 bool CodecCapabilities::SupportsBitrate(Range<int32_t> bitrateRange,
         const sp<AMessage> &format) {
     // consider max bitrate over average bitrate for support
@@ -46,6 +99,212 @@
     return true;
 }
 
+bool CodecCapabilities::isFeatureSupported(const std::string &name) const {
+    return mFeaturesSupported.contains(name);
+}
+
+bool CodecCapabilities::isFeatureRequired(const std::string &name) const {
+    return mFeaturesRequired.contains(name);
+}
+
+std::vector<std::string> CodecCapabilities::validFeatures() const {
+    std::vector<std::string> res;
+    for (const Feature& feature : getValidFeatures()) {
+        if (!feature.mInternal) {
+            res.push_back(feature.mName);
+        }
+    }
+    return res;
+}
+
+std::vector<Feature> CodecCapabilities::getValidFeatures() const {
+    if (isEncoder()) {
+        return ENCODER_FEATURES;
+    } else {
+        return DECODER_FEATURES;
+    }
+}
+
+bool CodecCapabilities::isRegular() const {
+    // regular codecs only require default features
+    std::vector<Feature> features = getValidFeatures();
+    return std::all_of(features.begin(), features.end(),
+            [this](Feature feat){ return (feat.mDefault || !isFeatureRequired(feat.mName)); });
+}
+
+bool CodecCapabilities::isFormatSupported(const sp<AMessage> &format) const {
+    AString mediaType;
+    format->findString(KEY_MIME, &mediaType);
+    // mediaType must match if present
+    if (!base::EqualsIgnoreCase(mMediaType, mediaType.c_str())) {
+        return false;
+    }
+
+    // check feature support
+    for (Feature feat: getValidFeatures()) {
+        if (feat.mInternal) {
+            continue;
+        }
+
+        int32_t yesNo;
+        std::string key = KEY_FEATURE_;
+        key = key + feat.mName;
+        if (format->findInt32(key.c_str(), &yesNo)) {
+            continue;
+        }
+        if ((yesNo == 1 && !isFeatureSupported(feat.mName)) ||
+                (yesNo == 0 && isFeatureRequired(feat.mName))) {
+            return false;
+        }
+    }
+
+    int32_t profile;
+    if (format->findInt32(KEY_PROFILE, &profile)) {
+        int32_t level = -1;
+        format->findInt32(KEY_LEVEL, &level);
+        if (!supportsProfileLevel(profile, level)) {
+            return false;
+        }
+
+        // If we recognize this profile, check that this format is supported by the
+        // highest level supported by the codec for that profile. (Ignore specified
+        // level beyond the above profile/level check as level is only used as a
+        // guidance. E.g. AVC Level 1 CIF format is supported if codec supports level 1.1
+        // even though max size for Level 1 is QCIF. However, MPEG2 Simple Profile
+        // 1080p format is not supported even if codec supports Main Profile Level High,
+        // as Simple Profile does not support 1080p.
+        int32_t maxLevel = 0;
+        for (ProfileLevel pl : mProfileLevels) {
+            if (pl.mProfile == profile && pl.mLevel > maxLevel) {
+                // H.263 levels are not completely ordered:
+                // Level45 support only implies Level10 support
+                if (!base::EqualsIgnoreCase(mMediaType, MIMETYPE_VIDEO_H263)
+                        || pl.mLevel != H263Level45
+                        || maxLevel == H263Level10) {
+                    maxLevel = pl.mLevel;
+                }
+            }
+        }
+        std::shared_ptr<CodecCapabilities> levelCaps
+                = CreateFromProfileLevel(mMediaType, profile, maxLevel);
+        // We must remove the profile from this format otherwise levelCaps.isFormatSupported
+        // will get into this same condition and loop forever. Furthermore, since levelCaps
+        // does not contain features and bitrate specific keys, keep only keys relevant for
+        // a level check.
+        sp<AMessage> levelCriticalFormat = new AMessage;
+
+        // critical keys will always contain KEY_MIME, but should also contain others to be
+        // meaningful
+        if ((isVideo() || isAudio()) && levelCaps != nullptr) {
+            const std::set<std::pair<std::string, AMessage::Type>> criticalKeys =
+                isVideo() ? VIDEO_LEVEL_CRITICAL_FORMAT_KEYS : AUDIO_LEVEL_CRITICAL_FORMAT_KEYS;
+            for (std::pair<std::string, AMessage::Type> key : criticalKeys) {
+                if (format->contains(key.first.c_str())) {
+                    // AMessage::ItemData value = format->findItem(key.c_str());
+                    // levelCriticalFormat->setItem(key.c_str(), value);
+                    switch (key.second) {
+                        case AMessage::kTypeInt32: {
+                            int32_t value;
+                            format->findInt32(key.first.c_str(), &value);
+                            levelCriticalFormat->setInt32(key.first.c_str(), value);
+                            break;
+                        }
+                        case AMessage::kTypeString: {
+                            AString value;
+                            format->findString(key.first.c_str(), &value);
+                            levelCriticalFormat->setString(key.first.c_str(), value);
+                            break;
+                        }
+                        default:
+                            ALOGE("Unsupported type");
+                    }
+                }
+            }
+            if (!levelCaps->isFormatSupported(levelCriticalFormat)) {
+                return false;
+            }
+        }
+    }
+    if (mAudioCaps && !mAudioCaps->supportsFormat(format)) {
+        return false;
+    }
+    if (mVideoCaps && !mVideoCaps->supportsFormat(format)) {
+        return false;
+    }
+    if (mEncoderCaps && !mEncoderCaps->supportsFormat(format)) {
+        return false;
+    }
+    return true;
+}
+
+bool CodecCapabilities::supportsProfileLevel(int32_t profile, int32_t level) const {
+    for (ProfileLevel pl: mProfileLevels) {
+        if (pl.mProfile != profile) {
+            continue;
+        }
+
+        // No specific level requested
+        if (level == -1) {
+            return true;
+        }
+
+        // AAC doesn't use levels
+        if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_AAC)) {
+            return true;
+        }
+
+        // DTS doesn't use levels
+        if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_DTS)
+                || base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_DTS_HD)
+                || base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_DTS_UHD)) {
+            return true;
+        }
+
+        // H.263 levels are not completely ordered:
+        // Level45 support only implies Level10 support
+        if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_VIDEO_H263)) {
+            if (pl.mLevel != level && pl.mLevel == H263Level45
+                    && level > H263Level10) {
+                continue;
+            }
+        }
+
+        // MPEG4 levels are not completely ordered:
+        // Level1 support only implies Level0 (and not Level0b) support
+        if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_VIDEO_MPEG4)) {
+            if (pl.mLevel != level && pl.mLevel == MPEG4Level1
+                    && level > MPEG4Level0) {
+                continue;
+            }
+        }
+
+        // HEVC levels incorporate both tiers and levels. Verify tier support.
+        if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_VIDEO_HEVC)) {
+            bool supportsHighTier =
+                (pl.mLevel & HEVCHighTierLevels) != 0;
+            bool checkingHighTier = (level & HEVCHighTierLevels) != 0;
+            // high tier levels are only supported by other high tier levels
+            if (checkingHighTier && !supportsHighTier) {
+                continue;
+            }
+        }
+
+        if (pl.mLevel >= level) {
+            // if we recognize the listed profile/level, we must also recognize the
+            // profile/level arguments.
+            if (CreateFromProfileLevel(mMediaType, profile, pl.mLevel) != nullptr) {
+                return CreateFromProfileLevel(mMediaType, profile, level) != nullptr;
+            }
+            return true;
+        }
+    }
+    return false;
+}
+
+sp<AMessage> CodecCapabilities::getDefaultFormat() const {
+    return mDefaultFormat;
+}
+
 const std::string& CodecCapabilities::getMediaType() {
     return mMediaType;
 }
@@ -54,4 +313,130 @@
     return mProfileLevels;
 }
 
+std::vector<uint32_t> CodecCapabilities::getColorFormats() const {
+    return mColorFormats;
+}
+
+int32_t CodecCapabilities::getMaxSupportedInstances() const {
+    return mMaxSupportedInstances;
+}
+
+bool CodecCapabilities::isAudio() const {
+    return mAudioCaps != nullptr;
+}
+
+std::shared_ptr<AudioCapabilities>
+        CodecCapabilities::getAudioCapabilities() const {
+    return mAudioCaps;
+}
+
+bool CodecCapabilities::isEncoder() const {
+    return mEncoderCaps != nullptr;
+}
+
+std::shared_ptr<EncoderCapabilities>
+        CodecCapabilities::getEncoderCapabilities() const {
+    return mEncoderCaps;
+}
+
+bool CodecCapabilities::isVideo() const {
+    return mVideoCaps != nullptr;
+}
+
+std::shared_ptr<VideoCapabilities> CodecCapabilities::getVideoCapabilities() const {
+    return mVideoCaps;
+}
+
+// static
+std::shared_ptr<CodecCapabilities> CodecCapabilities::CreateFromProfileLevel(
+        std::string mediaType, int32_t profile, int32_t level, int32_t maxConcurrentInstances) {
+    ProfileLevel pl;
+    pl.mProfile = profile;
+    pl.mLevel = level;
+    sp<AMessage> defaultFormat = new AMessage;
+    defaultFormat->setString(KEY_MIME, mediaType.c_str());
+
+    std::vector<ProfileLevel> pls;
+    pls.push_back(pl);
+    std::vector<uint32_t> colFmts;
+    sp<AMessage> capabilitiesInfo = new AMessage;
+    std::shared_ptr<CodecCapabilities> ret(new CodecCapabilities());
+    ret->init(pls, colFmts, true /* encoder */, defaultFormat, capabilitiesInfo,
+            maxConcurrentInstances);
+    if (ret->getErrors() != 0) {
+        return nullptr;
+    }
+    return ret;
+}
+
+void CodecCapabilities::init(std::vector<ProfileLevel> profLevs, std::vector<uint32_t> colFmts,
+        bool encoder, sp<AMessage> &defaultFormat, sp<AMessage> &capabilitiesInfo,
+        int32_t maxConcurrentInstances) {
+    mColorFormats = colFmts;
+    mDefaultFormat = defaultFormat;
+    mCapabilitiesInfo = capabilitiesInfo;
+
+    AString mediaTypeAStr;
+    mDefaultFormat->findString(KEY_MIME, &mediaTypeAStr);
+    mMediaType = mediaTypeAStr.c_str();
+
+    /* VP9 introduced profiles around 2016, so some VP9 codecs may not advertise any
+       supported profiles. Determine the level for them using the info they provide. */
+    if (profLevs.size() == 0 && mMediaType == MIMETYPE_VIDEO_VP9) {
+        ProfileLevel profLev;
+        profLev.mProfile = VP9Profile0;
+        profLev.mLevel = VideoCapabilities::EquivalentVP9Level(capabilitiesInfo);
+        profLevs.push_back(profLev);
+    }
+    mProfileLevels = profLevs;
+
+    if (mediaTypeAStr.startsWithIgnoreCase("audio/")) {
+        mAudioCaps = AudioCapabilities::Create(mMediaType, profLevs, capabilitiesInfo);
+        mAudioCaps->getDefaultFormat(mDefaultFormat);
+    } else if (mediaTypeAStr.startsWithIgnoreCase("video/")
+            || mediaTypeAStr.equalsIgnoreCase(MIMETYPE_IMAGE_ANDROID_HEIC)) {
+        mVideoCaps = VideoCapabilities::Create(mMediaType, profLevs, capabilitiesInfo);
+    }
+
+    if (encoder) {
+        mEncoderCaps = EncoderCapabilities::Create(mMediaType, profLevs, capabilitiesInfo);
+        mEncoderCaps->getDefaultFormat(mDefaultFormat);
+    }
+
+    mMaxSupportedInstances = maxConcurrentInstances > 0
+            ? maxConcurrentInstances : DEFAULT_MAX_SUPPORTED_INSTANCES;
+
+    int32_t maxInstances = mMaxSupportedInstances;
+    capabilitiesInfo->findInt32("max-concurrent-instances", &maxInstances);
+    mMaxSupportedInstances =
+            Range(1, MAX_SUPPORTED_INSTANCES_LIMIT).clamp(maxInstances);
+
+    mFeaturesRequired.clear();
+    mFeaturesSupported.clear();
+    for (Feature feat: getValidFeatures()) {
+        std::string key = KEY_FEATURE_;
+        key = key + feat.mName;
+        int yesNo = -1;
+        if (!capabilitiesInfo->findInt32(key.c_str(), &yesNo)) {
+            continue;
+        }
+        if (yesNo > 0) {
+            mFeaturesRequired.insert(feat.mName);
+        }
+        mFeaturesSupported.insert(feat.mName);
+        if (!feat.mInternal) {
+            mDefaultFormat->setInt32(key.c_str(), 1);
+        }
+    }
+}
+
+int32_t CodecCapabilities::getErrors() const {
+    if (mAudioCaps) {
+        return mAudioCaps->mError;
+    } else if (mVideoCaps) {
+        return mVideoCaps->mError;
+    }
+    return 0;
+}
+
 }  // namespace android
\ No newline at end of file
diff --git a/media/libmedia/EncoderCapabilities.cpp b/media/libmedia/EncoderCapabilities.cpp
new file mode 100644
index 0000000..a840220
--- /dev/null
+++ b/media/libmedia/EncoderCapabilities.cpp
@@ -0,0 +1,205 @@
+/*
+ * 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "EncoderCapabilities"
+
+#include <android-base/strings.h>
+
+#include <media/CodecCapabilities.h>
+#include <media/EncoderCapabilities.h>
+#include <media/stagefright/MediaCodecConstants.h>
+
+namespace android {
+
+const Range<int>& EncoderCapabilities::getQualityRange() {
+    return mQualityRange;
+}
+
+const Range<int>& EncoderCapabilities::getComplexityRange() {
+    return mComplexityRange;
+}
+
+// static
+int EncoderCapabilities::ParseBitrateMode(std::string mode) {
+    for (Feature feat: sBitrateModes) {
+        if (base::EqualsIgnoreCase(feat.mName, mode)) {
+            return feat.mValue;
+        }
+    }
+    return 0;
+}
+
+bool EncoderCapabilities::isBitrateModeSupported(int mode) {
+    for (Feature feat : sBitrateModes) {
+        if (mode == feat.mValue) {
+            return (mBitControl & (1 << mode)) != 0;
+        }
+    }
+    return false;
+}
+
+// static
+std::shared_ptr<EncoderCapabilities> EncoderCapabilities::Create(std::string mediaType,
+        std::vector<ProfileLevel> profLevs, const sp<AMessage> &format) {
+    std::shared_ptr<EncoderCapabilities> caps(new EncoderCapabilities());
+    caps->init(mediaType, profLevs, format);
+    return caps;
+}
+
+void EncoderCapabilities::init(std::string mediaType, std::vector<ProfileLevel> profLevs,
+        const sp<AMessage> &format) {
+    // no support for complexity or quality yet
+    mMediaType = mediaType;
+    mProfileLevels = profLevs;
+    mComplexityRange = Range(0, 0);
+    mQualityRange = Range(0, 0);
+    mBitControl = (1 << BITRATE_MODE_VBR);
+
+    applyLevelLimits();
+    parseFromInfo(format);
+}
+
+void EncoderCapabilities::applyLevelLimits() {
+    if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_FLAC)) {
+        mComplexityRange = Range(0, 8);
+        mBitControl = (1 << BITRATE_MODE_CQ);
+    } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_AMR_NB)
+            || base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_AMR_WB)
+            || base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_G711_ALAW)
+            || base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_G711_MLAW)
+            || base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_MSGSM)) {
+        mBitControl = (1 << BITRATE_MODE_CBR);
+    }
+}
+
+void EncoderCapabilities::parseFromInfo(const sp<AMessage> &format) {
+    AString complexityRangeAStr;
+    if (format->findString("complexity-range", &complexityRangeAStr)) {
+        std::optional<Range<int>> complexityRangeOpt
+                = Range<int32_t>::Parse(std::string(complexityRangeAStr.c_str()));
+        mComplexityRange = complexityRangeOpt.value_or(mComplexityRange);
+        // TODO should we limit this to level limits?
+    }
+    AString qualityRangeAStr;
+    if (format->findString("quality-range", &qualityRangeAStr)) {
+        std::optional<Range<int>> qualityRangeOpt
+                = Range<int32_t>::Parse(std::string(qualityRangeAStr.c_str()));
+        mQualityRange = qualityRangeOpt.value_or(mQualityRange);
+    }
+    AString bitrateModesAStr;
+    if (format->findString("feature-bitrate-modes", &bitrateModesAStr)) {
+        mBitControl = 0;
+        for (std::string mode: base::Split(std::string(bitrateModesAStr.c_str()), ",")) {
+            mBitControl |= (1 << ParseBitrateMode(mode));
+        }
+    }
+    format->findInt32("complexity-default", &mDefaultComplexity);
+    format->findInt32("quality-default", &mDefaultQuality);
+    AString qualityScaleAStr;
+    if (format->findString("quality-scale", &qualityScaleAStr)) {
+        mQualityScale = std::string(qualityScaleAStr.c_str());
+    }
+}
+
+bool EncoderCapabilities::supports(
+        std::optional<int> complexity, std::optional<int> quality, std::optional<int> profile) {
+    bool ok = true;
+    if (complexity) {
+        ok &= mComplexityRange.contains(complexity.value());
+    }
+    if (quality) {
+        ok &= mQualityRange.contains(quality.value());
+    }
+    if (profile) {
+        ok &= std::any_of(mProfileLevels.begin(), mProfileLevels.end(),
+                [&profile](ProfileLevel pl){ return pl.mProfile == profile.value(); });
+    }
+    return ok;
+}
+
+void EncoderCapabilities::getDefaultFormat(sp<AMessage> &format) {
+    // don't list trivial quality/complexity as default for now
+    if (mQualityRange.upper() != mQualityRange.lower()
+            && mDefaultQuality != 0) {
+        format->setInt32(KEY_QUALITY, mDefaultQuality);
+    }
+    if (mComplexityRange.upper() != mComplexityRange.lower()
+            && mDefaultComplexity != 0) {
+        format->setInt32(KEY_COMPLEXITY, mDefaultComplexity);
+    }
+    // bitrates are listed in order of preference
+    for (Feature feat : sBitrateModes) {
+        if ((mBitControl & (1 << feat.mValue)) != 0) {
+            format->setInt32(KEY_BITRATE_MODE, feat.mValue);
+            break;
+        }
+    }
+}
+
+bool EncoderCapabilities::supportsFormat(const sp<AMessage> &format) {
+    int32_t mode;
+    if (format->findInt32(KEY_BITRATE_MODE, &mode) && !isBitrateModeSupported(mode)) {
+        return false;
+    }
+
+    int tmp;
+    std::optional<int> complexity = std::nullopt;
+    if (format->findInt32(KEY_COMPLEXITY, &tmp)) {
+        complexity = tmp;
+    }
+
+    if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_FLAC)) {
+        int flacComplexity;
+        if (format->findInt32(KEY_FLAC_COMPRESSION_LEVEL, &flacComplexity)) {
+            if (!complexity) {
+                complexity = flacComplexity;
+            } else if (flacComplexity != complexity.value()) {
+                ALOGE("Conflicting values for complexity and flac-compression-level,"
+                        " which are %d and %d", complexity.value(), flacComplexity);
+                return false;
+            }
+        }
+    }
+
+    // other audio parameters
+    std::optional<int> profile = std::nullopt;
+    if (format->findInt32(KEY_PROFILE, &tmp)) {
+        profile = tmp;
+    }
+
+    if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_AAC)) {
+        int aacProfile;
+        if (format->findInt32(KEY_AAC_PROFILE, &aacProfile)) {
+            if (!profile) {
+                profile = aacProfile;
+            } else if (aacProfile != profile.value()) {
+                ALOGE("Conflicting values for profile and aac-profile, which are %d and %d",
+                        profile.value(), aacProfile);
+                return false;
+            }
+        }
+    }
+
+    std::optional<int> quality = std::nullopt;
+    if (format->findInt32(KEY_QUALITY, &tmp)) {
+        quality = tmp;
+    }
+
+    return supports(complexity, quality, profile);
+}
+
+}  // namespace android
\ No newline at end of file
diff --git a/media/libmedia/include/media/CodecCapabilities.h b/media/libmedia/include/media/CodecCapabilities.h
index 700373a..0611d8c 100644
--- a/media/libmedia/include/media/CodecCapabilities.h
+++ b/media/libmedia/include/media/CodecCapabilities.h
@@ -19,8 +19,9 @@
 #define CODEC_CAPABILITIES_H_
 
 #include <media/AudioCapabilities.h>
-#include <media/VideoCapabilities.h>
 #include <media/CodecCapabilitiesUtils.h>
+#include <media/EncoderCapabilities.h>
+#include <media/VideoCapabilities.h>
 #include <media/stagefright/foundation/ABase.h>
 #include <media/stagefright/foundation/AMessage.h>
 #include <media/stagefright/foundation/AString.h>
@@ -39,6 +40,26 @@
             const sp<AMessage> &format);
 
     /**
+     * Retrieve the codec capabilities for a certain {@code mime type}, {@code
+     * profile} and {@code level}.  If the type, or profile-level combination
+     * is not understood by the framework, it returns null.
+     * <p class=note> In {@link android.os.Build.VERSION_CODES#M}, calling this
+     * method without calling any method of the {@link MediaCodecList} class beforehand
+     * results in a {@link NullPointerException}.</p>
+     */
+    static std::shared_ptr<CodecCapabilities> CreateFromProfileLevel(std::string mediaType,
+                int32_t profile, int32_t level, int32_t maxConcurrentInstances = -1);
+
+    CodecCapabilities() {};
+
+    /**
+     * Init CodecCapabilities with settings.
+     */
+    void init(std::vector<ProfileLevel> profLevs, std::vector<uint32_t> colFmts, bool encoder,
+            sp<AMessage> &defaultFormat, sp<AMessage> &capabilitiesInfo,
+            int32_t maxConcurrentInstances = 0);
+
+    /**
      * Returns the media type for which this codec-capability object was created.
      */
     const std::string& getMediaType();
@@ -48,12 +69,209 @@
      */
     const std::vector<ProfileLevel>& getProfileLevels();
 
+    /**
+     * Returns the supported color formats.
+     */
+    std::vector<uint32_t> getColorFormats() const;
+
+    /**
+     * Returns a media format with default values for configurations that have defaults.
+     */
+    sp<AMessage> getDefaultFormat() const;
+
+    /**
+     * Returns the max number of the supported concurrent codec instances.
+     * <p>
+     * This is a hint for an upper bound. Applications should not expect to successfully
+     * operate more instances than the returned value, but the actual number of
+     * concurrently operable instances may be less as it depends on the available
+     * resources at time of use.
+     */
+    int32_t getMaxSupportedInstances() const;
+
+    /**
+     * Returns the audio capabilities or {@code null} if this is not an audio codec.
+     */
+    std::shared_ptr<AudioCapabilities> getAudioCapabilities() const;
+
+    /**
+     * Returns the video capabilities or {@code null} if this is not a video codec.
+     */
+    std::shared_ptr<VideoCapabilities> getVideoCapabilities() const;
+
+    /**
+     * Returns the encoding capabilities or {@code null} if this is not an encoder.
+     */
+    std::shared_ptr<EncoderCapabilities> getEncoderCapabilities() const;
+
+    std::vector<std::string> validFeatures() const;
+
+    /**
+     * Query codec feature capabilities.
+     * <p>
+     * These features are supported to be used by the codec.  These
+     * include optional features that can be turned on, as well as
+     * features that are always on.
+     */
+    bool isFeatureSupported(const std::string &name) const;
+
+    /**
+     * Query codec feature requirements.
+     * <p>
+     * These features are required to be used by the codec, and as such,
+     * they are always turned on.
+     */
+    bool isFeatureRequired(const std::string &name) const;
+
+    bool isRegular() const;
+
+    /**
+    * Query whether codec supports a given {@link MediaFormat}.
+    *
+    * <p class=note>
+    * <strong>Note:</strong> On {@link android.os.Build.VERSION_CODES#LOLLIPOP},
+    * {@code format} must not contain a {@linkplain MediaFormat#KEY_FRAME_RATE
+    * frame rate}. Use
+    * <code class=prettyprint>format.setString(MediaFormat.KEY_FRAME_RATE, null)</code>
+    * to clear any existing frame rate setting in the format.
+    * <p>
+    *
+    * The following table summarizes the format keys considered by this method.
+    * This is especially important to consider when targeting a higher SDK version than the
+    * minimum SDK version, as this method will disregard some keys on devices below the target
+    * SDK version.
+    *
+    * <table style="width: 0%">
+    *  <thead>
+    *   <tr>
+    *    <th rowspan=3>OS Version(s)</th>
+    *    <td colspan=3>{@code MediaFormat} keys considered for</th>
+    *   </tr><tr>
+    *    <th>Audio Codecs</th>
+    *    <th>Video Codecs</th>
+    *    <th>Encoders</th>
+    *   </tr>
+    *  </thead>
+    *  <tbody>
+    *   <tr>
+    *    <td>{@link android.os.Build.VERSION_CODES#LOLLIPOP}</td>
+    *    <td rowspan=3>{@link MediaFormat#KEY_MIME}<sup>*</sup>,<br>
+    *        {@link MediaFormat#KEY_SAMPLE_RATE},<br>
+    *        {@link MediaFormat#KEY_CHANNEL_COUNT},</td>
+    *    <td>{@link MediaFormat#KEY_MIME}<sup>*</sup>,<br>
+    *        {@link CodecCapabilities#FEATURE_AdaptivePlayback}<sup>D</sup>,<br>
+    *        {@link CodecCapabilities#FEATURE_SecurePlayback}<sup>D</sup>,<br>
+    *        {@link CodecCapabilities#FEATURE_TunneledPlayback}<sup>D</sup>,<br>
+    *        {@link MediaFormat#KEY_WIDTH},<br>
+    *        {@link MediaFormat#KEY_HEIGHT},<br>
+    *        <strong>no</strong> {@code KEY_FRAME_RATE}</td>
+    *    <td rowspan=10>as to the left, plus<br>
+    *        {@link MediaFormat#KEY_BITRATE_MODE},<br>
+    *        {@link MediaFormat#KEY_PROFILE}
+    *        (and/or {@link MediaFormat#KEY_AAC_PROFILE}<sup>~</sup>),<br>
+    *        <!-- {link MediaFormat#KEY_QUALITY},<br> -->
+    *        {@link MediaFormat#KEY_COMPLEXITY}
+    *        (and/or {@link MediaFormat#KEY_FLAC_COMPRESSION_LEVEL}<sup>~</sup>)</td>
+    *   </tr><tr>
+    *    <td>{@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1}</td>
+    *    <td rowspan=2>as above, plus<br>
+    *        {@link MediaFormat#KEY_FRAME_RATE}</td>
+    *   </tr><tr>
+    *    <td>{@link android.os.Build.VERSION_CODES#M}</td>
+    *   </tr><tr>
+    *    <td>{@link android.os.Build.VERSION_CODES#N}</td>
+    *    <td rowspan=2>as above, plus<br>
+    *        {@link MediaFormat#KEY_PROFILE},<br>
+    *        <!-- {link MediaFormat#KEY_MAX_BIT_RATE},<br> -->
+    *        {@link MediaFormat#KEY_BIT_RATE}</td>
+    *    <td rowspan=2>as above, plus<br>
+    *        {@link MediaFormat#KEY_PROFILE},<br>
+    *        {@link MediaFormat#KEY_LEVEL}<sup>+</sup>,<br>
+    *        <!-- {link MediaFormat#KEY_MAX_BIT_RATE},<br> -->
+    *        {@link MediaFormat#KEY_BIT_RATE},<br>
+    *        {@link CodecCapabilities#FEATURE_IntraRefresh}<sup>E</sup></td>
+    *   </tr><tr>
+    *    <td>{@link android.os.Build.VERSION_CODES#N_MR1}</td>
+    *   </tr><tr>
+    *    <td>{@link android.os.Build.VERSION_CODES#O}</td>
+    *    <td rowspan=3 colspan=2>as above, plus<br>
+    *        {@link CodecCapabilities#FEATURE_PartialFrame}<sup>D</sup></td>
+    *   </tr><tr>
+    *    <td>{@link android.os.Build.VERSION_CODES#O_MR1}</td>
+    *   </tr><tr>
+    *    <td>{@link android.os.Build.VERSION_CODES#P}</td>
+    *   </tr><tr>
+    *    <td>{@link android.os.Build.VERSION_CODES#Q}</td>
+    *    <td colspan=2>as above, plus<br>
+    *        {@link CodecCapabilities#FEATURE_FrameParsing}<sup>D</sup>,<br>
+    *        {@link CodecCapabilities#FEATURE_MultipleFrames},<br>
+    *        {@link CodecCapabilities#FEATURE_DynamicTimestamp}</td>
+    *   </tr><tr>
+    *    <td>{@link android.os.Build.VERSION_CODES#R}</td>
+    *    <td colspan=2>as above, plus<br>
+    *        {@link CodecCapabilities#FEATURE_LowLatency}<sup>D</sup></td>
+    *   </tr>
+    *   <tr>
+    *    <td colspan=4>
+    *     <p class=note><strong>Notes:</strong><br>
+    *      *: must be specified; otherwise, method returns {@code false}.<br>
+    *      +: method does not verify that the format parameters are supported
+    *      by the specified level.<br>
+    *      D: decoders only<br>
+    *      E: encoders only<br>
+    *      ~: if both keys are provided values must match
+    *    </td>
+    *   </tr>
+    *  </tbody>
+    * </table>
+    *
+    * @param format media format with optional feature directives.
+    * @return whether the codec capabilities support the given format
+    *         and feature requests.
+    */
+    bool isFormatSupported(const sp<AMessage> &format) const;
+
+    /**
+     * If the CodecCapabilities contains an AudioCapabilities.
+     *
+     * Not a public API to users.
+     */
+    bool isAudio() const;
+
+    /**
+     * If the CodecCapabilities contains a VideoCapabilities.
+     *
+     * Not a public API to users.
+     */
+    bool isVideo() const;
+
+    /**
+     * If the CodecCapabilities contains an EncoderCapabilities.
+     *
+     * Not a public API to users.
+     */
+    bool isEncoder() const;
+
 private:
     std::string mMediaType;
     std::vector<ProfileLevel> mProfileLevels;
+    std::vector<uint32_t> mColorFormats;
+    int32_t mMaxSupportedInstances;
+
+    sp<AMessage> mDefaultFormat;
+    sp<AMessage> mCapabilitiesInfo;
+
+    // Features
+    std::set<std::string> mFeaturesSupported;
+    std::set<std::string> mFeaturesRequired;
 
     std::shared_ptr<AudioCapabilities> mAudioCaps;
     std::shared_ptr<VideoCapabilities> mVideoCaps;
+    std::shared_ptr<EncoderCapabilities> mEncoderCaps;
+
+    bool supportsProfileLevel(int32_t profile, int32_t level) const;
+    std::vector<Feature> getValidFeatures() const;
+    int32_t getErrors() const;
 };
 
 }  // namespace android
diff --git a/media/libmedia/include/media/CodecCapabilitiesUtils.h b/media/libmedia/include/media/CodecCapabilitiesUtils.h
index 7ca536a..eb62bf9 100644
--- a/media/libmedia/include/media/CodecCapabilitiesUtils.h
+++ b/media/libmedia/include/media/CodecCapabilitiesUtils.h
@@ -42,6 +42,21 @@
     }
 };
 
+struct Feature {
+    std::string mName;
+    int mValue;
+    bool mDefault;
+    bool mInternal;
+    Feature(std::string name, int value, bool def, bool internal) {
+        mName = name;
+        mValue = value;
+        mDefault = def;
+        mInternal = internal;
+    }
+    Feature(std::string name, int value, bool def) :
+        Feature(name, value, def, false /* internal */) {}
+};
+
 /**
  * Immutable class for describing the range of two numeric values.
  *
diff --git a/media/libmedia/include/media/EncoderCapabilities.h b/media/libmedia/include/media/EncoderCapabilities.h
new file mode 100644
index 0000000..a9654bb
--- /dev/null
+++ b/media/libmedia/include/media/EncoderCapabilities.h
@@ -0,0 +1,105 @@
+/*
+ * 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.
+ */
+
+#ifndef ENCODER_CAPABILITIES_H_
+
+#define ENCODER_CAPABILITIES_H_
+
+#include <media/CodecCapabilitiesUtils.h>
+#include <media/stagefright/foundation/AMessage.h>
+
+#include <utils/StrongPointer.h>
+
+namespace android {
+
+/**
+ * A class that supports querying the encoding capabilities of a codec.
+ */
+struct EncoderCapabilities {
+    /**
+    * Returns the supported range of quality values.
+    *
+    * Quality is implementation-specific. As a general rule, a higher quality
+    * setting results in a better image quality and a lower compression ratio.
+    */
+    const Range<int>& getQualityRange();
+
+    /**
+     * Returns the supported range of encoder complexity values.
+     * <p>
+     * Some codecs may support multiple complexity levels, where higher
+     * complexity values use more encoder tools (e.g. perform more
+     * intensive calculations) to improve the quality or the compression
+     * ratio.  Use a lower value to save power and/or time.
+     */
+    const Range<int>& getComplexityRange();
+
+    /** Constant quality mode */
+    inline static constexpr int BITRATE_MODE_CQ = 0;
+    /** Variable bitrate mode */
+    inline static constexpr int BITRATE_MODE_VBR = 1;
+    /** Constant bitrate mode */
+    inline static constexpr int BITRATE_MODE_CBR = 2;
+    /** Constant bitrate mode with frame drops */
+    inline static constexpr int BITRATE_MODE_CBR_FD =  3;
+
+    /**
+     * Query whether a bitrate mode is supported.
+     */
+    bool isBitrateModeSupported(int mode);
+
+    /** @hide */
+    static std::shared_ptr<EncoderCapabilities> Create(std::string mediaType,
+            std::vector<ProfileLevel> profLevs, const sp<AMessage> &format);
+
+    /** @hide */
+    void getDefaultFormat(sp<AMessage> &format);
+
+    /** @hide */
+    bool supportsFormat(const sp<AMessage> &format);
+
+private:
+    inline static const Feature sBitrateModes[] = {
+        Feature("VBR", BITRATE_MODE_VBR, true),
+        Feature("CBR", BITRATE_MODE_CBR, false),
+        Feature("CQ",  BITRATE_MODE_CQ,  false),
+        Feature("CBR-FD", BITRATE_MODE_CBR_FD, false)
+    };
+    static int ParseBitrateMode(std::string mode);
+
+    std::string mMediaType;
+    std::vector<ProfileLevel> mProfileLevels;
+
+    Range<int> mQualityRange;
+    Range<int> mComplexityRange;
+    int mBitControl;
+    int mDefaultComplexity;
+    int mDefaultQuality;
+    std::string mQualityScale;
+
+    /* no public constructor */
+    EncoderCapabilities() {}
+    void init(std::string mediaType, std::vector<ProfileLevel> profLevs,
+            const sp<AMessage> &format);
+    void applyLevelLimits();
+    void parseFromInfo(const sp<AMessage> &format);
+    bool supports(std::optional<int> complexity, std::optional<int> quality,
+            std::optional<int> profile);
+};
+
+}  // namespace android
+
+#endif // ENCODER_CAPABILITIES_H_
\ No newline at end of file
diff --git a/media/libmedia/tests/codeccapabilities/CodecCapabilitiesTest.cpp b/media/libmedia/tests/codeccapabilities/CodecCapabilitiesTest.cpp
index c1bd65a..e59d4d6 100644
--- a/media/libmedia/tests/codeccapabilities/CodecCapabilitiesTest.cpp
+++ b/media/libmedia/tests/codeccapabilities/CodecCapabilitiesTest.cpp
@@ -227,3 +227,147 @@
     EXPECT_EQ(achievableFR1080p.value().lower(), 569);
     EXPECT_EQ(achievableFR1080p.value().upper(), 572);
 }
+
+class EncoderCapsAacTest : public testing::Test {
+protected:
+    EncoderCapsAacTest() {
+        std::string mediaType = MIMETYPE_AUDIO_AAC;
+
+        sp<AMessage> details = new AMessage;
+        details->setString("bitrate-range", "8000-960000");
+        details->setString("max-channel-count", "6");
+        details->setString("sample-rate-ranges",
+                "8000,11025,12000,16000,22050,24000,32000,44100,48000");
+
+        std::vector<ProfileLevel> profileLevel{
+            ProfileLevel(2, 0),
+            ProfileLevel(5, 0),
+            ProfileLevel(29, 0),
+            ProfileLevel(23, 0),
+            ProfileLevel(39, 0),
+        };
+
+        encoderCaps = EncoderCapabilities::Create(mediaType, profileLevel, details);
+    }
+
+    std::shared_ptr<EncoderCapabilities> encoderCaps;
+};
+
+
+TEST_F(EncoderCapsAacTest, EncoderCaps_AAC_ComplexityRange) {
+    const Range<int>& complexityRange = encoderCaps->getComplexityRange();
+    EXPECT_EQ(complexityRange.lower(), 0);
+    EXPECT_EQ(complexityRange.upper(), 0);
+}
+
+TEST_F(EncoderCapsAacTest, EncoderCaps_AAC_QualityRange) {
+    const Range<int>& qualityRange = encoderCaps->getQualityRange();
+    EXPECT_EQ(qualityRange.lower(), 0);
+    EXPECT_EQ(qualityRange.upper(), 0);
+}
+
+TEST_F(EncoderCapsAacTest, EncoderCaps_AAC_SupportedBitrateMode) {
+    EXPECT_FALSE(encoderCaps->isBitrateModeSupported(BITRATE_MODE_CBR));
+    EXPECT_TRUE(encoderCaps->isBitrateModeSupported(BITRATE_MODE_VBR));
+    EXPECT_FALSE(encoderCaps->isBitrateModeSupported(BITRATE_MODE_CQ));
+    EXPECT_FALSE(encoderCaps->isBitrateModeSupported(BITRATE_MODE_CBR_FD));
+}
+
+class EncoderCapsFlacTest : public testing::Test {
+protected:
+    EncoderCapsFlacTest() {
+        std::string mediaType = MIMETYPE_AUDIO_FLAC;
+
+        sp<AMessage> details = new AMessage;
+        details->setString("bitrate-range", "1-21000000");
+        details->setString("complexity-default", "5");
+        details->setString("complexity-range", "0-8");
+        details->setString("feature-bitrate-modes", "CQ");
+        details->setString("max-channel-count", "2");
+        details->setString("sample-rate-ranges", "1-655350");
+
+        std::vector<ProfileLevel> profileLevel;
+
+        encoderCaps = EncoderCapabilities::Create(mediaType, profileLevel, details);
+    }
+
+    std::shared_ptr<EncoderCapabilities> encoderCaps;
+};
+
+TEST_F(EncoderCapsFlacTest, EncoderCaps_FLAC_ComplexityRange) {
+    const Range<int>& complexityRange = encoderCaps->getComplexityRange();
+    EXPECT_EQ(complexityRange.lower(), 0);
+    EXPECT_EQ(complexityRange.upper(), 8);
+}
+
+TEST_F(EncoderCapsFlacTest, EncoderCaps_FLAC_QualityRange) {
+    const Range<int>& qualityRange = encoderCaps->getQualityRange();
+    EXPECT_EQ(qualityRange.lower(), 0);
+    EXPECT_EQ(qualityRange.upper(), 0);
+}
+
+TEST_F(EncoderCapsFlacTest, EncoderCaps_FLAC_SupportedBitrateMode) {
+    EXPECT_FALSE(encoderCaps->isBitrateModeSupported(BITRATE_MODE_CBR));
+    EXPECT_FALSE(encoderCaps->isBitrateModeSupported(BITRATE_MODE_VBR));
+    EXPECT_TRUE(encoderCaps->isBitrateModeSupported(BITRATE_MODE_CQ));
+    EXPECT_FALSE(encoderCaps->isBitrateModeSupported(BITRATE_MODE_CBR_FD));
+}
+
+class EncoderCapsHevcTest : public testing::Test {
+protected:
+    EncoderCapsHevcTest() {
+        std::string mediaType = MIMETYPE_VIDEO_HEVC;
+
+        sp<AMessage> details = new AMessage;
+        details->setString("alignment", "2x2");
+        details->setString("bitrate-range", "1-120000000");
+        details->setString("block-count-range", "1-8160");
+        details->setString("block-size", "32x32");
+        details->setString("blocks-per-second-range", "1-979200");
+        details->setString("feature-bitrate-modes", "VBR,CBR,CQ,CBR-FD");
+        details->setInt32("feature-can-swap-width-height", 1);
+        details->setInt32("feature-qp-bounds", 0);
+        details->setInt32("feature-vq-minimum-quality", 0);
+        details->setString("max-concurrent-instances", "16");
+        details->setString("measured-frame-rate-1280x720-range", "154-198");
+        details->setString("measured-frame-rate-1920x1080-range", "46-97");
+        details->setString("measured-frame-rate-320x240-range", "371-553");
+        details->setString("measured-frame-rate-720x480-range", "214-305");
+        details->setString("performance-point-1280x720-range", "240");
+        details->setString("performance-point-3840x2160-range", "120");
+        details->setString("quality-default", "57");
+        details->setString("quality-range", "0-100");
+        details->setString("quality-scale", "linear");
+        details->setString("size-range", "64x64-3840x2176");
+
+        std::vector<ProfileLevel> profileLevel{
+            ProfileLevel(1, 2097152),
+            ProfileLevel(2, 2097152),
+            ProfileLevel(4096, 2097152),
+            ProfileLevel(8192, 2097152),
+        };
+
+        encoderCaps = EncoderCapabilities::Create(mediaType, profileLevel, details);
+    }
+
+    std::shared_ptr<EncoderCapabilities> encoderCaps;
+};
+
+TEST_F(EncoderCapsHevcTest, EncoderCaps_HEVC_ComplexityRange) {
+    const Range<int>& complexityRange = encoderCaps->getComplexityRange();
+    EXPECT_EQ(complexityRange.lower(), 0);
+    EXPECT_EQ(complexityRange.upper(), 0);
+}
+
+TEST_F(EncoderCapsHevcTest, EncoderCaps_HEVC_QualityRange) {
+    const Range<int>& qualityRange = encoderCaps->getQualityRange();
+    EXPECT_EQ(qualityRange.lower(), 0);
+    EXPECT_EQ(qualityRange.upper(), 100);
+}
+
+TEST_F(EncoderCapsHevcTest, EncoderCaps_HEVC_SupportedBitrateMode) {
+    EXPECT_TRUE(encoderCaps->isBitrateModeSupported(BITRATE_MODE_CBR));
+    EXPECT_TRUE(encoderCaps->isBitrateModeSupported(BITRATE_MODE_VBR));
+    EXPECT_TRUE(encoderCaps->isBitrateModeSupported(BITRATE_MODE_CQ));
+    EXPECT_TRUE(encoderCaps->isBitrateModeSupported(BITRATE_MODE_CBR_FD));
+}
diff --git a/media/libstagefright/Android.bp b/media/libstagefright/Android.bp
index d084f10..9ed5343 100644
--- a/media/libstagefright/Android.bp
+++ b/media/libstagefright/Android.bp
@@ -99,6 +99,7 @@
 
     static_libs: [
         "libstagefright_esds",
+        "android.media.extractor.flags-aconfig-cc",
     ],
 
     export_include_dirs: [
@@ -321,6 +322,7 @@
 
     static_libs: [
         "android.media.codec-aconfig-cc",
+        "android.media.extractor.flags-aconfig-cc",
         "com.android.media.flags.editing-aconfig-cc",
         "libstagefright_esds",
         "libstagefright_color_conversion",
diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index 86741a6..50eeb62 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -44,6 +44,8 @@
 #include <media/AudioParameter.h>
 #include <system/audio.h>
 
+#include <com_android_media_extractor_flags.h>
+
 // TODO : Remove the defines once mainline media is built against NDK >= 31.
 // The mp4 extractor is part of mainline and builds against NDK 29 as of
 // writing. These keys are available only from NDK 31:
@@ -1443,6 +1445,17 @@
         buffer->meta()->setInt64("timeUs", 0);
         msg->setBuffer("csd-0", buffer);
         parseAV1ProfileLevelFromCsd(buffer, msg);
+    } else if (com::android::media::extractor::flags::extractor_mp4_enable_apv() &&
+               meta->findData(kKeyAPVC, &type, &data, &size)) {
+        sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
+        if (buffer.get() == NULL || buffer->base() == NULL) {
+            return NO_MEMORY;
+        }
+        memcpy(buffer->data(), data, size);
+
+        buffer->meta()->setInt32("csd", true);
+        buffer->meta()->setInt64("timeUs", 0);
+        msg->setBuffer("csd-0", buffer);
     } else if (meta->findData(kKeyESDS, &type, &data, &size)) {
         ESDS esds((const char *)data, size);
         if (esds.InitCheck() != (status_t)OK) {
@@ -2091,6 +2104,9 @@
         } else if (mime == MEDIA_MIMETYPE_VIDEO_AV1 ||
                    mime == MEDIA_MIMETYPE_IMAGE_AVIF) {
             meta->setData(kKeyAV1C, 0, csd0->data(), csd0->size());
+        } else if (com::android::media::extractor::flags::extractor_mp4_enable_apv() &&
+                   mime == MEDIA_MIMETYPE_VIDEO_APV) {
+            meta->setData(kKeyAPVC, 0, csd0->data(), csd0->size());
         } else if (mime == MEDIA_MIMETYPE_VIDEO_DOLBY_VISION) {
             int32_t profile = -1;
             uint8_t blCompatibilityId = -1;
diff --git a/media/libstagefright/include/media/stagefright/MediaCodecConstants.h b/media/libstagefright/include/media/stagefright/MediaCodecConstants.h
index 8f2f162..b0f671d 100644
--- a/media/libstagefright/include/media/stagefright/MediaCodecConstants.h
+++ b/media/libstagefright/include/media/stagefright/MediaCodecConstants.h
@@ -854,12 +854,17 @@
 }
 
 inline constexpr char FEATURE_AdaptivePlayback[]       = "adaptive-playback";
+inline constexpr char FEATURE_DynamicTimestamp[]       = "dynamic-timestamp";
 inline constexpr char FEATURE_EncodingStatistics[]     = "encoding-statistics";
+inline constexpr char FEATURE_FrameParsing[]           = "frame-parsing";
+inline constexpr char FEATURE_HdrEditing[]             = "hdr-editing";
 inline constexpr char FEATURE_IntraRefresh[] = "intra-refresh";
+inline constexpr char FEATURE_LowLatency[]             = "low-latency";
 inline constexpr char FEATURE_MultipleFrames[] = "multiple-frames";
 inline constexpr char FEATURE_PartialFrame[] = "partial-frame";
 inline constexpr char FEATURE_QpBounds[] = "qp-bounds";
 inline constexpr char FEATURE_SecurePlayback[]         = "secure-playback";
+inline constexpr char FEATURE_SpecialCodec[]           = "special-codec";
 inline constexpr char FEATURE_TunneledPlayback[]       = "tunneled-playback";
 
 // from MediaFormat.java
diff --git a/services/audiopolicy/engineconfigurable/config/example/common/audio_policy_engine_criterion_types_aidl.xml.in b/services/audiopolicy/engineconfigurable/config/example/common/audio_policy_engine_criterion_types_aidl.xml.in
index dc2517b..424c983 100644
--- a/services/audiopolicy/engineconfigurable/config/example/common/audio_policy_engine_criterion_types_aidl.xml.in
+++ b/services/audiopolicy/engineconfigurable/config/example/common/audio_policy_engine_criterion_types_aidl.xml.in
@@ -19,76 +19,77 @@
     <criterion_type name="OutputDevicesAddressesType" type="inclusive">
         <values>
             <!-- legacy remote submix -->
-            <value literal="0" numerical="1"/>
+            <value literal="0"/>
         </values>
     </criterion_type>
     <criterion_type name="InputDevicesAddressesType" type="inclusive">
         <values>
             <!-- legacy remote submix -->
-            <value literal="0" numerical="1"/>
+            <value literal="0"/>
         </values>
     </criterion_type>
     <criterion_type name="AndroidModeType" type="exclusive"/>
     <criterion_type name="ForceUseForCommunicationType" type="exclusive">
         <values>
-            <value literal="NONE" numerical="0"/>
-            <value literal="SPEAKER" numerical="1"/>
-            <value literal="BT_SCO" numerical="3"/>
+            <value literal="NONE"/>
+            <value literal="SPEAKER"/>
+            <value literal="BT_SCO"/>
         </values>
     </criterion_type>
     <criterion_type name="ForceUseForMediaType" type="exclusive">
         <values>
-            <value literal="NONE" numerical="0"/>
-            <value literal="SPEAKER" numerical="1"/>
-            <value literal="HEADPHONES" numerical="2"/>
-            <value literal="BT_A2DP" numerical="4"/>
-            <value literal="WIRED_ACCESSORY" numerical="5"/>
-            <value literal="ANALOG_DOCK" numerical="8"/>
-            <value literal="DIGITAL_DOCK" numerical="9"/>
-            <value literal="NO_BT_A2DP" numerical="10"/>
+            <value literal="NONE"/>
+            <value literal="SPEAKER"/>
+            <value literal="HEADPHONES"/>
+            <value literal="BT_A2DP"/>
+            <value literal="ANALOG_DOCK"/>
+            <value literal="DIGITAL_DOCK"/>
+            <value literal="WIRED_ACCESSORY"/>
+            <value literal="NO_BT_A2DP"/>
         </values>
     </criterion_type>
     <criterion_type name="ForceUseForRecordType" type="exclusive">
         <values>
-            <value literal="NONE" numerical="0"/>
-            <value literal="BT_SCO" numerical="3"/>
-            <value literal="WIRED_ACCESSORY" numerical="5"/>
+            <value literal="NONE"/>
+            <value literal="BT_SCO"/>
+            <value literal="WIRED_ACCESSORY"/>
         </values>
     </criterion_type>
     <criterion_type name="ForceUseForDockType" type="exclusive">
         <values>
-            <value literal="NONE" numerical="0"/>
-            <value literal="WIRED_ACCESSORY" numerical="5"/>
-            <value literal="BT_CAR_DOCK" numerical="6"/>
-            <value literal="BT_DESK_DOCK" numerical="7"/>
-            <value literal="ANALOG_DOCK" numerical="8"/>
-            <value literal="DIGITAL_DOCK" numerical="9"/>
+            <value literal="NONE"/>
+            <value literal="BT_CAR_DOCK"/>
+            <value literal="BT_DESK_DOCK"/>
+            <value literal="ANALOG_DOCK"/>
+            <value literal="DIGITAL_DOCK"/>
+            <value literal="WIRED_ACCESSORY"/>
         </values>
     </criterion_type>
     <criterion_type name="ForceUseForSystemType" type="exclusive" >
         <values>
-            <value literal="NONE" numerical="0"/>
-            <value literal="SYSTEM_ENFORCED" numerical="11"/>
+            <value literal="NONE"/>
+            <value literal="SYSTEM_ENFORCED"/>
         </values>
     </criterion_type>
     <criterion_type name="ForceUseForHdmiSystemAudioType" type="exclusive">
         <values>
-            <value literal="NONE" numerical="0"/>
-            <value literal="HDMI_SYSTEM_AUDIO_ENFORCED" numerical="12"/>
+            <value literal="NONE"/>
+            <value literal="HDMI_SYSTEM_AUDIO_ENFORCED"/>
         </values>
     </criterion_type>
     <criterion_type name="ForceUseForEncodedSurroundType" type="exclusive">
         <values>
-            <value literal="NONE" numerical="0"/>
-            <value literal="ENCODED_SURROUND_NEVER" numerical="13"/>
-            <value literal="ENCODED_SURROUND_ALWAYS" numerical="14"/>
-            <value literal="ENCODED_SURROUND_MANUAL" numerical="15"/>
+            <value literal="UNSPECIFIED"/>
+            <value literal="NEVER"/>
+            <value literal="ALWAYS"/>
+            <value literal="MANUAL"/>
         </values>
     </criterion_type>
     <criterion_type name="ForceUseForVibrateRingingType" type="exclusive">
         <values>
-            <value literal="NONE" numerical="0"/>
-            <value literal="BT_SCO" numerical="3"/>
+            <value literal="NONE"/>
+            <value literal="BT_SCO"/>
+            <value literal="BT_BLE"/>
         </values>
     </criterion_type>
 </criterion_types>
diff --git a/services/audiopolicy/engineconfigurable/config/src/CapEngineConfig.cpp b/services/audiopolicy/engineconfigurable/config/src/CapEngineConfig.cpp
index b72e517..b89fba0 100644
--- a/services/audiopolicy/engineconfigurable/config/src/CapEngineConfig.cpp
+++ b/services/audiopolicy/engineconfigurable/config/src/CapEngineConfig.cpp
@@ -41,21 +41,23 @@
 
 namespace android {
 
-using utilities::convertTo;
+using base::unexpected;
 using media::audio::common::AudioDeviceAddress;
 using media::audio::common::AudioDeviceDescription;
 using media::audio::common::AudioHalCapCriterion;
+using media::audio::common::AudioHalCapCriterionV2;
 using media::audio::common::AudioHalCapParameter;
 using media::audio::common::AudioHalCapRule;
+using media::audio::common::AudioPolicyForceUse;
 using media::audio::common::AudioSource;
 using media::audio::common::AudioStreamType;
-using media::audio::common::AudioHalCapCriterionV2;
-using ::android::base::unexpected;
+using utilities::convertTo;
 
 namespace capEngineConfig {
 
 static constexpr const char *gLegacyOutputDevicePrefix = "AUDIO_DEVICE_OUT_";
 static constexpr const char *gLegacyInputDevicePrefix = "AUDIO_DEVICE_IN_";
+static constexpr const char *gLegacyForcePrefix = "AUDIO_POLICY_FORCE_";
 static constexpr const char *gLegacyStreamPrefix = "AUDIO_STREAM_";
 static constexpr const char *gLegacySourcePrefix = "AUDIO_SOURCE_";
 static constexpr const char *gPolicyParamPrefix = "/Policy/policy/";
@@ -83,6 +85,134 @@
     return capName;
 }
 
+ConversionResult<audio_policy_forced_cfg_t>
+        aidl2legacy_AudioPolicyForceUseCommunicationDeviceCategory_audio_policy_forced_cfg_t(
+        const AudioPolicyForceUse::CommunicationDeviceCategory aidl) {
+    switch (aidl) {
+        case AudioPolicyForceUse::CommunicationDeviceCategory::NONE:
+            return AUDIO_POLICY_FORCE_NONE;
+        case AudioPolicyForceUse::CommunicationDeviceCategory::SPEAKER:
+            return AUDIO_POLICY_FORCE_SPEAKER;
+        case AudioPolicyForceUse::CommunicationDeviceCategory::BT_SCO:
+            return AUDIO_POLICY_FORCE_BT_SCO;
+        case AudioPolicyForceUse::CommunicationDeviceCategory::BT_BLE:
+            return AUDIO_POLICY_FORCE_BT_BLE;
+        case AudioPolicyForceUse::CommunicationDeviceCategory::WIRED_ACCESSORY:
+            return AUDIO_POLICY_FORCE_WIRED_ACCESSORY;
+    }
+    return unexpected(BAD_VALUE);
+}
+
+ConversionResult<audio_policy_forced_cfg_t>
+        aidl2legacy_AudioPolicyForceUseMediaDeviceCategory_audio_policy_forced_cfg_t(
+        const AudioPolicyForceUse::MediaDeviceCategory aidl) {
+    switch (aidl) {
+        case AudioPolicyForceUse::MediaDeviceCategory::NONE:
+            return AUDIO_POLICY_FORCE_NONE;
+        case AudioPolicyForceUse::MediaDeviceCategory::SPEAKER:
+            return AUDIO_POLICY_FORCE_SPEAKER;
+        case AudioPolicyForceUse::MediaDeviceCategory::HEADPHONES:
+            return AUDIO_POLICY_FORCE_HEADPHONES;
+        case AudioPolicyForceUse::MediaDeviceCategory::BT_A2DP:
+            return AUDIO_POLICY_FORCE_BT_A2DP;
+        case AudioPolicyForceUse::MediaDeviceCategory::ANALOG_DOCK:
+            return AUDIO_POLICY_FORCE_ANALOG_DOCK;
+        case AudioPolicyForceUse::MediaDeviceCategory::DIGITAL_DOCK:
+            return AUDIO_POLICY_FORCE_DIGITAL_DOCK;
+        case AudioPolicyForceUse::MediaDeviceCategory::WIRED_ACCESSORY:
+            return AUDIO_POLICY_FORCE_WIRED_ACCESSORY;
+        case AudioPolicyForceUse::MediaDeviceCategory::NO_BT_A2DP:
+            return AUDIO_POLICY_FORCE_NO_BT_A2DP;
+    }
+    return unexpected(BAD_VALUE);
+}
+
+ConversionResult<audio_policy_forced_cfg_t>
+        aidl2legacy_AudioPolicyForceUseDockType_audio_policy_forced_cfg_t(
+        const AudioPolicyForceUse::DockType aidl) {
+    switch (aidl) {
+        case AudioPolicyForceUse::DockType::NONE:
+            return AUDIO_POLICY_FORCE_NONE;
+        case AudioPolicyForceUse::DockType::BT_CAR_DOCK:
+            return AUDIO_POLICY_FORCE_BT_CAR_DOCK;
+        case AudioPolicyForceUse::DockType::BT_DESK_DOCK:
+            return AUDIO_POLICY_FORCE_BT_DESK_DOCK;
+        case AudioPolicyForceUse::DockType::ANALOG_DOCK:
+            return AUDIO_POLICY_FORCE_ANALOG_DOCK;
+        case AudioPolicyForceUse::DockType::DIGITAL_DOCK:
+            return AUDIO_POLICY_FORCE_DIGITAL_DOCK;
+        case AudioPolicyForceUse::DockType::WIRED_ACCESSORY:
+            return AUDIO_POLICY_FORCE_WIRED_ACCESSORY;
+    }
+    return unexpected(BAD_VALUE);
+}
+
+ConversionResult<audio_policy_forced_cfg_t>
+        aidl2legacy_AudioPolicyForceUseEncodedSurroundConfig_audio_policy_forced_cfg_t(
+        const AudioPolicyForceUse::EncodedSurroundConfig aidl) {
+    switch (aidl) {
+        case AudioPolicyForceUse::EncodedSurroundConfig::UNSPECIFIED:
+            return AUDIO_POLICY_FORCE_NONE;
+        case AudioPolicyForceUse::EncodedSurroundConfig::NEVER:
+            return AUDIO_POLICY_FORCE_ENCODED_SURROUND_NEVER;
+        case AudioPolicyForceUse::EncodedSurroundConfig::ALWAYS:
+            return AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS;
+        case AudioPolicyForceUse::EncodedSurroundConfig::MANUAL:
+            return AUDIO_POLICY_FORCE_ENCODED_SURROUND_MANUAL;
+    }
+    return unexpected(BAD_VALUE);
+}
+
+ConversionResult<std::pair<audio_policy_force_use_t, audio_policy_forced_cfg_t>>
+        aidl2legacy_AudioPolicyForceUse_audio_policy_force_use_t_audio_policy_forced_cfg_t(
+        const AudioPolicyForceUse& aidl) {
+    switch (aidl.getTag()) {
+        case AudioPolicyForceUse::forCommunication:
+            return std::make_pair(
+                    AUDIO_POLICY_FORCE_FOR_COMMUNICATION,
+                    VALUE_OR_RETURN(
+                            aidl2legacy_AudioPolicyForceUseCommunicationDeviceCategory_audio_policy_forced_cfg_t(
+                                    aidl.get<AudioPolicyForceUse::forCommunication>())));
+        case AudioPolicyForceUse::forMedia:
+            return std::make_pair(
+                    AUDIO_POLICY_FORCE_FOR_MEDIA,
+                    VALUE_OR_RETURN(
+                            aidl2legacy_AudioPolicyForceUseMediaDeviceCategory_audio_policy_forced_cfg_t(
+                                    aidl.get<AudioPolicyForceUse::forMedia>())));
+        case AudioPolicyForceUse::forRecord:
+            return std::make_pair(
+                    AUDIO_POLICY_FORCE_FOR_RECORD,
+                    VALUE_OR_RETURN(
+                            aidl2legacy_AudioPolicyForceUseCommunicationDeviceCategory_audio_policy_forced_cfg_t(
+                                    aidl.get<AudioPolicyForceUse::forRecord>())));
+        case AudioPolicyForceUse::dock:
+            return std::make_pair(AUDIO_POLICY_FORCE_FOR_DOCK,
+                    VALUE_OR_RETURN(
+                            aidl2legacy_AudioPolicyForceUseDockType_audio_policy_forced_cfg_t(
+                                    aidl.get<AudioPolicyForceUse::dock>())));
+        case AudioPolicyForceUse::systemSounds:
+            return std::make_pair(AUDIO_POLICY_FORCE_FOR_SYSTEM,
+                    aidl.get<AudioPolicyForceUse::systemSounds>() ?
+                    AUDIO_POLICY_FORCE_SYSTEM_ENFORCED : AUDIO_POLICY_FORCE_NONE);
+        case AudioPolicyForceUse::hdmiSystemAudio:
+            return std::make_pair(
+                    AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO,
+                    aidl.get<AudioPolicyForceUse::hdmiSystemAudio>() ?
+                    AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED : AUDIO_POLICY_FORCE_NONE);
+        case AudioPolicyForceUse::encodedSurround:
+            return std::make_pair(AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND, VALUE_OR_RETURN(
+                aidl2legacy_AudioPolicyForceUseEncodedSurroundConfig_audio_policy_forced_cfg_t(
+                        aidl.get<AudioPolicyForceUse::encodedSurround>())));
+        case AudioPolicyForceUse::forVibrateRinging:
+            return std::make_pair(
+                    AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING,
+                    VALUE_OR_RETURN(
+                            aidl2legacy_AudioPolicyForceUseCommunicationDeviceCategory_audio_policy_forced_cfg_t(
+                                    aidl.get<AudioPolicyForceUse::forVibrateRinging>())));
+    }
+    return unexpected(BAD_VALUE);
+}
+
 ConversionResult<std::string> aidl2legacy_AudioHalCapCriterionV2_CapName(
         const AudioHalCapCriterionV2& aidl) {
     switch (aidl.getTag()) {
@@ -97,14 +227,14 @@
         case AudioHalCapCriterionV2::telephonyMode:
             return gPhoneStateCriterionName;
         case AudioHalCapCriterionV2::forceConfigForUse: {
-            auto aidlCriterion = aidl.get<AudioHalCapCriterionV2::forceConfigForUse>();
-            return gForceUseCriterionTag[VALUE_OR_RETURN(
-                    aidl2legacy_AudioPolicyForceUse_audio_policy_force_use_t(
-                            aidlCriterion.forceUse))];
+            auto aidlCriterion = aidl.get<AudioHalCapCriterionV2::forceConfigForUse>().values[0];
+            const auto [forceUse, _] = VALUE_OR_RETURN(
+                aidl2legacy_AudioPolicyForceUse_audio_policy_force_use_t_audio_policy_forced_cfg_t(
+                        aidlCriterion));
+            return gForceUseCriterionTag[forceUse];
         }
-        default:
-            return unexpected(BAD_VALUE);
     }
+    return unexpected(BAD_VALUE);
 }
 
 ConversionResult<std::string> aidl2legacy_AudioHalCapCriterionV2TypeDevice_CapCriterionValue(
@@ -121,6 +251,32 @@
             isOut ? gLegacyOutputDevicePrefix : gLegacyInputDevicePrefix);
 }
 
+ConversionResult<audio_policy_forced_cfg_t>
+        aidl2legacy_AudioHalCapCriterionV2ForceUse_audio_policy_forced_cfg_t(
+        const AudioPolicyForceUse& aidl) {
+    const auto [_, legacyForcedCfg] = VALUE_OR_RETURN(
+            aidl2legacy_AudioPolicyForceUse_audio_policy_force_use_t_audio_policy_forced_cfg_t(
+                    aidl));
+    return legacyForcedCfg;
+}
+
+ConversionResult<std::string> audio_policy_forced_cfg_t_CapCriterionValue(
+        audio_policy_forced_cfg_t legacyForcedCfg) {
+    std::string legacyForcedCfgLiteral = audio_policy_forced_cfg_to_string(legacyForcedCfg);
+    if (legacyForcedCfgLiteral.empty()) {
+        ALOGE("%s Invalid forced config value %d", __func__, legacyForcedCfg);
+        return unexpected(BAD_VALUE);
+    }
+    return truncatePrefix(legacyForcedCfgLiteral, gLegacyForcePrefix);
+}
+
+ConversionResult<std::string> aidl2legacy_AudioHalCapCriterionV2ForceUse_CapCriterionValue(
+        const AudioPolicyForceUse& aidl) {
+    const audio_policy_forced_cfg_t legacyForcedCfg = VALUE_OR_RETURN(
+            aidl2legacy_AudioHalCapCriterionV2ForceUse_audio_policy_forced_cfg_t(aidl));
+    return audio_policy_forced_cfg_t_CapCriterionValue(legacyForcedCfg);
+}
+
 ConversionResult<std::string> aidl2legacy_AudioHalCapCriterionV2Type_CapCriterionValue(
         const AudioHalCapCriterionV2& aidl) {
     switch (aidl.getTag()) {
@@ -139,10 +295,10 @@
         case AudioHalCapCriterionV2::telephonyMode:
             return toString(aidl.get<AudioHalCapCriterionV2::telephonyMode>().values[0]);
         case AudioHalCapCriterionV2::forceConfigForUse:
-            return toString(aidl.get<AudioHalCapCriterionV2::forceConfigForUse>().values[0]);
-        default:
-            return unexpected(BAD_VALUE);
+            return aidl2legacy_AudioHalCapCriterionV2ForceUse_CapCriterionValue(
+                    aidl.get<AudioHalCapCriterionV2::forceConfigForUse>().values[0]);
     }
+    return unexpected(BAD_VALUE);
 }
 
 ConversionResult<std::string> aidl2legacy_AudioHalCapRule_CapRule(
@@ -331,24 +487,28 @@
     engineConfig::Criterion& criterion = capCriterion.criterion;
     engineConfig::CriterionType& criterionType = capCriterion.criterionType;
 
-    auto loadForceUseCriterion = [](const auto &aidlCriterion, auto &criterion,
-            auto &criterionType) -> status_t {
-        uint32_t legacyForceUse = VALUE_OR_RETURN_STATUS(
-                aidl2legacy_AudioPolicyForceUse_audio_policy_force_use_t(
-                        aidlCriterion.forceUse));
+    auto loadForceUseCriterion = [](const auto& aidlCriterion, auto& criterion,
+                                    auto& criterionType) -> status_t {
+        if (aidlCriterion.values.empty()) {
+            return BAD_VALUE;
+        }
+        const auto [legacyForceUse, _] = VALUE_OR_RETURN_STATUS(
+                aidl2legacy_AudioPolicyForceUse_audio_policy_force_use_t_audio_policy_forced_cfg_t(
+                        aidlCriterion.values[0]));
         criterion.typeName = criterionType.name;
         criterionType.name = criterion.typeName + gCriterionTypeSuffix;
         criterionType.isInclusive =
                 (aidlCriterion.logic == AudioHalCapCriterionV2::LogicalDisjunction::INCLUSIVE);
         criterion.name = gForceUseCriterionTag[legacyForceUse];
-        criterion.defaultLiteralValue = toString(aidlCriterion.defaultValue);
-        if (aidlCriterion.values.empty()) {
-            return BAD_VALUE;
-        }
+        criterion.defaultLiteralValue = toString(
+                aidlCriterion.defaultValue.template get<AudioPolicyForceUse::forMedia>());
         for (auto &value : aidlCriterion.values) {
-            uint32_t legacyForcedConfig = VALUE_OR_RETURN_STATUS(
-                    aidl2legacy_AudioPolicyForcedConfig_audio_policy_forced_cfg_t(value));
-            criterionType.valuePairs.push_back({legacyForcedConfig, 0, toString(value)});
+            const audio_policy_forced_cfg_t legacyForcedCfg = VALUE_OR_RETURN_STATUS(
+                    aidl2legacy_AudioHalCapCriterionV2ForceUse_audio_policy_forced_cfg_t(value));
+            const std::string legacyForcedCfgLiteral = VALUE_OR_RETURN_STATUS(
+                    audio_policy_forced_cfg_t_CapCriterionValue(legacyForcedCfg));
+            criterionType.valuePairs.push_back(
+                    {legacyForcedCfg, 0, legacyForcedCfgLiteral});
         }
         return NO_ERROR;
     };
diff --git a/services/audiopolicy/engineconfigurable/tools/capBuildPolicyCriterionTypes.py b/services/audiopolicy/engineconfigurable/tools/capBuildPolicyCriterionTypes.py
index b873830..1adc602 100755
--- a/services/audiopolicy/engineconfigurable/tools/capBuildPolicyCriterionTypes.py
+++ b/services/audiopolicy/engineconfigurable/tools/capBuildPolicyCriterionTypes.py
@@ -102,7 +102,6 @@
                 ordered_values = OrderedDict(sorted(values_dict.items(), key=lambda x: x[1]))
                 for key, value in ordered_values.items():
                     value_node = ET.SubElement(values_node, "value")
-                    value_node.set('numerical', str(value))
                     value_node.set('literal', key)
 
                     if criterion_type.get('name') == "OutputDevicesMaskType":
@@ -114,20 +113,14 @@
         for criterion_name, values_list in addressCriteria.items():
             for criterion_type in criterion_types_root.findall('criterion_type'):
                 if criterion_type.get('name') == criterion_name:
-                    index = 0
                     existing_values_node = criterion_type.find("values")
                     if existing_values_node is not None:
-                        for existing_value in existing_values_node.findall('value'):
-                            if existing_value.get('numerical') == str(1 << index):
-                                index += 1
                         values_node = existing_values_node
                     else:
                         values_node = ET.SubElement(criterion_type, "values")
 
                     for value in values_list:
                         value_node = ET.SubElement(values_node, "value", literal=value)
-                        value_node.set('numerical', str(1 << index))
-                        index += 1
 
     xmlstr = ET.tostring(criterion_types_root, encoding='utf8', method='xml')
     reparsed = MINIDOM.parseString(xmlstr)
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index b2f0c22..768cd07 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -60,8 +60,6 @@
 using media::audio::common::AudioFormatDescription;
 using media::audio::common::AudioMode;
 using media::audio::common::AudioOffloadInfo;
-using media::audio::common::AudioPolicyForceUse;
-using media::audio::common::AudioPolicyForcedConfig;
 using media::audio::common::AudioSource;
 using media::audio::common::AudioStreamType;
 using media::audio::common::AudioUsage;
@@ -255,8 +253,8 @@
     return Status::ok();
 }
 
-Status AudioPolicyService::setForceUse(AudioPolicyForceUse usageAidl,
-                                       AudioPolicyForcedConfig configAidl)
+Status AudioPolicyService::setForceUse(media::AudioPolicyForceUse usageAidl,
+                                       media::AudioPolicyForcedConfig configAidl)
 {
     audio_policy_force_use_t usage = VALUE_OR_RETURN_BINDER_STATUS(
             aidl2legacy_AudioPolicyForceUse_audio_policy_force_use_t(usageAidl));
@@ -285,8 +283,8 @@
     return Status::ok();
 }
 
-Status AudioPolicyService::getForceUse(AudioPolicyForceUse usageAidl,
-                                       AudioPolicyForcedConfig* _aidl_return) {
+Status AudioPolicyService::getForceUse(media::AudioPolicyForceUse usageAidl,
+                                       media::AudioPolicyForcedConfig* _aidl_return) {
     audio_policy_force_use_t usage = VALUE_OR_RETURN_BINDER_STATUS(
             aidl2legacy_AudioPolicyForceUse_audio_policy_force_use_t(usageAidl));
 
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index eccefa7..428e560 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -105,10 +105,10 @@
             const std::string& deviceName,
             const AudioFormatDescription& encodedFormat) override;
     binder::Status setPhoneState(AudioMode state, int32_t uid) override;
-    binder::Status setForceUse(android::media::audio::common::AudioPolicyForceUse usage,
-            android::media::audio::common::AudioPolicyForcedConfig config) override;
-    binder::Status getForceUse(android::media::audio::common::AudioPolicyForceUse usage,
-            android::media::audio::common::AudioPolicyForcedConfig* _aidl_return) override;
+    binder::Status setForceUse(media::AudioPolicyForceUse usage,
+                               media::AudioPolicyForcedConfig config) override;
+    binder::Status getForceUse(media::AudioPolicyForceUse usage,
+                               media::AudioPolicyForcedConfig* _aidl_return) override;
     binder::Status getOutput(AudioStreamType stream, int32_t* _aidl_return) override;
     binder::Status getOutputForAttr(const media::audio::common::AudioAttributes& attr,
                                     int32_t session,