Merge "Check for MGF1 digests in key characteristics."
diff --git a/audio/aidl/Android.bp b/audio/aidl/Android.bp
index 515787e..4038ab5 100644
--- a/audio/aidl/Android.bp
+++ b/audio/aidl/Android.bp
@@ -42,7 +42,7 @@
         "android/hardware/audio/common/SinkMetadata.aidl",
         "android/hardware/audio/common/SourceMetadata.aidl",
     ],
-    frozen: false,
+    frozen: true,
     imports: [
         "android.media.audio.common.types-V2",
     ],
@@ -71,6 +71,11 @@
             version: "1",
             imports: ["android.media.audio.common.types-V2"],
         },
+        {
+            version: "2",
+            imports: ["android.media.audio.common.types-V2"],
+        },
+
         // IMPORTANT: Update latest_android_hardware_audio_common every time you
         // add the latest frozen version to versions_with_info
     ],
@@ -147,9 +152,22 @@
         },
     },
     versions_with_info: [
+        {
+            version: "1",
+            imports: [
+                "android.hardware.common-V2",
+                "android.hardware.common.fmq-V1",
+                "android.hardware.audio.common-V2",
+                "android.hardware.audio.core.sounddose-V1",
+                "android.hardware.audio.effect-V1",
+                "android.media.audio.common.types-V2",
+            ],
+        },
+
         // IMPORTANT: Update latest_android_hardware_audio_core every time you
         // add the latest frozen version to versions_with_info
     ],
+    frozen: true,
 }
 
 // Note: This should always be one version ahead of the last frozen version
@@ -194,9 +212,15 @@
         },
     },
     versions_with_info: [
+        {
+            version: "1",
+            imports: ["android.media.audio.common.types-V2"],
+        },
+
         // IMPORTANT: Update latest_android_hardware_audio_core_sounddose every time you
         // add the latest frozen version to versions_with_info
     ],
+    frozen: true,
 }
 
 // Note: This should always be one version ahead of the last frozen version
@@ -268,6 +292,19 @@
             sdk_version: "module_current",
         },
     },
+    frozen: true,
+    versions_with_info: [
+        {
+            version: "1",
+            imports: [
+                "android.hardware.common-V2",
+                "android.hardware.common.fmq-V1",
+                "android.hardware.audio.common-V2",
+                "android.media.audio.common.types-V2",
+            ],
+        },
+    ],
+
 }
 
 latest_android_hardware_audio_effect = "android.hardware.audio.effect-V1"
diff --git a/audio/aidl/aidl_api/android.hardware.audio.common/2/.hash b/audio/aidl/aidl_api/android.hardware.audio.common/2/.hash
new file mode 100644
index 0000000..6f56a4c
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.common/2/.hash
@@ -0,0 +1 @@
+6780ccb29120b4c7d3ed60f55a23c13b0431f3a4
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl b/audio/aidl/aidl_api/android.hardware.audio.common/2/android/hardware/audio/common/AudioOffloadMetadata.aidl
similarity index 82%
copy from media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
copy to audio/aidl/aidl_api/android.hardware.audio.common/2/android/hardware/audio/common/AudioOffloadMetadata.aidl
index 1c9bf8d..000504b 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.common/2/android/hardware/audio/common/AudioOffloadMetadata.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2023 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.
@@ -31,11 +31,12 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.media.c2;
-@VintfStability
-parcelable SurfaceSyncObj {
-  android.hardware.common.NativeHandle syncMemory;
-  long bqId;
-  int generationId;
-  long consumerUsage;
+package android.hardware.audio.common;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable AudioOffloadMetadata {
+  int sampleRate;
+  android.media.audio.common.AudioChannelLayout channelMask;
+  int averageBitRatePerSecond;
+  int delayFrames;
+  int paddingFrames;
 }
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl b/audio/aidl/aidl_api/android.hardware.audio.common/2/android/hardware/audio/common/PlaybackTrackMetadata.aidl
similarity index 74%
copy from media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
copy to audio/aidl/aidl_api/android.hardware.audio.common/2/android/hardware/audio/common/PlaybackTrackMetadata.aidl
index 1c9bf8d..be4941c 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.common/2/android/hardware/audio/common/PlaybackTrackMetadata.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022 The Android Open Source Project
+ * 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.
@@ -31,11 +31,13 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.media.c2;
-@VintfStability
-parcelable SurfaceSyncObj {
-  android.hardware.common.NativeHandle syncMemory;
-  long bqId;
-  int generationId;
-  long consumerUsage;
+package android.hardware.audio.common;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable PlaybackTrackMetadata {
+  android.media.audio.common.AudioUsage usage = android.media.audio.common.AudioUsage.INVALID;
+  android.media.audio.common.AudioContentType contentType = android.media.audio.common.AudioContentType.UNKNOWN;
+  float gain;
+  android.media.audio.common.AudioChannelLayout channelMask;
+  @nullable android.media.audio.common.AudioDevice sourceDevice;
+  @utf8InCpp String[] tags;
 }
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl b/audio/aidl/aidl_api/android.hardware.audio.common/2/android/hardware/audio/common/RecordTrackMetadata.aidl
similarity index 77%
copy from media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
copy to audio/aidl/aidl_api/android.hardware.audio.common/2/android/hardware/audio/common/RecordTrackMetadata.aidl
index 1c9bf8d..8f667d1 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.common/2/android/hardware/audio/common/RecordTrackMetadata.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022 The Android Open Source Project
+ * 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.
@@ -31,11 +31,12 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.media.c2;
-@VintfStability
-parcelable SurfaceSyncObj {
-  android.hardware.common.NativeHandle syncMemory;
-  long bqId;
-  int generationId;
-  long consumerUsage;
+package android.hardware.audio.common;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable RecordTrackMetadata {
+  android.media.audio.common.AudioSource source = android.media.audio.common.AudioSource.SYS_RESERVED_INVALID;
+  float gain;
+  @nullable android.media.audio.common.AudioDevice destinationDevice;
+  android.media.audio.common.AudioChannelLayout channelMask;
+  @utf8InCpp String[] tags;
 }
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl b/audio/aidl/aidl_api/android.hardware.audio.common/2/android/hardware/audio/common/SinkMetadata.aidl
similarity index 86%
copy from media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
copy to audio/aidl/aidl_api/android.hardware.audio.common/2/android/hardware/audio/common/SinkMetadata.aidl
index 1c9bf8d..270147d 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.common/2/android/hardware/audio/common/SinkMetadata.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022 The Android Open Source Project
+ * 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.
@@ -31,11 +31,8 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.media.c2;
-@VintfStability
-parcelable SurfaceSyncObj {
-  android.hardware.common.NativeHandle syncMemory;
-  long bqId;
-  int generationId;
-  long consumerUsage;
+package android.hardware.audio.common;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable SinkMetadata {
+  android.hardware.audio.common.RecordTrackMetadata[] tracks;
 }
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl b/audio/aidl/aidl_api/android.hardware.audio.common/2/android/hardware/audio/common/SourceMetadata.aidl
similarity index 86%
copy from media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
copy to audio/aidl/aidl_api/android.hardware.audio.common/2/android/hardware/audio/common/SourceMetadata.aidl
index 1c9bf8d..2d4a982 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.common/2/android/hardware/audio/common/SourceMetadata.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022 The Android Open Source Project
+ * 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.
@@ -31,11 +31,8 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.media.c2;
-@VintfStability
-parcelable SurfaceSyncObj {
-  android.hardware.common.NativeHandle syncMemory;
-  long bqId;
-  int generationId;
-  long consumerUsage;
+package android.hardware.audio.common;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable SourceMetadata {
+  android.hardware.audio.common.PlaybackTrackMetadata[] tracks;
 }
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core.sounddose/1/.hash b/audio/aidl/aidl_api/android.hardware.audio.core.sounddose/1/.hash
new file mode 100644
index 0000000..270b1c9
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.core.sounddose/1/.hash
@@ -0,0 +1 @@
+7913a7ff584002e6889416e5dddbe46878d0a51e
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl b/audio/aidl/aidl_api/android.hardware.audio.core.sounddose/1/android/hardware/audio/core/sounddose/ISoundDose.aidl
similarity index 68%
copy from media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
copy to audio/aidl/aidl_api/android.hardware.audio.core.sounddose/1/android/hardware/audio/core/sounddose/ISoundDose.aidl
index 1c9bf8d..5800091 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.core.sounddose/1/android/hardware/audio/core/sounddose/ISoundDose.aidl
@@ -31,11 +31,22 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.media.c2;
+package android.hardware.audio.core.sounddose;
 @VintfStability
-parcelable SurfaceSyncObj {
-  android.hardware.common.NativeHandle syncMemory;
-  long bqId;
-  int generationId;
-  long consumerUsage;
+interface ISoundDose {
+  void setOutputRs2UpperBound(float rs2ValueDbA);
+  float getOutputRs2UpperBound();
+  void registerSoundDoseCallback(in android.hardware.audio.core.sounddose.ISoundDose.IHalSoundDoseCallback callback);
+  const int DEFAULT_MAX_RS2 = 100;
+  const int MIN_RS2 = 80;
+  @VintfStability
+  interface IHalSoundDoseCallback {
+    oneway void onMomentaryExposureWarning(float currentDbA, in android.media.audio.common.AudioDevice audioDevice);
+    oneway void onNewMelValues(in android.hardware.audio.core.sounddose.ISoundDose.IHalSoundDoseCallback.MelRecord melRecord, in android.media.audio.common.AudioDevice audioDevice);
+    @VintfStability
+    parcelable MelRecord {
+      float[] melValues;
+      long timestamp;
+    }
+  }
 }
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/1/.hash b/audio/aidl/aidl_api/android.hardware.audio.core/1/.hash
new file mode 100644
index 0000000..8eb6be5
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/1/.hash
@@ -0,0 +1 @@
+1cec1e67515bdd2b896d80d20a64bf899b2470bf
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/AudioPatch.aidl
similarity index 86%
copy from media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
copy to audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/AudioPatch.aidl
index 1c9bf8d..078b5ea 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/AudioPatch.aidl
@@ -31,11 +31,12 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.media.c2;
-@VintfStability
-parcelable SurfaceSyncObj {
-  android.hardware.common.NativeHandle syncMemory;
-  long bqId;
-  int generationId;
-  long consumerUsage;
+package android.hardware.audio.core;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable AudioPatch {
+  int id;
+  int[] sourcePortConfigIds;
+  int[] sinkPortConfigIds;
+  int minimumStreamBufferSizeFrames;
+  int[] latenciesMs;
 }
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/AudioRoute.aidl
similarity index 89%
copy from media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
copy to audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/AudioRoute.aidl
index 1c9bf8d..deeef87 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/AudioRoute.aidl
@@ -31,11 +31,10 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.media.c2;
-@VintfStability
-parcelable SurfaceSyncObj {
-  android.hardware.common.NativeHandle syncMemory;
-  long bqId;
-  int generationId;
-  long consumerUsage;
+package android.hardware.audio.core;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable AudioRoute {
+  int[] sourcePortIds;
+  int sinkPortId;
+  boolean isExclusive;
 }
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IBluetooth.aidl
similarity index 60%
copy from media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
copy to audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IBluetooth.aidl
index 1c9bf8d..9357a15 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IBluetooth.aidl
@@ -31,11 +31,31 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.media.c2;
+package android.hardware.audio.core;
 @VintfStability
-parcelable SurfaceSyncObj {
-  android.hardware.common.NativeHandle syncMemory;
-  long bqId;
-  int generationId;
-  long consumerUsage;
+interface IBluetooth {
+  android.hardware.audio.core.IBluetooth.ScoConfig setScoConfig(in android.hardware.audio.core.IBluetooth.ScoConfig config);
+  android.hardware.audio.core.IBluetooth.HfpConfig setHfpConfig(in android.hardware.audio.core.IBluetooth.HfpConfig config);
+  @JavaDerive(equals=true, toString=true) @VintfStability
+  parcelable ScoConfig {
+    @nullable android.media.audio.common.Boolean isEnabled;
+    @nullable android.media.audio.common.Boolean isNrecEnabled;
+    android.hardware.audio.core.IBluetooth.ScoConfig.Mode mode = android.hardware.audio.core.IBluetooth.ScoConfig.Mode.UNSPECIFIED;
+    @nullable @utf8InCpp String debugName;
+    @VintfStability
+    enum Mode {
+      UNSPECIFIED,
+      SCO,
+      SCO_WB,
+      SCO_SWB,
+    }
+  }
+  @JavaDerive(equals=true, toString=true) @VintfStability
+  parcelable HfpConfig {
+    @nullable android.media.audio.common.Boolean isEnabled;
+    @nullable android.media.audio.common.Int sampleRate;
+    @nullable android.media.audio.common.Float volume;
+    const int VOLUME_MIN = 0;
+    const int VOLUME_MAX = 1;
+  }
 }
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IBluetoothA2dp.aidl
similarity index 83%
copy from media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
copy to audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IBluetoothA2dp.aidl
index 1c9bf8d..0f4c46d 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IBluetoothA2dp.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2023 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.
@@ -31,11 +31,11 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.media.c2;
+package android.hardware.audio.core;
 @VintfStability
-parcelable SurfaceSyncObj {
-  android.hardware.common.NativeHandle syncMemory;
-  long bqId;
-  int generationId;
-  long consumerUsage;
+interface IBluetoothA2dp {
+  boolean isEnabled();
+  void setEnabled(boolean enabled);
+  boolean supportsOffloadReconfiguration();
+  void reconfigureOffload(in android.hardware.audio.core.VendorParameter[] parameters);
 }
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IBluetoothLe.aidl
similarity index 83%
copy from media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
copy to audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IBluetoothLe.aidl
index 1c9bf8d..2068daf 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IBluetoothLe.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2023 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.
@@ -31,11 +31,11 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.media.c2;
+package android.hardware.audio.core;
 @VintfStability
-parcelable SurfaceSyncObj {
-  android.hardware.common.NativeHandle syncMemory;
-  long bqId;
-  int generationId;
-  long consumerUsage;
+interface IBluetoothLe {
+  boolean isEnabled();
+  void setEnabled(boolean enabled);
+  boolean supportsOffloadReconfiguration();
+  void reconfigureOffload(in android.hardware.audio.core.VendorParameter[] parameters);
 }
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IConfig.aidl
similarity index 88%
copy from media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
copy to audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IConfig.aidl
index 1c9bf8d..9ce45bb 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IConfig.aidl
@@ -31,11 +31,9 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.media.c2;
+package android.hardware.audio.core;
 @VintfStability
-parcelable SurfaceSyncObj {
-  android.hardware.common.NativeHandle syncMemory;
-  long bqId;
-  int generationId;
-  long consumerUsage;
+interface IConfig {
+  android.hardware.audio.core.SurroundSoundConfig getSurroundSoundConfig();
+  android.media.audio.common.AudioHalEngineConfig getEngineConfig();
 }
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IModule.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IModule.aidl
new file mode 100644
index 0000000..e14e9c0
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IModule.aidl
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.core;
+@VintfStability
+interface IModule {
+  void setModuleDebug(in android.hardware.audio.core.ModuleDebug debug);
+  @nullable android.hardware.audio.core.ITelephony getTelephony();
+  @nullable android.hardware.audio.core.IBluetooth getBluetooth();
+  @nullable android.hardware.audio.core.IBluetoothA2dp getBluetoothA2dp();
+  @nullable android.hardware.audio.core.IBluetoothLe getBluetoothLe();
+  android.media.audio.common.AudioPort connectExternalDevice(in android.media.audio.common.AudioPort templateIdAndAdditionalData);
+  void disconnectExternalDevice(int portId);
+  android.hardware.audio.core.AudioPatch[] getAudioPatches();
+  android.media.audio.common.AudioPort getAudioPort(int portId);
+  android.media.audio.common.AudioPortConfig[] getAudioPortConfigs();
+  android.media.audio.common.AudioPort[] getAudioPorts();
+  android.hardware.audio.core.AudioRoute[] getAudioRoutes();
+  android.hardware.audio.core.AudioRoute[] getAudioRoutesForAudioPort(int portId);
+  android.hardware.audio.core.IModule.OpenInputStreamReturn openInputStream(in android.hardware.audio.core.IModule.OpenInputStreamArguments args);
+  android.hardware.audio.core.IModule.OpenOutputStreamReturn openOutputStream(in android.hardware.audio.core.IModule.OpenOutputStreamArguments args);
+  android.hardware.audio.core.IModule.SupportedPlaybackRateFactors getSupportedPlaybackRateFactors();
+  android.hardware.audio.core.AudioPatch setAudioPatch(in android.hardware.audio.core.AudioPatch requested);
+  boolean setAudioPortConfig(in android.media.audio.common.AudioPortConfig requested, out android.media.audio.common.AudioPortConfig suggested);
+  void resetAudioPatch(int patchId);
+  void resetAudioPortConfig(int portConfigId);
+  boolean getMasterMute();
+  void setMasterMute(boolean mute);
+  float getMasterVolume();
+  void setMasterVolume(float volume);
+  boolean getMicMute();
+  void setMicMute(boolean mute);
+  android.media.audio.common.MicrophoneInfo[] getMicrophones();
+  void updateAudioMode(android.media.audio.common.AudioMode mode);
+  void updateScreenRotation(android.hardware.audio.core.IModule.ScreenRotation rotation);
+  void updateScreenState(boolean isTurnedOn);
+  @nullable android.hardware.audio.core.sounddose.ISoundDose getSoundDose();
+  int generateHwAvSyncId();
+  android.hardware.audio.core.VendorParameter[] getVendorParameters(in @utf8InCpp String[] ids);
+  void setVendorParameters(in android.hardware.audio.core.VendorParameter[] parameters, boolean async);
+  void addDeviceEffect(int portConfigId, in android.hardware.audio.effect.IEffect effect);
+  void removeDeviceEffect(int portConfigId, in android.hardware.audio.effect.IEffect effect);
+  android.media.audio.common.AudioMMapPolicyInfo[] getMmapPolicyInfos(android.media.audio.common.AudioMMapPolicyType mmapPolicyType);
+  boolean supportsVariableLatency();
+  int getAAudioMixerBurstCount();
+  int getAAudioHardwareBurstMinUsec();
+  const int DEFAULT_AAUDIO_MIXER_BURST_COUNT = 2;
+  const int DEFAULT_AAUDIO_HARDWARE_BURST_MIN_DURATION_US = 1000;
+  @VintfStability
+  parcelable OpenInputStreamArguments {
+    int portConfigId;
+    android.hardware.audio.common.SinkMetadata sinkMetadata;
+    long bufferSizeFrames;
+  }
+  @VintfStability
+  parcelable OpenInputStreamReturn {
+    android.hardware.audio.core.IStreamIn stream;
+    android.hardware.audio.core.StreamDescriptor desc;
+  }
+  @VintfStability
+  parcelable OpenOutputStreamArguments {
+    int portConfigId;
+    android.hardware.audio.common.SourceMetadata sourceMetadata;
+    @nullable android.media.audio.common.AudioOffloadInfo offloadInfo;
+    long bufferSizeFrames;
+    @nullable android.hardware.audio.core.IStreamCallback callback;
+    @nullable android.hardware.audio.core.IStreamOutEventCallback eventCallback;
+  }
+  @VintfStability
+  parcelable OpenOutputStreamReturn {
+    android.hardware.audio.core.IStreamOut stream;
+    android.hardware.audio.core.StreamDescriptor desc;
+  }
+  @VintfStability
+  parcelable SupportedPlaybackRateFactors {
+    float minSpeed;
+    float maxSpeed;
+    float minPitch;
+    float maxPitch;
+  }
+  @Backing(type="int") @VintfStability
+  enum ScreenRotation {
+    DEG_0 = 0,
+    DEG_90 = 1,
+    DEG_180 = 2,
+    DEG_270 = 3,
+  }
+}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IStreamCallback.aidl
similarity index 90%
rename from media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
rename to audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IStreamCallback.aidl
index 1c9bf8d..5a2ab78 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IStreamCallback.aidl
@@ -31,11 +31,10 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.media.c2;
+package android.hardware.audio.core;
 @VintfStability
-parcelable SurfaceSyncObj {
-  android.hardware.common.NativeHandle syncMemory;
-  long bqId;
-  int generationId;
-  long consumerUsage;
+interface IStreamCallback {
+  oneway void onTransferReady();
+  oneway void onError();
+  oneway void onDrainReady();
 }
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IStreamCommon.aidl
similarity index 77%
copy from media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
copy to audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IStreamCommon.aidl
index 1c9bf8d..65a2ee4 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IStreamCommon.aidl
@@ -31,11 +31,14 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.media.c2;
+package android.hardware.audio.core;
 @VintfStability
-parcelable SurfaceSyncObj {
-  android.hardware.common.NativeHandle syncMemory;
-  long bqId;
-  int generationId;
-  long consumerUsage;
+interface IStreamCommon {
+  void close();
+  void prepareToClose();
+  void updateHwAvSyncId(int hwAvSyncId);
+  android.hardware.audio.core.VendorParameter[] getVendorParameters(in @utf8InCpp String[] ids);
+  void setVendorParameters(in android.hardware.audio.core.VendorParameter[] parameters, boolean async);
+  void addEffect(in android.hardware.audio.effect.IEffect effect);
+  void removeEffect(in android.hardware.audio.effect.IEffect effect);
 }
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IStreamIn.aidl
similarity index 63%
copy from media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
copy to audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IStreamIn.aidl
index 1c9bf8d..a01f877 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IStreamIn.aidl
@@ -31,11 +31,28 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.media.c2;
+package android.hardware.audio.core;
 @VintfStability
-parcelable SurfaceSyncObj {
-  android.hardware.common.NativeHandle syncMemory;
-  long bqId;
-  int generationId;
-  long consumerUsage;
+interface IStreamIn {
+  android.hardware.audio.core.IStreamCommon getStreamCommon();
+  android.media.audio.common.MicrophoneDynamicInfo[] getActiveMicrophones();
+  android.hardware.audio.core.IStreamIn.MicrophoneDirection getMicrophoneDirection();
+  void setMicrophoneDirection(android.hardware.audio.core.IStreamIn.MicrophoneDirection direction);
+  float getMicrophoneFieldDimension();
+  void setMicrophoneFieldDimension(float zoom);
+  void updateMetadata(in android.hardware.audio.common.SinkMetadata sinkMetadata);
+  float[] getHwGain();
+  void setHwGain(in float[] channelGains);
+  const int MIC_FIELD_DIMENSION_WIDE_ANGLE = (-1) /* -1 */;
+  const int MIC_FIELD_DIMENSION_NO_ZOOM = 0;
+  const int MIC_FIELD_DIMENSION_MAX_ZOOM = 1;
+  const int HW_GAIN_MIN = 0;
+  const int HW_GAIN_MAX = 1;
+  @Backing(type="int") @VintfStability
+  enum MicrophoneDirection {
+    UNSPECIFIED = 0,
+    FRONT = 1,
+    BACK = 2,
+    EXTERNAL = 3,
+  }
 }
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IStreamOut.aidl
similarity index 60%
copy from media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
copy to audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IStreamOut.aidl
index 1c9bf8d..ec3078e 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IStreamOut.aidl
@@ -31,11 +31,24 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.media.c2;
+package android.hardware.audio.core;
 @VintfStability
-parcelable SurfaceSyncObj {
-  android.hardware.common.NativeHandle syncMemory;
-  long bqId;
-  int generationId;
-  long consumerUsage;
+interface IStreamOut {
+  android.hardware.audio.core.IStreamCommon getStreamCommon();
+  void updateMetadata(in android.hardware.audio.common.SourceMetadata sourceMetadata);
+  void updateOffloadMetadata(in android.hardware.audio.common.AudioOffloadMetadata offloadMetadata);
+  float[] getHwVolume();
+  void setHwVolume(in float[] channelVolumes);
+  float getAudioDescriptionMixLevel();
+  void setAudioDescriptionMixLevel(float leveldB);
+  android.media.audio.common.AudioDualMonoMode getDualMonoMode();
+  void setDualMonoMode(android.media.audio.common.AudioDualMonoMode mode);
+  android.media.audio.common.AudioLatencyMode[] getRecommendedLatencyModes();
+  void setLatencyMode(android.media.audio.common.AudioLatencyMode mode);
+  android.media.audio.common.AudioPlaybackRate getPlaybackRateParameters();
+  void setPlaybackRateParameters(in android.media.audio.common.AudioPlaybackRate playbackRate);
+  void selectPresentation(int presentationId, int programId);
+  const int HW_VOLUME_MIN = 0;
+  const int HW_VOLUME_MAX = 1;
+  const int AUDIO_DESCRIPTION_MIX_LEVEL_MAX = 48;
 }
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IStreamOutEventCallback.aidl
similarity index 87%
copy from media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
copy to audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IStreamOutEventCallback.aidl
index 1c9bf8d..31cf0b7 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IStreamOutEventCallback.aidl
@@ -31,11 +31,9 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.media.c2;
+package android.hardware.audio.core;
 @VintfStability
-parcelable SurfaceSyncObj {
-  android.hardware.common.NativeHandle syncMemory;
-  long bqId;
-  int generationId;
-  long consumerUsage;
+interface IStreamOutEventCallback {
+  oneway void onCodecFormatChanged(in byte[] audioMetadata);
+  oneway void onRecommendedLatencyModeChanged(in android.media.audio.common.AudioLatencyMode[] modes);
 }
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/ITelephony.aidl
similarity index 64%
copy from media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
copy to audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/ITelephony.aidl
index 1c9bf8d..84d7aa1 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/ITelephony.aidl
@@ -31,11 +31,26 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.media.c2;
+package android.hardware.audio.core;
 @VintfStability
-parcelable SurfaceSyncObj {
-  android.hardware.common.NativeHandle syncMemory;
-  long bqId;
-  int generationId;
-  long consumerUsage;
+interface ITelephony {
+  android.media.audio.common.AudioMode[] getSupportedAudioModes();
+  void switchAudioMode(android.media.audio.common.AudioMode mode);
+  android.hardware.audio.core.ITelephony.TelecomConfig setTelecomConfig(in android.hardware.audio.core.ITelephony.TelecomConfig config);
+  @JavaDerive(equals=true, toString=true) @VintfStability
+  parcelable TelecomConfig {
+    @nullable android.media.audio.common.Float voiceVolume;
+    android.hardware.audio.core.ITelephony.TelecomConfig.TtyMode ttyMode = android.hardware.audio.core.ITelephony.TelecomConfig.TtyMode.UNSPECIFIED;
+    @nullable android.media.audio.common.Boolean isHacEnabled;
+    const int VOICE_VOLUME_MIN = 0;
+    const int VOICE_VOLUME_MAX = 1;
+    @Backing(type="int") @VintfStability
+    enum TtyMode {
+      UNSPECIFIED = (-1) /* -1 */,
+      OFF = 0,
+      FULL = 1,
+      HCO = 2,
+      VCO = 3,
+    }
+  }
 }
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/MmapBufferDescriptor.aidl
similarity index 85%
copy from media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
copy to audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/MmapBufferDescriptor.aidl
index 1c9bf8d..6ea1c69 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/MmapBufferDescriptor.aidl
@@ -31,11 +31,11 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.media.c2;
-@VintfStability
-parcelable SurfaceSyncObj {
-  android.hardware.common.NativeHandle syncMemory;
-  long bqId;
-  int generationId;
-  long consumerUsage;
+package android.hardware.audio.core;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable MmapBufferDescriptor {
+  android.hardware.common.Ashmem sharedMemory;
+  long burstSizeFrames;
+  int flags;
+  const int FLAG_INDEX_APPLICATION_SHAREABLE = 0;
 }
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/ModuleDebug.aidl
similarity index 89%
copy from media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
copy to audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/ModuleDebug.aidl
index 1c9bf8d..467d37b 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/ModuleDebug.aidl
@@ -31,11 +31,9 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.media.c2;
-@VintfStability
-parcelable SurfaceSyncObj {
-  android.hardware.common.NativeHandle syncMemory;
-  long bqId;
-  int generationId;
-  long consumerUsage;
+package android.hardware.audio.core;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable ModuleDebug {
+  boolean simulateDeviceConnections;
+  int streamTransientStateDelayMs;
 }
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/StreamDescriptor.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/StreamDescriptor.aidl
new file mode 100644
index 0000000..3e3dc38
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/StreamDescriptor.aidl
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.core;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable StreamDescriptor {
+  android.hardware.common.fmq.MQDescriptor<android.hardware.audio.core.StreamDescriptor.Command,android.hardware.common.fmq.SynchronizedReadWrite> command;
+  android.hardware.common.fmq.MQDescriptor<android.hardware.audio.core.StreamDescriptor.Reply,android.hardware.common.fmq.SynchronizedReadWrite> reply;
+  int frameSizeBytes;
+  long bufferSizeFrames;
+  android.hardware.audio.core.StreamDescriptor.AudioBuffer audio;
+  const int LATENCY_UNKNOWN = (-1) /* -1 */;
+  @FixedSize @VintfStability
+  parcelable Position {
+    long frames = UNKNOWN /* -1 */;
+    long timeNs = UNKNOWN /* -1 */;
+    const long UNKNOWN = (-1) /* -1 */;
+  }
+  @Backing(type="int") @VintfStability
+  enum State {
+    STANDBY = 1,
+    IDLE = 2,
+    ACTIVE = 3,
+    PAUSED = 4,
+    DRAINING = 5,
+    DRAIN_PAUSED = 6,
+    TRANSFERRING = 7,
+    TRANSFER_PAUSED = 8,
+    ERROR = 100,
+  }
+  @Backing(type="byte") @VintfStability
+  enum DrainMode {
+    DRAIN_UNSPECIFIED = 0,
+    DRAIN_ALL = 1,
+    DRAIN_EARLY_NOTIFY = 2,
+  }
+  @FixedSize @VintfStability
+  union Command {
+    int halReservedExit;
+    android.media.audio.common.Void getStatus;
+    android.media.audio.common.Void start;
+    int burst;
+    android.hardware.audio.core.StreamDescriptor.DrainMode drain;
+    android.media.audio.common.Void standby;
+    android.media.audio.common.Void pause;
+    android.media.audio.common.Void flush;
+  }
+  @FixedSize @VintfStability
+  parcelable Reply {
+    int status;
+    int fmqByteCount;
+    android.hardware.audio.core.StreamDescriptor.Position observable;
+    android.hardware.audio.core.StreamDescriptor.Position hardware;
+    int latencyMs;
+    int xrunFrames;
+    android.hardware.audio.core.StreamDescriptor.State state = android.hardware.audio.core.StreamDescriptor.State.STANDBY;
+  }
+  @VintfStability
+  union AudioBuffer {
+    android.hardware.common.fmq.MQDescriptor<byte,android.hardware.common.fmq.SynchronizedReadWrite> fmq;
+    android.hardware.audio.core.MmapBufferDescriptor mmap;
+  }
+}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/SurroundSoundConfig.aidl
similarity index 79%
copy from media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
copy to audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/SurroundSoundConfig.aidl
index 1c9bf8d..08a1537 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/SurroundSoundConfig.aidl
@@ -31,11 +31,13 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.media.c2;
-@VintfStability
-parcelable SurfaceSyncObj {
-  android.hardware.common.NativeHandle syncMemory;
-  long bqId;
-  int generationId;
-  long consumerUsage;
+package android.hardware.audio.core;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable SurroundSoundConfig {
+  android.hardware.audio.core.SurroundSoundConfig.SurroundFormatFamily[] formatFamilies;
+  @VintfStability
+  parcelable SurroundFormatFamily {
+    android.media.audio.common.AudioFormatDescription primaryFormat;
+    android.media.audio.common.AudioFormatDescription[] subFormats;
+  }
 }
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/VendorParameter.aidl
similarity index 89%
copy from media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
copy to audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/VendorParameter.aidl
index 1c9bf8d..bfe33ee 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/VendorParameter.aidl
@@ -31,11 +31,9 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.media.c2;
-@VintfStability
-parcelable SurfaceSyncObj {
-  android.hardware.common.NativeHandle syncMemory;
-  long bqId;
-  int generationId;
-  long consumerUsage;
+package android.hardware.audio.core;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable VendorParameter {
+  @utf8InCpp String id;
+  ParcelableHolder ext;
 }
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/1/.hash b/audio/aidl/aidl_api/android.hardware.audio.effect/1/.hash
new file mode 100644
index 0000000..b71ab29
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/.hash
@@ -0,0 +1 @@
+34b618a587cb9977ee0cd13b173e699d2dcdb320
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/AcousticEchoCanceler.aidl
similarity index 82%
copy from media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
copy to audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/AcousticEchoCanceler.aidl
index 1c9bf8d..16367c0 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/AcousticEchoCanceler.aidl
@@ -31,11 +31,15 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.media.c2;
+package android.hardware.audio.effect;
 @VintfStability
-parcelable SurfaceSyncObj {
-  android.hardware.common.NativeHandle syncMemory;
-  long bqId;
-  int generationId;
-  long consumerUsage;
+union AcousticEchoCanceler {
+  android.hardware.audio.effect.VendorExtension vendor;
+  int echoDelayUs;
+  boolean mobileMode;
+  @VintfStability
+  union Id {
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
+    android.hardware.audio.effect.AcousticEchoCanceler.Tag commonTag;
+  }
 }
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/AutomaticGainControlV1.aidl
similarity index 78%
copy from media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
copy to audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/AutomaticGainControlV1.aidl
index 1c9bf8d..e69e2bd 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/AutomaticGainControlV1.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2023 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.
@@ -31,11 +31,16 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.media.c2;
+package android.hardware.audio.effect;
 @VintfStability
-parcelable SurfaceSyncObj {
-  android.hardware.common.NativeHandle syncMemory;
-  long bqId;
-  int generationId;
-  long consumerUsage;
+union AutomaticGainControlV1 {
+  android.hardware.audio.effect.VendorExtension vendor;
+  int targetPeakLevelDbFs;
+  int maxCompressionGainDb;
+  boolean enableLimiter;
+  @VintfStability
+  union Id {
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
+    android.hardware.audio.effect.AutomaticGainControlV1.Tag commonTag;
+  }
 }
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/AutomaticGainControlV2.aidl
similarity index 75%
copy from media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
copy to audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/AutomaticGainControlV2.aidl
index 1c9bf8d..46ffcaf 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/AutomaticGainControlV2.aidl
@@ -31,11 +31,21 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.media.c2;
+package android.hardware.audio.effect;
 @VintfStability
-parcelable SurfaceSyncObj {
-  android.hardware.common.NativeHandle syncMemory;
-  long bqId;
-  int generationId;
-  long consumerUsage;
+union AutomaticGainControlV2 {
+  android.hardware.audio.effect.VendorExtension vendor;
+  int fixedDigitalGainMb;
+  android.hardware.audio.effect.AutomaticGainControlV2.LevelEstimator levelEstimator;
+  int saturationMarginMb;
+  @VintfStability
+  union Id {
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
+    android.hardware.audio.effect.AutomaticGainControlV2.Tag commonTag;
+  }
+  @Backing(type="int") @VintfStability
+  enum LevelEstimator {
+    RMS = 0,
+    PEAK = 1,
+  }
 }
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/BassBoost.aidl
similarity index 84%
copy from media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
copy to audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/BassBoost.aidl
index 1c9bf8d..c248ce8 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/BassBoost.aidl
@@ -31,11 +31,14 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.media.c2;
+package android.hardware.audio.effect;
 @VintfStability
-parcelable SurfaceSyncObj {
-  android.hardware.common.NativeHandle syncMemory;
-  long bqId;
-  int generationId;
-  long consumerUsage;
+union BassBoost {
+  android.hardware.audio.effect.VendorExtension vendor;
+  int strengthPm;
+  @VintfStability
+  union Id {
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
+    android.hardware.audio.effect.BassBoost.Tag commonTag;
+  }
 }
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Capability.aidl
similarity index 90%
copy from media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
copy to audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Capability.aidl
index 1c9bf8d..c9df073 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Capability.aidl
@@ -31,11 +31,9 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.media.c2;
+package android.hardware.audio.effect;
 @VintfStability
-parcelable SurfaceSyncObj {
-  android.hardware.common.NativeHandle syncMemory;
-  long bqId;
-  int generationId;
-  long consumerUsage;
+parcelable Capability {
+  android.hardware.audio.effect.VendorExtension vendorExtension;
+  android.hardware.audio.effect.Range range;
 }
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/CommandId.aidl
similarity index 82%
copy from media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
copy to audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/CommandId.aidl
index 1c9bf8d..86b69fa 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/CommandId.aidl
@@ -31,11 +31,20 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.media.c2;
-@VintfStability
-parcelable SurfaceSyncObj {
-  android.hardware.common.NativeHandle syncMemory;
-  long bqId;
-  int generationId;
-  long consumerUsage;
+package android.hardware.audio.effect;
+@Backing(type="int") @VintfStability
+enum CommandId {
+  START = 0,
+  STOP = 1,
+  RESET = 2,
+  VENDOR_COMMAND_0 = 0x100,
+  VENDOR_COMMAND_1,
+  VENDOR_COMMAND_2,
+  VENDOR_COMMAND_3,
+  VENDOR_COMMAND_4,
+  VENDOR_COMMAND_5,
+  VENDOR_COMMAND_6,
+  VENDOR_COMMAND_7,
+  VENDOR_COMMAND_8,
+  VENDOR_COMMAND_9,
 }
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/DefaultExtension.aidl
similarity index 87%
copy from media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
copy to audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/DefaultExtension.aidl
index 1c9bf8d..f1cf389 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/DefaultExtension.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2023 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.
@@ -31,11 +31,8 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.media.c2;
+package android.hardware.audio.effect;
 @VintfStability
-parcelable SurfaceSyncObj {
-  android.hardware.common.NativeHandle syncMemory;
-  long bqId;
-  int generationId;
-  long consumerUsage;
+parcelable DefaultExtension {
+  byte[] bytes;
 }
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Descriptor.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Descriptor.aidl
new file mode 100644
index 0000000..115da1d
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Descriptor.aidl
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+parcelable Descriptor {
+  android.hardware.audio.effect.Descriptor.Common common;
+  android.hardware.audio.effect.Capability capability;
+  const String EFFECT_TYPE_UUID_AEC = "7b491460-8d4d-11e0-bd61-0002a5d5c51b";
+  const String EFFECT_TYPE_UUID_AGC1 = "0a8abfe0-654c-11e0-ba26-0002a5d5c51b";
+  const String EFFECT_TYPE_UUID_AGC2 = "ae3c653b-be18-4ab8-8938-418f0a7f06ac";
+  const String EFFECT_TYPE_UUID_BASS_BOOST = "0634f220-ddd4-11db-a0fc-0002a5d5c51b";
+  const String EFFECT_TYPE_UUID_DOWNMIX = "381e49cc-a858-4aa2-87f6-e8388e7601b2";
+  const String EFFECT_TYPE_UUID_DYNAMICS_PROCESSING = "7261676f-6d75-7369-6364-28e2fd3ac39e";
+  const String EFFECT_TYPE_UUID_ENV_REVERB = "c2e5d5f0-94bd-4763-9cac-4e234d06839e";
+  const String EFFECT_TYPE_UUID_EQUALIZER = "0bed4300-ddd6-11db-8f34-0002a5d5c51b";
+  const String EFFECT_TYPE_UUID_HAPTIC_GENERATOR = "1411e6d6-aecd-4021-a1cf-a6aceb0d71e5";
+  const String EFFECT_TYPE_UUID_LOUDNESS_ENHANCER = "fe3199be-aed0-413f-87bb-11260eb63cf1";
+  const String EFFECT_TYPE_UUID_NS = "58b4b260-8e06-11e0-aa8e-0002a5d5c51b";
+  const String EFFECT_TYPE_UUID_PRESET_REVERB = "47382d60-ddd8-11db-bf3a-0002a5d5c51b";
+  const String EFFECT_TYPE_UUID_SPATIALIZER = "ccd4cf09-a79d-46c2-9aae-06a1698d6c8f";
+  const String EFFECT_TYPE_UUID_VIRTUALIZER = "37cc2c00-dddd-11db-8577-0002a5d5c51b";
+  const String EFFECT_TYPE_UUID_VISUALIZER = "e46b26a0-dddd-11db-8afd-0002a5d5c51b";
+  const String EFFECT_TYPE_UUID_VOLUME = "09e8ede0-ddde-11db-b4f6-0002a5d5c51b";
+  @VintfStability
+  parcelable Identity {
+    android.media.audio.common.AudioUuid type;
+    android.media.audio.common.AudioUuid uuid;
+    @nullable android.media.audio.common.AudioUuid proxy;
+  }
+  @VintfStability
+  parcelable Common {
+    android.hardware.audio.effect.Descriptor.Identity id;
+    android.hardware.audio.effect.Flags flags;
+    int cpuLoad;
+    int memoryUsage;
+    @utf8InCpp String name;
+    @utf8InCpp String implementor;
+  }
+}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Downmix.aidl
similarity index 81%
copy from media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
copy to audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Downmix.aidl
index 1c9bf8d..ce0a7df 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Downmix.aidl
@@ -31,11 +31,19 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.media.c2;
+package android.hardware.audio.effect;
 @VintfStability
-parcelable SurfaceSyncObj {
-  android.hardware.common.NativeHandle syncMemory;
-  long bqId;
-  int generationId;
-  long consumerUsage;
+union Downmix {
+  android.hardware.audio.effect.VendorExtension vendor;
+  android.hardware.audio.effect.Downmix.Type type;
+  @VintfStability
+  union Id {
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
+    android.hardware.audio.effect.Downmix.Tag commonTag;
+  }
+  @VintfStability
+  enum Type {
+    STRIP,
+    FOLD,
+  }
 }
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/DynamicsProcessing.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/DynamicsProcessing.aidl
new file mode 100644
index 0000000..04f627d
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/DynamicsProcessing.aidl
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+union DynamicsProcessing {
+  android.hardware.audio.effect.VendorExtension vendor;
+  android.hardware.audio.effect.DynamicsProcessing.EngineArchitecture engineArchitecture;
+  android.hardware.audio.effect.DynamicsProcessing.ChannelConfig[] preEq;
+  android.hardware.audio.effect.DynamicsProcessing.ChannelConfig[] postEq;
+  android.hardware.audio.effect.DynamicsProcessing.EqBandConfig[] preEqBand;
+  android.hardware.audio.effect.DynamicsProcessing.EqBandConfig[] postEqBand;
+  android.hardware.audio.effect.DynamicsProcessing.ChannelConfig[] mbc;
+  android.hardware.audio.effect.DynamicsProcessing.MbcBandConfig[] mbcBand;
+  android.hardware.audio.effect.DynamicsProcessing.LimiterConfig[] limiter;
+  android.hardware.audio.effect.DynamicsProcessing.InputGain[] inputGain;
+  @VintfStability
+  union Id {
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
+    android.hardware.audio.effect.DynamicsProcessing.Tag commonTag;
+  }
+  enum ResolutionPreference {
+    FAVOR_FREQUENCY_RESOLUTION,
+    FAVOR_TIME_RESOLUTION,
+  }
+  @VintfStability
+  parcelable StageEnablement {
+    boolean inUse;
+    int bandCount;
+  }
+  @VintfStability
+  parcelable EngineArchitecture {
+    android.hardware.audio.effect.DynamicsProcessing.ResolutionPreference resolutionPreference = android.hardware.audio.effect.DynamicsProcessing.ResolutionPreference.FAVOR_FREQUENCY_RESOLUTION;
+    float preferredProcessingDurationMs;
+    android.hardware.audio.effect.DynamicsProcessing.StageEnablement preEqStage;
+    android.hardware.audio.effect.DynamicsProcessing.StageEnablement postEqStage;
+    android.hardware.audio.effect.DynamicsProcessing.StageEnablement mbcStage;
+    boolean limiterInUse;
+  }
+  @VintfStability
+  parcelable ChannelConfig {
+    int channel;
+    boolean enable;
+  }
+  @VintfStability
+  parcelable EqBandConfig {
+    int channel;
+    int band;
+    boolean enable;
+    float cutoffFrequencyHz;
+    float gainDb;
+  }
+  @VintfStability
+  parcelable MbcBandConfig {
+    int channel;
+    int band;
+    boolean enable;
+    float cutoffFrequencyHz;
+    float attackTimeMs;
+    float releaseTimeMs;
+    float ratio;
+    float thresholdDb;
+    float kneeWidthDb;
+    float noiseGateThresholdDb;
+    float expanderRatio;
+    float preGainDb;
+    float postGainDb;
+  }
+  @VintfStability
+  parcelable LimiterConfig {
+    int channel;
+    boolean enable;
+    int linkGroup;
+    float attackTimeMs;
+    float releaseTimeMs;
+    float ratio;
+    float thresholdDb;
+    float postGainDb;
+  }
+  @VintfStability
+  parcelable InputGain {
+    int channel;
+    float gainDb;
+  }
+}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/EnvironmentalReverb.aidl
similarity index 76%
copy from media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
copy to audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/EnvironmentalReverb.aidl
index 1c9bf8d..00b7d1a 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/EnvironmentalReverb.aidl
@@ -31,11 +31,24 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.media.c2;
+package android.hardware.audio.effect;
 @VintfStability
-parcelable SurfaceSyncObj {
-  android.hardware.common.NativeHandle syncMemory;
-  long bqId;
-  int generationId;
-  long consumerUsage;
+union EnvironmentalReverb {
+  android.hardware.audio.effect.VendorExtension vendor;
+  int roomLevelMb;
+  int roomHfLevelMb;
+  int decayTimeMs;
+  int decayHfRatioPm;
+  int reflectionsLevelMb;
+  int reflectionsDelayMs;
+  int levelMb;
+  int delayMs;
+  int diffusionPm;
+  int densityPm;
+  boolean bypass;
+  @VintfStability
+  union Id {
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
+    android.hardware.audio.effect.EnvironmentalReverb.Tag commonTag;
+  }
 }
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Equalizer.aidl
similarity index 68%
copy from media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
copy to audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Equalizer.aidl
index 1c9bf8d..80f7c7e 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Equalizer.aidl
@@ -31,11 +31,34 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.media.c2;
+package android.hardware.audio.effect;
 @VintfStability
-parcelable SurfaceSyncObj {
-  android.hardware.common.NativeHandle syncMemory;
-  long bqId;
-  int generationId;
-  long consumerUsage;
+union Equalizer {
+  android.hardware.audio.effect.VendorExtension vendor;
+  android.hardware.audio.effect.Equalizer.BandLevel[] bandLevels;
+  int preset;
+  int[] centerFreqMh;
+  android.hardware.audio.effect.Equalizer.BandFrequency[] bandFrequencies;
+  android.hardware.audio.effect.Equalizer.Preset[] presets;
+  @VintfStability
+  union Id {
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
+    android.hardware.audio.effect.Equalizer.Tag commonTag;
+  }
+  @VintfStability
+  parcelable BandLevel {
+    int index;
+    int levelMb;
+  }
+  @VintfStability
+  parcelable BandFrequency {
+    int index;
+    int minMh;
+    int maxMh;
+  }
+  @VintfStability
+  parcelable Preset {
+    int index;
+    @utf8InCpp String name;
+  }
 }
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Flags.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Flags.aidl
new file mode 100644
index 0000000..bcbf870
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Flags.aidl
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+parcelable Flags {
+  android.hardware.audio.effect.Flags.Type type = android.hardware.audio.effect.Flags.Type.INSERT;
+  android.hardware.audio.effect.Flags.Insert insert = android.hardware.audio.effect.Flags.Insert.ANY;
+  android.hardware.audio.effect.Flags.Volume volume = android.hardware.audio.effect.Flags.Volume.NONE;
+  android.hardware.audio.effect.Flags.HardwareAccelerator hwAcceleratorMode = android.hardware.audio.effect.Flags.HardwareAccelerator.NONE;
+  boolean offloadIndication;
+  boolean deviceIndication;
+  boolean audioModeIndication;
+  boolean audioSourceIndication;
+  boolean bypass;
+  @Backing(type="byte") @VintfStability
+  enum Type {
+    INSERT = 0,
+    AUXILIARY = 1,
+    REPLACE = 2,
+    PRE_PROC = 3,
+    POST_PROC = 4,
+  }
+  @Backing(type="byte") @VintfStability
+  enum Insert {
+    ANY = 0,
+    FIRST = 1,
+    LAST = 2,
+    EXCLUSIVE = 3,
+  }
+  @Backing(type="byte") @VintfStability
+  enum Volume {
+    NONE = 0,
+    CTRL = 1,
+    IND = 2,
+    MONITOR = 3,
+  }
+  @Backing(type="byte") @VintfStability
+  enum HardwareAccelerator {
+    NONE = 0,
+    SIMPLE = 1,
+    TUNNEL = 2,
+  }
+}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/HapticGenerator.aidl
similarity index 63%
copy from media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
copy to audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/HapticGenerator.aidl
index 1c9bf8d..8addab7 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/HapticGenerator.aidl
@@ -31,11 +31,35 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.media.c2;
+package android.hardware.audio.effect;
 @VintfStability
-parcelable SurfaceSyncObj {
-  android.hardware.common.NativeHandle syncMemory;
-  long bqId;
-  int generationId;
-  long consumerUsage;
+union HapticGenerator {
+  android.hardware.audio.effect.VendorExtension vendor;
+  android.hardware.audio.effect.HapticGenerator.HapticScale[] hapticScales;
+  android.hardware.audio.effect.HapticGenerator.VibratorInformation vibratorInfo;
+  @VintfStability
+  union Id {
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
+    android.hardware.audio.effect.HapticGenerator.Tag commonTag;
+  }
+  @Backing(type="int") @VintfStability
+  enum VibratorScale {
+    MUTE = (-100) /* -100 */,
+    VERY_LOW = (-2) /* -2 */,
+    LOW = (-1) /* -1 */,
+    NONE = 0,
+    HIGH = 1,
+    VERY_HIGH = 2,
+  }
+  @VintfStability
+  parcelable HapticScale {
+    int id;
+    android.hardware.audio.effect.HapticGenerator.VibratorScale scale = android.hardware.audio.effect.HapticGenerator.VibratorScale.MUTE;
+  }
+  @VintfStability
+  parcelable VibratorInformation {
+    float resonantFrequencyHz;
+    float qFactor;
+    float maxAmplitude;
+  }
 }
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/IEffect.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/IEffect.aidl
new file mode 100644
index 0000000..8c196e7
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/IEffect.aidl
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+interface IEffect {
+  android.hardware.audio.effect.IEffect.OpenEffectReturn open(in android.hardware.audio.effect.Parameter.Common common, in @nullable android.hardware.audio.effect.Parameter.Specific specific);
+  void close();
+  android.hardware.audio.effect.Descriptor getDescriptor();
+  void command(in android.hardware.audio.effect.CommandId commandId);
+  android.hardware.audio.effect.State getState();
+  void setParameter(in android.hardware.audio.effect.Parameter param);
+  android.hardware.audio.effect.Parameter getParameter(in android.hardware.audio.effect.Parameter.Id paramId);
+  @FixedSize @VintfStability
+  parcelable Status {
+    int status;
+    int fmqConsumed;
+    int fmqProduced;
+  }
+  @VintfStability
+  parcelable OpenEffectReturn {
+    android.hardware.common.fmq.MQDescriptor<android.hardware.audio.effect.IEffect.Status,android.hardware.common.fmq.SynchronizedReadWrite> statusMQ;
+    android.hardware.common.fmq.MQDescriptor<float,android.hardware.common.fmq.SynchronizedReadWrite> inputDataMQ;
+    android.hardware.common.fmq.MQDescriptor<float,android.hardware.common.fmq.SynchronizedReadWrite> outputDataMQ;
+  }
+}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/IFactory.aidl
similarity index 73%
copy from media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
copy to audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/IFactory.aidl
index 1c9bf8d..a6c138c 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/IFactory.aidl
@@ -31,11 +31,11 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.media.c2;
+package android.hardware.audio.effect;
 @VintfStability
-parcelable SurfaceSyncObj {
-  android.hardware.common.NativeHandle syncMemory;
-  long bqId;
-  int generationId;
-  long consumerUsage;
+interface IFactory {
+  android.hardware.audio.effect.Descriptor[] queryEffects(in @nullable android.media.audio.common.AudioUuid type, in @nullable android.media.audio.common.AudioUuid implementation, in @nullable android.media.audio.common.AudioUuid proxy);
+  android.hardware.audio.effect.Processing[] queryProcessing(in @nullable android.hardware.audio.effect.Processing.Type type);
+  android.hardware.audio.effect.IEffect createEffect(in android.media.audio.common.AudioUuid implUuid);
+  void destroyEffect(in android.hardware.audio.effect.IEffect handle);
 }
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/LoudnessEnhancer.aidl
similarity index 84%
copy from media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
copy to audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/LoudnessEnhancer.aidl
index 1c9bf8d..fc276d6 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/LoudnessEnhancer.aidl
@@ -31,11 +31,14 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.media.c2;
+package android.hardware.audio.effect;
 @VintfStability
-parcelable SurfaceSyncObj {
-  android.hardware.common.NativeHandle syncMemory;
-  long bqId;
-  int generationId;
-  long consumerUsage;
+union LoudnessEnhancer {
+  android.hardware.audio.effect.VendorExtension vendor;
+  int gainMb;
+  @VintfStability
+  union Id {
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
+    android.hardware.audio.effect.LoudnessEnhancer.Tag commonTag;
+  }
 }
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/NoiseSuppression.aidl
similarity index 73%
copy from media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
copy to audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/NoiseSuppression.aidl
index 1c9bf8d..7f30fe2 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/NoiseSuppression.aidl
@@ -31,11 +31,27 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.media.c2;
+package android.hardware.audio.effect;
 @VintfStability
-parcelable SurfaceSyncObj {
-  android.hardware.common.NativeHandle syncMemory;
-  long bqId;
-  int generationId;
-  long consumerUsage;
+union NoiseSuppression {
+  android.hardware.audio.effect.VendorExtension vendor;
+  android.hardware.audio.effect.NoiseSuppression.Level level;
+  android.hardware.audio.effect.NoiseSuppression.Type type;
+  @VintfStability
+  union Id {
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
+    android.hardware.audio.effect.NoiseSuppression.Tag commonTag;
+  }
+  @Backing(type="int") @VintfStability
+  enum Level {
+    LOW,
+    MEDIUM,
+    HIGH,
+    VERY_HIGH,
+  }
+  @Backing(type="int") @VintfStability
+  enum Type {
+    SINGLE_CHANNEL,
+    MULTI_CHANNEL,
+  }
 }
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Parameter.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Parameter.aidl
new file mode 100644
index 0000000..0422bd9
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Parameter.aidl
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+union Parameter {
+  android.hardware.audio.effect.Parameter.Common common;
+  android.media.audio.common.AudioDeviceDescription[] deviceDescription;
+  android.media.audio.common.AudioMode mode;
+  android.media.audio.common.AudioSource source;
+  boolean offload;
+  android.hardware.audio.effect.Parameter.VolumeStereo volumeStereo;
+  android.hardware.audio.effect.Parameter.Specific specific;
+  @VintfStability
+  union Id {
+    android.hardware.audio.effect.VendorExtension vendorEffectTag;
+    android.hardware.audio.effect.AcousticEchoCanceler.Id acousticEchoCancelerTag;
+    android.hardware.audio.effect.AutomaticGainControlV1.Id automaticGainControlV1Tag;
+    android.hardware.audio.effect.AutomaticGainControlV2.Id automaticGainControlV2Tag;
+    android.hardware.audio.effect.BassBoost.Id bassBoostTag;
+    android.hardware.audio.effect.Downmix.Id downmixTag;
+    android.hardware.audio.effect.DynamicsProcessing.Id dynamicsProcessingTag;
+    android.hardware.audio.effect.EnvironmentalReverb.Id environmentalReverbTag;
+    android.hardware.audio.effect.Equalizer.Id equalizerTag;
+    android.hardware.audio.effect.HapticGenerator.Id hapticGeneratorTag;
+    android.hardware.audio.effect.LoudnessEnhancer.Id loudnessEnhancerTag;
+    android.hardware.audio.effect.NoiseSuppression.Id noiseSuppressionTag;
+    android.hardware.audio.effect.PresetReverb.Id presetReverbTag;
+    android.hardware.audio.effect.Virtualizer.Id virtualizerTag;
+    android.hardware.audio.effect.Visualizer.Id visualizerTag;
+    android.hardware.audio.effect.Volume.Id volumeTag;
+    android.hardware.audio.effect.Parameter.Tag commonTag;
+  }
+  @VintfStability
+  parcelable Common {
+    int session;
+    int ioHandle;
+    android.media.audio.common.AudioConfig input;
+    android.media.audio.common.AudioConfig output;
+  }
+  @VintfStability
+  parcelable VolumeStereo {
+    float left;
+    float right;
+  }
+  @VintfStability
+  union Specific {
+    android.hardware.audio.effect.VendorExtension vendorEffect;
+    android.hardware.audio.effect.AcousticEchoCanceler acousticEchoCanceler;
+    android.hardware.audio.effect.AutomaticGainControlV1 automaticGainControlV1;
+    android.hardware.audio.effect.AutomaticGainControlV2 automaticGainControlV2;
+    android.hardware.audio.effect.BassBoost bassBoost;
+    android.hardware.audio.effect.Downmix downmix;
+    android.hardware.audio.effect.DynamicsProcessing dynamicsProcessing;
+    android.hardware.audio.effect.EnvironmentalReverb environmentalReverb;
+    android.hardware.audio.effect.Equalizer equalizer;
+    android.hardware.audio.effect.HapticGenerator hapticGenerator;
+    android.hardware.audio.effect.LoudnessEnhancer loudnessEnhancer;
+    android.hardware.audio.effect.NoiseSuppression noiseSuppression;
+    android.hardware.audio.effect.PresetReverb presetReverb;
+    android.hardware.audio.effect.Virtualizer virtualizer;
+    android.hardware.audio.effect.Visualizer visualizer;
+    android.hardware.audio.effect.Volume volume;
+  }
+}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/PresetReverb.aidl
similarity index 74%
copy from media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
copy to audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/PresetReverb.aidl
index 1c9bf8d..26d96b5 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/PresetReverb.aidl
@@ -31,11 +31,25 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.media.c2;
+package android.hardware.audio.effect;
 @VintfStability
-parcelable SurfaceSyncObj {
-  android.hardware.common.NativeHandle syncMemory;
-  long bqId;
-  int generationId;
-  long consumerUsage;
+union PresetReverb {
+  android.hardware.audio.effect.VendorExtension vendor;
+  android.hardware.audio.effect.PresetReverb.Presets[] supportedPresets;
+  android.hardware.audio.effect.PresetReverb.Presets preset;
+  @Backing(type="int") @VintfStability
+  enum Presets {
+    NONE,
+    SMALLROOM,
+    MEDIUMROOM,
+    LARGEROOM,
+    MEDIUMHALL,
+    LARGEHALL,
+    PLATE,
+  }
+  @VintfStability
+  union Id {
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
+    android.hardware.audio.effect.PresetReverb.Tag commonTag;
+  }
 }
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Processing.aidl
similarity index 81%
copy from media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
copy to audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Processing.aidl
index 1c9bf8d..f6d6ee2 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Processing.aidl
@@ -31,11 +31,14 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.media.c2;
+package android.hardware.audio.effect;
 @VintfStability
-parcelable SurfaceSyncObj {
-  android.hardware.common.NativeHandle syncMemory;
-  long bqId;
-  int generationId;
-  long consumerUsage;
+parcelable Processing {
+  android.hardware.audio.effect.Processing.Type type;
+  android.hardware.audio.effect.Descriptor[] ids;
+  @VintfStability
+  union Type {
+    android.media.audio.common.AudioStreamType streamType = android.media.audio.common.AudioStreamType.INVALID;
+    android.media.audio.common.AudioSource source;
+  }
 }
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Range.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Range.aidl
new file mode 100644
index 0000000..93edc5e
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Range.aidl
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+union Range {
+  android.hardware.audio.effect.Range.VendorExtensionRange[] vendorExtension = {};
+  android.hardware.audio.effect.Range.AcousticEchoCancelerRange[] acousticEchoCanceler;
+  android.hardware.audio.effect.Range.AutomaticGainControlV1Range[] automaticGainControlV1;
+  android.hardware.audio.effect.Range.AutomaticGainControlV2Range[] automaticGainControlV2;
+  android.hardware.audio.effect.Range.BassBoostRange[] bassBoost;
+  android.hardware.audio.effect.Range.DownmixRange[] downmix;
+  android.hardware.audio.effect.Range.DynamicsProcessingRange[] dynamicsProcessing;
+  android.hardware.audio.effect.Range.EnvironmentalReverbRange[] environmentalReverb;
+  android.hardware.audio.effect.Range.EqualizerRange[] equalizer;
+  android.hardware.audio.effect.Range.HapticGeneratorRange[] hapticGenerator;
+  android.hardware.audio.effect.Range.LoudnessEnhancerRange[] loudnessEnhancer;
+  android.hardware.audio.effect.Range.NoiseSuppressionRange[] noiseSuppression;
+  android.hardware.audio.effect.Range.PresetReverbRange[] presetReverb;
+  android.hardware.audio.effect.Range.VirtualizerRange[] virtualizer;
+  android.hardware.audio.effect.Range.VisualizerRange[] visualizer;
+  android.hardware.audio.effect.Range.VolumeRange[] volume;
+  @VintfStability
+  parcelable AcousticEchoCancelerRange {
+    android.hardware.audio.effect.AcousticEchoCanceler min;
+    android.hardware.audio.effect.AcousticEchoCanceler max;
+  }
+  @VintfStability
+  parcelable AutomaticGainControlV1Range {
+    android.hardware.audio.effect.AutomaticGainControlV1 min;
+    android.hardware.audio.effect.AutomaticGainControlV1 max;
+  }
+  @VintfStability
+  parcelable AutomaticGainControlV2Range {
+    android.hardware.audio.effect.AutomaticGainControlV2 min;
+    android.hardware.audio.effect.AutomaticGainControlV2 max;
+  }
+  @VintfStability
+  parcelable BassBoostRange {
+    android.hardware.audio.effect.BassBoost min;
+    android.hardware.audio.effect.BassBoost max;
+  }
+  @VintfStability
+  parcelable DownmixRange {
+    android.hardware.audio.effect.Downmix min;
+    android.hardware.audio.effect.Downmix max;
+  }
+  @VintfStability
+  parcelable DynamicsProcessingRange {
+    android.hardware.audio.effect.DynamicsProcessing min;
+    android.hardware.audio.effect.DynamicsProcessing max;
+  }
+  @VintfStability
+  parcelable EnvironmentalReverbRange {
+    android.hardware.audio.effect.EnvironmentalReverb min;
+    android.hardware.audio.effect.EnvironmentalReverb max;
+  }
+  @VintfStability
+  parcelable EqualizerRange {
+    android.hardware.audio.effect.Equalizer min;
+    android.hardware.audio.effect.Equalizer max;
+  }
+  @VintfStability
+  parcelable HapticGeneratorRange {
+    android.hardware.audio.effect.HapticGenerator min;
+    android.hardware.audio.effect.HapticGenerator max;
+  }
+  @VintfStability
+  parcelable LoudnessEnhancerRange {
+    android.hardware.audio.effect.LoudnessEnhancer min;
+    android.hardware.audio.effect.LoudnessEnhancer max;
+  }
+  @VintfStability
+  parcelable NoiseSuppressionRange {
+    android.hardware.audio.effect.NoiseSuppression min;
+    android.hardware.audio.effect.NoiseSuppression max;
+  }
+  @VintfStability
+  parcelable PresetReverbRange {
+    android.hardware.audio.effect.PresetReverb min;
+    android.hardware.audio.effect.PresetReverb max;
+  }
+  @VintfStability
+  parcelable VendorExtensionRange {
+    android.hardware.audio.effect.VendorExtension min;
+    android.hardware.audio.effect.VendorExtension max;
+  }
+  @VintfStability
+  parcelable VirtualizerRange {
+    android.hardware.audio.effect.Virtualizer min;
+    android.hardware.audio.effect.Virtualizer max;
+  }
+  @VintfStability
+  parcelable VisualizerRange {
+    android.hardware.audio.effect.Visualizer min;
+    android.hardware.audio.effect.Visualizer max;
+  }
+  @VintfStability
+  parcelable VolumeRange {
+    android.hardware.audio.effect.Volume min;
+    android.hardware.audio.effect.Volume max;
+  }
+}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/State.aidl
similarity index 89%
copy from media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
copy to audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/State.aidl
index 1c9bf8d..17f9814 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/State.aidl
@@ -31,11 +31,10 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.media.c2;
-@VintfStability
-parcelable SurfaceSyncObj {
-  android.hardware.common.NativeHandle syncMemory;
-  long bqId;
-  int generationId;
-  long consumerUsage;
+package android.hardware.audio.effect;
+@Backing(type="byte") @VintfStability
+enum State {
+  INIT,
+  IDLE,
+  PROCESSING,
 }
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/VendorExtension.aidl
similarity index 90%
copy from media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
copy to audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/VendorExtension.aidl
index 1c9bf8d..b806334 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/VendorExtension.aidl
@@ -31,11 +31,8 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.media.c2;
+package android.hardware.audio.effect;
 @VintfStability
-parcelable SurfaceSyncObj {
-  android.hardware.common.NativeHandle syncMemory;
-  long bqId;
-  int generationId;
-  long consumerUsage;
+parcelable VendorExtension {
+  ParcelableHolder extension;
 }
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Virtualizer.aidl
similarity index 67%
copy from media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
copy to audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Virtualizer.aidl
index 1c9bf8d..6092b14 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Virtualizer.aidl
@@ -31,11 +31,28 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.media.c2;
+package android.hardware.audio.effect;
 @VintfStability
-parcelable SurfaceSyncObj {
-  android.hardware.common.NativeHandle syncMemory;
-  long bqId;
-  int generationId;
-  long consumerUsage;
+union Virtualizer {
+  android.hardware.audio.effect.VendorExtension vendor;
+  int strengthPm;
+  android.hardware.audio.effect.Virtualizer.ChannelAngle[] speakerAngles;
+  android.media.audio.common.AudioDeviceDescription device;
+  @VintfStability
+  union Id {
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
+    android.hardware.audio.effect.Virtualizer.Tag commonTag;
+    android.hardware.audio.effect.Virtualizer.SpeakerAnglesPayload speakerAnglesPayload;
+  }
+  @VintfStability
+  parcelable SpeakerAnglesPayload {
+    android.media.audio.common.AudioChannelLayout layout;
+    android.media.audio.common.AudioDeviceDescription device;
+  }
+  @VintfStability
+  parcelable ChannelAngle {
+    int channel;
+    int azimuthDegree;
+    int elevationDegree;
+  }
 }
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Visualizer.aidl
similarity index 66%
copy from media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
copy to audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Visualizer.aidl
index 1c9bf8d..7d319da 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Visualizer.aidl
@@ -31,11 +31,35 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.media.c2;
+package android.hardware.audio.effect;
 @VintfStability
-parcelable SurfaceSyncObj {
-  android.hardware.common.NativeHandle syncMemory;
-  long bqId;
-  int generationId;
-  long consumerUsage;
+union Visualizer {
+  android.hardware.audio.effect.Visualizer.Id id;
+  android.hardware.audio.effect.VendorExtension vendor;
+  android.hardware.audio.effect.Visualizer.Measurement measurement;
+  byte[] captureSampleBuffer;
+  int latencyMs;
+  int captureSamples;
+  android.hardware.audio.effect.Visualizer.ScalingMode scalingMode;
+  android.hardware.audio.effect.Visualizer.MeasurementMode measurementMode;
+  @VintfStability
+  union Id {
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
+    android.hardware.audio.effect.Visualizer.Tag commonTag;
+  }
+  @VintfStability
+  enum ScalingMode {
+    NORMALIZED = 0,
+    AS_PLAYED,
+  }
+  @VintfStability
+  enum MeasurementMode {
+    NONE = 0,
+    PEAK_RMS,
+  }
+  @VintfStability
+  parcelable Measurement {
+    int rms;
+    int peak;
+  }
 }
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Volume.aidl
similarity index 84%
copy from media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
copy to audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Volume.aidl
index 1c9bf8d..8227118 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Volume.aidl
@@ -31,11 +31,15 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.media.c2;
+package android.hardware.audio.effect;
 @VintfStability
-parcelable SurfaceSyncObj {
-  android.hardware.common.NativeHandle syncMemory;
-  long bqId;
-  int generationId;
-  long consumerUsage;
+union Volume {
+  android.hardware.audio.effect.VendorExtension vendor;
+  int levelDb;
+  boolean mute;
+  @VintfStability
+  union Id {
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
+    android.hardware.audio.effect.Volume.Tag commonTag;
+  }
 }
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Descriptor.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Descriptor.aidl
index 82dae97..115da1d 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Descriptor.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Descriptor.aidl
@@ -50,8 +50,8 @@
   const String EFFECT_TYPE_UUID_PRESET_REVERB = "47382d60-ddd8-11db-bf3a-0002a5d5c51b";
   const String EFFECT_TYPE_UUID_SPATIALIZER = "ccd4cf09-a79d-46c2-9aae-06a1698d6c8f";
   const String EFFECT_TYPE_UUID_VIRTUALIZER = "37cc2c00-dddd-11db-8577-0002a5d5c51b";
-  const String EFFECT_TYPE_UUID_VISUALIZER = "d069d9e0-8329-11df-9168-0002a5d5c51b";
-  const String EFFECT_TYPE_UUID_VOLUME = "fa81a2b8-588b-11ed-9b6a-0242ac120002";
+  const String EFFECT_TYPE_UUID_VISUALIZER = "e46b26a0-dddd-11db-8afd-0002a5d5c51b";
+  const String EFFECT_TYPE_UUID_VOLUME = "09e8ede0-ddde-11db-b4f6-0002a5d5c51b";
   @VintfStability
   parcelable Identity {
     android.media.audio.common.AudioUuid type;
diff --git a/audio/aidl/android/hardware/audio/core/IModule.aidl b/audio/aidl/android/hardware/audio/core/IModule.aidl
index 7622d9a..e736c32 100644
--- a/audio/aidl/android/hardware/audio/core/IModule.aidl
+++ b/audio/aidl/android/hardware/audio/core/IModule.aidl
@@ -234,6 +234,12 @@
      * instance previously instantiated using the 'connectExternalDevice'
      * method.
      *
+     * The framework will call this method before closing streams and resetting
+     * patches. This call can be used by the HAL module to prepare itself to
+     * device disconnection. If the HAL module indicates an error after the first
+     * call, the framework will call this method once again after closing associated
+     * streams and patches.
+     *
      * @throws EX_ILLEGAL_ARGUMENT In the following cases:
      *                             - If the port can not be found by the ID.
      *                             - If this is not a connected device port.
diff --git a/audio/aidl/android/hardware/audio/effect/Descriptor.aidl b/audio/aidl/android/hardware/audio/effect/Descriptor.aidl
index 2fbc401..b152f76 100644
--- a/audio/aidl/android/hardware/audio/effect/Descriptor.aidl
+++ b/audio/aidl/android/hardware/audio/effect/Descriptor.aidl
@@ -96,11 +96,11 @@
     /**
      * UUID for visualizer effect type.
      */
-    const String EFFECT_TYPE_UUID_VISUALIZER = "d069d9e0-8329-11df-9168-0002a5d5c51b";
+    const String EFFECT_TYPE_UUID_VISUALIZER = "e46b26a0-dddd-11db-8afd-0002a5d5c51b";
     /**
      * UUID for Volume effect type.
      */
-    const String EFFECT_TYPE_UUID_VOLUME = "fa81a2b8-588b-11ed-9b6a-0242ac120002";
+    const String EFFECT_TYPE_UUID_VOLUME = "09e8ede0-ddde-11db-b4f6-0002a5d5c51b";
 
     /**
      * This structure completely identifies an effect implementation.
diff --git a/audio/aidl/common/include/Utils.h b/audio/aidl/common/include/Utils.h
index 305c924..bd903d7 100644
--- a/audio/aidl/common/include/Utils.h
+++ b/audio/aidl/common/include/Utils.h
@@ -102,7 +102,8 @@
 constexpr bool isDefaultAudioFormat(
         const ::aidl::android::media::audio::common::AudioFormatDescription& desc) {
     return desc.type == ::aidl::android::media::audio::common::AudioFormatType::DEFAULT &&
-           desc.pcm == ::aidl::android::media::audio::common::PcmType::DEFAULT;
+           desc.pcm == ::aidl::android::media::audio::common::PcmType::DEFAULT &&
+           desc.encoding.empty();
 }
 
 constexpr bool isTelephonyDeviceType(
@@ -111,30 +112,6 @@
            device == ::aidl::android::media::audio::common::AudioDeviceType::OUT_TELEPHONY_TX;
 }
 
-constexpr bool isUsbInputDeviceType(::aidl::android::media::audio::common::AudioDeviceType type) {
-    switch (type) {
-        case ::aidl::android::media::audio::common::AudioDeviceType::IN_DOCK:
-        case ::aidl::android::media::audio::common::AudioDeviceType::IN_ACCESSORY:
-        case ::aidl::android::media::audio::common::AudioDeviceType::IN_DEVICE:
-        case ::aidl::android::media::audio::common::AudioDeviceType::IN_HEADSET:
-            return true;
-        default:
-            return false;
-    }
-}
-
-constexpr bool isUsbOutputtDeviceType(::aidl::android::media::audio::common::AudioDeviceType type) {
-    switch (type) {
-        case ::aidl::android::media::audio::common::AudioDeviceType::OUT_DOCK:
-        case ::aidl::android::media::audio::common::AudioDeviceType::OUT_ACCESSORY:
-        case ::aidl::android::media::audio::common::AudioDeviceType::OUT_DEVICE:
-        case ::aidl::android::media::audio::common::AudioDeviceType::OUT_HEADSET:
-            return true;
-        default:
-            return false;
-    }
-}
-
 constexpr bool isValidAudioMode(::aidl::android::media::audio::common::AudioMode mode) {
     return std::find(kValidAudioModes.begin(), kValidAudioModes.end(), mode) !=
            kValidAudioModes.end();
diff --git a/audio/aidl/default/AidlConversionXsdc.cpp b/audio/aidl/default/AidlConversionXsdc.cpp
new file mode 100644
index 0000000..c404d67
--- /dev/null
+++ b/audio/aidl/default/AidlConversionXsdc.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2023 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_TAG "AHAL_AidlXsdc"
+#include <android-base/logging.h>
+#include <error/expected_utils.h>
+#include <media/AidlConversionCppNdk.h>
+#include <media/TypeConverter.h>
+
+#include "core-impl/AidlConversionXsdc.h"
+
+using aidl::android::media::audio::common::AudioFormatDescription;
+
+namespace xsd = android::audio::policy::configuration;
+
+namespace aidl::android::hardware::audio::core::internal {
+
+ConversionResult<AudioFormatDescription> xsdc2aidl_AudioFormatDescription(const std::string& xsdc) {
+    return legacy2aidl_audio_format_t_AudioFormatDescription(::android::formatFromString(xsdc));
+}
+
+ConversionResult<SurroundSoundConfig::SurroundFormatFamily> xsdc2aidl_SurroundFormatFamily(
+        const ::xsd::SurroundFormats::Format& xsdc) {
+    SurroundSoundConfig::SurroundFormatFamily aidl;
+    aidl.primaryFormat = VALUE_OR_RETURN(xsdc2aidl_AudioFormatDescription(xsdc.getName()));
+    if (xsdc.hasSubformats()) {
+        aidl.subFormats = VALUE_OR_RETURN(convertContainer<std::vector<AudioFormatDescription>>(
+                xsdc.getSubformats(), xsdc2aidl_AudioFormatDescription));
+    }
+    return aidl;
+}
+
+ConversionResult<SurroundSoundConfig> xsdc2aidl_SurroundSoundConfig(
+        const ::xsd::SurroundSound& xsdc) {
+    SurroundSoundConfig aidl;
+    if (!xsdc.hasFormats() || !xsdc.getFirstFormats()->hasFormat()) return aidl;
+    aidl.formatFamilies = VALUE_OR_RETURN(
+            convertContainer<std::vector<SurroundSoundConfig::SurroundFormatFamily>>(
+                    xsdc.getFirstFormats()->getFormat(), xsdc2aidl_SurroundFormatFamily));
+    return aidl;
+}
+
+}  // namespace aidl::android::hardware::audio::core::internal
diff --git a/audio/aidl/default/Android.bp b/audio/aidl/default/Android.bp
index c9edae0..bda0de2 100644
--- a/audio/aidl/default/Android.bp
+++ b/audio/aidl/default/Android.bp
@@ -65,6 +65,7 @@
     ],
     export_include_dirs: ["include"],
     srcs: [
+        "AidlConversionXsdc.cpp",
         "AudioPolicyConfigXmlConverter.cpp",
         "Bluetooth.cpp",
         "Config.cpp",
@@ -92,6 +93,21 @@
         "audio_policy_configuration_aidl_default",
         "audio_policy_engine_configuration_aidl_default",
     ],
+    shared_libs: [
+        "libaudio_aidl_conversion_common_ndk",
+        "libmedia_helper",
+        "libstagefright_foundation",
+    ],
+    export_shared_lib_headers: [
+        "libaudio_aidl_conversion_common_ndk",
+    ],
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-Werror",
+        "-Wthread-safety",
+        "-DBACKEND_NDK",
+    ],
 }
 
 cc_binary {
@@ -108,7 +124,19 @@
     static_libs: [
         "libaudioserviceexampleimpl",
     ],
+    shared_libs: [
+        "libaudio_aidl_conversion_common_ndk",
+        "libmedia_helper",
+        "libstagefright_foundation",
+    ],
     srcs: ["main.cpp"],
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-Werror",
+        "-Wthread-safety",
+        "-DBACKEND_NDK",
+    ],
 }
 
 cc_defaults {
diff --git a/audio/aidl/default/AudioPolicyConfigXmlConverter.cpp b/audio/aidl/default/AudioPolicyConfigXmlConverter.cpp
index 6290912..2848d71 100644
--- a/audio/aidl/default/AudioPolicyConfigXmlConverter.cpp
+++ b/audio/aidl/default/AudioPolicyConfigXmlConverter.cpp
@@ -21,11 +21,17 @@
 #include <functional>
 #include <unordered_map>
 
+#define LOG_TAG "AHAL_ApmXmlConverter"
+#include <android-base/logging.h>
+
 #include <aidl/android/media/audio/common/AudioHalEngineConfig.h>
+#include <media/stagefright/foundation/MediaDefs.h>
 #include <system/audio-base-utils.h>
 
+#include "core-impl/AidlConversionXsdc.h"
 #include "core-impl/AudioPolicyConfigXmlConverter.h"
 
+using aidl::android::media::audio::common::AudioFormatDescription;
 using aidl::android::media::audio::common::AudioHalEngineConfig;
 using aidl::android::media::audio::common::AudioHalVolumeCurve;
 using aidl::android::media::audio::common::AudioHalVolumeGroup;
@@ -68,13 +74,13 @@
                     getXsdcConfig()->getVolumes());
         }
         aidlVolumeCurve.curvePoints =
-                convertCollectionToAidl<std::string, AudioHalVolumeCurve::CurvePoint>(
+                convertCollectionToAidlUnchecked<std::string, AudioHalVolumeCurve::CurvePoint>(
                         mVolumesReferenceMap.at(xsdcVolumeCurve.getRef()).getPoint(),
                         std::bind(&AudioPolicyConfigXmlConverter::convertCurvePointToAidl, this,
                                   std::placeholders::_1));
     } else {
         aidlVolumeCurve.curvePoints =
-                convertCollectionToAidl<std::string, AudioHalVolumeCurve::CurvePoint>(
+                convertCollectionToAidlUnchecked<std::string, AudioHalVolumeCurve::CurvePoint>(
                         xsdcVolumeCurve.getPoint(),
                         std::bind(&AudioPolicyConfigXmlConverter::convertCurvePointToAidl, this,
                                   std::placeholders::_1));
@@ -87,6 +93,22 @@
             convertVolumeCurveToAidl(xsdcVolumeCurve));
 }
 
+const SurroundSoundConfig& AudioPolicyConfigXmlConverter::getSurroundSoundConfig() {
+    static const SurroundSoundConfig aidlSurroundSoundConfig = [this]() {
+        if (auto xsdcConfig = getXsdcConfig(); xsdcConfig && xsdcConfig->hasSurroundSound()) {
+            auto configConv = xsdc2aidl_SurroundSoundConfig(*xsdcConfig->getFirstSurroundSound());
+            if (configConv.ok()) {
+                return configConv.value();
+            }
+            LOG(ERROR) << "There was an error converting surround formats to AIDL: "
+                       << configConv.error();
+        }
+        LOG(WARNING) << "Audio policy config does not have <surroundSound> section, using default";
+        return getDefaultSurroundSoundConfig();
+    }();
+    return aidlSurroundSoundConfig;
+}
+
 const AudioHalEngineConfig& AudioPolicyConfigXmlConverter::getAidlEngineConfig() {
     if (mAidlEngineConfig.volumeGroups.empty() && getXsdcConfig() &&
         getXsdcConfig()->hasVolumes()) {
@@ -95,6 +117,47 @@
     return mAidlEngineConfig;
 }
 
+// static
+const SurroundSoundConfig& AudioPolicyConfigXmlConverter::getDefaultSurroundSoundConfig() {
+    // Provide a config similar to the one used by the framework by default
+    // (see AudioPolicyConfig::setDefaultSurroundFormats).
+#define ENCODED_FORMAT(format)        \
+    AudioFormatDescription {          \
+        .encoding = ::android::format \
+    }
+#define SIMPLE_FORMAT(format)                   \
+    SurroundSoundConfig::SurroundFormatFamily { \
+        .primaryFormat = ENCODED_FORMAT(format) \
+    }
+
+    static const SurroundSoundConfig defaultConfig = {
+            .formatFamilies = {
+                    SIMPLE_FORMAT(MEDIA_MIMETYPE_AUDIO_AC3),
+                    SIMPLE_FORMAT(MEDIA_MIMETYPE_AUDIO_EAC3),
+                    SIMPLE_FORMAT(MEDIA_MIMETYPE_AUDIO_DTS),
+                    SIMPLE_FORMAT(MEDIA_MIMETYPE_AUDIO_DTS_HD),
+                    SIMPLE_FORMAT(MEDIA_MIMETYPE_AUDIO_DTS_HD_MA),
+                    SIMPLE_FORMAT(MEDIA_MIMETYPE_AUDIO_DTS_UHD),
+                    SIMPLE_FORMAT(MEDIA_MIMETYPE_AUDIO_DTS_UHD_P2),
+                    SIMPLE_FORMAT(MEDIA_MIMETYPE_AUDIO_DOLBY_TRUEHD),
+                    SIMPLE_FORMAT(MEDIA_MIMETYPE_AUDIO_EAC3_JOC),
+                    SurroundSoundConfig::SurroundFormatFamily{
+                            .primaryFormat = ENCODED_FORMAT(MEDIA_MIMETYPE_AUDIO_AAC_LC),
+                            .subFormats =
+                                    {
+                                            ENCODED_FORMAT(MEDIA_MIMETYPE_AUDIO_AAC_HE_V1),
+                                            ENCODED_FORMAT(MEDIA_MIMETYPE_AUDIO_AAC_HE_V2),
+                                            ENCODED_FORMAT(MEDIA_MIMETYPE_AUDIO_AAC_ELD),
+                                            ENCODED_FORMAT(MEDIA_MIMETYPE_AUDIO_AAC_XHE),
+                                    }},
+                    SIMPLE_FORMAT(MEDIA_MIMETYPE_AUDIO_AC4),
+            }};
+#undef SIMPLE_FORMAT
+#undef ENCODED_FORMAT
+
+    return defaultConfig;
+}
+
 void AudioPolicyConfigXmlConverter::mapStreamsToVolumeCurves() {
     if (getXsdcConfig()->hasVolumes()) {
         for (const xsd::Volumes& xsdcWrapperType : getXsdcConfig()->getVolumes()) {
diff --git a/audio/aidl/default/Config.cpp b/audio/aidl/default/Config.cpp
index 87c0ace..d1023da 100644
--- a/audio/aidl/default/Config.cpp
+++ b/audio/aidl/default/Config.cpp
@@ -27,9 +27,16 @@
 
 namespace aidl::android::hardware::audio::core {
 ndk::ScopedAStatus Config::getSurroundSoundConfig(SurroundSoundConfig* _aidl_return) {
-    SurroundSoundConfig surroundSoundConfig;
-    // TODO: parse from XML; for now, use empty config as default
-    *_aidl_return = std::move(surroundSoundConfig);
+    static const SurroundSoundConfig surroundSoundConfig = [this]() {
+        SurroundSoundConfig surroundCfg;
+        if (mAudioPolicyConverter.getStatus() == ::android::OK) {
+            surroundCfg = mAudioPolicyConverter.getSurroundSoundConfig();
+        } else {
+            LOG(WARNING) << __func__ << mAudioPolicyConverter.getError();
+        }
+        return surroundCfg;
+    }();
+    *_aidl_return = surroundSoundConfig;
     LOG(DEBUG) << __func__ << ": returning " << _aidl_return->toString();
     return ndk::ScopedAStatus::ok();
 }
@@ -47,10 +54,14 @@
                 LOG(WARNING) << __func__ << mAudioPolicyConverter.getError();
             }
         }
+        // Logging full contents of the config is an overkill, just provide statistics.
+        LOG(DEBUG) << "getEngineConfig: number of strategies parsed: "
+                   << engConfig.productStrategies.size()
+                   << ", default strategy: " << engConfig.defaultProductStrategyId
+                   << ", number of volume groups parsed: " << engConfig.volumeGroups.size();
         return engConfig;
     }();
     *_aidl_return = returnEngCfg;
-    LOG(DEBUG) << __func__ << ": returning " << _aidl_return->toString();
     return ndk::ScopedAStatus::ok();
 }
 }  // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/Configuration.cpp b/audio/aidl/default/Configuration.cpp
index e1e1f79..d41ea67 100644
--- a/audio/aidl/default/Configuration.cpp
+++ b/audio/aidl/default/Configuration.cpp
@@ -81,6 +81,8 @@
         deviceExt.device.address = "bottom";
     } else if (devType == AudioDeviceType::IN_MICROPHONE_BACK && connection.empty()) {
         deviceExt.device.address = "back";
+    } else if (devType == AudioDeviceType::IN_SUBMIX || devType == AudioDeviceType::OUT_SUBMIX) {
+        deviceExt.device.address = "0";
     }
     deviceExt.device.type.connection = std::move(connection);
     deviceExt.flags = flags;
@@ -365,8 +367,10 @@
 
         // Device ports
 
-        AudioPort rsubmixOutDevice = createPort(c.nextPortId++, "Remote Submix Out", 0, false,
-                                                createDeviceExt(AudioDeviceType::OUT_SUBMIX, 0));
+        AudioPort rsubmixOutDevice =
+                createPort(c.nextPortId++, "Remote Submix Out", 0, false,
+                           createDeviceExt(AudioDeviceType::OUT_SUBMIX, 0,
+                                           AudioDeviceDescription::CONNECTION_VIRTUAL));
         rsubmixOutDevice.profiles.push_back(
                 createProfile(PcmType::INT_24_BIT, {AudioChannelLayout::LAYOUT_STEREO}, {48000}));
         c.ports.push_back(rsubmixOutDevice);
diff --git a/audio/aidl/default/EffectConfig.cpp b/audio/aidl/default/EffectConfig.cpp
index 5a83fef..71d111b 100644
--- a/audio/aidl/default/EffectConfig.cpp
+++ b/audio/aidl/default/EffectConfig.cpp
@@ -14,12 +14,17 @@
  * limitations under the License.
  */
 
+#include <optional>
+#include <string>
 #define LOG_TAG "AHAL_EffectConfig"
 #include <android-base/logging.h>
+#include <system/audio_effects/audio_effects_conf.h>
 #include <system/audio_effects/effect_uuid.h>
 
 #include "effectFactory-impl/EffectConfig.h"
 
+using aidl::android::media::audio::common::AudioSource;
+using aidl::android::media::audio::common::AudioStreamType;
 using aidl::android::media::audio::common::AudioUuid;
 
 namespace aidl::android::hardware::audio::effect {
@@ -55,14 +60,16 @@
         // Parse pre processing chains
         for (auto& xmlPreprocess : getChildren(xmlConfig, "preprocess")) {
             for (auto& xmlStream : getChildren(xmlPreprocess, "stream")) {
-                registerFailure(parseStream(xmlStream));
+                // AudioSource
+                registerFailure(parseProcessing(Processing::Type::source, xmlStream));
             }
         }
 
         // Parse post processing chains
         for (auto& xmlPostprocess : getChildren(xmlConfig, "postprocess")) {
             for (auto& xmlStream : getChildren(xmlPostprocess, "stream")) {
-                registerFailure(parseStream(xmlStream));
+                // AudioStreamType
+                registerFailure(parseProcessing(Processing::Type::streamType, xmlStream));
             }
         }
     }
@@ -140,21 +147,6 @@
     return true;
 }
 
-bool EffectConfig::parseStream(const tinyxml2::XMLElement& xml) {
-    LOG(DEBUG) << __func__ << dump(xml);
-    const char* type = xml.Attribute("type");
-    RETURN_VALUE_IF(!type, false, "noTypeInProcess");
-    RETURN_VALUE_IF(0 != mProcessingMap.count(type), false, "duplicateType");
-
-    for (auto& apply : getChildren(xml, "apply")) {
-        const char* name = apply.get().Attribute("effect");
-        RETURN_VALUE_IF(!name, false, "noEffectAttribute");
-        mProcessingMap[type].push_back(name);
-        LOG(DEBUG) << __func__ << " " << type << " : " << name;
-    }
-    return true;
-}
-
 bool EffectConfig::parseLibraryUuid(const tinyxml2::XMLElement& xml,
                                     struct LibraryUuid& libraryUuid, bool isProxy) {
     // Retrieve library name only if not effectProxy element
@@ -174,6 +166,80 @@
     return true;
 }
 
+std::optional<Processing::Type> EffectConfig::stringToProcessingType(Processing::Type::Tag typeTag,
+                                                                     const std::string& type) {
+    // see list of audio stream types in audio_stream_type_t:
+    // system/media/audio/include/system/audio_effects/audio_effects_conf.h
+    // AUDIO_STREAM_DEFAULT_TAG is not listed here because according to SYS_RESERVED_DEFAULT in
+    // AudioStreamType.aidl: "Value reserved for system use only. HALs must never return this value
+    // to the system or accept it from the system".
+    static const std::map<const std::string, AudioStreamType> sAudioStreamTypeTable = {
+            {AUDIO_STREAM_VOICE_CALL_TAG, AudioStreamType::VOICE_CALL},
+            {AUDIO_STREAM_SYSTEM_TAG, AudioStreamType::SYSTEM},
+            {AUDIO_STREAM_RING_TAG, AudioStreamType::RING},
+            {AUDIO_STREAM_MUSIC_TAG, AudioStreamType::MUSIC},
+            {AUDIO_STREAM_ALARM_TAG, AudioStreamType::ALARM},
+            {AUDIO_STREAM_NOTIFICATION_TAG, AudioStreamType::NOTIFICATION},
+            {AUDIO_STREAM_BLUETOOTH_SCO_TAG, AudioStreamType::BLUETOOTH_SCO},
+            {AUDIO_STREAM_ENFORCED_AUDIBLE_TAG, AudioStreamType::ENFORCED_AUDIBLE},
+            {AUDIO_STREAM_DTMF_TAG, AudioStreamType::DTMF},
+            {AUDIO_STREAM_TTS_TAG, AudioStreamType::TTS},
+            {AUDIO_STREAM_ASSISTANT_TAG, AudioStreamType::ASSISTANT}};
+
+    // see list of audio sources in audio_source_t:
+    // system/media/audio/include/system/audio_effects/audio_effects_conf.h
+    static const std::map<const std::string, AudioSource> sAudioSourceTable = {
+            {MIC_SRC_TAG, AudioSource::VOICE_CALL},
+            {VOICE_UL_SRC_TAG, AudioSource::VOICE_CALL},
+            {VOICE_DL_SRC_TAG, AudioSource::VOICE_CALL},
+            {VOICE_CALL_SRC_TAG, AudioSource::VOICE_CALL},
+            {CAMCORDER_SRC_TAG, AudioSource::VOICE_CALL},
+            {VOICE_REC_SRC_TAG, AudioSource::VOICE_CALL},
+            {VOICE_COMM_SRC_TAG, AudioSource::VOICE_CALL},
+            {REMOTE_SUBMIX_SRC_TAG, AudioSource::VOICE_CALL},
+            {UNPROCESSED_SRC_TAG, AudioSource::VOICE_CALL},
+            {VOICE_PERFORMANCE_SRC_TAG, AudioSource::VOICE_CALL}};
+
+    if (typeTag == Processing::Type::streamType) {
+        auto typeIter = sAudioStreamTypeTable.find(type);
+        if (typeIter != sAudioStreamTypeTable.end()) {
+            return typeIter->second;
+        }
+    } else if (typeTag == Processing::Type::source) {
+        auto typeIter = sAudioSourceTable.find(type);
+        if (typeIter != sAudioSourceTable.end()) {
+            return typeIter->second;
+        }
+    }
+
+    return std::nullopt;
+}
+
+bool EffectConfig::parseProcessing(Processing::Type::Tag typeTag, const tinyxml2::XMLElement& xml) {
+    LOG(DEBUG) << __func__ << dump(xml);
+    const char* typeStr = xml.Attribute("type");
+    auto aidlType = stringToProcessingType(typeTag, typeStr);
+    RETURN_VALUE_IF(!aidlType.has_value(), false, "illegalStreamType");
+    RETURN_VALUE_IF(0 != mProcessingMap.count(aidlType.value()), false, "duplicateStreamType");
+
+    for (auto& apply : getChildren(xml, "apply")) {
+        const char* name = apply.get().Attribute("effect");
+        if (mEffectsMap.find(name) == mEffectsMap.end()) {
+            LOG(ERROR) << __func__ << " effect " << name << " doesn't exist, skipping";
+            continue;
+        }
+        RETURN_VALUE_IF(!name, false, "noEffectAttribute");
+        mProcessingMap[aidlType.value()].emplace_back(mEffectsMap[name]);
+        LOG(WARNING) << __func__ << " " << typeStr << " : " << name;
+    }
+    return true;
+}
+
+const std::map<Processing::Type, std::vector<EffectConfig::EffectLibraries>>&
+EffectConfig::getProcessingMap() const {
+    return mProcessingMap;
+}
+
 bool EffectConfig::findUuid(const std::string& xmlEffectName, AudioUuid* uuid) {
 // Difference from EFFECT_TYPE_LIST_DEF, there could be multiple name mapping to same Effect Type
 #define EFFECT_XML_TYPE_LIST_DEF(V)                        \
diff --git a/audio/aidl/default/EffectFactory.cpp b/audio/aidl/default/EffectFactory.cpp
index f0687cc..7073a10 100644
--- a/audio/aidl/default/EffectFactory.cpp
+++ b/audio/aidl/default/EffectFactory.cpp
@@ -15,8 +15,10 @@
  */
 
 #include <dlfcn.h>
+#include <algorithm>
 #include <iterator>
 #include <memory>
+#include <optional>
 #include <tuple>
 #include <unordered_set>
 #define LOG_TAG "AHAL_EffectFactory"
@@ -52,6 +54,22 @@
     }
 }
 
+ndk::ScopedAStatus Factory::getDescriptorWithUuid(const AudioUuid& uuid, Descriptor* desc) {
+    RETURN_IF(!desc, EX_NULL_POINTER, "nullDescriptor");
+
+    if (mEffectLibMap.count(uuid)) {
+        auto& entry = mEffectLibMap[uuid];
+        getDlSyms(entry);
+        auto& libInterface = std::get<kMapEntryInterfaceIndex>(entry);
+        RETURN_IF(!libInterface || !libInterface->queryEffectFunc, EX_NULL_POINTER,
+                  "dlNullQueryEffectFunc");
+        RETURN_IF_BINDER_EXCEPTION(libInterface->queryEffectFunc(&uuid, desc));
+        return ndk::ScopedAStatus::ok();
+    }
+
+    return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+}
+
 ndk::ScopedAStatus Factory::queryEffects(const std::optional<AudioUuid>& in_type_uuid,
                                          const std::optional<AudioUuid>& in_impl_uuid,
                                          const std::optional<AudioUuid>& in_proxy_uuid,
@@ -69,12 +87,7 @@
     for (const auto& id : idList) {
         if (mEffectLibMap.count(id.uuid)) {
             Descriptor desc;
-            auto& entry = mEffectLibMap[id.uuid];
-            getDlSyms(entry);
-            auto& libInterface = std::get<kMapEntryInterfaceIndex>(entry);
-            RETURN_IF(!libInterface || !libInterface->queryEffectFunc, EX_NULL_POINTER,
-                      "dlNullQueryEffectFunc");
-            RETURN_IF_BINDER_EXCEPTION(libInterface->queryEffectFunc(&id.uuid, &desc));
+            RETURN_IF_ASTATUS_NOT_OK(getDescriptorWithUuid(id.uuid, &desc), "getDescriptorFailed");
             // update proxy UUID with information from config xml
             desc.common.id.proxy = id.proxy;
             _aidl_return->emplace_back(std::move(desc));
@@ -85,12 +98,26 @@
 
 ndk::ScopedAStatus Factory::queryProcessing(const std::optional<Processing::Type>& in_type,
                                             std::vector<Processing>* _aidl_return) {
-    // TODO: implement this with audio_effect.xml.
-    if (in_type.has_value()) {
-        // return all matching process filter
-        LOG(DEBUG) << __func__ << " process type: " << in_type.value().toString();
+    const auto& processings = mConfig.getProcessingMap();
+    // Processing stream type
+    for (const auto& procIter : processings) {
+        if (!in_type.has_value() || in_type.value() == procIter.first) {
+            Processing process = {.type = procIter.first /* Processing::Type */};
+            for (const auto& libs : procIter.second /* std::vector<struct EffectLibraries> */) {
+                for (const auto& lib : libs.libraries /* std::vector<struct LibraryUuid> */) {
+                    Descriptor desc;
+                    if (libs.proxyLibrary.has_value()) {
+                        desc.common.id.proxy = libs.proxyLibrary.value().uuid;
+                    }
+                    RETURN_IF_ASTATUS_NOT_OK(getDescriptorWithUuid(lib.uuid, &desc),
+                                             "getDescriptorFailed");
+                    process.ids.emplace_back(desc);
+                }
+            }
+            _aidl_return->emplace_back(process);
+        }
     }
-    LOG(DEBUG) << __func__ << " return " << _aidl_return->size();
+
     return ndk::ScopedAStatus::ok();
 }
 
diff --git a/audio/aidl/default/EngineConfigXmlConverter.cpp b/audio/aidl/default/EngineConfigXmlConverter.cpp
index 5f17d71..96b555c 100644
--- a/audio/aidl/default/EngineConfigXmlConverter.cpp
+++ b/audio/aidl/default/EngineConfigXmlConverter.cpp
@@ -140,7 +140,7 @@
     aidlAttributesGroup.volumeGroupName = xsdcAttributesGroup.getVolumeGroup();
     if (xsdcAttributesGroup.hasAttributes_optional()) {
         aidlAttributesGroup.attributes =
-                convertCollectionToAidl<xsd::AttributesType, AudioAttributes>(
+                convertCollectionToAidlUnchecked<xsd::AttributesType, AudioAttributes>(
                         xsdcAttributesGroup.getAttributes_optional(),
                         std::bind(&EngineConfigXmlConverter::convertAudioAttributesToAidl, this,
                                   std::placeholders::_1));
@@ -172,7 +172,7 @@
 
     if (xsdcProductStrategy.hasAttributesGroup()) {
         aidlProductStrategy.attributesGroups =
-                convertCollectionToAidl<xsd::AttributesGroup, AudioHalAttributesGroup>(
+                convertCollectionToAidlUnchecked<xsd::AttributesGroup, AudioHalAttributesGroup>(
                         xsdcProductStrategy.getAttributesGroup(),
                         std::bind(&EngineConfigXmlConverter::convertAttributesGroupToAidl, this,
                                   std::placeholders::_1));
@@ -204,13 +204,13 @@
                     getXsdcConfig()->getVolumes());
         }
         aidlVolumeCurve.curvePoints =
-                convertCollectionToAidl<std::string, AudioHalVolumeCurve::CurvePoint>(
+                convertCollectionToAidlUnchecked<std::string, AudioHalVolumeCurve::CurvePoint>(
                         mVolumesReferenceMap.at(xsdcVolumeCurve.getRef()).getPoint(),
                         std::bind(&EngineConfigXmlConverter::convertCurvePointToAidl, this,
                                   std::placeholders::_1));
     } else {
         aidlVolumeCurve.curvePoints =
-                convertCollectionToAidl<std::string, AudioHalVolumeCurve::CurvePoint>(
+                convertCollectionToAidlUnchecked<std::string, AudioHalVolumeCurve::CurvePoint>(
                         xsdcVolumeCurve.getPoint(),
                         std::bind(&EngineConfigXmlConverter::convertCurvePointToAidl, this,
                                   std::placeholders::_1));
@@ -224,10 +224,11 @@
     aidlVolumeGroup.name = xsdcVolumeGroup.getName();
     aidlVolumeGroup.minIndex = xsdcVolumeGroup.getIndexMin();
     aidlVolumeGroup.maxIndex = xsdcVolumeGroup.getIndexMax();
-    aidlVolumeGroup.volumeCurves = convertCollectionToAidl<xsd::Volume, AudioHalVolumeCurve>(
-            xsdcVolumeGroup.getVolume(),
-            std::bind(&EngineConfigXmlConverter::convertVolumeCurveToAidl, this,
-                      std::placeholders::_1));
+    aidlVolumeGroup.volumeCurves =
+            convertCollectionToAidlUnchecked<xsd::Volume, AudioHalVolumeCurve>(
+                    xsdcVolumeGroup.getVolume(),
+                    std::bind(&EngineConfigXmlConverter::convertVolumeCurveToAidl, this,
+                              std::placeholders::_1));
     return aidlVolumeGroup;
 }
 
@@ -251,7 +252,7 @@
     aidlCapCriterionType.name = xsdcCriterionType.getName();
     aidlCapCriterionType.isInclusive = !(static_cast<bool>(xsdcCriterionType.getType()));
     aidlCapCriterionType.values =
-            convertWrappedCollectionToAidl<xsd::ValuesType, xsd::ValueType, std::string>(
+            convertWrappedCollectionToAidlUnchecked<xsd::ValuesType, xsd::ValueType, std::string>(
                     xsdcCriterionType.getValues(), &xsd::ValuesType::getValue,
                     std::bind(&EngineConfigXmlConverter::convertCriterionTypeValueToAidl, this,
                               std::placeholders::_1));
@@ -266,9 +267,9 @@
     initProductStrategyMap();
     if (getXsdcConfig()->hasProductStrategies()) {
         mAidlEngineConfig.productStrategies =
-                convertWrappedCollectionToAidl<xsd::ProductStrategies,
-                                               xsd::ProductStrategies::ProductStrategy,
-                                               AudioHalProductStrategy>(
+                convertWrappedCollectionToAidlUnchecked<xsd::ProductStrategies,
+                                                        xsd::ProductStrategies::ProductStrategy,
+                                                        AudioHalProductStrategy>(
                         getXsdcConfig()->getProductStrategies(),
                         &xsd::ProductStrategies::getProductStrategy,
                         std::bind(&EngineConfigXmlConverter::convertProductStrategyToAidl, this,
@@ -278,7 +279,7 @@
         }
     }
     if (getXsdcConfig()->hasVolumeGroups()) {
-        mAidlEngineConfig.volumeGroups = convertWrappedCollectionToAidl<
+        mAidlEngineConfig.volumeGroups = convertWrappedCollectionToAidlUnchecked<
                 xsd::VolumeGroupsType, xsd::VolumeGroupsType::VolumeGroup, AudioHalVolumeGroup>(
                 getXsdcConfig()->getVolumeGroups(), &xsd::VolumeGroupsType::getVolumeGroup,
                 std::bind(&EngineConfigXmlConverter::convertVolumeGroupToAidl, this,
@@ -287,19 +288,17 @@
     if (getXsdcConfig()->hasCriteria() && getXsdcConfig()->hasCriterion_types()) {
         AudioHalEngineConfig::CapSpecificConfig capSpecificConfig;
         capSpecificConfig.criteria =
-                convertWrappedCollectionToAidl<xsd::CriteriaType, xsd::CriterionType,
-                                               AudioHalCapCriterion>(
+                convertWrappedCollectionToAidlUnchecked<xsd::CriteriaType, xsd::CriterionType,
+                                                        AudioHalCapCriterion>(
                         getXsdcConfig()->getCriteria(), &xsd::CriteriaType::getCriterion,
                         std::bind(&EngineConfigXmlConverter::convertCapCriterionToAidl, this,
                                   std::placeholders::_1));
-        capSpecificConfig.criterionTypes =
-                convertWrappedCollectionToAidl<xsd::CriterionTypesType, xsd::CriterionTypeType,
-                                               AudioHalCapCriterionType>(
-                        getXsdcConfig()->getCriterion_types(),
-                        &xsd::CriterionTypesType::getCriterion_type,
-                        std::bind(&EngineConfigXmlConverter::convertCapCriterionTypeToAidl, this,
-                                  std::placeholders::_1));
+        capSpecificConfig.criterionTypes = convertWrappedCollectionToAidlUnchecked<
+                xsd::CriterionTypesType, xsd::CriterionTypeType, AudioHalCapCriterionType>(
+                getXsdcConfig()->getCriterion_types(), &xsd::CriterionTypesType::getCriterion_type,
+                std::bind(&EngineConfigXmlConverter::convertCapCriterionTypeToAidl, this,
+                          std::placeholders::_1));
         mAidlEngineConfig.capSpecificConfig = capSpecificConfig;
     }
 }
-}  // namespace aidl::android::hardware::audio::core::internal
\ No newline at end of file
+}  // namespace aidl::android::hardware::audio::core::internal
diff --git a/audio/aidl/default/Module.cpp b/audio/aidl/default/Module.cpp
index 6b417a4..6885a49 100644
--- a/audio/aidl/default/Module.cpp
+++ b/audio/aidl/default/Module.cpp
@@ -187,7 +187,7 @@
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
     }
     LOG(DEBUG) << __func__ << ": frame size " << frameSize << " bytes";
-    if (frameSize > kMaximumStreamBufferSizeBytes / in_bufferSizeFrames) {
+    if (frameSize > static_cast<size_t>(kMaximumStreamBufferSizeBytes / in_bufferSizeFrames)) {
         LOG(ERROR) << __func__ << ": buffer size " << in_bufferSizeFrames
                    << " frames is too large, maximum size is "
                    << kMaximumStreamBufferSizeBytes / frameSize;
@@ -281,7 +281,7 @@
                    << " does not correspond to a mix port";
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
     }
-    const int32_t maxOpenStreamCount = portIt->ext.get<AudioPortExt::Tag::mix>().maxOpenStreamCount;
+    const size_t maxOpenStreamCount = portIt->ext.get<AudioPortExt::Tag::mix>().maxOpenStreamCount;
     if (maxOpenStreamCount != 0 && mStreams.count(portId) >= maxOpenStreamCount) {
         LOG(ERROR) << __func__ << ": port id " << portId
                    << " has already reached maximum allowed opened stream count: "
diff --git a/audio/aidl/default/audio_effects_config.xml b/audio/aidl/default/audio_effects_config.xml
index c06742d..6627ae7 100644
--- a/audio/aidl/default/audio_effects_config.xml
+++ b/audio/aidl/default/audio_effects_config.xml
@@ -95,8 +95,17 @@
             <libsw library="bundle" uuid="ce772f20-847d-11df-bb17-0002a5d5c51b"/>
         </effectProxy>
         <effect name="extensioneffect" library="extensioneffect" uuid="fa81dd00-588b-11ed-9b6a-0242ac120002"/>
+        <effect name="acoustic_echo_canceler" library="aecsw" uuid="bb392ec0-8d4d-11e0-a896-0002a5d5c51b"/>
+        <effect name="noise_suppression" library="nssw" uuid="c06c8400-8e06-11e0-9cb6-0002a5d5c51b"/>
     </effects>
 
+    <preprocess>
+        <stream type="voice_communication">
+            <apply effect="acoustic_echo_canceler"/>
+            <apply effect="noise_suppression"/>
+        </stream>
+    </preprocess>
+
     <!-- Audio pre processor configurations.
          The pre processor configuration is described in a "preprocess" element and consists in a
          list of elements each describing pre processor settings for a given use case or "stream".
diff --git a/audio/aidl/default/bassboost/BassBoostSw.cpp b/audio/aidl/default/bassboost/BassBoostSw.cpp
index dbf2e15..6072d89 100644
--- a/audio/aidl/default/bassboost/BassBoostSw.cpp
+++ b/audio/aidl/default/bassboost/BassBoostSw.cpp
@@ -68,8 +68,7 @@
 const Capability BassBoostSw::kCapability = {.range = {BassBoostSw::kRanges}};
 const Descriptor BassBoostSw::kDescriptor = {
         .common = {.id = {.type = getEffectTypeUuidBassBoost(),
-                          .uuid = getEffectImplUuidBassBoostSw(),
-                          .proxy = getEffectImplUuidBassBoostProxy()},
+                          .uuid = getEffectImplUuidBassBoostSw()},
                    .flags = {.type = Flags::Type::INSERT,
                              .insert = Flags::Insert::FIRST,
                              .volume = Flags::Volume::CTRL},
diff --git a/audio/aidl/default/config/audioPolicy/api/current.txt b/audio/aidl/default/config/audioPolicy/api/current.txt
index ad79a0c..ba867a0 100644
--- a/audio/aidl/default/config/audioPolicy/api/current.txt
+++ b/audio/aidl/default/config/audioPolicy/api/current.txt
@@ -33,14 +33,19 @@
     enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_8;
     enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_9;
     enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_IN_2POINT0POINT2;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_IN_2POINT1;
     enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_IN_2POINT1POINT2;
     enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_IN_3POINT0POINT2;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_IN_3POINT1;
     enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_IN_3POINT1POINT2;
     enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_IN_5POINT1;
     enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_IN_6;
     enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_IN_FRONT_BACK;
     enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_IN_MONO;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_IN_PENTA;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_IN_QUAD;
     enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_IN_STEREO;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_IN_TRI;
     enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_IN_VOICE_CALL_MONO;
     enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_IN_VOICE_DNLINK_MONO;
     enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_IN_VOICE_UPLINK_MONO;
diff --git a/audio/aidl/default/config/audioPolicy/audio_policy_configuration.xsd b/audio/aidl/default/config/audioPolicy/audio_policy_configuration.xsd
index 301c969..92d6777 100644
--- a/audio/aidl/default/config/audioPolicy/audio_policy_configuration.xsd
+++ b/audio/aidl/default/config/audioPolicy/audio_policy_configuration.xsd
@@ -533,12 +533,17 @@
             <xs:enumeration value="AUDIO_CHANNEL_OUT_STEREO_HAPTIC_AB"/>
             <xs:enumeration value="AUDIO_CHANNEL_IN_MONO"/>
             <xs:enumeration value="AUDIO_CHANNEL_IN_STEREO"/>
+            <xs:enumeration value="AUDIO_CHANNEL_IN_2POINT1"/>
             <xs:enumeration value="AUDIO_CHANNEL_IN_FRONT_BACK"/>
+            <xs:enumeration value="AUDIO_CHANNEL_IN_TRI"/>
+            <xs:enumeration value="AUDIO_CHANNEL_IN_3POINT1"/>
             <xs:enumeration value="AUDIO_CHANNEL_IN_6"/>
             <xs:enumeration value="AUDIO_CHANNEL_IN_2POINT0POINT2"/>
             <xs:enumeration value="AUDIO_CHANNEL_IN_2POINT1POINT2"/>
             <xs:enumeration value="AUDIO_CHANNEL_IN_3POINT0POINT2"/>
             <xs:enumeration value="AUDIO_CHANNEL_IN_3POINT1POINT2"/>
+            <xs:enumeration value="AUDIO_CHANNEL_IN_QUAD"/>
+            <xs:enumeration value="AUDIO_CHANNEL_IN_PENTA"/>
             <xs:enumeration value="AUDIO_CHANNEL_IN_5POINT1"/>
             <xs:enumeration value="AUDIO_CHANNEL_IN_VOICE_UPLINK_MONO"/>
             <xs:enumeration value="AUDIO_CHANNEL_IN_VOICE_DNLINK_MONO"/>
diff --git a/audio/aidl/default/equalizer/EqualizerSw.cpp b/audio/aidl/default/equalizer/EqualizerSw.cpp
index 9769924..b2add31 100644
--- a/audio/aidl/default/equalizer/EqualizerSw.cpp
+++ b/audio/aidl/default/equalizer/EqualizerSw.cpp
@@ -88,16 +88,14 @@
         MAKE_RANGE(Equalizer, centerFreqMh, std::vector<int>({1}), std::vector<int>({0}))};
 
 const Capability EqualizerSw::kEqCap = {.range = EqualizerSw::kRanges};
-const Descriptor EqualizerSw::kDesc = {
-        .common = {.id = {.type = getEffectTypeUuidEqualizer(),
-                          .uuid = getEffectImplUuidEqualizerSw(),
-                          .proxy = getEffectImplUuidEqualizerProxy()},
-                   .flags = {.type = Flags::Type::INSERT,
-                             .insert = Flags::Insert::FIRST,
-                             .volume = Flags::Volume::CTRL},
-                   .name = EqualizerSw::kEffectName,
-                   .implementor = "The Android Open Source Project"},
-        .capability = EqualizerSw::kEqCap};
+const Descriptor EqualizerSw::kDesc = {.common = {.id = {.type = getEffectTypeUuidEqualizer(),
+                                                         .uuid = getEffectImplUuidEqualizerSw()},
+                                                  .flags = {.type = Flags::Type::INSERT,
+                                                            .insert = Flags::Insert::FIRST,
+                                                            .volume = Flags::Volume::CTRL},
+                                                  .name = EqualizerSw::kEffectName,
+                                                  .implementor = "The Android Open Source Project"},
+                                       .capability = EqualizerSw::kEqCap};
 
 ndk::ScopedAStatus EqualizerSw::getDescriptor(Descriptor* _aidl_return) {
     LOG(DEBUG) << __func__ << kDesc.toString();
diff --git a/audio/aidl/default/include/core-impl/AidlConversionXsdc.h b/audio/aidl/default/include/core-impl/AidlConversionXsdc.h
new file mode 100644
index 0000000..c9aefc7
--- /dev/null
+++ b/audio/aidl/default/include/core-impl/AidlConversionXsdc.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/audio/core/SurroundSoundConfig.h>
+#include <aidl/android/media/audio/common/AudioFormatDescription.h>
+#include <android_audio_policy_configuration.h>
+#include <media/AidlConversionUtil.h>
+
+namespace aidl::android::hardware::audio::core::internal {
+
+ConversionResult<::aidl::android::media::audio::common::AudioFormatDescription>
+xsdc2aidl_AudioFormatDescription(const std::string& xsdc);
+
+ConversionResult<SurroundSoundConfig> xsdc2aidl_SurroundSoundConfig(
+        const ::android::audio::policy::configuration::SurroundSound& xsdc);
+
+}  // namespace aidl::android::hardware::audio::core::internal
diff --git a/audio/aidl/default/include/core-impl/AudioPolicyConfigXmlConverter.h b/audio/aidl/default/include/core-impl/AudioPolicyConfigXmlConverter.h
index 47918f0..94501a8 100644
--- a/audio/aidl/default/include/core-impl/AudioPolicyConfigXmlConverter.h
+++ b/audio/aidl/default/include/core-impl/AudioPolicyConfigXmlConverter.h
@@ -18,6 +18,7 @@
 
 #include <string>
 
+#include <aidl/android/hardware/audio/core/SurroundSoundConfig.h>
 #include <aidl/android/media/audio/common/AudioHalEngineConfig.h>
 #include <android_audio_policy_configuration.h>
 #include <android_audio_policy_configuration_enums.h>
@@ -35,8 +36,11 @@
     ::android::status_t getStatus() const { return mConverter.getStatus(); }
 
     const ::aidl::android::media::audio::common::AudioHalEngineConfig& getAidlEngineConfig();
+    const SurroundSoundConfig& getSurroundSoundConfig();
 
   private:
+    static const SurroundSoundConfig& getDefaultSurroundSoundConfig();
+
     const std::optional<::android::audio::policy::configuration::AudioPolicyConfiguration>&
     getXsdcConfig() const {
         return mConverter.getXsdcConfig();
@@ -48,7 +52,6 @@
     void parseVolumes();
     ::aidl::android::media::audio::common::AudioHalVolumeCurve::CurvePoint convertCurvePointToAidl(
             const std::string& xsdcCurvePoint);
-
     ::aidl::android::media::audio::common::AudioHalVolumeCurve convertVolumeCurveToAidl(
             const ::android::audio::policy::configuration::Volume& xsdcVolumeCurve);
 
diff --git a/audio/aidl/default/include/core-impl/Stream.h b/audio/aidl/default/include/core-impl/Stream.h
index 65680df..476f1ff 100644
--- a/audio/aidl/default/include/core-impl/Stream.h
+++ b/audio/aidl/default/include/core-impl/Stream.h
@@ -155,20 +155,19 @@
 struct DriverInterface {
     using CreateInstance = std::function<DriverInterface*(const StreamContext&)>;
     virtual ~DriverInterface() = default;
-    // This function is called once, on the main thread, before starting the worker thread.
-    virtual ::android::status_t init() = 0;
-    // This function is called from Binder pool thread. It must be done in a thread-safe manner
-    // if this method and other methods in this interface share data.
-    virtual ::android::status_t setConnectedDevices(
-            const std::vector<::aidl::android::media::audio::common::AudioDevice>&
-                    connectedDevices) = 0;
-    // All the functions below are called on the worker thread.
+    // All the methods below are called on the worker thread.
+    virtual ::android::status_t init() = 0;  // This function is only called once.
     virtual ::android::status_t drain(StreamDescriptor::DrainMode mode) = 0;
     virtual ::android::status_t flush() = 0;
     virtual ::android::status_t pause() = 0;
     virtual ::android::status_t transfer(void* buffer, size_t frameCount, size_t* actualFrameCount,
                                          int32_t* latencyMs) = 0;
     virtual ::android::status_t standby() = 0;
+    // The method below is called from a thread of the Binder pool. Access to data shared with other
+    // methods of this interface must be done in a thread-safe manner.
+    virtual ::android::status_t setConnectedDevices(
+            const std::vector<::aidl::android::media::audio::common::AudioDevice>&
+                    connectedDevices) = 0;
 };
 
 class StreamWorkerCommonLogic : public ::android::hardware::audio::common::StreamLogic {
diff --git a/audio/aidl/default/include/core-impl/StreamStub.h b/audio/aidl/default/include/core-impl/StreamStub.h
index df0182c..436e610 100644
--- a/audio/aidl/default/include/core-impl/StreamStub.h
+++ b/audio/aidl/default/include/core-impl/StreamStub.h
@@ -24,15 +24,16 @@
   public:
     DriverStub(const StreamContext& context, bool isInput);
     ::android::status_t init() override;
-    ::android::status_t setConnectedDevices(
-            const std::vector<::aidl::android::media::audio::common::AudioDevice>& connectedDevices)
-            override;
     ::android::status_t drain(StreamDescriptor::DrainMode) override;
     ::android::status_t flush() override;
     ::android::status_t pause() override;
     ::android::status_t transfer(void* buffer, size_t frameCount, size_t* actualFrameCount,
                                  int32_t* latencyMs) override;
     ::android::status_t standby() override;
+    // Note: called on a different thread.
+    ::android::status_t setConnectedDevices(
+            const std::vector<::aidl::android::media::audio::common::AudioDevice>& connectedDevices)
+            override;
 
   private:
     const size_t mFrameSizeBytes;
diff --git a/audio/aidl/default/include/core-impl/StreamUsb.h b/audio/aidl/default/include/core-impl/StreamUsb.h
index 36e64cb..05d889a 100644
--- a/audio/aidl/default/include/core-impl/StreamUsb.h
+++ b/audio/aidl/default/include/core-impl/StreamUsb.h
@@ -34,15 +34,16 @@
   public:
     DriverUsb(const StreamContext& context, bool isInput);
     ::android::status_t init() override;
-    ::android::status_t setConnectedDevices(
-            const std::vector<::aidl::android::media::audio::common::AudioDevice>& connectedDevices)
-            override;
     ::android::status_t drain(StreamDescriptor::DrainMode) override;
     ::android::status_t flush() override;
     ::android::status_t pause() override;
     ::android::status_t transfer(void* buffer, size_t frameCount, size_t* actualFrameCount,
                                  int32_t* latencyMs) override;
     ::android::status_t standby() override;
+    // Note: called on a different thread.
+    ::android::status_t setConnectedDevices(
+            const std::vector<::aidl::android::media::audio::common::AudioDevice>& connectedDevices)
+            override;
 
   private:
     ::android::status_t exitStandby();
diff --git a/audio/aidl/default/include/core-impl/XmlConverter.h b/audio/aidl/default/include/core-impl/XmlConverter.h
index ec23edb..a68a6fd 100644
--- a/audio/aidl/default/include/core-impl/XmlConverter.h
+++ b/audio/aidl/default/include/core-impl/XmlConverter.h
@@ -20,6 +20,7 @@
 #include <string>
 #include <unordered_map>
 
+#include <media/AidlConversionUtil.h>
 #include <system/audio_config.h>
 #include <utils/Errors.h>
 
@@ -78,7 +79,7 @@
  *     </Modules>
  */
 template <typename W, typename X, typename A>
-static std::vector<A> convertWrappedCollectionToAidl(
+std::vector<A> convertWrappedCollectionToAidlUnchecked(
         const std::vector<W>& xsdcWrapperTypeVec,
         std::function<const std::vector<X>&(const W&)> getInnerTypeVec,
         std::function<A(const X&)> convertToAidl) {
@@ -100,12 +101,12 @@
 }
 
 template <typename X, typename A>
-static std::vector<A> convertCollectionToAidl(const std::vector<X>& xsdcTypeVec,
-                                              std::function<A(const X&)> convertToAidl) {
+std::vector<A> convertCollectionToAidlUnchecked(const std::vector<X>& xsdcTypeVec,
+                                                std::function<A(const X&)> itemConversion) {
     std::vector<A> resultAidlTypeVec;
     resultAidlTypeVec.reserve(xsdcTypeVec.size());
     std::transform(xsdcTypeVec.begin(), xsdcTypeVec.end(), std::back_inserter(resultAidlTypeVec),
-                   convertToAidl);
+                   itemConversion);
     return resultAidlTypeVec;
 }
 
@@ -121,8 +122,7 @@
  *     </Wrapper>
  */
 template <typename W, typename R>
-static std::unordered_map<std::string, R> generateReferenceMap(
-        const std::vector<W>& xsdcWrapperTypeVec) {
+std::unordered_map<std::string, R> generateReferenceMap(const std::vector<W>& xsdcWrapperTypeVec) {
     std::unordered_map<std::string, R> resultMap;
     if (!xsdcWrapperTypeVec.empty()) {
         /*
diff --git a/audio/aidl/default/include/effectFactory-impl/EffectConfig.h b/audio/aidl/default/include/effectFactory-impl/EffectConfig.h
index c627a27..f8a86e1 100644
--- a/audio/aidl/default/include/effectFactory-impl/EffectConfig.h
+++ b/audio/aidl/default/include/effectFactory-impl/EffectConfig.h
@@ -26,6 +26,7 @@
 #include <cutils/properties.h>
 #include <tinyxml2.h>
 
+#include <aidl/android/hardware/audio/effect/Processing.h>
 #include "effect-impl/EffectTypes.h"
 
 namespace aidl::android::hardware::audio::effect {
@@ -39,11 +40,6 @@
   public:
     explicit EffectConfig(const std::string& file);
 
-    // <library>
-    struct Library {
-        std::string name;
-        std::string path;
-    };
     struct LibraryUuid {
         std::string name;  // library name
         ::aidl::android::media::audio::common::AudioUuid uuid;
@@ -59,13 +55,13 @@
     const std::unordered_map<std::string, struct EffectLibraries> getEffectsMap() const {
         return mEffectsMap;
     }
-    const std::unordered_map<std::string, std::vector<std::string>> getProcessingMap() const {
-        return mProcessingMap;
-    }
 
     static bool findUuid(const std::string& xmlEffectName,
                          ::aidl::android::media::audio::common::AudioUuid* uuid);
 
+    using ProcessingLibrariesMap = std::map<Processing::Type, std::vector<struct EffectLibraries>>;
+    const ProcessingLibrariesMap& getProcessingMap() const;
+
   private:
     static constexpr const char* kEffectLibPath[] =
 #ifdef __LP64__
@@ -79,8 +75,11 @@
     std::unordered_map<std::string, std::string> mLibraryMap;
     /* Parsed Effects result */
     std::unordered_map<std::string, struct EffectLibraries> mEffectsMap;
-    /* Parsed pre/post processing result */
-    std::unordered_map<std::string, std::vector<std::string>> mProcessingMap;
+    /**
+     * For parsed pre/post processing result: {key: AudioStreamType/AudioSource, value:
+     * EffectLibraries}
+     */
+    ProcessingLibrariesMap mProcessingMap;
 
     /** @return all `node`s children that are elements and match the tag if provided. */
     std::vector<std::reference_wrapper<const tinyxml2::XMLElement>> getChildren(
@@ -94,7 +93,7 @@
      */
     bool parseEffect(const tinyxml2::XMLElement& xml);
 
-    bool parseStream(const tinyxml2::XMLElement& xml);
+    bool parseProcessing(Processing::Type::Tag typeTag, const tinyxml2::XMLElement& xml);
 
     // Function to parse effect.library name and effect.uuid from xml
     bool parseLibraryUuid(const tinyxml2::XMLElement& xml, struct LibraryUuid& libraryUuid,
@@ -104,6 +103,9 @@
                      tinyxml2::XMLPrinter&& printer = {}) const;
 
     bool resolveLibrary(const std::string& path, std::string* resolvedPath);
+
+    std::optional<Processing::Type> stringToProcessingType(Processing::Type::Tag typeTag,
+                                                           const std::string& type);
 };
 
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/include/effectFactory-impl/EffectFactory.h b/audio/aidl/default/include/effectFactory-impl/EffectFactory.h
index b7f63af..ad59ca7 100644
--- a/audio/aidl/default/include/effectFactory-impl/EffectFactory.h
+++ b/audio/aidl/default/include/effectFactory-impl/EffectFactory.h
@@ -107,6 +107,10 @@
             const EffectConfig::LibraryUuid& configLib,
             const ::aidl::android::media::audio::common::AudioUuid& typeUuidStr,
             const std::optional<::aidl::android::media::audio::common::AudioUuid> proxyUuid);
+
+    ndk::ScopedAStatus getDescriptorWithUuid(
+            const aidl::android::media::audio::common::AudioUuid& uuid, Descriptor* desc);
+
     void loadEffectLibs();
     /* Get effect_dl_interface_s from library handle */
     void getDlSyms(DlEntry& entry);
diff --git a/audio/aidl/default/main.cpp b/audio/aidl/default/main.cpp
index af71aa8..12c0c4b 100644
--- a/audio/aidl/default/main.cpp
+++ b/audio/aidl/default/main.cpp
@@ -64,6 +64,7 @@
     auto modules = {createModule(Module::Type::DEFAULT, "default"),
                     createModule(Module::Type::R_SUBMIX, "r_submix"),
                     createModule(Module::Type::USB, "usb")};
+    (void)modules;
 
     ABinderProcess_joinThreadPool();
     return EXIT_FAILURE;  // should not reach
diff --git a/audio/aidl/default/usb/ModuleUsb.cpp b/audio/aidl/default/usb/ModuleUsb.cpp
index ecdbd5c..28116ae 100644
--- a/audio/aidl/default/usb/ModuleUsb.cpp
+++ b/audio/aidl/default/usb/ModuleUsb.cpp
@@ -30,13 +30,13 @@
 #include "alsa_device_profile.h"
 }
 
-using aidl::android::hardware::audio::common::isUsbInputDeviceType;
 using aidl::android::media::audio::common::AudioChannelLayout;
 using aidl::android::media::audio::common::AudioDeviceAddress;
 using aidl::android::media::audio::common::AudioDeviceDescription;
 using aidl::android::media::audio::common::AudioDeviceType;
 using aidl::android::media::audio::common::AudioFormatDescription;
 using aidl::android::media::audio::common::AudioFormatType;
+using aidl::android::media::audio::common::AudioIoFlags;
 using aidl::android::media::audio::common::AudioPort;
 using aidl::android::media::audio::common::AudioPortConfig;
 using aidl::android::media::audio::common::AudioPortExt;
@@ -117,7 +117,7 @@
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
     }
 
-    const bool isInput = isUsbInputDeviceType(devicePort.device.type.type);
+    const bool isInput = audioPort->flags.getTag() == AudioIoFlags::input;
     alsa_device_profile profile;
     profile_init(&profile, isInput ? PCM_IN : PCM_OUT);
     profile.card = alsaAddress[0];
diff --git a/audio/aidl/default/usb/StreamUsb.cpp b/audio/aidl/default/usb/StreamUsb.cpp
index 5d1d7fe..9ac1cc9 100644
--- a/audio/aidl/default/usb/StreamUsb.cpp
+++ b/audio/aidl/default/usb/StreamUsb.cpp
@@ -106,10 +106,13 @@
 
 ::android::status_t DriverUsb::transfer(void* buffer, size_t frameCount, size_t* actualFrameCount,
                                         int32_t* latencyMs) {
-    if (!mConfig.has_value() || mConnectedDevices.empty()) {
-        LOG(ERROR) << __func__ << ": failed, has config: " << mConfig.has_value()
-                   << ", has connected devices: " << mConnectedDevices.empty();
-        return ::android::NO_INIT;
+    {
+        std::lock_guard guard(mLock);
+        if (!mConfig.has_value() || mConnectedDevices.empty()) {
+            LOG(ERROR) << __func__ << ": failed, has config: " << mConfig.has_value()
+                       << ", has connected devices: " << mConnectedDevices.empty();
+            return ::android::NO_INIT;
+        }
     }
     if (mIsStandby) {
         if (::android::status_t status = exitStandby(); status != ::android::OK) {
diff --git a/audio/aidl/default/usb/UsbAlsaMixerControl.cpp b/audio/aidl/default/usb/UsbAlsaMixerControl.cpp
index b5337d1..6c0c24b 100644
--- a/audio/aidl/default/usb/UsbAlsaMixerControl.cpp
+++ b/audio/aidl/default/usb/UsbAlsaMixerControl.cpp
@@ -99,16 +99,6 @@
     return minValue + std::ceil((maxValue - minValue) * fValue);
 }
 
-float volumeIntegerToFloat(int iValue, int maxValue, int minValue) {
-    if (iValue > maxValue) {
-        return 1.0f;
-    }
-    if (iValue < minValue) {
-        return 0.0f;
-    }
-    return static_cast<float>(iValue - minValue) / (maxValue - minValue);
-}
-
 }  // namespace
 
 ndk::ScopedAStatus AlsaMixer::setMasterMute(bool muted) {
@@ -146,11 +136,14 @@
         return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
     }
     const int numValues = it->second->getNumValues();
+    if (numValues < 0) {
+        LOG(FATAL) << __func__ << ": negative number of values: " << numValues;
+    }
     const int maxValue = it->second->getMaxValue();
     const int minValue = it->second->getMinValue();
     std::vector<int> values;
     size_t i = 0;
-    for (; i < numValues && i < values.size(); ++i) {
+    for (; i < static_cast<size_t>(numValues) && i < values.size(); ++i) {
         values.emplace_back(volumeFloatToInteger(volumes[i], maxValue, minValue));
     }
     if (int err = it->second->setArray(values.data(), values.size()); err != 0) {
diff --git a/audio/aidl/default/virtualizer/VirtualizerSw.cpp b/audio/aidl/default/virtualizer/VirtualizerSw.cpp
index e34464f..0e8435e 100644
--- a/audio/aidl/default/virtualizer/VirtualizerSw.cpp
+++ b/audio/aidl/default/virtualizer/VirtualizerSw.cpp
@@ -16,6 +16,7 @@
 
 #include <algorithm>
 #include <cstddef>
+#include <optional>
 
 #define LOG_TAG "AHAL_VirtualizerSw"
 #include <Utils.h>
@@ -76,8 +77,7 @@
 
 const Descriptor VirtualizerSw::kDescriptor = {
         .common = {.id = {.type = getEffectTypeUuidVirtualizer(),
-                          .uuid = getEffectImplUuidVirtualizerSw(),
-                          .proxy = getEffectImplUuidVirtualizerProxy()},
+                          .uuid = getEffectImplUuidVirtualizerSw()},
                    .flags = {.type = Flags::Type::INSERT,
                              .insert = Flags::Insert::FIRST,
                              .volume = Flags::Volume::CTRL},
diff --git a/audio/aidl/vts/EffectHelper.h b/audio/aidl/vts/EffectHelper.h
index 4e84f6b..685d07d 100644
--- a/audio/aidl/vts/EffectHelper.h
+++ b/audio/aidl/vts/EffectHelper.h
@@ -30,6 +30,7 @@
 #include <android/binder_auto_utils.h>
 #include <fmq/AidlMessageQueue.h>
 #include <gtest/gtest.h>
+#include <system/audio_aidl_utils.h>
 #include <system/audio_effects/aidl_effects_utils.h>
 #include <system/audio_effects/effect_uuid.h>
 
@@ -51,6 +52,7 @@
 using aidl::android::media::audio::common::AudioFormatType;
 using aidl::android::media::audio::common::AudioUuid;
 using aidl::android::media::audio::common::PcmType;
+using ::android::audio::utils::toString;
 using ::android::hardware::EventFlag;
 
 const AudioFormatDescription kDefaultFormatDescription = {
@@ -63,6 +65,12 @@
                                     ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>
         DataMQ;
 
+static inline std::string getPrefix(Descriptor& descriptor) {
+    std::string prefix = "Implementor_" + descriptor.common.implementor + "_name_" +
+                         descriptor.common.name + "_UUID_" + toString(descriptor.common.id.uuid);
+    return prefix;
+}
+
 class EffectHelper {
   public:
     static void create(std::shared_ptr<IFactory> factory, std::shared_ptr<IEffect>& effect,
@@ -71,7 +79,7 @@
         auto& id = desc.common.id;
         ASSERT_STATUS(status, factory->createEffect(id.uuid, &effect));
         if (status == EX_NONE) {
-            ASSERT_NE(effect, nullptr) << id.uuid.toString();
+            ASSERT_NE(effect, nullptr) << toString(id.uuid);
         }
     }
 
diff --git a/audio/aidl/vts/VtsHalAECTargetTest.cpp b/audio/aidl/vts/VtsHalAECTargetTest.cpp
index 8828c41..1a7c3d4 100644
--- a/audio/aidl/vts/VtsHalAECTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAECTargetTest.cpp
@@ -162,10 +162,8 @@
             auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
             std::string echoDelay = std::to_string(std::get<PARAM_ECHO_DELAY>(info.param));
             std::string mobileMode = std::get<PARAM_MOBILE_MODE>(info.param) ? "true" : "false";
-            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
-                               descriptor.common.name + "_UUID_" +
-                               descriptor.common.id.uuid.toString() + "_EchoDelay_" + echoDelay +
-                               "_MobileMode_" + mobileMode;
+            std::string name =
+                    getPrefix(descriptor) + "_EchoDelay_" + echoDelay + "_MobileMode_" + mobileMode;
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
diff --git a/audio/aidl/vts/VtsHalAGC1TargetTest.cpp b/audio/aidl/vts/VtsHalAGC1TargetTest.cpp
index edfcdf6..65c6a8f 100644
--- a/audio/aidl/vts/VtsHalAGC1TargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAGC1TargetTest.cpp
@@ -177,11 +177,9 @@
                     std::to_string(std::get<PARAM_MAX_COMPRESSION_GAIN>(info.param));
             std::string enableLimiter = std::to_string(std::get<PARAM_ENABLE_LIMITER>(info.param));
 
-            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
-                               descriptor.common.name + "_UUID_" +
-                               descriptor.common.id.uuid.toString() + "_target_peak_level_" +
-                               targetPeakLevel + "_max_compression_gain_" + maxCompressionGain +
-                               "_enable_limiter_" + enableLimiter;
+            std::string name = getPrefix(descriptor) + "_target_peak_level_" + targetPeakLevel +
+                               "_max_compression_gain_" + maxCompressionGain + "_enable_limiter_" +
+                               enableLimiter;
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
diff --git a/audio/aidl/vts/VtsHalAGC2TargetTest.cpp b/audio/aidl/vts/VtsHalAGC2TargetTest.cpp
index 8ba8e45..46a569e 100644
--- a/audio/aidl/vts/VtsHalAGC2TargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAGC2TargetTest.cpp
@@ -183,9 +183,7 @@
             std::string margin =
                     std::to_string(static_cast<int>(std::get<PARAM_SATURATION_MARGIN>(info.param)));
 
-            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
-                               descriptor.common.name + "_UUID_" +
-                               descriptor.common.id.uuid.toString() + "_digital_gain_" + gain +
+            std::string name = getPrefix(descriptor) + "_digital_gain_" + gain +
                                "_level_estimator_" + estimator + "_margin_" + margin;
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
diff --git a/audio/aidl/vts/VtsHalAudioCoreConfigTargetTest.cpp b/audio/aidl/vts/VtsHalAudioCoreConfigTargetTest.cpp
index e5e06eb..f82e8e5 100644
--- a/audio/aidl/vts/VtsHalAudioCoreConfigTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioCoreConfigTargetTest.cpp
@@ -20,21 +20,27 @@
 #include <unordered_set>
 #include <vector>
 
+#define LOG_TAG "VtsHalAudioCore.Config"
+
+#include <Utils.h>
 #include <aidl/Gtest.h>
 #include <aidl/Vintf.h>
 #include <aidl/android/hardware/audio/core/IConfig.h>
 #include <aidl/android/media/audio/common/AudioFlag.h>
 #include <aidl/android/media/audio/common/AudioProductStrategyType.h>
-#define LOG_TAG "VtsHalAudioCore.Config"
 #include <android-base/logging.h>
 
 #include "AudioHalBinderServiceUtil.h"
 #include "TestUtils.h"
 
 using namespace android;
+using aidl::android::hardware::audio::common::isDefaultAudioFormat;
 using aidl::android::hardware::audio::core::IConfig;
+using aidl::android::hardware::audio::core::SurroundSoundConfig;
 using aidl::android::media::audio::common::AudioAttributes;
 using aidl::android::media::audio::common::AudioFlag;
+using aidl::android::media::audio::common::AudioFormatDescription;
+using aidl::android::media::audio::common::AudioFormatType;
 using aidl::android::media::audio::common::AudioHalAttributesGroup;
 using aidl::android::media::audio::common::AudioHalCapCriterion;
 using aidl::android::media::audio::common::AudioHalCapCriterionType;
@@ -46,6 +52,7 @@
 using aidl::android::media::audio::common::AudioSource;
 using aidl::android::media::audio::common::AudioStreamType;
 using aidl::android::media::audio::common::AudioUsage;
+using aidl::android::media::audio::common::PcmType;
 
 class AudioCoreConfig : public testing::TestWithParam<std::string> {
   public:
@@ -58,6 +65,7 @@
     void RestartService() {
         ASSERT_NE(mConfig, nullptr);
         mEngineConfig.reset();
+        mSurroundSoundConfig.reset();
         mConfig = IConfig::fromBinder(mBinderUtil.restartService());
         ASSERT_NE(mConfig, nullptr);
     }
@@ -70,6 +78,14 @@
         }
     }
 
+    void SetUpSurroundSoundConfig() {
+        if (mSurroundSoundConfig == nullptr) {
+            auto tempConfig = std::make_unique<SurroundSoundConfig>();
+            ASSERT_IS_OK(mConfig->getSurroundSoundConfig(tempConfig.get()));
+            mSurroundSoundConfig = std::move(tempConfig);
+        }
+    }
+
     static bool IsProductStrategyTypeReservedForSystemUse(const AudioProductStrategyType& pst) {
         switch (pst) {
             case AudioProductStrategyType::SYS_RESERVED_NONE:
@@ -325,9 +341,41 @@
         }
     }
 
+    void ValidateAudioFormatDescription(const AudioFormatDescription& format) {
+        EXPECT_NE(AudioFormatType::SYS_RESERVED_INVALID, format.type);
+        if (format.type == AudioFormatType::PCM) {
+            EXPECT_NE(PcmType::DEFAULT, format.pcm);
+            EXPECT_TRUE(format.encoding.empty()) << format.encoding;
+        } else {
+            EXPECT_FALSE(format.encoding.empty());
+        }
+    }
+
+    /**
+     * Verify that the surround sound configuration is not empty.
+     * Verify each of the formatFamilies has a non-empty primaryFormat.
+     * Verify that each format only appears once.
+     */
+    void ValidateSurroundSoundConfig() {
+        EXPECT_FALSE(mSurroundSoundConfig->formatFamilies.empty());
+        std::set<AudioFormatDescription> formatSet;
+        for (const SurroundSoundConfig::SurroundFormatFamily& family :
+             mSurroundSoundConfig->formatFamilies) {
+            EXPECT_NO_FATAL_FAILURE(ValidateAudioFormatDescription(family.primaryFormat));
+            EXPECT_FALSE(isDefaultAudioFormat(family.primaryFormat));
+            EXPECT_TRUE(formatSet.insert(family.primaryFormat).second);
+            for (const AudioFormatDescription& subformat : family.subFormats) {
+                EXPECT_NO_FATAL_FAILURE(ValidateAudioFormatDescription(subformat));
+                EXPECT_FALSE(isDefaultAudioFormat(subformat));
+                EXPECT_TRUE(formatSet.insert(subformat).second);
+            }
+        }
+    }
+
   private:
     std::shared_ptr<IConfig> mConfig;
     std::unique_ptr<AudioHalEngineConfig> mEngineConfig;
+    std::unique_ptr<SurroundSoundConfig> mSurroundSoundConfig;
     AudioHalBinderServiceUtil mBinderUtil;
 };
 
@@ -344,6 +392,11 @@
     EXPECT_NO_FATAL_FAILURE(ValidateAudioHalEngineConfig());
 }
 
+TEST_P(AudioCoreConfig, GetSurroundSoundConfigIsValid) {
+    ASSERT_NO_FATAL_FAILURE(SetUpSurroundSoundConfig());
+    EXPECT_NO_FATAL_FAILURE(ValidateSurroundSoundConfig());
+}
+
 INSTANTIATE_TEST_SUITE_P(AudioCoreConfigTest, AudioCoreConfig,
                          testing::ValuesIn(android::getAidlHalInstanceNames(IConfig::descriptor)),
                          android::PrintInstanceNameToString);
diff --git a/audio/aidl/vts/VtsHalAudioEffectFactoryTargetTest.cpp b/audio/aidl/vts/VtsHalAudioEffectFactoryTargetTest.cpp
index 7b9477d..8084a59 100644
--- a/audio/aidl/vts/VtsHalAudioEffectFactoryTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioEffectFactoryTargetTest.cpp
@@ -36,6 +36,11 @@
 #include "EffectFactoryHelper.h"
 #include "TestUtils.h"
 
+#include <system/audio_aidl_utils.h>
+
+using namespace android;
+using ::android::audio::utils::toString;
+
 using namespace android;
 
 using aidl::android::hardware::audio::effect::Descriptor;
@@ -93,7 +98,7 @@
             std::shared_ptr<IEffect> effect;
             EXPECT_STATUS(expectStatus, mEffectFactory->createEffect(uuid, &effect));
             if (expectStatus == EX_NONE) {
-                EXPECT_NE(effect, nullptr) << " null effect with uuid: " << uuid.toString();
+                EXPECT_NE(effect, nullptr) << " null effect with uuid: " << toString(uuid);
                 effects.push_back(std::move(effect));
             }
         }
@@ -148,7 +153,7 @@
     }
     std::string msg = " missing type UUID:\n";
     for (const auto& uuid : typeUuidSet) {
-        msg += (uuid.toString() + "\n");
+        msg += (toString(uuid) + "\n");
     }
     SCOPED_TRACE(msg);
     EXPECT_EQ(0UL, typeUuidSet.size());
@@ -267,6 +272,7 @@
 TEST_P(EffectFactoryTest, QueryProcess) {
     std::vector<Processing> processing;
     EXPECT_IS_OK(mEffectFactory->queryProcessing(std::nullopt, &processing));
+    std::set<Processing> processingSet(processing.begin(), processing.end());
 
     Processing::Type streamType =
             Processing::Type::make<Processing::Type::streamType>(AudioStreamType::SYSTEM);
@@ -279,7 +285,14 @@
     EXPECT_IS_OK(mEffectFactory->queryProcessing(source, &processingFilteredBySource));
 
     EXPECT_TRUE(processing.size() >= processingFilteredByStream.size());
+    EXPECT_TRUE(std::all_of(
+            processingFilteredByStream.begin(), processingFilteredByStream.end(),
+            [&](const auto& proc) { return processingSet.find(proc) != processingSet.end(); }));
+
     EXPECT_TRUE(processing.size() >= processingFilteredBySource.size());
+    EXPECT_TRUE(std::all_of(
+            processingFilteredBySource.begin(), processingFilteredBySource.end(),
+            [&](const auto& proc) { return processingSet.find(proc) != processingSet.end(); }));
 }
 
 INSTANTIATE_TEST_SUITE_P(EffectFactoryTest, EffectFactoryTest,
diff --git a/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp b/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
index 436f2a3..4ad9b2d 100644
--- a/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
@@ -848,10 +848,7 @@
                 EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor))),
         [](const testing::TestParamInfo<AudioEffectTest::ParamType>& info) {
             auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
-            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
-                               descriptor.common.name + "_TYPE_" +
-                               descriptor.common.id.type.toString() + "_UUID_" +
-                               descriptor.common.id.uuid.toString();
+            std::string name = getPrefix(descriptor);
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
diff --git a/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp b/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp
index 9cfdc50..afddb84 100644
--- a/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp
@@ -145,9 +145,7 @@
         [](const testing::TestParamInfo<BassBoostParamTest::ParamType>& info) {
             auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
             std::string strength = std::to_string(std::get<PARAM_STRENGTH>(info.param));
-            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
-                               descriptor.common.name + "_UUID_" +
-                               descriptor.common.id.uuid.toString() + "_strength_" + strength;
+            std::string name = getPrefix(descriptor) + "_strength_" + strength;
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
diff --git a/audio/aidl/vts/VtsHalDownmixTargetTest.cpp b/audio/aidl/vts/VtsHalDownmixTargetTest.cpp
index 5aeebde..7a2f31b 100644
--- a/audio/aidl/vts/VtsHalDownmixTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalDownmixTargetTest.cpp
@@ -126,9 +126,7 @@
         [](const testing::TestParamInfo<DownmixParamTest::ParamType>& info) {
             auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
             std::string type = std::to_string(static_cast<int>(std::get<PARAM_TYPE>(info.param)));
-            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
-                               descriptor.common.name + "_UUID_" +
-                               descriptor.common.id.uuid.toString() + "_type" + type;
+            std::string name = getPrefix(descriptor) + "_type" + type;
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
diff --git a/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp b/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp
index 033e3b5..5509c76 100644
--- a/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp
+++ b/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp
@@ -513,9 +513,7 @@
             auto descriptor = std::get<ENGINE_TEST_INSTANCE_NAME>(info.param).second;
             DynamicsProcessing::EngineArchitecture cfg;
             fillEngineArchConfig(cfg, info.param);
-            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
-                               descriptor.common.name + "_UUID_" +
-                               descriptor.common.id.uuid.toString() + "_Cfg_" + cfg.toString();
+            std::string name = getPrefix(descriptor) + "_Cfg_" + cfg.toString();
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
diff --git a/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp b/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp
index 05c2c5b..f2ef185 100644
--- a/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp
@@ -209,9 +209,7 @@
             auto descriptor = std::get<0>(info.param).second;
             std::string roomLevel = std::to_string(std::get<1>(info.param));
 
-            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
-                               descriptor.common.name + "_UUID_" +
-                               descriptor.common.id.uuid.toString() + "_roomLevel" + roomLevel;
+            std::string name = getPrefix(descriptor) + "_roomLevel" + roomLevel;
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
diff --git a/audio/aidl/vts/VtsHalEqualizerTargetTest.cpp b/audio/aidl/vts/VtsHalEqualizerTargetTest.cpp
index 716a2c6..37e7c0a 100644
--- a/audio/aidl/vts/VtsHalEqualizerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalEqualizerTargetTest.cpp
@@ -209,9 +209,7 @@
             auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
             std::string bandLevel =
                     ::android::internal::ToString(std::get<PARAM_BAND_LEVEL>(info.param));
-            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
-                               descriptor.common.name + "_UUID_" +
-                               descriptor.common.id.uuid.toString() + "_preset_" +
+            std::string name = getPrefix(descriptor) + "_preset_" +
                                std::to_string(std::get<PARAM_PRESET>(info.param)) + "_bandLevel_" +
                                bandLevel;
             std::replace_if(
diff --git a/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp b/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp
index 7c79d1b..54caed9 100644
--- a/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp
@@ -195,12 +195,10 @@
                     std::to_string(std::get<PARAM_VIBRATION_INFORMATION_Q_FACTOR>(info.param));
             std::string maxAmplitude =
                     std::to_string(std::get<PARAM_VIBRATION_INFORMATION_MAX_AMPLITUDE>(info.param));
-            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
-                               descriptor.common.name + "_UUID_" +
-                               descriptor.common.id.uuid.toString() + "_hapticScaleId" +
-                               hapticScaleID + "_hapticScaleVibScale" + hapticScaleVibScale +
-                               "_resonantFrequency" + resonantFrequency + "_qFactor" + qFactor +
-                               "_maxAmplitude" + maxAmplitude;
+            std::string name = getPrefix(descriptor) + "_hapticScaleId" + hapticScaleID +
+                               "_hapticScaleVibScale" + hapticScaleVibScale + "_resonantFrequency" +
+                               resonantFrequency + "_qFactor" + qFactor + "_maxAmplitude" +
+                               maxAmplitude;
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
diff --git a/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp b/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
index 96b048e..cbb80a9 100644
--- a/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
@@ -131,9 +131,7 @@
         [](const testing::TestParamInfo<LoudnessEnhancerParamTest::ParamType>& info) {
             auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
             std::string gainMb = std::to_string(std::get<PARAM_GAIN_MB>(info.param));
-            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
-                               descriptor.common.name + "_UUID_" +
-                               descriptor.common.id.uuid.toString() + "_gainMb_" + gainMb;
+            std::string name = getPrefix(descriptor) + "_gainMb_" + gainMb;
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
diff --git a/audio/aidl/vts/VtsHalNSTargetTest.cpp b/audio/aidl/vts/VtsHalNSTargetTest.cpp
index 5525c80..bbb11fc 100644
--- a/audio/aidl/vts/VtsHalNSTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalNSTargetTest.cpp
@@ -155,10 +155,7 @@
                     std::get<PARAM_LEVEL>(info.param));
             std::string type = aidl::android::hardware::audio::effect::toString(
                     std::get<PARAM_TYPE>(info.param));
-            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
-                               descriptor.common.name + "_UUID_" +
-                               descriptor.common.id.uuid.toString() + "_level_" + level + "_type_" +
-                               type;
+            std::string name = getPrefix(descriptor) + "_level_" + level + "_type_" + type;
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
diff --git a/audio/aidl/vts/VtsHalPresetReverbTargetTest.cpp b/audio/aidl/vts/VtsHalPresetReverbTargetTest.cpp
index 8fb4ebf..3056c6c 100644
--- a/audio/aidl/vts/VtsHalPresetReverbTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalPresetReverbTargetTest.cpp
@@ -137,9 +137,7 @@
             auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
             std::string preset =
                     std::to_string(static_cast<int>(std::get<PARAM_PRESETS>(info.param)));
-            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
-                               descriptor.common.name + "_UUID_" +
-                               descriptor.common.id.uuid.toString() + "_preset" + preset;
+            std::string name = getPrefix(descriptor) + "_preset" + preset;
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
diff --git a/audio/aidl/vts/VtsHalVirtualizerTargetTest.cpp b/audio/aidl/vts/VtsHalVirtualizerTargetTest.cpp
index 6b1da63..07a9fa4 100644
--- a/audio/aidl/vts/VtsHalVirtualizerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalVirtualizerTargetTest.cpp
@@ -141,9 +141,7 @@
         [](const testing::TestParamInfo<VirtualizerParamTest::ParamType>& info) {
             auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
             std::string strength = std::to_string(std::get<PARAM_STRENGTH>(info.param));
-            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
-                               descriptor.common.name + "_UUID_" +
-                               descriptor.common.id.uuid.toString() + "_strength" + strength;
+            std::string name = getPrefix(descriptor) + "_strength" + strength;
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
diff --git a/audio/aidl/vts/VtsHalVisualizerTargetTest.cpp b/audio/aidl/vts/VtsHalVisualizerTargetTest.cpp
index f41ba30..903ba69 100644
--- a/audio/aidl/vts/VtsHalVisualizerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalVisualizerTargetTest.cpp
@@ -195,9 +195,7 @@
                     std::get<PARAM_MEASUREMENT_MODE>(info.param));
             std::string latency = std::to_string(std::get<PARAM_LATENCY>(info.param));
 
-            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
-                               descriptor.common.name + "_UUID_" +
-                               descriptor.common.id.uuid.toString() + "_captureSize" + captureSize +
+            std::string name = getPrefix(descriptor) + "_captureSize" + captureSize +
                                "_scalingMode" + scalingMode + "_measurementMode" + measurementMode +
                                "_latency" + latency;
             std::replace_if(
diff --git a/audio/aidl/vts/VtsHalVolumeTargetTest.cpp b/audio/aidl/vts/VtsHalVolumeTargetTest.cpp
index 90b7f37..0b5b9fc 100644
--- a/audio/aidl/vts/VtsHalVolumeTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalVolumeTargetTest.cpp
@@ -149,10 +149,7 @@
             auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
             std::string level = std::to_string(std::get<PARAM_LEVEL>(info.param));
             std::string mute = std::to_string(std::get<PARAM_MUTE>(info.param));
-            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
-                               descriptor.common.name + "_UUID_" +
-                               descriptor.common.id.uuid.toString() + "_level" + level + "_mute" +
-                               mute;
+            std::string name = getPrefix(descriptor) + "_level" + level + "_mute" + mute;
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
diff --git a/audio/common/all-versions/test/utility/Android.bp b/audio/common/all-versions/test/utility/Android.bp
index 757f8a8..c6a3963 100644
--- a/audio/common/all-versions/test/utility/Android.bp
+++ b/audio/common/all-versions/test/utility/Android.bp
@@ -62,6 +62,5 @@
         "libxml2",
         "liblog",
     ],
-    static_libs: ["libgtest"],
     test_suites: ["general-tests"],
 }
diff --git a/audio/core/all-versions/vts/functional/6.0/Generators.cpp b/audio/core/all-versions/vts/functional/6.0/Generators.cpp
index dafd326..705932d 100644
--- a/audio/core/all-versions/vts/functional/6.0/Generators.cpp
+++ b/audio/core/all-versions/vts/functional/6.0/Generators.cpp
@@ -16,6 +16,8 @@
 
 #include <android-base/macros.h>
 
+#include <IOProfile.h>
+
 #include "6.0/Generators.h"
 #include "ConfigHelper.h"
 #include "PolicyConfig.h"
diff --git a/audio/core/all-versions/vts/functional/7.0/PolicyConfig.h b/audio/core/all-versions/vts/functional/7.0/PolicyConfig.h
index c1d5669..f6271ff 100644
--- a/audio/core/all-versions/vts/functional/7.0/PolicyConfig.h
+++ b/audio/core/all-versions/vts/functional/7.0/PolicyConfig.h
@@ -41,15 +41,10 @@
 
 class PolicyConfig {
   public:
-    explicit PolicyConfig(const std::string& configFileName)
-        : mConfigFileName{configFileName},
-          mFilePath{findExistingConfigurationFile(mConfigFileName)},
-          mConfig{xsd::read(mFilePath.c_str())} {
-        init();
-    }
     PolicyConfig(const std::string& configPath, const std::string& configFileName)
         : mConfigFileName{configFileName},
-          mFilePath{configPath + "/" + mConfigFileName},
+          mFilePath{configPath.empty() ? findExistingConfigurationFile(mConfigFileName)
+                                       : configPath + "/" + mConfigFileName},
           mConfig{xsd::read(mFilePath.c_str())} {
         init();
     }
diff --git a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
index 478482d..fabe2d2 100644
--- a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
+++ b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
@@ -195,7 +195,7 @@
 // Cached policy config after parsing for faster test startup
 const PolicyConfig& getCachedPolicyConfig() {
     static std::unique_ptr<PolicyConfig> policyConfig = [] {
-        auto config = std::make_unique<PolicyConfig>(kConfigFileName);
+        auto config = std::make_unique<PolicyConfig>("", kConfigFileName);
         return config;
     }();
     return *policyConfig;
diff --git a/audio/core/all-versions/vts/functional/PolicyConfig.h b/audio/core/all-versions/vts/functional/PolicyConfig.h
index 171d03f..b08e808 100644
--- a/audio/core/all-versions/vts/functional/PolicyConfig.h
+++ b/audio/core/all-versions/vts/functional/PolicyConfig.h
@@ -19,9 +19,9 @@
 #include <set>
 #include <string>
 
+#include <AudioPolicyConfig.h>
 #include <DeviceDescriptor.h>
 #include <HwModule.h>
-#include <Serializer.h>
 #include <gtest/gtest.h>
 #include <system/audio_config.h>
 
@@ -30,47 +30,35 @@
 using ::android::sp;
 using ::android::status_t;
 
-struct PolicyConfigData {
-    android::HwModuleCollection hwModules;
-    android::DeviceVector availableOutputDevices;
-    android::DeviceVector availableInputDevices;
-    sp<android::DeviceDescriptor> defaultOutputDevice;
-};
-
-class PolicyConfig : private PolicyConfigData, public android::AudioPolicyConfig {
+class PolicyConfig {
   public:
-    explicit PolicyConfig(const std::string& configFileName)
-        : android::AudioPolicyConfig(hwModules, availableOutputDevices, availableInputDevices,
-                                     defaultOutputDevice),
-          mConfigFileName{configFileName} {
-        for (const auto& location : android::audio_get_configuration_paths()) {
-            std::string path = location + '/' + mConfigFileName;
-            if (access(path.c_str(), F_OK) == 0) {
-                mFilePath = path;
-                break;
-            }
-        }
-        init();
-    }
     PolicyConfig(const std::string& configPath, const std::string& configFileName)
-        : android::AudioPolicyConfig(hwModules, availableOutputDevices, availableInputDevices,
-                                     defaultOutputDevice),
-          mConfigFileName{configFileName},
-          mFilePath{configPath + "/" + mConfigFileName} {
-        init();
+        : mInitialFilePath(configPath.empty() ? configFileName
+                                              : configPath + "/" + configFileName) {
+        auto result = android::AudioPolicyConfig::loadFromCustomXmlConfigForVtsTests(
+                configPath, configFileName);
+        if (result.ok()) {
+            mStatus = ::android::OK;
+            mConfig = result.value();
+            init();
+        } else {
+            mStatus = result.error();
+        }
     }
     status_t getStatus() const { return mStatus; }
     std::string getError() const {
-        if (mFilePath.empty()) {
-            return std::string{"Could not find "} + mConfigFileName +
+        if (mConfig == nullptr) {
+            return std::string{"Could not find "} + mInitialFilePath +
                    " file in: " + testing::PrintToString(android::audio_get_configuration_paths());
         } else {
-            return "Invalid config file: " + mFilePath;
+            return "Invalid config file: " + mConfig->getSource();
         }
     }
-    const std::string& getFilePath() const { return mFilePath; }
+    const std::string& getFilePath() const {
+        return mConfig != nullptr ? mConfig->getSource() : mInitialFilePath;
+    }
     sp<const android::HwModule> getModuleFromName(const std::string& name) const {
-        return getHwModules().getModuleFromName(name.c_str());
+        return mConfig->getHwModules().getModuleFromName(name.c_str());
     }
     sp<const android::HwModule> getPrimaryModule() const { return mPrimaryModule; }
     const std::set<std::string>& getModulesWithDevicesNames() const {
@@ -86,6 +74,8 @@
         return findAttachedDevice(getAttachedDevices(moduleName),
                                   getSourceDevicesForMixPort(moduleName, mixPortName));
     }
+    const android::DeviceVector& getInputDevices() const { return mConfig->getInputDevices(); }
+    const android::DeviceVector& getOutputDevices() const { return mConfig->getOutputDevices(); }
     bool haveInputProfilesInModule(const std::string& name) const {
         auto module = getModuleFromName(name);
         return module && !module->getInputProfiles().empty();
@@ -93,29 +83,24 @@
 
   private:
     void init() {
-        mStatus = android::deserializeAudioPolicyFileForVts(mFilePath.c_str(), this);
-        if (mStatus == android::OK) {
-            mPrimaryModule = getModuleFromName(DeviceManager::kPrimaryDevice);
-            // Available devices are not 'attached' to modules at this moment.
-            // Need to go over available devices and find their module.
-            for (const auto& device : availableOutputDevices) {
-                for (const auto& module : hwModules) {
-                    if (module->getDeclaredDevices().indexOf(device) >= 0) {
-                        mModulesWithDevicesNames.insert(module->getName());
-                        mAttachedDevicesPerModule[module->getName()].push_back(
-                                device->getTagName());
-                        break;
-                    }
+        mPrimaryModule = getModuleFromName(DeviceManager::kPrimaryDevice);
+        // Available devices are not 'attached' to modules at this moment.
+        // Need to go over available devices and find their module.
+        for (const auto& device : mConfig->getOutputDevices()) {
+            for (const auto& module : mConfig->getHwModules()) {
+                if (module->getDeclaredDevices().indexOf(device) >= 0) {
+                    mModulesWithDevicesNames.insert(module->getName());
+                    mAttachedDevicesPerModule[module->getName()].push_back(device->getTagName());
+                    break;
                 }
             }
-            for (const auto& device : availableInputDevices) {
-                for (const auto& module : hwModules) {
-                    if (module->getDeclaredDevices().indexOf(device) >= 0) {
-                        mModulesWithDevicesNames.insert(module->getName());
-                        mAttachedDevicesPerModule[module->getName()].push_back(
-                                device->getTagName());
-                        break;
-                    }
+        }
+        for (const auto& device : mConfig->getInputDevices()) {
+            for (const auto& module : mConfig->getHwModules()) {
+                if (module->getDeclaredDevices().indexOf(device) >= 0) {
+                    mModulesWithDevicesNames.insert(module->getName());
+                    mAttachedDevicesPerModule[module->getName()].push_back(device->getTagName());
+                    break;
                 }
             }
         }
@@ -166,10 +151,10 @@
         return result;
     }
 
-    const std::string mConfigFileName;
+    const std::string mInitialFilePath;
     status_t mStatus = android::NO_INIT;
-    std::string mFilePath;
-    sp<const android::HwModule> mPrimaryModule = nullptr;
+    sp<android::AudioPolicyConfig> mConfig;
+    sp<const android::HwModule> mPrimaryModule;
     std::set<std::string> mModulesWithDevicesNames;
     std::map<std::string, std::vector<std::string>> mAttachedDevicesPerModule;
 };
diff --git a/audio/policy/1.0/xml/pfw_schemas/Android.bp b/audio/policy/1.0/xml/pfw_schemas/Android.bp
index 5d669c2..225c065 100644
--- a/audio/policy/1.0/xml/pfw_schemas/Android.bp
+++ b/audio/policy/1.0/xml/pfw_schemas/Android.bp
@@ -11,6 +11,7 @@
     name: "audio_policy_engine_configurable_configuration_V1_0",
     srcs: ["AllSchemas.xsd"],
     package_name: "audio.policy.configurable.V1_0",
+    root_elements: ["ParameterFrameworkConfiguration"],
 }
 
 // Unfortunately, all rules only have a single output, thus
diff --git a/audio/policy/1.0/xml/pfw_schemas/api/current.txt b/audio/policy/1.0/xml/pfw_schemas/api/current.txt
index c2fb6fc..2b83e60 100644
--- a/audio/policy/1.0/xml/pfw_schemas/api/current.txt
+++ b/audio/policy/1.0/xml/pfw_schemas/api/current.txt
@@ -470,23 +470,7 @@
 
   public class XmlParser {
     ctor public XmlParser();
-    method public static audio.policy.configurable.V1_0.BitParameterBlock readBitParameterBlock(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
-    method public static audio.policy.configurable.V1_0.BooleanParameter readBooleanParameter(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
-    method public static audio.policy.configurable.V1_0.ComponentTypeSetType readComponentTypeSetType(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
-    method public static audio.policy.configurable.V1_0.ComponentTypeSetType readComponentTypeSetType(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
-    method public static audio.policy.configurable.V1_0.ConfigurableDomainType readConfigurableDomainType(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
-    method public static audio.policy.configurable.V1_0.ConfigurableDomains readConfigurableDomains(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
-    method public static audio.policy.configurable.V1_0.EnumParameterType readEnumParameterType(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
-    method public static audio.policy.configurable.V1_0.FixedPointParameterType readFixedPointParameterType(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
-    method public static audio.policy.configurable.V1_0.FloatingPointParameterType readFloatingPointParameterType(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
-    method public static audio.policy.configurable.V1_0.IntegerParameterType readIntegerParameterType(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
-    method public static audio.policy.configurable.V1_0.LinearAdaptationType readLinearAdaptationType(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
-    method public static audio.policy.configurable.V1_0.LogarithmicAdaptation readLogarithmicAdaptation(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
     method public static audio.policy.configurable.V1_0.ParameterFrameworkConfiguration readParameterFrameworkConfiguration(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
-    method public static audio.policy.configurable.V1_0.StringParameter readStringParameter(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
-    method public static audio.policy.configurable.V1_0.SubsystemPlugins readSubsystemPlugins(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
-    method public static audio.policy.configurable.V1_0.SubsystemType readSubsystemType(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
-    method public static audio.policy.configurable.V1_0.SystemClass readSystemClass(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
     method public static String readText(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
     method public static void skip(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
   }
diff --git a/automotive/evs/1.0/vts/functional/FrameHandler.cpp b/automotive/evs/1.0/vts/functional/FrameHandler.cpp
index 6a01a44..4233430 100644
--- a/automotive/evs/1.0/vts/functional/FrameHandler.cpp
+++ b/automotive/evs/1.0/vts/functional/FrameHandler.cpp
@@ -133,6 +133,9 @@
     // Local flag we use to keep track of when the stream is stopping
     bool timeToStop = false;
 
+    // Another local flag telling whether or not current frame is displayed.
+    bool frameDisplayed = false;
+
     if (bufferArg.memHandle.getNativeHandle() == nullptr) {
         // Signal that the last frame has been received and the stream is stopped
         timeToStop = true;
@@ -172,9 +175,7 @@
                 } else {
                     // Everything looks good!
                     // Keep track so tests or watch dogs can monitor progress
-                    mLock.lock();
-                    mFramesDisplayed++;
-                    mLock.unlock();
+                    frameDisplayed = true;
                 }
             }
         }
@@ -197,12 +198,15 @@
     }
 
 
-    // Update our received frame count and notify anybody who cares that things have changed
+    // Update frame counters and notify anybody who cares that things have changed.
     mLock.lock();
     if (timeToStop) {
         mRunning = false;
     } else {
         mFramesReceived++;
+        if (frameDisplayed) {
+            mFramesDisplayed++;
+        }
     }
     mLock.unlock();
     mSignal.notify_all();
diff --git a/biometrics/face/aidl/default/Android.bp b/biometrics/face/aidl/default/Android.bp
index 7f66eca..8aa06f8 100644
--- a/biometrics/face/aidl/default/Android.bp
+++ b/biometrics/face/aidl/default/Android.bp
@@ -7,11 +7,21 @@
     default_applicable_licenses: ["hardware_interfaces_license"],
 }
 
+filegroup {
+    name: "face-default.rc",
+    srcs: ["face-default.rc"],
+}
+
+filegroup {
+    name: "face-default.xml",
+    srcs: ["face-default.xml"],
+}
+
 cc_binary {
     name: "android.hardware.biometrics.face-service.example",
     relative_install_path: "hw",
-    init_rc: ["face-default.rc"],
-    vintf_fragments: ["face-default.xml"],
+    init_rc: [":face-default.rc"],
+    vintf_fragments: [":face-default.xml"],
     vendor: true,
     shared_libs: [
         "libbase",
diff --git a/biometrics/face/aidl/default/apex/Android.bp b/biometrics/face/aidl/default/apex/Android.bp
new file mode 100644
index 0000000..2f39a08
--- /dev/null
+++ b/biometrics/face/aidl/default/apex/Android.bp
@@ -0,0 +1,79 @@
+// Copyright (C) 2023 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 {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+apex_key {
+    name: "com.android.hardware.biometrics.face.key",
+    public_key: "com.android.hardware.biometrics.face.avbpubkey",
+    private_key: "com.android.hardware.biometrics.face.pem",
+}
+
+android_app_certificate {
+    name: "com.android.hardware.biometrics.face.certificate",
+    certificate: "com.android.hardware.biometrics.face",
+}
+
+apex {
+    name: "com.android.hardware.biometrics.face",
+    manifest: "manifest.json",
+    file_contexts: "file_contexts",
+    key: "com.android.hardware.biometrics.face.key",
+    certificate: ":com.android.hardware.biometrics.face.certificate",
+    updatable: false,
+
+    vendor: true,
+    use_vndk_as_stable: true,
+
+    binaries: [
+        // hal
+        "android.hardware.biometrics.face-service.example",
+    ],
+    prebuilts: [
+        // init_rc
+        "face-default-apex.rc",
+        // vintf_fragment
+        "face-default-apex.xml",
+        // permission
+        "android.hardware.biometrics.face.prebuilt.xml",
+    ],
+
+    overrides: [
+        "android.hardware.biometrics.face-service.example",
+    ],
+}
+
+prebuilt_etc {
+    name: "face-default-apex.rc",
+    src: ":gen-face-default-apex.rc",
+    vendor: true,
+    installable: false,
+}
+
+genrule {
+    name: "gen-face-default-apex.rc",
+    srcs: [":face-default.rc"],
+    out: ["face-default-apex.rc"],
+    cmd: "sed -e 's@/vendor/bin/@/apex/com.android.hardware.biometrics.face/bin/@' $(in) > $(out)",
+}
+
+prebuilt_etc {
+    name: "face-default-apex.xml",
+    src: ":face-default.xml",
+    sub_dir: "vintf",
+    vendor: true,
+    installable: false,
+}
diff --git a/biometrics/face/aidl/default/apex/com.android.hardware.biometrics.face.avbpubkey b/biometrics/face/aidl/default/apex/com.android.hardware.biometrics.face.avbpubkey
new file mode 100644
index 0000000..9f358ff
--- /dev/null
+++ b/biometrics/face/aidl/default/apex/com.android.hardware.biometrics.face.avbpubkey
Binary files differ
diff --git a/biometrics/face/aidl/default/apex/com.android.hardware.biometrics.face.pem b/biometrics/face/aidl/default/apex/com.android.hardware.biometrics.face.pem
new file mode 100644
index 0000000..ad8f57d
--- /dev/null
+++ b/biometrics/face/aidl/default/apex/com.android.hardware.biometrics.face.pem
@@ -0,0 +1,52 @@
+-----BEGIN PRIVATE KEY-----
+MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQCoZ28KVXxB9kkX
+zPhi8pVSmiMU0xchU4PkoOvFzmr9t5b7rA1zmzOLjkNWMrxt1XCUEfOgT3N50z5T
+484dpEZBrwIH31NqSOr/T8mG5frZAkNg0WqfgV+AG81mCuA+nG4a08fmDL4nEzVg
+irQvWpXzRCNIn+LEx+gG4I2KG8EGWDiFnzXwSFJG4n60rfLQNHgsejv/06BmPCnS
+gp06LhqJTO2oJKCJVQxfO0TPNUd9FSVSXdWuHcHE2gwoHM/7C/10Bdx8XXCMbAQR
+a4d3moH5oRuhh1841PtIQ0ozw/vHapCTmdMbjmgbwpXZ49DfvJl2cnz5c5G/CUO1
+9CkLDdxffsHh48jLUzH1nRgcWW2CAnSIs8nGjScyOKB+gn831ke8agJGbVHs1Cp/
+ONbMZeQIhEL0kderI1vVoufeBf38/I93rpz6PXp5NiTwOnVdEik595/W7oldr/rM
+taKvWwfnjml+Z1uzJWWDKPnS+onxBVcoBGFhiewIejPz3UjncMiHW5QAx/BzfGgh
+UmFO0vsh8qrEfAqT4AqL4uCuyVm0JmugdWKoeQISh5i4+HMmvPaudd+8yF0plr10
++pyNGkLZm4NBJxOD7V0AMjfTIpKRbmV8xnCAnWQ+xx/qWxHAZ0wfbZXXF0m6L6po
+dVwJJI7EnuQbAkbXnzMtCTQToZTSVwIDAQABAoICAAGjGJNY15kYKO3xzXWMyfXT
+gl7L9Im1TNVwP3Dpu+S7U0NSd1w12Iju35znzlwhx7/j8skOrKubaZvM9ztJ79Yb
+1CDs3PWhP6OVJeGvvHU9zkp59RexQ5Ma8hXskIroE2WJ97bQgRkfi/r9x8wKc39T
+aYv/SrTC0SPr+YRFSjMvfV35kvLC759slgwkmsH6ZWatSeyhPooJfX1kTRBi08A2
+i4lOBD+Bhtn2jG/+1eYtFyYXVaHx/E9XfU6QhSPgIhBULdujPucmj6pc4yRYnKxA
+32QxGc35u0QHEqJ9/iWAoporIMAmU/Qp7phl9g+OvxrFkloMc3cp3GSMh8k2bJUY
+nRvk0IPG1bF7jwezHbQGTwTlguJlWPl3+v+qeKJQI4pov3Cz6aNrBmBfEbjwcJrf
+RvPNCQ2X1GciZcGoJxcHRgFNKarzb+m92qNRftr6YDBZM8PlvJgGhnTRkOuFmIZB
+WPRergEwaClp1DbQsXwKlWpGfSMLznj57oKT3MJ31R4pusfMDBS39p9jUFH7uO+p
+e/Wdy+RaKei4AYBZIc+ks8LJzeIG+YWD9kN0lPVvzoza6nJYGGNVe/bxErjpESsR
+fZDs5EMNPGsCQ56Tgt+vtHEGF3x7ufGMF1XqisCMlaxH03aT2N3Wi5um8jO2pfFC
+4NEBq4ixvlyefb0TER+5AoIBAQC6nSDDzeeseLOJ8QSb1kHHkvQOGb8kdYY/KJ51
++uiwoEWOYAxKubqumo2rYaqcM0lbZKWb/9cgVK4LAzdqY4z3BINA7YRzXSUXdb8T
+rbqtg33Yj7f1KBiBqns2FMktfIZ+6JUDALb+CD7rHGpi62RDd8JaKL8wugqMBmwM
+YHBfzECVSjDosjGpbILbDJPTfiEQLyPEoJxJ48Z3Xg6l+0BSZrrH9FqGVgsvEQ7f
+zhZ6rpJIefb1cFjwIRFORS4tMqS1keu+dugyUBs83AOp5kaq6O31n5hDAOyZVFsw
+HSBu8pbWAceWJrF7R1Am23063hIztjPbU9yeN2mvhVQSgO4PAoIBAQDnBQHt3prI
+AajCYbHmk0v1WT2kDD5yEX/fZzifTU5k/+0Jvixpa0KOR2qaUXyx4ocIT6F1hR89
+VXGby2UG6SlvuwXMzwmoVf5sueQ6wshu3fCaS8BYNpJnOAfgLTnUpKIWITDm/2Hj
+4NCFYL77EfBXXhFH7lLPhiPcTWQlPDuFCXU/BJuVhJbpd+GtF1+loiNQArg9nmKb
+9Ac7ccR9UBO/XSQN1th4+yaxyGQKaiYsBqsy8SPp2ynTdGXT72LePqSUrkNsjgE7
+PkzgX0pBZw8upBXk+8ByfIaaQONRbCuMQEXj6B66szaWeR2hDfaoDOk3/w6JN93r
+yPKfk4TFNB85AoIBAGoiHVVfUOjViP7l9cIPvD+eQ3GVkRFSSfS3zE+7UQXLUWPl
+GniRYywUuIgFNvw5avowpsOvYRGBN68JuEWosq52gZO2wkK+ce8Cx5aQkwBGLZey
+PWSP1khAxmx+q+BT10ZsTvtzN6AI3ofnFFaIG/EHNqECVaKH3KHAsUjkvGSvjPeb
+R2/AkOAT1+RvJc/+Bx3mQYh99AVOJz0SYHBkEjQLOyWnwqhuXVP6dqQw2LYTfRz9
+SMhUijCgDfCfBeEs0WJ2yEX96Jdc2fDmDKtfTUe8zEGK8BUDfIzD3kzh8+VF0SWL
+w5CRFxXO/DXtVS7ayC1i7eFKs8nEKDZsNOGFNF8CggEAKXRMlFKNk7Y4gijls2pb
+Bvusg/NugSmCuKPdFTjaCGWkM0tczM3ic4V9K5PTvFfZwzQG1P++S1M5v6sPxd2x
+AcudjtLX+Mz1iq0QtzqcnMhWlFljenDQdJUpVKDI789bBn2OOOU6u5lr0YM6wfLG
+HedTUoUBdxuq860vez8DryuzTkuVX48bRWmtpVG8aAxgKctTJDt3lmSDp7cSeyoT
+YRNllNYoogzvNJew2+2QS/YmYk3DFAOvzbHlU9Jw+1BiWAutLZ2NuwPC58AxourL
+XqMzCpPiRKjzvlpGcCXo6pHd+Ld+TCI8eWPiXTQUPrOSZenuwdC0kcrNPrVJ7dkc
+gQKCAQEAmE6BTX7nn0HT859PtBlsy3rM8psihR4UYuYkTdE0+KF4hBRIP6uhMAVh
+vV6UMnt3QubKIekG14seGkwkBnEhv5reYWn/1+t3qP7qqvgndGgI2yPbzJx/cPMK
++KKhRbBAIgkjiY6hlo+DhrNS5nuBjZS2q/NnkO4NK7qBHvpIYAnRZK9qNsT4KZm6
+EO9YlCCnoZ3EB7brNgBZkxoekZG4jTlpD0E7nTxPTF1iVWedKRfmLFxAiDaSz0eo
+9tbTaRQ6ybU6jl1hMg4aINjp4xl/ScKk51veKg5ptjpPtspIh7keJRIUz3qwhuvk
+ZJpVwCxgxAOagrQtvwdedbmvChAfGA==
+-----END PRIVATE KEY-----
diff --git a/biometrics/face/aidl/default/apex/com.android.hardware.biometrics.face.pk8 b/biometrics/face/aidl/default/apex/com.android.hardware.biometrics.face.pk8
new file mode 100644
index 0000000..af0ff4e
--- /dev/null
+++ b/biometrics/face/aidl/default/apex/com.android.hardware.biometrics.face.pk8
Binary files differ
diff --git a/biometrics/face/aidl/default/apex/com.android.hardware.biometrics.face.x509.pem b/biometrics/face/aidl/default/apex/com.android.hardware.biometrics.face.x509.pem
new file mode 100644
index 0000000..3dc37ff
--- /dev/null
+++ b/biometrics/face/aidl/default/apex/com.android.hardware.biometrics.face.x509.pem
@@ -0,0 +1,34 @@
+-----BEGIN CERTIFICATE-----
+MIIF7TCCA9UCFCmJBOOYRVUgdy8vKm8OQd0ii2pPMA0GCSqGSIb3DQEBCwUAMIGx
+MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91
+bnRhaW4gVmlldzEQMA4GA1UECgwHQW5kcm9pZDEQMA4GA1UECwwHQW5kcm9pZDEi
+MCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTEtMCsGA1UEAwwkY29t
+LmFuZHJvaWQuaGFyZHdhcmUuYmlvbWV0cmljcy5mYWNlMCAXDTIzMDUyNTA2NDIw
+MFoYDzQ3NjEwNDIwMDY0MjAwWjCBsTELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNh
+bGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxEDAOBgNVBAoMB0FuZHJv
+aWQxEDAOBgNVBAsMB0FuZHJvaWQxIjAgBgkqhkiG9w0BCQEWE2FuZHJvaWRAYW5k
+cm9pZC5jb20xLTArBgNVBAMMJGNvbS5hbmRyb2lkLmhhcmR3YXJlLmJpb21ldHJp
+Y3MuZmFjZTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAPadnCNPEvKN
+HxACZt3C+tE2rga6gZ1pxfvlwGo1UY9yAxcQjL22SW93OA6R3de5uvQUbHh7b9g5
+AbNYcRnxOMiuUK2XSGWGDscxuGpQVCph4G1rXCOtbTmz1Zb42vQLCCQHHyxzI7ZE
+9Y6+rzw4p3jtEyBSiiErk13GFZTzwcDzqsQs12vDn9ovSTTn5Nyy6Csz7+O2t4SN
+qU4S/uLE6b/TiXj7196r58DcGvJgKbzbbnv/DUHGfaESrVWYLk3xoX3X8VJvP7jI
+M9XoZBbbgFLgAP5DFEvf5QWS9tR092z0YXOGr+mLHtkJM7Or9nKOohm6aFfHbuvu
+pSWyR4FWnaFANQ8wLH+fH485fiO6juJdTuRWeQpZddv0/IgguZ2Plu7z6NHCf5+L
+KYFjQ5y716wOufIqHhRLqYnpsAG2AFaMuPKzsy2KMifqoyB4KYR24EA1MCT7vwqu
+Hurp+SJrmNdkFVXbhGVUfMKf4nRZ37b9Miie0ju0OxJ9C3zY5uR5BMnqEjqq/rCX
+pQh5o1y+bWacOQVp0iQWJHfy8KkjhhQ1Pd1VeoVk9l2DsAJWm6unwMvGHviRcvzg
+BejDOVcE0x4xDj+TwAu2X2+w2hbUSY9W6lmkX4nGHlbLz211bIBFq42PzAMpRnYq
+jLxml4VpO4UnhyRp7Ipps99s7/iMFOn7AgMBAAEwDQYJKoZIhvcNAQELBQADggIB
+AG/5t56hKYKORne0bwJpMSCWZNT6JcYjf6fEmNrvG3/gz9BCuj4osZjJHD2OSUJl
+F5yI52RgPrXK8bNqJOvX6MIc4Y2JoSI2Uz4J2vZ3QhRkPC9oqwk/Enz4GIVJ4Dnm
+/kgpBbN2SN0TjnmEooptly5tWb3IPTjqLZpaPIW1ntQeCAbgrYVHiMsvNe1BuBrn
+RNi1xqw3QGp2ZV/RfJ3MH6d49TswEL1gwiUeg3hw5eG7IDfLB/2IJBrff7kmPTQ6
+n+il4uXuXMmX70xSvJXwP/NinomJsORZ4Npbmp7xV/QJp9cNoxNAo3DJ4OHRAnA+
+L7E1KZ3+nSRxGcVlqBekmG6wH9U39NN+dh758aGdJOWqA+B+1PAGxkvFCNqLgTpm
+xNl62YiRRo4FiIAkntvs+JneMEphv/T5i824t2xFZD2lBuW8r54nWj5cpx8AU9W2
+rulR0jx7BnVdj6czn1/pPCIah8Os9pZM8q1CbF8vXD+QLAF0/NjPNomTEGd/M+V+
+sfn1OhLGF/E1kWyNeOmkvX26txQdY8k6jUdsAc5vmQqgwxdorjI38ynpYQnFwq2g
+eO4l62sx8icsSh2TRklWy8BwZpaCyO/WVv/FcjIUexYhmZ0EHpmQk/RAlD1f9wFy
+CciNa/Dm94AwJgZk9LcXye3BSvb1sKF6C7eYrW0eI95V
+-----END CERTIFICATE-----
diff --git a/biometrics/face/aidl/default/apex/file_contexts b/biometrics/face/aidl/default/apex/file_contexts
new file mode 100644
index 0000000..4f935c1
--- /dev/null
+++ b/biometrics/face/aidl/default/apex/file_contexts
@@ -0,0 +1,3 @@
+(/.*)?                                          u:object_r:vendor_file:s0
+/etc(/.*)?                                      u:object_r:vendor_configs_file:s0
+/bin/hw/android\.hardware\.biometrics\.face-service\.example u:object_r:hal_face_default_exec:s0
\ No newline at end of file
diff --git a/biometrics/face/aidl/default/apex/manifest.json b/biometrics/face/aidl/default/apex/manifest.json
new file mode 100644
index 0000000..4d46896
--- /dev/null
+++ b/biometrics/face/aidl/default/apex/manifest.json
@@ -0,0 +1,4 @@
+{
+    "name": "com.android.hardware.biometrics.face",
+    "version": 1
+}
diff --git a/bluetooth/1.0/default/bluetooth_address.cc b/bluetooth/1.0/default/bluetooth_address.cc
index 93a5469..df3e84a 100644
--- a/bluetooth/1.0/default/bluetooth_address.cc
+++ b/bluetooth/1.0/default/bluetooth_address.cc
@@ -67,7 +67,7 @@
       const uint8_t zero_bdaddr[kBytes] = {0, 0, 0, 0, 0, 0};
       if ((string_to_bytes(address, local_addr)) &&
           (memcmp(local_addr, zero_bdaddr, kBytes) != 0)) {
-        ALOGD("%s: Got Factory BDA %s", __func__, address);
+        ALOGD("%s: Got Factory BDA", __func__);
         return true;
       } else {
         ALOGE("%s: Got Invalid BDA '%s' from %s", __func__, address, property);
@@ -78,12 +78,14 @@
   // No BDADDR found in the file. Look for BDA in a factory property.
   if (property_get(FACTORY_BDADDR_PROPERTY, property, NULL) &&
       string_to_bytes(property, local_addr)) {
+    ALOGD("%s: Using FACTORY_BDADDR_PROPERTY", __func__);
     return true;
   }
 
   // No factory BDADDR found. Look for a previously stored BDA.
   if (property_get(PERSIST_BDADDR_PROPERTY, property, NULL) &&
       string_to_bytes(property, local_addr)) {
+    ALOGD("%s: Using PERSIST_BDADDR_PROPERTY", __func__);
     return true;
   }
 
diff --git a/bluetooth/aidl/TEST_MAPPING b/bluetooth/aidl/TEST_MAPPING
index d1de251..18958d2 100644
--- a/bluetooth/aidl/TEST_MAPPING
+++ b/bluetooth/aidl/TEST_MAPPING
@@ -1,24 +1,12 @@
 {
   "presubmit" : [
     {
-      "name" : "VtsHalBluetoothTargetTest",
-      "options": [
-        {
-          // TODO(b/275847929)
-          "exclude-filter": "VtsHalBluetoothTargetTest.PerInstance/BluetoothAidlTest#Cdd_C_12_1_Bluetooth5Requirements/0_android_hardware_bluetooth_IBluetoothHci_default"
-        }
-      ]
+      "name" : "VtsHalBluetoothTargetTest"
     }
   ],
   "hwasan-presubmit" : [
     {
-      "name" : "VtsHalBluetoothTargetTest",
-      "options": [
-        {
-          // TODO(b/275847929)
-          "exclude-filter": "VtsHalBluetoothTargetTest.PerInstance/BluetoothAidlTest#Cdd_C_12_1_Bluetooth5Requirements/0_android_hardware_bluetooth_IBluetoothHci_default"
-        }
-      ]
+      "name" : "VtsHalBluetoothTargetTest"
     }
   ]
 }
diff --git a/bluetooth/aidl/default/BluetoothHci.cpp b/bluetooth/aidl/default/BluetoothHci.cpp
index d4e4b34..18a371d 100644
--- a/bluetooth/aidl/default/BluetoothHci.cpp
+++ b/bluetooth/aidl/default/BluetoothHci.cpp
@@ -117,11 +117,9 @@
           strerror(errno));
     return fd;
   }
-  if (int ret = SetTerminalRaw(mFd) < 0) {
-    ALOGE("Could not make %s a raw terminal %d(%s)", mDevPath.c_str(), ret,
+  if (int ret = SetTerminalRaw(fd) < 0) {
+    ALOGI("Could not make %s a raw terminal %d(%s)", mDevPath.c_str(), ret,
           strerror(errno));
-    ::close(fd);
-    return -1;
   }
   return fd;
 }
@@ -176,7 +174,10 @@
   mFdWatcher.WatchFdForNonBlockingReads(mFd,
                                         [this](int) { mH4->OnDataReady(); });
 
-  send(PacketType::COMMAND, reset);
+  ndk::ScopedAStatus result = send(PacketType::COMMAND, reset);
+  if (!result.isOk()) {
+    ALOGE("Error sending reset command");
+  }
   auto status = resetFuture.wait_for(std::chrono::seconds(1));
   mFdWatcher.StopWatchingFileDescriptors();
   if (status == std::future_status::ready) {
@@ -303,30 +304,35 @@
 
 ndk::ScopedAStatus BluetoothHci::sendHciCommand(
     const std::vector<uint8_t>& packet) {
-  send(PacketType::COMMAND, packet);
-  return ndk::ScopedAStatus::ok();
+  return send(PacketType::COMMAND, packet);
 }
 
 ndk::ScopedAStatus BluetoothHci::sendAclData(
     const std::vector<uint8_t>& packet) {
-  send(PacketType::ACL_DATA, packet);
-  return ndk::ScopedAStatus::ok();
+  return send(PacketType::ACL_DATA, packet);
 }
 
 ndk::ScopedAStatus BluetoothHci::sendScoData(
     const std::vector<uint8_t>& packet) {
-  send(PacketType::SCO_DATA, packet);
-  return ndk::ScopedAStatus::ok();
+  return send(PacketType::SCO_DATA, packet);
 }
 
 ndk::ScopedAStatus BluetoothHci::sendIsoData(
     const std::vector<uint8_t>& packet) {
-  send(PacketType::ISO_DATA, packet);
-  return ndk::ScopedAStatus::ok();
+  return send(PacketType::ISO_DATA, packet);
 }
 
-void BluetoothHci::send(PacketType type, const std::vector<uint8_t>& v) {
+ndk::ScopedAStatus BluetoothHci::send(PacketType type,
+    const std::vector<uint8_t>& v) {
+  if (mH4 == nullptr) {
+    return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+  }
+  if (v.empty()) {
+    ALOGE("Packet is empty, no data was found to be sent");
+    return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+  }
   mH4->Send(type, v);
+  return ndk::ScopedAStatus::ok();
 }
 
 }  // namespace aidl::android::hardware::bluetooth::impl
diff --git a/bluetooth/aidl/default/BluetoothHci.h b/bluetooth/aidl/default/BluetoothHci.h
index 85aafc8..477cc5c 100644
--- a/bluetooth/aidl/default/BluetoothHci.h
+++ b/bluetooth/aidl/default/BluetoothHci.h
@@ -66,8 +66,9 @@
   ::android::hardware::bluetooth::async::AsyncFdWatcher mFdWatcher;
 
   int getFdFromDevPath();
-  void send(::android::hardware::bluetooth::hci::PacketType type,
-            const std::vector<uint8_t>& packet);
+  [[nodiscard]] ndk::ScopedAStatus send(
+      ::android::hardware::bluetooth::hci::PacketType type,
+      const std::vector<uint8_t>& packet);
   std::unique_ptr<NetBluetoothMgmt> management_{};
 
   // Send a reset command and discard all packets until a reset is received.
diff --git a/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp b/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp
index 529e092..e5222a7 100644
--- a/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp
+++ b/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp
@@ -14,12 +14,14 @@
  * limitations under the License.
  */
 
+#include <VtsCoreUtil.h>
 #include <aidl/Gtest.h>
 #include <aidl/Vintf.h>
 #include <aidl/android/hardware/bluetooth/BnBluetoothHciCallbacks.h>
 #include <aidl/android/hardware/bluetooth/IBluetoothHci.h>
 #include <aidl/android/hardware/bluetooth/IBluetoothHciCallbacks.h>
 #include <aidl/android/hardware/bluetooth/Status.h>
+#include <android-base/properties.h>
 #include <android/binder_auto_utils.h>
 #include <android/binder_manager.h>
 #include <android/binder_process.h>
@@ -67,6 +69,7 @@
 using ::bluetooth::hci::ReadLocalVersionInformationCompleteView;
 
 static constexpr uint8_t kMinLeAdvSetForBt5 = 16;
+static constexpr uint8_t kMinLeAdvSetForBt5FoTv = 10;
 static constexpr uint8_t kMinLeResolvingListForBt5 = 8;
 
 static constexpr size_t kNumHciCommandsBandwidth = 100;
@@ -81,6 +84,40 @@
 // To discard Qualcomm ACL debugging
 static constexpr uint16_t kAclHandleQcaDebugMessage = 0xedc;
 
+static int get_vsr_api_level() {
+  int vendor_api_level =
+      ::android::base::GetIntProperty("ro.vendor.api_level", -1);
+  if (vendor_api_level != -1) {
+    return vendor_api_level;
+  }
+
+  // Android S and older devices do not define ro.vendor.api_level
+  vendor_api_level = ::android::base::GetIntProperty("ro.board.api_level", -1);
+  if (vendor_api_level == -1) {
+    vendor_api_level =
+        ::android::base::GetIntProperty("ro.board.first_api_level", -1);
+  }
+
+  int product_api_level =
+      ::android::base::GetIntProperty("ro.product.first_api_level", -1);
+  if (product_api_level == -1) {
+    product_api_level =
+        ::android::base::GetIntProperty("ro.build.version.sdk", -1);
+    EXPECT_NE(product_api_level, -1) << "Could not find ro.build.version.sdk";
+  }
+
+  // VSR API level is the minimum of vendor_api_level and product_api_level.
+  if (vendor_api_level == -1 || vendor_api_level > product_api_level) {
+    return product_api_level;
+  }
+  return vendor_api_level;
+}
+
+static bool isTv() {
+  return testing::deviceSupportsFeature("android.software.leanback") ||
+         testing::deviceSupportsFeature("android.hardware.type.television");
+}
+
 class ThroughputLogger {
  public:
   explicit ThroughputLogger(std::string task)
@@ -914,7 +951,7 @@
   ASSERT_EQ(status, std::future_status::ready);
 }
 
-TEST_P(BluetoothAidlTest, Cdd_C_12_1_Bluetooth5Requirements) {
+TEST_P(BluetoothAidlTest, Vsr_Bluetooth5Requirements) {
   std::vector<uint8_t> version_event;
   send_and_wait_for_cmd_complete(ReadLocalVersionInformationBuilder::Create(),
                                  version_event);
@@ -959,7 +996,12 @@
   ASSERT_TRUE(num_adv_set_view.IsValid());
   ASSERT_EQ(::bluetooth::hci::ErrorCode::SUCCESS, num_adv_set_view.GetStatus());
   auto num_adv_set = num_adv_set_view.GetNumberSupportedAdvertisingSets();
-  ASSERT_GE(num_adv_set, kMinLeAdvSetForBt5);
+
+  if (isTv() && get_vsr_api_level() == __ANDROID_API_U__) {
+    ASSERT_GE(num_adv_set, kMinLeAdvSetForBt5FoTv);
+  } else {
+    ASSERT_GE(num_adv_set, kMinLeAdvSetForBt5);
+  }
 
   std::vector<uint8_t> num_resolving_list_event;
   send_and_wait_for_cmd_complete(LeReadResolvingListSizeBuilder::Create(),
diff --git a/bluetooth/audio/aidl/TEST_MAPPING b/bluetooth/audio/aidl/TEST_MAPPING
new file mode 100644
index 0000000..0c853f8
--- /dev/null
+++ b/bluetooth/audio/aidl/TEST_MAPPING
@@ -0,0 +1,12 @@
+{
+  "presubmit": [
+    {
+      "name": "VtsHalBluetoothAudioTargetTest"
+    }
+  ],
+  "kernel-presubmit": [
+    {
+      "name": "VtsHalBluetoothAudioTargetTest"
+    }
+  ]
+}
diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp b/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp
index 2a88959..9c72e19 100644
--- a/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp
+++ b/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp
@@ -27,9 +27,31 @@
 namespace bluetooth {
 namespace audio {
 
+struct BluetoothAudioProviderContext {
+  SessionType session_type;
+};
+
+static void binderUnlinkedCallbackAidl(void* cookie) {
+  LOG(INFO) << __func__;
+  BluetoothAudioProviderContext* ctx =
+      static_cast<BluetoothAudioProviderContext*>(cookie);
+  delete ctx;
+}
+
+static void binderDiedCallbackAidl(void* cookie) {
+  LOG(INFO) << __func__;
+  BluetoothAudioProviderContext* ctx =
+      static_cast<BluetoothAudioProviderContext*>(cookie);
+  CHECK_NE(ctx, nullptr);
+
+  BluetoothAudioSessionReport::OnSessionEnded(ctx->session_type);
+}
+
 BluetoothAudioProvider::BluetoothAudioProvider() {
   death_recipient_ = ::ndk::ScopedAIBinder_DeathRecipient(
       AIBinder_DeathRecipient_new(binderDiedCallbackAidl));
+  AIBinder_DeathRecipient_setOnUnlinked(death_recipient_.get(),
+                                        binderUnlinkedCallbackAidl);
 }
 
 ndk::ScopedAStatus BluetoothAudioProvider::startSession(
@@ -39,17 +61,21 @@
     DataMQDesc* _aidl_return) {
   if (host_if == nullptr) {
     *_aidl_return = DataMQDesc();
+    LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_)
+               << " Illegal argument";
     return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
   }
 
   latency_modes_ = latencyModes;
   audio_config_ = std::make_unique<AudioConfiguration>(audio_config);
   stack_iface_ = host_if;
-  is_binder_died = false;
+  BluetoothAudioProviderContext* cookie =
+      new BluetoothAudioProviderContext{session_type_};
 
   AIBinder_linkToDeath(stack_iface_->asBinder().get(), death_recipient_.get(),
-                       this);
+                       cookie);
 
+  LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_);
   onSessionReady(_aidl_return);
   return ndk::ScopedAStatus::ok();
 }
@@ -60,10 +86,8 @@
   if (stack_iface_ != nullptr) {
     BluetoothAudioSessionReport::OnSessionEnded(session_type_);
 
-    if (!is_binder_died) {
-      AIBinder_unlinkToDeath(stack_iface_->asBinder().get(),
-                             death_recipient_.get(), this);
-    }
+    AIBinder_unlinkToDeath(stack_iface_->asBinder().get(),
+                           death_recipient_.get(), this);
   } else {
     LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
               << " has NO session";
@@ -77,10 +101,9 @@
 
 ndk::ScopedAStatus BluetoothAudioProvider::streamStarted(
     BluetoothAudioStatus status) {
-  LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
-            << ", status=" << toString(status);
-
   if (stack_iface_ != nullptr) {
+    LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
+              << ", status=" << toString(status);
     BluetoothAudioSessionReport::ReportControlStatus(session_type_, true,
                                                      status);
   } else {
@@ -108,8 +131,6 @@
 
 ndk::ScopedAStatus BluetoothAudioProvider::updateAudioConfiguration(
     const AudioConfiguration& audio_config) {
-  LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_);
-
   if (stack_iface_ == nullptr || audio_config_ == nullptr) {
     LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
               << " has NO session";
@@ -125,13 +146,13 @@
   audio_config_ = std::make_unique<AudioConfiguration>(audio_config);
   BluetoothAudioSessionReport::ReportAudioConfigChanged(session_type_,
                                                         *audio_config_);
+  LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
+            << " | audio_config=" << audio_config.toString();
   return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus BluetoothAudioProvider::setLowLatencyModeAllowed(
     bool allowed) {
-  LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_);
-
   if (stack_iface_ == nullptr) {
     LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
               << " has NO session";
@@ -143,17 +164,6 @@
   return ndk::ScopedAStatus::ok();
 }
 
-void BluetoothAudioProvider::binderDiedCallbackAidl(void* ptr) {
-  LOG(ERROR) << __func__ << " - BluetoothAudio Service died";
-  auto provider = static_cast<BluetoothAudioProvider*>(ptr);
-  if (provider == nullptr) {
-    LOG(ERROR) << __func__ << ": Null AudioProvider HAL died";
-    return;
-  }
-  provider->is_binder_died = true;
-  provider->endSession();
-}
-
 }  // namespace audio
 }  // namespace bluetooth
 }  // namespace hardware
diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProvider.h b/bluetooth/audio/aidl/default/BluetoothAudioProvider.h
index dbfff7d..b6e07a1 100644
--- a/bluetooth/audio/aidl/default/BluetoothAudioProvider.h
+++ b/bluetooth/audio/aidl/default/BluetoothAudioProvider.h
@@ -54,7 +54,6 @@
 
  protected:
   virtual ndk::ScopedAStatus onSessionReady(DataMQDesc* _aidl_return) = 0;
-  static void binderDiedCallbackAidl(void* cookie_ptr);
 
   ::ndk::ScopedAIBinder_DeathRecipient death_recipient_;
 
@@ -62,9 +61,7 @@
   std::unique_ptr<AudioConfiguration> audio_config_ = nullptr;
   SessionType session_type_;
   std::vector<LatencyMode> latency_modes_;
-  bool is_binder_died = false;
 };
-
 }  // namespace audio
 }  // namespace bluetooth
 }  // namespace hardware
diff --git a/bluetooth/audio/utils/Android.bp b/bluetooth/audio/utils/Android.bp
index 914d2b2..2cba61e 100644
--- a/bluetooth/audio/utils/Android.bp
+++ b/bluetooth/audio/utils/Android.bp
@@ -93,4 +93,5 @@
     srcs: ["le_audio_codec_capabilities/le_audio_codec_capabilities.xsd"],
     package_name: "aidl.android.hardware.bluetooth.audio.setting",
     api_dir: "le_audio_codec_capabilities/schema",
+    root_elements: ["leAudioOffloadSetting"],
 }
diff --git a/bluetooth/audio/utils/le_audio_codec_capabilities/schema/current.txt b/bluetooth/audio/utils/le_audio_codec_capabilities/schema/current.txt
index 886350e..3cef417 100644
--- a/bluetooth/audio/utils/le_audio_codec_capabilities/schema/current.txt
+++ b/bluetooth/audio/utils/le_audio_codec_capabilities/schema/current.txt
@@ -96,15 +96,7 @@
 
   public class XmlParser {
     ctor public XmlParser();
-    method public static aidl.android.hardware.bluetooth.audio.setting.CodecConfiguration readCodecConfiguration(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
-    method public static aidl.android.hardware.bluetooth.audio.setting.CodecConfigurationList readCodecConfigurationList(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
-    method public static aidl.android.hardware.bluetooth.audio.setting.Configuration readConfiguration(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
-    method public static aidl.android.hardware.bluetooth.audio.setting.ConfigurationList readConfigurationList(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
     method public static aidl.android.hardware.bluetooth.audio.setting.LeAudioOffloadSetting readLeAudioOffloadSetting(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
-    method public static aidl.android.hardware.bluetooth.audio.setting.Scenario readScenario(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
-    method public static aidl.android.hardware.bluetooth.audio.setting.ScenarioList readScenarioList(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
-    method public static aidl.android.hardware.bluetooth.audio.setting.StrategyConfiguration readStrategyConfiguration(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
-    method public static aidl.android.hardware.bluetooth.audio.setting.StrategyConfigurationList readStrategyConfigurationList(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
     method public static String readText(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
     method public static void skip(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
   }
diff --git a/bluetooth/hci/h4_protocol.cc b/bluetooth/hci/h4_protocol.cc
index 51a624f..5f6d86e 100644
--- a/bluetooth/hci/h4_protocol.cc
+++ b/bluetooth/hci/h4_protocol.cc
@@ -105,15 +105,12 @@
       buffer_offset += 1;
     } else {
       bool packet_ready = hci_packetizer_.OnDataReady(
-          hci_packet_type_, input_buffer, buffer_offset);
+          hci_packet_type_, input_buffer, &buffer_offset);
       if (packet_ready) {
-        // Call packet callback and move offset.
-        buffer_offset += OnPacketReady(hci_packetizer_.GetPacket());
+        // Call packet callback.
+        OnPacketReady(hci_packetizer_.GetPacket());
         // Get ready for the next type byte.
         hci_packet_type_ = PacketType::UNKNOWN;
-      } else {
-        // The data was consumed, but there wasn't a packet.
-        buffer_offset = input_buffer.size();
       }
     }
   }
diff --git a/bluetooth/hci/hci_packetizer.cc b/bluetooth/hci/hci_packetizer.cc
index 5b6c443..4135920 100644
--- a/bluetooth/hci/hci_packetizer.cc
+++ b/bluetooth/hci/hci_packetizer.cc
@@ -51,9 +51,10 @@
 
 bool HciPacketizer::OnDataReady(PacketType packet_type,
                                 const std::vector<uint8_t>& buffer,
-                                size_t offset) {
+                                size_t* offset) {
   bool packet_completed = false;
-  size_t bytes_available = buffer.size() - offset;
+  size_t bytes_available = buffer.size() - *offset;
+
   switch (state_) {
     case HCI_HEADER: {
       size_t header_size =
@@ -62,18 +63,20 @@
         bytes_remaining_ = header_size;
         packet_.clear();
       }
+
       size_t bytes_to_copy = std::min(bytes_remaining_, bytes_available);
-      packet_.insert(packet_.end(), buffer.begin() + offset,
-                     buffer.begin() + offset + bytes_to_copy);
+      packet_.insert(packet_.end(), buffer.begin() + *offset,
+                     buffer.begin() + *offset + bytes_to_copy);
       bytes_remaining_ -= bytes_to_copy;
       bytes_available -= bytes_to_copy;
+      *offset += bytes_to_copy;
+
       if (bytes_remaining_ == 0) {
         bytes_remaining_ = HciGetPacketLengthForType(packet_type, packet_);
         if (bytes_remaining_ > 0) {
           state_ = HCI_PAYLOAD;
           if (bytes_available > 0) {
-            packet_completed =
-                OnDataReady(packet_type, buffer, offset + bytes_to_copy);
+            packet_completed = OnDataReady(packet_type, buffer, offset);
           }
         } else {
           packet_completed = true;
@@ -84,9 +87,10 @@
 
     case HCI_PAYLOAD: {
       size_t bytes_to_copy = std::min(bytes_remaining_, bytes_available);
-      packet_.insert(packet_.end(), buffer.begin() + offset,
-                     buffer.begin() + offset + bytes_to_copy);
+      packet_.insert(packet_.end(), buffer.begin() + *offset,
+                     buffer.begin() + *offset + bytes_to_copy);
       bytes_remaining_ -= bytes_to_copy;
+      *offset += bytes_to_copy;
       if (bytes_remaining_ == 0) {
         state_ = HCI_HEADER;
         packet_completed = true;
@@ -94,6 +98,7 @@
       break;
     }
   }
+
   return packet_completed;
 }
 
diff --git a/bluetooth/hci/hci_packetizer.h b/bluetooth/hci/hci_packetizer.h
index ba3e841..0d9319f 100644
--- a/bluetooth/hci/hci_packetizer.h
+++ b/bluetooth/hci/hci_packetizer.h
@@ -28,7 +28,7 @@
  public:
   HciPacketizer() = default;
   bool OnDataReady(PacketType packet_type, const std::vector<uint8_t>& data,
-                   size_t offset);
+                   size_t* offset);
   const std::vector<uint8_t>& GetPacket() const;
 
  protected:
diff --git a/bluetooth/hci/test/h4_protocol_unittest.cc b/bluetooth/hci/test/h4_protocol_unittest.cc
index d3fab61..f0c49b5 100644
--- a/bluetooth/hci/test/h4_protocol_unittest.cc
+++ b/bluetooth/hci/test/h4_protocol_unittest.cc
@@ -31,7 +31,6 @@
 #include <vector>
 
 #include "async_fd_watcher.h"
-#include "log/log.h"
 
 using android::hardware::bluetooth::async::AsyncFdWatcher;
 using namespace android::hardware::bluetooth::hci;
@@ -49,6 +48,7 @@
 static char event_data[100] = "The edges of a surface are lines.";
 static char iso_data[100] =
     "A plane angle is the inclination to one another of two lines in a ...";
+static char short_payload[10] = "12345";
 
 // 5 seconds.  Just don't hang.
 static constexpr size_t kTimeoutMs = 5000;
@@ -225,6 +225,49 @@
     CallDataReady();
   }
 
+  void WriteAndExpectManyAclDataPacketsDifferentOffsetsShort() {
+    std::promise<void> last_packet_promise;
+    size_t kNumPackets = 30;
+    // h4 type[1] + handle[2] + size[2]
+    char preamble[5] = {static_cast<uint8_t>(PacketType::ACL_DATA), 19, 92, 0,
+                        0};
+    int length = strlen(short_payload);
+    preamble[3] = length & 0xFF;
+    preamble[4] = 0;
+
+    EXPECT_CALL(acl_cb_, Call(PacketMatches(preamble + 1, kAclHeaderSize,
+                                            short_payload)))
+        .Times(kNumPackets);
+    ExpectInboundEvent(event_data, &last_packet_promise);
+
+    char all_packets[kNumPackets * 10];
+    size_t total_bytes = 0;
+
+    for (size_t packet = 0; packet < kNumPackets; packet++) {
+      for (size_t i = 0; i < sizeof(preamble); i++) {
+        all_packets[total_bytes++] = preamble[i];
+      }
+      for (size_t i = 0; i < length; i++) {
+        all_packets[total_bytes++] = short_payload[i];
+      }
+    }
+
+    size_t written_bytes = 0;
+    size_t partial_size = 1;
+    while (written_bytes < total_bytes) {
+      size_t to_write = std::min(partial_size, total_bytes - written_bytes);
+      TEMP_FAILURE_RETRY(
+          write(chip_uart_fd_, all_packets + written_bytes, to_write));
+      written_bytes += to_write;
+      CallDataReady();
+      partial_size++;
+      partial_size = partial_size % 5 + 1;
+    }
+    WriteInboundEvent(event_data);
+    CallDataReady();
+    WaitForTimeout(&last_packet_promise);
+  }
+
   testing::MockFunction<void(const std::vector<uint8_t>&)> cmd_cb_;
   testing::MockFunction<void(const std::vector<uint8_t>&)> event_cb_;
   testing::MockFunction<void(const std::vector<uint8_t>&)> acl_cb_;
@@ -276,6 +319,10 @@
   WriteAndExpectManyInboundAclDataPackets(sco_data);
 }
 
+TEST_F(H4ProtocolTest, TestMultipleWritesPacketsShortWrites) {
+  WriteAndExpectManyAclDataPacketsDifferentOffsetsShort();
+}
+
 TEST_F(H4ProtocolTest, TestDisconnect) {
   EXPECT_CALL(disconnect_cb_, Call());
   close(chip_uart_fd_);
@@ -332,10 +379,8 @@
 
   void TearDown() override { fd_watcher_.StopWatchingFileDescriptors(); }
 
-  void CallDataReady() override {
-    // The Async test can't call data ready.
-    FAIL();
-  }
+  // Calling CallDataReady() has no effect in the AsyncTest
+  void CallDataReady() override {}
 
   void SendAndReadUartOutbound(PacketType type, char* data) {
     ALOGD("%s sending", __func__);
@@ -434,6 +479,10 @@
   WriteAndExpectManyInboundAclDataPackets(sco_data);
 }
 
+TEST_F(H4ProtocolAsyncTest, TestMultipleWritesPacketsShortWrites) {
+  WriteAndExpectManyAclDataPacketsDifferentOffsetsShort();
+}
+
 TEST_F(H4ProtocolAsyncTest, TestDisconnect) {
   std::promise<void> promise;
   EXPECT_CALL(disconnect_cb_, Call()).WillOnce(Notify(&promise));
diff --git a/camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.cpp b/camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.cpp
index 4fc7437..04db7f3 100644
--- a/camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.cpp
+++ b/camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.cpp
@@ -18,15 +18,16 @@
 //#define LOG_NDEBUG 0
 #include <log/log.h>
 
-#include <regex>
-#include <sys/inotify.h>
+#include <cutils/properties.h>
 #include <errno.h>
 #include <linux/videodev2.h>
-#include <cutils/properties.h>
-#include "ExternalCameraProviderImpl_2_4.h"
+#include <sys/inotify.h>
+#include <regex>
+#include <string>
 #include "ExternalCameraDevice_3_4.h"
 #include "ExternalCameraDevice_3_5.h"
 #include "ExternalCameraDevice_3_6.h"
+#include "ExternalCameraProviderImpl_2_4.h"
 
 namespace android {
 namespace hardware {
@@ -41,10 +42,10 @@
 // "device@<version>/external/<id>"
 const std::regex kDeviceNameRE("device@([0-9]+\\.[0-9]+)/external/(.+)");
 const int kMaxDevicePathLen = 256;
-const char* kDevicePath = "/dev/";
-constexpr char kPrefix[] = "video";
-constexpr int kPrefixLen = sizeof(kPrefix) - 1;
-constexpr int kDevicePrefixLen = sizeof(kDevicePath) + kPrefixLen + 1;
+constexpr const char* kDevicePath = "/dev/";
+constexpr const char* kPrefix = "video";
+constexpr int kPrefixLen = std::char_traits<char>::length(kPrefix);
+constexpr int kDevicePrefixLen = std::char_traits<char>::length(kDevicePath) + kPrefixLen;
 
 bool matchDeviceName(int cameraIdOffset,
                      const hidl_string& deviceName, std::string* deviceVersion,
diff --git a/camera/provider/2.7/default/ExternalCameraProviderImpl_2_7.cpp b/camera/provider/2.7/default/ExternalCameraProviderImpl_2_7.cpp
index b63e3bb..62ce074 100644
--- a/camera/provider/2.7/default/ExternalCameraProviderImpl_2_7.cpp
+++ b/camera/provider/2.7/default/ExternalCameraProviderImpl_2_7.cpp
@@ -23,6 +23,7 @@
 #include <linux/videodev2.h>
 #include <sys/inotify.h>
 #include <regex>
+#include <string>
 #include "ExternalCameraDevice_3_4.h"
 #include "ExternalCameraDevice_3_5.h"
 #include "ExternalCameraDevice_3_6.h"
@@ -39,10 +40,10 @@
 // "device@<version>/external/<id>"
 const std::regex kDeviceNameRE("device@([0-9]+\\.[0-9]+)/external/(.+)");
 const int kMaxDevicePathLen = 256;
-const char* kDevicePath = "/dev/";
-constexpr char kPrefix[] = "video";
-constexpr int kPrefixLen = sizeof(kPrefix) - 1;
-constexpr int kDevicePrefixLen = sizeof(kDevicePath) + kPrefixLen + 1;
+constexpr const char* kDevicePath = "/dev/";
+constexpr const char* kPrefix = "video";
+constexpr int kPrefixLen = std::char_traits<char>::length(kPrefix);
+constexpr int kDevicePrefixLen = std::char_traits<char>::length(kDevicePath) + kPrefixLen;
 
 bool matchDeviceName(int cameraIdOffset, const hidl_string& deviceName, std::string* deviceVersion,
                      std::string* cameraDevicePath) {
diff --git a/camera/provider/aidl/vts/Android.bp b/camera/provider/aidl/vts/Android.bp
index f17de3a..647cbac 100644
--- a/camera/provider/aidl/vts/Android.bp
+++ b/camera/provider/aidl/vts/Android.bp
@@ -68,6 +68,16 @@
         "libgralloctypes",
         "libaidlcommonsupport",
     ],
+
+    require_root: true,
+    test_options: {
+        test_runner_options: [
+            {
+                name: "native-test-timeout",
+                value: "1800000",
+            },
+        ],
+    },
     test_suites: [
         "general-tests",
         "vts",
diff --git a/camera/provider/aidl/vts/AndroidTest.xml b/camera/provider/aidl/vts/AndroidTest.xml
deleted file mode 100644
index 226121d..0000000
--- a/camera/provider/aidl/vts/AndroidTest.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2022 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     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.
--->
-<configuration description="Runs VtsAidlHalCameraProvider_TargetTest.">
-    <option name="test-suite-tag" value="apct" />
-    <option name="test-suite-tag" value="apct-native" />
-
-    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
-    </target_preparer>
-
-    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
-        <option name="cleanup" value="true" />
-        <option name="push" value="VtsAidlHalCameraProvider_TargetTest->/data/local/tmp/VtsAidlHalCameraProvider_TargetTest" />
-    </target_preparer>
-
-    <test class="com.android.tradefed.testtype.GTest" >
-        <option name="native-test-device-path" value="/data/local/tmp" />
-        <option name="module-name" value="VtsAidlHalCameraProvider_TargetTest" />
-        <option name="native-test-timeout" value="1800000"/> <!-- 30 min -->
-    </test>
-</configuration>
\ No newline at end of file
diff --git a/compatibility_matrices/compatibility_matrix.9.xml b/compatibility_matrices/compatibility_matrix.9.xml
index 1906325..e23f2ae 100644
--- a/compatibility_matrices/compatibility_matrix.9.xml
+++ b/compatibility_matrices/compatibility_matrix.9.xml
@@ -134,7 +134,7 @@
             <regex-instance>.*</regex-instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl" optional="true" updatable-via-apex="true">
         <name>android.hardware.biometrics.face</name>
         <version>2</version>
         <interface>
@@ -142,7 +142,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl" optional="true" updatable-via-apex="true">
         <name>android.hardware.biometrics.fingerprint</name>
         <version>2</version>
         <interface>
@@ -150,14 +150,6 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.bluetooth</name>
-        <version>1.0-1</version>
-        <interface>
-            <name>IBluetoothHci</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
     <hal format="aidl" optional="true">
         <name>android.hardware.bluetooth</name>
         <interface>
@@ -587,14 +579,6 @@
             <instance>slot1</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.renderscript</name>
-        <version>1.0</version>
-        <interface>
-            <name>IDevice</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
     <hal format="aidl" optional="true">
         <name>android.hardware.rebootescrow</name>
         <version>1</version>
@@ -645,14 +629,6 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.soundtrigger</name>
-        <version>2.3</version>
-        <interface>
-            <name>ISoundTriggerHw</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
     <hal format="aidl" optional="true">
          <name>android.hardware.soundtrigger3</name>
          <version>1</version>
@@ -661,22 +637,6 @@
              <instance>default</instance>
          </interface>
     </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.tetheroffload.config</name>
-        <version>1.0</version>
-        <interface>
-            <name>IOffloadConfig</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.tetheroffload.control</name>
-        <version>1.1</version>
-        <interface>
-            <name>IOffloadControl</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
     <hal format="aidl" optional="true">
         <name>android.hardware.tetheroffload</name>
         <version>1</version>
diff --git a/contexthub/aidl/Android.bp b/contexthub/aidl/Android.bp
index a865445..7a0a93b 100644
--- a/contexthub/aidl/Android.bp
+++ b/contexthub/aidl/Android.bp
@@ -34,6 +34,9 @@
         ndk: {
             apps_enabled: false,
         },
+        rust: {
+            enabled: true,
+        },
     },
     versions_with_info: [
         {
diff --git a/drm/1.3/vts/OWNERS b/drm/1.3/vts/OWNERS
index 3a0672e..744827c 100644
--- a/drm/1.3/vts/OWNERS
+++ b/drm/1.3/vts/OWNERS
@@ -1,9 +1,11 @@
+# Bug component: 49079
 conglin@google.com
-edwinwong@google.com
 fredgc@google.com
-jtinker@google.com
 juce@google.com
+kelzhan@google.com
 kylealexander@google.com
+mattfedd@google.com
 rfrias@google.com
 robertshih@google.com
 sigquit@google.com
+vickymin@google.com
\ No newline at end of file
diff --git a/gnss/aidl/OWNERS b/gnss/aidl/OWNERS
index b7b4a2e..e5b585e 100644
--- a/gnss/aidl/OWNERS
+++ b/gnss/aidl/OWNERS
@@ -1,3 +1,5 @@
+# Bug component: 393449
+
 gomo@google.com
 smalkos@google.com
 wyattriley@google.com
diff --git a/graphics/composer/2.4/vts/functional/TEST_MAPPING b/graphics/composer/2.4/vts/functional/TEST_MAPPING
new file mode 100644
index 0000000..aedac5b
--- /dev/null
+++ b/graphics/composer/2.4/vts/functional/TEST_MAPPING
@@ -0,0 +1,13 @@
+{
+  "presubmit": [
+    {
+      "name": "VtsHalGraphicsComposerV2_4TargetTest"
+    }
+  ],
+  "kernel-presubmit": [
+    {
+      "name": "VtsHalGraphicsComposerV2_4TargetTest"
+    }
+  ]
+}
+
diff --git a/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp b/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
index 2ec98d4..0ddb236 100644
--- a/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
+++ b/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
@@ -677,7 +677,7 @@
 
     const native_handle_t* clonedBufferHandle;
     ASSERT_NO_FATAL_FAILURE(clonedBufferHandle = mGralloc->allocate(mDummyDescriptorInfo, false));
-    error = mGralloc->getMapper()->freeBuffer(invalidHandle);
+    error = mGralloc->getMapper()->freeBuffer(const_cast<native_handle_t*>(clonedBufferHandle));
     EXPECT_EQ(Error::BAD_BUFFER, error)
             << "freeBuffer with un-imported handle did not fail with BAD_BUFFER";
 
diff --git a/graphics/mapper/stable-c/vts/VtsHalGraphicsMapperStableC_TargetTest.cpp b/graphics/mapper/stable-c/vts/VtsHalGraphicsMapperStableC_TargetTest.cpp
index 2c06353..b329de2 100644
--- a/graphics/mapper/stable-c/vts/VtsHalGraphicsMapperStableC_TargetTest.cpp
+++ b/graphics/mapper/stable-c/vts/VtsHalGraphicsMapperStableC_TargetTest.cpp
@@ -1371,6 +1371,28 @@
     EXPECT_EQ(buffer->info().usage, *value);
 }
 
+TEST_P(GraphicsMapperStableCTests, GetUsage64) {
+    BufferDescriptorInfo info{
+            .name = {"VTS_TEMP"},
+            .width = 64,
+            .height = 64,
+            .layerCount = 1,
+            .format = PixelFormat::RGBA_8888,
+            .usage = BufferUsage::FRONT_BUFFER | BufferUsage::GPU_RENDER_TARGET |
+                     BufferUsage::COMPOSER_OVERLAY | BufferUsage::GPU_TEXTURE,
+            .reservedSize = 0,
+    };
+    if (!isSupported(info)) {
+        GTEST_SKIP();
+    }
+    auto buffer = allocate(info);
+    auto bufferHandle = buffer->import();
+    auto value = getStandardMetadata<StandardMetadataType::USAGE>(*bufferHandle);
+    ASSERT_TRUE(value.has_value());
+    using T = std::underlying_type_t<BufferUsage>;
+    EXPECT_EQ(static_cast<T>(buffer->info().usage), static_cast<T>(*value));
+}
+
 TEST_P(GraphicsMapperStableCTests, GetAllocationSize) {
     auto buffer = allocateGeneric();
     auto bufferHandle = buffer->import();
diff --git a/health/storage/aidl/vts/functional/OWNERS b/health/storage/aidl/vts/functional/OWNERS
new file mode 100644
index 0000000..a15ed7c
--- /dev/null
+++ b/health/storage/aidl/vts/functional/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 30545
+file:platform/hardware/interfaces:/health/aidl/OWNERS
\ No newline at end of file
diff --git a/identity/aidl/vts/Util.cpp b/identity/aidl/vts/Util.cpp
index 4f5c121..ad9281c 100644
--- a/identity/aidl/vts/Util.cpp
+++ b/identity/aidl/vts/Util.cpp
@@ -73,7 +73,7 @@
     ndkMacedPublicKey.macedKey = macedPublicKey.macedKey;
 
     vector<uint8_t> publicKeyBits;
-    check_maced_pubkey(ndkMacedPublicKey, /*testMode=*/true, &publicKeyBits);
+    check_maced_pubkey(ndkMacedPublicKey, /*testMode=*/false, &publicKeyBits);
 
     ::aidl::android::hardware::security::keymint::EVP_PKEY_Ptr publicKey;
     p256_pub_key(publicKeyBits, &publicKey);
diff --git a/identity/aidl/vts/VtsIWritableIdentityCredentialTests.cpp b/identity/aidl/vts/VtsIWritableIdentityCredentialTests.cpp
index 94d4c88..eb74fa2 100644
--- a/identity/aidl/vts/VtsIWritableIdentityCredentialTests.cpp
+++ b/identity/aidl/vts/VtsIWritableIdentityCredentialTests.cpp
@@ -125,7 +125,8 @@
 
     MacedPublicKey macedPublicKey;
     std::vector<uint8_t> attestationKey;
-    result = rpc->generateEcdsaP256KeyPair(/*testMode=*/true, &macedPublicKey, &attestationKey);
+    // Start by RPC version 3, we don't support testMode=true. So just verify testMode=false here.
+    result = rpc->generateEcdsaP256KeyPair(/*testMode=*/false, &macedPublicKey, &attestationKey);
     ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage();
 
     optional<vector<vector<uint8_t>>> remotelyProvisionedCertChain =
@@ -176,7 +177,8 @@
 
     MacedPublicKey macedPublicKey;
     std::vector<uint8_t> attestationKey;
-    result = rpc->generateEcdsaP256KeyPair(/*testMode=*/true, &macedPublicKey, &attestationKey);
+    // Start by RPC version 3, we don't support testMode=true. So just verify testMode=false here.
+    result = rpc->generateEcdsaP256KeyPair(/*testMode=*/false, &macedPublicKey, &attestationKey);
     ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage();
 
     optional<vector<vector<uint8_t>>> remotelyProvisionedCertChain =
diff --git a/identity/support/Android.bp b/identity/support/Android.bp
index 3096fe5..d62d055 100644
--- a/identity/support/Android.bp
+++ b/identity/support/Android.bp
@@ -22,15 +22,8 @@
     default_applicable_licenses: ["hardware_interfaces_license"],
 }
 
-cc_library {
-    name: "android.hardware.identity-support-lib",
-    vendor_available: true,
-    srcs: [
-        "src/IdentityCredentialSupport.cpp",
-    ],
-    export_include_dirs: [
-        "include",
-    ],
+cc_defaults {
+    name: "android.hardware.identity-support-lib-deps",
     shared_libs: [
         "android.hardware.keymaster@4.0",
         "libcrypto",
@@ -47,19 +40,36 @@
     ],
 }
 
+cc_library {
+    name: "android.hardware.identity-support-lib",
+    vendor_available: true,
+    defaults: [
+        "android.hardware.identity-support-lib-deps",
+    ],
+    srcs: [
+        "src/IdentityCredentialSupport.cpp",
+    ],
+    export_include_dirs: [
+        "include",
+    ],
+}
+
 cc_test {
     name: "android.hardware.identity-support-lib-test",
     srcs: [
         "tests/IdentityCredentialSupportTest.cpp",
     ],
+    defaults: [
+        "android.hardware.identity-support-lib-deps",
+    ],
     shared_libs: [
-        "android.hardware.identity-support-lib",
         "libcrypto",
         "libbase",
         "libhidlbase",
         "libhardware",
     ],
     static_libs: [
+        "android.hardware.identity-support-lib",
         "libcppbor_external",
         "libgmock",
     ],
diff --git a/keymaster/3.0/vts/functional/keymaster_hidl_hal_test.cpp b/keymaster/3.0/vts/functional/keymaster_hidl_hal_test.cpp
index 554afe7..65b3dfa 100644
--- a/keymaster/3.0/vts/functional/keymaster_hidl_hal_test.cpp
+++ b/keymaster/3.0/vts/functional/keymaster_hidl_hal_test.cpp
@@ -2617,10 +2617,11 @@
     EVP_PKEY_Ptr pkey(d2i_PUBKEY(nullptr /* alloc new */, &p, exported.size()));
     RSA_Ptr rsa(EVP_PKEY_get1_RSA(pkey.get()));
 
-    size_t modulus_len = BN_num_bytes(rsa->n);
+    const BIGNUM* n = RSA_get0_n(rsa.get());
+    size_t modulus_len = BN_num_bytes(n);
     ASSERT_EQ(1024U / 8, modulus_len);
     std::unique_ptr<uint8_t[]> modulus_buf(new uint8_t[modulus_len]);
-    BN_bn2bin(rsa->n, modulus_buf.get());
+    BN_bn2bin(n, modulus_buf.get());
 
     // The modulus is too big to encrypt.
     string message(reinterpret_cast<const char*>(modulus_buf.get()), modulus_len);
@@ -2632,10 +2633,12 @@
     EXPECT_EQ(ErrorCode::INVALID_ARGUMENT, Finish(message, &result));
 
     // One smaller than the modulus is okay.
-    BN_sub(rsa->n, rsa->n, BN_value_one());
-    modulus_len = BN_num_bytes(rsa->n);
+    BIGNUM_Ptr n_minus_1(BN_new());
+    ASSERT_TRUE(n_minus_1);
+    ASSERT_TRUE(BN_sub(n_minus_1.get(), n, BN_value_one()));
+    modulus_len = BN_num_bytes(n_minus_1.get());
     ASSERT_EQ(1024U / 8, modulus_len);
-    BN_bn2bin(rsa->n, modulus_buf.get());
+    BN_bn2bin(n_minus_1.get(), modulus_buf.get());
     message = string(reinterpret_cast<const char*>(modulus_buf.get()), modulus_len);
     EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params));
     EXPECT_EQ(ErrorCode::OK, Finish(message, &result));
diff --git a/keymaster/4.0/vts/functional/Android.bp b/keymaster/4.0/vts/functional/Android.bp
index f9a02ba..e1dfcfc 100644
--- a/keymaster/4.0/vts/functional/Android.bp
+++ b/keymaster/4.0/vts/functional/Android.bp
@@ -30,13 +30,17 @@
         "keymaster_hidl_hal_test.cpp",
     ],
     srcs: [
+        "BootloaderStateTest.cpp",
         "HmacKeySharingTest.cpp",
         "VerificationTokenTest.cpp",
         "keymaster_hidl_hal_test.cpp",
     ],
     static_libs: [
         "android.hardware.keymaster@4.0",
+        "libavb_user",
+        "libavb",
         "libcrypto_static",
+        "libfs_mgr",
         "libkeymaster4support",
         "libkeymaster4vtstest",
     ],
@@ -64,6 +68,7 @@
     ],
     static_libs: [
         "android.hardware.keymaster@4.0",
+        "libcrypto_static",
         "libkeymaster4support",
     ],
 }
diff --git a/keymaster/4.0/vts/functional/BootloaderStateTest.cpp b/keymaster/4.0/vts/functional/BootloaderStateTest.cpp
new file mode 100644
index 0000000..912b59b
--- /dev/null
+++ b/keymaster/4.0/vts/functional/BootloaderStateTest.cpp
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <memory>
+#include <optional>
+#include <string>
+#include <vector>
+
+#include <android-base/properties.h>
+#include <fstab/fstab.h>
+#include <libavb/libavb.h>
+#include <libavb_user/avb_ops_user.h>
+
+#include "KeymasterHidlTest.h"
+
+namespace android::hardware::keymaster::V4_0::test {
+
+using ::std::string;
+using ::std::vector;
+
+// Since this test needs to talk to Keymaster HAL, it can only run as root. Thus,
+// bootloader can not be locked.
+class BootloaderStateTest : public KeymasterHidlTest {
+  public:
+    virtual void SetUp() override {
+        KeymasterHidlTest::SetUp();
+
+        // Generate a key.
+        auto ec = GenerateKey(AuthorizationSetBuilder()
+                                      .Authorization(TAG_NO_AUTH_REQUIRED)
+                                      .EcdsaSigningKey(EcCurve::P_256)
+                                      .Digest(Digest::SHA_2_256));
+        ASSERT_EQ(ec, ErrorCode::OK) << "Failed to generate key.";
+
+        // Generate attestation.
+        hidl_vec<hidl_vec<uint8_t>> cert_chain;
+        ec = AttestKey(AuthorizationSetBuilder()
+                               .Authorization(TAG_ATTESTATION_CHALLENGE, HidlBuf("challenge"))
+                               .Authorization(TAG_ATTESTATION_APPLICATION_ID, HidlBuf("foo")),
+                       &cert_chain);
+        ASSERT_EQ(ec, ErrorCode::OK) << "Failed to generate attestation.";
+
+        X509_Ptr cert(parse_cert_blob(cert_chain[0]));
+        ASSERT_TRUE(cert.get()) << "Failed to parse certificate blob.";
+
+        ASN1_OCTET_STRING* attest_rec = get_attestation_record(cert.get());
+        ASSERT_TRUE(attest_rec) << "Failed to get attestation record.";
+
+        // Parse root of trust.
+        auto result = parse_root_of_trust(attest_rec->data, attest_rec->length, &attestedVbKey_,
+                                          &attestedVbState_, &attestedBootloaderState_,
+                                          &attestedVbmetaDigest_);
+        ASSERT_EQ(result, ErrorCode::OK) << "Failed to parse root of trust.";
+    }
+
+    hidl_vec<uint8_t> attestedVbKey_;
+    keymaster_verified_boot_t attestedVbState_;
+    bool attestedBootloaderState_;
+    hidl_vec<uint8_t> attestedVbmetaDigest_;
+};
+
+// Check that attested bootloader state is set to unlocked.
+TEST_P(BootloaderStateTest, BootloaderIsUnlocked) {
+    ASSERT_FALSE(attestedBootloaderState_)
+            << "This test runs as root. Bootloader must be unlocked.";
+}
+
+// Check that verified boot state is set to "unverified", i.e. "orange".
+TEST_P(BootloaderStateTest, VbStateIsUnverified) {
+    // Unlocked bootloader implies that verified boot state must be "unverified".
+    ASSERT_EQ(attestedVbState_, KM_VERIFIED_BOOT_UNVERIFIED)
+            << "Verified boot state must be \"UNVERIFIED\" aka \"orange\".";
+
+    // AVB spec stipulates that bootloader must set "androidboot.verifiedbootstate" parameter
+    // on the kernel command-line. This parameter is exposed to userspace as
+    // "ro.boot.verifiedbootstate" property.
+    auto vbStateProp = ::android::base::GetProperty("ro.boot.verifiedbootstate", "");
+    ASSERT_EQ(vbStateProp, "orange")
+            << "Verified boot state must be \"UNVERIFIED\" aka \"orange\".";
+}
+
+// Following error codes from avb_slot_data() mean that slot data was loaded
+// (even if verification failed).
+static inline bool avb_slot_data_loaded(AvbSlotVerifyResult result) {
+    switch (result) {
+        case AVB_SLOT_VERIFY_RESULT_OK:
+        case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION:
+        case AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX:
+        case AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED:
+            return true;
+        default:
+            return false;
+    }
+}
+
+// Check that attested vbmeta digest is correct.
+TEST_P(BootloaderStateTest, VbmetaDigest) {
+    AvbSlotVerifyData* avbSlotData;
+    auto suffix = fs_mgr_get_slot_suffix();
+    const char* partitions[] = {nullptr};
+    auto avbOps = avb_ops_user_new();
+
+    // For VTS, devices run with vendor_boot-debug.img, which is not release key
+    // signed. Use AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR to bypass avb
+    // verification errors. This is OK since we only care about the digest for
+    // this test case.
+    auto result = avb_slot_verify(avbOps, partitions, suffix.c_str(),
+                                  AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
+                                  AVB_HASHTREE_ERROR_MODE_EIO, &avbSlotData);
+    ASSERT_TRUE(avb_slot_data_loaded(result)) << "Failed to load avb slot data";
+
+    // Unfortunately, bootloader is not required to report the algorithm used
+    // to calculate the digest. There are only two supported options though,
+    // SHA256 and SHA512. Attested VBMeta digest must match one of these.
+    vector<uint8_t> digest256(AVB_SHA256_DIGEST_SIZE);
+    vector<uint8_t> digest512(AVB_SHA512_DIGEST_SIZE);
+
+    avb_slot_verify_data_calculate_vbmeta_digest(avbSlotData, AVB_DIGEST_TYPE_SHA256,
+                                                 digest256.data());
+    avb_slot_verify_data_calculate_vbmeta_digest(avbSlotData, AVB_DIGEST_TYPE_SHA512,
+                                                 digest512.data());
+
+    ASSERT_TRUE((attestedVbmetaDigest_ == digest256) || (attestedVbmetaDigest_ == digest512))
+            << "Attested digest does not match computed digest.";
+}
+
+INSTANTIATE_KEYMASTER_HIDL_TEST(BootloaderStateTest);
+
+}  // namespace android::hardware::keymaster::V4_0::test
diff --git a/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp b/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp
index 315a4bd..e2ad0ef 100644
--- a/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp
+++ b/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp
@@ -841,6 +841,30 @@
     return {};
 }
 
+X509* parse_cert_blob(const hidl_vec<uint8_t>& blob) {
+    const uint8_t* p = blob.data();
+    return d2i_X509(nullptr, &p, blob.size());
+}
+
+ASN1_OCTET_STRING* get_attestation_record(X509* certificate) {
+    ASN1_OBJECT_Ptr oid(OBJ_txt2obj(kAttestionRecordOid, 1 /* dotted string format */));
+    EXPECT_TRUE(!!oid.get());
+    if (!oid.get()) return nullptr;
+
+    int location = X509_get_ext_by_OBJ(certificate, oid.get(), -1 /* search from beginning */);
+    EXPECT_NE(-1, location) << "Attestation extension not found in certificate";
+    if (location == -1) return nullptr;
+
+    X509_EXTENSION* attest_rec_ext = X509_get_ext(certificate, location);
+    EXPECT_TRUE(!!attest_rec_ext)
+            << "Found attestation extension but couldn't retrieve it?  Probably a BoringSSL bug.";
+    if (!attest_rec_ext) return nullptr;
+
+    ASN1_OCTET_STRING* attest_rec = X509_EXTENSION_get_data(attest_rec_ext);
+    EXPECT_TRUE(!!attest_rec) << "Attestation extension contained no data";
+    return attest_rec;
+}
+
 }  // namespace test
 }  // namespace V4_0
 }  // namespace keymaster
diff --git a/keymaster/4.0/vts/functional/KeymasterHidlTest.h b/keymaster/4.0/vts/functional/KeymasterHidlTest.h
index ad30aa7..67829ec 100644
--- a/keymaster/4.0/vts/functional/KeymasterHidlTest.h
+++ b/keymaster/4.0/vts/functional/KeymasterHidlTest.h
@@ -22,7 +22,9 @@
 #include <hidl/GtestPrinter.h>
 #include <hidl/ServiceManagement.h>
 
+#include <keymasterV4_0/attestation_record.h>
 #include <keymasterV4_0/authorization_set.h>
+#include <keymasterV4_0/openssl_utils.h>
 
 namespace android {
 namespace hardware {
@@ -241,6 +243,11 @@
                              testing::ValuesIn(KeymasterHidlTest::build_params()), \
                              android::hardware::PrintInstanceNameToString)
 
+X509* parse_cert_blob(const hidl_vec<uint8_t>& blob);
+// Extract attestation record from cert. Returned object is still part of cert; don't free it
+// separately.
+ASN1_OCTET_STRING* get_attestation_record(X509* certificate);
+
 }  // namespace test
 }  // namespace V4_0
 }  // namespace keymaster
diff --git a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
index 728cc91..96580c0 100644
--- a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
+++ b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
@@ -263,11 +263,6 @@
     void operator()(RSA* p) { RSA_free(p); }
 };
 
-X509* parse_cert_blob(const hidl_vec<uint8_t>& blob) {
-    const uint8_t* p = blob.data();
-    return d2i_X509(nullptr, &p, blob.size());
-}
-
 bool verify_chain(const hidl_vec<hidl_vec<uint8_t>>& chain, const std::string& msg,
                   const std::string& signature) {
     {
@@ -337,27 +332,6 @@
     return true;
 }
 
-// Extract attestation record from cert. Returned object is still part of cert; don't free it
-// separately.
-ASN1_OCTET_STRING* get_attestation_record(X509* certificate) {
-    ASN1_OBJECT_Ptr oid(OBJ_txt2obj(kAttestionRecordOid, 1 /* dotted string format */));
-    EXPECT_TRUE(!!oid.get());
-    if (!oid.get()) return nullptr;
-
-    int location = X509_get_ext_by_OBJ(certificate, oid.get(), -1 /* search from beginning */);
-    EXPECT_NE(-1, location) << "Attestation extension not found in certificate";
-    if (location == -1) return nullptr;
-
-    X509_EXTENSION* attest_rec_ext = X509_get_ext(certificate, location);
-    EXPECT_TRUE(!!attest_rec_ext)
-        << "Found attestation extension but couldn't retrieve it?  Probably a BoringSSL bug.";
-    if (!attest_rec_ext) return nullptr;
-
-    ASN1_OCTET_STRING* attest_rec = X509_EXTENSION_get_data(attest_rec_ext);
-    EXPECT_TRUE(!!attest_rec) << "Attestation extension contained no data";
-    return attest_rec;
-}
-
 bool tag_in_list(const KeyParameter& entry) {
     // Attestations don't contain everything in key authorization lists, so we need to filter
     // the key lists to produce the lists that we expect to match the attestations.
@@ -2475,10 +2449,11 @@
     EVP_PKEY_Ptr pkey(d2i_PUBKEY(nullptr /* alloc new */, &p, exported.size()));
     RSA_Ptr rsa(EVP_PKEY_get1_RSA(pkey.get()));
 
-    size_t modulus_len = BN_num_bytes(rsa->n);
+    const BIGNUM* n = RSA_get0_n(rsa.get());
+    size_t modulus_len = BN_num_bytes(n);
     ASSERT_EQ(2048U / 8, modulus_len);
     std::unique_ptr<uint8_t[]> modulus_buf(new uint8_t[modulus_len]);
-    BN_bn2bin(rsa->n, modulus_buf.get());
+    BN_bn2bin(n, modulus_buf.get());
 
     // The modulus is too big to encrypt.
     string message(reinterpret_cast<const char*>(modulus_buf.get()), modulus_len);
@@ -2490,10 +2465,12 @@
     EXPECT_EQ(ErrorCode::INVALID_ARGUMENT, Finish(message, &result));
 
     // One smaller than the modulus is okay.
-    BN_sub(rsa->n, rsa->n, BN_value_one());
-    modulus_len = BN_num_bytes(rsa->n);
+    BIGNUM_Ptr n_minus_1(BN_new());
+    ASSERT_TRUE(n_minus_1);
+    ASSERT_TRUE(BN_sub(n_minus_1.get(), n, BN_value_one()));
+    modulus_len = BN_num_bytes(n_minus_1.get());
     ASSERT_EQ(2048U / 8, modulus_len);
-    BN_bn2bin(rsa->n, modulus_buf.get());
+    BN_bn2bin(n_minus_1.get(), modulus_buf.get());
     message = string(reinterpret_cast<const char*>(modulus_buf.get()), modulus_len);
     EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params));
     EXPECT_EQ(ErrorCode::OK, Finish(message, &result));
diff --git a/keymaster/TEST_MAPPING b/keymaster/TEST_MAPPING
new file mode 100644
index 0000000..8cbf3e1
--- /dev/null
+++ b/keymaster/TEST_MAPPING
@@ -0,0 +1,13 @@
+{
+  "presubmit": [
+    {
+      "name": "VtsHalKeymasterV3_0TargetTest"
+    },
+    {
+      "name": "VtsHalKeymasterV4_0TargetTest"
+    },
+    {
+      "name": "VtsHalKeymasterV4_1TargetTest"
+    }
+  ]
+}
diff --git a/media/bufferpool/aidl/Android.bp b/media/bufferpool/aidl/Android.bp
index 68ac489..5ea2948 100644
--- a/media/bufferpool/aidl/Android.bp
+++ b/media/bufferpool/aidl/Android.bp
@@ -24,6 +24,7 @@
 aidl_interface {
     name: "android.hardware.media.bufferpool2",
     vendor_available: true,
+    double_loadable: true,
     srcs: ["android/hardware/media/bufferpool2/*.aidl"],
     imports: [
         "android.hardware.common-V2",
diff --git a/media/c2/aidl/Android.bp b/media/c2/aidl/Android.bp
index 3393ede..75d74ac 100644
--- a/media/c2/aidl/Android.bp
+++ b/media/c2/aidl/Android.bp
@@ -12,9 +12,10 @@
 aidl_interface {
     name: "android.hardware.media.c2",
     vendor_available: true,
+    double_loadable: true,
     srcs: ["android/hardware/media/c2/*.aidl"],
     include_dirs: [
-        "frameworks/native/aidl/gui",
+        "frameworks/base/core/java",
     ],
     imports: [
         "android.hardware.common-V2",
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FieldDescriptor.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FieldDescriptor.aidl
index d0e4cbf..909476c 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FieldDescriptor.aidl
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FieldDescriptor.aidl
@@ -43,16 +43,16 @@
   @Backing(type="int") @VintfStability
   enum Type {
     NO_INIT = 0,
-    INT32 = 1,
-    UINT32 = 2,
-    CNTR32 = 3,
-    INT64 = 4,
-    UINT64 = 5,
-    CNTR64 = 6,
-    FLOAT = 7,
-    STRING = 256,
-    BLOB = 257,
-    STRUCT = 131072,
+    INT32,
+    UINT32,
+    CNTR32,
+    INT64,
+    UINT64,
+    CNTR64,
+    FLOAT,
+    STRING = 0x100,
+    BLOB,
+    STRUCT = 0x20000,
   }
   @VintfStability
   parcelable NamedValue {
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FieldSupportedValuesQuery.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FieldSupportedValuesQuery.aidl
index 22f7c84..6a5fbe2 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FieldSupportedValuesQuery.aidl
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FieldSupportedValuesQuery.aidl
@@ -39,6 +39,6 @@
   @Backing(type="int") @VintfStability
   enum Type {
     POSSIBLE = 0,
-    CURRENT = 1,
+    CURRENT,
   }
 }
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FrameData.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FrameData.aidl
index e73b05e..07bfb72 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FrameData.aidl
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FrameData.aidl
@@ -39,9 +39,9 @@
   android.hardware.media.c2.Buffer[] buffers;
   android.hardware.media.c2.Params configUpdate;
   android.hardware.media.c2.InfoBuffer[] infoBuffers;
-  const int DROP_FRAME = 1;
-  const int END_OF_STREAM = 2;
-  const int DISCARD_FRAME = 4;
-  const int FLAG_INCOMPLETE = 8;
-  const int CODEC_CONFIG = -2147483648;
+  const int DROP_FRAME = (1 << 0) /* 1 */;
+  const int END_OF_STREAM = (1 << 1) /* 2 */;
+  const int DISCARD_FRAME = (1 << 2) /* 4 */;
+  const int FLAG_INCOMPLETE = (1 << 3) /* 8 */;
+  const int CODEC_CONFIG = (1 << 31) /* -2147483648 */;
 }
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponent.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponent.aidl
index 7ed09af..1af66d0 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponent.aidl
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponent.aidl
@@ -43,7 +43,7 @@
   void queue(in android.hardware.media.c2.WorkBundle workBundle);
   void release();
   void reset();
-  void setOutputSurface(in long blockPoolId, in android.view.Surface surface, in android.hardware.media.c2.SurfaceSyncObj syncObject);
+  void setDecoderOutputAllocator(in android.hardware.media.c2.IGraphicBufferAllocator allocator);
   void start();
   void stop();
   parcelable BlockPool {
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponentStore.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponentStore.aidl
index 35532be..d1b5915 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponentStore.aidl
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponentStore.aidl
@@ -52,15 +52,15 @@
     @Backing(type="int") @VintfStability
     enum Kind {
       OTHER = 0,
-      DECODER = 1,
-      ENCODER = 2,
+      DECODER,
+      ENCODER,
     }
     @Backing(type="int") @VintfStability
     enum Domain {
       OTHER = 0,
-      VIDEO = 1,
-      AUDIO = 2,
-      IMAGE = 3,
+      VIDEO,
+      AUDIO,
+      IMAGE,
     }
   }
 }
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IGraphicBufferAllocator.aidl
similarity index 72%
copy from media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
copy to media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IGraphicBufferAllocator.aidl
index 1c9bf8d..da3d5ff 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IGraphicBufferAllocator.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2023 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.
@@ -33,9 +33,22 @@
 
 package android.hardware.media.c2;
 @VintfStability
-parcelable SurfaceSyncObj {
-  android.hardware.common.NativeHandle syncMemory;
-  long bqId;
-  int generationId;
-  long consumerUsage;
+interface IGraphicBufferAllocator {
+  android.hardware.media.c2.IGraphicBufferAllocator.Allocation allocate(in android.hardware.media.c2.IGraphicBufferAllocator.Description desc);
+  boolean deallocate(in long id);
+  android.hardware.media.c2.IGraphicBufferAllocator.WaitableFds getWaitableFds();
+  parcelable Allocation {
+    android.hardware.HardwareBuffer buffer;
+    ParcelFileDescriptor fence;
+  }
+  parcelable Description {
+    int width;
+    int height;
+    int format;
+    long usage;
+  }
+  parcelable WaitableFds {
+    ParcelFileDescriptor allocEvent;
+    ParcelFileDescriptor statusEvent;
+  }
 }
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/ParamDescriptor.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/ParamDescriptor.aidl
index 04c869c..6f0ac50 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/ParamDescriptor.aidl
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/ParamDescriptor.aidl
@@ -38,11 +38,11 @@
   int attrib;
   String name;
   int[] dependencies;
-  const int ATTRIBUTE_REQUIRED = 1;
-  const int ATTRIBUTE_PERSISTENT = 2;
-  const int ATTRIBUTE_STRICT = 4;
-  const int ATTRIBUTE_READ_ONLY = 8;
-  const int ATTRIBUTE_HIDDEN = 16;
-  const int ATTRIBUTE_INTERNAL = 32;
-  const int ATTRIBUTE_CONST = 64;
+  const int ATTRIBUTE_REQUIRED = (1 << 0) /* 1 */;
+  const int ATTRIBUTE_PERSISTENT = (1 << 1) /* 2 */;
+  const int ATTRIBUTE_STRICT = (1 << 2) /* 4 */;
+  const int ATTRIBUTE_READ_ONLY = (1 << 3) /* 8 */;
+  const int ATTRIBUTE_HIDDEN = (1 << 4) /* 16 */;
+  const int ATTRIBUTE_INTERNAL = (1 << 5) /* 32 */;
+  const int ATTRIBUTE_CONST = (1 << 6) /* 64 */;
 }
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SettingResult.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SettingResult.aidl
index f9e6a93..07fc1f3 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SettingResult.aidl
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SettingResult.aidl
@@ -39,15 +39,15 @@
   android.hardware.media.c2.ParamFieldValues[] conflicts;
   @Backing(type="int") @VintfStability
   enum Failure {
-    BAD_TYPE = 0,
-    BAD_PORT = 1,
-    BAD_INDEX = 2,
-    READ_ONLY = 3,
-    MISMATCH = 4,
-    BAD_VALUE = 5,
-    CONFLICT = 6,
-    UNSUPPORTED = 7,
-    INFO_BAD_VALUE = 8,
-    INFO_CONFLICT = 9,
+    BAD_TYPE,
+    BAD_PORT,
+    BAD_INDEX,
+    READ_ONLY,
+    MISMATCH,
+    BAD_VALUE,
+    CONFLICT,
+    UNSUPPORTED,
+    INFO_BAD_VALUE,
+    INFO_CONFLICT,
   }
 }
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/Status.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/Status.aidl
index ad07677..8b430d2 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/Status.aidl
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/Status.aidl
@@ -36,17 +36,17 @@
 parcelable Status {
   int status;
   const int OK = 0;
-  const int BAD_VALUE = -22;
-  const int BAD_INDEX = -75;
-  const int CANNOT_DO = -2147483646;
-  const int DUPLICATE = -17;
-  const int NOT_FOUND = -2;
-  const int BAD_STATE = -38;
-  const int BLOCKING = -9930;
-  const int NO_MEMORY = -12;
-  const int REFUSED = -1;
-  const int TIMED_OUT = -110;
-  const int OMITTED = -74;
-  const int CORRUPTED = -2147483648;
-  const int NO_INIT = -19;
+  const int BAD_VALUE = (-22) /* -22 */;
+  const int BAD_INDEX = (-75) /* -75 */;
+  const int CANNOT_DO = (-2147483646) /* -2147483646 */;
+  const int DUPLICATE = (-17) /* -17 */;
+  const int NOT_FOUND = (-2) /* -2 */;
+  const int BAD_STATE = (-38) /* -38 */;
+  const int BLOCKING = (-9930) /* -9930 */;
+  const int NO_MEMORY = (-12) /* -12 */;
+  const int REFUSED = (-1) /* -1 */;
+  const int TIMED_OUT = (-110) /* -110 */;
+  const int OMITTED = (-74) /* -74 */;
+  const int CORRUPTED = (-2147483648) /* -2147483648 */;
+  const int NO_INIT = (-19) /* -19 */;
 }
diff --git a/media/c2/aidl/android/hardware/media/c2/IComponent.aidl b/media/c2/aidl/android/hardware/media/c2/IComponent.aidl
index b3390c3..a9fddbb 100644
--- a/media/c2/aidl/android/hardware/media/c2/IComponent.aidl
+++ b/media/c2/aidl/android/hardware/media/c2/IComponent.aidl
@@ -17,12 +17,10 @@
 package android.hardware.media.c2;
 
 import android.hardware.common.NativeHandle;
-import android.view.Surface;
-
 import android.hardware.media.c2.IComponentInterface;
 import android.hardware.media.c2.IConfigurable;
+import android.hardware.media.c2.IGraphicBufferAllocator;
 import android.hardware.media.c2.WorkBundle;
-import android.hardware.media.c2.SurfaceSyncObj;
 
 /**
  * Interface for an AIDL Codec2 component.
@@ -234,23 +232,15 @@
     void reset();
 
     /**
-     * Starts using a surface for output with a synchronization object
+     * Specify an allocator for decoder output buffer from HAL.
      *
-     * This method must not block.
-     *
-     * @param blockPoolId Id of the `C2BlockPool` to be associated with the
-     *     output surface.
-     * @param surface Output surface.
-     * @param syncObject synchronization object for buffer allocation between
-     *     Framework and Component.
-     * @throws ServiceSpecificException with one of the following values:
-     *   - `Status::CANNOT_DO` - The component does not support an output surface.
-     *   - `Status::REFUSED`   - The output surface cannot be accessed.
-     *   - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+     * The method will be used once during the life-cycle of a codec instance.
+     * @param allocator Decoder output buffer allocator from the client
+     * @throws ServiceSpecificException with one of the following values
+     *   - `Status::CANNOT_DO` - The component does not support allocating from the client.
      *   - `Status::CORRUPTED` - Some unknown error occurred.
      */
-    void setOutputSurface(in long blockPoolId, in Surface surface,
-        in SurfaceSyncObj syncObject);
+    void setDecoderOutputAllocator(in IGraphicBufferAllocator allocator);
 
     /**
      * Starts the component.
diff --git a/media/c2/aidl/android/hardware/media/c2/IGraphicBufferAllocator.aidl b/media/c2/aidl/android/hardware/media/c2/IGraphicBufferAllocator.aidl
new file mode 100644
index 0000000..1c97214
--- /dev/null
+++ b/media/c2/aidl/android/hardware/media/c2/IGraphicBufferAllocator.aidl
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+import android.hardware.HardwareBuffer;
+import android.os.ParcelFileDescriptor;
+
+/**
+ * Interface for decoder output buffer allocator for HAL process
+ *
+ * A graphic buffer for decoder output is allocated by the interface.
+ */
+@VintfStability
+interface IGraphicBufferAllocator {
+    /**
+     * A graphic buffer allocation.
+     *
+     * buffer is in android.hardware.HardwareBuffer.
+     * fence is provided in order to signal readiness of the buffer I/O inside
+     * underlying Graphics subsystem. This is called a sync fence throughout Android framework.
+     */
+    parcelable Allocation {
+        HardwareBuffer buffer;
+        ParcelFileDescriptor fence;
+    }
+
+    /**
+     * Parameters for a graphic buffer allocation.
+     *
+     * Refer to AHardwareBuffer_Desc(libnativewindow) for details.
+     */
+    parcelable Description {
+        int width;
+        int height;
+        int format;
+        long usage;
+    }
+
+    /**
+     * Allocate a graphic buffer.
+     *
+     * @param desc Allocation parameters.
+     * @return an android.hardware.HardwareBuffer which is basically same to
+     *     AHardwareBuffer. If underlying grpahics system is blocked, c2::Status::Blocked
+     *     will be returned. In this case getWaitableFds() will return file descriptors which
+     *     can be used to construct a waitable object. The waitable object will be notified
+     *     when underlying graphics system is unblocked
+     * @throws ServiceSpecificException with one of the following values:
+     *   - `c2::Status::BAD_STATE` - The client is not in running states.
+     *   - `c2::Status::BLOCKED`   - Underlying graphics system is blocked.
+     *   - `c2::Status::CORRUPTED` - Some unknown error occurred.
+     */
+    Allocation allocate(in Description desc);
+
+    /**
+     * De-allocate a graphic buffer by graphic buffer's unique id.
+     *
+     * @param id graphic buffer's unique id. See also AHardwareBuffer_getId().
+     * @return {@code true} when de-allocate happened, {@code false} otherwise.
+     */
+    boolean deallocate(in long id);
+
+    /**
+     * Fds for waitable object events.
+     *
+     * Fds are created by eventfd() with semaphore mode.
+     * For allocEvent, An integer counter regarding dequeuable buffer count is maintained
+     * by client using read()/write() to the fd. The fd can be checked whether it is
+     * readable via poll(). When in readable status, the specified counter is positive
+     * so allocate/dequeue can happen.
+     *
+     * For statusEvent, the client can notify further allocation is not feasible.
+     * e.g.) life-cycle of the underlying allocator is ended.
+     *
+     * C2Fence object should be implemented based on this Fds. Thus, C2Fence can return
+     * either by allocation being ready or allocation being infeasible by the client status
+     * change.
+     */
+    parcelable WaitableFds {
+        ParcelFileDescriptor allocEvent;
+        ParcelFileDescriptor statusEvent;
+    }
+
+    /**
+     * Gets waiable file descriptors.
+     *
+     * Use this method once and cache it in order not to create unnecessary duplicated fds.
+     * The returned array will have two fds.
+     *
+     * If many waitable objects based on the same fd are competing, all watiable objects will be
+     * notified. After being notified, they should invoke allocate(). At least one of them can
+     * successfully allocate. Others not having an Allocation will have c2::Status::BLOCKED
+     * as return value. They should wait again via waitable objects based on the fds which are
+     * already returned from this interface.
+     *
+     * @return an fd array which will be wrapped to C2Fence and will be waited for
+     *     until allocating is unblocked.
+     */
+    WaitableFds getWaitableFds();
+}
diff --git a/media/c2/aidl/android/hardware/media/c2/SurfaceSyncObj.aidl b/media/c2/aidl/android/hardware/media/c2/SurfaceSyncObj.aidl
deleted file mode 100644
index d20e102..0000000
--- a/media/c2/aidl/android/hardware/media/c2/SurfaceSyncObj.aidl
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.media.c2;
-
-import android.hardware.common.NativeHandle;
-/**
- * Surface(BufferQueue/IGBP) synchronization object regarding # of dequeued
- * output buffers. This keeps # of dequeued buffers from Surface less than
- * configured max # of dequeued buffers all the time.
- */
-@VintfStability
-parcelable SurfaceSyncObj {
-    /**
-     * ASharedMemory for synchronization data. Layout is below
-     *
-     * |lock(futex)                               4bytes|
-     * |conditional_variable(futex)               4bytes|
-     * |# of max dequeable buffer                 4bytes|
-     * |# of dequeued buffer                      4bytes|
-     * |Status of the surface                     4bytes|
-     *      INIT        = 0, Configuring surface is not finished.
-     *      ACTIVE      = 1, Surface is ready to allocate(dequeue).
-     *      SWITCHING   = 2, Switching to the new surface. It is blocked
-     *                       to allocate(dequeue) a buffer until switching
-     *                       completes.
-     */
-    NativeHandle syncMemory;
-    /**
-     * BufferQueue id.
-     */
-    long bqId;
-    /**
-     * Generation id.
-     */
-    int generationId;
-    /**
-     * Consumer usage flags. See +ndk
-     * libnativewindow#AHardwareBuffer_UsageFlags for possible values.
-     */
-    long consumerUsage;
-}
diff --git a/neuralnetworks/1.0/Android.bp b/neuralnetworks/1.0/Android.bp
index 7bc65ff..8b7af11 100644
--- a/neuralnetworks/1.0/Android.bp
+++ b/neuralnetworks/1.0/Android.bp
@@ -23,4 +23,8 @@
         "android.hidl.base@1.0",
     ],
     gen_java: false,
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.neuralnetworks",
+    ],
 }
diff --git a/neuralnetworks/1.1/Android.bp b/neuralnetworks/1.1/Android.bp
index 772e5e6..b93c80c 100644
--- a/neuralnetworks/1.1/Android.bp
+++ b/neuralnetworks/1.1/Android.bp
@@ -21,4 +21,8 @@
         "android.hidl.base@1.0",
     ],
     gen_java: false,
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.neuralnetworks",
+    ],
 }
diff --git a/neuralnetworks/1.2/Android.bp b/neuralnetworks/1.2/Android.bp
index 2b83d39..63e0f61 100644
--- a/neuralnetworks/1.2/Android.bp
+++ b/neuralnetworks/1.2/Android.bp
@@ -28,4 +28,8 @@
         "android.hidl.safe_union@1.0",
     ],
     gen_java: false,
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.neuralnetworks",
+    ],
 }
diff --git a/neuralnetworks/1.3/Android.bp b/neuralnetworks/1.3/Android.bp
index aa8fc39..c343802 100644
--- a/neuralnetworks/1.3/Android.bp
+++ b/neuralnetworks/1.3/Android.bp
@@ -29,4 +29,8 @@
         "android.hidl.safe_union@1.0",
     ],
     gen_java: false,
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.neuralnetworks",
+    ],
 }
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_data.cpp b/radio/1.0/vts/functional/radio_hidl_hal_data.cpp
index 655b869..38cb33b 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_data.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_data.cpp
@@ -87,12 +87,19 @@
                                                  cellIdentities.cellIdentityTdscdma.size());
 
         if (checkMccMnc) {
-            // 32 bit system gets result: "\xff\xff\xff..." from RIL, which is not testable. Only
-            // test for 64 bit here. TODO: remove this limit after b/113181277 being fixed.
-            if (hidl_mcc.size() < 4 && hidl_mnc.size() < 4) {
+            // 32 bit system gets result: "\xff\xff\xff..." from RIL, which is not testable.
+            // Only test for 64 bit here. TODO: remove this limit after b/113181277 being fixed.
+            int mccSize = hidl_mcc.size();
+            EXPECT_TRUE(mccSize == 0 || mccSize == 3);
+            if (mccSize > 0) {
                 int mcc = stoi(hidl_mcc);
-                int mnc = stoi(hidl_mnc);
                 EXPECT_TRUE(mcc >= 0 && mcc <= 999);
+            }
+
+            int mncSize = hidl_mnc.size();
+            EXPECT_TRUE(mncSize == 0 || mncSize == 2 || mncSize == 3);
+            if (mncSize > 0) {
+                int mnc = stoi(hidl_mnc);
                 EXPECT_TRUE(mnc >= 0 && mnc <= 999);
             }
         }
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp b/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp
index 624d003..ee8b4dc 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp
@@ -654,6 +654,8 @@
         ASSERT_TRUE(CheckAnyOfErrors(radioRsp->rspInfo.error,
                                      {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
     }
+    // wait until modem reset finishes
+    sleep(10);
     LOG(DEBUG) << "nvResetConfig finished";
 }
 
diff --git a/radio/1.0/vts/functional/vts_hal_radio_target_test.xml b/radio/1.0/vts/functional/vts_hal_radio_target_test.xml
index 82af2ee..7aaadff 100644
--- a/radio/1.0/vts/functional/vts_hal_radio_target_test.xml
+++ b/radio/1.0/vts/functional/vts_hal_radio_target_test.xml
@@ -16,6 +16,7 @@
 <configuration description="Runs VtsHalRadioV1_0TargetTest.">
     <option name="test-suite-tag" value="apct" />
     <option name="test-suite-tag" value="apct-native" />
+    <option name="config-descriptor:metadata" key="token" value="SIM_CARD" />
 
     <!-- TODO: b/154638140, b/152655658: bad interactions -->
     <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" />
diff --git a/radio/1.1/vts/functional/AndroidTest.xml b/radio/1.1/vts/functional/AndroidTest.xml
index f1bc7a8..90428f4 100644
--- a/radio/1.1/vts/functional/AndroidTest.xml
+++ b/radio/1.1/vts/functional/AndroidTest.xml
@@ -16,6 +16,7 @@
 <configuration description="Runs VtsHalRadioV1_1TargetTest.">
     <option name="test-suite-tag" value="apct" />
     <option name="test-suite-tag" value="apct-native" />
+    <option name="config-descriptor:metadata" key="token" value="SIM_CARD" />
 
     <!-- TODO: b/154638140, b/152655658: bad interactions -->
     <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" />
diff --git a/radio/1.2/vts/functional/AndroidTest.xml b/radio/1.2/vts/functional/AndroidTest.xml
index 9904760..e25249b 100644
--- a/radio/1.2/vts/functional/AndroidTest.xml
+++ b/radio/1.2/vts/functional/AndroidTest.xml
@@ -16,6 +16,7 @@
 <configuration description="Runs VtsHalRadioV1_2TargetTest.">
     <option name="test-suite-tag" value="apct" />
     <option name="test-suite-tag" value="apct-native" />
+    <option name="config-descriptor:metadata" key="token" value="SIM_CARD" />
 
     <!-- TODO: b/154638140, b/152655658: bad interactions -->
     <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" />
diff --git a/radio/1.2/vts/functional/radio_hidl_hal_api.cpp b/radio/1.2/vts/functional/radio_hidl_hal_api.cpp
index 2400bde..2bce2f9 100644
--- a/radio/1.2/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.2/vts/functional/radio_hidl_hal_api.cpp
@@ -120,7 +120,7 @@
     serial = GetRandomSerialNumber();
 
     ::android::hardware::radio::V1_2::NetworkScanRequest request = {
-            .type = ScanType::ONE_SHOT,
+            .type = ScanType::PERIODIC,
             .interval = 4,
             .specifiers = {::GERAN_SPECIFIER_P900, ::GERAN_SPECIFIER_850},
             .maxSearchTime = 60,
@@ -155,7 +155,7 @@
     serial = GetRandomSerialNumber();
 
     ::android::hardware::radio::V1_2::NetworkScanRequest request = {
-            .type = ScanType::ONE_SHOT,
+            .type = ScanType::PERIODIC,
             .interval = 301,
             .specifiers = {::GERAN_SPECIFIER_P900, ::GERAN_SPECIFIER_850},
             .maxSearchTime = 60,
@@ -821,11 +821,20 @@
                   cellIdentities.cellIdentityTdscdma.size());
 
     // 32 bit system might return invalid mcc and mnc hidl string "\xff\xff..."
-    if (checkMccMnc && hidl_mcc.size() < 4 && hidl_mnc.size() < 4) {
-        int mcc = stoi(hidl_mcc);
-        int mnc = stoi(hidl_mnc);
-        EXPECT_TRUE(mcc >= 0 && mcc <= 999);
-        EXPECT_TRUE(mnc >= 0 && mnc <= 999);
+    if (checkMccMnc) {
+        int mccSize = hidl_mcc.size();
+        EXPECT_TRUE(mccSize == 0 || mccSize == 3);
+        if (mccSize > 0) {
+            int mcc = stoi(hidl_mcc);
+            EXPECT_TRUE(mcc >= 0 && mcc <= 999);
+        }
+
+        int mncSize = hidl_mnc.size();
+        EXPECT_TRUE(mncSize == 0 || mncSize == 2 || mncSize == 3);
+        if (mncSize > 0) {
+            int mnc = stoi(hidl_mnc);
+            EXPECT_TRUE(mnc >= 0 && mnc <= 999);
+        }
     }
 }
 
diff --git a/radio/1.3/vts/functional/AndroidTest.xml b/radio/1.3/vts/functional/AndroidTest.xml
index 9df8f9c..44b7419 100644
--- a/radio/1.3/vts/functional/AndroidTest.xml
+++ b/radio/1.3/vts/functional/AndroidTest.xml
@@ -16,6 +16,7 @@
 <configuration description="Runs VtsHalRadioV1_3TargetTest.">
     <option name="test-suite-tag" value="apct" />
     <option name="test-suite-tag" value="apct-native" />
+    <option name="config-descriptor:metadata" key="token" value="SIM_CARD" />
 
     <!-- TODO: b/154638140, b/152655658: bad interactions -->
     <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" />
diff --git a/radio/1.4/vts/functional/AndroidTest.xml b/radio/1.4/vts/functional/AndroidTest.xml
index 469e103..d0843e6 100644
--- a/radio/1.4/vts/functional/AndroidTest.xml
+++ b/radio/1.4/vts/functional/AndroidTest.xml
@@ -16,6 +16,7 @@
 <configuration description="Runs VtsHalRadioV1_4TargetTest.">
     <option name="test-suite-tag" value="apct" />
     <option name="test-suite-tag" value="apct-native" />
+    <option name="config-descriptor:metadata" key="token" value="SIM_CARD" />
 
     <!-- TODO: b/154638140, b/152655658: bad interactions -->
     <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" />
diff --git a/radio/1.4/vts/functional/radio_hidl_hal_api.cpp b/radio/1.4/vts/functional/radio_hidl_hal_api.cpp
index 8f357a0..744af75 100644
--- a/radio/1.4/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.4/vts/functional/radio_hidl_hal_api.cpp
@@ -335,7 +335,7 @@
     serial = GetRandomSerialNumber();
 
     ::android::hardware::radio::V1_2::NetworkScanRequest request = {
-            .type = ScanType::ONE_SHOT,
+            .type = ScanType::PERIODIC,
             .interval = 4,
             .specifiers = {::GERAN_SPECIFIER_P900, ::GERAN_SPECIFIER_850},
             .maxSearchTime = 60,
@@ -368,7 +368,7 @@
     serial = GetRandomSerialNumber();
 
     ::android::hardware::radio::V1_2::NetworkScanRequest request = {
-            .type = ScanType::ONE_SHOT,
+            .type = ScanType::PERIODIC,
             .interval = 301,
             .specifiers = {::GERAN_SPECIFIER_P900, ::GERAN_SPECIFIER_850},
             .maxSearchTime = 60,
diff --git a/radio/1.5/vts/functional/radio_hidl_hal_api.cpp b/radio/1.5/vts/functional/radio_hidl_hal_api.cpp
index 316c308..fd44e93 100644
--- a/radio/1.5/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.5/vts/functional/radio_hidl_hal_api.cpp
@@ -661,7 +661,7 @@
             .channels = {128, 129}};
 
     ::android::hardware::radio::V1_5::NetworkScanRequest request = {
-            .type = ScanType::ONE_SHOT,
+            .type = ScanType::PERIODIC,
             .interval = 4,
             .specifiers = {specifierP900, specifier850},
             .maxSearchTime = 60,
@@ -705,7 +705,7 @@
             .channels = {128, 129}};
 
     ::android::hardware::radio::V1_5::NetworkScanRequest request = {
-            .type = ScanType::ONE_SHOT,
+            .type = ScanType::PERIODIC,
             .interval = 301,
             .specifiers = {specifierP900, specifier850},
             .maxSearchTime = 60,
diff --git a/radio/aidl/vts/AndroidTest.xml b/radio/aidl/vts/AndroidTest.xml
index 36381d1..7edc072 100644
--- a/radio/aidl/vts/AndroidTest.xml
+++ b/radio/aidl/vts/AndroidTest.xml
@@ -16,6 +16,7 @@
 <configuration description="Runs VtsHalRadioTargetTest.">
     <option name="test-suite-tag" value="apct" />
     <option name="test-suite-tag" value="apct-native" />
+    <option name="config-descriptor:metadata" key="token" value="SIM_CARD" />
 
     <target_preparer class="com.android.tradefed.targetprep.MultiSimPreparer" />
     <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
@@ -31,4 +32,4 @@
         <option name="native-test-timeout" value="300000" /> <!-- 5 min -->
         <option name="module-name" value="VtsHalRadioTargetTest" />
     </test>
-</configuration>
\ No newline at end of file
+</configuration>
diff --git a/radio/aidl/vts/radio_aidl_hal_utils.cpp b/radio/aidl/vts/radio_aidl_hal_utils.cpp
index 6ed8e7d..f18da55 100644
--- a/radio/aidl/vts/radio_aidl_hal_utils.cpp
+++ b/radio/aidl/vts/radio_aidl_hal_utils.cpp
@@ -85,7 +85,7 @@
     // Do not use checkSubstringInCommandOutput("getprop persist.radio.multisim.config", "")
     // until b/148904287 is fixed. We need exact matching instead of partial matching. (i.e.
     // by definition the empty string "" is a substring of any string).
-    return !isDsDsEnabled() && !isTsTsEnabled();
+    return !isDsDsEnabled() && !isTsTsEnabled() && !isDsDaEnabled();
 }
 
 bool isDsDsEnabled() {
@@ -125,8 +125,8 @@
             ALOGI("%s instance is not valid for SSSS device.", serviceName.c_str());
             return false;
         }
-    } else if (isDsDsEnabled()) {
-        // Device is configured as DSDS.
+    } else if (isDsDsEnabled() || isDsDaEnabled()) {
+        // Device is configured as DSDS or DSDA.
         if (!stringEndsWith(serviceName, RADIO_SERVICE_SLOT1_NAME) &&
             !stringEndsWith(serviceName, RADIO_SERVICE_SLOT2_NAME)) {
             ALOGI("%s instance is not valid for DSDS device.", serviceName.c_str());
diff --git a/radio/aidl/vts/radio_data_test.cpp b/radio/aidl/vts/radio_data_test.cpp
index aa6ac88..3eedc14 100644
--- a/radio/aidl/vts/radio_data_test.cpp
+++ b/radio/aidl/vts/radio_data_test.cpp
@@ -531,8 +531,7 @@
 
         ASSERT_TRUE(CheckAnyOfErrors(
                 radioRsp_data->rspInfo.error,
-                {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::INVALID_ARGUMENTS,
-                 RadioError::REQUEST_NOT_SUPPORTED}));
+                {RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED}));
     }
 }
 
@@ -549,8 +548,7 @@
 
     ASSERT_TRUE(
             CheckAnyOfErrors(radioRsp_data->rspInfo.error,
-                             {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
-                              RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED}));
+                             {RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED}));
 }
 
 /*
diff --git a/radio/aidl/vts/radio_modem_test.cpp b/radio/aidl/vts/radio_modem_test.cpp
index f88da13..e867378 100644
--- a/radio/aidl/vts/radio_modem_test.cpp
+++ b/radio/aidl/vts/radio_modem_test.cpp
@@ -264,6 +264,8 @@
         ASSERT_TRUE(CheckAnyOfErrors(radioRsp_modem->rspInfo.error,
                                      {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
     }
+    // wait until modem reset finishes
+    sleep(10);
     LOG(DEBUG) << "nvResetConfig finished";
 }
 
diff --git a/radio/aidl/vts/radio_network_test.cpp b/radio/aidl/vts/radio_network_test.cpp
index 61b34d7..95ab2b1 100644
--- a/radio/aidl/vts/radio_network_test.cpp
+++ b/radio/aidl/vts/radio_network_test.cpp
@@ -66,12 +66,20 @@
 }
 
 /*
- * Test IRadioNetwork.setAllowedNetworkTypesBitmap for the response returned.
+ * Test IRadioNetwork.setAllowedNetworkTypesBitmap and IRadioNetwork.getAllowedNetworkTypesBitmap
+ * for the response returned.
  */
-TEST_P(RadioNetworkTest, setAllowedNetworkTypesBitmap) {
+TEST_P(RadioNetworkTest, setGetAllowedNetworkTypesBitmap) {
     serial = GetRandomSerialNumber();
-    int32_t allowedNetworkTypesBitmap = static_cast<int32_t>(RadioAccessFamily::LTE);
 
+    // save current value
+    radio_network->getAllowedNetworkTypesBitmap(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    int32_t currentAllowedNetworkTypesBitmap = radioRsp_network->networkTypeBitmapResponse;
+
+    // set new value
+    int32_t allowedNetworkTypesBitmap = static_cast<int32_t>(RadioAccessFamily::LTE);
+    serial = GetRandomSerialNumber();
     radio_network->setAllowedNetworkTypesBitmap(serial, allowedNetworkTypesBitmap);
 
     EXPECT_EQ(std::cv_status::no_timeout, wait());
@@ -83,20 +91,6 @@
              RadioError::MODE_NOT_SUPPORTED, RadioError::INTERNAL_ERR, RadioError::MODEM_ERR,
              RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED,
              RadioError::NO_RESOURCES}));
-}
-
-/*
- * Test IRadioNetwork.getAllowedNetworkTypesBitmap for the response returned.
- */
-TEST_P(RadioNetworkTest, getAllowedNetworkTypesBitmap) {
-    serial = GetRandomSerialNumber();
-    int32_t allowedNetworkTypesBitmap = static_cast<int32_t>(RadioAccessFamily::LTE);
-
-    radio_network->setAllowedNetworkTypesBitmap(serial, allowedNetworkTypesBitmap);
-
-    EXPECT_EQ(std::cv_status::no_timeout, wait());
-    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
-    EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
 
     if (radioRsp_network->rspInfo.error == RadioError::NONE) {
         sleep(3);  // wait for modem
@@ -112,7 +106,16 @@
                  RadioError::OPERATION_NOT_ALLOWED, RadioError::MODE_NOT_SUPPORTED,
                  RadioError::INVALID_ARGUMENTS, RadioError::MODEM_ERR,
                  RadioError::REQUEST_NOT_SUPPORTED, RadioError::NO_RESOURCES}));
+        if (radioRsp_network->rspInfo.error == RadioError::NONE) {
+            // verify we get the value we set
+            ASSERT_EQ(radioRsp_network->networkTypeBitmapResponse, allowedNetworkTypesBitmap);
+        }
     }
+
+    // reset value to previous
+    serial = GetRandomSerialNumber();
+    radio_network->setAllowedNetworkTypesBitmap(serial, currentAllowedNetworkTypesBitmap);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
 }
 
 /*
@@ -920,7 +923,7 @@
     RadioAccessSpecifier specifier850 = {
             .accessNetwork = AccessNetwork::GERAN, .bands = band850, .channels = {128, 129}};
 
-    NetworkScanRequest request = {.type = NetworkScanRequest::SCAN_TYPE_ONE_SHOT,
+    NetworkScanRequest request = {.type = NetworkScanRequest::SCAN_TYPE_PERIODIC,
                                   .interval = 4,
                                   .specifiers = {specifierP900, specifier850},
                                   .maxSearchTime = 60,
@@ -961,7 +964,7 @@
     RadioAccessSpecifier specifier850 = {
             .accessNetwork = AccessNetwork::GERAN, .bands = band850, .channels = {128, 129}};
 
-    NetworkScanRequest request = {.type = NetworkScanRequest::SCAN_TYPE_ONE_SHOT,
+    NetworkScanRequest request = {.type = NetworkScanRequest::SCAN_TYPE_PERIODIC,
                                   .interval = 301,
                                   .specifiers = {specifierP900, specifier850},
                                   .maxSearchTime = 60,
@@ -1494,11 +1497,20 @@
     }
 
     // 32 bit system might return invalid mcc and mnc string "\xff\xff..."
-    if (checkMccMnc && mcc.size() < 4 && mnc.size() < 4) {
-        int mcc_int = stoi(mcc);
-        int mnc_int = stoi(mnc);
-        EXPECT_TRUE(mcc_int >= 0 && mcc_int <= 999);
-        EXPECT_TRUE(mnc_int >= 0 && mnc_int <= 999);
+    if (checkMccMnc) {
+        int mccSize = mcc.size();
+        EXPECT_TRUE(mccSize == 0 || mccSize == 3);
+        if (mccSize > 0) {
+            int mcc_int = stoi(mcc);
+            EXPECT_TRUE(mcc_int >= 0 && mcc_int <= 999);
+        }
+
+        int mncSize = mnc.size();
+        EXPECT_TRUE(mncSize == 0 || mncSize == 2 || mncSize == 3);
+        if (mncSize > 0) {
+            int mnc_int = stoi(mnc);
+            EXPECT_TRUE(mnc_int >= 0 && mnc_int <= 999);
+        }
     }
 
     // Check for access technology specific info
diff --git a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl
index 82c8a0d..a4fab55 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl
@@ -126,8 +126,8 @@
      *
      *   o The HMAC field must validate correctly.
      *
-     *   o The challenge field in the auth token must contain the challenge value contained in the
-     *     BeginResult returned from IKeyMintDevice::begin().
+     *   o The challenge field in the timestamp token must contain the challenge value contained in
+     *     the BeginResult returned from IKeyMintDevice::begin().
      *
      * The resulting secure time value is then used to authenticate the HardwareAuthToken. For the
      * auth token to be valid, all of the following has to be true:
@@ -139,9 +139,6 @@
      *
      *   o The key must have a Tag::USER_AUTH_TYPE that matches the auth type in the token.
      *
-     *   o The challenge field in the auth token must contain the challenge value contained in the
-     *     BeginResult returned from IKeyMintDevice::begin().
-     *
      *   o The timestamp in the auth token plus the value of the Tag::AUTH_TIMEOUT must be greater
      *     than the provided secure timestamp.
 
diff --git a/security/keymint/aidl/vts/functional/Android.bp b/security/keymint/aidl/vts/functional/Android.bp
index 7a4359d..41b161d 100644
--- a/security/keymint/aidl/vts/functional/Android.bp
+++ b/security/keymint/aidl/vts/functional/Android.bp
@@ -43,8 +43,11 @@
         "android.hardware.gatekeeper-V1-ndk",
         "android.hardware.security.rkp-V3-ndk",
         "android.hardware.security.secureclock-V1-ndk",
+        "libavb_user",
+        "libavb",
         "libcppbor_external",
         "libcppcose_rkp",
+        "libfs_mgr",
         "libjsoncpp",
         "libkeymint",
         "libkeymint_remote_prov_support",
diff --git a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
index e759123..0fc359a 100644
--- a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
+++ b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
@@ -80,7 +80,13 @@
         return "";
     }
 
-    return ::android::base::Trim(out[0]);
+    string imei = ::android::base::Trim(out[0]);
+    if (imei.compare("null") == 0) {
+        LOG(ERROR) << "Error in getting IMEI from Telephony service: value is null. Cmd: " << cmd;
+        return "";
+    }
+
+    return imei;
 }
 
 }  // namespace
@@ -88,96 +94,9 @@
 class AttestKeyTest : public KeyMintAidlTestBase {
   public:
     void SetUp() override {
-        check_skip_test();
+        skipAttestKeyTest();
         KeyMintAidlTestBase::SetUp();
     }
-
-  protected:
-    const string FEATURE_KEYSTORE_APP_ATTEST_KEY = "android.hardware.keystore.app_attest_key";
-
-    const string FEATURE_STRONGBOX_KEYSTORE = "android.hardware.strongbox_keystore";
-
-    ErrorCode GenerateAttestKey(const AuthorizationSet& key_desc,
-                                const optional<AttestationKey>& attest_key,
-                                vector<uint8_t>* key_blob,
-                                vector<KeyCharacteristics>* key_characteristics,
-                                vector<Certificate>* cert_chain) {
-        // The original specification for KeyMint v1 required ATTEST_KEY not be combined
-        // with any other key purpose, but the original VTS tests incorrectly did exactly that.
-        // This means that a device that launched prior to Android T (API level 33) may
-        // accept or even require KeyPurpose::SIGN too.
-        if (property_get_int32("ro.board.first_api_level", 0) < __ANDROID_API_T__) {
-            AuthorizationSet key_desc_plus_sign = key_desc;
-            key_desc_plus_sign.push_back(TAG_PURPOSE, KeyPurpose::SIGN);
-
-            auto result = GenerateKey(key_desc_plus_sign, attest_key, key_blob, key_characteristics,
-                                      cert_chain);
-            if (result == ErrorCode::OK) {
-                return result;
-            }
-            // If the key generation failed, it may be because the device is (correctly)
-            // rejecting the combination of ATTEST_KEY+SIGN.  Fall through to try again with
-            // just ATTEST_KEY.
-        }
-        return GenerateKey(key_desc, attest_key, key_blob, key_characteristics, cert_chain);
-    }
-
-    // Check if ATTEST_KEY feature is disabled
-    bool is_attest_key_feature_disabled(void) const {
-        if (!check_feature(FEATURE_KEYSTORE_APP_ATTEST_KEY)) {
-            GTEST_LOG_(INFO) << "Feature " + FEATURE_KEYSTORE_APP_ATTEST_KEY + " is disabled";
-            return true;
-        }
-
-        return false;
-    }
-
-    // Check if StrongBox KeyStore is enabled
-    bool is_strongbox_enabled(void) const {
-        if (check_feature(FEATURE_STRONGBOX_KEYSTORE)) {
-            GTEST_LOG_(INFO) << "Feature " + FEATURE_STRONGBOX_KEYSTORE + " is enabled";
-            return true;
-        }
-
-        return false;
-    }
-
-    // Check if chipset has received a waiver allowing it to be launched with Android S or T with
-    // Keymaster 4.0 in StrongBox.
-    bool is_chipset_allowed_km4_strongbox(void) const {
-        std::array<char, PROPERTY_VALUE_MAX> buffer;
-
-        const int32_t first_api_level = property_get_int32("ro.board.first_api_level", 0);
-        if (first_api_level <= 0 || first_api_level > __ANDROID_API_T__) return false;
-
-        auto res = property_get("ro.vendor.qti.soc_model", buffer.data(), nullptr);
-        if (res <= 0) return false;
-
-        const string allowed_soc_models[] = {"SM8450", "SM8475", "SM8550", "SXR2230P"};
-
-        for (const string model : allowed_soc_models) {
-            if (model.compare(buffer.data()) == 0) {
-                GTEST_LOG_(INFO) << "QTI SOC Model " + model + " is allowed SB KM 4.0";
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    // Skip the test if all the following conditions hold:
-    // 1. ATTEST_KEY feature is disabled
-    // 2. STRONGBOX is enabled
-    // 3. The device is running one of the chipsets that have received a waiver
-    //     allowing it to be launched with Android S (or later) with Keymaster 4.0
-    //     in StrongBox
-    void check_skip_test(void) const {
-        // Check the chipset first as that doesn't require a round-trip to Package Manager.
-        if (is_chipset_allowed_km4_strongbox() && is_strongbox_enabled() &&
-            is_attest_key_feature_disabled()) {
-            GTEST_SKIP() << "Test is not applicable";
-        }
-    }
 };
 
 /*
@@ -201,6 +120,7 @@
                                             .SetDefaultValidity(),
                                     {} /* attestation signing key */, &attest_key.keyBlob,
                                     &attest_key_characteristics, &attest_key_cert_chain));
+        KeyBlobDeleter attest_deleter(keymint_, attest_key.keyBlob);
 
         ASSERT_GT(attest_key_cert_chain.size(), 0);
         EXPECT_EQ(attest_key_cert_chain.size(), 1);
@@ -222,8 +142,7 @@
                                       .SetDefaultValidity(),
                               attest_key, &attested_key_blob, &attested_key_characteristics,
                               &attested_key_cert_chain));
-
-        CheckedDeleteKey(&attested_key_blob);
+        KeyBlobDeleter attested_deleter(keymint_, attested_key_blob);
 
         AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
         AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
@@ -255,8 +174,7 @@
                                       .SetDefaultValidity(),
                               attest_key, &attested_key_blob, &attested_key_characteristics,
                               &attested_key_cert_chain));
-
-        CheckedDeleteKey(&attested_key_blob);
+        KeyBlobDeleter attested_deleter2(keymint_, attested_key_blob);
 
         hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
         sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
@@ -288,6 +206,7 @@
                                       .SetDefaultValidity(),
                               attest_key, &attested_key_blob, &attested_key_characteristics,
                               &attested_key_cert_chain));
+        KeyBlobDeleter attested_deleter3(keymint_, attested_key_blob);
 
         // The returned key characteristics will include CREATION_DATETIME (checked below)
         // in SecurityLevel::KEYSTORE; this will be stripped out in the CheckCharacteristics()
@@ -295,9 +214,6 @@
         // any SecurityLevel::KEYSTORE characteristics).
         CheckCharacteristics(attested_key_blob, attested_key_characteristics);
 
-        CheckedDeleteKey(&attested_key_blob);
-        CheckedDeleteKey(&attest_key.keyBlob);
-
         hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
         sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
 
@@ -389,6 +305,7 @@
         if (result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) return;
     }
     ASSERT_EQ(ErrorCode::OK, result);
+    KeyBlobDeleter attest_deleter(keymint_, attest_key.keyBlob);
 
     EXPECT_GT(attest_key_cert_chain.size(), 1);
     verify_subject_and_serial(attest_key_cert_chain[0], serial_int, subject, false);
@@ -425,9 +342,7 @@
                                   .SetDefaultValidity(),
                           attest_key, &attested_key_blob, &attested_key_characteristics,
                           &attested_key_cert_chain));
-
-    CheckedDeleteKey(&attested_key_blob);
-    CheckedDeleteKey(&attest_key.keyBlob);
+    KeyBlobDeleter attested_deleter(keymint_, attested_key_blob);
 
     AuthorizationSet hw_enforced2 = HwEnforcedAuthorizations(attested_key_characteristics);
     AuthorizationSet sw_enforced2 = SwEnforcedAuthorizations(attested_key_characteristics);
@@ -457,6 +372,7 @@
     const int chain_size = 6;
     vector<vector<uint8_t>> key_blob_list(chain_size);
     vector<vector<Certificate>> cert_chain_list(chain_size);
+    vector<KeyBlobDeleter> deleters;
 
     for (int i = 0; i < chain_size; i++) {
         string sub = "attest key chaining ";
@@ -493,6 +409,7 @@
             if (result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) return;
         }
         ASSERT_EQ(ErrorCode::OK, result);
+        deleters.push_back(KeyBlobDeleter(keymint_, key_blob_list[i]));
 
         AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
         AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
@@ -518,10 +435,6 @@
         EXPECT_GT(cert_chain_list[i].size(), i + 1);
         verify_subject_and_serial(cert_chain_list[i][0], serial_int, subject, false);
     }
-
-    for (int i = 0; i < chain_size; i++) {
-        CheckedDeleteKey(&key_blob_list[i]);
-    }
 }
 
 /*
@@ -534,6 +447,7 @@
     const int chain_size = 6;
     vector<vector<uint8_t>> key_blob_list(chain_size);
     vector<vector<Certificate>> cert_chain_list(chain_size);
+    vector<KeyBlobDeleter> deleters;
 
     for (int i = 0; i < chain_size; i++) {
         string sub = "Ec attest key chaining ";
@@ -570,6 +484,7 @@
             if (result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) return;
         }
         ASSERT_EQ(ErrorCode::OK, result);
+        deleters.push_back(KeyBlobDeleter(keymint_, key_blob_list[i]));
 
         AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
         AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
@@ -595,10 +510,6 @@
         EXPECT_GT(cert_chain_list[i].size(), i + 1);
         verify_subject_and_serial(cert_chain_list[i][0], serial_int, subject, false);
     }
-
-    for (int i = 0; i < chain_size; i++) {
-        CheckedDeleteKey(&key_blob_list[i]);
-    }
 }
 
 /*
@@ -638,6 +549,7 @@
     const int chain_size = 6;
     vector<vector<uint8_t>> key_blob_list(chain_size);
     vector<vector<Certificate>> cert_chain_list(chain_size);
+    vector<KeyBlobDeleter> deleters;
 
     for (int i = 0; i < chain_size; i++) {
         string sub = "Alt attest key chaining ";
@@ -688,6 +600,7 @@
             if (result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) return;
         }
         ASSERT_EQ(ErrorCode::OK, result);
+        deleters.push_back(KeyBlobDeleter(keymint_, key_blob_list[i]));
 
         AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
         AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
@@ -713,10 +626,6 @@
         EXPECT_GT(cert_chain_list[i].size(), i + 1);
         verify_subject_and_serial(cert_chain_list[i][0], serial_int, subject, false);
     }
-
-    for (int i = 0; i < chain_size; i++) {
-        CheckedDeleteKey(&key_blob_list[i]);
-    }
 }
 
 TEST_P(AttestKeyTest, MissingChallenge) {
@@ -734,6 +643,7 @@
                                             .SetDefaultValidity(),
                                     {} /* attestation signing key */, &attest_key.keyBlob,
                                     &attest_key_characteristics, &attest_key_cert_chain));
+        KeyBlobDeleter attest_deleter(keymint_, attest_key.keyBlob);
 
         EXPECT_EQ(attest_key_cert_chain.size(), 1);
         EXPECT_TRUE(IsSelfSigned(attest_key_cert_chain)) << "Failed on size " << size;
@@ -762,8 +672,6 @@
                                       .SetDefaultValidity(),
                               attest_key, &attested_key_blob, &attested_key_characteristics,
                               &attested_key_cert_chain));
-
-        CheckedDeleteKey(&attest_key.keyBlob);
     }
 }
 
@@ -781,6 +689,7 @@
                         AuthorizationSetBuilder().EcdsaKey(curve).AttestKey().SetDefaultValidity(),
                         {} /* attestation signing key */, &attest_key.keyBlob,
                         &attest_key_characteristics, &attest_key_cert_chain));
+        KeyBlobDeleter attest_deleter(keymint_, attest_key.keyBlob);
 
         ASSERT_GT(attest_key_cert_chain.size(), 0);
         EXPECT_EQ(attest_key_cert_chain.size(), 1);
@@ -802,9 +711,9 @@
                                       .SetDefaultValidity(),
                               attest_key, &attested_key_blob, &attested_key_characteristics,
                               &attested_key_cert_chain));
+        KeyBlobDeleter attested_deleter(keymint_, attested_key_blob);
 
         ASSERT_GT(attested_key_cert_chain.size(), 0);
-        CheckedDeleteKey(&attested_key_blob);
 
         AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
         AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
@@ -833,10 +742,9 @@
                                       .SetDefaultValidity(),
                               attest_key, &attested_key_blob, &attested_key_characteristics,
                               &attested_key_cert_chain));
+        KeyBlobDeleter attested_deleter2(keymint_, attested_key_blob);
 
         ASSERT_GT(attested_key_cert_chain.size(), 0);
-        CheckedDeleteKey(&attested_key_blob);
-        CheckedDeleteKey(&attest_key.keyBlob);
 
         hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
         sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
@@ -906,6 +814,7 @@
                                         .SetDefaultValidity(),
                                 {} /* attestation signing key */, &attest_key.keyBlob,
                                 &attest_key_characteristics, &attest_key_cert_chain));
+    KeyBlobDeleter attest_deleter(keymint_, attest_key.keyBlob);
     attest_key.issuerSubjectName = make_name_from_str("Android Keystore Key");
     ASSERT_GT(attest_key_cert_chain.size(), 0);
     EXPECT_EQ(attest_key_cert_chain.size(), 1);
@@ -972,8 +881,7 @@
         }
 
         ASSERT_EQ(result, ErrorCode::OK);
-
-        CheckedDeleteKey(&attested_key_blob);
+        KeyBlobDeleter attested_deleter(keymint_, attested_key_blob);
 
         AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
         AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
@@ -987,7 +895,6 @@
                                               hw_enforced, SecLevel(),
                                               attested_key_cert_chain[0].encodedCertificate));
     }
-    CheckedDeleteKey(&attest_key.keyBlob);
 }
 
 TEST_P(AttestKeyTest, EcdsaAttestationMismatchID) {
@@ -1002,6 +909,7 @@
                                         .SetDefaultValidity(),
                                 {} /* attestation signing key */, &attest_key.keyBlob,
                                 &attest_key_characteristics, &attest_key_cert_chain));
+    KeyBlobDeleter attest_deleter(keymint_, attest_key.keyBlob);
     attest_key.issuerSubjectName = make_name_from_str("Android Keystore Key");
     ASSERT_GT(attest_key_cert_chain.size(), 0);
     EXPECT_EQ(attest_key_cert_chain.size(), 1);
@@ -1042,12 +950,8 @@
         vector<Certificate> attested_key_cert_chain;
         auto result = GenerateKey(builder, attest_key, &attested_key_blob,
                                   &attested_key_characteristics, &attested_key_cert_chain);
-
-        ASSERT_TRUE(result == ErrorCode::CANNOT_ATTEST_IDS || result == ErrorCode::INVALID_TAG)
-                << "result = " << result;
-        device_id_attestation_vsr_check(result);
+        device_id_attestation_check_acceptable_error(invalid_tag.tag, result);
     }
-    CheckedDeleteKey(&attest_key.keyBlob);
 }
 
 TEST_P(AttestKeyTest, SecondIMEIAttestationIDSuccess) {
@@ -1059,7 +963,7 @@
 
     // Skip the test if there is no second IMEI exists.
     string second_imei = get_imei(1);
-    if (second_imei.empty() || second_imei.compare("null") == 0) {
+    if (second_imei.empty()) {
         GTEST_SKIP() << "Test not applicable as there is no second IMEI";
     }
 
@@ -1078,6 +982,7 @@
                                         .SetDefaultValidity(),
                                 {} /* attestation signing key */, &attest_key.keyBlob,
                                 &attest_key_characteristics, &attest_key_cert_chain));
+    KeyBlobDeleter attest_deleter(keymint_, attest_key.keyBlob);
     attest_key.issuerSubjectName = make_name_from_str("Android Keystore Key");
     EXPECT_EQ(attest_key_cert_chain.size(), 1);
     EXPECT_TRUE(IsSelfSigned(attest_key_cert_chain));
@@ -1106,10 +1011,7 @@
     }
 
     ASSERT_EQ(result, ErrorCode::OK);
-
-    device_id_attestation_vsr_check(result);
-
-    CheckedDeleteKey(&attested_key_blob);
+    KeyBlobDeleter attested_deleter(keymint_, attested_key_blob);
 
     AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
     AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
@@ -1124,8 +1026,6 @@
     EXPECT_TRUE(verify_attestation_record(AidlVersion(), "challenge", "foo", sw_enforced,
                                           hw_enforced, SecLevel(),
                                           attested_key_cert_chain[0].encodedCertificate));
-
-    CheckedDeleteKey(&attest_key.keyBlob);
 }
 
 TEST_P(AttestKeyTest, MultipleIMEIAttestationIDSuccess) {
@@ -1137,13 +1037,13 @@
 
     // Skip the test if there is no first IMEI exists.
     string imei = get_imei(0);
-    if (imei.empty() || imei.compare("null") == 0) {
+    if (imei.empty()) {
         GTEST_SKIP() << "Test not applicable as there is no first IMEI";
     }
 
     // Skip the test if there is no second IMEI exists.
     string second_imei = get_imei(1);
-    if (second_imei.empty() || second_imei.compare("null") == 0) {
+    if (second_imei.empty()) {
         GTEST_SKIP() << "Test not applicable as there is no second IMEI";
     }
 
@@ -1162,6 +1062,7 @@
                                         .SetDefaultValidity(),
                                 {} /* attestation signing key */, &attest_key.keyBlob,
                                 &attest_key_characteristics, &attest_key_cert_chain));
+    KeyBlobDeleter attest_deleter(keymint_, attest_key.keyBlob);
     attest_key.issuerSubjectName = make_name_from_str("Android Keystore Key");
     EXPECT_EQ(attest_key_cert_chain.size(), 1);
     EXPECT_TRUE(IsSelfSigned(attest_key_cert_chain));
@@ -1187,10 +1088,7 @@
     }
 
     ASSERT_EQ(result, ErrorCode::OK);
-
-    device_id_attestation_vsr_check(result);
-
-    CheckedDeleteKey(&attested_key_blob);
+    KeyBlobDeleter attested_deleter(keymint_, attested_key_blob);
 
     AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
     AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
@@ -1208,8 +1106,6 @@
     EXPECT_TRUE(verify_attestation_record(AidlVersion(), "challenge", "foo", sw_enforced,
                                           hw_enforced, SecLevel(),
                                           attested_key_cert_chain[0].encodedCertificate));
-
-    CheckedDeleteKey(&attest_key.keyBlob);
 }
 
 INSTANTIATE_KEYMINT_AIDL_TEST(AttestKeyTest);
diff --git a/security/keymint/aidl/vts/functional/AuthTest.cpp b/security/keymint/aidl/vts/functional/AuthTest.cpp
index 78c88f4..290e8fc 100644
--- a/security/keymint/aidl/vts/functional/AuthTest.cpp
+++ b/security/keymint/aidl/vts/functional/AuthTest.cpp
@@ -93,17 +93,21 @@
     void TearDown() {
         if (gk_ == nullptr) return;
         gk_->deleteUser(uid_);
+        if (alt_uid_ != 0) {
+            gk_->deleteUser(alt_uid_);
+        }
     }
 
     bool GatekeeperAvailable() { return (gk_ != nullptr) || (hidl_gk_ != nullptr); }
 
-    std::optional<GatekeeperEnrollResponse> doEnroll(const std::vector<uint8_t>& newPwd,
+    std::optional<GatekeeperEnrollResponse> doEnroll(uint32_t uid,
+                                                     const std::vector<uint8_t>& newPwd,
                                                      const std::vector<uint8_t>& curHandle = {},
                                                      const std::vector<uint8_t>& curPwd = {}) {
         if (gk_ != nullptr) {
             while (true) {
                 GatekeeperEnrollResponse rsp;
-                Status status = gk_->enroll(uid_, curHandle, curPwd, newPwd, &rsp);
+                Status status = gk_->enroll(uid, curHandle, curPwd, newPwd, &rsp);
                 if (!status.isOk() && status.getExceptionCode() == EX_SERVICE_SPECIFIC &&
                     status.getServiceSpecificError() == IGatekeeper::ERROR_RETRY_TIMEOUT) {
                     sleep(1);
@@ -120,7 +124,7 @@
             while (true) {
                 HidlGatekeeperResponse rsp;
                 auto status = hidl_gk_->enroll(
-                        uid_, curHandle, curPwd, newPwd,
+                        uid, curHandle, curPwd, newPwd,
                         [&rsp](const HidlGatekeeperResponse& cbRsp) { rsp = cbRsp; });
                 if (!status.isOk()) {
                     GTEST_LOG_(ERROR) << "doEnroll(HIDL) failed";
@@ -155,20 +159,23 @@
         }
     }
 
-    std::optional<GatekeeperEnrollResponse> doEnroll(const string& newPwd,
+    std::optional<GatekeeperEnrollResponse> doEnroll(uint32_t uid, const string& newPwd,
                                                      const std::vector<uint8_t>& curHandle = {},
                                                      const string& curPwd = {}) {
-        return doEnroll(std::vector<uint8_t>(newPwd.begin(), newPwd.end()), curHandle,
+        return doEnroll(uid, std::vector<uint8_t>(newPwd.begin(), newPwd.end()), curHandle,
                         std::vector<uint8_t>(curPwd.begin(), curPwd.end()));
     }
+    std::optional<GatekeeperEnrollResponse> doEnroll(const string& newPwd) {
+        return doEnroll(uid_, newPwd);
+    }
 
-    std::optional<HardwareAuthToken> doVerify(uint64_t challenge,
+    std::optional<HardwareAuthToken> doVerify(uint32_t uid, uint64_t challenge,
                                               const std::vector<uint8_t>& handle,
                                               const std::vector<uint8_t>& pwd) {
         if (gk_ != nullptr) {
             while (true) {
                 GatekeeperVerifyResponse rsp;
-                Status status = gk_->verify(uid_, challenge, handle, pwd, &rsp);
+                Status status = gk_->verify(uid, challenge, handle, pwd, &rsp);
                 if (!status.isOk() && status.getExceptionCode() == EX_SERVICE_SPECIFIC &&
                     status.getServiceSpecificError() == IGatekeeper::ERROR_RETRY_TIMEOUT) {
                     sleep(1);
@@ -185,7 +192,7 @@
             while (true) {
                 HidlGatekeeperResponse rsp;
                 auto status = hidl_gk_->verify(
-                        uid_, challenge, handle, pwd,
+                        uid, challenge, handle, pwd,
                         [&rsp](const HidlGatekeeperResponse& cbRsp) { rsp = cbRsp; });
                 if (!status.isOk()) {
                     GTEST_LOG_(ERROR) << "doVerify(HIDL) failed";
@@ -220,10 +227,15 @@
             return std::nullopt;
         }
     }
+    std::optional<HardwareAuthToken> doVerify(uint32_t uid, uint64_t challenge,
+                                              const std::vector<uint8_t>& handle,
+                                              const string& pwd) {
+        return doVerify(uid, challenge, handle, std::vector<uint8_t>(pwd.begin(), pwd.end()));
+    }
     std::optional<HardwareAuthToken> doVerify(uint64_t challenge,
                                               const std::vector<uint8_t>& handle,
                                               const string& pwd) {
-        return doVerify(challenge, handle, std::vector<uint8_t>(pwd.begin(), pwd.end()));
+        return doVerify(uid_, challenge, handle, pwd);
     }
 
     // Variants of the base class methods but with authentication information included.
@@ -268,6 +280,13 @@
         return plaintext;
     }
 
+    string SignMessage(const vector<uint8_t>& key_blob, const string& message,
+                       const AuthorizationSet& in_params, AuthorizationSet* out_params,
+                       const HardwareAuthToken& hat) {
+        SCOPED_TRACE("SignMessage");
+        return ProcessMessage(key_blob, KeyPurpose::SIGN, message, in_params, out_params, hat);
+    }
+
   protected:
     std::shared_ptr<IGatekeeper> gk_;
     sp<IHidlGatekeeper> hidl_gk_;
@@ -275,6 +294,8 @@
     string password_;
     uint32_t uid_;
     int64_t sid_;
+    uint32_t alt_uid_;
+    int64_t alt_sid_;
     std::vector<uint8_t> handle_;
 };
 
@@ -347,6 +368,116 @@
     }
 }
 
+// Test use of a key that requires user-authentication within recent history, but where
+// the `TimestampToken` provided to the device is unrelated to the in-progress operation.
+TEST_P(AuthTest, TimeoutAuthenticationIncorrectTimestampToken) {
+    if (!GatekeeperAvailable()) {
+        GTEST_SKIP() << "No Gatekeeper available";
+    }
+    if (!timestamp_token_required_) {
+        GTEST_SKIP() << "Test only applies to devices with no secure clock";
+    }
+    if (clock_ == nullptr) {
+        GTEST_SKIP() << "Device requires timestamps and no ISecureClock available";
+    }
+
+    // Create an AES key that requires authentication within the last 3 seconds.
+    const uint32_t timeout_secs = 3;
+    auto builder = AuthorizationSetBuilder()
+                           .AesEncryptionKey(256)
+                           .BlockMode(BlockMode::ECB)
+                           .Padding(PaddingMode::PKCS7)
+                           .Authorization(TAG_USER_SECURE_ID, sid_)
+                           .Authorization(TAG_USER_AUTH_TYPE, HardwareAuthenticatorType::PASSWORD)
+                           .Authorization(TAG_AUTH_TIMEOUT, timeout_secs);
+    vector<uint8_t> keyblob;
+    vector<KeyCharacteristics> key_characteristics;
+    vector<Certificate> cert_chain;
+    ASSERT_EQ(ErrorCode::OK,
+              GenerateKey(builder, std::nullopt, &keyblob, &key_characteristics, &cert_chain));
+
+    // Verify to get a HAT, arbitrary challenge.
+    const uint64_t challenge = 42;
+    const std::optional<HardwareAuthToken> hat = doVerify(challenge, handle_, password_);
+    ASSERT_TRUE(hat.has_value());
+    EXPECT_EQ(hat->userId, sid_);
+
+    // KeyMint implementation has no clock, so only detects timeout via timestamp token provided
+    // on update()/finish().  However, for this test we ensure that that the timestamp token has a
+    // *different* challenge value.
+    const string message = "Hello World!";
+    auto params = AuthorizationSetBuilder().BlockMode(BlockMode::ECB).Padding(PaddingMode::PKCS7);
+    AuthorizationSet out_params;
+    ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, keyblob, params, &out_params, hat));
+
+    secureclock::TimeStampToken time_token;
+    EXPECT_EQ(ErrorCode::OK,
+              GetReturnErrorCode(clock_->generateTimeStamp(challenge_ + 1, &time_token)));
+    string output;
+    EXPECT_EQ(ErrorCode::KEY_USER_NOT_AUTHENTICATED,
+              Finish(message, {} /* signature */, &output, hat, time_token));
+}
+
+// Test use of a key with multiple USER_SECURE_ID values.  For variety, use an EC signing key
+// generated with attestation.
+TEST_P(AuthTest, TimeoutAuthenticationMultiSid) {
+    if (!GatekeeperAvailable()) {
+        GTEST_SKIP() << "No Gatekeeper available";
+    }
+    if (timestamp_token_required_ && clock_ == nullptr) {
+        GTEST_SKIP() << "Device requires timestamps and no ISecureClock available";
+    }
+
+    // Enroll a password for a second user.
+    alt_uid_ = 20001;
+    const string alt_password = "correcthorsebatterystaple2";
+    std::optional<GatekeeperEnrollResponse> rsp = doEnroll(alt_uid_, alt_password);
+    ASSERT_TRUE(rsp.has_value());
+    alt_sid_ = rsp->secureUserId;
+    const std::vector<uint8_t> alt_handle = rsp->data;
+
+    // Create an attested EC key that requires authentication within the last 3 seconds from either
+    // secure ID. Also allow any authenticator type.
+    const uint32_t timeout_secs = 3;
+    auto builder = AuthorizationSetBuilder()
+                           .EcdsaSigningKey(EcCurve::P_256)
+                           .Digest(Digest::NONE)
+                           .Digest(Digest::SHA_2_256)
+                           .SetDefaultValidity()
+                           .AttestationChallenge("challenge")
+                           .AttestationApplicationId("app_id")
+                           .Authorization(TAG_USER_SECURE_ID, alt_sid_)
+                           .Authorization(TAG_USER_SECURE_ID, sid_)
+                           .Authorization(TAG_USER_AUTH_TYPE, HardwareAuthenticatorType::ANY)
+                           .Authorization(TAG_AUTH_TIMEOUT, timeout_secs);
+    vector<uint8_t> keyblob;
+    vector<KeyCharacteristics> key_characteristics;
+    vector<Certificate> cert_chain;
+    ASSERT_EQ(ErrorCode::OK,
+              GenerateKey(builder, std::nullopt, &keyblob, &key_characteristics, &cert_chain));
+
+    // Verify first user to get a HAT that should work.
+    const uint64_t challenge = 42;
+    const std::optional<HardwareAuthToken> hat = doVerify(uid_, challenge, handle_, password_);
+    ASSERT_TRUE(hat.has_value());
+    EXPECT_EQ(hat->userId, sid_);
+
+    const string message = "Hello World!";
+    auto params = AuthorizationSetBuilder().Digest(Digest::SHA_2_256);
+    AuthorizationSet out_params;
+    const string signature = SignMessage(keyblob, message, params, &out_params, hat.value());
+
+    // Verify second user to get a HAT that should work.
+    const uint64_t alt_challenge = 43;
+    const std::optional<HardwareAuthToken> alt_hat =
+            doVerify(alt_uid_, alt_challenge, alt_handle, alt_password);
+    ASSERT_TRUE(alt_hat.has_value());
+    EXPECT_EQ(alt_hat->userId, alt_sid_);
+
+    const string alt_signature =
+            SignMessage(keyblob, message, params, &out_params, alt_hat.value());
+}
+
 // Test use of a key that requires an auth token for each action on the operation, with
 // a per-operation challenge value included.
 TEST_P(AuthTest, AuthPerOperation) {
@@ -407,6 +538,93 @@
               Finish(message, {} /* signature */, &ciphertext, hat.value()));
 }
 
+// Test use of a key that requires an auth token for each action on the operation, with
+// a per-operation challenge value included, with multiple secure IDs allowed.
+TEST_P(AuthTest, AuthPerOperationMultiSid) {
+    if (!GatekeeperAvailable()) {
+        GTEST_SKIP() << "No Gatekeeper available";
+    }
+
+    // Enroll a password for a second user.
+    alt_uid_ = 20001;
+    const string alt_password = "correcthorsebatterystaple2";
+    std::optional<GatekeeperEnrollResponse> rsp = doEnroll(alt_uid_, alt_password);
+    ASSERT_TRUE(rsp.has_value());
+    alt_sid_ = rsp->secureUserId;
+    const std::vector<uint8_t> alt_handle = rsp->data;
+
+    // Create an AES key that requires authentication per-action.
+    auto builder = AuthorizationSetBuilder()
+                           .AesEncryptionKey(256)
+                           .BlockMode(BlockMode::ECB)
+                           .Padding(PaddingMode::PKCS7)
+                           .Authorization(TAG_USER_SECURE_ID, sid_)
+                           .Authorization(TAG_USER_SECURE_ID, alt_sid_)
+                           .Authorization(TAG_USER_AUTH_TYPE, HardwareAuthenticatorType::ANY);
+    vector<uint8_t> keyblob;
+    vector<KeyCharacteristics> key_characteristics;
+    vector<Certificate> cert_chain;
+    ASSERT_EQ(ErrorCode::OK,
+              GenerateKey(builder, std::nullopt, &keyblob, &key_characteristics, &cert_chain));
+
+    // Get a HAT for first user with the challenge from an in-progress operation.
+    const string message = "Hello World!";
+    auto params = AuthorizationSetBuilder().BlockMode(BlockMode::ECB).Padding(PaddingMode::PKCS7);
+    AuthorizationSet out_params;
+    EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, keyblob, params, &out_params));
+    const std::optional<HardwareAuthToken> hat = doVerify(uid_, challenge_, handle_, password_);
+    ASSERT_TRUE(hat.has_value());
+    EXPECT_EQ(hat->userId, sid_);
+    string ciphertext;
+    EXPECT_EQ(ErrorCode::OK, Finish(message, {} /* signature */, &ciphertext, hat.value()));
+
+    // Get a HAT for second user with the challenge from an in-progress operation.
+    EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, keyblob, params, &out_params));
+    const std::optional<HardwareAuthToken> alt_hat =
+            doVerify(alt_uid_, challenge_, alt_handle, alt_password);
+    ASSERT_TRUE(alt_hat.has_value());
+    EXPECT_EQ(alt_hat->userId, alt_sid_);
+    string alt_ciphertext;
+    EXPECT_EQ(ErrorCode::OK, Finish(message, {} /* signature */, &ciphertext, alt_hat.value()));
+}
+
+// Test use of a key that requires an auth token for each action on the operation, but
+// which gets passed a HAT of the wrong type
+TEST_P(AuthTest, AuthPerOperationWrongAuthType) {
+    if (!GatekeeperAvailable()) {
+        GTEST_SKIP() << "No Gatekeeper available";
+    }
+
+    // Create an AES key that requires authentication per-action, but with no valid authenticator
+    // types.
+    auto builder =
+            AuthorizationSetBuilder()
+                    .AesEncryptionKey(256)
+                    .BlockMode(BlockMode::ECB)
+                    .Padding(PaddingMode::PKCS7)
+                    .Authorization(TAG_USER_SECURE_ID, sid_)
+                    .Authorization(TAG_USER_AUTH_TYPE, HardwareAuthenticatorType::FINGERPRINT);
+    vector<uint8_t> keyblob;
+    vector<KeyCharacteristics> key_characteristics;
+    vector<Certificate> cert_chain;
+    ASSERT_EQ(ErrorCode::OK,
+              GenerateKey(builder, std::nullopt, &keyblob, &key_characteristics, &cert_chain));
+
+    // Get a HAT with the challenge from an in-progress operation.
+    const string message = "Hello World!";
+    auto params = AuthorizationSetBuilder().BlockMode(BlockMode::ECB).Padding(PaddingMode::PKCS7);
+    AuthorizationSet out_params;
+    EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, keyblob, params, &out_params));
+    const std::optional<HardwareAuthToken> hat = doVerify(challenge_, handle_, password_);
+    ASSERT_TRUE(hat.has_value());
+    EXPECT_EQ(hat->userId, sid_);
+
+    // Should fail because auth type doesn't (can't) match.
+    string ciphertext;
+    EXPECT_EQ(ErrorCode::KEY_USER_NOT_AUTHENTICATED,
+              Finish(message, {} /* signature */, &ciphertext, hat.value()));
+}
+
 INSTANTIATE_KEYMINT_AIDL_TEST(AuthTest);
 
 }  // namespace aidl::android::hardware::security::keymint::test
diff --git a/security/keymint/aidl/vts/functional/BootloaderStateTest.cpp b/security/keymint/aidl/vts/functional/BootloaderStateTest.cpp
index 723edee..54f187c 100644
--- a/security/keymint/aidl/vts/functional/BootloaderStateTest.cpp
+++ b/security/keymint/aidl/vts/functional/BootloaderStateTest.cpp
@@ -21,7 +21,11 @@
 #include <string>
 #include <vector>
 
+#include <android-base/properties.h>
 #include <android/binder_manager.h>
+#include <fstab/fstab.h>
+#include <libavb/libavb.h>
+#include <libavb_user/avb_ops_user.h>
 #include <remote_prov/remote_prov_utils.h>
 
 #include "KeyMintAidlTestBase.h"
@@ -34,49 +38,118 @@
 
 // Since this test needs to talk to KeyMint HAL, it can only run as root. Thus,
 // bootloader can not be locked.
-class BootloaderStateTest : public testing::TestWithParam<std::string> {
+class BootloaderStateTest : public KeyMintAidlTestBase {
   public:
     virtual void SetUp() override {
-        ::ndk::SpAIBinder binder(AServiceManager_waitForService(GetParam().c_str()));
-        keyMint_ = IKeyMintDevice::fromBinder(binder);
-        ASSERT_TRUE(keyMint_) << "Failed to get KM device";
+        KeyMintAidlTestBase::SetUp();
+
+        // Generate a key with attestation.
+        vector<uint8_t> key_blob;
+        vector<KeyCharacteristics> key_characteristics;
+        AuthorizationSet keyDesc = AuthorizationSetBuilder()
+                                           .Authorization(TAG_NO_AUTH_REQUIRED)
+                                           .EcdsaSigningKey(EcCurve::P_256)
+                                           .AttestationChallenge("foo")
+                                           .AttestationApplicationId("bar")
+                                           .Digest(Digest::NONE)
+                                           .SetDefaultValidity();
+        auto result = GenerateKey(keyDesc, &key_blob, &key_characteristics);
+        // If factory provisioned attestation key is not supported by Strongbox,
+        // then create a key with self-signed attestation and use it as the
+        // attestation key instead.
+        if (SecLevel() == SecurityLevel::STRONGBOX &&
+            result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) {
+            result = GenerateKeyWithSelfSignedAttestKey(
+                    AuthorizationSetBuilder()
+                            .EcdsaKey(EcCurve::P_256)
+                            .AttestKey()
+                            .SetDefaultValidity(), /* attest key params */
+                    keyDesc, &key_blob, &key_characteristics);
+        }
+        ASSERT_EQ(ErrorCode::OK, result);
+
+        // Parse attested AVB values.
+        X509_Ptr cert(parse_cert_blob(cert_chain_[0].encodedCertificate));
+        ASSERT_TRUE(cert.get());
+
+        ASN1_OCTET_STRING* attest_rec = get_attestation_record(cert.get());
+        ASSERT_TRUE(attest_rec);
+
+        auto error = parse_root_of_trust(attest_rec->data, attest_rec->length, &attestedVbKey_,
+                                         &attestedVbState_, &attestedBootloaderState_,
+                                         &attestedVbmetaDigest_);
+        ASSERT_EQ(error, ErrorCode::OK);
     }
 
-    std::shared_ptr<IKeyMintDevice> keyMint_;
+    vector<uint8_t> attestedVbKey_;
+    VerifiedBoot attestedVbState_;
+    bool attestedBootloaderState_;
+    vector<uint8_t> attestedVbmetaDigest_;
 };
 
 // Check that attested bootloader state is set to unlocked.
-TEST_P(BootloaderStateTest, IsUnlocked) {
-    // Generate a key with attestation.
-    AuthorizationSet keyDesc = AuthorizationSetBuilder()
-                                       .Authorization(TAG_NO_AUTH_REQUIRED)
-                                       .EcdsaSigningKey(EcCurve::P_256)
-                                       .AttestationChallenge("foo")
-                                       .AttestationApplicationId("bar")
-                                       .Digest(Digest::NONE)
-                                       .SetDefaultValidity();
-    KeyCreationResult creationResult;
-    auto kmStatus = keyMint_->generateKey(keyDesc.vector_data(), std::nullopt, &creationResult);
-    ASSERT_TRUE(kmStatus.isOk());
+TEST_P(BootloaderStateTest, BootloaderIsUnlocked) {
+    ASSERT_FALSE(attestedBootloaderState_)
+            << "This test runs as root. Bootloader must be unlocked.";
+}
 
-    vector<Certificate> key_cert_chain = std::move(creationResult.certificateChain);
+// Check that verified boot state is set to "unverified", i.e. "orange".
+TEST_P(BootloaderStateTest, VbStateIsUnverified) {
+    // Unlocked bootloader implies that verified boot state must be "unverified".
+    ASSERT_EQ(attestedVbState_, VerifiedBoot::UNVERIFIED)
+            << "Verified boot state must be \"UNVERIFIED\" aka \"orange\".";
 
-    // Parse attested AVB values.
-    const auto& attestation_cert = key_cert_chain[0].encodedCertificate;
-    X509_Ptr cert(parse_cert_blob(attestation_cert));
-    ASSERT_TRUE(cert.get());
+    // AVB spec stipulates that bootloader must set "androidboot.verifiedbootstate" parameter
+    // on the kernel command-line. This parameter is exposed to userspace as
+    // "ro.boot.verifiedbootstate" property.
+    auto vbStateProp = ::android::base::GetProperty("ro.boot.verifiedbootstate", "");
+    ASSERT_EQ(vbStateProp, "orange")
+            << "Verified boot state must be \"UNVERIFIED\" aka \"orange\".";
+}
 
-    ASN1_OCTET_STRING* attest_rec = get_attestation_record(cert.get());
-    ASSERT_TRUE(attest_rec);
+// Following error codes from avb_slot_data() mean that slot data was loaded
+// (even if verification failed).
+static inline bool avb_slot_data_loaded(AvbSlotVerifyResult result) {
+    switch (result) {
+        case AVB_SLOT_VERIFY_RESULT_OK:
+        case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION:
+        case AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX:
+        case AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED:
+            return true;
+        default:
+            return false;
+    }
+}
 
-    vector<uint8_t> key;
-    VerifiedBoot attestedVbState;
-    bool attestedBootloaderState;
-    vector<uint8_t> attestedVbmetaDigest;
-    auto error = parse_root_of_trust(attest_rec->data, attest_rec->length, &key, &attestedVbState,
-                                     &attestedBootloaderState, &attestedVbmetaDigest);
-    ASSERT_EQ(error, ErrorCode::OK);
-    ASSERT_FALSE(attestedBootloaderState) << "This test runs as root. Bootloader must be unlocked.";
+// Check that attested vbmeta digest is correct.
+TEST_P(BootloaderStateTest, VbmetaDigest) {
+    AvbSlotVerifyData* avbSlotData;
+    auto suffix = fs_mgr_get_slot_suffix();
+    const char* partitions[] = {nullptr};
+    auto avbOps = avb_ops_user_new();
+
+    // For VTS, devices run with vendor_boot-debug.img, which is not release key
+    // signed. Use AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR to bypass avb
+    // verification errors. This is OK since we only care about the digest for
+    // this test case.
+    auto result = avb_slot_verify(avbOps, partitions, suffix.c_str(),
+                                  AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
+                                  AVB_HASHTREE_ERROR_MODE_EIO, &avbSlotData);
+    ASSERT_TRUE(avb_slot_data_loaded(result)) << "Failed to load avb slot data";
+
+    // Unfortunately, bootloader is not required to report the algorithm used
+    // to calculate the digest. There are only two supported options though,
+    // SHA256 and SHA512. Attested VBMeta digest must match one of these.
+    vector<uint8_t> digest256(AVB_SHA256_DIGEST_SIZE);
+    vector<uint8_t> digest512(AVB_SHA512_DIGEST_SIZE);
+
+    avb_slot_verify_data_calculate_vbmeta_digest(avbSlotData, AVB_DIGEST_TYPE_SHA256,
+                                                 digest256.data());
+    avb_slot_verify_data_calculate_vbmeta_digest(avbSlotData, AVB_DIGEST_TYPE_SHA512,
+                                                 digest512.data());
+
+    ASSERT_TRUE((attestedVbmetaDigest_ == digest256) || (attestedVbmetaDigest_ == digest512))
+            << "Attested digest does not match computed digest.";
 }
 
 INSTANTIATE_KEYMINT_AIDL_TEST(BootloaderStateTest);
diff --git a/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp b/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp
index 55bb5b4..8e9aded 100644
--- a/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp
+++ b/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp
@@ -374,8 +374,8 @@
         // Add the tag that doesn't match the local device's real ID.
         builder.push_back(invalid_tag);
         auto result = GenerateKey(builder, &key_blob, &key_characteristics);
-        ASSERT_TRUE(result == ErrorCode::CANNOT_ATTEST_IDS || result == ErrorCode::INVALID_TAG);
-        device_id_attestation_vsr_check(result);
+
+        device_id_attestation_check_acceptable_error(invalid_tag.tag, result);
     }
 }
 
diff --git a/security/keymint/aidl/vts/functional/KeyBlobUpgradeTest.cpp b/security/keymint/aidl/vts/functional/KeyBlobUpgradeTest.cpp
index 6892442..4830422 100644
--- a/security/keymint/aidl/vts/functional/KeyBlobUpgradeTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyBlobUpgradeTest.cpp
@@ -36,11 +36,14 @@
 //
 //      adb push keymint-blobs /data/local/tmp/keymint-blobs
 //
-// 5) Run the "*After*" subset of these tests with the `--keyblob_dir <dir>` command-line argument
-//    pointing to the directory with the keyblobs:
+// 5) Run the "*After*" subset of these tests, with the following command-line arguments
+//    `--keyblob_dir <dir>`: pointing to the directory with the keyblobs.
+//    `--expect_upgrade {yes|no}` (Optional): To specify if users expect an upgrade on the keyBlobs,
+//                                            will be "yes" by default.
 //
 //      VtsAidlKeyMintTargetTest --gtest_filter="*KeyBlobUpgradeTest*After*" \
-//                               --keyblob_dir /data/local/tmp/keymint-blobs
+//                               --keyblob_dir /data/local/tmp/keymint-blobs \
+//                               --expect_upgrade {yes|no}
 //
 //    (Note that this skips the `CreateKeyBlobs` test, which would otherwise replace the saved
 //    keyblobs with freshly generated ones.).
@@ -408,12 +411,18 @@
 //
 //     VtsAidlKeyMintTargetTest --gtest_filter="*KeyBlobUpgradeTest.UpgradeKeyBlobsAfter*" \
 //                              --keyblob_dir /data/local/tmp/keymint-blobs
+//                              --expect_upgrade {yes|no}
 //
 // - this replaces the keyblob contents in that directory; if needed, save the upgraded keyblobs
 //   with:
 //      adb pull /data/local/tmp/keymint-blobs/
 TEST_P(KeyBlobUpgradeTest, UpgradeKeyBlobsAfter) {
-    UpgradeKeyBlobs(/* expectUpgrade= */ true);
+    bool expectUpgrade = true;  // this test expects upgrade to happen by default
+    if (expect_upgrade.has_value() && expect_upgrade == false) {
+        std::cout << "Not expecting key upgrade due to --expect_upgrade no\n";
+        expectUpgrade = false;
+    }
+    UpgradeKeyBlobs(expectUpgrade);
 }
 
 // To run this test:
@@ -551,7 +560,7 @@
                                               .SetDefaultValidity(),
                                       attest_key, &attested_key_blob, &attested_key_characteristics,
                                       &attested_key_cert_chain));
-                CheckedDeleteKey(&attested_key_blob);
+                KeyBlobDeleter(keymint_, attested_key_blob);
             } else {
                 FAIL() << "Unexpected name: " << name;
             }
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index 60d8748..12b21c1 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -181,6 +181,18 @@
 bool KeyMintAidlTestBase::arm_deleteAllKeys = false;
 bool KeyMintAidlTestBase::dump_Attestations = false;
 std::string KeyMintAidlTestBase::keyblob_dir;
+std::optional<bool> KeyMintAidlTestBase::expect_upgrade = std::nullopt;
+
+KeyBlobDeleter::~KeyBlobDeleter() {
+    if (key_blob_.empty()) {
+        return;
+    }
+    Status result = keymint_->deleteKey(key_blob_);
+    key_blob_.clear();
+    EXPECT_TRUE(result.isOk()) << result.getServiceSpecificError() << "\n";
+    ErrorCode rc = GetReturnErrorCode(result);
+    EXPECT_TRUE(rc == ErrorCode::OK || rc == ErrorCode::UNIMPLEMENTED) << result << "\n";
+}
 
 uint32_t KeyMintAidlTestBase::boot_patch_level(
         const vector<KeyCharacteristics>& key_characteristics) {
@@ -235,16 +247,6 @@
     return version >= 2;
 }
 
-ErrorCode KeyMintAidlTestBase::GetReturnErrorCode(const Status& result) {
-    if (result.isOk()) return ErrorCode::OK;
-
-    if (result.getExceptionCode() == EX_SERVICE_SPECIFIC) {
-        return static_cast<ErrorCode>(result.getServiceSpecificError());
-    }
-
-    return ErrorCode::UNKNOWN_ERROR;
-}
-
 void KeyMintAidlTestBase::InitializeKeyMint(std::shared_ptr<IKeyMintDevice> keyMint) {
     ASSERT_NE(keyMint, nullptr);
     keymint_ = std::move(keyMint);
@@ -329,12 +331,13 @@
         const AuthorizationSet& attest_key_desc, const AuthorizationSet& key_desc,
         vector<uint8_t>* key_blob, vector<KeyCharacteristics>* key_characteristics,
         vector<Certificate>* cert_chain) {
+    skipAttestKeyTest();
     AttestationKey attest_key;
     vector<Certificate> attest_cert_chain;
     vector<KeyCharacteristics> attest_key_characteristics;
     // Generate a key with self signed attestation.
-    auto error = GenerateKey(attest_key_desc, std::nullopt, &attest_key.keyBlob,
-                             &attest_key_characteristics, &attest_cert_chain);
+    auto error = GenerateAttestKey(attest_key_desc, std::nullopt, &attest_key.keyBlob,
+                                   &attest_key_characteristics, &attest_cert_chain);
     if (error != ErrorCode::OK) {
         return error;
     }
@@ -518,13 +521,9 @@
     return GetReturnErrorCode(result);
 }
 
-void KeyMintAidlTestBase::CheckedDeleteKey(vector<uint8_t>* key_blob, bool keep_key_blob) {
-    ErrorCode result = DeleteKey(key_blob, keep_key_blob);
-    EXPECT_TRUE(result == ErrorCode::OK || result == ErrorCode::UNIMPLEMENTED) << result << endl;
-}
-
 void KeyMintAidlTestBase::CheckedDeleteKey() {
-    CheckedDeleteKey(&key_blob_);
+    ErrorCode result = DeleteKey(&key_blob_, /* keep_key_blob = */ false);
+    EXPECT_TRUE(result == ErrorCode::OK || result == ErrorCode::UNIMPLEMENTED) << result << endl;
 }
 
 ErrorCode KeyMintAidlTestBase::Begin(KeyPurpose purpose, const vector<uint8_t>& key_blob,
@@ -1555,6 +1554,89 @@
     return result;
 }
 
+ErrorCode KeyMintAidlTestBase::GenerateAttestKey(const AuthorizationSet& key_desc,
+                                                 const optional<AttestationKey>& attest_key,
+                                                 vector<uint8_t>* key_blob,
+                                                 vector<KeyCharacteristics>* key_characteristics,
+                                                 vector<Certificate>* cert_chain) {
+    // The original specification for KeyMint v1 required ATTEST_KEY not be combined
+    // with any other key purpose, but the original VTS tests incorrectly did exactly that.
+    // This means that a device that launched prior to Android T (API level 33) may
+    // accept or even require KeyPurpose::SIGN too.
+    if (property_get_int32("ro.board.first_api_level", 0) < __ANDROID_API_T__) {
+        AuthorizationSet key_desc_plus_sign = key_desc;
+        key_desc_plus_sign.push_back(TAG_PURPOSE, KeyPurpose::SIGN);
+
+        auto result = GenerateKey(key_desc_plus_sign, attest_key, key_blob, key_characteristics,
+                                  cert_chain);
+        if (result == ErrorCode::OK) {
+            return result;
+        }
+        // If the key generation failed, it may be because the device is (correctly)
+        // rejecting the combination of ATTEST_KEY+SIGN.  Fall through to try again with
+        // just ATTEST_KEY.
+    }
+    return GenerateKey(key_desc, attest_key, key_blob, key_characteristics, cert_chain);
+}
+
+// Check if ATTEST_KEY feature is disabled
+bool KeyMintAidlTestBase::is_attest_key_feature_disabled(void) const {
+    if (!check_feature(FEATURE_KEYSTORE_APP_ATTEST_KEY)) {
+        GTEST_LOG_(INFO) << "Feature " + FEATURE_KEYSTORE_APP_ATTEST_KEY + " is disabled";
+        return true;
+    }
+
+    return false;
+}
+
+// Check if StrongBox KeyStore is enabled
+bool KeyMintAidlTestBase::is_strongbox_enabled(void) const {
+    if (check_feature(FEATURE_STRONGBOX_KEYSTORE)) {
+        GTEST_LOG_(INFO) << "Feature " + FEATURE_STRONGBOX_KEYSTORE + " is enabled";
+        return true;
+    }
+
+    return false;
+}
+
+// Check if chipset has received a waiver allowing it to be launched with Android S or T with
+// Keymaster 4.0 in StrongBox.
+bool KeyMintAidlTestBase::is_chipset_allowed_km4_strongbox(void) const {
+    std::array<char, PROPERTY_VALUE_MAX> buffer;
+
+    const int32_t first_api_level = property_get_int32("ro.board.first_api_level", 0);
+    if (first_api_level <= 0 || first_api_level > __ANDROID_API_T__) return false;
+
+    auto res = property_get("ro.vendor.qti.soc_model", buffer.data(), nullptr);
+    if (res <= 0) return false;
+
+    const string allowed_soc_models[] = {"SM8450", "SM8475", "SM8550", "SXR2230P",
+                                         "SM4450", "SM7450", "SM6450"};
+
+    for (const string model : allowed_soc_models) {
+        if (model.compare(buffer.data()) == 0) {
+            GTEST_LOG_(INFO) << "QTI SOC Model " + model + " is allowed SB KM 4.0";
+            return true;
+        }
+    }
+
+    return false;
+}
+
+// Skip the test if all the following conditions hold:
+// 1. ATTEST_KEY feature is disabled
+// 2. STRONGBOX is enabled
+// 3. The device is running one of the chipsets that have received a waiver
+//     allowing it to be launched with Android S (or later) with Keymaster 4.0
+//     in StrongBox
+void KeyMintAidlTestBase::skipAttestKeyTest(void) const {
+    // Check the chipset first as that doesn't require a round-trip to Package Manager.
+    if (is_chipset_allowed_km4_strongbox() && is_strongbox_enabled() &&
+        is_attest_key_feature_disabled()) {
+        GTEST_SKIP() << "Test is not applicable";
+    }
+}
+
 void verify_serial(X509* cert, const uint64_t expected_serial) {
     BIGNUM_Ptr ser(BN_new());
     EXPECT_TRUE(ASN1_INTEGER_to_BN(X509_get_serialNumber(cert), ser.get()));
@@ -1908,6 +1990,16 @@
     return AssertionSuccess();
 }
 
+ErrorCode GetReturnErrorCode(const Status& result) {
+    if (result.isOk()) return ErrorCode::OK;
+
+    if (result.getExceptionCode() == EX_SERVICE_SPECIFIC) {
+        return static_cast<ErrorCode>(result.getServiceSpecificError());
+    }
+
+    return ErrorCode::UNKNOWN_ERROR;
+}
+
 X509_Ptr parse_cert_blob(const vector<uint8_t>& blob) {
     const uint8_t* p = blob.data();
     return X509_Ptr(d2i_X509(nullptr /* allocate new */, &p, blob.size()));
@@ -2077,14 +2169,32 @@
     *signingKey = std::move(pubKey);
 }
 
-void device_id_attestation_vsr_check(const ErrorCode& result) {
-    if (get_vsr_api_level() > __ANDROID_API_T__) {
-        ASSERT_FALSE(result == ErrorCode::INVALID_TAG)
+// Check the error code from an attempt to perform device ID attestation with an invalid value.
+void device_id_attestation_check_acceptable_error(Tag tag, const ErrorCode& result) {
+    // Standard/default error code for ID mismatch.
+    if (result == ErrorCode::CANNOT_ATTEST_IDS) {
+        return;
+    }
+
+    // Depending on the situation, other error codes may be acceptable.  First, allow older
+    // implementations to use INVALID_TAG.
+    if (result == ErrorCode::INVALID_TAG) {
+        ASSERT_FALSE(get_vsr_api_level() > __ANDROID_API_T__)
                 << "It is a specification violation for INVALID_TAG to be returned due to ID "
                 << "mismatch in a Device ID Attestation call. INVALID_TAG is only intended to "
                 << "be used for a case where updateAad() is called after update(). As of "
                 << "VSR-14, this is now enforced as an error.";
     }
+
+    // If the device is not a phone, it will not have IMEI/MEID values available.  Allow
+    // ATTESTATION_IDS_NOT_PROVISIONED in this case.
+    if (result == ErrorCode::ATTESTATION_IDS_NOT_PROVISIONED) {
+        ASSERT_TRUE((tag == TAG_ATTESTATION_ID_IMEI || tag == TAG_ATTESTATION_ID_MEID ||
+                     tag == TAG_ATTESTATION_ID_SECOND_IMEI))
+                << "incorrect error code on attestation ID mismatch";
+    }
+    ADD_FAILURE() << "Error code " << result
+                  << " returned on attestation ID mismatch, should be CANNOT_ATTEST_IDS";
 }
 
 // Check whether the given named feature is available.
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
index 3245ca9..0d0790f 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
@@ -54,6 +54,21 @@
 
 constexpr uint64_t kOpHandleSentinel = 0xFFFFFFFFFFFFFFFF;
 
+const string FEATURE_KEYSTORE_APP_ATTEST_KEY = "android.hardware.keystore.app_attest_key";
+const string FEATURE_STRONGBOX_KEYSTORE = "android.hardware.strongbox_keystore";
+
+// RAII class to ensure that a keyblob is deleted regardless of how a test exits.
+class KeyBlobDeleter {
+  public:
+    KeyBlobDeleter(const shared_ptr<IKeyMintDevice>& keymint, const vector<uint8_t>& key_blob)
+        : keymint_(keymint), key_blob_(key_blob) {}
+    ~KeyBlobDeleter();
+
+  private:
+    shared_ptr<IKeyMintDevice> keymint_;
+    vector<uint8_t> key_blob_;
+};
+
 class KeyMintAidlTestBase : public ::testing::TestWithParam<string> {
   public:
     struct KeyData {
@@ -67,6 +82,8 @@
     // Directory to store/retrieve keyblobs, using subdirectories named for the
     // KeyMint instance in question (e.g. "./default/", "./strongbox/").
     static std::string keyblob_dir;
+    // To specify if users expect an upgrade on the keyBlobs.
+    static std::optional<bool> expect_upgrade;
 
     void SetUp() override;
     void TearDown() override {
@@ -89,8 +106,6 @@
 
     bool Curve25519Supported();
 
-    ErrorCode GetReturnErrorCode(const Status& result);
-
     ErrorCode GenerateKey(const AuthorizationSet& key_desc, vector<uint8_t>* key_blob,
                           vector<KeyCharacteristics>* key_characteristics) {
         return GenerateKey(key_desc, std::nullopt /* attest_key */, key_blob, key_characteristics,
@@ -154,7 +169,6 @@
 
     ErrorCode DestroyAttestationIds();
 
-    void CheckedDeleteKey(vector<uint8_t>* key_blob, bool keep_key_blob = false);
     void CheckedDeleteKey();
 
     ErrorCode Begin(KeyPurpose purpose, const vector<uint8_t>& key_blob,
@@ -347,6 +361,17 @@
     ErrorCode UseRsaKey(const vector<uint8_t>& rsaKeyBlob);
     ErrorCode UseEcdsaKey(const vector<uint8_t>& ecdsaKeyBlob);
 
+    ErrorCode GenerateAttestKey(const AuthorizationSet& key_desc,
+                                const optional<AttestationKey>& attest_key,
+                                vector<uint8_t>* key_blob,
+                                vector<KeyCharacteristics>* key_characteristics,
+                                vector<Certificate>* cert_chain);
+
+    bool is_attest_key_feature_disabled(void) const;
+    bool is_strongbox_enabled(void) const;
+    bool is_chipset_allowed_km4_strongbox(void) const;
+    void skipAttestKeyTest(void) const;
+
   protected:
     std::shared_ptr<IKeyMintDevice> keymint_;
     uint32_t os_version_;
@@ -407,7 +432,7 @@
 void check_maced_pubkey(const MacedPublicKey& macedPubKey, bool testMode,
                         vector<uint8_t>* payload_value);
 void p256_pub_key(const vector<uint8_t>& coseKeyData, EVP_PKEY_Ptr* signingKey);
-void device_id_attestation_vsr_check(const ErrorCode& result);
+void device_id_attestation_check_acceptable_error(Tag tag, const ErrorCode& result);
 bool check_feature(const std::string& name);
 
 AuthorizationSet HwEnforcedAuthorizations(const vector<KeyCharacteristics>& key_characteristics);
@@ -415,6 +440,8 @@
 ::testing::AssertionResult ChainSignaturesAreValid(const vector<Certificate>& chain,
                                                    bool strict_issuer_check = true);
 
+ErrorCode GetReturnErrorCode(const Status& result);
+
 #define INSTANTIATE_KEYMINT_AIDL_TEST(name)                                          \
     INSTANTIATE_TEST_SUITE_P(PerInstance, name,                                      \
                              testing::ValuesIn(KeyMintAidlTestBase::build_params()), \
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index 0a70baf..43dc626 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -693,6 +693,7 @@
                     builder.Authorization(TAG_MIN_MAC_LENGTH, 128);
                 }
                 ASSERT_EQ(ErrorCode::OK, GenerateKey(builder, &key_blob, &key_characteristics));
+                KeyBlobDeleter deleter(keymint_, key_blob);
 
                 EXPECT_GT(key_blob.size(), 0U);
                 CheckSymmetricParams(key_characteristics);
@@ -703,8 +704,6 @@
                 EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::AES));
                 EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size))
                         << "Key size " << key_size << "missing";
-
-                CheckedDeleteKey(&key_blob);
             }
         }
     }
@@ -877,6 +876,7 @@
                                                              .Authorization(TAG_NO_AUTH_REQUIRED)
                                                              .SetDefaultValidity(),
                                                      &key_blob, &key_characteristics));
+                KeyBlobDeleter deleter(keymint_, key_blob);
 
                 EXPECT_GT(key_blob.size(), 0U);
                 CheckSymmetricParams(key_characteristics);
@@ -887,8 +887,6 @@
                 EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::TRIPLE_DES));
                 EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size))
                         << "Key size " << key_size << "missing";
-
-                CheckedDeleteKey(&key_blob);
             }
         }
     }
@@ -924,6 +922,7 @@
                                                              .AttestationApplicationId(app_id)
                                                              .SetDefaultValidity(),
                                                      &key_blob, &key_characteristics));
+                KeyBlobDeleter deleter(keymint_, key_blob);
 
                 EXPECT_GT(key_blob.size(), 0U);
                 CheckSymmetricParams(key_characteristics);
@@ -934,8 +933,6 @@
                 EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::TRIPLE_DES));
                 EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size))
                         << "Key size " << key_size << "missing";
-
-                CheckedDeleteKey(&key_blob);
             }
         }
     }
@@ -1003,6 +1000,7 @@
                                                      .Padding(PaddingMode::NONE)
                                                      .SetDefaultValidity(),
                                              &key_blob, &key_characteristics));
+        KeyBlobDeleter deleter(keymint_, key_blob);
 
         ASSERT_GT(key_blob.size(), 0U);
         CheckBaseParams(key_characteristics);
@@ -1014,8 +1012,6 @@
         EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size))
                 << "Key size " << key_size << "missing";
         EXPECT_TRUE(crypto_params.Contains(TAG_RSA_PUBLIC_EXPONENT, 65537U));
-
-        CheckedDeleteKey(&key_blob);
     }
 }
 
@@ -1139,6 +1135,7 @@
             }
         }
         ASSERT_EQ(ErrorCode::OK, result);
+        KeyBlobDeleter deleter(keymint_, key_blob);
         ASSERT_GT(key_blob.size(), 0U);
         CheckBaseParams(key_characteristics);
         CheckCharacteristics(key_blob, key_characteristics);
@@ -1159,8 +1156,6 @@
         EXPECT_TRUE(verify_attestation_record(AidlVersion(), challenge, app_id,  //
                                               sw_enforced, hw_enforced, SecLevel(),
                                               cert_chain_[0].encodedCertificate));
-
-        CheckedDeleteKey(&key_blob);
     }
 }
 
@@ -1214,6 +1209,7 @@
                                       .Authorization(TAG_NO_AUTH_REQUIRED)
                                       .SetDefaultValidity(),
                               attestation_key, &key_blob, &key_characteristics, &cert_chain_));
+        KeyBlobDeleter deleter(keymint_, key_blob);
 
         ASSERT_GT(key_blob.size(), 0U);
         CheckBaseParams(key_characteristics);
@@ -1240,8 +1236,6 @@
         ASSERT_TRUE(X509_verify(key_cert.get(), signing_pubkey.get()))
                 << "Verification of attested certificate failed "
                 << "OpenSSL error string: " << ERR_error_string(ERR_get_error(), NULL);
-
-        CheckedDeleteKey(&key_blob);
     }
 }
 
@@ -1294,6 +1288,7 @@
                                       .Authorization(TAG_NO_AUTH_REQUIRED)
                                       .SetDefaultValidity(),
                               attestation_key, &key_blob, &key_characteristics, &cert_chain_));
+        KeyBlobDeleter deleter(keymint_, key_blob);
 
         ASSERT_GT(key_blob.size(), 0U);
         CheckBaseParams(key_characteristics);
@@ -1318,8 +1313,6 @@
         ASSERT_TRUE(X509_verify(key_cert.get(), signing_pubkey.get()))
                 << "Verification of attested certificate failed "
                 << "OpenSSL error string: " << ERR_error_string(ERR_get_error(), NULL);
-
-        CheckedDeleteKey(&key_blob);
     }
 }
 
@@ -1365,6 +1358,7 @@
         }
     }
     ASSERT_EQ(ErrorCode::OK, result);
+    KeyBlobDeleter deleter(keymint_, key_blob);
 
     ASSERT_GT(key_blob.size(), 0U);
     AuthorizationSet auths;
@@ -1405,8 +1399,6 @@
     EXPECT_TRUE(verify_attestation_record(AidlVersion(), challenge, app_id,  //
                                           sw_enforced, hw_enforced, SecLevel(),
                                           cert_chain_[0].encodedCertificate));
-
-    CheckedDeleteKey(&key_blob);
 }
 
 /*
@@ -1437,6 +1429,7 @@
                                       .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
                                       .SetDefaultValidity(),
                               &key_blob, &key_characteristics));
+        KeyBlobDeleter deleter(keymint_, key_blob);
 
         ASSERT_GT(key_blob.size(), 0U);
         CheckBaseParams(key_characteristics);
@@ -1452,8 +1445,6 @@
         ASSERT_EQ(cert_chain_.size(), 1);
         verify_subject_and_serial(cert_chain_[0], serial_int, subject, false);
         EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
-
-        CheckedDeleteKey(&key_blob);
     }
 }
 
@@ -1518,6 +1509,7 @@
                                   .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
                                   .SetDefaultValidity(),
                           &key_blob, &key_characteristics));
+    KeyBlobDeleter deleter(keymint_, key_blob);
 
     ASSERT_GT(key_blob.size(), 0U);
     CheckBaseParams(key_characteristics);
@@ -1534,8 +1526,6 @@
     verify_subject_and_serial(cert_chain_[0], serial_int, subject, false);
     EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
     ASSERT_EQ(cert_chain_.size(), 1);
-
-    CheckedDeleteKey(&key_blob);
 }
 
 /*
@@ -1556,6 +1546,7 @@
                                                      .Authorization(TAG_USAGE_COUNT_LIMIT, 1)
                                                      .SetDefaultValidity(),
                                              &key_blob, &key_characteristics));
+        KeyBlobDeleter deleter(keymint_, key_blob);
 
         ASSERT_GT(key_blob.size(), 0U);
         CheckBaseParams(key_characteristics);
@@ -1575,8 +1566,6 @@
         }
         EXPECT_TRUE(auths.Contains(TAG_USAGE_COUNT_LIMIT, 1U))
                 << "key usage count limit " << 1U << " missing";
-
-        CheckedDeleteKey(&key_blob);
     }
 }
 
@@ -1625,6 +1614,7 @@
             }
         }
         ASSERT_EQ(ErrorCode::OK, result);
+        KeyBlobDeleter deleter(keymint_, key_blob);
 
         ASSERT_GT(key_blob.size(), 0U);
         CheckBaseParams(key_characteristics);
@@ -1655,8 +1645,6 @@
         EXPECT_TRUE(verify_attestation_record(AidlVersion(), challenge, app_id,  //
                                               sw_enforced, hw_enforced, SecLevel(),
                                               cert_chain_[0].encodedCertificate));
-
-        CheckedDeleteKey(&key_blob);
     }
 }
 
@@ -1726,6 +1714,7 @@
                                                      .Digest(Digest::NONE)
                                                      .SetDefaultValidity(),
                                              &key_blob, &key_characteristics));
+        KeyBlobDeleter deleter(keymint_, key_blob);
         ASSERT_GT(key_blob.size(), 0U);
         CheckBaseParams(key_characteristics);
         CheckCharacteristics(key_blob, key_characteristics);
@@ -1734,8 +1723,6 @@
 
         EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::EC));
         EXPECT_TRUE(crypto_params.Contains(TAG_EC_CURVE, curve)) << "Curve " << curve << "missing";
-
-        CheckedDeleteKey(&key_blob);
     }
 }
 
@@ -1759,6 +1746,8 @@
                                            .SetDefaultValidity(),
                                    &key_blob, &key_characteristics);
     ASSERT_EQ(result, ErrorCode::OK);
+    KeyBlobDeleter deleter(keymint_, key_blob);
+
     ASSERT_GT(key_blob.size(), 0U);
 
     EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
@@ -1771,8 +1760,6 @@
 
     EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::EC));
     EXPECT_TRUE(crypto_params.Contains(TAG_EC_CURVE, curve)) << "Curve " << curve << "missing";
-
-    CheckedDeleteKey(&key_blob);
 }
 
 /*
@@ -1879,6 +1866,7 @@
             }
         }
         ASSERT_EQ(ErrorCode::OK, result);
+        KeyBlobDeleter deleter(keymint_, key_blob);
         ASSERT_GT(key_blob.size(), 0U);
         CheckBaseParams(key_characteristics);
         CheckCharacteristics(key_blob, key_characteristics);
@@ -1897,8 +1885,6 @@
         EXPECT_TRUE(verify_attestation_record(AidlVersion(), challenge, app_id,  //
                                               sw_enforced, hw_enforced, SecLevel(),
                                               cert_chain_[0].encodedCertificate));
-
-        CheckedDeleteKey(&key_blob);
     }
 }
 
@@ -1936,6 +1922,7 @@
                                            .SetDefaultValidity(),
                                    &key_blob, &key_characteristics);
     ASSERT_EQ(ErrorCode::OK, result);
+    KeyBlobDeleter deleter(keymint_, key_blob);
     ASSERT_GT(key_blob.size(), 0U);
     CheckBaseParams(key_characteristics);
     CheckCharacteristics(key_blob, key_characteristics);
@@ -1954,8 +1941,6 @@
     EXPECT_TRUE(verify_attestation_record(AidlVersion(), challenge, app_id,  //
                                           sw_enforced, hw_enforced, SecLevel(),
                                           cert_chain_[0].encodedCertificate));
-
-    CheckedDeleteKey(&key_blob);
 }
 
 /*
@@ -2024,6 +2009,7 @@
             }
         }
         ASSERT_EQ(result, ErrorCode::OK);
+        KeyBlobDeleter deleter(keymint_, key_blob);
         ASSERT_GT(key_blob.size(), 0U);
 
         EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
@@ -2043,8 +2029,6 @@
         EXPECT_TRUE(verify_attestation_record(AidlVersion(), challenge, app_id, sw_enforced,
                                               hw_enforced, SecLevel(),
                                               cert_chain_[0].encodedCertificate));
-
-        CheckedDeleteKey(&key_blob);
     }
 
     // Collection of invalid attestation ID tags.
@@ -2170,6 +2154,7 @@
             continue;
         }
         ASSERT_EQ(result, ErrorCode::OK);
+        KeyBlobDeleter deleter(keymint_, key_blob);
         ASSERT_GT(key_blob.size(), 0U);
 
         EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
@@ -2189,8 +2174,6 @@
         EXPECT_TRUE(verify_attestation_record(AidlVersion(), challenge, app_id, sw_enforced,
                                               hw_enforced, SecLevel(),
                                               cert_chain_[0].encodedCertificate));
-
-        CheckedDeleteKey(&key_blob);
     }
 }
 
@@ -2345,6 +2328,7 @@
         }
     }
     ASSERT_EQ(result, ErrorCode::OK);
+    KeyBlobDeleter deleter(keymint_, key_blob);
     ASSERT_GT(key_blob.size(), 0U);
 
     EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
@@ -2364,8 +2348,6 @@
     ASSERT_EQ(std::search(cert_chain_[0].encodedCertificate.begin(),
                           cert_chain_[0].encodedCertificate.end(), needle.begin(), needle.end()),
               cert_chain_[0].encodedCertificate.end());
-
-    CheckedDeleteKey(&key_blob);
 }
 
 /*
@@ -2393,6 +2375,7 @@
                                       .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
                                       .SetDefaultValidity(),
                               &key_blob, &key_characteristics));
+        KeyBlobDeleter deleter(keymint_, key_blob);
         ASSERT_GT(key_blob.size(), 0U);
         CheckBaseParams(key_characteristics);
         CheckCharacteristics(key_blob, key_characteristics);
@@ -2408,8 +2391,6 @@
 
         AuthorizationSet hw_enforced = HwEnforcedAuthorizations(key_characteristics);
         AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics);
-
-        CheckedDeleteKey(&key_blob);
     }
 }
 
@@ -2463,6 +2444,7 @@
                                                      .AttestationApplicationId(app_id)
                                                      .SetDefaultValidity(),
                                              &key_blob, &key_characteristics));
+        KeyBlobDeleter deleter(keymint_, key_blob);
 
         ASSERT_GT(key_blob.size(), 0U);
         CheckBaseParams(key_characteristics);
@@ -2478,8 +2460,6 @@
 
         AuthorizationSet hw_enforced = HwEnforcedAuthorizations(key_characteristics);
         AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics);
-
-        CheckedDeleteKey(&key_blob);
     }
 }
 
@@ -2521,6 +2501,7 @@
             }
         }
         ASSERT_EQ(ErrorCode::OK, result);
+        KeyBlobDeleter deleter(keymint_, key_blob);
         ASSERT_GT(key_blob.size(), 0U);
         CheckBaseParams(key_characteristics);
         CheckCharacteristics(key_blob, key_characteristics);
@@ -2538,8 +2519,6 @@
         EXPECT_TRUE(verify_attestation_record(AidlVersion(), challenge, app_id,  //
                                               sw_enforced, hw_enforced, SecLevel(),
                                               cert_chain_[0].encodedCertificate));
-
-        CheckedDeleteKey(&key_blob);
     }
 }
 
@@ -2560,6 +2539,7 @@
                                                      .Authorization(TAG_USAGE_COUNT_LIMIT, 1)
                                                      .SetDefaultValidity(),
                                              &key_blob, &key_characteristics));
+        KeyBlobDeleter deleter(keymint_, key_blob);
 
         ASSERT_GT(key_blob.size(), 0U);
         CheckBaseParams(key_characteristics);
@@ -2577,8 +2557,6 @@
         }
         EXPECT_TRUE(auths.Contains(TAG_USAGE_COUNT_LIMIT, 1U))
                 << "key usage count limit " << 1U << " missing";
-
-        CheckedDeleteKey(&key_blob);
     }
 }
 
@@ -2710,6 +2688,7 @@
                           AuthorizationSetBuilder().HmacKey(key_size).Digest(digest).Authorization(
                                   TAG_MIN_MAC_LENGTH, 128),
                           &key_blob, &key_characteristics));
+        KeyBlobDeleter deleter(keymint_, key_blob);
 
         ASSERT_GT(key_blob.size(), 0U);
         CheckBaseParams(key_characteristics);
@@ -2719,8 +2698,6 @@
         EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::HMAC));
         EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size))
                 << "Key size " << key_size << "missing";
-
-        CheckedDeleteKey(&key_blob);
     }
 }
 
@@ -2746,6 +2723,7 @@
                                                      .AttestationApplicationId(app_id)
                                                      .Authorization(TAG_MIN_MAC_LENGTH, 128),
                                              &key_blob, &key_characteristics));
+        KeyBlobDeleter deleter(keymint_, key_blob);
 
         ASSERT_GT(key_blob.size(), 0U);
         ASSERT_EQ(cert_chain_.size(), 0);
@@ -2756,8 +2734,6 @@
         EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::HMAC));
         EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size))
                 << "Key size " << key_size << "missing";
-
-        CheckedDeleteKey(&key_blob);
     }
 }
 
@@ -2779,6 +2755,7 @@
                                                      .Authorization(TAG_MIN_MAC_LENGTH, 128)
                                                      .Authorization(TAG_USAGE_COUNT_LIMIT, 1),
                                              &key_blob, &key_characteristics));
+        KeyBlobDeleter deleter(keymint_, key_blob);
 
         ASSERT_GT(key_blob.size(), 0U);
         CheckBaseParams(key_characteristics);
@@ -2796,8 +2773,6 @@
         }
         EXPECT_TRUE(auths.Contains(TAG_USAGE_COUNT_LIMIT, 1U))
                 << "key usage count limit " << 1U << " missing";
-
-        CheckedDeleteKey(&key_blob);
     }
 }
 
@@ -3119,7 +3094,7 @@
  */
 TEST_P(SigningOperationsTest, NoUserConfirmation) {
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
-                                                 .RsaSigningKey(1024, 65537)
+                                                 .RsaSigningKey(2048, 65537)
                                                  .Digest(Digest::NONE)
                                                  .Padding(PaddingMode::NONE)
                                                  .Authorization(TAG_NO_AUTH_REQUIRED)
@@ -3891,6 +3866,7 @@
                                 .Digest(Digest::SHA_2_256)
                                 .Authorization(TAG_MIN_MAC_LENGTH, 160),
                         KeyFormat::RAW, key_material, &signing_key, &signing_key_chars));
+    KeyBlobDeleter sign_deleter(keymint_, signing_key);
     EXPECT_EQ(ErrorCode::OK,
               ImportKey(AuthorizationSetBuilder()
                                 .Authorization(TAG_NO_AUTH_REQUIRED)
@@ -3899,6 +3875,7 @@
                                 .Digest(Digest::SHA_2_256)
                                 .Authorization(TAG_MIN_MAC_LENGTH, 160),
                         KeyFormat::RAW, key_material, &verification_key, &verification_key_chars));
+    KeyBlobDeleter verify_deleter(keymint_, verification_key);
 
     string message = "This is a message.";
     string signature = SignMessage(
@@ -3914,9 +3891,6 @@
     // Verification key should work.
     VerifyMessage(verification_key, message, signature,
                   AuthorizationSetBuilder().Digest(Digest::SHA_2_256));
-
-    CheckedDeleteKey(&signing_key);
-    CheckedDeleteKey(&verification_key);
 }
 
 /*
@@ -3937,6 +3911,7 @@
                                 .Digest(Digest::SHA_2_256)
                                 .Authorization(TAG_MIN_MAC_LENGTH, 160),
                         KeyFormat::RAW, key_material, &signing_key, &signing_key_chars));
+    KeyBlobDeleter sign_deleter(keymint_, signing_key);
     EXPECT_EQ(ErrorCode::OK,
               ImportKey(AuthorizationSetBuilder()
                                 .Authorization(TAG_NO_AUTH_REQUIRED)
@@ -3945,6 +3920,7 @@
                                 .Digest(Digest::SHA_2_256)
                                 .Authorization(TAG_MIN_MAC_LENGTH, 160),
                         KeyFormat::RAW, key_material, &verification_key, &verification_key_chars));
+    KeyBlobDeleter verify_deleter(keymint_, verification_key);
 
     string message = "This is a message.";
     string signature = SignMessage(
@@ -3966,9 +3942,6 @@
 
     signature[0] += 1;  // Corrupt a signature
     EXPECT_EQ(ErrorCode::VERIFICATION_FAILED, Finish(message, signature, &output));
-
-    CheckedDeleteKey(&signing_key);
-    CheckedDeleteKey(&verification_key);
 }
 
 INSTANTIATE_KEYMINT_AIDL_TEST(VerificationOperationsTest);
@@ -8511,16 +8484,16 @@
     // Early boot keys can be created after early boot.
     auto [aesKeyData, hmacKeyData, rsaKeyData, ecdsaKeyData] =
             CreateTestKeys(TAG_EARLY_BOOT_ONLY, ErrorCode::OK);
+    KeyBlobDeleter aes_deleter(keymint_, aesKeyData.blob);
+    KeyBlobDeleter hmac_deleter(keymint_, hmacKeyData.blob);
+    KeyBlobDeleter rsa_deleter(keymint_, rsaKeyData.blob);
+    KeyBlobDeleter ecdsa_deleter(keymint_, ecdsaKeyData.blob);
 
     for (const auto& keyData : {aesKeyData, hmacKeyData, rsaKeyData, ecdsaKeyData}) {
         ASSERT_GT(keyData.blob.size(), 0U);
         AuthorizationSet crypto_params = SecLevelAuthorizations(keyData.characteristics);
         EXPECT_TRUE(crypto_params.Contains(TAG_EARLY_BOOT_ONLY)) << crypto_params;
     }
-    CheckedDeleteKey(&aesKeyData.blob);
-    CheckedDeleteKey(&hmacKeyData.blob);
-    CheckedDeleteKey(&rsaKeyData.blob);
-    CheckedDeleteKey(&ecdsaKeyData.blob);
 }
 
 /*
@@ -8534,6 +8507,10 @@
                 builder->AttestationChallenge("challenge");
                 builder->AttestationApplicationId("app_id");
             });
+    KeyBlobDeleter aes_deleter(keymint_, aesKeyData.blob);
+    KeyBlobDeleter hmac_deleter(keymint_, hmacKeyData.blob);
+    KeyBlobDeleter rsa_deleter(keymint_, rsaKeyData.blob);
+    KeyBlobDeleter ecdsa_deleter(keymint_, ecdsaKeyData.blob);
 
     for (const auto& keyData : {aesKeyData, hmacKeyData, rsaKeyData, ecdsaKeyData}) {
         // Strongbox may not support factory attestation. Key creation might fail with
@@ -8545,14 +8522,6 @@
         AuthorizationSet crypto_params = SecLevelAuthorizations(keyData.characteristics);
         EXPECT_TRUE(crypto_params.Contains(TAG_EARLY_BOOT_ONLY)) << crypto_params;
     }
-    CheckedDeleteKey(&aesKeyData.blob);
-    CheckedDeleteKey(&hmacKeyData.blob);
-    if (rsaKeyData.blob.size() != 0U) {
-        CheckedDeleteKey(&rsaKeyData.blob);
-    }
-    if (ecdsaKeyData.blob.size() != 0U) {
-        CheckedDeleteKey(&ecdsaKeyData.blob);
-    }
 }
 
 /*
@@ -8597,6 +8566,11 @@
 TEST_P(EarlyBootKeyTest, DISABLED_FullTest) {
     auto [aesKeyData, hmacKeyData, rsaKeyData, ecdsaKeyData] =
             CreateTestKeys(TAG_EARLY_BOOT_ONLY, ErrorCode::OK);
+    KeyBlobDeleter aes_deleter(keymint_, aesKeyData.blob);
+    KeyBlobDeleter hmac_deleter(keymint_, hmacKeyData.blob);
+    KeyBlobDeleter rsa_deleter(keymint_, rsaKeyData.blob);
+    KeyBlobDeleter ecdsa_deleter(keymint_, ecdsaKeyData.blob);
+
     // TAG_EARLY_BOOT_ONLY should be in hw-enforced.
     EXPECT_TRUE(HwEnforcedAuthorizations(aesKeyData.characteristics).Contains(TAG_EARLY_BOOT_ONLY));
     EXPECT_TRUE(
@@ -8621,19 +8595,13 @@
     EXPECT_EQ(ErrorCode::EARLY_BOOT_ENDED, UseRsaKey(rsaKeyData.blob));
     EXPECT_EQ(ErrorCode::EARLY_BOOT_ENDED, UseEcdsaKey(ecdsaKeyData.blob));
 
-    CheckedDeleteKey(&aesKeyData.blob);
-    CheckedDeleteKey(&hmacKeyData.blob);
-    CheckedDeleteKey(&rsaKeyData.blob);
-    CheckedDeleteKey(&ecdsaKeyData.blob);
-
     // Should not be able to create new keys
-    std::tie(aesKeyData, hmacKeyData, rsaKeyData, ecdsaKeyData) =
+    auto [aesKeyData2, hmacKeyData2, rsaKeyData2, ecdsaKeyData2] =
             CreateTestKeys(TAG_EARLY_BOOT_ONLY, ErrorCode::EARLY_BOOT_ENDED);
-
-    CheckedDeleteKey(&aesKeyData.blob);
-    CheckedDeleteKey(&hmacKeyData.blob);
-    CheckedDeleteKey(&rsaKeyData.blob);
-    CheckedDeleteKey(&ecdsaKeyData.blob);
+    KeyBlobDeleter aes_deleter2(keymint_, aesKeyData2.blob);
+    KeyBlobDeleter hmac_deleter2(keymint_, hmacKeyData2.blob);
+    KeyBlobDeleter rsa_deleter2(keymint_, rsaKeyData2.blob);
+    KeyBlobDeleter ecdsa_deleter2(keymint_, ecdsaKeyData2.blob);
 }
 
 INSTANTIATE_KEYMINT_AIDL_TEST(EarlyBootKeyTest);
@@ -8651,6 +8619,10 @@
 TEST_P(UnlockedDeviceRequiredTest, DISABLED_KeysBecomeUnusable) {
     auto [aesKeyData, hmacKeyData, rsaKeyData, ecdsaKeyData] =
             CreateTestKeys(TAG_UNLOCKED_DEVICE_REQUIRED, ErrorCode::OK);
+    KeyBlobDeleter aes_deleter(keymint_, aesKeyData.blob);
+    KeyBlobDeleter hmac_deleter(keymint_, hmacKeyData.blob);
+    KeyBlobDeleter rsa_deleter(keymint_, rsaKeyData.blob);
+    KeyBlobDeleter ecdsa_deleter(keymint_, ecdsaKeyData.blob);
 
     EXPECT_EQ(ErrorCode::OK, UseAesKey(aesKeyData.blob));
     EXPECT_EQ(ErrorCode::OK, UseHmacKey(hmacKeyData.blob));
@@ -8664,11 +8636,6 @@
     EXPECT_EQ(ErrorCode::DEVICE_LOCKED, UseHmacKey(hmacKeyData.blob));
     EXPECT_EQ(ErrorCode::DEVICE_LOCKED, UseRsaKey(rsaKeyData.blob));
     EXPECT_EQ(ErrorCode::DEVICE_LOCKED, UseEcdsaKey(ecdsaKeyData.blob));
-
-    CheckedDeleteKey(&aesKeyData.blob);
-    CheckedDeleteKey(&hmacKeyData.blob);
-    CheckedDeleteKey(&rsaKeyData.blob);
-    CheckedDeleteKey(&ecdsaKeyData.blob);
 }
 
 INSTANTIATE_KEYMINT_AIDL_TEST(UnlockedDeviceRequiredTest);
@@ -8732,6 +8699,19 @@
                         std::string(argv[i + 1]);
                 ++i;
             }
+            if (std::string(argv[i]) == "--expect_upgrade") {
+                if (i + 1 >= argc) {
+                    std::cerr << "Missing argument for --expect_upgrade\n";
+                    return 1;
+                }
+                std::string arg = argv[i + 1];
+                aidl::android::hardware::security::keymint::test::KeyMintAidlTestBase::
+                        expect_upgrade =
+                                arg == "yes"
+                                        ? true
+                                        : (arg == "no" ? false : std::optional<bool>(std::nullopt));
+                ++i;
+            }
         }
     }
     return RUN_ALL_TESTS();
diff --git a/security/keymint/support/remote_prov_utils.cpp b/security/keymint/support/remote_prov_utils.cpp
index 3cb783c..c9c3e4d 100644
--- a/security/keymint/support/remote_prov_utils.cpp
+++ b/security/keymint/support/remote_prov_utils.cpp
@@ -115,6 +115,36 @@
     return std::make_tuple(std::move(pubX), std::move(pubY));
 }
 
+ErrMsgOr<bytevec> getRawPublicKey(const EVP_PKEY_Ptr& pubKey) {
+    if (pubKey.get() == nullptr) {
+        return "pkey is null.";
+    }
+    int keyType = EVP_PKEY_base_id(pubKey.get());
+    switch (keyType) {
+        case EVP_PKEY_EC: {
+            auto ecKey = EC_KEY_Ptr(EVP_PKEY_get1_EC_KEY(pubKey.get()));
+            if (ecKey.get() == nullptr) {
+                return "Failed to get ec key";
+            }
+            return ecKeyGetPublicKey(ecKey.get());
+        }
+        case EVP_PKEY_ED25519: {
+            bytevec rawPubKey;
+            size_t rawKeySize = 0;
+            if (!EVP_PKEY_get_raw_public_key(pubKey.get(), NULL, &rawKeySize)) {
+                return "Failed to get raw public key.";
+            }
+            rawPubKey.resize(rawKeySize);
+            if (!EVP_PKEY_get_raw_public_key(pubKey.get(), rawPubKey.data(), &rawKeySize)) {
+                return "Failed to get raw public key.";
+            }
+            return rawPubKey;
+        }
+        default:
+            return "Unknown key type.";
+    }
+}
+
 ErrMsgOr<std::tuple<bytevec, bytevec>> generateEc256KeyPair() {
     auto ec_key = EC_KEY_Ptr(EC_KEY_new());
     if (ec_key.get() == nullptr) {
@@ -706,11 +736,10 @@
 
 // Validates the certificate chain and returns the leaf public key.
 ErrMsgOr<bytevec> validateCertChain(const cppbor::Array& chain) {
-    uint8_t rawPubKey[64];
-    size_t rawPubKeySize = sizeof(rawPubKey);
+    bytevec rawPubKey;
     for (size_t i = 0; i < chain.size(); ++i) {
         // Root must be self-signed.
-        size_t signingCertIndex = (i > 1) ? i - 1 : i;
+        size_t signingCertIndex = (i > 0) ? i - 1 : i;
         auto& keyCertItem = chain[i];
         auto& signingCertItem = chain[signingCertIndex];
         if (!keyCertItem || !keyCertItem->asBstr()) {
@@ -724,7 +753,7 @@
         if (!keyCert) {
             return keyCert.message();
         }
-        auto signingCert = parseX509Cert(keyCertItem->asBstr()->value());
+        auto signingCert = parseX509Cert(signingCertItem->asBstr()->value());
         if (!signingCert) {
             return signingCert.message();
         }
@@ -749,17 +778,16 @@
             return "Certificate " + std::to_string(i) + " has wrong issuer. Signer subject is " +
                    signerSubj + " Issuer subject is " + certIssuer;
         }
-
-        rawPubKeySize = sizeof(rawPubKey);
-        if (!EVP_PKEY_get_raw_public_key(pubKey.get(), rawPubKey, &rawPubKeySize)) {
-            return "Failed to get raw public key.";
+        if (i == chain.size() - 1) {
+            auto key = getRawPublicKey(pubKey);
+            if (!key) key.moveMessage();
+            rawPubKey = key.moveValue();
         }
     }
-
-    return bytevec(rawPubKey, rawPubKey + rawPubKeySize);
+    return rawPubKey;
 }
 
-std::string validateUdsCerts(const cppbor::Map& udsCerts, const bytevec& udsPub) {
+std::string validateUdsCerts(const cppbor::Map& udsCerts, const bytevec& udsCoseKeyBytes) {
     for (const auto& [signerName, udsCertChain] : udsCerts) {
         if (!signerName || !signerName->asTstr()) {
             return "Signer Name must be a Tstr.";
@@ -775,8 +803,31 @@
         if (!leafPubKey) {
             return leafPubKey.message();
         }
+        auto coseKey = CoseKey::parse(udsCoseKeyBytes);
+        if (!coseKey) return coseKey.moveMessage();
+
+        auto curve = coseKey->getIntValue(CoseKey::CURVE);
+        if (!curve) {
+            return "CoseKey must contain curve.";
+        }
+        bytevec udsPub;
+        if (curve == CoseKeyCurve::P256 || curve == CoseKeyCurve::P384) {
+            auto pubKey = coseKey->getEcPublicKey();
+            if (!pubKey) return pubKey.moveMessage();
+            // convert public key to uncompressed form by prepending 0x04 at begin.
+            pubKey->insert(pubKey->begin(), 0x04);
+            udsPub = pubKey.moveValue();
+        } else if (curve == CoseKeyCurve::ED25519) {
+            auto& pubkey = coseKey->getMap().get(cppcose::CoseKey::PUBKEY_X);
+            if (!pubkey || !pubkey->asBstr()) {
+                return "Invalid public key.";
+            }
+            udsPub = pubkey->asBstr()->value();
+        } else {
+            return "Unknown curve.";
+        }
         if (*leafPubKey != udsPub) {
-            return "Leaf public key in UDS certificat chain doesn't match UDS public key.";
+            return "Leaf public key in UDS certificate chain doesn't match UDS public key.";
         }
     }
     return "";
diff --git a/security/rkp/README.md b/security/rkp/README.md
index 01c90a8..f8e1d5e 100644
--- a/security/rkp/README.md
+++ b/security/rkp/README.md
@@ -3,7 +3,7 @@
 ## Objective
 
 Design a HAL to support over-the-air provisioning of certificates for asymmetric
-keys. The HAL must interact effectively with Keystore (and other daemons) and
+keys. The HAL must interact effectively with Keystore (and other services) and
 protect device privacy and security.
 
 Note that this API was originally designed for KeyMint, with the intention that
@@ -20,125 +20,52 @@
 To more securely and reliably get keys and certificates to Android devices, we
 need to create a system where no party outside of the device's secure components
 is responsible for managing private keys. The strategy we've chosen is to
-deliver certificates over the air, using an asymmetric key pair created
-on-device in the factory as a root of trust to create an authenticated, secure
-channel. In this document we refer to this device-unique asymmetric key pair as
-Device Key (DK), its public half DK\_pub, its private half DK\_priv and a Device
-Key Certificate containing DK\_pub is denoted DKC.
+deliver certificates over the air, using an asymmetric key pair derived from a
+unique device secret (UDS) as a root of trust for authenticated requests from
+the secure components. We refer to the public half of this asymmetric key pair
+as UDS\_pub.
 
-In order for the provisioning service to use DK (or a key authenticated by DK),
-it must know whether a given DK\_pub is known and trusted. To prove trust, we
-ask device OEMs to use one of two mechanisms:
+In order for the provisioning service to trust UDS\_pub we ask device OEMs to
+use one of two mechanisms:
 
-1.  (Preferred, recommended) The device OEM extracts DK\_pub from each device it
-    manufactures and uploads the public keys to a backend server.
+1.  (Preferred, recommended) The device OEM extracts the UDS\_pub from each
+    device they manufacture and uploads the public keys to a backend server.
 
-1.  The device OEM signs the DK\_pub to produce DKC and stores it on the device.
-    This has the advantage that they don't need to upload a DK\_pub for every
-    device immediately, but the disadvantage that they have to manage their
-    private signing keys, which means they have to have HSMs, configure and
-    secure them correctly, etc. Some backend providers may also require that the
-    OEM passes a factory security audit, and additionally promises to upload the
-    keys eventually as well.
+1.  The device OEM signs the UDS\_pub and stores the certificates on the device
+    rather than uploading a UDS\_pub for every device immediately. However,
+    there are many disadvantages and costs associated with this option as the
+    OEM will need to pass a security audit of their factory's physical security,
+    CA and HSM configuration, and incident response processes before the OEM's
+    public key is registered with the provisioning server.
 
-Note that in the full elaboration of this plan, DK\_pub is not the key used to
-establish a secure channel. Instead, DK\_pub is just the first public key in a
-chain of public keys which ends with the KeyMint public key, KM\_pub. All keys
-in the chain are device-unique and are joined in a certificate chain called the
-_Boot Certificate Chain_ (BCC), because in phases 2 and 3 of the remote
-provisioning project it is a chain of certificates corresponding to boot phases.
-We speak of the BCC even for phase 1, though in phase 1 it contains only a
-single self-signed DKC. This is described in more depth in the Phases section
-below.
-
-The BCC is authenticated by DK\_pub. To authenticate DK\_pub, we may have
-additional DKCs, from the SoC vendor, the device OEM, or both. Those are not
-part of the BCC but included as optional fields in the certificate request
-structure.
-
-The format of the the DK and BCC is specified within [Open Profile for DICE]
-(https://pigweed.googlesource.com/open-dice/+/HEAD/docs/specification.md).  To
-map phrases within this document to their equivalent terminology in the DICE
-specification, read the terms as follows: the DK corresponds to the UDS-derived
-key pair, DKC corresponds to the UDS certificate, and the BCC entries between
-DK\_pub and KM\_pub correspond to a chain of CDI certificates.
-
-Note: In addition to allowing 32 byte hash values for fields in the BCC payload,
-this spec additionally constrains some of the choices allowed in open-DICE.
-Specifically, these include which entries are required and which are optional in
-the BCC payload, and which algorithms are acceptable for use.
+Note that in the full elaboration of this plan, UDS\_pub is not the key used to
+sign certificate requests. Instead, UDS\_pub is just the first public key in a
+chain of public keys that end the KeyMint public key. All keys in the chain are
+transitively derived from the UDS and joined in a certificate chain following
+the specification of the [Android Profile for DICE](#android-profile-for-dice).
 
 ### Phases
 
-RKP will be deployed in three phases, in terms of managing the root of trust
+RKP will be deployed with phased management of the root of trust
 binding between the device and the backend. To briefly describe them:
 
-* Phase 1: In phase 1 there is only one entry in the BCC; DK_pub and KM_pub are
-  the same key and the certificate is self-signed.
-* Phase 2: This is identical to phase 1, except it leverages the hardware root
-  of trust process described by DICE. Instead of trust being rooted in the TEE,
-  it is now rooted in the ROM by key material blown into fuses which are only
-  accessible to the ROM code.
-* Phase 3: This is identical to Phase 2, except the SoC vendor also does the
-  public key extraction or certification in their facilities, along with the OEM
-  doing it in the factory. This tightens up the "supply chain" and aims to make
-  key upload management more secure.
+* Degenerate DICE (Phase 1): A TEE root of trust key pair is used to sign
+  certificate requests; a single self-signed certificate signifies this phase.
+* DICE (Phase 2): A hardware root of trust key pair is only accessible to ROM
+  code; the boot process follows the [Android Profile for
+  DICE](#android-profile-for-dice).
+* SoC vendor certified DICE (Phase 3): This is identical to Phase 2, except the
+  SoC vendor also does the UDS\_pub extraction or certification in their
+  facilities, along with the OEM doing it in the factory. This tightens up the
+  "supply chain" and aims to make key upload management more secure.
 
 ### Privacy considerations
 
-Because DK and the DKCs are unique, immutable, unspoofable hardware-bound
-identifiers for the device, we must limit access to them to the absolute minimum
-possible. We do this in two ways:
-
-1.  We require KeyMint (which knows the BCC and either knows or at least has the
-ability to use KM\_priv) to refuse to ever divulge the BCC or additional
-signatures in plaintext. Instead, KeyMint requires the caller to provide an
-_Endpoint Encryption Key_ (EEK), with which it will encrypt the data before
-returning it. When provisioning production keys, the EEK must be signed by an
-approved authority whose public key is embedded in KeyMint. When certifying test
-keys, KeyMint will accept any EEK without checking the signature, but will
-encrypt and return a test BCC, rather than the real one.  The result is that
-only an entity in possession of an Trusted EEK (TEEK) private key can discover
-the plaintext of the production BCC.
-1.  Having thus limited access to the public keys to the trusted party only, we
-need to prevent the entity from abusing this unique device identifier.  The
-approach and mechanisms for doing that are beyond the scope of this document
-(they must be addressed in the server design), but generally involve taking care
-to ensure that we do not create any links between user IDs, IP addresses or
-issued certificates and the device pubkey.
-
-Although the details of the mechanisms for preventing the entity from abusing
-the BCC are, as stated, beyond the scope of this document, there is a subtle
-design decision here made specifically to enable abuse prevention. Specifically
-the `CertificateRequest` message sent to the server is (in
-[CDDL](https://tools.ietf.org/html/rfc8610)):
-
-```
-cddl
-CertificateRequest = [
-    DeviceInfo,
-    challenge : bstr,
-    ProtectedData,
-    MacedKeysToSign
-]
-```
-
-The public keys to be attested by the server are in `MacedKeysToSign`, which is
-a COSE\_Mac0 structure, MACed with a key that is found in `ProtectedData`. The
-MAC key is signed by DK\_pub.
-
-This structure allows the backend component that has access to EEK\_priv to
-decrypt `ProtectedData`, validate that the request is from an authorized device,
-check that the request is fresh and verify and extract the MAC key. That backend
-component never sees any data related to the keys to be signed, but can provide
-the MAC key to another backend component that can verify `MacedKeysToSign` and
-proceed to generate the certificates.
-
-In this way, we can partition the provisioning server into one component that
-knows the device identity, as represented by DK\_pub, but never sees the keys to
-be certified or certificates generated, and another component that sees the keys
-to be certified and certificates generated but does not know the device
-identity.
+Because the UDS, CDIs and derived values are unique, immutable, unspoofable
+hardware-bound identifiers for the device, we must limit access to them. We
+require that the values are never exposed in public APIs and are only available
+to the minimum set of system components that require access to them to function
+correctly.
 
 ### Key and cryptographic message formatting
 
@@ -195,24 +122,6 @@
 choice for algorithm implies the implementor should also choose the P256 public
 key group further down in the COSE structure.
 
-### Testability
-
-It's critical that the remote provisioning implementation be testable, to
-minimize the probability that broken devices are sold to end users. To support
-testing, the remote provisioning HAL methods take a `testMode` argument. Keys
-created in test mode are tagged to indicate this. The provisioning server will
-check for the test mode tag and issue test certificates that do not chain back
-to a trusted public key. In test mode, any EEK will be accepted, enabling
-testing tools to use EEKs for which they have the private key so they can
-validate the content of certificate requests. The BCC included in the
-`CertificateRequest` must contain freshly-generated keys, not the real BCC keys.
-
-Keystore (or similar) will need to be able to handle both testMode keys and
-production keys and keep them distinct, generating test certificate requests
-when asked with a test EEK and production certificate requests when asked with a
-production EEK. Likewise, the interface used to instruct Keystore to create keys
-will need to be able to specify whether test or production keys are desired.
-
 ## Design
 
 ### Certificate provisioning flow
@@ -220,25 +129,20 @@
 TODO(jbires): Replace this with a `.png` containing a sequence diagram.  The
 provisioning flow looks something like this:
 
-Provisioner -> Keystore: Prepare N keys
-Keystore -> KeyMint: generateKeyPair
-KeyMint -> KeyMint: Generate  key pair
-KeyMint --> Keystore: key\_blob,pubkey
-Keystore -> Keystore: Store key\_blob,pubkey
-Provisioner -> Server: Get TEEK
-Server --> Provisioner: TEEK
-Provisioner -> Keystore: genCertReq(N, TEEK)
-Keystore -> KeyMint: genCertReq(pubkeys, TEEK)
-KeyMint -> KeyMint: Sign pubkeys & encrypt BCC
-KeyMint --> Keystore: signature, encrypted BCC
-Keystore -> Keystore: Construct cert\_request
-Keystore --> Provisioner: cert\_request
-Provisioner --> Server: cert\_request
-Server -> Server: Validate cert\_request
+rkpd -> KeyMint: generateKeyPair
+KeyMint -> KeyMint: Generate key pair
+KeyMint --> rkpd: key\_blob,pubkey
+rkpd -> rkpd: Store key\_blob,pubkey
+rkpd -> Server: Get challenge
+Server --> rkpd: challenge
+rkpd -> KeyMint: genCertReq(pubkeys, challenge)
+KeyMint -> KeyMint: Sign CSR
+KeyMint --> rkpd: signed CSR
+rkpd --> Server: CSR
+Server -> Server: Validate CSR
 Server -> Server: Generate certificates
-Server --> Provisioner: certificates
-Provisioner -> Keystore: certificates
-Keystore -> Keystore: Store certificates
+Server --> rkpd: certificates
+rkpd -> rkpd: Store certificates
 
 The actors in the above diagram are:
 
@@ -246,10 +150,12 @@
     the uploaded device public keys and is responsible for providing encryption
     keys, decrypting and validating requests, and generating certificates in
     response to requests.
-*   **Provisioner** is an application that is responsible for communicating with
-    the server and all of the system components that require key certificates
-    from the server. It also implements the policy that defines how many key
-    pairs each client should keep in their pool.
+*   **rkpd** is, optionally, a modular system component that is responsible for
+    communicating with the server and all of the system components that require
+    key certificates from the server. It also implements the policy that defines
+    how many key pairs each client should keep in their pool. When a system
+    ships with rkpd as a modular component, it may be updated independently from
+    the rest of the system.
 *   **Keystore** is the [Android keystore
     daemon](https://developer.android.com/training/articles/keystore) (or, more
     generally, whatever system component manages communications with a
@@ -257,45 +163,50 @@
 *   **KeyMint** is the secure area component that manages cryptographic keys and
     performs attestations (or perhaps some other secure area component).
 
-### `BCC`
+### Android Profile for DICE
 
-The _Boot Certificate Chain_ (BCC) is the chain of certificates that contains
-DK\_pub as well as other often device-unique certificates. The BCC is
-represented as a COSE\_Key containing DK\_pub followed by an array of
-COSE\_Sign1 "certificates" containing public keys and optional additional
-information, ordered from root to leaf, with each certificate signing the next.
-The first certificate in the array is signed by DK\_pub, the last certificate
-has the KeyMint (or whatever) signing key's public key, KM\_pub. In phase 1
-there is only one entry; DK\_pub and KM\_pub are the same key and the
-certificate is self-signed.
+The Android Profile for DICE is based on the [Open Profile for
+DICE](https://pigweed.googlesource.com/open-dice/+/refs/heads/main/docs/specification.md),
+with additional constraints for details that the Open Profile for DICE leaves
+intentionally underspecified. This section describes the differences from the
+Open Profile for DICE.
 
-Each COSE\_Sign1 certificate is a CBOR Web Token (CWT) as described in [RFC
-8392](https://tools.ietf.org/html/rfc8392) with additional fields as described
-in the Open Profile for DICE. Of these additional fields, only the
-_subjectPublicKey_ and _keyUsage_ fields are expected to be present for the
-KM\_pub entry (that is, the last entry) in a BCC, but all fields required by the
-Open Profile for DICE are expected for other entries (each of which corresponds
-to a particular firmware component or boot stage). The CWT fields _iss_ and
-_sub_ identify the issuer and subject of the certificate and are consistent
-along the BCC entries; the issuer of a given entry matches the subject of the
-previous entry.
+#### Algorithms
 
-The BCC is designed to be constructed using the Open Profile for DICE. In this
-case the DK key pair is derived from the UDS as described by that profile and
-all BCC entries before the leaf are CBOR CDI certificates chained from DK\_pub.
-The KM key pair is not part of the derived DICE chain. It is generated (not
-derived) by the KeyMint module, certified by the last key in the DICE chain, and
-added as the leaf BCC entry. The key usage field in this leaf certificate must
-indicate the key is not used to sign certificates. If a UDS certificate is
-available on the device it should appear in the certificate request as the leaf
-of a DKCertChain in AdditionalDKSignatures (see
-[CertificateRequest](#certificaterequest)).
+The choice of algorithm must remain consistent with a given certificate e.g. if
+SHA-256 is used for the code hash then the authority hash, config hash, etc.
+must also use SHA-256.
 
-The Open Profile for DICE allows for an arbitrary configuration descriptor. For
-BCC entries, this configuration descriptor is a CBOR map with the following
-optional fields. If no fields are relevant, an empty map should be encoded.
-Additional implementation-specific fields may be added using key values not in
-the range \[-70000, -70999\] (these are reserved for future additions here).
+* UDS and CDI key pairs:
+  * Ed25519 / P-256 / P-384
+* Hash algorithms (digests can be encoded with their natural size and do not
+  need to be the 64-bytes specified by the Open Profile for DICE):
+  * SHA-256 / SHA-384 / SHA-512
+* HKDF with a supported message digest for all key derivation
+
+#### Mode
+
+A certificate must only set the mode to `normal` when all of the following
+conditions are met when loading and verifying the software component that is
+being described by the certificate:
+
+* verified boot with anti-rollback protection is enabled
+* only the verified boot authorities for production images are enabled
+* debug ports, fuses, or other debug facilities are disabled
+* device booted software from the normal primary source e.g. internal flash
+
+The mode should never be `not configured`.
+
+Every certificate in the DICE chain will need to be have the `normal` mode in
+order to be provisioned with production certificates by RKP.
+
+#### Configuration descriptor
+
+The configuration descriptor is a CBOR map with the following optional fields.
+If no fields are relevant, an empty map should be encoded. The key value range
+\[-70000, -70999\] is reserved for the Android Profile for DICE.
+Implementation-specific fields may be added using key values outside of the
+reserved range.
 
 ```
 | Name              | Key    | Value type | Meaning                           |
@@ -306,44 +217,13 @@
 :                   :        :            : boot stage                        :
 | Resettable        | -70004 | null       | If present, key changes on factory|
 :                   :        :            : reset                             :
+| Security version  | -70005 | uint       | Machine-comparable, monotonically |
+:                   :        :            : increasing version of the firmware:
+:                   :        :            : component / boot stage where a    :
+:                   :        :            : greater value indicates a newer   :
+:                   :        :            : version                           :
 ```
 
-Please see
-[ProtectedData.aidl](https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/rkp/aidl/android/hardware/security/keymint/ProtectedData.aidl)
-for a full CDDL definition of the BCC.
-
-### `CertificateRequest`
-
-The full CBOR message that will be sent to the server to request certificates
-is:
-
-```cddl
-CertificateRequest = [
-    DeviceInfo,
-    challenge : bstr,       // Provided by the server
-    ProtectedData,          // See ProtectedData.aidl
-    MacedKeysToSign         // See IRemotelyProvisionedComponent.aidl
-]
-
-DeviceInfo = [
-    VerifiedDeviceInfo,     // See DeviceInfo.aidl
-    UnverifiedDeviceInfo
-]
-
-// Unverified info is anything provided by the HLOS. Subject to change out of
-// step with the HAL.
-UnverifiedDeviceInfo = {
-    ? "fingerprint" : tstr,
-}
-
-```
-
-It will be the responsibility of Keystore and the Provisioner to construct the
-`CertificateRequest`. The HAL provides a method to generate the elements that
-need to be constructed on the secure side, which are the tag field of
-`MacedKeysToSign`, `VerifiedDeviceInfo`, and the ciphertext field of
-`ProtectedData`.
-
 ### HAL
 
 The remote provisioning HAL provides a simple interface that can be implemented
diff --git a/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl b/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
index 461357d..b231dae 100644
--- a/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
+++ b/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
@@ -134,6 +134,10 @@
      *        are marked (see the definition of PublicKey in the MacedPublicKey structure) to
      *        prevent them from being confused with production keys.
      *
+     *        This parameter has been deprecated since version 3 of the HAL and will always be
+     *        false. From v3, if this parameter is true, the method must raise a
+     *        ServiceSpecificException with an error of code of STATUS_REMOVED.
+     *
      * @param out MacedPublicKey macedPublicKey contains the public key of the generated key pair,
      *        MACed so that generateCertificateRequest can easily verify, without the
      *        privateKeyHandle, that the contained public key is for remote certification.
@@ -418,11 +422,12 @@
      *     ;       described above.
      *     -4670545 : bstr,                         ; Code Hash
      *     ? -4670546 : bstr,                       ; Code Descriptor
-     *     ? -4670547 : bstr,                       ; Configuration Hash
+     *     -4670547 : bstr,                         ; Configuration Hash
      *     -4670548 : bstr .cbor {                  ; Configuration Descriptor
      *         ? -70002 : tstr,                         ; Component name
      *         ? -70003 : int / tstr,                   ; Component version
      *         ? -70004 : null,                         ; Resettable
+     *         ? -70005 : uint,                         ; Security version
      *     },
      *     -4670549 : bstr,                         ; Authority Hash
      *     ? -4670550 : bstr,                       ; Authority Descriptor
diff --git a/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp b/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
index 94bfbb4..62463eb 100644
--- a/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
+++ b/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
@@ -47,7 +47,11 @@
 namespace {
 
 constexpr int32_t VERSION_WITH_UNIQUE_ID_SUPPORT = 2;
+
+constexpr int32_t VERSION_WITHOUT_EEK = 3;
 constexpr int32_t VERSION_WITHOUT_TEST_MODE = 3;
+constexpr int32_t VERSION_WITH_CERTIFICATE_REQUEST_V2 = 3;
+constexpr int32_t VERSION_WITH_SUPPORTED_NUM_KEYS_IN_CSR = 3;
 
 constexpr uint8_t MIN_CHALLENGE_SIZE = 0;
 constexpr uint8_t MAX_CHALLENGE_SIZE = 64;
@@ -226,21 +230,13 @@
     RpcHardwareInfo hwInfo;
     ASSERT_TRUE(provisionable_->getHardwareInfo(&hwInfo).isOk());
 
-    const std::set<int> validCurves = {RpcHardwareInfo::CURVE_P256, RpcHardwareInfo::CURVE_25519};
-    // First check for the implementations that supports only IRPC V3+.
-    if (rpcHardwareInfo.versionNumber >= VERSION_WITHOUT_TEST_MODE) {
-        bytevec keysToSignMac;
-        DeviceInfo deviceInfo;
-        ProtectedData protectedData;
-        auto status = provisionable_->generateCertificateRequest(false, {}, {}, {}, &deviceInfo,
-                                                                 &protectedData, &keysToSignMac);
-        if (!status.isOk() &&
-            (status.getServiceSpecificError() == BnRemotelyProvisionedComponent::STATUS_REMOVED)) {
-            ASSERT_EQ(hwInfo.supportedEekCurve, RpcHardwareInfo::CURVE_NONE)
-                    << "Invalid curve: " << hwInfo.supportedEekCurve;
-            return;
-        }
+    if (rpcHardwareInfo.versionNumber >= VERSION_WITHOUT_EEK) {
+        ASSERT_EQ(hwInfo.supportedEekCurve, RpcHardwareInfo::CURVE_NONE)
+                << "Invalid curve: " << hwInfo.supportedEekCurve;
+        return;
     }
+
+    const std::set<int> validCurves = {RpcHardwareInfo::CURVE_P256, RpcHardwareInfo::CURVE_25519};
     ASSERT_EQ(validCurves.count(hwInfo.supportedEekCurve), 1)
             << "Invalid curve: " << hwInfo.supportedEekCurve;
 }
@@ -264,7 +260,7 @@
  * Verify implementation supports at least MIN_SUPPORTED_NUM_KEYS_IN_CSR keys in a CSR.
  */
 TEST_P(GetHardwareInfoTests, supportedNumKeysInCsr) {
-    if (rpcHardwareInfo.versionNumber < VERSION_WITHOUT_TEST_MODE) {
+    if (rpcHardwareInfo.versionNumber < VERSION_WITH_SUPPORTED_NUM_KEYS_IN_CSR) {
         return;
     }
 
@@ -365,6 +361,13 @@
     bytevec privateKeyBlob;
     bool testMode = true;
     auto status = provisionable_->generateEcdsaP256KeyPair(testMode, &macedPubKey, &privateKeyBlob);
+
+    if (rpcHardwareInfo.versionNumber >= VERSION_WITHOUT_TEST_MODE) {
+        ASSERT_FALSE(status.isOk());
+        EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_REMOVED);
+        return;
+    }
+
     ASSERT_TRUE(status.isOk());
     check_maced_pubkey(macedPubKey, testMode, nullptr);
 }
@@ -410,7 +413,7 @@
         CertificateRequestTestBase::SetUp();
         ASSERT_FALSE(HasFatalFailure());
 
-        if (rpcHardwareInfo.versionNumber >= VERSION_WITHOUT_TEST_MODE) {
+        if (rpcHardwareInfo.versionNumber >= VERSION_WITH_CERTIFICATE_REQUEST_V2) {
             GTEST_SKIP() << "This test case only applies to RKP v1 and v2. "
                          << "RKP version discovered: " << rpcHardwareInfo.versionNumber;
         }
@@ -688,7 +691,7 @@
         CertificateRequestTestBase::SetUp();
         ASSERT_FALSE(HasFatalFailure());
 
-        if (rpcHardwareInfo.versionNumber < VERSION_WITHOUT_TEST_MODE) {
+        if (rpcHardwareInfo.versionNumber < VERSION_WITH_CERTIFICATE_REQUEST_V2) {
             GTEST_SKIP() << "This test case only applies to RKP v3 and above. "
                          << "RKP version discovered: " << rpcHardwareInfo.versionNumber;
         }
@@ -699,6 +702,7 @@
  * Generate an empty certificate request with all possible length of challenge, and decrypt and
  * verify the structure and content.
  */
+// @VsrTest = 3.10-015
 TEST_P(CertificateRequestV2Test, EmptyRequest) {
     bytevec csr;
 
@@ -718,6 +722,7 @@
  * Generate a non-empty certificate request with all possible length of challenge.  Decrypt, parse
  * and validate the contents.
  */
+// @VsrTest = 3.10-015
 TEST_P(CertificateRequestV2Test, NonEmptyRequest) {
     generateKeys(false /* testMode */, 1 /* numKeys */);
 
@@ -750,6 +755,7 @@
  * Generate a non-empty certificate request.  Make sure contents are reproducible but allow for the
  * signature to be different since algorithms including ECDSA P-256 can include a random value.
  */
+// @VsrTest = 3.10-015
 TEST_P(CertificateRequestV2Test, NonEmptyRequestReproducible) {
     generateKeys(false /* testMode */, 1 /* numKeys */);
 
@@ -773,6 +779,7 @@
 /**
  * Generate a non-empty certificate request with multiple keys.
  */
+// @VsrTest = 3.10-015
 TEST_P(CertificateRequestV2Test, NonEmptyRequestMultipleKeys) {
     generateKeys(false /* testMode */, rpcHardwareInfo.supportedNumKeysInCsr /* numKeys */);
 
@@ -802,23 +809,23 @@
 }
 
 /**
- * Generate a non-empty certificate request in prod mode, with test keys.  Must fail with
- * STATUS_TEST_KEY_IN_PRODUCTION_REQUEST.
+ * Call generateCertificateRequest(). Make sure it's removed.
  */
-TEST_P(CertificateRequestV2Test, NonEmptyRequest_testKeyInProdCert) {
-    generateKeys(true /* testMode */, 1 /* numKeys */);
-
-    bytevec csr;
-    auto status = provisionable_->generateCertificateRequestV2(keysToSign_, challenge_, &csr);
+TEST_P(CertificateRequestV2Test, CertificateRequestV1Removed_prodMode) {
+    bytevec keysToSignMac;
+    DeviceInfo deviceInfo;
+    ProtectedData protectedData;
+    auto status = provisionable_->generateCertificateRequest(
+            false /* testMode */, {} /* keysToSign */, {} /* EEK chain */, challenge_, &deviceInfo,
+            &protectedData, &keysToSignMac);
     ASSERT_FALSE(status.isOk()) << status.getMessage();
-    ASSERT_EQ(status.getServiceSpecificError(),
-              BnRemotelyProvisionedComponent::STATUS_TEST_KEY_IN_PRODUCTION_REQUEST);
+    EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_REMOVED);
 }
 
 /**
- * Call generateCertificateRequest(). Make sure it's removed.
+ * Call generateCertificateRequest() in test mode. Make sure it's removed.
  */
-TEST_P(CertificateRequestV2Test, CertificateRequestV1Removed) {
+TEST_P(CertificateRequestV2Test, CertificateRequestV1Removed_testMode) {
     bytevec keysToSignMac;
     DeviceInfo deviceInfo;
     ProtectedData protectedData;
@@ -846,6 +853,7 @@
 /**
  * Generate a CSR and verify DeviceInfo against IDs attested by KeyMint.
  */
+// @VsrTest = 3.10-015
 TEST_P(CertificateRequestV2Test, DeviceInfo) {
     // See if there is a matching IKeyMintDevice for this IRemotelyProvisionedComponent.
     std::shared_ptr<IKeyMintDevice> keyMint;
diff --git a/sensors/2.1/default/apex/apex_manifest.json b/sensors/2.1/default/apex/apex_manifest.json
deleted file mode 100644
index 47e45ee..0000000
--- a/sensors/2.1/default/apex/apex_manifest.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-  "name": "com.android.hardware.sensors",
-  "version": 1
-}
diff --git a/sensors/2.1/default/apex/com.android.hardware.sensors.rc b/sensors/2.1/default/apex/com.android.hardware.sensors.rc
deleted file mode 100644
index bd245b4..0000000
--- a/sensors/2.1/default/apex/com.android.hardware.sensors.rc
+++ /dev/null
@@ -1,7 +0,0 @@
-service vendor.sensors-hal-2-1-mock /apex/com.android.hardware.sensors/bin/hw/android.hardware.sensors@2.1-service.mock
-    interface android.hardware.sensors@2.0::ISensors default
-    interface android.hardware.sensors@2.1::ISensors default
-    class hal
-    user system
-    group system
-    rlimit rtprio 10 10
diff --git a/sensors/2.1/default/apex/file_contexts b/sensors/2.1/default/apex/file_contexts
deleted file mode 100644
index d0095c0..0000000
--- a/sensors/2.1/default/apex/file_contexts
+++ /dev/null
@@ -1,5 +0,0 @@
-(/.*)?							u:object_r:vendor_file:s0
-# Permission XMLs
-/etc/permissions(/.*)?					u:object_r:vendor_configs_file:s0
-# Service binary
-/bin/hw/android\.hardware\.sensors@2\.1-service\.mock	u:object_r:hal_sensors_default_exec:s0
diff --git a/sensors/aidl/default/Android.bp b/sensors/aidl/default/Android.bp
index 49841a4..3c66744 100644
--- a/sensors/aidl/default/Android.bp
+++ b/sensors/aidl/default/Android.bp
@@ -23,6 +23,16 @@
     default_applicable_licenses: ["hardware_interfaces_license"],
 }
 
+filegroup {
+    name: "sensors-default.rc",
+    srcs: ["sensors-default.rc"],
+}
+
+filegroup {
+    name: "sensors-default.xml",
+    srcs: ["sensors-default.xml"],
+}
+
 cc_library_static {
     name: "libsensorsexampleimpl",
     vendor: true,
@@ -47,8 +57,8 @@
 cc_binary {
     name: "android.hardware.sensors-service.example",
     relative_install_path: "hw",
-    init_rc: ["sensors-default.rc"],
-    vintf_fragments: ["sensors-default.xml"],
+    init_rc: [":sensors-default.rc"],
+    vintf_fragments: [":sensors-default.xml"],
     vendor: true,
     shared_libs: [
         "libbase",
diff --git a/sensors/2.1/default/apex/Android.bp b/sensors/aidl/default/apex/Android.bp
similarity index 78%
rename from sensors/2.1/default/apex/Android.bp
rename to sensors/aidl/default/apex/Android.bp
index 3345b92..ceb428b 100644
--- a/sensors/2.1/default/apex/Android.bp
+++ b/sensors/aidl/default/apex/Android.bp
@@ -13,9 +13,16 @@
     certificate: "com.android.hardware.sensors",
 }
 
+genrule {
+    name: "com.android.hardware.sensors.rc-gen",
+    srcs: [":sensors-default.rc"],
+    out: ["com.android.hardware.sensors.rc"],
+    cmd: "sed -E 's/\\/vendor/\\/apex\\/com.android.hardware.sensors/' $(in) > $(out)",
+}
+
 prebuilt_etc {
     name: "com.android.hardware.sensors.rc",
-    src: "com.android.hardware.sensors.rc",
+    src: ":com.android.hardware.sensors.rc-gen",
     installable: false,
 }
 
@@ -31,7 +38,7 @@
     updatable: false,
     // Install the apex in /vendor/apex
     soc_specific: true,
-    binaries: ["android.hardware.sensors@2.1-service.mock"],
+    binaries: ["android.hardware.sensors-service.example"],
     prebuilts: [
         "com.android.hardware.sensors.rc",
         "android.hardware.sensor.ambient_temperature.prebuilt.xml",
@@ -42,5 +49,5 @@
         "android.hardware.sensor.proximity.prebuilt.xml",
         "android.hardware.sensor.relative_humidity.prebuilt.xml",
     ],
-    vintf_fragments: [":android.hardware.sensors@2.1.xml"],
+    vintf_fragments: [":sensors-default.xml"],
 }
diff --git a/sensors/aidl/default/apex/apex_manifest.json b/sensors/aidl/default/apex/apex_manifest.json
new file mode 100644
index 0000000..659e739
--- /dev/null
+++ b/sensors/aidl/default/apex/apex_manifest.json
@@ -0,0 +1,4 @@
+{
+    "name": "com.android.hardware.sensors",
+    "version": 1
+}
diff --git a/sensors/2.1/default/apex/com.android.hardware.sensors.avbpubkey b/sensors/aidl/default/apex/com.android.hardware.sensors.avbpubkey
similarity index 100%
rename from sensors/2.1/default/apex/com.android.hardware.sensors.avbpubkey
rename to sensors/aidl/default/apex/com.android.hardware.sensors.avbpubkey
Binary files differ
diff --git a/sensors/2.1/default/apex/com.android.hardware.sensors.pem b/sensors/aidl/default/apex/com.android.hardware.sensors.pem
similarity index 100%
rename from sensors/2.1/default/apex/com.android.hardware.sensors.pem
rename to sensors/aidl/default/apex/com.android.hardware.sensors.pem
diff --git a/sensors/2.1/default/apex/com.android.hardware.sensors.pk8 b/sensors/aidl/default/apex/com.android.hardware.sensors.pk8
similarity index 100%
rename from sensors/2.1/default/apex/com.android.hardware.sensors.pk8
rename to sensors/aidl/default/apex/com.android.hardware.sensors.pk8
Binary files differ
diff --git a/sensors/2.1/default/apex/com.android.hardware.sensors.x509.pem b/sensors/aidl/default/apex/com.android.hardware.sensors.x509.pem
similarity index 100%
rename from sensors/2.1/default/apex/com.android.hardware.sensors.x509.pem
rename to sensors/aidl/default/apex/com.android.hardware.sensors.x509.pem
diff --git a/sensors/aidl/default/apex/file_contexts b/sensors/aidl/default/apex/file_contexts
new file mode 100644
index 0000000..27be16b
--- /dev/null
+++ b/sensors/aidl/default/apex/file_contexts
@@ -0,0 +1,5 @@
+(/.*)?							u:object_r:vendor_file:s0
+# Permission XMLs
+/etc/permissions(/.*)?					u:object_r:vendor_configs_file:s0
+# Service binary
+/bin/hw/android\.hardware\.sensors-service\.example	u:object_r:hal_sensors_default_exec:s0
\ No newline at end of file
diff --git a/tetheroffload/control/1.1/Android.bp b/tetheroffload/control/1.1/Android.bp
index 7871c2c..0daa90e 100644
--- a/tetheroffload/control/1.1/Android.bp
+++ b/tetheroffload/control/1.1/Android.bp
@@ -22,7 +22,7 @@
         "android.hidl.base@1.0",
     ],
     apex_available: [
-        "//apex_available:platform", // Used by InProcessTethering
+        "//apex_available:platform",
         "com.android.tethering",
     ],
     gen_java: true,
diff --git a/threadnetwork/OWNERS b/threadnetwork/OWNERS
new file mode 100644
index 0000000..54fd66d
--- /dev/null
+++ b/threadnetwork/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 1288834
+
+include platform/packages/modules/ThreadNetwork:/OWNERS
diff --git a/tv/tuner/1.1/vts/functional/FrontendTests.cpp b/tv/tuner/1.1/vts/functional/FrontendTests.cpp
index 9f0f30d..0a645fc 100644
--- a/tv/tuner/1.1/vts/functional/FrontendTests.cpp
+++ b/tv/tuner/1.1/vts/functional/FrontendTests.cpp
@@ -379,7 +379,7 @@
                 break;
             }
             case FrontendStatusTypeExt1_1::UEC: {
-                ASSERT_TRUE(realStatuses[i].uec() == expectStatuses[i].uec());
+                ASSERT_TRUE(realStatuses[i].uec() >= 0 );
                 break;
             }
             case FrontendStatusTypeExt1_1::T2_SYSTEM_ID: {
diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h
index 669fa11..dcdc673 100644
--- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h
+++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h
@@ -86,7 +86,7 @@
     types.push_back(FrontendStatusTypeExt1_1::IS_MISO);
     vector<FrontendStatusExt1_1> statuses;
     FrontendStatusExt1_1 status;
-    status.uec(4);
+    status.uec(0);
     statuses.push_back(status);
     status.isMiso(true);
     statuses.push_back(status);
diff --git a/usb/1.1/vts/functional/VtsHalUsbV1_1TargetTest.cpp b/usb/1.1/vts/functional/VtsHalUsbV1_1TargetTest.cpp
index 19830a6..0883de2 100644
--- a/usb/1.1/vts/functional/VtsHalUsbV1_1TargetTest.cpp
+++ b/usb/1.1/vts/functional/VtsHalUsbV1_1TargetTest.cpp
@@ -95,6 +95,7 @@
                                             Status retval) override {
         UsbClientCallbackArgs arg;
         if (retval == Status::SUCCESS) {
+            arg.usb_last_port_status.status.portName = currentPortStatus[0].status.portName.c_str();
             arg.usb_last_port_status.status.supportedModes =
                 currentPortStatus[0].status.supportedModes;
             arg.usb_last_port_status.status.currentMode = currentPortStatus[0].status.currentMode;
@@ -165,9 +166,12 @@
     auto res = usb_cb_2->WaitForCallback(kCallbackNameNotifyPortStatusChange_1_1);
     EXPECT_TRUE(res.no_timeout);
     EXPECT_EQ(2, res.args->last_usb_cookie);
-    EXPECT_EQ(PortMode::NONE, res.args->usb_last_port_status.status.currentMode);
-    EXPECT_EQ(PortMode::NONE, res.args->usb_last_port_status.status.supportedModes);
-    EXPECT_EQ(Status::SUCCESS, res.args->usb_last_status);
+    // if there are no type-c ports, skip below checks
+    if (!res.args->usb_last_port_status.status.portName.empty()) {
+        EXPECT_EQ(PortMode::NONE, res.args->usb_last_port_status.status.currentMode);
+        EXPECT_EQ(PortMode::NONE, res.args->usb_last_port_status.status.supportedModes);
+        EXPECT_EQ(Status::SUCCESS, res.args->usb_last_status);
+    }
 }
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(UsbHidlTest);
 INSTANTIATE_TEST_SUITE_P(
diff --git a/usb/OWNERS b/usb/OWNERS
index 2b1d34d..3611b4d 100644
--- a/usb/OWNERS
+++ b/usb/OWNERS
@@ -1,4 +1,8 @@
 # Bug component: 175220
 
+aprasath@google.com
+kumarashishg@google.com
+sarup@google.com
+anothermark@google.com
 albertccwang@google.com
 badhri@google.com
diff --git a/uwb/aidl/default/src/uwb_chip.rs b/uwb/aidl/default/src/uwb_chip.rs
index 7c2c300..cf32694 100644
--- a/uwb/aidl/default/src/uwb_chip.rs
+++ b/uwb/aidl/default/src/uwb_chip.rs
@@ -6,8 +6,8 @@
 use async_trait::async_trait;
 use binder::{Result, Strong};
 
-use tokio::fs::File;
-use tokio::io::{AsyncReadExt, AsyncWriteExt};
+use tokio::fs::{self, File};
+use tokio::io::AsyncReadExt;
 use tokio::sync::Mutex;
 
 use std::os::fd::AsRawFd;
@@ -22,7 +22,6 @@
         callbacks: Strong<dyn IUwbClientCallback>,
         #[allow(dead_code)]
         tasks: tokio::task::JoinSet<()>,
-        write: File,
     },
 }
 
@@ -65,17 +64,11 @@
     async fn open(&self, callbacks: &Strong<dyn IUwbClientCallback>) -> Result<()> {
         log::debug!("open: {:?}", &self.path);
 
-        let serial = File::open(&self.path)
+        let mut serial = File::open(&self.path)
             .await
             .and_then(makeraw)
             .map_err(|_| binder::StatusCode::UNKNOWN_ERROR)?;
 
-        let mut read = serial
-            .try_clone()
-            .await
-            .map_err(|_| binder::StatusCode::UNKNOWN_ERROR)?;
-        let write = serial;
-
         let mut state = self.state.lock().await;
 
         if let State::Closed = *state {
@@ -88,14 +81,16 @@
                     const UWB_HEADER_SIZE: usize = 4;
 
                     let mut buffer = vec![0; UWB_HEADER_SIZE];
-                    read.read_exact(&mut buffer[0..UWB_HEADER_SIZE])
+                    serial
+                        .read_exact(&mut buffer[0..UWB_HEADER_SIZE])
                         .await
                         .unwrap();
 
                     let length = buffer[3] as usize + UWB_HEADER_SIZE;
 
                     buffer.resize(length, 0);
-                    read.read_exact(&mut buffer[UWB_HEADER_SIZE..length])
+                    serial
+                        .read_exact(&mut buffer[UWB_HEADER_SIZE..length])
                         .await
                         .unwrap();
 
@@ -108,7 +103,6 @@
             *state = State::Opened {
                 callbacks: callbacks.clone(),
                 tasks,
-                write,
             };
 
             Ok(())
@@ -155,11 +149,10 @@
     async fn sendUciMessage(&self, data: &[u8]) -> Result<i32> {
         log::debug!("sendUciMessage");
 
-        if let State::Opened { write, .. } = &mut *self.state.lock().await {
-            write
-                .write(data)
+        if let State::Opened { .. } = &mut *self.state.lock().await {
+            fs::write(&self.path, data)
                 .await
-                .map(|written| written as i32)
+                .map(|_| data.len() as i32)
                 .map_err(|_| binder::StatusCode::UNKNOWN_ERROR.into())
         } else {
             Err(binder::ExceptionCode::ILLEGAL_STATE.into())
diff --git a/wifi/1.6/vts/functional/Android.bp b/wifi/1.6/vts/functional/Android.bp
index 2d126c7..92e6d13 100644
--- a/wifi/1.6/vts/functional/Android.bp
+++ b/wifi/1.6/vts/functional/Android.bp
@@ -23,6 +23,28 @@
     default_applicable_licenses: ["hardware_interfaces_license"],
 }
 
+cc_library_static {
+    name: "VtsHalWifiV1_6TargetTestUtil",
+    defaults: ["VtsHalTargetTestDefaults"],
+    srcs: [
+        "wifi_hidl_test_utils_1_6.cpp",
+    ],
+    export_include_dirs: [
+        ".",
+    ],
+    shared_libs: [
+        "libnativehelper",
+    ],
+    static_libs: [
+        "VtsHalWifiV1_0TargetTestUtil",
+        "android.hardware.wifi@1.0",
+        "android.hardware.wifi@1.3",
+        "android.hardware.wifi@1.5",
+        "android.hardware.wifi@1.6",
+        "libwifi-system-iface",
+    ],
+}
+
 cc_test {
     name: "VtsHalWifiV1_6TargetTest",
     defaults: ["VtsHalTargetTestDefaults"],
diff --git a/wifi/1.6/vts/functional/wifi_hidl_test_utils_1_6.cpp b/wifi/1.6/vts/functional/wifi_hidl_test_utils_1_6.cpp
new file mode 100644
index 0000000..5b8115b
--- /dev/null
+++ b/wifi/1.6/vts/functional/wifi_hidl_test_utils_1_6.cpp
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <VtsHalHidlTargetCallbackBase.h>
+
+#undef NAN  // NAN is defined in bionic/libc/include/math.h:38
+
+#include <android/hardware/wifi/1.5/IWifiApIface.h>
+#include <android/hardware/wifi/1.6/IWifiChip.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
+
+#include "wifi_hidl_call_util.h"
+#include "wifi_hidl_test_utils.h"
+
+using ::android::sp;
+using ::android::hardware::wifi::V1_0::ChipModeId;
+using ::android::hardware::wifi::V1_0::WifiStatusCode;
+using ::android::hardware::wifi::V1_5::IWifiApIface;
+using ::android::hardware::wifi::V1_6::IfaceConcurrencyType;
+using ::android::hardware::wifi::V1_6::IWifiChip;
+
+namespace {
+
+bool findAnyModeSupportingConcurrencyType(IfaceConcurrencyType desired_type,
+                                          const std::vector<IWifiChip::ChipMode>& modes,
+                                          ChipModeId* mode_id) {
+    for (const auto& mode : modes) {
+        for (const auto& combination : mode.availableCombinations) {
+            for (const auto& iface_limit : combination.limits) {
+                const auto& iface_types = iface_limit.types;
+                if (std::find(iface_types.begin(), iface_types.end(), desired_type) !=
+                    iface_types.end()) {
+                    *mode_id = mode.id;
+                    return true;
+                }
+            }
+        }
+    }
+    return false;
+}
+
+bool configureChipToSupportConcurrencyType(const sp<IWifiChip>& wifi_chip,
+                                           IfaceConcurrencyType type,
+                                           ChipModeId* configured_mode_id) {
+    const auto& status_and_modes = HIDL_INVOKE(wifi_chip, getAvailableModes_1_6);
+    if (status_and_modes.first.code != WifiStatusCode::SUCCESS) {
+        return false;
+    }
+    if (!findAnyModeSupportingConcurrencyType(type, status_and_modes.second, configured_mode_id)) {
+        return false;
+    }
+    if (HIDL_INVOKE(wifi_chip, configureChip, *configured_mode_id).code !=
+        WifiStatusCode::SUCCESS) {
+        return false;
+    }
+    return true;
+}
+
+sp<IWifiChip> getWifiChip_1_6(const std::string& instance_name) {
+    return IWifiChip::castFrom(getWifiChip(instance_name));
+}
+
+}  // namespace
+
+sp<IWifiApIface> getBridgedWifiApIface_1_6(const std::string& instance_name) {
+    ChipModeId mode_id;
+    sp<IWifiChip> wifi_chip = getWifiChip_1_6(instance_name);
+    if (!wifi_chip.get()) return nullptr;
+    configureChipToSupportConcurrencyType(wifi_chip, IfaceConcurrencyType::AP_BRIDGED, &mode_id);
+    const auto& status_and_iface = HIDL_INVOKE(wifi_chip, createBridgedApIface);
+    return IWifiApIface::castFrom(status_and_iface.second);
+}
diff --git a/wifi/1.6/vts/functional/wifi_hidl_test_utils_1_6.h b/wifi/1.6/vts/functional/wifi_hidl_test_utils_1_6.h
new file mode 100644
index 0000000..ab8ff3b
--- /dev/null
+++ b/wifi/1.6/vts/functional/wifi_hidl_test_utils_1_6.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/hardware/wifi/1.5/IWifiApIface.h>
+#include <android/hardware/wifi/1.6/IWifiChip.h>
+
+#include <VtsHalHidlTargetTestEnvBase.h>
+
+android::sp<android::hardware::wifi::V1_5::IWifiApIface> getBridgedWifiApIface_1_6(
+        const std::string& instance_name);
diff --git a/wifi/1.6/vts/functional/wifi_rtt_controller_hidl_test.cpp b/wifi/1.6/vts/functional/wifi_rtt_controller_hidl_test.cpp
index 5b5e623..0572ac6 100644
--- a/wifi/1.6/vts/functional/wifi_rtt_controller_hidl_test.cpp
+++ b/wifi/1.6/vts/functional/wifi_rtt_controller_hidl_test.cpp
@@ -78,6 +78,13 @@
 
     virtual void TearDown() override { stopWifi(GetInstanceName()); }
 
+    RttCapabilities getRttCapabilities() {
+        std::pair<WifiStatus, RttCapabilities> status_and_caps;
+        status_and_caps = HIDL_INVOKE(wifi_rtt_controller_, getCapabilities_1_6);
+        EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_caps.first.code);
+        return status_and_caps.second;
+    }
+
     // A simple test implementation of WifiRttControllerEventCallback.
     class WifiRttControllerEventCallback
         : public ::testing::VtsHalHidlTargetCallbackBase<WifiRttControllerHidlTest>,
@@ -151,12 +158,9 @@
  * This test case tests the two sided ranging - 802.11mc FTM protocol.
  */
 TEST_P(WifiRttControllerHidlTest, Request2SidedRangeMeasurement) {
-    std::pair<WifiStatus, RttCapabilities> status_and_caps;
-
     // Get the Capabilities
-    status_and_caps = HIDL_INVOKE(wifi_rtt_controller_, getCapabilities_1_6);
-    EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_caps.first.code);
-    if (!status_and_caps.second.rttFtmSupported) {
+    RttCapabilities capabilities = getRttCapabilities();
+    if (!capabilities.rttFtmSupported) {
         GTEST_SKIP() << "Skipping two sided RTT since driver/fw doesn't support";
     }
     std::vector<RttConfig> configs;
@@ -196,19 +200,16 @@
  * rangeRequest_1_6
  */
 TEST_P(WifiRttControllerHidlTest, RangeRequest_1_6) {
-    std::pair<WifiStatus, RttCapabilities> status_and_caps;
-
     // Get the Capabilities
-    status_and_caps = HIDL_INVOKE(wifi_rtt_controller_, getCapabilities_1_6);
-    EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_caps.first.code);
-    if (!status_and_caps.second.rttOneSidedSupported) {
+    RttCapabilities capabilities = getRttCapabilities();
+    if (!capabilities.rttOneSidedSupported) {
         GTEST_SKIP() << "Skipping one sided RTT since driver/fw doesn't support";
     }
     // Get the highest support preamble
     int preamble = 1;
-    status_and_caps.second.preambleSupport >>= 1;
-    while (status_and_caps.second.preambleSupport != 0) {
-        status_and_caps.second.preambleSupport >>= 1;
+    capabilities.preambleSupport >>= 1;
+    while (capabilities.preambleSupport != 0) {
+        capabilities.preambleSupport >>= 1;
         preamble <<= 1;
     }
     std::vector<RttConfig> configs;
@@ -259,9 +260,14 @@
  * getResponderInfo_1_6
  */
 TEST_P(WifiRttControllerHidlTest, GetResponderInfo_1_6) {
-    std::pair<WifiStatus, RttResponder> status_and_info;
+    // Get the capabilities
+    RttCapabilities capabilities = getRttCapabilities();
+    if (!capabilities.responderSupported) {
+        GTEST_SKIP() << "Skipping because responder is not supported";
+    }
 
     // Invoke the call
+    std::pair<WifiStatus, RttResponder> status_and_info;
     status_and_info = HIDL_INVOKE(wifi_rtt_controller_, getResponderInfo_1_6);
     EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_info.first.code);
 }
@@ -270,6 +276,12 @@
  * enableResponder_1_6
  */
 TEST_P(WifiRttControllerHidlTest, EnableResponder_1_6) {
+    // Get the capabilities
+    RttCapabilities capabilities = getRttCapabilities();
+    if (!capabilities.responderSupported) {
+        GTEST_SKIP() << "Skipping because responder is not supported";
+    }
+
     std::pair<WifiStatus, RttResponder> status_and_info;
     int cmdId = 55;
     WifiChannelInfo channelInfo;
diff --git a/wifi/hostapd/aidl/vts/functional/Android.bp b/wifi/hostapd/aidl/vts/functional/Android.bp
index e61d397..a24bcc0 100644
--- a/wifi/hostapd/aidl/vts/functional/Android.bp
+++ b/wifi/hostapd/aidl/vts/functional/Android.bp
@@ -23,6 +23,7 @@
         "android.hardware.wifi.hostapd-V1-ndk",
         "VtsHalWifiV1_0TargetTestUtil",
         "VtsHalWifiV1_5TargetTestUtil",
+        "VtsHalWifiV1_6TargetTestUtil",
         "VtsHalWifiHostapdV1_0TargetTestUtil",
         "android.hardware.wifi.hostapd@1.0",
         "android.hardware.wifi.hostapd@1.1",
@@ -34,6 +35,7 @@
         "android.hardware.wifi@1.3",
         "android.hardware.wifi@1.4",
         "android.hardware.wifi@1.5",
+        "android.hardware.wifi@1.6",
     ],
     test_suites: [
         "general-tests",
diff --git a/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp b/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp
index bd2649f..1b9c0b0 100644
--- a/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp
+++ b/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp
@@ -29,6 +29,7 @@
 #include <hostapd_hidl_test_utils.h>
 #include <wifi_hidl_test_utils.h>
 #include <wifi_hidl_test_utils_1_5.h>
+#include <wifi_hidl_test_utils_1_6.h>
 
 using aidl::android::hardware::wifi::hostapd::BandMask;
 using aidl::android::hardware::wifi::hostapd::BnHostapdCallback;
@@ -101,7 +102,7 @@
     std::string setupApIfaceAndGetName(bool isBridged) {
         android::sp<::android::hardware::wifi::V1_0::IWifiApIface> wifi_ap_iface;
         if (isBridged) {
-            wifi_ap_iface = getBridgedWifiApIface_1_5(wifiInstanceName);
+            wifi_ap_iface = getBridgedWifiApIface_1_6(wifiInstanceName);
         } else {
             wifi_ap_iface = getWifiApIface_1_5(wifiInstanceName);
         }