Merge "All hals are marked optional in compatibility matrices (Q~T)"
diff --git a/audio/README.md b/audio/README.md
index 3f40d72..1938ad4 100644
--- a/audio/README.md
+++ b/audio/README.md
@@ -2,29 +2,10 @@
 
 Directory structure of the audio HAL related code.
 
-## Directory Structure for AIDL audio HAL
+Run `common/all-versions/copyHAL.sh` to create a new version of the audio HAL
+based on an existing one.
 
-The AIDL version is located inside `aidl` directory. The tree below explains
-the role of each subdirectory:
-
-* `aidl_api` — snapshots of the API created each Android release. Every
-  release, the current version of the API becomes "frozen" and gets assigned
-  the next version number. If the API needs further modifications, they are
-  made on the "current" version. After making modifications, run
-  `m <package name>-update-api` to update the snapshot of the "current"
-  version.
-* `android/hardware/audio/common` — data structures and interfaces shared
-  between various HALs: BT HAL, core and effects audio HALs.
-* `android/hardware/audio/core` — data structures and interfaces of the
-  core audio HAL.
-* `default` — the default, reference implementation of the audio HAL service.
-* `vts` — VTS tests for the AIDL HAL.
-
-## Directory Structure for HIDL audio HAL
-
-Run `common/all-versions/copyHAL.sh` to create a new version of the HIDL audio
-HAL based on an existing one. Note that this isn't possible since Android T
-release. Android U and above uses AIDL audio HAL.
+## Directory Structure
 
 * `2.0` — version 2.0 of the core HIDL API. Note that `.hal` files
   can not be moved into the `core` directory because that would change
diff --git a/audio/aidl/Android.bp b/audio/aidl/Android.bp
index 01af940..515787e 100644
--- a/audio/aidl/Android.bp
+++ b/audio/aidl/Android.bp
@@ -36,12 +36,13 @@
         "android.hardware.audio_defaults",
     ],
     srcs: [
+        "android/hardware/audio/common/AudioOffloadMetadata.aidl",
         "android/hardware/audio/common/PlaybackTrackMetadata.aidl",
         "android/hardware/audio/common/RecordTrackMetadata.aidl",
         "android/hardware/audio/common/SinkMetadata.aidl",
         "android/hardware/audio/common/SourceMetadata.aidl",
     ],
-    frozen: true,
+    frozen: false,
     imports: [
         "android.media.audio.common.types-V2",
     ],
@@ -77,7 +78,7 @@
 }
 
 // Note: This should always be one version ahead of the last frozen version
-latest_android_hardware_audio_common = "android.hardware.audio.common-V1"
+latest_android_hardware_audio_common = "android.hardware.audio.common-V2"
 
 // Modules that depend on android.hardware.audio.common directly can include
 // the following cc_defaults to avoid explicitly managing dependency versions
@@ -112,6 +113,8 @@
         "android/hardware/audio/core/AudioPatch.aidl",
         "android/hardware/audio/core/AudioRoute.aidl",
         "android/hardware/audio/core/IBluetooth.aidl",
+        "android/hardware/audio/core/IBluetoothA2dp.aidl",
+        "android/hardware/audio/core/IBluetoothLe.aidl",
         "android/hardware/audio/core/IConfig.aidl",
         "android/hardware/audio/core/IModule.aidl",
         "android/hardware/audio/core/IStreamCallback.aidl",
@@ -120,8 +123,6 @@
         "android/hardware/audio/core/IStreamOut.aidl",
         "android/hardware/audio/core/IStreamOutEventCallback.aidl",
         "android/hardware/audio/core/ITelephony.aidl",
-        "android/hardware/audio/core/MicrophoneDynamicInfo.aidl",
-        "android/hardware/audio/core/MicrophoneInfo.aidl",
         "android/hardware/audio/core/MmapBufferDescriptor.aidl",
         "android/hardware/audio/core/ModuleDebug.aidl",
         "android/hardware/audio/core/StreamDescriptor.aidl",
@@ -131,7 +132,7 @@
     imports: [
         "android.hardware.common-V2",
         "android.hardware.common.fmq-V1",
-        "android.hardware.audio.common-V1",
+        "android.hardware.audio.common-V2",
         "android.hardware.audio.core.sounddose-V1",
         "android.hardware.audio.effect-V1",
         "android.media.audio.common.types-V2",
@@ -225,11 +226,12 @@
     ],
     srcs: [
         "android/hardware/audio/effect/AcousticEchoCanceler.aidl",
-        "android/hardware/audio/effect/AutomaticGainControl.aidl",
         "android/hardware/audio/effect/AutomaticGainControlV1.aidl",
+        "android/hardware/audio/effect/AutomaticGainControlV2.aidl",
         "android/hardware/audio/effect/BassBoost.aidl",
         "android/hardware/audio/effect/Capability.aidl",
         "android/hardware/audio/effect/CommandId.aidl",
+        "android/hardware/audio/effect/DefaultExtension.aidl",
         "android/hardware/audio/effect/Descriptor.aidl",
         "android/hardware/audio/effect/Downmix.aidl",
         "android/hardware/audio/effect/DynamicsProcessing.aidl",
@@ -254,7 +256,7 @@
     imports: [
         "android.hardware.common-V2",
         "android.hardware.common.fmq-V1",
-        "android.hardware.audio.common-V1",
+        "android.hardware.audio.common-V2",
         "android.media.audio.common.types-V2",
     ],
     backend: {
diff --git a/audio/aidl/TEST_MAPPING b/audio/aidl/TEST_MAPPING
index 6a545c1..3e06595 100644
--- a/audio/aidl/TEST_MAPPING
+++ b/audio/aidl/TEST_MAPPING
@@ -13,9 +13,6 @@
       "name": "VtsHalDownmixTargetTest"
     },
     {
-      "name": "VtsHalDynamicsProcessingTargetTest"
-    },
-    {
       "name": "VtsHalEnvironmentalReverbTargetTest"
     },
     {
@@ -43,7 +40,10 @@
       "name": "VtsHalAECTargetTest"
     },
     {
-      "name": "VtsHalAGCTargetTest"
+      "name": "VtsHalAGC1TargetTest"
+    },
+    {
+      "name": "VtsHalAGC2TargetTest"
     },
     {
       "name": "VtsHalNSTargetTest"
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneDynamicInfo.aidl b/audio/aidl/aidl_api/android.hardware.audio.common/current/android/hardware/audio/common/AudioOffloadMetadata.aidl
similarity index 82%
rename from audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneDynamicInfo.aidl
rename to audio/aidl/aidl_api/android.hardware.audio.common/current/android/hardware/audio/common/AudioOffloadMetadata.aidl
index 50a5528..000504b 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneDynamicInfo.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.common/current/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,15 +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.audio.core;
+package android.hardware.audio.common;
 @JavaDerive(equals=true, toString=true) @VintfStability
-parcelable MicrophoneDynamicInfo {
-  @utf8InCpp String id;
-  android.hardware.audio.core.MicrophoneDynamicInfo.ChannelMapping[] channelMapping;
-  @Backing(type="int") @VintfStability
-  enum ChannelMapping {
-    UNUSED = 0,
-    DIRECT = 1,
-    PROCESSED = 2,
-  }
+parcelable AudioOffloadMetadata {
+  int sampleRate;
+  android.media.audio.common.AudioChannelLayout channelMask;
+  int averageBitRatePerSecond;
+  int delayFrames;
+  int paddingFrames;
 }
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core.sounddose/current/android/hardware/audio/core/sounddose/ISoundDose.aidl b/audio/aidl/aidl_api/android.hardware.audio.core.sounddose/current/android/hardware/audio/core/sounddose/ISoundDose.aidl
index 3b5d2d0..5800091 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.core.sounddose/current/android/hardware/audio/core/sounddose/ISoundDose.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.core.sounddose/current/android/hardware/audio/core/sounddose/ISoundDose.aidl
@@ -34,8 +34,8 @@
 package android.hardware.audio.core.sounddose;
 @VintfStability
 interface ISoundDose {
-  void setOutputRs2(float rs2ValueDbA);
-  float getOutputRs2();
+  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;
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneDynamicInfo.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IBluetoothA2dp.aidl
similarity index 81%
copy from audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneDynamicInfo.aidl
copy to audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IBluetoothA2dp.aidl
index 50a5528..0f4c46d 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneDynamicInfo.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/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.
@@ -32,14 +32,10 @@
 // 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 MicrophoneDynamicInfo {
-  @utf8InCpp String id;
-  android.hardware.audio.core.MicrophoneDynamicInfo.ChannelMapping[] channelMapping;
-  @Backing(type="int") @VintfStability
-  enum ChannelMapping {
-    UNUSED = 0,
-    DIRECT = 1,
-    PROCESSED = 2,
-  }
+@VintfStability
+interface IBluetoothA2dp {
+  boolean isEnabled();
+  void setEnabled(boolean enabled);
+  boolean supportsOffloadReconfiguration();
+  void reconfigureOffload(in android.hardware.audio.core.VendorParameter[] parameters);
 }
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneDynamicInfo.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IBluetoothLe.aidl
similarity index 81%
copy from audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneDynamicInfo.aidl
copy to audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IBluetoothLe.aidl
index 50a5528..2068daf 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneDynamicInfo.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/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.
@@ -32,14 +32,10 @@
 // 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 MicrophoneDynamicInfo {
-  @utf8InCpp String id;
-  android.hardware.audio.core.MicrophoneDynamicInfo.ChannelMapping[] channelMapping;
-  @Backing(type="int") @VintfStability
-  enum ChannelMapping {
-    UNUSED = 0,
-    DIRECT = 1,
-    PROCESSED = 2,
-  }
+@VintfStability
+interface IBluetoothLe {
+  boolean isEnabled();
+  void setEnabled(boolean enabled);
+  boolean supportsOffloadReconfiguration();
+  void reconfigureOffload(in android.hardware.audio.core.VendorParameter[] parameters);
 }
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IModule.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IModule.aidl
index 45217e7..e14e9c0 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IModule.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IModule.aidl
@@ -37,6 +37,8 @@
   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();
@@ -58,7 +60,7 @@
   void setMasterVolume(float volume);
   boolean getMicMute();
   void setMicMute(boolean mute);
-  android.hardware.audio.core.MicrophoneInfo[] getMicrophones();
+  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);
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IStreamCommon.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IStreamCommon.aidl
index f0bf100..65a2ee4 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IStreamCommon.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IStreamCommon.aidl
@@ -35,6 +35,7 @@
 @VintfStability
 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);
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IStreamIn.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IStreamIn.aidl
index 1041943..a01f877 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IStreamIn.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IStreamIn.aidl
@@ -35,7 +35,7 @@
 @VintfStability
 interface IStreamIn {
   android.hardware.audio.core.IStreamCommon getStreamCommon();
-  android.hardware.audio.core.MicrophoneDynamicInfo[] getActiveMicrophones();
+  android.media.audio.common.MicrophoneDynamicInfo[] getActiveMicrophones();
   android.hardware.audio.core.IStreamIn.MicrophoneDirection getMicrophoneDirection();
   void setMicrophoneDirection(android.hardware.audio.core.IStreamIn.MicrophoneDirection direction);
   float getMicrophoneFieldDimension();
@@ -43,7 +43,7 @@
   void updateMetadata(in android.hardware.audio.common.SinkMetadata sinkMetadata);
   float[] getHwGain();
   void setHwGain(in float[] channelGains);
-  const int MIC_FIELD_DIMENSION_WIDE_ANGLE = (-1);
+  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;
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IStreamOut.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IStreamOut.aidl
index 46acc11..ec3078e 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IStreamOut.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IStreamOut.aidl
@@ -36,6 +36,7 @@
 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();
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/ITelephony.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/ITelephony.aidl
index 001d074..84d7aa1 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/ITelephony.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/ITelephony.aidl
@@ -46,7 +46,7 @@
     const int VOICE_VOLUME_MAX = 1;
     @Backing(type="int") @VintfStability
     enum TtyMode {
-      UNSPECIFIED = (-1),
+      UNSPECIFIED = (-1) /* -1 */,
       OFF = 0,
       FULL = 1,
       HCO = 2,
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneInfo.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneInfo.aidl
deleted file mode 100644
index b77afe3..0000000
--- a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneInfo.aidl
+++ /dev/null
@@ -1,82 +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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// 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 MicrophoneInfo {
-  @utf8InCpp String id;
-  android.media.audio.common.AudioDevice device;
-  android.hardware.audio.core.MicrophoneInfo.Location location = android.hardware.audio.core.MicrophoneInfo.Location.UNKNOWN;
-  int group = GROUP_UNKNOWN;
-  int indexInTheGroup = INDEX_IN_THE_GROUP_UNKNOWN;
-  @nullable android.hardware.audio.core.MicrophoneInfo.Sensitivity sensitivity;
-  android.hardware.audio.core.MicrophoneInfo.Directionality directionality = android.hardware.audio.core.MicrophoneInfo.Directionality.UNKNOWN;
-  android.hardware.audio.core.MicrophoneInfo.FrequencyResponsePoint[] frequencyResponse;
-  @nullable android.hardware.audio.core.MicrophoneInfo.Coordinate position;
-  @nullable android.hardware.audio.core.MicrophoneInfo.Coordinate orientation;
-  const int GROUP_UNKNOWN = (-1);
-  const int INDEX_IN_THE_GROUP_UNKNOWN = (-1);
-  @Backing(type="int") @VintfStability
-  enum Location {
-    UNKNOWN = 0,
-    MAINBODY = 1,
-    MAINBODY_MOVABLE = 2,
-    PERIPHERAL = 3,
-  }
-  @VintfStability
-  parcelable Sensitivity {
-    float leveldBFS;
-    float maxSpldB;
-    float minSpldB;
-  }
-  @Backing(type="int") @VintfStability
-  enum Directionality {
-    UNKNOWN = 0,
-    OMNI = 1,
-    BI_DIRECTIONAL = 2,
-    CARDIOID = 3,
-    HYPER_CARDIOID = 4,
-    SUPER_CARDIOID = 5,
-  }
-  @VintfStability
-  parcelable FrequencyResponsePoint {
-    float frequencyHz;
-    float leveldB;
-  }
-  @VintfStability
-  parcelable Coordinate {
-    float x;
-    float y;
-    float z;
-  }
-}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/StreamDescriptor.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/StreamDescriptor.aidl
index a65d7b7..3e3dc38 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/StreamDescriptor.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/StreamDescriptor.aidl
@@ -39,12 +39,12 @@
   int frameSizeBytes;
   long bufferSizeFrames;
   android.hardware.audio.core.StreamDescriptor.AudioBuffer audio;
-  const int LATENCY_UNKNOWN = (-1);
+  const int LATENCY_UNKNOWN = (-1) /* -1 */;
   @FixedSize @VintfStability
   parcelable Position {
-    long frames = UNKNOWN;
-    long timeNs = UNKNOWN;
-    const long UNKNOWN = (-1);
+    long frames = UNKNOWN /* -1 */;
+    long timeNs = UNKNOWN /* -1 */;
+    const long UNKNOWN = (-1) /* -1 */;
   }
   @Backing(type="int") @VintfStability
   enum State {
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/AcousticEchoCanceler.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/AcousticEchoCanceler.aidl
index 1d51ade..16367c0 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/AcousticEchoCanceler.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/AcousticEchoCanceler.aidl
@@ -39,13 +39,7 @@
   boolean mobileMode;
   @VintfStability
   union Id {
-    int vendorExtensionTag;
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
     android.hardware.audio.effect.AcousticEchoCanceler.Tag commonTag;
   }
-  @VintfStability
-  parcelable Capability {
-    ParcelableHolder extension;
-    int maxEchoDelayUs;
-    boolean supportMobileMode;
-  }
 }
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/AutomaticGainControlV1.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/AutomaticGainControlV1.aidl
index ff010c6..e69e2bd 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/AutomaticGainControlV1.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/AutomaticGainControlV1.aidl
@@ -40,12 +40,7 @@
   boolean enableLimiter;
   @VintfStability
   union Id {
-    int vendorExtensionTag;
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
     android.hardware.audio.effect.AutomaticGainControlV1.Tag commonTag;
   }
-  @VintfStability
-  parcelable Capability {
-    ParcelableHolder extension;
-    android.hardware.audio.effect.Range[] ranges;
-  }
 }
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/AutomaticGainControl.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/AutomaticGainControlV2.aidl
similarity index 84%
rename from audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/AutomaticGainControl.aidl
rename to audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/AutomaticGainControlV2.aidl
index 39068d5..46ffcaf 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/AutomaticGainControl.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/AutomaticGainControlV2.aidl
@@ -33,21 +33,15 @@
 
 package android.hardware.audio.effect;
 @VintfStability
-union AutomaticGainControl {
+union AutomaticGainControlV2 {
   android.hardware.audio.effect.VendorExtension vendor;
   int fixedDigitalGainMb;
-  android.hardware.audio.effect.AutomaticGainControl.LevelEstimator levelEstimator;
+  android.hardware.audio.effect.AutomaticGainControlV2.LevelEstimator levelEstimator;
   int saturationMarginMb;
   @VintfStability
   union Id {
-    int vendorExtensionTag;
-    android.hardware.audio.effect.AutomaticGainControl.Tag commonTag;
-  }
-  @VintfStability
-  parcelable Capability {
-    ParcelableHolder extension;
-    int maxFixedDigitalGainMb;
-    int maxSaturationMarginMb;
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
+    android.hardware.audio.effect.AutomaticGainControlV2.Tag commonTag;
   }
   @Backing(type="int") @VintfStability
   enum LevelEstimator {
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/BassBoost.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/BassBoost.aidl
index f8baa2a..c248ce8 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/BassBoost.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/BassBoost.aidl
@@ -38,13 +38,7 @@
   int strengthPm;
   @VintfStability
   union Id {
-    int vendorExtensionTag;
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
     android.hardware.audio.effect.BassBoost.Tag commonTag;
   }
-  @VintfStability
-  parcelable Capability {
-    ParcelableHolder extension;
-    int maxStrengthPm;
-    boolean strengthSupported;
-  }
 }
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Capability.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Capability.aidl
index 28f77b3..c9df073 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Capability.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Capability.aidl
@@ -33,20 +33,7 @@
 
 package android.hardware.audio.effect;
 @VintfStability
-union Capability {
+parcelable Capability {
   android.hardware.audio.effect.VendorExtension vendorExtension;
-  android.hardware.audio.effect.AcousticEchoCanceler.Capability acousticEchoCanceler;
-  android.hardware.audio.effect.AutomaticGainControl.Capability automaticGainControl;
-  android.hardware.audio.effect.BassBoost.Capability bassBoost;
-  android.hardware.audio.effect.Downmix.Capability downmix;
-  android.hardware.audio.effect.DynamicsProcessing.Capability dynamicsProcessing;
-  android.hardware.audio.effect.EnvironmentalReverb.Capability environmentalReverb;
-  android.hardware.audio.effect.Equalizer.Capability equalizer;
-  android.hardware.audio.effect.HapticGenerator.Capability hapticGenerator;
-  android.hardware.audio.effect.LoudnessEnhancer.Capability loudnessEnhancer;
-  android.hardware.audio.effect.NoiseSuppression.Capability noiseSuppression;
-  android.hardware.audio.effect.PresetReverb.Capability presetReverb;
-  android.hardware.audio.effect.Virtualizer.Capability virtualizer;
-  android.hardware.audio.effect.Visualizer.Capability visualizer;
-  android.hardware.audio.effect.Volume.Capability volume;
+  android.hardware.audio.effect.Range range;
 }
diff --git a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/Mode.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/DefaultExtension.aidl
similarity index 84%
rename from security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/Mode.aidl
rename to audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/DefaultExtension.aidl
index 295c32e..f1cf389 100644
--- a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/Mode.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/DefaultExtension.aidl
@@ -1,11 +1,11 @@
 /*
- * Copyright 2021, 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.
  * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      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,
@@ -31,12 +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.security.dice;
-/* @hide */
-@Backing(type="int") @VintfStability
-enum Mode {
-  NOT_INITIALIZED = 0,
-  NORMAL = 1,
-  DEBUG = 2,
-  RECOVERY = 3,
+package android.hardware.audio.effect;
+@VintfStability
+parcelable DefaultExtension {
+  byte[] bytes;
 }
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 990d369..82dae97 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
@@ -36,19 +36,22 @@
 parcelable Descriptor {
   android.hardware.audio.effect.Descriptor.Common common;
   android.hardware.audio.effect.Capability capability;
-  const String EFFECT_TYPE_UUID_ENV_REVERB = "c2e5d5f0-94bd-4763-9cac-4e234d06839e";
-  const String EFFECT_TYPE_UUID_PRESET_REVERB = "47382d60-ddd8-11db-bf3a-0002a5d5c51b";
-  const String EFFECT_TYPE_UUID_EQUALIZER = "0bed4300-ddd6-11db-8f34-0002a5d5c51b";
-  const String EFFECT_TYPE_UUID_BASS_BOOST = "0634f220-ddd4-11db-a0fc-0002a5d5c51b";
-  const String EFFECT_TYPE_UUID_VIRTUALIZER = "37cc2c00-dddd-11db-8577-0002a5d5c51b";
-  const String EFFECT_TYPE_UUID_AGC = "0a8abfe0-654c-11e0-ba26-0002a5d5c51b";
   const String EFFECT_TYPE_UUID_AEC = "7b491460-8d4d-11e0-bd61-0002a5d5c51b";
-  const String EFFECT_TYPE_UUID_NS = "58b4b260-8e06-11e0-aa8e-0002a5d5c51b";
-  const String EFFECT_TYPE_UUID_LOUDNESS_ENHANCER = "fe3199be-aed0-413f-87bb-11260eb63cf1";
+  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_VOLUME = "09e8ede0-ddde-11db-b4f6-0002a5d5c51b";
+  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";
   @VintfStability
   parcelable Identity {
     android.media.audio.common.AudioUuid type;
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Downmix.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Downmix.aidl
index 402441d..ce0a7df 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Downmix.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Downmix.aidl
@@ -38,14 +38,10 @@
   android.hardware.audio.effect.Downmix.Type type;
   @VintfStability
   union Id {
-    int vendorExtensionTag;
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
     android.hardware.audio.effect.Downmix.Tag commonTag;
   }
   @VintfStability
-  parcelable Capability {
-    ParcelableHolder extension;
-  }
-  @VintfStability
   enum Type {
     STRIP,
     FOLD,
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/DynamicsProcessing.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/DynamicsProcessing.aidl
index 8e5b719..04f627d 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/DynamicsProcessing.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/DynamicsProcessing.aidl
@@ -34,7 +34,7 @@
 package android.hardware.audio.effect;
 @VintfStability
 union DynamicsProcessing {
-  android.hardware.audio.effect.VendorExtension vendorExtension;
+  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;
@@ -46,15 +46,9 @@
   android.hardware.audio.effect.DynamicsProcessing.InputGain[] inputGain;
   @VintfStability
   union Id {
-    int vendorExtensionTag;
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
     android.hardware.audio.effect.DynamicsProcessing.Tag commonTag;
   }
-  @VintfStability
-  parcelable Capability {
-    ParcelableHolder extension;
-    float minCutOffFreq;
-    float maxCutOffFreq;
-  }
   enum ResolutionPreference {
     FAVOR_FREQUENCY_RESOLUTION,
     FAVOR_TIME_RESOLUTION,
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/EnvironmentalReverb.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/EnvironmentalReverb.aidl
index 9edad09..00b7d1a 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/EnvironmentalReverb.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/EnvironmentalReverb.aidl
@@ -39,6 +39,8 @@
   int roomHfLevelMb;
   int decayTimeMs;
   int decayHfRatioPm;
+  int reflectionsLevelMb;
+  int reflectionsDelayMs;
   int levelMb;
   int delayMs;
   int diffusionPm;
@@ -46,23 +48,7 @@
   boolean bypass;
   @VintfStability
   union Id {
-    int vendorExtensionTag;
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
     android.hardware.audio.effect.EnvironmentalReverb.Tag commonTag;
   }
-  @VintfStability
-  parcelable Capability {
-    android.hardware.audio.effect.VendorExtension extension;
-    int minRoomLevelMb;
-    int maxRoomLevelMb;
-    int minRoomHfLevelMb;
-    int maxRoomHfLevelMb;
-    int maxDecayTimeMs;
-    int minDecayHfRatioPm;
-    int maxDecayHfRatioPm;
-    int minLevelMb;
-    int maxLevelMb;
-    int maxDelayMs;
-    int maxDiffusionPm;
-    int maxDensityPm;
-  }
 }
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Equalizer.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Equalizer.aidl
index d825eac..80f7c7e 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Equalizer.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Equalizer.aidl
@@ -34,21 +34,18 @@
 package android.hardware.audio.effect;
 @VintfStability
 union Equalizer {
-  android.hardware.audio.effect.VendorExtension vendorExtension;
+  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 {
-    int vendorExtensionTag;
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
     android.hardware.audio.effect.Equalizer.Tag commonTag;
   }
   @VintfStability
-  parcelable Capability {
-    ParcelableHolder extension;
-    android.hardware.audio.effect.Equalizer.BandFrequency[] bandFrequencies;
-    android.hardware.audio.effect.Equalizer.Preset[] presets;
-  }
-  @VintfStability
   parcelable BandLevel {
     int index;
     int levelMb;
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/HapticGenerator.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/HapticGenerator.aidl
index 20f7e02..8addab7 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/HapticGenerator.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/HapticGenerator.aidl
@@ -34,23 +34,19 @@
 package android.hardware.audio.effect;
 @VintfStability
 union HapticGenerator {
-  android.hardware.audio.effect.VendorExtension vendorExtension;
+  android.hardware.audio.effect.VendorExtension vendor;
   android.hardware.audio.effect.HapticGenerator.HapticScale[] hapticScales;
   android.hardware.audio.effect.HapticGenerator.VibratorInformation vibratorInfo;
   @VintfStability
   union Id {
-    int vendorExtensionTag;
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
     android.hardware.audio.effect.HapticGenerator.Tag commonTag;
   }
-  @VintfStability
-  parcelable Capability {
-    android.hardware.audio.effect.VendorExtension extension;
-  }
   @Backing(type="int") @VintfStability
   enum VibratorScale {
-    MUTE = (-100),
-    VERY_LOW = (-2),
-    LOW = (-1),
+    MUTE = (-100) /* -100 */,
+    VERY_LOW = (-2) /* -2 */,
+    LOW = (-1) /* -1 */,
     NONE = 0,
     HIGH = 1,
     VERY_HIGH = 2,
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/LoudnessEnhancer.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/LoudnessEnhancer.aidl
index 5c6ca16..fc276d6 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/LoudnessEnhancer.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/LoudnessEnhancer.aidl
@@ -38,11 +38,7 @@
   int gainMb;
   @VintfStability
   union Id {
-    int vendorExtensionTag;
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
     android.hardware.audio.effect.LoudnessEnhancer.Tag commonTag;
   }
-  @VintfStability
-  parcelable Capability {
-    android.hardware.audio.effect.VendorExtension extension;
-  }
 }
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/NoiseSuppression.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/NoiseSuppression.aidl
index 1cf92ef..7f30fe2 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/NoiseSuppression.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/NoiseSuppression.aidl
@@ -36,15 +36,12 @@
 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 {
-    int vendorExtensionTag;
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
     android.hardware.audio.effect.NoiseSuppression.Tag commonTag;
   }
-  @VintfStability
-  parcelable Capability {
-    ParcelableHolder extension;
-  }
   @Backing(type="int") @VintfStability
   enum Level {
     LOW,
@@ -52,4 +49,9 @@
     HIGH,
     VERY_HIGH,
   }
+  @Backing(type="int") @VintfStability
+  enum Type {
+    SINGLE_CHANNEL,
+    MULTI_CHANNEL,
+  }
 }
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Parameter.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Parameter.aidl
index 3ba44a0..0422bd9 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Parameter.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Parameter.aidl
@@ -38,13 +38,15 @@
   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 {
-    int vendorEffectTag;
+    android.hardware.audio.effect.VendorExtension vendorEffectTag;
     android.hardware.audio.effect.AcousticEchoCanceler.Id acousticEchoCancelerTag;
-    android.hardware.audio.effect.AutomaticGainControl.Id automaticGainControlTag;
+    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;
@@ -75,7 +77,8 @@
   union Specific {
     android.hardware.audio.effect.VendorExtension vendorEffect;
     android.hardware.audio.effect.AcousticEchoCanceler acousticEchoCanceler;
-    android.hardware.audio.effect.AutomaticGainControl automaticGainControl;
+    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;
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/PresetReverb.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/PresetReverb.aidl
index 4651742..26d96b5 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/PresetReverb.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/PresetReverb.aidl
@@ -35,6 +35,7 @@
 @VintfStability
 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 {
@@ -48,12 +49,7 @@
   }
   @VintfStability
   union Id {
-    int vendorExtensionTag;
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
     android.hardware.audio.effect.PresetReverb.Tag commonTag;
   }
-  @VintfStability
-  parcelable Capability {
-    android.hardware.audio.effect.VendorExtension extension;
-    android.hardware.audio.effect.PresetReverb.Presets[] supportedPresets;
-  }
 }
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Range.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Range.aidl
index 531d3a1..93edc5e 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Range.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Range.aidl
@@ -33,34 +33,101 @@
 
 package android.hardware.audio.effect;
 @VintfStability
-parcelable Range {
-  int tag;
-  android.hardware.audio.effect.Range.Types types;
+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 Int {
-    int min;
-    int max;
+  parcelable AcousticEchoCancelerRange {
+    android.hardware.audio.effect.AcousticEchoCanceler min;
+    android.hardware.audio.effect.AcousticEchoCanceler max;
   }
   @VintfStability
-  parcelable Float {
-    float min;
-    float max;
+  parcelable AutomaticGainControlV1Range {
+    android.hardware.audio.effect.AutomaticGainControlV1 min;
+    android.hardware.audio.effect.AutomaticGainControlV1 max;
   }
   @VintfStability
-  parcelable Long {
-    long min;
-    long max;
+  parcelable AutomaticGainControlV2Range {
+    android.hardware.audio.effect.AutomaticGainControlV2 min;
+    android.hardware.audio.effect.AutomaticGainControlV2 max;
   }
   @VintfStability
-  parcelable Byte {
-    byte min;
-    byte max;
+  parcelable BassBoostRange {
+    android.hardware.audio.effect.BassBoost min;
+    android.hardware.audio.effect.BassBoost max;
   }
   @VintfStability
-  union Types {
-    android.hardware.audio.effect.Range.Int rangeInt;
-    android.hardware.audio.effect.Range.Float rangeFloat;
-    android.hardware.audio.effect.Range.Long rangeLong;
-    android.hardware.audio.effect.Range.Byte rangeByte;
+  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/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Virtualizer.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Virtualizer.aidl
index 9fdd692..6092b14 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Virtualizer.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Virtualizer.aidl
@@ -36,15 +36,23 @@
 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 {
-    int vendorExtensionTag;
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
     android.hardware.audio.effect.Virtualizer.Tag commonTag;
+    android.hardware.audio.effect.Virtualizer.SpeakerAnglesPayload speakerAnglesPayload;
   }
   @VintfStability
-  parcelable Capability {
-    android.hardware.audio.effect.VendorExtension extension;
-    int maxStrengthPm;
-    boolean strengthSupported;
+  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/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Visualizer.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Visualizer.aidl
index c8cb551..7d319da 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Visualizer.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Visualizer.aidl
@@ -36,30 +36,18 @@
 union Visualizer {
   android.hardware.audio.effect.Visualizer.Id id;
   android.hardware.audio.effect.VendorExtension vendor;
-  android.hardware.audio.effect.Visualizer.GetOnlyParameters getOnlyParameters;
-  android.hardware.audio.effect.Visualizer.SetOnlyParameters setOnlyParameters;
+  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 {
-    int vendorExtensionTag;
-    android.hardware.audio.effect.Visualizer.GetOnlyParameters.Tag getOnlyParamTag;
-    android.hardware.audio.effect.Visualizer.SetOnlyParameters.Tag setOnlyParamTag;
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
     android.hardware.audio.effect.Visualizer.Tag commonTag;
   }
   @VintfStability
-  parcelable Capability {
-    android.hardware.audio.effect.VendorExtension extension;
-    int maxLatencyMs;
-    android.hardware.audio.effect.Visualizer.CaptureSamplesRange captureSampleRange;
-  }
-  @VintfStability
-  parcelable CaptureSamplesRange {
-    int min;
-    int max;
-  }
-  @VintfStability
   enum ScalingMode {
     NORMALIZED = 0,
     AS_PLAYED,
@@ -70,17 +58,8 @@
     PEAK_RMS,
   }
   @VintfStability
-  union GetOnlyParameters {
-    android.hardware.audio.effect.Visualizer.GetOnlyParameters.Measurement measurement;
-    byte[] captureSampleBuffer;
-    @VintfStability
-    parcelable Measurement {
-      int rms;
-      int peak;
-    }
-  }
-  @VintfStability
-  union SetOnlyParameters {
-    int latencyMs;
+  parcelable Measurement {
+    int rms;
+    int peak;
   }
 }
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Volume.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Volume.aidl
index 6259cfb..8227118 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Volume.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Volume.aidl
@@ -39,13 +39,7 @@
   boolean mute;
   @VintfStability
   union Id {
-    int vendorExtensionTag;
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
     android.hardware.audio.effect.Volume.Tag commonTag;
   }
-  @VintfStability
-  parcelable Capability {
-    android.hardware.audio.effect.VendorExtension extension;
-    int minLevelDb;
-    int maxLevelDb;
-  }
 }
diff --git a/audio/aidl/android/hardware/audio/common/AudioOffloadMetadata.aidl b/audio/aidl/android/hardware/audio/common/AudioOffloadMetadata.aidl
new file mode 100644
index 0000000..5881658
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/common/AudioOffloadMetadata.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.audio.common;
+
+import android.media.audio.common.AudioChannelLayout;
+
+/**
+ * Dynamic metadata for offloaded compressed audio.
+ * For static metadata, see android.media.audio.common.AudioOffloadInfo.
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable AudioOffloadMetadata {
+    int sampleRate;
+    AudioChannelLayout channelMask;
+    /** Average bit rate in bits per second. */
+    int averageBitRatePerSecond;
+    /**
+     * Number of frames to be ignored at the beginning of the stream.
+     * The value must be non-negative. A value of 0 indicates no delay
+     * has to be applied.
+     */
+    int delayFrames;
+    /**
+     * Number of frames to be ignored at the end of the stream.
+     * The value must be non-negative. A value of 0 indicates no padding
+     * has to be applied.
+     */
+    int paddingFrames;
+}
diff --git a/audio/aidl/android/hardware/audio/core/IBluetooth.aidl b/audio/aidl/android/hardware/audio/core/IBluetooth.aidl
index 21ac8e2..7fa2e24 100644
--- a/audio/aidl/android/hardware/audio/core/IBluetooth.aidl
+++ b/audio/aidl/android/hardware/audio/core/IBluetooth.aidl
@@ -25,6 +25,9 @@
  * and the SCO Link. This interface is optional to implement and provide by the
  * vendor. It needs to be provided only if the device actually supports BT SCO
  * or HFP.
+ *
+ * Each of IBluetooth* interfaces is independent of each other. The HAL module
+ * can provide any combination of them.
  */
 @VintfStability
 interface IBluetooth {
diff --git a/audio/aidl/android/hardware/audio/core/IBluetoothA2dp.aidl b/audio/aidl/android/hardware/audio/core/IBluetoothA2dp.aidl
new file mode 100644
index 0000000..a690ca4
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/core/IBluetoothA2dp.aidl
@@ -0,0 +1,83 @@
+/*
+ * 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.audio.core;
+
+import android.hardware.audio.core.VendorParameter;
+
+/**
+ * An instance of IBluetoothA2dp manages settings for the A2DP (Advanced Audio
+ * Distribution Profile) profiles. This interface is optional to implement by
+ * the vendor. It needs to be provided only if the device actually supports BT
+ * A2DP.
+ *
+ * Each of IBluetooth* interfaces is independent of each other. The HAL module
+ * can provide any combination of them.
+ */
+@VintfStability
+interface IBluetoothA2dp {
+    /**
+     * Whether BT A2DP is enabled.
+     *
+     * Returns the current state of A2DP support. The client might need to
+     * disable (suspend) A2DP when another profile (for example, SCO) is
+     * activated.
+     *
+     * @return Whether BT A2DP is enabled.
+     */
+    boolean isEnabled();
+
+    /**
+     * Enable or disable A2DP.
+     *
+     * Sets the current state of A2DP support. The client might need to
+     * disable (suspend) A2DP when another profile (for example, SCO) is
+     * activated.
+     *
+     * @param enabled Whether BT A2DP must be enabled or suspended.
+     * @throws EX_ILLEGAL_STATE If there was an error performing the operation.
+     */
+    void setEnabled(boolean enabled);
+
+    /**
+     * Indicates whether the module supports reconfiguration of offloaded codecs.
+     *
+     * Offloaded codec implementations may need to be reconfigured when the
+     * active A2DP device changes. This method indicates whether the HAL module
+     * supports the reconfiguration event. The result returned from this method
+     * must not change over time.
+     *
+     * @return Whether reconfiguration offload of offloaded codecs is supported.
+     */
+    boolean supportsOffloadReconfiguration();
+
+    /**
+     * Instructs the HAL module to reconfigure offloaded codec.
+     *
+     * Offloaded codec implementations may need to be reconfigured when the
+     * active A2DP device changes. This method is a notification for the HAL
+     * module to commence reconfiguration.
+     *
+     * Note that 'EX_UNSUPPORTED_OPERATION' must be thrown if and only if
+     * 'supportsOffloadReconfiguration' returns 'false'.
+     *
+     * @param parameter Optional vendor-specific parameters, can be left empty.
+     * @throws EX_ILLEGAL_STATE If there was an error performing the operation,
+     *                          or the operation can not be commenced in the current state.
+     * @throws EX_UNSUPPORTED_OPERATION If the module does not support codec reconfiguration.
+     */
+    void reconfigureOffload(in VendorParameter[] parameters);
+}
diff --git a/audio/aidl/android/hardware/audio/core/IBluetoothLe.aidl b/audio/aidl/android/hardware/audio/core/IBluetoothLe.aidl
new file mode 100644
index 0000000..444ff68
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/core/IBluetoothLe.aidl
@@ -0,0 +1,82 @@
+/*
+ * 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.audio.core;
+
+import android.hardware.audio.core.VendorParameter;
+
+/**
+ * An instance of IBluetoothLe manages settings for the LE (Low Energy)
+ * profiles. This interface is optional to implement by the vendor. It needs to
+ * be provided only if the device actually supports BT LE.
+ *
+ * Each of IBluetooth* interfaces is independent of each other. The HAL module
+ * can provide any combination of them.
+ */
+@VintfStability
+interface IBluetoothLe {
+    /**
+     * Whether BT LE is enabled.
+     *
+     * Returns the current state of LE support. The client might need to
+     * disable (suspend) LE when another profile (for example, SCO) is
+     * activated.
+     *
+     * @return Whether BT LE is enabled.
+     */
+    boolean isEnabled();
+
+    /**
+     * Enable or disable LE.
+     *
+     * Sets the current state of LE support. The client might need to
+     * disable (suspend) LE when another Bluetooth profile (for example, SCO) is
+     * activated.
+     *
+     * @param enabled Whether BT LE must be enabled or suspended.
+     * @throws EX_ILLEGAL_STATE If there was an error performing the operation.
+     */
+    void setEnabled(boolean enabled);
+
+    /**
+     * Indicates whether the module supports reconfiguration of offloaded codecs.
+     *
+     * Offloaded codec implementations may need to be reconfigured when the
+     * active LE device changes. This method indicates whether the HAL module
+     * supports the reconfiguration event. The result returned from this method
+     * must not change over time.
+     *
+     * @return Whether reconfiguration offload of offloaded codecs is supported.
+     */
+    boolean supportsOffloadReconfiguration();
+
+    /**
+     * Instructs the HAL module to reconfigure offloaded codec.
+     *
+     * Offloaded codec implementations may need to be reconfigured when the
+     * active LE device changes. This method is a notification for the HAL
+     * module to commence reconfiguration.
+     *
+     * Note that 'EX_UNSUPPORTED_OPERATION' must be thrown if and only if
+     * 'supportsOffloadReconfiguration' returns 'false'.
+     *
+     * @param parameter Optional vendor-specific parameters, can be left empty.
+     * @throws EX_ILLEGAL_STATE If there was an error performing the operation,
+     *                          or the operation can not be commenced in the current state.
+     * @throws EX_UNSUPPORTED_OPERATION If the module does not support codec reconfiguration.
+     */
+    void reconfigureOffload(in VendorParameter[] parameters);
+}
diff --git a/audio/aidl/android/hardware/audio/core/IModule.aidl b/audio/aidl/android/hardware/audio/core/IModule.aidl
index 968b573..7622d9a 100644
--- a/audio/aidl/android/hardware/audio/core/IModule.aidl
+++ b/audio/aidl/android/hardware/audio/core/IModule.aidl
@@ -21,12 +21,13 @@
 import android.hardware.audio.core.AudioPatch;
 import android.hardware.audio.core.AudioRoute;
 import android.hardware.audio.core.IBluetooth;
+import android.hardware.audio.core.IBluetoothA2dp;
+import android.hardware.audio.core.IBluetoothLe;
 import android.hardware.audio.core.IStreamCallback;
 import android.hardware.audio.core.IStreamIn;
 import android.hardware.audio.core.IStreamOut;
 import android.hardware.audio.core.IStreamOutEventCallback;
 import android.hardware.audio.core.ITelephony;
-import android.hardware.audio.core.MicrophoneInfo;
 import android.hardware.audio.core.ModuleDebug;
 import android.hardware.audio.core.StreamDescriptor;
 import android.hardware.audio.core.VendorParameter;
@@ -39,6 +40,7 @@
 import android.media.audio.common.AudioPort;
 import android.media.audio.common.AudioPortConfig;
 import android.media.audio.common.Float;
+import android.media.audio.common.MicrophoneInfo;
 
 /**
  * Each instance of IModule corresponds to a separate audio module. The system
@@ -103,6 +105,34 @@
     @nullable IBluetooth getBluetooth();
 
     /**
+     * Retrieve the interface to control Bluetooth A2DP.
+     *
+     * If the HAL module supports A2DP Profile functionality for Bluetooth, it
+     * must return an instance of the IBluetoothA2dp interface. The same
+     * instance must be returned during the lifetime of the HAL module. If the
+     * HAL module does not support BT A2DP, a null must be returned, without
+     * throwing any errors.
+     *
+     * @return An instance of the IBluetoothA2dp interface implementation.
+     * @throws EX_ILLEGAL_STATE If there was an error creating an instance.
+     */
+    @nullable IBluetoothA2dp getBluetoothA2dp();
+
+    /**
+     * Retrieve the interface to control Bluetooth LE.
+     *
+     * If the HAL module supports LE Profile functionality for Bluetooth, it
+     * must return an instance of the IBluetoothLe interface. The same
+     * instance must be returned during the lifetime of the HAL module. If the
+     * HAL module does not support BT LE, a null must be returned, without
+     * throwing any errors.
+     *
+     * @return An instance of the IBluetoothLe interface implementation.
+     * @throws EX_ILLEGAL_STATE If there was an error creating an instance.
+     */
+    @nullable IBluetoothLe getBluetoothLe();
+
+    /**
      * Set a device port of an external device into connected state.
      *
      * This method is used to inform the HAL module that an external device has
@@ -162,6 +192,19 @@
      * device address is specified for a point-to-multipoint external device
      * connection.
      *
+     * Since not all modules have a DSP that could perform sample rate and
+     * format conversions, behavior related to mix port configurations may vary.
+     * For modules with a DSP, mix ports can be pre-configured and have a fixed
+     * set of audio profiles supported by the DSP. For modules without a DSP,
+     * audio profiles of mix ports may change after connecting an external
+     * device. The typical case is that the mix port has an empty set of
+     * profiles when no external devices are connected, and after external
+     * device connection it receives the same set of profiles as the device
+     * ports that they can be routed to. The client will re-query current port
+     * configurations using 'getAudioPorts'. All mix ports that can be routed to
+     * the connected device port must have a non-empty set of audio profiles
+     * after successful connection of an external device.
+     *
      * Handling of a disconnect is done in a reverse order:
      *  1. Reset port configuration using the 'resetAudioPortConfig' method.
      *  2. Release the connected device port by calling the 'disconnectExternalDevice'
@@ -596,6 +639,7 @@
      * @param mute Whether the output from the module is muted.
      * @throws EX_UNSUPPORTED_OPERATION If muting of combined output
      *                                  is not supported by the module.
+     * @throws EX_ILLEGAL_STATE If any error happens while muting of combined output.
      */
     void setMasterMute(boolean mute);
 
@@ -627,6 +671,8 @@
      *                             accepted range.
      * @throws EX_UNSUPPORTED_OPERATION If attenuation of combined output
      *                                  is not supported by the module.
+     * @throws EX_ILLEGAL_STATE If any error happens while updating attenuation of
+                                combined output.
      */
     void setMasterVolume(float volume);
 
@@ -824,7 +870,7 @@
     AudioMMapPolicyInfo[] getMmapPolicyInfos(AudioMMapPolicyType mmapPolicyType);
 
     /**
-     * Indicates if this module supports variable latency control for instance
+     * Indicates if this module supports variable latency control, for instance,
      * over Bluetooth A2DP or LE Audio links.
      *
      * If supported, all instances of IStreamOut interface returned by this module must
diff --git a/audio/aidl/android/hardware/audio/core/IStreamCommon.aidl b/audio/aidl/android/hardware/audio/core/IStreamCommon.aidl
index 533ef67..543d9e2 100644
--- a/audio/aidl/android/hardware/audio/core/IStreamCommon.aidl
+++ b/audio/aidl/android/hardware/audio/core/IStreamCommon.aidl
@@ -44,6 +44,33 @@
     void close();
 
     /**
+     * Notify the stream that it is about to be closed.
+     *
+     * This is a notification sent by the client to indicate that it intends to
+     * close the stream "soon" (the actual time period is unspecified). The
+     * purpose of this notification is to allow the stream implementation to
+     * unblock the I/O thread. This is useful for HAL modules that act as
+     * proxies to other subsystems, examples are "bluetooth" and "r_submix"
+     * modules. In such modules the I/O thread might get blocked on a read or
+     * write operation to the external subsystem. Thus, calling 'close' directly
+     * will stall, as it will try to send the 'Command.halReservedExit' on the
+     * I/O thread which is blocked and is not reading commands from the FMQ. The
+     * HAL implementation must initiate unblocking as a result of receiving the
+     * 'prepareToClose' notification.
+     *
+     * This operation must be handled by the HAL module in an "asynchronous"
+     * manner, returning control back as quick as possible.
+     *
+     * Since this operation does not have any effects observable from the client
+     * side, the HAL module must be able to handle multiple calls of this method
+     * without throwing any errors. The only case when this method is allowed
+     * to throw is when the stream has been closed.
+     *
+     * @throws EX_ILLEGAL_STATE If the stream is closed.
+     */
+    void prepareToClose();
+
+    /**
      * Update the HW AV Sync identifier for the stream.
      *
      * The argument to this method must be one of the identifiers previously
diff --git a/audio/aidl/android/hardware/audio/core/IStreamIn.aidl b/audio/aidl/android/hardware/audio/core/IStreamIn.aidl
index c2b3633..93cad11 100644
--- a/audio/aidl/android/hardware/audio/core/IStreamIn.aidl
+++ b/audio/aidl/android/hardware/audio/core/IStreamIn.aidl
@@ -18,7 +18,7 @@
 
 import android.hardware.audio.common.SinkMetadata;
 import android.hardware.audio.core.IStreamCommon;
-import android.hardware.audio.core.MicrophoneDynamicInfo;
+import android.media.audio.common.MicrophoneDynamicInfo;
 
 /**
  * This interface provides means for receiving audio data from input devices.
diff --git a/audio/aidl/android/hardware/audio/core/IStreamOut.aidl b/audio/aidl/android/hardware/audio/core/IStreamOut.aidl
index 0e58add..f26dc1c 100644
--- a/audio/aidl/android/hardware/audio/core/IStreamOut.aidl
+++ b/audio/aidl/android/hardware/audio/core/IStreamOut.aidl
@@ -16,6 +16,7 @@
 
 package android.hardware.audio.core;
 
+import android.hardware.audio.common.AudioOffloadMetadata;
 import android.hardware.audio.common.SourceMetadata;
 import android.hardware.audio.core.IStreamCommon;
 import android.media.audio.common.AudioDualMonoMode;
@@ -48,6 +49,18 @@
      */
     void updateMetadata(in SourceMetadata sourceMetadata);
 
+    /**
+     * Update offload metadata for a compressed stream.
+     *
+     * Updates the offload metadata initially provided at the stream creation.
+     *
+     * @param offloadMetadata Updated offload metadata.
+     * @throws EX_ILLEGAL_STATE If the stream is closed.
+     * @throws EX_ILLEGAL_ARGUMENT If the metadata contains invalid values.
+     * @throws EX_UNSUPPORTED_OPERATION If the stream is not for compressed offload.
+     */
+    void updateOffloadMetadata(in AudioOffloadMetadata offloadMetadata);
+
     const int HW_VOLUME_MIN = 0;
     const int HW_VOLUME_MAX = 1;
     /**
@@ -85,7 +98,8 @@
      * @throws EX_ILLEGAL_ARGUMENT If the number of elements in the provided
      *                             array does not match the channel count, or
      *                             attenuation values are out of range.
-     * @throws EX_ILLEGAL_STATE If the stream is closed.
+     * @throws EX_ILLEGAL_STATE If the stream is closed or there is any error happens
+                                when applying hardware volume.
      * @throws EX_UNSUPPORTED_OPERATION If hardware volume control is not supported.
      */
     void setHwVolume(in float[] channelVolumes);
diff --git a/audio/aidl/android/hardware/audio/core/MicrophoneDynamicInfo.aidl b/audio/aidl/android/hardware/audio/core/MicrophoneDynamicInfo.aidl
deleted file mode 100644
index 36cc51f..0000000
--- a/audio/aidl/android/hardware/audio/core/MicrophoneDynamicInfo.aidl
+++ /dev/null
@@ -1,48 +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.audio.core;
-
-/**
- * Structure providing dynamic information on a microphone. This information
- * changes between recording sessions.
- */
-@JavaDerive(equals=true, toString=true)
-@VintfStability
-parcelable MicrophoneDynamicInfo {
-    /**
-     * Unique alphanumeric id for the microphone. It must match the id of one of
-     * the 'MicrophoneInfo' entries returned by 'IModule.getMicrophones'.
-     */
-    @utf8InCpp String id;
-
-    @VintfStability
-    @Backing(type="int")
-    enum ChannelMapping {
-        /** Channel not used. */
-        UNUSED = 0,
-        /** Channel is used and the signal is not processed. */
-        DIRECT = 1,
-        /** Channel is used and the signal has some processing. */
-        PROCESSED = 2,
-    }
-    /**
-     * The vector is indexes by zero-based channels of the microphone, thus the
-     * element '0' corresponds to the first channel, '1' is the second, etc. The
-     * vector must contain at least 1 element.
-     */
-    ChannelMapping[] channelMapping;
-}
diff --git a/audio/aidl/android/hardware/audio/core/MicrophoneInfo.aidl b/audio/aidl/android/hardware/audio/core/MicrophoneInfo.aidl
deleted file mode 100644
index 3b8c7f3..0000000
--- a/audio/aidl/android/hardware/audio/core/MicrophoneInfo.aidl
+++ /dev/null
@@ -1,146 +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.audio.core;
-
-import android.media.audio.common.AudioDevice;
-
-/**
- * Structure providing static information on a microphone. This information
- * never changes during the lifetime of the IModule which owns the microphone.
- * The information presented in this structure indicates the location and
- * orientation of the microphone on the device as well as useful information
- * like frequency response and sensitivity.
- */
-@JavaDerive(equals=true, toString=true)
-@VintfStability
-parcelable MicrophoneInfo {
-    /**
-     * Unique alphanumeric id for the microphone. It must remain the same across
-     * device reboots. The client must never attempt to parse the value of this
-     * field.
-     */
-    @utf8InCpp String id;
-    /**
-     * Describes the location of the microphone in terms of managed audio devices.
-     */
-    AudioDevice device;
-
-    @VintfStability
-    @Backing(type="int")
-    enum Location {
-        /** Microphone location is unknown. */
-        UNKNOWN = 0,
-        /** The microphone is located on the main body of the device. */
-        MAINBODY = 1,
-        /** The microphone is located on a movable main body of the device. */
-        MAINBODY_MOVABLE = 2,
-        /** The microphone is located on a peripheral. */
-        PERIPHERAL = 3,
-    }
-    /** Location of the microphone in regard to the body of the device */
-    Location location = Location.UNKNOWN;
-
-    /**
-     * This value is used when the group of the microphone is unknown.
-     */
-    const int GROUP_UNKNOWN = -1;
-    /**
-     * An identifier to group related microphones together, for example,
-     * microphones of a microphone array should all belong to the same group.
-     * Note that microphones assigned to 'GROUP_UNKNOWN' do not form a group.
-     */
-    int group = GROUP_UNKNOWN;
-    /**
-     * This value is used when the index in the group of the microphone is
-     * unknown.
-     */
-    const int INDEX_IN_THE_GROUP_UNKNOWN = -1;
-    /**
-     * Index of this microphone within the group. The pair (group, index) must
-     * be unique within the same HAL module, except the pair
-     * (GROUP_UNKNOWN, INDEX_IN_THE_GROUP_UNKNOWN).
-     */
-    int indexInTheGroup = INDEX_IN_THE_GROUP_UNKNOWN;
-
-    @VintfStability
-    parcelable Sensitivity {
-        /** Level in dBFS produced by a 1000 Hz tone at 94 dB SPL. */
-        float leveldBFS;
-        /** Level in dB of the max SPL supported at 1000 Hz */
-        float maxSpldB;
-        /** Level in dB of the min SPL supported at 1000 Hz */
-        float minSpldB;
-    }
-    /**
-     * If provided, must describe acceptable sound pressure levels (SPL)
-     * for a 1 kHz sine wave, and the resulting level in dBFS.
-     */
-    @nullable Sensitivity sensitivity;
-
-    @VintfStability
-    @Backing(type="int")
-    enum Directionality {
-        UNKNOWN = 0,
-        OMNI = 1,
-        BI_DIRECTIONAL = 2,
-        CARDIOID = 3,
-        HYPER_CARDIOID = 4,
-        SUPER_CARDIOID = 5,
-    }
-    /**
-     * The standard polar pattern of the microphone.
-     */
-    Directionality directionality = Directionality.UNKNOWN;
-
-    /**
-     * A (frequency, level) pair. Used to represent frequency response.
-     */
-    @VintfStability
-    parcelable FrequencyResponsePoint {
-        float frequencyHz;
-        float leveldB;
-    }
-    /**
-     * Vector with ordered frequency responses (from low to high frequencies)
-     * with the frequency response of the microphone. Levels are in dB,
-     * relative to level at 1000 Hz.
-     */
-    FrequencyResponsePoint[] frequencyResponse;
-
-    /**
-     * A 3D point used to represent position or orientation of a microphone.
-     */
-    @VintfStability
-    parcelable Coordinate {
-        float x;
-        float y;
-        float z;
-    }
-    /**
-     * If provided, must specify distances of the microphone's capsule, in
-     * meters, from the bottom-left-back corner of the bounding box of device in
-     * its natural orientation (PORTRAIT for phones, LANDSCAPE for tablets, TVs,
-     * etc).
-     */
-    @nullable Coordinate position;
-    /**
-     * If provided, describes the normalized point which defines the main
-     * orientation of the microphone's capsule.
-     * Magnitude = sqrt(x^2 + y^2 + z^2) = 1.
-     */
-    @nullable Coordinate orientation;
-}
diff --git a/audio/aidl/android/hardware/audio/core/sounddose/ISoundDose.aidl b/audio/aidl/android/hardware/audio/core/sounddose/ISoundDose.aidl
index 953ab62..b442ac5 100644
--- a/audio/aidl/android/hardware/audio/core/sounddose/ISoundDose.aidl
+++ b/audio/aidl/android/hardware/audio/core/sounddose/ISoundDose.aidl
@@ -35,21 +35,21 @@
     const int MIN_RS2 = 80;
 
     /**
-     * Sets the RS2 value used for momentary exposure warnings. Default value is
+     * Sets the RS2 upper bound used for momentary exposure warnings. Default value is
      * DEFAULT_MAX_RS2 as specified in IEC62368-1 3rd edition.
      *
-     * @param rs2ValueDbA custom RS2 value to use. Must not be higher than DEFAULT_MAX_RS2
+     * @param rs2ValueDbA custom RS2 upper bound to use
      * @throws EX_ILLEGAL_ARGUMENT if rs2ValueDbA is greater than DEFAULT_MAX_RS2 or lower
-     *                             than 80dBA
+     *                             than MIN_RS2
      */
-    void setOutputRs2(float rs2ValueDbA);
+    void setOutputRs2UpperBound(float rs2ValueDbA);
 
     /**
-     * Gets the RS2 value used for momentary exposure warnings.
+     * Gets the RS2 upper bound used for momentary exposure warnings.
      *
-     * @return the RS2 value in dBA
+     * @return the RS2 upper bound in dBA
      */
-    float getOutputRs2();
+    float getOutputRs2UpperBound();
 
     /**
      * Registers the HAL callback for sound dose computation. If sound dose is supported
@@ -68,9 +68,9 @@
     @VintfStability
     oneway interface IHalSoundDoseCallback {
         /**
-         * Called whenever the current MEL value exceeds the set RS2 value.
+         * Called whenever the current MEL value exceeds the set RS2 upper bound.
          *
-         * @param currentDbA the current MEL value which exceeds the RS2 value
+         * @param currentDbA the current MEL value which exceeds the RS2 upper bound
          * @param audioDevice the audio device where the MEL exposure warning was recorded
          */
         void onMomentaryExposureWarning(float currentDbA, in AudioDevice audioDevice);
@@ -78,14 +78,15 @@
         @VintfStability
         parcelable MelRecord {
             /**
-             * Array of continuously recorded MEL values >= RS1 (1 per second).
+             * Array of continuously recorded MEL values >= MIN_RS2 (1 per second).
              * First value in the array was recorded at 'timestamp'.
              */
             float[] melValues;
             /**
-             * Corresponds to the time in seconds when the first MEL entry in melValues
-             * was recorded. The timestamp values have to be consistent throughout all
-             * audio ports, equal timestamp values will be aggregated.
+             * Corresponds to the time in seconds, as reported by CLOCK_MONOTONIC, when
+             * the first MEL entry in melValues was recorded. The timestamp values have
+             * to be consistent throughout all audio ports, equal timestamp values will
+             * be aggregated.
              */
             long timestamp;
         }
diff --git a/audio/aidl/android/hardware/audio/effect/AcousticEchoCanceler.aidl b/audio/aidl/android/hardware/audio/effect/AcousticEchoCanceler.aidl
index 19d60b6..bf1f8a2 100644
--- a/audio/aidl/android/hardware/audio/effect/AcousticEchoCanceler.aidl
+++ b/audio/aidl/android/hardware/audio/effect/AcousticEchoCanceler.aidl
@@ -22,9 +22,9 @@
  * Acoustic Echo Canceler (AEC) is an audio pre-processor which removes the contribution of the
  * signal received from the remote party from the captured audio signal.
  *
- * All parameters defined in union AcousticEchoCanceler must be gettable and settable. The
- * capabilities defined in AcousticEchoCanceler.Capability can only acquired with
- * IEffect.getDescriptor() and not settable.
+ * All parameter settings must be inside the range of Capability.Range.acousticEchoCanceler
+ * definition if the definition for the corresponding parameter tag exist. See more detals about
+ * Range in Range.aidl.
  */
 @VintfStability
 union AcousticEchoCanceler {
@@ -33,7 +33,7 @@
      */
     @VintfStability
     union Id {
-        int vendorExtensionTag;
+        VendorExtension vendorExtensionTag;
         AcousticEchoCanceler.Tag commonTag;
     }
 
@@ -43,35 +43,20 @@
     VendorExtension vendor;
 
     /**
-     * Capability supported by AEC implementation.
-     */
-    @VintfStability
-    parcelable Capability {
-        /**
-         * AEC capability extension, vendor can use this extension in case existing capability
-         * definition not enough.
-         */
-        ParcelableHolder extension;
-
-        /**
-         * Maximum AEC echo delay in microseconds supported.
-         */
-        int maxEchoDelayUs;
-        /**
-         * If AEC mobile mode was supported by the AEC implementation.
-         */
-        boolean supportMobileMode;
-    }
-
-    /**
      * The AEC echo delay in microseconds.
-     * Must never be negative, and not larger than maxEchoDelayUs in capability.
      */
     int echoDelayUs;
     /**
-     * If AEC mobile mode enabled.
-     * Can only be false if AEC implementation indicate not support mobile mode by set
-     * supportMobileMode to false in capability.
+     * Indicate if the AEC mobile mode is enabled or not.
+     * If an effect implementation supports enabling and disabling mobileMode at runtime, it does
+     * not need to set the min and max range for mobileMode, or report the mobileMode min/max range
+     * as [false, true] in Range.AcousticEchoCancelerRange. If the effect implementation doesn't
+     * support mobileMode, it must report the mobileMode range as [false, false]. If the effect
+     * implementation supports mobileMode and cannot be disabled, it must report the mobileMode
+     * range as [true, true].
+     * If the effect implementation sets the range as invalid: [true, false], it indicates that
+     * mobileMode setParameter is not supported, and clients can only use getParameter to check if
+     * it's enabled or not.
      */
     boolean mobileMode;
 }
diff --git a/audio/aidl/android/hardware/audio/effect/AutomaticGainControl.aidl b/audio/aidl/android/hardware/audio/effect/AutomaticGainControl.aidl
deleted file mode 100644
index e82a564..0000000
--- a/audio/aidl/android/hardware/audio/effect/AutomaticGainControl.aidl
+++ /dev/null
@@ -1,90 +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.audio.effect;
-
-import android.hardware.audio.effect.VendorExtension;
-
-/**
- * Automatic Gain Control (AGC) is an audio pre-processor which automatically normalizes the output
- * of the captured signal by boosting or lowering input from the microphone to match a preset level
- * so that the output signal level is virtually constant. AGC can be used by applications where the
- * input signal dynamic range is not important but where a constant strong capture level is desired.
- *
- * All parameters defined in union AutomaticGainControl must be gettable and settable. The
- * capabilities defined in AutomaticGainControl.Capability can only acquired with
- * IEffect.getDescriptor() and not settable.
- */
-@VintfStability
-union AutomaticGainControl {
-    /**
-     * Effect parameter tag to identify the parameters for getParameter().
-     */
-    @VintfStability
-    union Id {
-        int vendorExtensionTag;
-        AutomaticGainControl.Tag commonTag;
-    }
-
-    /**
-     * Vendor AutomaticGainControl implementation definition for additional parameters.
-     */
-    VendorExtension vendor;
-
-    /**
-     * Capability supported by AutomaticGainControl implementation.
-     */
-    @VintfStability
-    parcelable Capability {
-        /**
-         * AutomaticGainControl capability extension, vendor can use this extension in case existing
-         * capability definition not enough.
-         */
-        ParcelableHolder extension;
-        /**
-         * Max fixed digital gain supported by AGC implementation in millibel.
-         */
-        int maxFixedDigitalGainMb;
-        /**
-         * Max fixed saturation margin supported by AGC implementation in millibel.
-         */
-        int maxSaturationMarginMb;
-    }
-
-    @VintfStability
-    @Backing(type="int")
-    enum LevelEstimator {
-        /* Use Root Mean Square level estimator*/
-        RMS = 0,
-        /* Use Peak level estimator*/
-        PEAK = 1,
-    }
-
-    /**
-     * The AGC fixed digital gain in millibel.
-     * Must never be negative, and not larger than maxFixedDigitalGainMb in capability.
-     */
-    int fixedDigitalGainMb;
-    /*
-     * Adaptive digital level estimator.
-     */
-    LevelEstimator levelEstimator;
-    /**
-     * The AGC saturation margin in millibel.
-     * Must never be negative, and not larger than maxSaturationMarginMb in capability.
-     */
-    int saturationMarginMb;
-}
diff --git a/audio/aidl/android/hardware/audio/effect/AutomaticGainControlV1.aidl b/audio/aidl/android/hardware/audio/effect/AutomaticGainControlV1.aidl
index d6e0648..e7bf99d 100644
--- a/audio/aidl/android/hardware/audio/effect/AutomaticGainControlV1.aidl
+++ b/audio/aidl/android/hardware/audio/effect/AutomaticGainControlV1.aidl
@@ -16,7 +16,6 @@
 
 package android.hardware.audio.effect;
 
-import android.hardware.audio.effect.Range;
 import android.hardware.audio.effect.VendorExtension;
 
 /**
@@ -25,9 +24,9 @@
  * so that the output signal level is virtually constant. AGC can be used by applications where the
  * input signal dynamic range is not important but where a constant strong capture level is desired.
  *
- * All parameters defined in union AutomaticGainControlV1 must be gettable and settable. The
- * capabilities defined in AutomaticGainControlV1.Capability can only acquired with
- * IEffect.getDescriptor() and not settable.
+ * All parameter settings must be inside the range of Capability.Range.automaticGainControlV1
+ * definition if the definition for the corresponding parameter tag exist. See more detals about
+ * Range in Range.aidl.
  */
 @VintfStability
 union AutomaticGainControlV1 {
@@ -36,7 +35,7 @@
      */
     @VintfStability
     union Id {
-        int vendorExtensionTag;
+        VendorExtension vendorExtensionTag;
         AutomaticGainControlV1.Tag commonTag;
     }
 
@@ -46,31 +45,13 @@
     VendorExtension vendor;
 
     /**
-     * Capability supported by AutomaticGainControlV1 implementation.
-     */
-    @VintfStability
-    parcelable Capability {
-        /**
-         * AutomaticGainControlV1 capability extension, vendor can use this extension in case
-         * existing capability definition not enough.
-         */
-        ParcelableHolder extension;
-        /**
-         * Supported range for parameters.
-         */
-        Range[] ranges;
-    }
-
-    /**
      * Target peak level (or envelope) of the AGC implementation in dBFs (dB relative to full
      * scale).
-     * Must be in range of AutomaticGainControlV1.Capability.ranges with targetPeakLevelDbFs tag.
      */
     int targetPeakLevelDbFs;
     /*
      * Sets the maximum gain the digital compression stage may apply, in dB. A higher number
      * corresponds to greater compression, while a value of 0 will leave the signal uncompressed.
-     * Must be in range of AutomaticGainControlV1.Capability.ranges with maxCompressionGainDb tag.
      */
     int maxCompressionGainDb;
     /**
diff --git a/audio/aidl/android/hardware/audio/effect/AutomaticGainControlV2.aidl b/audio/aidl/android/hardware/audio/effect/AutomaticGainControlV2.aidl
new file mode 100644
index 0000000..8f2afdc
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/effect/AutomaticGainControlV2.aidl
@@ -0,0 +1,69 @@
+/*
+ * 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.audio.effect;
+
+import android.hardware.audio.effect.VendorExtension;
+
+/**
+ * Automatic Gain Control V2 (AGC2) is an audio pre-processor which automatically normalizes the
+ * output of the captured signal by boosting or lowering input from the microphone to match a preset
+ * level so that the output signal level is virtually constant. AGC can be used by applications
+ * where the input signal dynamic range is not important but where a constant strong capture level
+ * is desired.
+ *
+ * All parameter settings must be inside the range of Capability.Range.automaticGainControlV2
+ * definition if the definition for the corresponding parameter tag exist. See more detals about
+ * Range in Range.aidl.
+ */
+@VintfStability
+union AutomaticGainControlV2 {
+    /**
+     * Effect parameter tag to identify the parameters for getParameter().
+     */
+    @VintfStability
+    union Id {
+        VendorExtension vendorExtensionTag;
+        AutomaticGainControlV2.Tag commonTag;
+    }
+
+    /**
+     * Vendor AutomaticGainControlV2 implementation definition for additional parameters.
+     */
+    VendorExtension vendor;
+
+    @VintfStability
+    @Backing(type="int")
+    enum LevelEstimator {
+        /* Use Root Mean Square level estimator*/
+        RMS = 0,
+        /* Use Peak level estimator*/
+        PEAK = 1,
+    }
+
+    /**
+     * The AGC fixed digital gain in millibel.
+     */
+    int fixedDigitalGainMb;
+    /*
+     * Adaptive digital level estimator.
+     */
+    LevelEstimator levelEstimator;
+    /**
+     * The AGC saturation margin in millibel.
+     */
+    int saturationMarginMb;
+}
diff --git a/audio/aidl/android/hardware/audio/effect/BassBoost.aidl b/audio/aidl/android/hardware/audio/effect/BassBoost.aidl
index 6a94242..479db96 100644
--- a/audio/aidl/android/hardware/audio/effect/BassBoost.aidl
+++ b/audio/aidl/android/hardware/audio/effect/BassBoost.aidl
@@ -22,8 +22,8 @@
  * Bass boost is an audio effect to boost or amplify low frequencies of the sound. It is comparable
  * to a simple equalizer but limited to one band amplification in the low frequency range.
  *
- * All parameters defined in union BassBoost must be gettable and settable. The capabilities defined
- * in BassBoost.Capability can only acquired with IEffect.getDescriptor() and not settable.
+ * All parameter settings must be inside the range of Capability.Range.bassBoost definition if the
+ * definition for the corresponding parameter tag exist. See more detals about Range in Range.aidl.
  */
 @VintfStability
 union BassBoost {
@@ -32,7 +32,7 @@
      */
     @VintfStability
     union Id {
-        int vendorExtensionTag;
+        VendorExtension vendorExtensionTag;
         BassBoost.Tag commonTag;
     }
 
@@ -42,35 +42,11 @@
     VendorExtension vendor;
 
     /**
-     * Capability supported by BassBoost implementation.
-     */
-    @VintfStability
-    parcelable Capability {
-        /**
-         * BassBoost capability extension, vendor can use this extension in case existing capability
-         * definition not enough.
-         */
-        ParcelableHolder extension;
-        /**
-         * Maximum possible per mille strength.
-         */
-        int maxStrengthPm;
-        /**
-         * Indicates whether setting strength is supported. False value indicates only one strength
-         * is supported and setParameter() method will return EX_ILLEGAL_ARGUMENT.
-         */
-        boolean strengthSupported;
-    }
-
-    /**
      * The per mille strength of the bass boost effect.
      *
      * If the implementation does not support per mille accuracy for setting the strength, it is
      * allowed to round the given strength to the nearest supported value. In this case {@link
      * #IEffect.getParameter()} method should return the rounded value that was actually set.
-     *
-     * The value of the strength must be non-negative and not exceed the value specified by
-     * the 'maxStrengthPm' capability.
      */
     int strengthPm;
 }
diff --git a/audio/aidl/android/hardware/audio/effect/Capability.aidl b/audio/aidl/android/hardware/audio/effect/Capability.aidl
index 30780e6..06c2024 100644
--- a/audio/aidl/android/hardware/audio/effect/Capability.aidl
+++ b/audio/aidl/android/hardware/audio/effect/Capability.aidl
@@ -16,21 +16,8 @@
 
 package android.hardware.audio.effect;
 
-import android.hardware.audio.effect.AcousticEchoCanceler;
-import android.hardware.audio.effect.AutomaticGainControl;
-import android.hardware.audio.effect.BassBoost;
-import android.hardware.audio.effect.Downmix;
-import android.hardware.audio.effect.DynamicsProcessing;
-import android.hardware.audio.effect.EnvironmentalReverb;
-import android.hardware.audio.effect.Equalizer;
-import android.hardware.audio.effect.HapticGenerator;
-import android.hardware.audio.effect.LoudnessEnhancer;
-import android.hardware.audio.effect.NoiseSuppression;
-import android.hardware.audio.effect.PresetReverb;
+import android.hardware.audio.effect.Range;
 import android.hardware.audio.effect.VendorExtension;
-import android.hardware.audio.effect.Virtualizer;
-import android.hardware.audio.effect.Visualizer;
-import android.hardware.audio.effect.Volume;
 
 /**
  * Effect capability definitions.
@@ -38,32 +25,19 @@
  * not meant to change at runtime.
  */
 @VintfStability
-union Capability {
+parcelable Capability {
     /**
      * Vendor defined effect capability.
-     * This extension can be used when vendor have a new effect implementated and need
+     * This extension can be used when vendor has a new effect implementation and needs
      * capability definition for this new type of effect.
-     * If vendor want to extend existing effect capabilities, it is recommended to expose though
-     * the ParcelableHolder in each effect capability definition. For example:
-     * Equalizer.Capability.extension.
+     * If vendor want to extend existing effect capabilities, it is recommended to expose through
+     * the ParcelableHolder in each effect definition. For example: Equalizer.vendorExtension. And
+     * define an appropriate Range for the extension.
      */
     VendorExtension vendorExtension;
 
     /**
-     * Effect capabilities.
+     * Supported range for parameters. See Range.aidl.
      */
-    AcousticEchoCanceler.Capability acousticEchoCanceler;
-    AutomaticGainControl.Capability automaticGainControl;
-    BassBoost.Capability bassBoost;
-    Downmix.Capability downmix;
-    DynamicsProcessing.Capability dynamicsProcessing;
-    EnvironmentalReverb.Capability environmentalReverb;
-    Equalizer.Capability equalizer;
-    HapticGenerator.Capability hapticGenerator;
-    LoudnessEnhancer.Capability loudnessEnhancer;
-    NoiseSuppression.Capability noiseSuppression;
-    PresetReverb.Capability presetReverb;
-    Virtualizer.Capability virtualizer;
-    Visualizer.Capability visualizer;
-    Volume.Capability volume;
+    Range range;
 }
diff --git a/audio/aidl/android/hardware/audio/effect/DefaultExtension.aidl b/audio/aidl/android/hardware/audio/effect/DefaultExtension.aidl
new file mode 100644
index 0000000..33e827f
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/effect/DefaultExtension.aidl
@@ -0,0 +1,38 @@
+/*
+ * 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.audio.effect;
+
+/**
+ * The default extension used for Parameter.Specific.vendorEffect ParcelableHolder.
+ *
+ * The audio framework attach this default extension to the ParcelableHolder in VendorExtension,
+ * and pass though all parameters it received from the client to audio HAL.
+ *
+ * For now it's not possible for vendor to define their own vendor extensions without changing the
+ * audio framework. More specificly, in order to add a customized effect parameter AIDL parcelable,
+ * vendors need to add the logic for conversion between AIDL and effect_param_t for the effect AIDL
+ * in: frameworks/av/media/libaudiohal/impl/effectAidlConversion.
+ *
+ * There is no VTS test cases for the vendor extension effect implementation, however all effect
+ * implementations must support the common parameters defined in Parameter.aidl, so vendor
+ * extension effect implementation still need to support setting and getting of these common
+ * parameters, which is enforced by VTS.
+ */
+@VintfStability
+parcelable DefaultExtension {
+    byte[] bytes;
+}
diff --git a/audio/aidl/android/hardware/audio/effect/Descriptor.aidl b/audio/aidl/android/hardware/audio/effect/Descriptor.aidl
index 47c88dc..2fbc401 100644
--- a/audio/aidl/android/hardware/audio/effect/Descriptor.aidl
+++ b/audio/aidl/android/hardware/audio/effect/Descriptor.aidl
@@ -37,57 +37,70 @@
      * UUID for effect types, these definitions are in sync with SDK, see @c AudioEffect.java.
      */
     /**
-     * UUID for environmental reverberation effect type.
+     * UUID for Acoustic Echo Canceler (AEC) type.
      */
-    const String EFFECT_TYPE_UUID_ENV_REVERB = "c2e5d5f0-94bd-4763-9cac-4e234d06839e";
+    const String EFFECT_TYPE_UUID_AEC = "7b491460-8d4d-11e0-bd61-0002a5d5c51b";
+
     /**
-     * UUID for preset reverberation effect type.
+     * UUID for Automatic Gain Control V1 (AGC1) type.
      */
-    const String EFFECT_TYPE_UUID_PRESET_REVERB = "47382d60-ddd8-11db-bf3a-0002a5d5c51b";
+    const String EFFECT_TYPE_UUID_AGC1 = "0a8abfe0-654c-11e0-ba26-0002a5d5c51b";
     /**
-     * UUID for equalizer effect type.
+     * UUID for Automatic Gain Control V2 (AGC2) type.
      */
-    const String EFFECT_TYPE_UUID_EQUALIZER = "0bed4300-ddd6-11db-8f34-0002a5d5c51b";
+    const String EFFECT_TYPE_UUID_AGC2 = "ae3c653b-be18-4ab8-8938-418f0a7f06ac";
     /**
      * UUID for bass boost effect type.
      */
     const String EFFECT_TYPE_UUID_BASS_BOOST = "0634f220-ddd4-11db-a0fc-0002a5d5c51b";
     /**
-     * UUID for virtualizer effect type.
+     * UUID for downmix effect type.
      */
-    const String EFFECT_TYPE_UUID_VIRTUALIZER = "37cc2c00-dddd-11db-8577-0002a5d5c51b";
-    /**
-     * UUID for Automatic Gain Control (AGC) type.
-     */
-    const String EFFECT_TYPE_UUID_AGC = "0a8abfe0-654c-11e0-ba26-0002a5d5c51b";
-    /**
-     * UUID for Acoustic Echo Canceler (AEC) type.
-     */
-    const String EFFECT_TYPE_UUID_AEC = "7b491460-8d4d-11e0-bd61-0002a5d5c51b";
-    /**
-     * UUID for Noise Suppressor (NS) type.
-     */
-    const String EFFECT_TYPE_UUID_NS = "58b4b260-8e06-11e0-aa8e-0002a5d5c51b";
-    /**
-     * UUID for Loudness Enhancer type.
-     */
-    const String EFFECT_TYPE_UUID_LOUDNESS_ENHANCER = "fe3199be-aed0-413f-87bb-11260eb63cf1";
+    const String EFFECT_TYPE_UUID_DOWNMIX = "381e49cc-a858-4aa2-87f6-e8388e7601b2";
     /**
      * UUID for Dynamics Processing type.
      */
     const String EFFECT_TYPE_UUID_DYNAMICS_PROCESSING = "7261676f-6d75-7369-6364-28e2fd3ac39e";
     /**
+     * UUID for environmental reverberation effect type.
+     */
+    const String EFFECT_TYPE_UUID_ENV_REVERB = "c2e5d5f0-94bd-4763-9cac-4e234d06839e";
+    /**
+     * UUID for equalizer effect type.
+     */
+    const String EFFECT_TYPE_UUID_EQUALIZER = "0bed4300-ddd6-11db-8f34-0002a5d5c51b";
+    /**
      * UUID for Haptic Generator type.
      */
     const String EFFECT_TYPE_UUID_HAPTIC_GENERATOR = "1411e6d6-aecd-4021-a1cf-a6aceb0d71e5";
     /**
+     * UUID for Loudness Enhancer type.
+     */
+    const String EFFECT_TYPE_UUID_LOUDNESS_ENHANCER = "fe3199be-aed0-413f-87bb-11260eb63cf1";
+    /**
+     * UUID for Noise Suppressor (NS) type.
+     */
+    const String EFFECT_TYPE_UUID_NS = "58b4b260-8e06-11e0-aa8e-0002a5d5c51b";
+    /**
+     * UUID for preset reverberation effect type.
+     */
+    const String EFFECT_TYPE_UUID_PRESET_REVERB = "47382d60-ddd8-11db-bf3a-0002a5d5c51b";
+    /**
      * UUID for Spatializer type.
      */
     const String EFFECT_TYPE_UUID_SPATIALIZER = "ccd4cf09-a79d-46c2-9aae-06a1698d6c8f";
     /**
-     * UUID for Volume type. The volume effect is used for automated tests only.
+     * UUID for virtualizer effect type.
      */
-    const String EFFECT_TYPE_UUID_VOLUME = "09e8ede0-ddde-11db-b4f6-0002a5d5c51b";
+    const String EFFECT_TYPE_UUID_VIRTUALIZER = "37cc2c00-dddd-11db-8577-0002a5d5c51b";
+    /**
+     * UUID for visualizer effect type.
+     */
+    const String EFFECT_TYPE_UUID_VISUALIZER = "d069d9e0-8329-11df-9168-0002a5d5c51b";
+    /**
+     * UUID for Volume effect type.
+     */
+    const String EFFECT_TYPE_UUID_VOLUME = "fa81a2b8-588b-11ed-9b6a-0242ac120002";
 
     /**
      * This structure completely identifies an effect implementation.
diff --git a/audio/aidl/android/hardware/audio/effect/Downmix.aidl b/audio/aidl/android/hardware/audio/effect/Downmix.aidl
index ee57baf..90fd4c7 100644
--- a/audio/aidl/android/hardware/audio/effect/Downmix.aidl
+++ b/audio/aidl/android/hardware/audio/effect/Downmix.aidl
@@ -21,8 +21,8 @@
 /**
  * Downmix specific definitions.
  *
- * All parameters defined in union Downmix must be gettable and settable. The capabilities defined
- * in Downmix.Capability can only acquired with IEffect.getDescriptor() and not settable.
+ * All parameter settings must be inside the range of Capability.Range.downmix definition if the
+ * definition for the corresponding parameter tag exist. See more detals about Range in Range.aidl.
  */
 @VintfStability
 union Downmix {
@@ -31,7 +31,7 @@
      */
     @VintfStability
     union Id {
-        int vendorExtensionTag;
+        VendorExtension vendorExtensionTag;
         Downmix.Tag commonTag;
     }
 
@@ -40,18 +40,6 @@
      */
     VendorExtension vendor;
 
-    /**
-     * Capability supported by Downmix implementation.
-     */
-    @VintfStability
-    parcelable Capability {
-        /**
-         * Downmix capability extension, vendor can use this extension in case existing capability
-         * definition not enough.
-         */
-        ParcelableHolder extension;
-    }
-
     @VintfStability
     enum Type {
         /**
diff --git a/audio/aidl/android/hardware/audio/effect/DynamicsProcessing.aidl b/audio/aidl/android/hardware/audio/effect/DynamicsProcessing.aidl
index 6db3338..5aea211 100644
--- a/audio/aidl/android/hardware/audio/effect/DynamicsProcessing.aidl
+++ b/audio/aidl/android/hardware/audio/effect/DynamicsProcessing.aidl
@@ -21,9 +21,9 @@
 /**
  * DynamicsProcessing specific definitions.
  *
- * All parameters defined in union DynamicsProcessing must be gettable and settable. The
- * capabilities defined in DynamicsProcessing.Capability can only acquired with
- * IEffect.getDescriptor() and not settable.
+ * All parameter settings must be inside the range of Capability.Range.dynamicsProcessing definition
+ * if the definition for the corresponding parameter tag exist. See more detals about Range in
+ * Range.aidl.
  */
 @VintfStability
 union DynamicsProcessing {
@@ -32,34 +32,14 @@
      */
     @VintfStability
     union Id {
-        int vendorExtensionTag;
+        VendorExtension vendorExtensionTag;
         DynamicsProcessing.Tag commonTag;
     }
 
     /**
      * Vendor DynamicsProcessing implementation definition for additional parameters.
      */
-    VendorExtension vendorExtension;
-
-    /**
-     * Capability supported by DynamicsProcessing implementation.
-     */
-    @VintfStability
-    parcelable Capability {
-        /**
-         * DynamicsProcessing capability extension, vendor can use this extension in case existing
-         * capability definition not enough.
-         */
-        ParcelableHolder extension;
-        /**
-         * Min Cut off frequency (in Hz) for all Bands.
-         */
-        float minCutOffFreq;
-        /**
-         * Max Cut off frequency (in Hz) for all Bands.
-         */
-        float maxCutOffFreq;
-    }
+    VendorExtension vendor;
 
     /**
      * Resolution preference definition.
@@ -159,8 +139,7 @@
          */
         boolean enable;
         /**
-         * Topmost frequency number (in Hz) this band will process. Must be in the range of
-         * [minCutOffFreq, maxCutOffFreq] defined in Capability.
+         * Topmost frequency number (in Hz) this band will process.
          */
         float cutoffFrequencyHz;
         /**
@@ -190,8 +169,7 @@
          */
         boolean enable;
         /**
-         * Topmost frequency number (in Hz) this band will process. Must be in the range of
-         * [minCutOffFreq, maxCutOffFreq] defined in Capability.
+         * Topmost frequency number (in Hz) this band will process.
          */
         float cutoffFrequencyHz;
         /**
diff --git a/audio/aidl/android/hardware/audio/effect/EnvironmentalReverb.aidl b/audio/aidl/android/hardware/audio/effect/EnvironmentalReverb.aidl
index fc98fe6..1d58e50 100644
--- a/audio/aidl/android/hardware/audio/effect/EnvironmentalReverb.aidl
+++ b/audio/aidl/android/hardware/audio/effect/EnvironmentalReverb.aidl
@@ -21,9 +21,9 @@
 /**
  * Environmental Reverb specific definitions.
  *
- * All parameters defined in union Environmental must be gettable and settable. The capabilities
- * * defined in EnvironmentalReverb.Capability can only acquired with IEffect.getDescriptor() and
- * not * settable.
+ * All parameter settings must be inside the range of Capability.Range.environmentalReverb
+ * definition if the definition for the corresponding parameter tag exist. See more detals about
+ * Range in Range.aidl.
  */
 
 @VintfStability
@@ -33,7 +33,7 @@
      */
     @VintfStability
     union Id {
-        int vendorExtensionTag;
+        VendorExtension vendorExtensionTag;
         EnvironmentalReverb.Tag commonTag;
     }
 
@@ -43,103 +43,43 @@
     VendorExtension vendor;
 
     /**
-     * Capability supported by effect implementation.
-     */
-    @VintfStability
-    parcelable Capability {
-        VendorExtension extension;
-
-        /**
-         * Minimal possible room level in millibels.
-         */
-        int minRoomLevelMb;
-        /**
-         * Maximum possible room level in millibels.
-         */
-        int maxRoomLevelMb;
-        /**
-         * Minimal possible room hf level in millibels.
-         */
-        int minRoomHfLevelMb;
-        /**
-         * Maximum possible room hf level in millibels.
-         */
-        int maxRoomHfLevelMb;
-        /**
-         * Max decay time supported in millisecond.
-         */
-        int maxDecayTimeMs;
-        /**
-         * Minimal possible per mille decay hf ratio.
-         */
-        int minDecayHfRatioPm;
-        /**
-         * Maximum possible per mille decay hf ratio.
-         */
-        int maxDecayHfRatioPm;
-        /**
-         * Minimal possible room level in millibels.
-         */
-        int minLevelMb;
-        /**
-         * Maximum possible room level in millibels.
-         */
-        int maxLevelMb;
-        /**
-         * Maximum possible delay time in milliseconds.
-         */
-        int maxDelayMs;
-        /**
-         * Maximum possible per mille diffusion.
-         */
-        int maxDiffusionPm;
-        /**
-         * Maximum possible per mille density.
-         */
-        int maxDensityPm;
-    }
-
-    /**
-     * Room level apply to the reverb effect in millibels. The value of the roomLevelMb must be in
-     * range of the value specified by the 'minRoomLevelMb' capability and the 'maxRoomLevelMb'
-     * capability.
+     * Room level apply to the reverb effect in millibels.
      */
     int roomLevelMb;
     /**
-     * Room HF level apply to the reverb effect in millibels. The value of the roomHfLevelMb must be
-     * in range of the value specified by the 'minRoomHfLevelMb' capability and the
-     * 'maxRoomHfLevelMb' capability.
+     * Room HF level apply to the reverb effect in millibels.
      */
     int roomHfLevelMb;
     /**
-     * Delay time apply to the reverb effect in milliseconds.The value of the decayTimeMs must
-     * be non-negative and not exceed the value specified by the 'maxDecayTimeMs' capability.
+     * Delay time apply to the reverb effect in milliseconds.
      */
     int decayTimeMs;
     /**
-     * HF decay ratio in permilles. The value of the decayHfRatioPm must be in range
-     * of the value specified by the 'minDecayHfRatioPm' capability and the 'maxDecayHfRatioPm'
-     * capability.
+     * HF decay ratio in permilles.
      */
     int decayHfRatioPm;
     /**
-     * Reverb level in millibels. The value of the levelMb must be in range
-     * of the value specified by the 'minLevelMb' capability and the 'maxLevelMb' capability.
+     * Reverb reflections level in millibels.
+     */
+    int reflectionsLevelMb;
+    /**
+     * Reverb reflections delay in milliseconds.
+     */
+    int reflectionsDelayMs;
+    /**
+     * Reverb level in millibels.
      */
     int levelMb;
     /**
-     * Reverb delay in milliseconds. The value of the delayMs must be non-negative and not
-     * exceed the value specified by the 'maxDelayMs' capability.
+     * Reverb delay in milliseconds.
      */
     int delayMs;
     /**
-     * Diffusion in permilles. The value of the diffusionPm must be non-negative and not
-     * exceed the value specified by the 'maxDiffusionPm' capability.
+     * Diffusion in permilles.
      */
     int diffusionPm;
     /**
-     * Density in permilles. The value of the densityPm must be non-negative and not
-     * exceed the value specified by the 'maxDensityPm' capability.
+     * Density in permilles.
      */
     int densityPm;
 
diff --git a/audio/aidl/android/hardware/audio/effect/Equalizer.aidl b/audio/aidl/android/hardware/audio/effect/Equalizer.aidl
index 79a1c4f..e727f70 100644
--- a/audio/aidl/android/hardware/audio/effect/Equalizer.aidl
+++ b/audio/aidl/android/hardware/audio/effect/Equalizer.aidl
@@ -21,8 +21,8 @@
 /**
  * Equalizer specific definitions.
  *
- * All parameters defined in union Equalizer must be gettable and settable. The capabilities defined
- * in Equalizer.Capability can only acquired with IEffect.getDescriptor() and not settable.
+ * All parameter settings must be inside the range of Capability.Range.equalizer definition if the
+ * definition for the corresponding parameter tag exist. See more detals about Range in Range.aidl.
  */
 @VintfStability
 union Equalizer {
@@ -31,36 +31,14 @@
      */
     @VintfStability
     union Id {
-        int vendorExtensionTag;
+        VendorExtension vendorExtensionTag;
         Equalizer.Tag commonTag;
     }
 
     /**
      * Vendor Equalizer implementation definition for additional parameters.
      */
-    VendorExtension vendorExtension;
-
-    /**
-     * Capability MUST be supported by Equalizer implementation.
-     */
-    @VintfStability
-    parcelable Capability {
-        /**
-         * Equalizer capability extension, vendor can use this extension in case existing capability
-         * definition not enough.
-         */
-        ParcelableHolder extension;
-
-        /**
-         * Bands frequency ranges supported.
-         */
-        BandFrequency[] bandFrequencies;
-
-        /**
-         * Presets name and index.
-         */
-        Preset[] presets;
-    }
+    VendorExtension vendor;
 
     /**
      * Level setting for each band in millibels.
@@ -72,7 +50,7 @@
     }
 
     /**
-     * Supported minimal and maximal frequency for each band in millihertz.
+     * Supported minimal and maximal frequency for each band in milliHertz.
      */
     @VintfStability
     parcelable BandFrequency {
@@ -97,8 +75,24 @@
      * Level for each band.
      */
     BandLevel[] bandLevels;
+
     /**
      * Index of current preset.
      */
     int preset;
+
+    /**
+     * Get only parameter, get the center frequency for all bands in milliHertz.
+     */
+    int[] centerFreqMh;
+
+    /**
+     * Get only parameter, indicating bands frequency ranges supported by implementation.
+     */
+    BandFrequency[] bandFrequencies;
+
+    /**
+     * Get only parameter, indicating presets name and index supported by implementation.
+     */
+    Preset[] presets;
 }
diff --git a/audio/aidl/android/hardware/audio/effect/Flags.aidl b/audio/aidl/android/hardware/audio/effect/Flags.aidl
index 1612234..28685c3 100644
--- a/audio/aidl/android/hardware/audio/effect/Flags.aidl
+++ b/audio/aidl/android/hardware/audio/effect/Flags.aidl
@@ -112,31 +112,31 @@
     HardwareAccelerator hwAcceleratorMode = HardwareAccelerator.NONE;
 
     /**
-     * Effect instance set this flag to true if it requires update on if the playback thread the
-     * effect attached to is offloaded or not. In this case the framework must call
+     * Effect instance sets this flag to true if it requires updates on whether the playback thread
+     * the effect is attached to is offloaded or not.  In this case the framework must call
      * IEffect.setParameter(Parameter.offload) to notify effect instance when playback thread
      * offload changes.
      */
     boolean offloadIndication;
 
     /**
-     * Effect instance set this flag to true if it requires device change update. In this case the
+     * Effect instance sets this flag to true if it requires device change update. In this case the
      * framework must call IEffect.setParameter(Parameter.device) to notify effect instance when the
      * device changes.
      */
     boolean deviceIndication;
 
     /**
-     * Effect instance set this flag to true if it requires audio mode change update. In this case
+     * Effect instance sets this flag to true if it requires audio mode change update. In this case
      * the framework must call IEffect.setParameter(Parameter.mode) to notify effect instance when
      * the audio mode changes.
      */
     boolean audioModeIndication;
 
     /**
-     * Effect instance set this flag to true if it requires audio source change update. In this case
-     * the framework must call IEffect.setParameter(Parameter.source) to notify effect instance when
-     * the audio source changes.
+     * Effect instance sets this flag to true if it requires audio source change update. In this
+     * case the framework must call IEffect.setParameter(Parameter.source) to notify effect instance
+     * when the audio source changes.
      */
     boolean audioSourceIndication;
 
diff --git a/audio/aidl/android/hardware/audio/effect/HapticGenerator.aidl b/audio/aidl/android/hardware/audio/effect/HapticGenerator.aidl
index 3063ee3..3cc5acb 100644
--- a/audio/aidl/android/hardware/audio/effect/HapticGenerator.aidl
+++ b/audio/aidl/android/hardware/audio/effect/HapticGenerator.aidl
@@ -22,9 +22,9 @@
  * HapticGenerator specific definitions. HapticGenerator effect provide HapticGenerator control and
  * mute/unmute functionality.
  *
- * All parameters defined in union HapticGenerator must be gettable and settable. The capabilities
- * defined in HapticGenerator.Capability can only acquired with IEffect.getDescriptor() and not
- * settable.
+ * All parameter settings must be inside the range of Capability.Range.hapticGenerator definition if
+ * the definition for the corresponding parameter tag exist. See more detals about Range in
+ * Range.aidl.
  */
 @VintfStability
 union HapticGenerator {
@@ -33,26 +33,14 @@
      */
     @VintfStability
     union Id {
-        int vendorExtensionTag;
+        VendorExtension vendorExtensionTag;
         HapticGenerator.Tag commonTag;
     }
 
     /**
      * Vendor HapticGenerator implementation definition for additional parameters.
      */
-    VendorExtension vendorExtension;
-
-    /**
-     * Capability supported by HapticGenerator implementation.
-     */
-    @VintfStability
-    parcelable Capability {
-        /**
-         * HapticGenerator capability extension, vendor can use this extension in case existing
-         * capability definition not enough.
-         */
-        VendorExtension extension;
-    }
+    VendorExtension vendor;
 
     @VintfStability
     @Backing(type="int")
diff --git a/audio/aidl/android/hardware/audio/effect/LoudnessEnhancer.aidl b/audio/aidl/android/hardware/audio/effect/LoudnessEnhancer.aidl
index 0441f10..23e1e5a 100644
--- a/audio/aidl/android/hardware/audio/effect/LoudnessEnhancer.aidl
+++ b/audio/aidl/android/hardware/audio/effect/LoudnessEnhancer.aidl
@@ -21,9 +21,9 @@
 /**
  * LoudnessEnhancer specific definitions.
  *
- * All parameters defined in union LoudnessEnhancer must be gettable and settable. The capabilities
- * defined in LoudnessEnhancer.Capability can only acquired with IEffect.getDescriptor() and not
- * settable.
+ * All parameter settings must be inside the range of Capability.Range.loudnessEnhancer definition
+ * if the definition for the corresponding parameter tag exist. See more detals about Range in
+ * Range.aidl.
  */
 @VintfStability
 union LoudnessEnhancer {
@@ -32,7 +32,7 @@
      */
     @VintfStability
     union Id {
-        int vendorExtensionTag;
+        VendorExtension vendorExtensionTag;
         LoudnessEnhancer.Tag commonTag;
     }
 
@@ -42,18 +42,6 @@
     VendorExtension vendor;
 
     /**
-     * Capability supported by LoudnessEnhancer implementation.
-     */
-    @VintfStability
-    parcelable Capability {
-        /**
-         * LoudnessEnhancer capability extension, vendor can use this extension in case existing
-         * capability definition not enough.
-         */
-        VendorExtension extension;
-    }
-
-    /**
      * The maximum gain in millibels (mB) applied to the signal to process, default value is 0 which
      * corresponds to no amplification.
      */
diff --git a/audio/aidl/android/hardware/audio/effect/NoiseSuppression.aidl b/audio/aidl/android/hardware/audio/effect/NoiseSuppression.aidl
index 9969a0b..c6bcc43 100644
--- a/audio/aidl/android/hardware/audio/effect/NoiseSuppression.aidl
+++ b/audio/aidl/android/hardware/audio/effect/NoiseSuppression.aidl
@@ -24,9 +24,9 @@
  * engine, AC system) or non-stationary (other peoples conversations, car horn) for more advanced
  * implementations.
  *
- * All parameters defined in union NoiseSuppression must be gettable and settable. The capabilities
- * defined in NoiseSuppression.Capability can only acquired with IEffect.getDescriptor() and not
- * settable.
+ * All parameter settings must be inside the range of Capability.Range.noiseSuppression definition
+ * if the definition for the corresponding parameter tag exist. See more detals about Range in
+ * Range.aidl.
  */
 @VintfStability
 union NoiseSuppression {
@@ -35,7 +35,7 @@
      */
     @VintfStability
     union Id {
-        int vendorExtensionTag;
+        VendorExtension vendorExtensionTag;
         NoiseSuppression.Tag commonTag;
     }
 
@@ -45,18 +45,6 @@
     VendorExtension vendor;
 
     /**
-     * Capability supported by NoiseSuppression implementation.
-     */
-    @VintfStability
-    parcelable Capability {
-        /**
-         * NoiseSuppression capability extension, vendor can use this extension in case existing
-         * capability definition not enough.
-         */
-        ParcelableHolder extension;
-    }
-
-    /**
      * Different level of Noise Suppression to set.
      * As an example, webrtc have NsConfig::SuppressionLevel::k6dB applied for LOW level noise
      * suppression, NsConfig::SuppressionLevel::k12dB for MEDIUM, and
@@ -68,4 +56,11 @@
      * The NS level.
      */
     Level level;
+
+    /**
+     * Noise suppression type.
+     */
+    @VintfStability @Backing(type="int") enum Type { SINGLE_CHANNEL, MULTI_CHANNEL }
+
+    Type type;
 }
diff --git a/audio/aidl/android/hardware/audio/effect/Parameter.aidl b/audio/aidl/android/hardware/audio/effect/Parameter.aidl
index 473dfb5..0954055 100644
--- a/audio/aidl/android/hardware/audio/effect/Parameter.aidl
+++ b/audio/aidl/android/hardware/audio/effect/Parameter.aidl
@@ -17,7 +17,8 @@
 package android.hardware.audio.effect;
 
 import android.hardware.audio.effect.AcousticEchoCanceler;
-import android.hardware.audio.effect.AutomaticGainControl;
+import android.hardware.audio.effect.AutomaticGainControlV1;
+import android.hardware.audio.effect.AutomaticGainControlV2;
 import android.hardware.audio.effect.BassBoost;
 import android.hardware.audio.effect.Downmix;
 import android.hardware.audio.effect.DynamicsProcessing;
@@ -44,6 +45,14 @@
  * 2. Parameters defined for a specific effect type.
  * 3. Extension parameters ParcelableHolder can be used for vendor effect definition.
  *
+ * All parameter settings must be inside the range of Capability.Range.$EffectType$ definition. If
+ * an effect implementation doesn't have limitation for a parameter, then don't define any effect
+ * range.
+ *
+ * All parameters are get-able, if any parameter doesn't support set, effect implementation should
+ * report the supported range for this parameter as range.min > range.max. If no support range is
+ * defined for a parameter, it means this parameter doesn't have any limitation.
+ *
  */
 @VintfStability
 union Parameter {
@@ -57,10 +66,10 @@
     @VintfStability
     union Id {
         /**
-         * Parameter tag defined for vendor effects. Use int here so there is flexibility for vendor
-         * to define different tag.
+         * Parameter tag defined for vendor effects. Use VendorExtension here so it's possible to
+         * pass customized information.
          */
-        int vendorEffectTag;
+        VendorExtension vendorEffectTag;
         /**
          * Parameter tag defined for nested parameters. Can be used to get any parameter defined in
          * nested Union structure.
@@ -75,7 +84,8 @@
          *
          */
         AcousticEchoCanceler.Id acousticEchoCancelerTag;
-        AutomaticGainControl.Id automaticGainControlTag;
+        AutomaticGainControlV1.Id automaticGainControlV1Tag;
+        AutomaticGainControlV2.Id automaticGainControlV2Tag;
         BassBoost.Id bassBoostTag;
         Downmix.Id downmixTag;
         DynamicsProcessing.Id dynamicsProcessingTag;
@@ -125,11 +135,13 @@
      * Effect must implement setParameter(deviceDescription) if Flags.deviceIndication set to true.
      */
     AudioDeviceDescription[] deviceDescription;
+
     /**
      * Used by audio framework to set the audio mode to effect engine.
      * Effect must implement setParameter(mode) if Flags.audioModeIndication set to true.
      */
     AudioMode mode;
+
     /**
      * Used by audio framework to set the audio source to effect engine.
      * Effect must implement setParameter(source) if Flags.audioSourceIndication set to true.
@@ -137,6 +149,12 @@
     AudioSource source;
 
     /**
+     * Used by audio framework to indicate whether the playback thread the effect is attached to is
+     * offloaded or not.
+     */
+    boolean offload;
+
+    /**
      * The volume gain for left and right channel, left and right equals to same value if it's mono.
      */
     @VintfStability
@@ -157,7 +175,8 @@
     union Specific {
         VendorExtension vendorEffect;
         AcousticEchoCanceler acousticEchoCanceler;
-        AutomaticGainControl automaticGainControl;
+        AutomaticGainControlV1 automaticGainControlV1;
+        AutomaticGainControlV2 automaticGainControlV2;
         BassBoost bassBoost;
         Downmix downmix;
         DynamicsProcessing dynamicsProcessing;
diff --git a/audio/aidl/android/hardware/audio/effect/PresetReverb.aidl b/audio/aidl/android/hardware/audio/effect/PresetReverb.aidl
index 6048eea..a36da2c 100644
--- a/audio/aidl/android/hardware/audio/effect/PresetReverb.aidl
+++ b/audio/aidl/android/hardware/audio/effect/PresetReverb.aidl
@@ -21,9 +21,9 @@
 /**
  * PresetReverb specific definitions.
  *
- * All parameters defined in union PresetReverb must be gettable and settable. The capabilities
- * defined in PresetReverb.Capability can only acquired with IEffect.getDescriptor() and not
- * settable.
+ * All parameter settings must be inside the range of Capability.Range.presetReverb definition if
+ * the definition for the corresponding parameter tag exist. See more detals about Range in
+ * Range.aidl.
  */
 @VintfStability
 union PresetReverb {
@@ -68,7 +68,7 @@
      */
     @VintfStability
     union Id {
-        int vendorExtensionTag;
+        VendorExtension vendorExtensionTag;
         PresetReverb.Tag commonTag;
     }
 
@@ -78,21 +78,24 @@
     VendorExtension vendor;
 
     /**
-     * Capability supported by effect implementation.
+     * The list of presets supported by implementation, effect implementation must declare the
+     * support of Presets with Capability.Range.presetReverb definition. For example, if an effect
+     * implementation supports all Presets in PresetReverb.Presets, then the capability will be:
+     *  const std::vector<PresetReverb::Presets> kSupportedPresets{
+     *          ndk::enum_range<PresetReverb::Presets>().begin(),
+     *          ndk::enum_range<PresetReverb::Presets>().end()};
+     *  const std::vector<Range::PresetReverbRange> kRanges = {
+     *          MAKE_RANGE(PresetReverb, supportedPresets, kSupportedPresets, kSupportedPresets)};
      */
-    @VintfStability
-    parcelable Capability {
-        VendorExtension extension;
-
-        /**
-         * List of presets supported.
-         */
-        Presets[] supportedPresets;
-    }
+    Presets[] supportedPresets;
 
     /**
      * Get current reverb preset when used in getParameter.
      * Enable a preset reverb when used in setParameter.
+     * With the current Range definition, there is no good way to define enum capability, so the
+     * Presets vector supportedPresets is used to defined the capability. Client must check the
+     * capability in PresetReverb.supportedPresets, and make sure to get the list of supported
+     * presets before setting.
      */
     Presets preset;
 }
diff --git a/audio/aidl/android/hardware/audio/effect/Range.aidl b/audio/aidl/android/hardware/audio/effect/Range.aidl
index c052502..567320a 100644
--- a/audio/aidl/android/hardware/audio/effect/Range.aidl
+++ b/audio/aidl/android/hardware/audio/effect/Range.aidl
@@ -16,50 +16,205 @@
 
 package android.hardware.audio.effect;
 
+import android.hardware.audio.effect.AcousticEchoCanceler;
+import android.hardware.audio.effect.AutomaticGainControlV1;
+import android.hardware.audio.effect.AutomaticGainControlV2;
+import android.hardware.audio.effect.BassBoost;
+import android.hardware.audio.effect.Downmix;
+import android.hardware.audio.effect.DynamicsProcessing;
+import android.hardware.audio.effect.EnvironmentalReverb;
+import android.hardware.audio.effect.Equalizer;
+import android.hardware.audio.effect.HapticGenerator;
+import android.hardware.audio.effect.LoudnessEnhancer;
+import android.hardware.audio.effect.NoiseSuppression;
+import android.hardware.audio.effect.PresetReverb;
+import android.hardware.audio.effect.VendorExtension;
+import android.hardware.audio.effect.Virtualizer;
+import android.hardware.audio.effect.Visualizer;
+import android.hardware.audio.effect.Volume;
+
 /**
- * Define the range (min and max) of a certain field, identified by tag.
- * Can be used by effect capabilities to define supported value ranges.
+ * Define the supported range of effect parameters.
+ * Effect implementation must report the supported range of parameter/capability if there is any
+ * limitation.
+ * Range of each effect type is defined with a vector, because each $EffectType$Range can only
+ * describe the range of one parameter. For example, Range::AcousticEchoCancelerRange can only
+ * describe one of vendor, echoDelayUs, and mobileMode.
+ *
+ * If an effect implementation needs to define the valid range for a certain parameter, it can
+ * write the minimum/maximum supported value to the corresponding effect range, and add the range
+ * to vector of this effect type.
+ * Say if an AcousticEchoCanceler implementation wants to define the supported range of echoDelayUs
+ * to [0, 500], then the Capability range should include an item in acousticEchoCanceler list:
+ * std::vector<Range::AcousticEchoCancelerRange> kRanges = {
+ *       MAKE_RANGE(AcousticEchoCanceler, echoDelayUs, 0, 500)};
+ *
+ * For a more complex example, if a DynamicsProcessing implementation wants to define the
+ * supported range of preEqBand channel to [0, 1], band index to [0, 5], and cutoffFrequencyHz to
+ * [220, 20000]:
+ * Range::DynamicsProcessingRange kRange = {
+ *   .min = DynamicsProcessing::make<DynamicsProcessing::preEqBand>(
+ *           {EqBandConfig({.channel = 0,
+ *                          .band = 0,
+ *                          .enable = false,
+ *                          .cutoffFrequencyHz = 220,
+ *                          .gainDb = std::numeric_limits<float>::min()})}),
+ *   .max = DynamicsProcessing::make<DynamicsProcessing::preEqBand>(
+ *           {EqBandConfig({.channel = 1,
+ *                          .band = 5,
+ *                          .enable = true,
+ *                          .cutoffFrequencyHz = 20000,
+ *                          .gainDb = std::numeric_limits<float>::max()})})};
+ *
+ * For get only parameters, the effect implementation must define an invalid range (min > max), to
+ * indicate no parameter from the effect client can be accepted for setting. The effect
+ * implementation must return EX_ILLEGAL_ARGUMENT if it receives any setParameter call for a get
+ * only parameter.
+ * As an example, the get-only parameter Virtualizer.speakerAngles can be defined with:
+ *   Range::VirtualizerRange kRanges = {
+ *       MAKE_RANGE(Virtualizer, speakerAngles,
+ *                  {Virtualizer::ChannelAngle({.channel = 1},
+ *                  {Virtualizer::ChannelAngle({.channel = 0})};
+ *
+ * For a capability definition (which is also get only), the effect implementation must define a
+ * range with min == max, to indicate this is a fixed capability which shouldn't set by client.
+ * As an example, the Equalizer presets capability can be defined with:
+ * std::vector<Equalizer::Preset> kPresets = {
+ *       {0, "Normal"},      {1, "Classical"}, {2, "Dance"}, {3, "Flat"}, {4, "Folk"},
+ *       {5, "Heavy Metal"}, {6, "Hip Hop"},   {7, "Jazz"},  {8, "Pop"},  {9, "Rock"}};
+ * Range::EqualizerRange kRanges =
+ *      MAKE_RANGE(Equalizer, presets, EqualizerSw::kPresets, EqualizerSw::kPresets);
+ *
+ * For enum capability, it's necessary to either list a range, or explicitly list out all enums in
+ * the Range definition, see PresetReverb.supportedPresets as example.
+ *
+ * The effect implementation must return EX_ILLEGAL_ARGUMENT if:
+ * 1. receive any setParameter call for get only parameter (min > max).
+ * 2. receive any setParameter call for capability parameter definition (min == max).
+ * 3. receive any setParameter call for parameters not in the range of [min, max].
+ *
  */
 @VintfStability
-parcelable Range {
+union Range {
+    @VintfStability
+    parcelable AcousticEchoCancelerRange {
+        AcousticEchoCanceler min;
+        AcousticEchoCanceler max;
+    }
+
+    @VintfStability
+    parcelable AutomaticGainControlV1Range {
+        AutomaticGainControlV1 min;
+        AutomaticGainControlV1 max;
+    }
+
+    @VintfStability
+    parcelable AutomaticGainControlV2Range {
+        AutomaticGainControlV2 min;
+        AutomaticGainControlV2 max;
+    }
+
+    @VintfStability
+    parcelable BassBoostRange {
+        BassBoost min;
+        BassBoost max;
+    }
+
+    @VintfStability
+    parcelable DownmixRange {
+        Downmix min;
+        Downmix max;
+    }
+
+    @VintfStability
+    parcelable DynamicsProcessingRange {
+        DynamicsProcessing min;
+        DynamicsProcessing max;
+    }
+
+    @VintfStability
+    parcelable EnvironmentalReverbRange {
+        EnvironmentalReverb min;
+        EnvironmentalReverb max;
+    }
+
+    @VintfStability
+    parcelable EqualizerRange {
+        Equalizer min;
+        Equalizer max;
+    }
+
+    @VintfStability
+    parcelable HapticGeneratorRange {
+        HapticGenerator min;
+        HapticGenerator max;
+    }
+
+    @VintfStability
+    parcelable LoudnessEnhancerRange {
+        LoudnessEnhancer min;
+        LoudnessEnhancer max;
+    }
+
+    @VintfStability
+    parcelable NoiseSuppressionRange {
+        NoiseSuppression min;
+        NoiseSuppression max;
+    }
+
+    @VintfStability
+    parcelable PresetReverbRange {
+        PresetReverb min;
+        PresetReverb max;
+    }
+
+    @VintfStability
+    parcelable VendorExtensionRange {
+        VendorExtension min;
+        VendorExtension max;
+    }
+
+    @VintfStability
+    parcelable VirtualizerRange {
+        Virtualizer min;
+        Virtualizer max;
+    }
+
+    @VintfStability
+    parcelable VisualizerRange {
+        Visualizer min;
+        Visualizer max;
+    }
+
+    @VintfStability
+    parcelable VolumeRange {
+        Volume min;
+        Volume max;
+    }
+
     /**
-     * The union tag name which the range is defined for.
-     * For example: if used in AutomaticGainControlV1.Capability, value of Range.tag could be
-     * targetLevelDbFs or compressionGainDb.
+     * The vector of range defined for parameters of each effect implementation.
+     * Each element of the vector represents the min and max range of a parameter, so the size of
+     * vector is the number of parameter ranges defined for this effect implementation.
+     *
+     * The effect implementation must not have duplicated parameter range definition in the vector.
+     * Client side must go though the vector and make sure the parameter setting to effect
+     * implementation is in valid range.
      */
-    int tag;
-
-    @VintfStability
-    parcelable Int {
-        int min;
-        int max;
-    }
-
-    @VintfStability
-    parcelable Float {
-        float min;
-        float max;
-    }
-
-    @VintfStability
-    parcelable Long {
-        long min;
-        long max;
-    }
-
-    @VintfStability
-    parcelable Byte {
-        byte min;
-        byte max;
-    }
-
-    @VintfStability
-    union Types {
-        Int rangeInt;
-        Float rangeFloat;
-        Long rangeLong;
-        Byte rangeByte;
-    }
-
-    Types types;
+    VendorExtensionRange[] vendorExtension = {};
+    AcousticEchoCancelerRange[] acousticEchoCanceler;
+    AutomaticGainControlV1Range[] automaticGainControlV1;
+    AutomaticGainControlV2Range[] automaticGainControlV2;
+    BassBoostRange[] bassBoost;
+    DownmixRange[] downmix;
+    DynamicsProcessingRange[] dynamicsProcessing;
+    EnvironmentalReverbRange[] environmentalReverb;
+    EqualizerRange[] equalizer;
+    HapticGeneratorRange[] hapticGenerator;
+    LoudnessEnhancerRange[] loudnessEnhancer;
+    NoiseSuppressionRange[] noiseSuppression;
+    PresetReverbRange[] presetReverb;
+    VirtualizerRange[] virtualizer;
+    VisualizerRange[] visualizer;
+    VolumeRange[] volume;
 }
diff --git a/audio/aidl/android/hardware/audio/effect/Virtualizer.aidl b/audio/aidl/android/hardware/audio/effect/Virtualizer.aidl
index 5f385a6..1dbb509 100644
--- a/audio/aidl/android/hardware/audio/effect/Virtualizer.aidl
+++ b/audio/aidl/android/hardware/audio/effect/Virtualizer.aidl
@@ -17,14 +17,15 @@
 package android.hardware.audio.effect;
 
 import android.hardware.audio.effect.VendorExtension;
+import android.media.audio.common.AudioChannelLayout;
+import android.media.audio.common.AudioDeviceDescription;
 
 /**
  * Virtualizer specific definitions. An audio virtualizer is a general name for an effect to
  * spatialize audio channels.
  *
- * All parameters defined in union Virtualizer must be gettable and settable. The capabilities
- * defined in Virtualizer.Capability can only acquired with IEffect.getDescriptor() and not
- * settable.
+ * All parameter settings must be inside the range of Capability.Range.virtualizer definition if the
+ * definition for the corresponding parameter tag exist. See more detals about Range in Range.aidl.
  */
 @VintfStability
 union Virtualizer {
@@ -33,8 +34,9 @@
      */
     @VintfStability
     union Id {
-        int vendorExtensionTag;
+        VendorExtension vendorExtensionTag;
         Virtualizer.Tag commonTag;
+        SpeakerAnglesPayload speakerAnglesPayload;
     }
 
     /**
@@ -43,24 +45,22 @@
     VendorExtension vendor;
 
     /**
-     * Capability supported by Virtualizer implementation.
+     * Payload to query speaker angles for the given channel position mask and device.
+     * The Virtualizer implementation must return EX_ILLEGAL_ARGUMENT if the given payload not
+     * supported.
      */
     @VintfStability
-    parcelable Capability {
+    parcelable SpeakerAnglesPayload {
         /**
-         * Virtualizer capability extension, vendor can use this extension in case existing
-         * capability definition not enough.
+         * Audio channel position definition. See
+         * android.media.audio.common.AudioChannelLayout.aidl. Only the channel position "CHANNEL_*"
+         * in AudioChannelLayout be used.
          */
-        VendorExtension extension;
+        AudioChannelLayout layout;
         /**
-         * Maximum possible per mille strength.
+         * Audio device type. See android.media.audio.common.AudioDeviceDescription.aidl.
          */
-        int maxStrengthPm;
-        /**
-         * Indicates whether setting strength is supported. False value indicates only one strength
-         * is supported and setParameter() method will always return EX_ILLEGAL_ARGUMENT.
-         */
-        boolean strengthSupported;
+        AudioDeviceDescription device;
     }
 
     /**
@@ -70,8 +70,42 @@
      * allowed to round the given strength to the nearest supported value. In this case {@link
      * #IEffect.getParameter()} method should return the rounded value that was actually set.
      *
-     * The value of the strength must be non-negative and not exceed the value specified by
-     * the 'maxStrengthPm' capability.
      */
     int strengthPm;
+
+    /**
+     * All angles are expressed in degrees and are relative to the listener.
+     */
+    @VintfStability
+    parcelable ChannelAngle {
+        /**
+         * Audio channel layout, CHANNEL_* constants defined in
+         * android.media.audio.common.AudioChannelLayout.
+         */
+        int channel;
+
+        /**
+         * 0 is the direction the listener faces, 180 is behind the listener, and -90 is left of
+         * the listener.
+         */
+        int azimuthDegree;
+
+        /**
+         * 0 is the horizontal plane, +90 is above the listener, -90 is below.
+         */
+        int elevationDegree;
+    }
+
+    /**
+     * Get only parameter.
+     * A vector of angles per channel represented by azimuth and elevation (in degrees), client must
+     * set Parameter.Id to SpeakerAnglesPayload to get speakerAngles.
+     */
+    ChannelAngle[] speakerAngles;
+
+    /**
+     * Get only parameter.
+     * The audio device on which virtualzation mode is forced.
+     */
+    AudioDeviceDescription device;
 }
diff --git a/audio/aidl/android/hardware/audio/effect/Visualizer.aidl b/audio/aidl/android/hardware/audio/effect/Visualizer.aidl
index dfe29c8..0b37546 100644
--- a/audio/aidl/android/hardware/audio/effect/Visualizer.aidl
+++ b/audio/aidl/android/hardware/audio/effect/Visualizer.aidl
@@ -22,9 +22,8 @@
  * Visualizer specific definitions. Visualizer enables application to retrieve part of the currently
  * playing audio for visualization purpose
  *
- * All parameters defined in union Visualizer other than these in GetOnlyParameters and
- * SetOnlyParameters must be gettable and settable. The capabilities defined in
- * Visualizer.Capability can only acquired with IEffect.getDescriptor() and not settable.
+ * All parameter settings must be inside the range of Capability.Range.visualizer definition if the
+ * definition for the corresponding parameter tag exist. See more detals about Range in Range.aidl.
  *
  */
 @VintfStability
@@ -34,9 +33,7 @@
      */
     @VintfStability
     union Id {
-        int vendorExtensionTag;
-        GetOnlyParameters.Tag getOnlyParamTag;
-        SetOnlyParameters.Tag setOnlyParamTag;
+        VendorExtension vendorExtensionTag;
         Visualizer.Tag commonTag;
     }
     Id id;
@@ -47,35 +44,6 @@
     VendorExtension vendor;
 
     /**
-     * Capability supported by Visualizer implementation.
-     */
-    @VintfStability
-    parcelable Capability {
-        /**
-         * Visualizer capability extension, vendor can use this extension in case existing
-         * capability definition not enough.
-         */
-        VendorExtension extension;
-        /**
-         * Max latency supported in millseconds.
-         */
-        int maxLatencyMs;
-        /**
-         *  Capture size range.
-         */
-        CaptureSamplesRange captureSampleRange;
-    }
-
-    /**
-     * Supported capture size range in samples.
-     */
-    @VintfStability
-    parcelable CaptureSamplesRange {
-        int min;
-        int max;
-    }
-
-    /**
      * Type of scaling applied on the captured visualization data.
      */
     @VintfStability
@@ -115,51 +83,42 @@
     }
 
     /**
-     * Any parameter defined in this union must be gettable via getParameter(), but must not
-     * settable.
+     * Get only parameter to get the current measurements.
      */
     @VintfStability
-    union GetOnlyParameters {
-        /**
-         * Get the current measurements.
-         */
-        @VintfStability
-        parcelable Measurement {
-            int rms;
-            int peak;
-        }
-        Measurement measurement;
-
-        /**
-         * Get the latest captureSamples of PCM samples (8 bits per sample).
-         */
-        byte[] captureSampleBuffer;
+    parcelable Measurement {
+        int rms;
+        int peak;
     }
-    GetOnlyParameters getOnlyParameters;
+    Measurement measurement;
 
     /**
-     * Any parameter defined in this union must be settable via setParameter(), but must not
-     * gettable.
+     * Get only parameter to get the latest captured samples of PCM samples (8 bits per sample).
      */
-    @VintfStability
-    union SetOnlyParameters {
-        /**
-         * Used by framework to inform the visualizer about the downstream latency (audio hardware
-         * driver estimated latency in milliseconds).
-         */
-        int latencyMs;
-    }
-    SetOnlyParameters setOnlyParameters;
+    byte[] captureSampleBuffer;
 
     /**
-     * Current capture size in number of samples. The capture size must be inside
-     * Capability.captureSizeRange.
+     * Used by framework to inform the visualizer about the downstream latency (audio hardware
+     * driver estimated latency in milliseconds).
+     *
+     * Visualizer implementation must use Range.VisualizerRange to define the range of supported
+     * latency.
+     */
+    int latencyMs;
+
+    /**
+     * Current capture size in number of samples.
+     *
+     * Visualizer implementation must use Range.VisualizerRange to define the range of supported
+     * capture size.
      */
     int captureSamples;
+
     /**
      * Visualizer capture mode
      */
     ScalingMode scalingMode;
+
     /**
      * Visualizer measurement mode.
      */
diff --git a/audio/aidl/android/hardware/audio/effect/Volume.aidl b/audio/aidl/android/hardware/audio/effect/Volume.aidl
index 5033881..15cfdd2 100644
--- a/audio/aidl/android/hardware/audio/effect/Volume.aidl
+++ b/audio/aidl/android/hardware/audio/effect/Volume.aidl
@@ -21,8 +21,8 @@
 /**
  * Volume specific definitions. Volume effect provide volume control and mute/unmute functionality.
  *
- * All parameters defined in union Volume must be gettable and settable. The capabilities defined in
- * Volume.Capability can only acquired with IEffect.getDescriptor() and not settable.
+ * All parameter settings must be inside the range of Capability.Range.volume definition if the
+ * definition for the corresponding parameter tag exist. See more detals about Range in Range.aidl.
  */
 @VintfStability
 union Volume {
@@ -31,7 +31,7 @@
      */
     @VintfStability
     union Id {
-        int vendorExtensionTag;
+        VendorExtension vendorExtensionTag;
         Volume.Tag commonTag;
     }
 
@@ -41,29 +41,7 @@
     VendorExtension vendor;
 
     /**
-     * Capability supported by Volume implementation.
-     */
-    @VintfStability
-    parcelable Capability {
-        /**
-         * Volume capability extension, vendor can use this extension in case existing capability
-         * definition not enough.
-         */
-        VendorExtension extension;
-
-        /**
-         * Minimum Volume level supported in dB.
-         */
-        int minLevelDb;
-
-        /**
-         * Maximum Volume level supported in dB.
-         */
-        int maxLevelDb;
-    }
-
-    /**
-     * Current level in dB with supported minimum and maximum level specified in capability.
+     * Current level in dB.
      */
     int levelDb;
     /**
diff --git a/audio/aidl/common/Android.bp b/audio/aidl/common/Android.bp
index a3f7f0b..4c6a74e 100644
--- a/audio/aidl/common/Android.bp
+++ b/audio/aidl/common/Android.bp
@@ -41,6 +41,20 @@
     ],
 }
 
+cc_library {
+    name: "libaudioaidlranges",
+    host_supported: true,
+    vendor_available: true,
+    static_libs: [
+        "android.hardware.audio.effect-V1-ndk",
+    ],
+    export_include_dirs: ["include"],
+    header_libs: ["libaudioaidl_headers"],
+    srcs: [
+        "EffectRangeSpecific.cpp",
+    ],
+}
+
 cc_test {
     name: "libaudioaidlcommon_test",
     host_supported: true,
diff --git a/audio/aidl/common/EffectRangeSpecific.cpp b/audio/aidl/common/EffectRangeSpecific.cpp
new file mode 100644
index 0000000..bd78ea0
--- /dev/null
+++ b/audio/aidl/common/EffectRangeSpecific.cpp
@@ -0,0 +1,161 @@
+/*

+ * 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 <aidl/android/hardware/audio/effect/DynamicsProcessing.h>

+#include <aidl/android/hardware/audio/effect/Range.h>

+

+#include "EffectRangeSpecific.h"

+#include "effect-impl/EffectRange.h"

+

+namespace aidl::android::hardware::audio::effect {

+

+namespace DynamicsProcessingRanges {

+

+static bool isInputGainConfigInRange(const std::vector<DynamicsProcessing::InputGain>& cfgs,

+                                     const DynamicsProcessing::InputGain& min,

+                                     const DynamicsProcessing::InputGain& max) {

+    auto func = [](const DynamicsProcessing::InputGain& arg) {

+        return std::make_tuple(arg.channel, arg.gainDb);

+    };

+    return isTupleInRange(cfgs, min, max, func);

+}

+

+static bool isLimiterConfigInRange(const std::vector<DynamicsProcessing::LimiterConfig>& cfgs,

+                                   const DynamicsProcessing::LimiterConfig& min,

+                                   const DynamicsProcessing::LimiterConfig& max) {

+    auto func = [](const DynamicsProcessing::LimiterConfig& arg) {

+        return std::make_tuple(arg.channel, arg.enable, arg.linkGroup, arg.attackTimeMs,

+                               arg.releaseTimeMs, arg.ratio, arg.thresholdDb, arg.postGainDb);

+    };

+    return isTupleInRange(cfgs, min, max, func);

+}

+

+static bool isMbcBandConfigInRange(const std::vector<DynamicsProcessing::MbcBandConfig>& cfgs,

+                                   const DynamicsProcessing::MbcBandConfig& min,

+                                   const DynamicsProcessing::MbcBandConfig& max) {

+    auto func = [](const DynamicsProcessing::MbcBandConfig& arg) {

+        return std::make_tuple(arg.channel, arg.band, arg.enable, arg.cutoffFrequencyHz,

+                               arg.attackTimeMs, arg.releaseTimeMs, arg.ratio, arg.thresholdDb,

+                               arg.kneeWidthDb, arg.noiseGateThresholdDb, arg.expanderRatio,

+                               arg.preGainDb, arg.postGainDb);

+    };

+    return isTupleInRange(cfgs, min, max, func);

+}

+

+static bool isEqBandConfigInRange(const std::vector<DynamicsProcessing::EqBandConfig>& cfgs,

+                                  const DynamicsProcessing::EqBandConfig& min,

+                                  const DynamicsProcessing::EqBandConfig& max) {

+    auto func = [](const DynamicsProcessing::EqBandConfig& arg) {

+        return std::make_tuple(arg.channel, arg.band, arg.enable, arg.cutoffFrequencyHz,

+                               arg.gainDb);

+    };

+    return isTupleInRange(cfgs, min, max, func);

+}

+

+static bool isChannelConfigInRange(const std::vector<DynamicsProcessing::ChannelConfig>& cfgs,

+                                   const DynamicsProcessing::ChannelConfig& min,

+                                   const DynamicsProcessing::ChannelConfig& max) {

+    auto func = [](const DynamicsProcessing::ChannelConfig& arg) {

+        return std::make_tuple(arg.channel, arg.enable);

+    };

+    return isTupleInRange(cfgs, min, max, func);

+}

+

+static bool isEngineConfigInRange(const DynamicsProcessing::EngineArchitecture& cfg,

+                                  const DynamicsProcessing::EngineArchitecture& min,

+                                  const DynamicsProcessing::EngineArchitecture& max) {

+    auto func = [](const DynamicsProcessing::EngineArchitecture& arg) {

+        return std::make_tuple(arg.resolutionPreference, arg.preferredProcessingDurationMs,

+                               arg.preEqStage.inUse, arg.preEqStage.bandCount,

+                               arg.postEqStage.inUse, arg.postEqStage.bandCount, arg.mbcStage.inUse,

+                               arg.mbcStage.bandCount, arg.limiterInUse);

+    };

+    return isTupleInRange(func(cfg), func(min), func(max));

+}

+

+static int locateMinMaxForTag(DynamicsProcessing::Tag tag,

+                              const std::vector<Range::DynamicsProcessingRange>& ranges) {

+    for (int i = 0; i < (int)ranges.size(); i++) {

+        if (tag == ranges[i].min.getTag() && tag == ranges[i].max.getTag()) {

+            return i;

+        }

+    }

+    return -1;

+}

+

+bool isParamInRange(const DynamicsProcessing& dp,

+                    const std::vector<Range::DynamicsProcessingRange>& ranges) {

+    auto tag = dp.getTag();

+    int i = locateMinMaxForTag(tag, ranges);

+    if (i == -1) return true;

+

+    switch (tag) {

+        case DynamicsProcessing::engineArchitecture: {

+            return isEngineConfigInRange(

+                    dp.get<DynamicsProcessing::engineArchitecture>(),

+                    ranges[i].min.get<DynamicsProcessing::engineArchitecture>(),

+                    ranges[i].max.get<DynamicsProcessing::engineArchitecture>());

+        }

+        case DynamicsProcessing::preEq: {

+            return isChannelConfigInRange(dp.get<DynamicsProcessing::preEq>(),

+                                          ranges[i].min.get<DynamicsProcessing::preEq>()[0],

+                                          ranges[i].max.get<DynamicsProcessing::preEq>()[0]);

+        }

+        case DynamicsProcessing::postEq: {

+            return isChannelConfigInRange(dp.get<DynamicsProcessing::postEq>(),

+                                          ranges[i].min.get<DynamicsProcessing::postEq>()[0],

+                                          ranges[i].max.get<DynamicsProcessing::postEq>()[0]);

+        }

+        case DynamicsProcessing::mbc: {

+            return isChannelConfigInRange(dp.get<DynamicsProcessing::mbc>(),

+                                          ranges[i].min.get<DynamicsProcessing::mbc>()[0],

+                                          ranges[i].max.get<DynamicsProcessing::mbc>()[0]);

+        }

+        case DynamicsProcessing::preEqBand: {

+            return isEqBandConfigInRange(dp.get<DynamicsProcessing::preEqBand>(),

+                                         ranges[i].min.get<DynamicsProcessing::preEqBand>()[0],

+                                         ranges[i].max.get<DynamicsProcessing::preEqBand>()[0]);

+        }

+        case DynamicsProcessing::postEqBand: {

+            return isEqBandConfigInRange(dp.get<DynamicsProcessing::postEqBand>(),

+                                         ranges[i].min.get<DynamicsProcessing::postEqBand>()[0],

+                                         ranges[i].max.get<DynamicsProcessing::postEqBand>()[0]);

+        }

+        case DynamicsProcessing::mbcBand: {

+            return isMbcBandConfigInRange(dp.get<DynamicsProcessing::mbcBand>(),

+                                          ranges[i].min.get<DynamicsProcessing::mbcBand>()[0],

+                                          ranges[i].max.get<DynamicsProcessing::mbcBand>()[0]);

+        }

+        case DynamicsProcessing::limiter: {

+            return isLimiterConfigInRange(dp.get<DynamicsProcessing::limiter>(),

+                                          ranges[i].min.get<DynamicsProcessing::limiter>()[0],

+                                          ranges[i].max.get<DynamicsProcessing::limiter>()[0]);

+        }

+        case DynamicsProcessing::inputGain: {

+            return isInputGainConfigInRange(dp.get<DynamicsProcessing::inputGain>(),

+                                            ranges[i].min.get<DynamicsProcessing::inputGain>()[0],

+                                            ranges[i].max.get<DynamicsProcessing::inputGain>()[0]);

+        }

+        default: {

+            return true;

+        }

+    }

+    return true;

+}

+

+}  // namespace DynamicsProcessingRanges

+

+}  // namespace aidl::android::hardware::audio::effect
\ No newline at end of file
diff --git a/audio/aidl/common/include/EffectRangeSpecific.h b/audio/aidl/common/include/EffectRangeSpecific.h
new file mode 100644
index 0000000..c7262bb
--- /dev/null
+++ b/audio/aidl/common/include/EffectRangeSpecific.h
@@ -0,0 +1,28 @@
+/*

+ * 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

+

+namespace aidl::android::hardware::audio::effect {

+

+namespace DynamicsProcessingRanges {

+

+bool isParamInRange(const DynamicsProcessing& dp,

+                    const std::vector<Range::DynamicsProcessingRange>& ranges);

+

+}  // namespace DynamicsProcessingRanges

+

+}  // namespace aidl::android::hardware::audio::effect
\ No newline at end of file
diff --git a/audio/aidl/common/include/Utils.h b/audio/aidl/common/include/Utils.h
index d87bbd4..305c924 100644
--- a/audio/aidl/common/include/Utils.h
+++ b/audio/aidl/common/include/Utils.h
@@ -19,6 +19,7 @@
 #include <algorithm>
 #include <array>
 #include <initializer_list>
+#include <regex>
 #include <type_traits>
 
 #include <aidl/android/media/audio/common/AudioChannelLayout.h>
@@ -29,7 +30,7 @@
 #include <aidl/android/media/audio/common/AudioOutputFlags.h>
 #include <aidl/android/media/audio/common/PcmType.h>
 
-namespace android::hardware::audio::common {
+namespace aidl::android::hardware::audio::common {
 
 // Some values are reserved for use by the system code only.
 // HALs must not accept or emit values outside from the provided list.
@@ -98,6 +99,12 @@
     return 0;
 }
 
+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;
+}
+
 constexpr bool isTelephonyDeviceType(
         ::aidl::android::media::audio::common::AudioDeviceType device) {
     return device == ::aidl::android::media::audio::common::AudioDeviceType::IN_TELEPHONY_RX ||
@@ -133,6 +140,18 @@
            kValidAudioModes.end();
 }
 
+static inline bool maybeVendorExtension(const std::string& s) {
+    // Only checks whether the string starts with the "vendor prefix".
+    static const std::string vendorPrefix = "VX_";
+    return s.size() > vendorPrefix.size() && s.substr(0, vendorPrefix.size()) == vendorPrefix;
+}
+
+static inline bool isVendorExtension(const std::string& s) {
+    // Must be the same as defined in {Playback|Record}TrackMetadata.aidl
+    static const std::regex vendorExtension("VX_[A-Z0-9]{3,}_[_A-Z0-9]+");
+    return std::regex_match(s.begin(), s.end(), vendorExtension);
+}
+
 // The helper functions defined below are only applicable to the case when an enum type
 // specifies zero-based bit positions, not bit masks themselves. This is why instantiation
 // is restricted to certain enum types.
@@ -163,4 +182,4 @@
     return result;
 }
 
-}  // namespace android::hardware::audio::common
+}  // namespace aidl::android::hardware::audio::common
diff --git a/audio/aidl/common/tests/utils_tests.cpp b/audio/aidl/common/tests/utils_tests.cpp
index d7f1a5d..1b8b8df 100644
--- a/audio/aidl/common/tests/utils_tests.cpp
+++ b/audio/aidl/common/tests/utils_tests.cpp
@@ -26,13 +26,13 @@
 #define LOG_TAG "Utils_Test"
 #include <log/log.h>
 
+using aidl::android::hardware::audio::common::getChannelCount;
+using aidl::android::hardware::audio::common::getFrameSizeInBytes;
+using aidl::android::hardware::audio::common::getPcmSampleSizeInBytes;
 using aidl::android::media::audio::common::AudioChannelLayout;
 using aidl::android::media::audio::common::AudioFormatDescription;
 using aidl::android::media::audio::common::AudioFormatType;
 using aidl::android::media::audio::common::PcmType;
-using android::hardware::audio::common::getChannelCount;
-using android::hardware::audio::common::getFrameSizeInBytes;
-using android::hardware::audio::common::getPcmSampleSizeInBytes;
 
 TEST(UtilsTest, ChannelCountOddCases) {
     using Tag = AudioChannelLayout::Tag;
diff --git a/audio/aidl/default/Android.bp b/audio/aidl/default/Android.bp
index 21616be..c9edae0 100644
--- a/audio/aidl/default/Android.bp
+++ b/audio/aidl/default/Android.bp
@@ -13,6 +13,7 @@
     shared_libs: [
         "libalsautilsv2",
         "libaudioaidlcommon",
+        "libaudioutils",
         "libbase",
         "libbinder_ndk",
         "libcutils",
@@ -54,12 +55,13 @@
     ],
 }
 
-cc_library_static {
+cc_library {
     name: "libaudioserviceexampleimpl",
     defaults: [
         "aidlaudioservice_defaults",
         "latest_android_media_audio_common_types_ndk_shared",
         "latest_android_hardware_audio_core_ndk_shared",
+        "latest_android_hardware_audio_core_sounddose_ndk_shared",
     ],
     export_include_dirs: ["include"],
     srcs: [
@@ -75,6 +77,7 @@
         "Telephony.cpp",
         "usb/ModuleUsb.cpp",
         "usb/StreamUsb.cpp",
+        "usb/UsbAlsaMixerControl.cpp",
         "usb/UsbAlsaUtils.cpp",
     ],
     generated_sources: [
@@ -89,9 +92,6 @@
         "audio_policy_configuration_aidl_default",
         "audio_policy_engine_configuration_aidl_default",
     ],
-    visibility: [
-        ":__subpackages__",
-    ],
 }
 
 cc_binary {
diff --git a/audio/aidl/default/Bluetooth.cpp b/audio/aidl/default/Bluetooth.cpp
index 38e0c21..c32b538 100644
--- a/audio/aidl/default/Bluetooth.cpp
+++ b/audio/aidl/default/Bluetooth.cpp
@@ -19,6 +19,7 @@
 
 #include "core-impl/Bluetooth.h"
 
+using aidl::android::hardware::audio::core::VendorParameter;
 using aidl::android::media::audio::common::Boolean;
 using aidl::android::media::audio::common::Float;
 using aidl::android::media::audio::common::Int;
@@ -79,4 +80,54 @@
     return ndk::ScopedAStatus::ok();
 }
 
+ndk::ScopedAStatus BluetoothA2dp::isEnabled(bool* _aidl_return) {
+    *_aidl_return = mEnabled;
+    LOG(DEBUG) << __func__ << ": returning " << *_aidl_return;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus BluetoothA2dp::setEnabled(bool in_enabled) {
+    mEnabled = in_enabled;
+    LOG(DEBUG) << __func__ << ": " << mEnabled;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus BluetoothA2dp::supportsOffloadReconfiguration(bool* _aidl_return) {
+    *_aidl_return = true;
+    LOG(DEBUG) << __func__ << ": returning " << *_aidl_return;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus BluetoothA2dp::reconfigureOffload(
+        const std::vector<::aidl::android::hardware::audio::core::VendorParameter>& in_parameters
+                __unused) {
+    LOG(DEBUG) << __func__ << ": " << ::android::internal::ToString(in_parameters);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus BluetoothLe::isEnabled(bool* _aidl_return) {
+    *_aidl_return = mEnabled;
+    LOG(DEBUG) << __func__ << ": returning " << *_aidl_return;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus BluetoothLe::setEnabled(bool in_enabled) {
+    mEnabled = in_enabled;
+    LOG(DEBUG) << __func__ << ": " << mEnabled;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus BluetoothLe::supportsOffloadReconfiguration(bool* _aidl_return) {
+    *_aidl_return = true;
+    LOG(DEBUG) << __func__ << ": returning " << *_aidl_return;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus BluetoothLe::reconfigureOffload(
+        const std::vector<::aidl::android::hardware::audio::core::VendorParameter>& in_parameters
+                __unused) {
+    LOG(DEBUG) << __func__ << ": " << ::android::internal::ToString(in_parameters);
+    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 854c7f3..e1e1f79 100644
--- a/audio/aidl/default/Configuration.cpp
+++ b/audio/aidl/default/Configuration.cpp
@@ -25,6 +25,7 @@
 
 #include "core-impl/Configuration.h"
 
+using aidl::android::hardware::audio::common::makeBitPositionFlagMask;
 using aidl::android::media::audio::common::AudioChannelLayout;
 using aidl::android::media::audio::common::AudioDeviceDescription;
 using aidl::android::media::audio::common::AudioDeviceType;
@@ -40,8 +41,8 @@
 using aidl::android::media::audio::common::AudioPortMixExt;
 using aidl::android::media::audio::common::AudioProfile;
 using aidl::android::media::audio::common::Int;
+using aidl::android::media::audio::common::MicrophoneInfo;
 using aidl::android::media::audio::common::PcmType;
-using android::hardware::audio::common::makeBitPositionFlagMask;
 
 namespace aidl::android::hardware::audio::core::internal {
 
diff --git a/audio/aidl/default/EffectConfig.cpp b/audio/aidl/default/EffectConfig.cpp
index c030b7a..5a83fef 100644
--- a/audio/aidl/default/EffectConfig.cpp
+++ b/audio/aidl/default/EffectConfig.cpp
@@ -16,6 +16,7 @@
 
 #define LOG_TAG "AHAL_EffectConfig"
 #include <android-base/logging.h>
+#include <system/audio_effects/effect_uuid.h>
 
 #include "effectFactory-impl/EffectConfig.h"
 
@@ -163,15 +164,53 @@
         libraryUuid.name = name;
     }
 
-    const char* uuid = xml.Attribute("uuid");
-    RETURN_VALUE_IF(!uuid, false, "noUuidAttribute");
-    RETURN_VALUE_IF(!stringToUuid(uuid, &libraryUuid.uuid), false, "invalidUuidAttribute");
+    const char* uuidStr = xml.Attribute("uuid");
+    RETURN_VALUE_IF(!uuidStr, false, "noUuidAttribute");
+    libraryUuid.uuid = stringToUuid(uuidStr);
+    RETURN_VALUE_IF((libraryUuid.uuid == getEffectUuidZero()), false, "invalidUuidAttribute");
 
     LOG(DEBUG) << __func__ << (isProxy ? " proxy " : libraryUuid.name) << " : "
                << libraryUuid.uuid.toString();
     return true;
 }
 
+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)                        \
+    V("acoustic_echo_canceler", AcousticEchoCanceler)      \
+    V("automatic_gain_control_v1", AutomaticGainControlV1) \
+    V("automatic_gain_control_v2", AutomaticGainControlV2) \
+    V("bassboost", BassBoost)                              \
+    V("downmix", Downmix)                                  \
+    V("dynamics_processing", DynamicsProcessing)           \
+    V("equalizer", Equalizer)                              \
+    V("haptic_generator", HapticGenerator)                 \
+    V("loudness_enhancer", LoudnessEnhancer)               \
+    V("env_reverb", EnvReverb)                             \
+    V("reverb_env_aux", EnvReverb)                         \
+    V("reverb_env_ins", EnvReverb)                         \
+    V("preset_reverb", PresetReverb)                       \
+    V("reverb_pre_aux", PresetReverb)                      \
+    V("reverb_pre_ins", PresetReverb)                      \
+    V("noise_suppression", NoiseSuppression)               \
+    V("spatializer", Spatializer)                          \
+    V("virtualizer", Virtualizer)                          \
+    V("visualizer", Visualizer)                            \
+    V("volume", Volume)
+
+#define GENERATE_MAP_ENTRY_V(s, symbol) {s, &getEffectTypeUuid##symbol},
+
+    typedef const AudioUuid& (*UuidGetter)(void);
+    static const std::map<std::string, UuidGetter> uuidMap{
+            // std::make_pair("s", &getEffectTypeUuidExtension)};
+            {EFFECT_XML_TYPE_LIST_DEF(GENERATE_MAP_ENTRY_V)}};
+    if (auto it = uuidMap.find(xmlEffectName); it != uuidMap.end()) {
+        *uuid = (*it->second)();
+        return true;
+    }
+    return false;
+}
+
 const char* EffectConfig::dump(const tinyxml2::XMLElement& element,
                                tinyxml2::XMLPrinter&& printer) const {
     element.Accept(&printer);
diff --git a/audio/aidl/default/EffectFactory.cpp b/audio/aidl/default/EffectFactory.cpp
index 638fa7f..f0687cc 100644
--- a/audio/aidl/default/EffectFactory.cpp
+++ b/audio/aidl/default/EffectFactory.cpp
@@ -14,20 +14,19 @@
  * limitations under the License.
  */
 
+#include <dlfcn.h>
 #include <iterator>
 #include <memory>
 #include <tuple>
-#include "include/effect-impl/EffectTypes.h"
-#define LOG_TAG "AHAL_EffectFactory"
-#include <dlfcn.h>
 #include <unordered_set>
+#define LOG_TAG "AHAL_EffectFactory"
 
 #include <android-base/logging.h>
 #include <android/binder_ibinder_platform.h>
+#include <system/audio_effects/effect_uuid.h>
 #include <system/thread_defs.h>
 
 #include "effect-impl/EffectTypes.h"
-#include "effect-impl/EffectUUID.h"
 #include "effectFactory-impl/EffectFactory.h"
 
 using aidl::android::media::audio::common::AudioUuid;
@@ -76,6 +75,8 @@
             RETURN_IF(!libInterface || !libInterface->queryEffectFunc, EX_NULL_POINTER,
                       "dlNullQueryEffectFunc");
             RETURN_IF_BINDER_EXCEPTION(libInterface->queryEffectFunc(&id.uuid, &desc));
+            // update proxy UUID with information from config xml
+            desc.common.id.proxy = id.proxy;
             _aidl_return->emplace_back(std::move(desc));
         }
     }
@@ -214,8 +215,8 @@
 void Factory::loadEffectLibs() {
     const auto& configEffectsMap = mConfig.getEffectsMap();
     for (const auto& configEffects : configEffectsMap) {
-        if (auto typeUuid = kUuidNameTypeMap.find(configEffects.first /* effect name */);
-            typeUuid != kUuidNameTypeMap.end()) {
+        if (AudioUuid uuid;
+            EffectConfig::findUuid(configEffects.first /* xml effect name */, &uuid)) {
             const auto& configLibs = configEffects.second;
             std::optional<AudioUuid> proxyUuid;
             if (configLibs.proxyLibrary.has_value()) {
@@ -223,7 +224,7 @@
                 proxyUuid = proxyLib.uuid;
             }
             for (const auto& configLib : configLibs.libraries) {
-                createIdentityWithConfig(configLib, typeUuid->second, proxyUuid);
+                createIdentityWithConfig(configLib, uuid, proxyUuid);
             }
         } else {
             LOG(ERROR) << __func__ << ": can not find type UUID for effect " << configEffects.first
diff --git a/audio/aidl/default/EffectImpl.cpp b/audio/aidl/default/EffectImpl.cpp
index 403a4b9..da1ad11 100644
--- a/audio/aidl/default/EffectImpl.cpp
+++ b/audio/aidl/default/EffectImpl.cpp
@@ -40,7 +40,7 @@
 ndk::ScopedAStatus EffectImpl::open(const Parameter::Common& common,
                                     const std::optional<Parameter::Specific>& specific,
                                     OpenEffectReturn* ret) {
-    LOG(DEBUG) << __func__;
+    LOG(DEBUG) << getEffectName() << __func__;
     // effect only support 32bits float
     RETURN_IF(common.input.base.format.pcm != common.output.base.format.pcm ||
                       common.input.base.format.pcm != PcmType::FLOAT_32_BIT,
@@ -71,14 +71,14 @@
     RETURN_IF(releaseContext() != RetCode::SUCCESS, EX_UNSUPPORTED_OPERATION,
               "FailedToCreateWorker");
 
-    LOG(DEBUG) << __func__;
+    LOG(DEBUG) << getEffectName() << __func__;
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus EffectImpl::setParameter(const Parameter& param) {
-    LOG(DEBUG) << __func__ << " with: " << param.toString();
+    LOG(DEBUG) << getEffectName() << __func__ << " with: " << param.toString();
 
-    auto tag = param.getTag();
+    const auto tag = param.getTag();
     switch (tag) {
         case Parameter::common:
         case Parameter::deviceDescription:
@@ -91,7 +91,8 @@
             return setParameterSpecific(param.get<Parameter::specific>());
         }
         default: {
-            LOG(ERROR) << __func__ << " unsupportedParameterTag " << toString(tag);
+            LOG(ERROR) << getEffectName() << __func__ << " unsupportedParameterTag "
+                       << toString(tag);
             return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
                                                                     "ParameterNotSupported");
         }
@@ -99,7 +100,7 @@
 }
 
 ndk::ScopedAStatus EffectImpl::getParameter(const Parameter::Id& id, Parameter* param) {
-    LOG(DEBUG) << __func__ << id.toString();
+    LOG(DEBUG) << getEffectName() << __func__ << id.toString();
     auto tag = id.getTag();
     switch (tag) {
         case Parameter::Id::commonTag: {
@@ -107,11 +108,8 @@
                                      "CommonParamNotSupported");
             break;
         }
-        case Parameter::Id::vendorEffectTag: {
-            LOG(DEBUG) << __func__ << " noop for vendor tag";
-            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
-                                                                    "vendortagNotSupported");
-        }
+        case Parameter::Id::vendorEffectTag:
+            FALLTHROUGH_INTENDED;
         default: {
             Parameter::Specific specific;
             RETURN_IF_ASTATUS_NOT_OK(getParameterSpecific(id, &specific), "SpecParamNotSupported");
@@ -119,7 +117,7 @@
             break;
         }
     }
-    LOG(DEBUG) << __func__ << param->toString();
+    LOG(DEBUG) << getEffectName() << __func__ << param->toString();
     return ndk::ScopedAStatus::ok();
 }
 
@@ -152,7 +150,8 @@
                       EX_ILLEGAL_ARGUMENT, "setVolumeStereoFailed");
             break;
         default: {
-            LOG(ERROR) << __func__ << " unsupportedParameterTag " << toString(tag);
+            LOG(ERROR) << getEffectName() << __func__ << " unsupportedParameterTag "
+                       << toString(tag);
             return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
                                                                     "commonParamNotSupported");
         }
@@ -186,7 +185,7 @@
             break;
         }
         default: {
-            LOG(DEBUG) << __func__ << " unsupported tag " << toString(tag);
+            LOG(DEBUG) << getEffectName() << __func__ << " unsupported tag " << toString(tag);
             return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
                                                                     "tagNotSupported");
         }
@@ -201,8 +200,8 @@
 
 ndk::ScopedAStatus EffectImpl::command(CommandId command) {
     RETURN_IF(mState == State::INIT, EX_ILLEGAL_STATE, "CommandStateError");
-    LOG(DEBUG) << __func__ << ": receive command: " << toString(command) << " at state "
-               << toString(mState);
+    LOG(DEBUG) << getEffectName() << __func__ << ": receive command: " << toString(command)
+               << " at state " << toString(mState);
 
     switch (command) {
         case CommandId::START:
@@ -220,11 +219,11 @@
             mState = State::IDLE;
             break;
         default:
-            LOG(ERROR) << __func__ << " instance still processing";
+            LOG(ERROR) << getEffectName() << __func__ << " instance still processing";
             return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
                                                                     "CommandIdNotSupported");
     }
-    LOG(DEBUG) << __func__ << " transfer to state: " << toString(mState);
+    LOG(DEBUG) << getEffectName() << __func__ << " transfer to state: " << toString(mState);
     return ndk::ScopedAStatus::ok();
 }
 
@@ -255,7 +254,7 @@
     for (int i = 0; i < samples; i++) {
         *out++ = *in++;
     }
-    LOG(DEBUG) << __func__ << " done processing " << samples << " samples";
+    LOG(DEBUG) << getEffectName() << __func__ << " done processing " << samples << " samples";
     return {STATUS_OK, samples, samples};
 }
 
diff --git a/audio/aidl/default/EffectThread.cpp b/audio/aidl/default/EffectThread.cpp
index 2b3513d..844127d 100644
--- a/audio/aidl/default/EffectThread.cpp
+++ b/audio/aidl/default/EffectThread.cpp
@@ -34,19 +34,20 @@
 };
 
 RetCode EffectThread::createThread(std::shared_ptr<EffectContext> context, const std::string& name,
-                                   const int priority) {
+                                   int priority, int sleepUs /* kSleepTimeUs */) {
     if (mThread.joinable()) {
-        LOG(WARNING) << __func__ << " thread already created, no-op";
+        LOG(WARNING) << "-" << mName << "-" << __func__ << " thread already created, no-op";
         return RetCode::SUCCESS;
     }
     mName = name;
     mPriority = priority;
+    mSleepTimeUs = sleepUs;
     {
         std::lock_guard lg(mThreadMutex);
         mThreadContext = std::move(context);
     }
     mThread = std::thread(&EffectThread::threadLoop, this);
-    LOG(DEBUG) << __func__ << " " << name << " priority " << mPriority << " done";
+    LOG(DEBUG) << "-" << mName << "-" << __func__ << " priority " << mPriority << " done";
     return RetCode::SUCCESS;
 }
 
@@ -65,45 +66,37 @@
         std::lock_guard lg(mThreadMutex);
         mThreadContext.reset();
     }
-    LOG(DEBUG) << __func__ << " done";
+    LOG(DEBUG) << "-" << mName << "-" << __func__ << " done";
     return RetCode::SUCCESS;
 }
 
 RetCode EffectThread::startThread() {
-    if (!mThread.joinable()) {
-        LOG(ERROR) << __func__ << " thread already destroyed";
-        return RetCode::ERROR_THREAD;
-    }
-
-    {
-        std::lock_guard lg(mThreadMutex);
-        if (!mStop) {
-            LOG(WARNING) << __func__ << " already start";
-            return RetCode::SUCCESS;
-        }
-        mStop = false;
-    }
-
-    mCv.notify_one();
-    LOG(DEBUG) << __func__ << " done";
-    return RetCode::SUCCESS;
+    return handleStartStop(false /* stop */);
 }
 
 RetCode EffectThread::stopThread() {
+    return handleStartStop(true /* stop */);
+}
+
+RetCode EffectThread::handleStartStop(bool stop) {
     if (!mThread.joinable()) {
-        LOG(ERROR) << __func__ << " thread already destroyed";
+        LOG(ERROR) << "-" << mName << "-" << __func__ << ": "
+                   << " thread already destroyed";
         return RetCode::ERROR_THREAD;
     }
 
     {
         std::lock_guard lg(mThreadMutex);
-        if (mStop) {
-            LOG(WARNING) << __func__ << " already stop";
+        if (stop == mStop) {
+            LOG(WARNING) << "-" << mName << "-" << __func__ << ": "
+                         << " already " << (stop ? "stop" : "start");
             return RetCode::SUCCESS;
         }
-        mStop = true;
+        mStop = stop;
     }
-    LOG(DEBUG) << __func__ << " done";
+
+    mCv.notify_one();
+    LOG(DEBUG) << ": " << mName << (stop ? " stop done" : " start done");
     return RetCode::SUCCESS;
 }
 
@@ -111,52 +104,42 @@
     pthread_setname_np(pthread_self(), mName.substr(0, kMaxTaskNameLen - 1).c_str());
     setpriority(PRIO_PROCESS, 0, mPriority);
     while (true) {
-        bool needExit = false;
-        {
-            std::unique_lock l(mThreadMutex);
-            mCv.wait(l, [&]() REQUIRES(mThreadMutex) {
-                needExit = mExit;
-                return mExit || !mStop;
-            });
-        }
-        if (needExit) {
+        std::unique_lock l(mThreadMutex);
+        ::android::base::ScopedLockAssertion lock_assertion(mThreadMutex);
+        mCv.wait(l, [&]() REQUIRES(mThreadMutex) { return mExit || !mStop; });
+        if (mExit) {
             LOG(WARNING) << __func__ << " EXIT!";
             return;
         }
-
-        process();
+        process_l();
     }
 }
 
-void EffectThread::process() {
-    std::shared_ptr<EffectContext> context;
-    {
-        std::lock_guard lg(mThreadMutex);
-        context = mThreadContext;
-        RETURN_VALUE_IF(!context, void(), "nullContext");
-    }
-    std::shared_ptr<EffectContext::StatusMQ> statusMQ = context->getStatusFmq();
-    std::shared_ptr<EffectContext::DataMQ> inputMQ = context->getInputDataFmq();
-    std::shared_ptr<EffectContext::DataMQ> outputMQ = context->getOutputDataFmq();
-    auto buffer = context->getWorkBuffer();
+void EffectThread::process_l() {
+    RETURN_VALUE_IF(!mThreadContext, void(), "nullContext");
+    std::shared_ptr<EffectContext::StatusMQ> statusMQ = mThreadContext->getStatusFmq();
+    std::shared_ptr<EffectContext::DataMQ> inputMQ = mThreadContext->getInputDataFmq();
+    std::shared_ptr<EffectContext::DataMQ> outputMQ = mThreadContext->getOutputDataFmq();
+    auto buffer = mThreadContext->getWorkBuffer();
 
     // Only this worker will read from input data MQ and write to output data MQ.
     auto readSamples = inputMQ->availableToRead(), writeSamples = outputMQ->availableToWrite();
     if (readSamples && writeSamples) {
         auto processSamples = std::min(readSamples, writeSamples);
-        LOG(DEBUG) << __func__ << " available to read " << readSamples << " available to write "
-                   << writeSamples << " process " << processSamples;
+        LOG(DEBUG) << "-" << mName << "-" << __func__ << ": "
+                   << " available to read " << readSamples << " available to write " << writeSamples
+                   << " process " << processSamples;
 
         inputMQ->read(buffer, processSamples);
 
-        // call effectProcessImpl without lock
         IEffect::Status status = effectProcessImpl(buffer, buffer, processSamples);
         outputMQ->write(buffer, status.fmqProduced);
         statusMQ->writeBlocking(&status, 1);
-        LOG(DEBUG) << __func__ << " done processing, effect consumed " << status.fmqConsumed
-                   << " produced " << status.fmqProduced;
+        LOG(DEBUG) << "-" << mName << "-" << __func__ << ": "
+                   << " done processing, effect consumed " << status.fmqConsumed << " produced "
+                   << status.fmqProduced;
     } else {
-        // TODO: maybe add some sleep here to avoid busy waiting
+        usleep(mSleepTimeUs);
     }
 }
 
diff --git a/audio/aidl/default/Module.cpp b/audio/aidl/default/Module.cpp
index 2f6ab2f..6b417a4 100644
--- a/audio/aidl/default/Module.cpp
+++ b/audio/aidl/default/Module.cpp
@@ -34,6 +34,9 @@
 #include "core-impl/Telephony.h"
 #include "core-impl/utils.h"
 
+using aidl::android::hardware::audio::common::getFrameSizeInBytes;
+using aidl::android::hardware::audio::common::isBitPositionFlagSet;
+using aidl::android::hardware::audio::common::isValidAudioMode;
 using aidl::android::hardware::audio::common::SinkMetadata;
 using aidl::android::hardware::audio::common::SourceMetadata;
 using aidl::android::hardware::audio::core::sounddose::ISoundDose;
@@ -55,10 +58,8 @@
 using aidl::android::media::audio::common::AudioProfile;
 using aidl::android::media::audio::common::Boolean;
 using aidl::android::media::audio::common::Int;
+using aidl::android::media::audio::common::MicrophoneInfo;
 using aidl::android::media::audio::common::PcmType;
-using android::hardware::audio::common::getFrameSizeInBytes;
-using android::hardware::audio::common::isBitPositionFlagSet;
-using android::hardware::audio::common::isValidAudioMode;
 
 namespace aidl::android::hardware::audio::core {
 
@@ -142,6 +143,21 @@
     }
 }
 
+std::ostream& operator<<(std::ostream& os, Module::Type t) {
+    switch (t) {
+        case Module::Type::DEFAULT:
+            os << "default";
+            break;
+        case Module::Type::R_SUBMIX:
+            os << "r_submix";
+            break;
+        case Module::Type::USB:
+            os << "usb";
+            break;
+    }
+    return os;
+}
+
 void Module::cleanUpPatch(int32_t patchId) {
     erase_all_values(mPatches, std::set<int32_t>{patchId});
 }
@@ -351,16 +367,17 @@
 
 ndk::ScopedAStatus Module::setModuleDebug(
         const ::aidl::android::hardware::audio::core::ModuleDebug& in_debug) {
-    LOG(DEBUG) << __func__ << ": old flags:" << mDebug.toString()
+    LOG(DEBUG) << __func__ << ": " << mType << ": old flags:" << mDebug.toString()
                << ", new flags: " << in_debug.toString();
     if (mDebug.simulateDeviceConnections != in_debug.simulateDeviceConnections &&
         !mConnectedDevicePorts.empty()) {
-        LOG(ERROR) << __func__ << ": attempting to change device connections simulation "
-                   << "while having external devices connected";
+        LOG(ERROR) << __func__ << ": " << mType
+                   << ": attempting to change device connections simulation while having external "
+                   << "devices connected";
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
     }
     if (in_debug.streamTransientStateDelayMs < 0) {
-        LOG(ERROR) << __func__ << ": streamTransientStateDelayMs is negative: "
+        LOG(ERROR) << __func__ << ": " << mType << ": streamTransientStateDelayMs is negative: "
                    << in_debug.streamTransientStateDelayMs;
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
     }
@@ -369,29 +386,41 @@
 }
 
 ndk::ScopedAStatus Module::getTelephony(std::shared_ptr<ITelephony>* _aidl_return) {
-    if (mTelephony == nullptr) {
+    if (!mTelephony) {
         mTelephony = ndk::SharedRefBase::make<Telephony>();
-        mTelephonyBinder = mTelephony->asBinder();
-        AIBinder_setMinSchedulerPolicy(mTelephonyBinder.get(), SCHED_NORMAL,
-                                       ANDROID_PRIORITY_AUDIO);
     }
-    *_aidl_return = mTelephony;
+    *_aidl_return = mTelephony.getPtr();
     LOG(DEBUG) << __func__ << ": returning instance of ITelephony: " << _aidl_return->get();
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus Module::getBluetooth(std::shared_ptr<IBluetooth>* _aidl_return) {
-    if (mBluetooth == nullptr) {
+    if (!mBluetooth) {
         mBluetooth = ndk::SharedRefBase::make<Bluetooth>();
-        mBluetoothBinder = mBluetooth->asBinder();
-        AIBinder_setMinSchedulerPolicy(mBluetoothBinder.get(), SCHED_NORMAL,
-                                       ANDROID_PRIORITY_AUDIO);
     }
-    *_aidl_return = mBluetooth;
+    *_aidl_return = mBluetooth.getPtr();
     LOG(DEBUG) << __func__ << ": returning instance of IBluetooth: " << _aidl_return->get();
     return ndk::ScopedAStatus::ok();
 }
 
+ndk::ScopedAStatus Module::getBluetoothA2dp(std::shared_ptr<IBluetoothA2dp>* _aidl_return) {
+    if (!mBluetoothA2dp) {
+        mBluetoothA2dp = ndk::SharedRefBase::make<BluetoothA2dp>();
+    }
+    *_aidl_return = mBluetoothA2dp.getPtr();
+    LOG(DEBUG) << __func__ << ": returning instance of IBluetoothA2dp: " << _aidl_return->get();
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Module::getBluetoothLe(std::shared_ptr<IBluetoothLe>* _aidl_return) {
+    if (!mBluetoothLe) {
+        mBluetoothLe = ndk::SharedRefBase::make<BluetoothLe>();
+    }
+    *_aidl_return = mBluetoothLe.getPtr();
+    LOG(DEBUG) << __func__ << ": returning instance of IBluetoothLe: " << _aidl_return->get();
+    return ndk::ScopedAStatus::ok();
+}
+
 ndk::ScopedAStatus Module::connectExternalDevice(const AudioPort& in_templateIdAndAdditionalData,
                                                  AudioPort* _aidl_return) {
     const int32_t templateId = in_templateIdAndAdditionalData.id;
@@ -427,37 +456,45 @@
         LOG(DEBUG) << __func__ << ": device port " << connectedPort.id << " device set to "
                    << connectedDevicePort.device.toString();
         // Check if there is already a connected port with for the same external device.
-        for (auto connectedPortId : mConnectedDevicePorts) {
-            auto connectedPortIt = findById<AudioPort>(ports, connectedPortId);
+        for (auto connectedPortPair : mConnectedDevicePorts) {
+            auto connectedPortIt = findById<AudioPort>(ports, connectedPortPair.first);
             if (connectedPortIt->ext.get<AudioPortExt::Tag::device>().device ==
                 connectedDevicePort.device) {
                 LOG(ERROR) << __func__ << ": device " << connectedDevicePort.device.toString()
-                           << " is already connected at the device port id " << connectedPortId;
+                           << " is already connected at the device port id "
+                           << connectedPortPair.first;
                 return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
             }
         }
     }
 
     if (!mDebug.simulateDeviceConnections) {
-        // In a real HAL here we would attempt querying the profiles from the device.
-        LOG(ERROR) << __func__ << ": failed to query supported device profiles";
-        // TODO: Check the return value when it is ready for actual devices.
-        populateConnectedDevicePort(&connectedPort);
+        if (ndk::ScopedAStatus status = populateConnectedDevicePort(&connectedPort);
+            !status.isOk()) {
+            return status;
+        }
+    } else {
+        auto& connectedProfiles = getConfig().connectedProfiles;
+        if (auto connectedProfilesIt = connectedProfiles.find(templateId);
+            connectedProfilesIt != connectedProfiles.end()) {
+            connectedPort.profiles = connectedProfilesIt->second;
+        }
+    }
+    if (connectedPort.profiles.empty()) {
+        LOG(ERROR) << "Profiles of a connected port still empty after connecting external device "
+                   << connectedPort.toString();
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
     }
 
     connectedPort.id = ++getConfig().nextPortId;
-    mConnectedDevicePorts.insert(connectedPort.id);
+    auto [connectedPortsIt, _] =
+            mConnectedDevicePorts.insert(std::pair(connectedPort.id, std::vector<int32_t>()));
     LOG(DEBUG) << __func__ << ": template port " << templateId << " external device connected, "
                << "connected port ID " << connectedPort.id;
-    auto& connectedProfiles = getConfig().connectedProfiles;
-    if (auto connectedProfilesIt = connectedProfiles.find(templateId);
-        connectedProfilesIt != connectedProfiles.end()) {
-        connectedPort.profiles = connectedProfilesIt->second;
-    }
     ports.push_back(connectedPort);
-    *_aidl_return = std::move(connectedPort);
+    onExternalDeviceConnectionChanged(connectedPort, true /*connected*/);
 
+    std::vector<int32_t> routablePortIds;
     std::vector<AudioRoute> newRoutes;
     auto& routes = getConfig().routes;
     for (auto& r : routes) {
@@ -467,15 +504,30 @@
             newRoute.sinkPortId = connectedPort.id;
             newRoute.isExclusive = r.isExclusive;
             newRoutes.push_back(std::move(newRoute));
+            routablePortIds.insert(routablePortIds.end(), r.sourcePortIds.begin(),
+                                   r.sourcePortIds.end());
         } else {
             auto& srcs = r.sourcePortIds;
             if (std::find(srcs.begin(), srcs.end(), templateId) != srcs.end()) {
                 srcs.push_back(connectedPort.id);
+                routablePortIds.push_back(r.sinkPortId);
             }
         }
     }
     routes.insert(routes.end(), newRoutes.begin(), newRoutes.end());
 
+    // Note: this is a simplistic approach assuming that a mix port can only be populated
+    // from a single device port. Implementing support for stuffing dynamic profiles with a superset
+    // of all profiles from all routable dynamic device ports would be more involved.
+    for (const auto mixPortId : routablePortIds) {
+        auto portsIt = findById<AudioPort>(ports, mixPortId);
+        if (portsIt != ports.end() && portsIt->profiles.empty()) {
+            portsIt->profiles = connectedPort.profiles;
+            connectedPortsIt->second.push_back(portsIt->id);
+        }
+    }
+    *_aidl_return = std::move(connectedPort);
+
     return ndk::ScopedAStatus::ok();
 }
 
@@ -490,7 +542,8 @@
         LOG(ERROR) << __func__ << ": port id " << in_portId << " is not a device port";
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
     }
-    if (mConnectedDevicePorts.count(in_portId) == 0) {
+    auto connectedPortsIt = mConnectedDevicePorts.find(in_portId);
+    if (connectedPortsIt == mConnectedDevicePorts.end()) {
         LOG(ERROR) << __func__ << ": port id " << in_portId << " is not a connected device port";
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
     }
@@ -509,8 +562,8 @@
                    << configIt->id;
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
     }
+    onExternalDeviceConnectionChanged(*portIt, false /*connected*/);
     ports.erase(portIt);
-    mConnectedDevicePorts.erase(in_portId);
     LOG(DEBUG) << __func__ << ": connected device port " << in_portId << " released";
 
     auto& routes = getConfig().routes;
@@ -525,6 +578,14 @@
         }
     }
 
+    for (const auto mixPortId : connectedPortsIt->second) {
+        auto mixPortIt = findById<AudioPort>(ports, mixPortId);
+        if (mixPortIt != ports.end()) {
+            mixPortIt->profiles = {};
+        }
+    }
+    mConnectedDevicePorts.erase(connectedPortsIt);
+
     return ndk::ScopedAStatus::ok();
 }
 
@@ -894,6 +955,21 @@
         out_suggested->gain = in_requested.gain.value();
     }
 
+    if (in_requested.ext.getTag() != AudioPortExt::Tag::unspecified) {
+        if (in_requested.ext.getTag() == out_suggested->ext.getTag()) {
+            if (out_suggested->ext.getTag() == AudioPortExt::Tag::mix) {
+                // 'AudioMixPortExt.handle' is set by the client, copy from in_requested
+                out_suggested->ext.get<AudioPortExt::Tag::mix>().handle =
+                        in_requested.ext.get<AudioPortExt::Tag::mix>().handle;
+            }
+        } else {
+            LOG(WARNING) << __func__ << ": requested ext tag "
+                         << toString(in_requested.ext.getTag()) << " do not match port's tag "
+                         << toString(out_suggested->ext.getTag());
+            requestedIsValid = false;
+        }
+    }
+
     if (existing == configs.end() && requestedIsValid && requestedIsFullySpecified) {
         out_suggested->id = getConfig().nextPortId++;
         configs.push_back(*out_suggested);
@@ -964,8 +1040,17 @@
 
 ndk::ScopedAStatus Module::setMasterMute(bool in_mute) {
     LOG(DEBUG) << __func__ << ": " << in_mute;
-    mMasterMute = in_mute;
-    return ndk::ScopedAStatus::ok();
+    auto result = mDebug.simulateDeviceConnections ? ndk::ScopedAStatus::ok()
+                                                   : onMasterMuteChanged(in_mute);
+    if (result.isOk()) {
+        mMasterMute = in_mute;
+    } else {
+        LOG(ERROR) << __func__ << ": failed calling onMasterMuteChanged(" << in_mute
+                   << "), error=" << result;
+        // Reset master mute if it failed.
+        onMasterMuteChanged(mMasterMute);
+    }
+    return std::move(result);
 }
 
 ndk::ScopedAStatus Module::getMasterVolume(float* _aidl_return) {
@@ -977,8 +1062,17 @@
 ndk::ScopedAStatus Module::setMasterVolume(float in_volume) {
     LOG(DEBUG) << __func__ << ": " << in_volume;
     if (in_volume >= 0.0f && in_volume <= 1.0f) {
-        mMasterVolume = in_volume;
-        return ndk::ScopedAStatus::ok();
+        auto result = mDebug.simulateDeviceConnections ? ndk::ScopedAStatus::ok()
+                                                       : onMasterVolumeChanged(in_volume);
+        if (result.isOk()) {
+            mMasterVolume = in_volume;
+        } else {
+            // Reset master volume if it failed.
+            LOG(ERROR) << __func__ << ": failed calling onMasterVolumeChanged(" << in_volume
+                       << "), error=" << result;
+            onMasterVolumeChanged(mMasterVolume);
+        }
+        return std::move(result);
     }
     LOG(ERROR) << __func__ << ": invalid master volume value: " << in_volume;
     return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
@@ -1023,13 +1117,10 @@
 }
 
 ndk::ScopedAStatus Module::getSoundDose(std::shared_ptr<ISoundDose>* _aidl_return) {
-    if (mSoundDose == nullptr) {
+    if (!mSoundDose) {
         mSoundDose = ndk::SharedRefBase::make<sounddose::SoundDose>();
-        mSoundDoseBinder = mSoundDose->asBinder();
-        AIBinder_setMinSchedulerPolicy(mSoundDoseBinder.get(), SCHED_NORMAL,
-                                       ANDROID_PRIORITY_AUDIO);
     }
-    *_aidl_return = mSoundDose;
+    *_aidl_return = mSoundDose.getPtr();
     LOG(DEBUG) << __func__ << ": returning instance of ISoundDose: " << _aidl_return->get();
     return ndk::ScopedAStatus::ok();
 }
@@ -1235,14 +1326,30 @@
 }
 
 ndk::ScopedAStatus Module::populateConnectedDevicePort(AudioPort* audioPort __unused) {
-    LOG(DEBUG) << __func__ << ": do nothing and return ok";
+    LOG(VERBOSE) << __func__ << ": do nothing and return ok";
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus Module::checkAudioPatchEndpointsMatch(
         const std::vector<AudioPortConfig*>& sources __unused,
         const std::vector<AudioPortConfig*>& sinks __unused) {
-    LOG(DEBUG) << __func__ << ": do nothing and return ok";
+    LOG(VERBOSE) << __func__ << ": do nothing and return ok";
+    return ndk::ScopedAStatus::ok();
+}
+
+void Module::onExternalDeviceConnectionChanged(
+        const ::aidl::android::media::audio::common::AudioPort& audioPort __unused,
+        bool connected __unused) {
+    LOG(DEBUG) << __func__ << ": do nothing and return";
+}
+
+ndk::ScopedAStatus Module::onMasterMuteChanged(bool mute __unused) {
+    LOG(VERBOSE) << __func__ << ": do nothing and return ok";
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Module::onMasterVolumeChanged(float volume __unused) {
+    LOG(VERBOSE) << __func__ << ": do nothing and return ok";
     return ndk::ScopedAStatus::ok();
 }
 
diff --git a/audio/aidl/default/SoundDose.cpp b/audio/aidl/default/SoundDose.cpp
index be9f93a..f12ce5d 100644
--- a/audio/aidl/default/SoundDose.cpp
+++ b/audio/aidl/default/SoundDose.cpp
@@ -22,7 +22,7 @@
 
 namespace aidl::android::hardware::audio::core::sounddose {
 
-ndk::ScopedAStatus SoundDose::setOutputRs2(float in_rs2ValueDbA) {
+ndk::ScopedAStatus SoundDose::setOutputRs2UpperBound(float in_rs2ValueDbA) {
     if (in_rs2ValueDbA < MIN_RS2 || in_rs2ValueDbA > DEFAULT_MAX_RS2) {
         LOG(ERROR) << __func__ << ": RS2 value is invalid: " << in_rs2ValueDbA;
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
@@ -32,7 +32,7 @@
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus SoundDose::getOutputRs2(float* _aidl_return) {
+ndk::ScopedAStatus SoundDose::getOutputRs2UpperBound(float* _aidl_return) {
     *_aidl_return = mRs2Value;
     LOG(DEBUG) << __func__ << ": returning " << *_aidl_return;
     return ndk::ScopedAStatus::ok();
diff --git a/audio/aidl/default/Stream.cpp b/audio/aidl/default/Stream.cpp
index d62ca1d..77b0601 100644
--- a/audio/aidl/default/Stream.cpp
+++ b/audio/aidl/default/Stream.cpp
@@ -24,6 +24,9 @@
 #include "core-impl/Module.h"
 #include "core-impl/Stream.h"
 
+using aidl::android::hardware::audio::common::AudioOffloadMetadata;
+using aidl::android::hardware::audio::common::getChannelCount;
+using aidl::android::hardware::audio::common::getFrameSizeInBytes;
 using aidl::android::hardware::audio::common::SinkMetadata;
 using aidl::android::hardware::audio::common::SourceMetadata;
 using aidl::android::media::audio::common::AudioDevice;
@@ -31,8 +34,8 @@
 using aidl::android::media::audio::common::AudioLatencyMode;
 using aidl::android::media::audio::common::AudioOffloadInfo;
 using aidl::android::media::audio::common::AudioPlaybackRate;
-using android::hardware::audio::common::getChannelCount;
-using android::hardware::audio::common::getFrameSizeInBytes;
+using aidl::android::media::audio::common::MicrophoneDynamicInfo;
+using aidl::android::media::audio::common::MicrophoneInfo;
 
 namespace aidl::android::hardware::audio::core {
 
@@ -657,6 +660,16 @@
 }
 
 template <class Metadata>
+ndk::ScopedAStatus StreamCommonImpl<Metadata>::prepareToClose() {
+    LOG(DEBUG) << __func__;
+    if (!isClosed()) {
+        return ndk::ScopedAStatus::ok();
+    }
+    LOG(ERROR) << __func__ << ": stream was closed";
+    return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+}
+
+template <class Metadata>
 void StreamCommonImpl<Metadata>::stopWorker() {
     if (auto commandMQ = mContext.getCommandMQ(); commandMQ != nullptr) {
         LOG(DEBUG) << __func__ << ": asking the worker to exit...";
@@ -783,6 +796,40 @@
     LOG(DEBUG) << __func__;
 }
 
+ndk::ScopedAStatus StreamOut::updateOffloadMetadata(
+        const AudioOffloadMetadata& in_offloadMetadata) {
+    LOG(DEBUG) << __func__;
+    if (isClosed()) {
+        LOG(ERROR) << __func__ << ": stream was closed";
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+    }
+    if (!mOffloadInfo.has_value()) {
+        LOG(ERROR) << __func__ << ": not a compressed offload stream";
+        return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+    }
+    if (in_offloadMetadata.sampleRate < 0) {
+        LOG(ERROR) << __func__ << ": invalid sample rate value: " << in_offloadMetadata.sampleRate;
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    if (in_offloadMetadata.averageBitRatePerSecond < 0) {
+        LOG(ERROR) << __func__
+                   << ": invalid average BPS value: " << in_offloadMetadata.averageBitRatePerSecond;
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    if (in_offloadMetadata.delayFrames < 0) {
+        LOG(ERROR) << __func__
+                   << ": invalid delay frames value: " << in_offloadMetadata.delayFrames;
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    if (in_offloadMetadata.paddingFrames < 0) {
+        LOG(ERROR) << __func__
+                   << ": invalid padding frames value: " << in_offloadMetadata.paddingFrames;
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    mOffloadMetadata = in_offloadMetadata;
+    return ndk::ScopedAStatus::ok();
+}
+
 ndk::ScopedAStatus StreamOut::getHwVolume(std::vector<float>* _aidl_return) {
     LOG(DEBUG) << __func__;
     (void)_aidl_return;
diff --git a/audio/aidl/default/StreamStub.cpp b/audio/aidl/default/StreamStub.cpp
index 85d1e16..2467320 100644
--- a/audio/aidl/default/StreamStub.cpp
+++ b/audio/aidl/default/StreamStub.cpp
@@ -14,8 +14,11 @@
  * limitations under the License.
  */
 
+#include <cmath>
+
 #define LOG_TAG "AHAL_Stream"
 #include <android-base/logging.h>
+#include <audio_utils/clock.h>
 
 #include "core-impl/Module.h"
 #include "core-impl/StreamStub.h"
@@ -24,35 +27,47 @@
 using aidl::android::hardware::audio::common::SourceMetadata;
 using aidl::android::media::audio::common::AudioDevice;
 using aidl::android::media::audio::common::AudioOffloadInfo;
+using aidl::android::media::audio::common::MicrophoneInfo;
 
 namespace aidl::android::hardware::audio::core {
 
 DriverStub::DriverStub(const StreamContext& context, bool isInput)
-    : mFrameSizeBytes(context.getFrameSize()), mIsInput(isInput) {}
+    : mFrameSizeBytes(context.getFrameSize()),
+      mSampleRate(context.getSampleRate()),
+      mIsAsynchronous(!!context.getAsyncCallback()),
+      mIsInput(isInput) {}
 
 ::android::status_t DriverStub::init() {
-    usleep(1000);
+    usleep(500);
     return ::android::OK;
 }
 
 ::android::status_t DriverStub::drain(StreamDescriptor::DrainMode) {
-    usleep(1000);
+    usleep(500);
     return ::android::OK;
 }
 
 ::android::status_t DriverStub::flush() {
-    usleep(1000);
+    usleep(500);
     return ::android::OK;
 }
 
 ::android::status_t DriverStub::pause() {
-    usleep(1000);
+    usleep(500);
     return ::android::OK;
 }
 
 ::android::status_t DriverStub::transfer(void* buffer, size_t frameCount, size_t* actualFrameCount,
                                          int32_t* latencyMs) {
-    usleep(3000);
+    static constexpr float kMicrosPerSecond = MICROS_PER_SECOND;
+    static constexpr float kScaleFactor = .8f;
+    if (mIsAsynchronous) {
+        usleep(500);
+    } else {
+        const size_t delayUs = static_cast<size_t>(
+                std::roundf(kScaleFactor * frameCount * kMicrosPerSecond / mSampleRate));
+        usleep(delayUs);
+    }
     if (mIsInput) {
         uint8_t* byteBuffer = static_cast<uint8_t*>(buffer);
         for (size_t i = 0; i < frameCount * mFrameSizeBytes; ++i) {
@@ -65,12 +80,13 @@
 }
 
 ::android::status_t DriverStub::standby() {
-    usleep(1000);
+    usleep(500);
     return ::android::OK;
 }
 
 ::android::status_t DriverStub::setConnectedDevices(
         const std::vector<AudioDevice>& connectedDevices __unused) {
+    usleep(500);
     return ::android::OK;
 }
 
diff --git a/audio/aidl/default/Telephony.cpp b/audio/aidl/default/Telephony.cpp
index ad22470..bf05a8d 100644
--- a/audio/aidl/default/Telephony.cpp
+++ b/audio/aidl/default/Telephony.cpp
@@ -22,10 +22,10 @@
 
 #include "core-impl/Telephony.h"
 
+using aidl::android::hardware::audio::common::isValidAudioMode;
 using aidl::android::media::audio::common::AudioMode;
 using aidl::android::media::audio::common::Boolean;
 using aidl::android::media::audio::common::Float;
-using android::hardware::audio::common::isValidAudioMode;
 
 namespace aidl::android::hardware::audio::core {
 
diff --git a/audio/aidl/default/acousticEchoCanceler/AcousticEchoCancelerSw.cpp b/audio/aidl/default/acousticEchoCanceler/AcousticEchoCancelerSw.cpp
index 40b46e0..63a014a 100644
--- a/audio/aidl/default/acousticEchoCanceler/AcousticEchoCancelerSw.cpp
+++ b/audio/aidl/default/acousticEchoCanceler/AcousticEchoCancelerSw.cpp
@@ -17,24 +17,26 @@
 #include <algorithm>
 #include <cstddef>
 #include <memory>
-#define LOG_TAG "AHAL_AcousticEchoCancelerSw"
-#include <Utils.h>
 #include <unordered_set>
 
+#define LOG_TAG "AHAL_AcousticEchoCancelerSw"
 #include <android-base/logging.h>
 #include <fmq/AidlMessageQueue.h>
+#include <system/audio_effects/effect_uuid.h>
 
 #include "AcousticEchoCancelerSw.h"
 
 using aidl::android::hardware::audio::effect::AcousticEchoCancelerSw;
 using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectImplUuidAcousticEchoCancelerSw;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidAcousticEchoCanceler;
 using aidl::android::hardware::audio::effect::IEffect;
-using aidl::android::hardware::audio::effect::kAcousticEchoCancelerSwImplUUID;
+using aidl::android::hardware::audio::effect::Range;
 using aidl::android::media::audio::common::AudioUuid;
 
 extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
                                            std::shared_ptr<IEffect>* instanceSpp) {
-    if (!in_impl_uuid || *in_impl_uuid != kAcousticEchoCancelerSwImplUUID) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidAcousticEchoCancelerSw()) {
         LOG(ERROR) << __func__ << "uuid not supported";
         return EX_ILLEGAL_ARGUMENT;
     }
@@ -49,7 +51,7 @@
 }
 
 extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
-    if (!in_impl_uuid || *in_impl_uuid != kAcousticEchoCancelerSwImplUUID) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidAcousticEchoCancelerSw()) {
         LOG(ERROR) << __func__ << "uuid not supported";
         return EX_ILLEGAL_ARGUMENT;
     }
@@ -60,19 +62,24 @@
 namespace aidl::android::hardware::audio::effect {
 
 const std::string AcousticEchoCancelerSw::kEffectName = "AcousticEchoCancelerSw";
-const AcousticEchoCanceler::Capability AcousticEchoCancelerSw::kCapability = {
-        .maxEchoDelayUs = 500, .supportMobileMode = false};
+
+const std::vector<Range::AcousticEchoCancelerRange> AcousticEchoCancelerSw::kRanges = {
+        MAKE_RANGE(AcousticEchoCanceler, echoDelayUs, 0, 500),
+        /* mobile mode not supported, and not settable */
+        MAKE_RANGE(AcousticEchoCanceler, mobileMode, false, false)};
+
+const Capability AcousticEchoCancelerSw::kCapability = {.range = AcousticEchoCancelerSw::kRanges};
+
 const Descriptor AcousticEchoCancelerSw::kDescriptor = {
-        .common = {.id = {.type = kAcousticEchoCancelerTypeUUID,
-                          .uuid = kAcousticEchoCancelerSwImplUUID,
+        .common = {.id = {.type = getEffectTypeUuidAcousticEchoCanceler(),
+                          .uuid = getEffectImplUuidAcousticEchoCancelerSw(),
                           .proxy = std::nullopt},
                    .flags = {.type = Flags::Type::INSERT,
                              .insert = Flags::Insert::FIRST,
                              .volume = Flags::Volume::CTRL},
                    .name = AcousticEchoCancelerSw::kEffectName,
                    .implementor = "The Android Open Source Project"},
-        .capability = Capability::make<Capability::acousticEchoCanceler>(
-                AcousticEchoCancelerSw::kCapability)};
+        .capability = AcousticEchoCancelerSw::kCapability};
 
 ndk::ScopedAStatus AcousticEchoCancelerSw::getDescriptor(Descriptor* _aidl_return) {
     LOG(DEBUG) << __func__ << kDescriptor.toString();
@@ -87,8 +94,9 @@
     RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
 
     auto& param = specific.get<Parameter::Specific::acousticEchoCanceler>();
-    auto tag = param.getTag();
+    RETURN_IF(!inRange(param, kRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
 
+    auto tag = param.getTag();
     switch (tag) {
         case AcousticEchoCanceler::echoDelayUs: {
             RETURN_IF(mContext->setEchoDelay(param.get<AcousticEchoCanceler::echoDelayUs>()) !=
@@ -182,10 +190,6 @@
 }
 
 RetCode AcousticEchoCancelerSwContext::setEchoDelay(int echoDelayUs) {
-    if (echoDelayUs < 0 || echoDelayUs > AcousticEchoCancelerSw::kCapability.maxEchoDelayUs) {
-        LOG(DEBUG) << __func__ << " illegal delay " << echoDelayUs;
-        return RetCode::ERROR_ILLEGAL_PARAMETER;
-    }
     mEchoDelayUs = echoDelayUs;
     return RetCode::SUCCESS;
 }
diff --git a/audio/aidl/default/acousticEchoCanceler/AcousticEchoCancelerSw.h b/audio/aidl/default/acousticEchoCanceler/AcousticEchoCancelerSw.h
index 5f1bc46..73cf42b 100644
--- a/audio/aidl/default/acousticEchoCanceler/AcousticEchoCancelerSw.h
+++ b/audio/aidl/default/acousticEchoCanceler/AcousticEchoCancelerSw.h
@@ -17,12 +17,12 @@
 #pragma once
 
 #include <aidl/android/hardware/audio/effect/BnEffect.h>
+#include <aidl/android/hardware/audio/effect/Range.h>
 #include <fmq/AidlMessageQueue.h>
 #include <cstdlib>
 #include <memory>
 
 #include "effect-impl/EffectImpl.h"
-#include "effect-impl/EffectUUID.h"
 
 namespace aidl::android::hardware::audio::effect {
 
@@ -43,8 +43,7 @@
 class AcousticEchoCancelerSw final : public EffectImpl {
   public:
     static const std::string kEffectName;
-    static const bool kStrengthSupported;
-    static const AcousticEchoCanceler::Capability kCapability;
+    static const Capability kCapability;
     static const Descriptor kDescriptor;
     AcousticEchoCancelerSw() { LOG(DEBUG) << __func__; }
     ~AcousticEchoCancelerSw() {
@@ -65,6 +64,7 @@
     IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
 
   private:
+    static const std::vector<Range::AcousticEchoCancelerRange> kRanges;
     std::shared_ptr<AcousticEchoCancelerSwContext> mContext;
     ndk::ScopedAStatus getParameterAcousticEchoCanceler(const AcousticEchoCanceler::Tag& tag,
                                                         Parameter::Specific* specific);
diff --git a/audio/aidl/default/audio_effects_config.xml b/audio/aidl/default/audio_effects_config.xml
index 6714a7e..c06742d 100644
--- a/audio/aidl/default/audio_effects_config.xml
+++ b/audio/aidl/default/audio_effects_config.xml
@@ -29,7 +29,8 @@
     -->
     <libraries>
         <library name="aecsw" path="libaecsw.so"/>
-        <library name="agcsw" path="libagcsw.so"/>
+        <library name="agc1sw" path="libagc1sw.so"/>
+        <library name="agc2sw" path="libagc2sw.so"/>
         <library name="bassboostsw" path="libbassboostsw.so"/>
         <library name="bundle" path="libbundleaidl.so"/>
         <library name="downmix" path="libdownmixaidl.so"/>
@@ -39,11 +40,13 @@
         <library name="loudness_enhancer" path="libloudnessenhanceraidl.so"/>
         <library name="nssw" path="libnssw.so"/>
         <library name="env_reverbsw" path="libenvreverbsw.so"/>
+        <library name="pre_processing" path="libpreprocessingaidl.so"/>
         <library name="preset_reverbsw" path="libpresetreverbsw.so"/>
         <library name="reverb" path="libreverbaidl.so"/>
         <library name="virtualizersw" path="libvirtualizersw.so"/>
         <library name="visualizer" path="libvisualizeraidl.so"/>
         <library name="volumesw" path="libvolumesw.so"/>
+        <library name="extensioneffect" path="libextensioneffect.so"/>
     </libraries>
 
     <!-- list of effects to load.
@@ -66,8 +69,7 @@
     -->
 
     <effects>
-        <effect name="acoustic_echo_canceler" library="aecsw" uuid="bb392ec0-8d4d-11e0-a896-0002a5d5c51b"/>
-        <effect name="automatic_gain_control" library="agcsw" uuid="89f38e65-d4d2-4d64-ad0e-2b3e799ea886"/>
+        <effect name="automatic_gain_control_v2" library="pre_processing" uuid="89f38e65-d4d2-4d64-ad0e-2b3e799ea886"/>
         <effectProxy name="bassboost" uuid="14804144-a5ee-4d24-aa88-0002a5d5c51b">
             <libsw library="bassboostsw" uuid="fa8181f2-588b-11ed-9b6a-0242ac120002"/>
             <libsw library="bundle" uuid="8631f300-72e2-11df-b57e-0002a5d5c51b"/>
@@ -77,7 +79,6 @@
         <effect name="haptic_generator" library="haptic_generator" uuid="97c4acd1-8b82-4f2f-832e-c2fe5d7a9931"/>
         <effect name="loudness_enhancer" library="loudness_enhancer" uuid="fa415329-2034-4bea-b5dc-5b381c8d1e2c"/>
         <effect name="env_reverb" library="env_reverbsw" uuid="fa819886-588b-11ed-9b6a-0242ac120002"/>
-        <effect name="noise_suppression" library="nssw" uuid="c06c8400-8e06-11e0-9cb6-0002a5d5c51b"/>
         <effect name="preset_reverb" library="preset_reverbsw" uuid="fa8199c6-588b-11ed-9b6a-0242ac120002"/>
         <effect name="reverb_env_aux" library="reverb" uuid="4a387fc0-8ab3-11df-8bad-0002a5d5c51b"/>
         <effect name="reverb_env_ins" library="reverb" uuid="c7a511a0-a3bb-11df-860e-0002a5d5c51b"/>
@@ -93,6 +94,7 @@
             <libsw library="equalizersw" uuid="0bed4300-847d-11df-bb17-0002a5d5c51b"/>
             <libsw library="bundle" uuid="ce772f20-847d-11df-bb17-0002a5d5c51b"/>
         </effectProxy>
+        <effect name="extensioneffect" library="extensioneffect" uuid="fa81dd00-588b-11ed-9b6a-0242ac120002"/>
     </effects>
 
     <!-- Audio pre processor configurations.
diff --git a/audio/aidl/default/automaticGainControl/AutomaticGainControlSw.cpp b/audio/aidl/default/automaticGainControl/AutomaticGainControlSw.cpp
deleted file mode 100644
index 8c706ef..0000000
--- a/audio/aidl/default/automaticGainControl/AutomaticGainControlSw.cpp
+++ /dev/null
@@ -1,234 +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.
- */
-
-#include <algorithm>
-#include <cstddef>
-#include <memory>
-#define LOG_TAG "AHAL_AutomaticGainControlSw"
-#include <Utils.h>
-#include <unordered_set>
-
-#include <android-base/logging.h>
-#include <fmq/AidlMessageQueue.h>
-
-#include "AutomaticGainControlSw.h"
-
-using aidl::android::hardware::audio::effect::AutomaticGainControlSw;
-using aidl::android::hardware::audio::effect::Descriptor;
-using aidl::android::hardware::audio::effect::IEffect;
-using aidl::android::hardware::audio::effect::kAutomaticGainControlSwImplUUID;
-using aidl::android::media::audio::common::AudioUuid;
-
-extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
-                                           std::shared_ptr<IEffect>* instanceSpp) {
-    if (!in_impl_uuid || *in_impl_uuid != kAutomaticGainControlSwImplUUID) {
-        LOG(ERROR) << __func__ << "uuid not supported";
-        return EX_ILLEGAL_ARGUMENT;
-    }
-    if (instanceSpp) {
-        *instanceSpp = ndk::SharedRefBase::make<AutomaticGainControlSw>();
-        LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
-        return EX_NONE;
-    } else {
-        LOG(ERROR) << __func__ << " invalid input parameter!";
-        return EX_ILLEGAL_ARGUMENT;
-    }
-}
-
-extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
-    if (!in_impl_uuid || *in_impl_uuid != kAutomaticGainControlSwImplUUID) {
-        LOG(ERROR) << __func__ << "uuid not supported";
-        return EX_ILLEGAL_ARGUMENT;
-    }
-    *_aidl_return = AutomaticGainControlSw::kDescriptor;
-    return EX_NONE;
-}
-
-namespace aidl::android::hardware::audio::effect {
-
-const std::string AutomaticGainControlSw::kEffectName = "AutomaticGainControlSw";
-const AutomaticGainControl::Capability AutomaticGainControlSw::kCapability = {
-        .maxFixedDigitalGainMb = 50000, .maxSaturationMarginMb = 10000};
-const Descriptor AutomaticGainControlSw::kDescriptor = {
-        .common = {.id = {.type = kAutomaticGainControlTypeUUID,
-                          .uuid = kAutomaticGainControlSwImplUUID,
-                          .proxy = std::nullopt},
-                   .flags = {.type = Flags::Type::INSERT,
-                             .insert = Flags::Insert::FIRST,
-                             .volume = Flags::Volume::CTRL},
-                   .name = AutomaticGainControlSw::kEffectName,
-                   .implementor = "The Android Open Source Project"},
-        .capability = Capability::make<Capability::automaticGainControl>(
-                AutomaticGainControlSw::kCapability)};
-
-ndk::ScopedAStatus AutomaticGainControlSw::getDescriptor(Descriptor* _aidl_return) {
-    LOG(DEBUG) << __func__ << kDescriptor.toString();
-    *_aidl_return = kDescriptor;
-    return ndk::ScopedAStatus::ok();
-}
-
-ndk::ScopedAStatus AutomaticGainControlSw::setParameterSpecific(
-        const Parameter::Specific& specific) {
-    RETURN_IF(Parameter::Specific::automaticGainControl != specific.getTag(), EX_ILLEGAL_ARGUMENT,
-              "EffectNotSupported");
-    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
-
-    auto& param = specific.get<Parameter::Specific::automaticGainControl>();
-    auto tag = param.getTag();
-
-    switch (tag) {
-        case AutomaticGainControl::fixedDigitalGainMb: {
-            RETURN_IF(mContext->setDigitalGain(
-                              param.get<AutomaticGainControl::fixedDigitalGainMb>()) !=
-                              RetCode::SUCCESS,
-                      EX_ILLEGAL_ARGUMENT, "digitalGainNotSupported");
-            return ndk::ScopedAStatus::ok();
-        }
-        case AutomaticGainControl::levelEstimator: {
-            RETURN_IF(
-                    mContext->setLevelEstimator(
-                            param.get<AutomaticGainControl::levelEstimator>()) != RetCode::SUCCESS,
-                    EX_ILLEGAL_ARGUMENT, "levelEstimatorNotSupported");
-            return ndk::ScopedAStatus::ok();
-        }
-        case AutomaticGainControl::saturationMarginMb: {
-            RETURN_IF(mContext->setSaturationMargin(
-                              param.get<AutomaticGainControl::saturationMarginMb>()) !=
-                              RetCode::SUCCESS,
-                      EX_ILLEGAL_ARGUMENT, "saturationMarginNotSupported");
-            return ndk::ScopedAStatus::ok();
-        }
-        default: {
-            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
-            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
-                    EX_ILLEGAL_ARGUMENT, "AutomaticGainControlTagNotSupported");
-        }
-    }
-}
-
-ndk::ScopedAStatus AutomaticGainControlSw::getParameterSpecific(const Parameter::Id& id,
-                                                                Parameter::Specific* specific) {
-    auto tag = id.getTag();
-    RETURN_IF(Parameter::Id::automaticGainControlTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
-    auto specificId = id.get<Parameter::Id::automaticGainControlTag>();
-    auto specificIdTag = specificId.getTag();
-    switch (specificIdTag) {
-        case AutomaticGainControl::Id::commonTag:
-            return getParameterAutomaticGainControl(
-                    specificId.get<AutomaticGainControl::Id::commonTag>(), specific);
-        default:
-            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
-            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
-                    EX_ILLEGAL_ARGUMENT, "AutomaticGainControlTagNotSupported");
-    }
-}
-
-ndk::ScopedAStatus AutomaticGainControlSw::getParameterAutomaticGainControl(
-        const AutomaticGainControl::Tag& tag, Parameter::Specific* specific) {
-    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
-    AutomaticGainControl param;
-    switch (tag) {
-        case AutomaticGainControl::fixedDigitalGainMb: {
-            param.set<AutomaticGainControl::fixedDigitalGainMb>(mContext->getDigitalGain());
-            break;
-        }
-        case AutomaticGainControl::levelEstimator: {
-            param.set<AutomaticGainControl::levelEstimator>(mContext->getLevelEstimator());
-            break;
-        }
-        case AutomaticGainControl::saturationMarginMb: {
-            param.set<AutomaticGainControl::saturationMarginMb>(mContext->getSaturationMargin());
-            break;
-        }
-        default: {
-            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
-            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
-                    EX_ILLEGAL_ARGUMENT, "AutomaticGainControlTagNotSupported");
-        }
-    }
-
-    specific->set<Parameter::Specific::automaticGainControl>(param);
-    return ndk::ScopedAStatus::ok();
-}
-
-std::shared_ptr<EffectContext> AutomaticGainControlSw::createContext(
-        const Parameter::Common& common) {
-    if (mContext) {
-        LOG(DEBUG) << __func__ << " context already exist";
-    } else {
-        mContext = std::make_shared<AutomaticGainControlSwContext>(1 /* statusFmqDepth */, common);
-    }
-    return mContext;
-}
-
-std::shared_ptr<EffectContext> AutomaticGainControlSw::getContext() {
-    return mContext;
-}
-
-RetCode AutomaticGainControlSw::releaseContext() {
-    if (mContext) {
-        mContext.reset();
-    }
-    return RetCode::SUCCESS;
-}
-
-// Processing method running in EffectWorker thread.
-IEffect::Status AutomaticGainControlSw::effectProcessImpl(float* in, float* out, int samples) {
-    // TODO: get data buffer and process.
-    LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
-    for (int i = 0; i < samples; i++) {
-        *out++ = *in++;
-    }
-    return {STATUS_OK, samples, samples};
-}
-
-RetCode AutomaticGainControlSwContext::setDigitalGain(int gain) {
-    if (gain < 0 || gain > AutomaticGainControlSw::kCapability.maxFixedDigitalGainMb) {
-        LOG(DEBUG) << __func__ << " illegal digital gain " << gain;
-        return RetCode::ERROR_ILLEGAL_PARAMETER;
-    }
-    mDigitalGain = gain;
-    return RetCode::SUCCESS;
-}
-
-int AutomaticGainControlSwContext::getDigitalGain() {
-    return mDigitalGain;
-}
-
-RetCode AutomaticGainControlSwContext::setLevelEstimator(
-        AutomaticGainControl::LevelEstimator levelEstimator) {
-    mLevelEstimator = levelEstimator;
-    return RetCode::SUCCESS;
-}
-
-AutomaticGainControl::LevelEstimator AutomaticGainControlSwContext::getLevelEstimator() {
-    return mLevelEstimator;
-}
-
-RetCode AutomaticGainControlSwContext::setSaturationMargin(int margin) {
-    if (margin < 0 || margin > AutomaticGainControlSw::kCapability.maxSaturationMarginMb) {
-        LOG(DEBUG) << __func__ << " illegal saturationMargin " << margin;
-        return RetCode::ERROR_ILLEGAL_PARAMETER;
-    }
-    mSaturationMargin = margin;
-    return RetCode::SUCCESS;
-}
-
-int AutomaticGainControlSwContext::getSaturationMargin() {
-    return mSaturationMargin;
-}
-
-}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/automaticGainControl/Android.bp b/audio/aidl/default/automaticGainControlV1/Android.bp
similarity index 91%
copy from audio/aidl/default/automaticGainControl/Android.bp
copy to audio/aidl/default/automaticGainControlV1/Android.bp
index 17d6416..4ae8e63 100644
--- a/audio/aidl/default/automaticGainControl/Android.bp
+++ b/audio/aidl/default/automaticGainControlV1/Android.bp
@@ -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.
@@ -24,14 +24,14 @@
 }
 
 cc_library_shared {
-    name: "libagcsw",
+    name: "libagc1sw",
     defaults: [
         "aidlaudioeffectservice_defaults",
         "latest_android_media_audio_common_types_ndk_shared",
         "latest_android_hardware_audio_effect_ndk_shared",
     ],
     srcs: [
-        "AutomaticGainControlSw.cpp",
+        "AutomaticGainControlV1Sw.cpp",
         ":effectCommonFile",
     ],
     relative_install_path: "soundfx",
diff --git a/audio/aidl/default/automaticGainControlV1/AutomaticGainControlV1Sw.cpp b/audio/aidl/default/automaticGainControlV1/AutomaticGainControlV1Sw.cpp
new file mode 100644
index 0000000..ce10ae1
--- /dev/null
+++ b/audio/aidl/default/automaticGainControlV1/AutomaticGainControlV1Sw.cpp
@@ -0,0 +1,228 @@
+/*
+ * 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_AutomaticGainControlV1Sw"
+
+#include <android-base/logging.h>
+#include <system/audio_effects/effect_uuid.h>
+
+#include "AutomaticGainControlV1Sw.h"
+
+using aidl::android::hardware::audio::effect::AutomaticGainControlV1Sw;
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectImplUuidAutomaticGainControlV1Sw;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidAutomaticGainControlV1;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::media::audio::common::AudioUuid;
+
+extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
+                                           std::shared_ptr<IEffect>* instanceSpp) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidAutomaticGainControlV1Sw()) {
+        LOG(ERROR) << __func__ << "uuid not supported";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+    if (instanceSpp) {
+        *instanceSpp = ndk::SharedRefBase::make<AutomaticGainControlV1Sw>();
+        LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
+        return EX_NONE;
+    } else {
+        LOG(ERROR) << __func__ << " invalid input parameter!";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+}
+
+extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidAutomaticGainControlV1Sw()) {
+        LOG(ERROR) << __func__ << "uuid not supported";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+    *_aidl_return = AutomaticGainControlV1Sw::kDescriptor;
+    return EX_NONE;
+}
+
+namespace aidl::android::hardware::audio::effect {
+
+const std::string AutomaticGainControlV1Sw::kEffectName = "AutomaticGainControlV1Sw";
+
+const std::vector<Range::AutomaticGainControlV1Range> AutomaticGainControlV1Sw::kRanges = {
+        MAKE_RANGE(AutomaticGainControlV1, targetPeakLevelDbFs, -3100, 0),
+        MAKE_RANGE(AutomaticGainControlV1, maxCompressionGainDb, 0, 9000)};
+
+const Capability AutomaticGainControlV1Sw::kCapability = {
+        .range = AutomaticGainControlV1Sw::kRanges};
+
+const Descriptor AutomaticGainControlV1Sw::kDescriptor = {
+        .common = {.id = {.type = getEffectTypeUuidAutomaticGainControlV1(),
+                          .uuid = getEffectImplUuidAutomaticGainControlV1Sw(),
+                          .proxy = std::nullopt},
+                   .flags = {.type = Flags::Type::INSERT,
+                             .insert = Flags::Insert::FIRST,
+                             .volume = Flags::Volume::CTRL},
+                   .name = AutomaticGainControlV1Sw::kEffectName,
+                   .implementor = "The Android Open Source Project"},
+        .capability = AutomaticGainControlV1Sw::kCapability};
+
+ndk::ScopedAStatus AutomaticGainControlV1Sw::getDescriptor(Descriptor* _aidl_return) {
+    LOG(DEBUG) << __func__ << kDescriptor.toString();
+    *_aidl_return = kDescriptor;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus AutomaticGainControlV1Sw::setParameterSpecific(
+        const Parameter::Specific& specific) {
+    RETURN_IF(Parameter::Specific::automaticGainControlV1 != specific.getTag(), EX_ILLEGAL_ARGUMENT,
+              "EffectNotSupported");
+    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+
+    auto& param = specific.get<Parameter::Specific::automaticGainControlV1>();
+    RETURN_IF(!inRange(param, kRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
+    auto tag = param.getTag();
+    switch (tag) {
+        case AutomaticGainControlV1::targetPeakLevelDbFs: {
+            RETURN_IF(mContext->setTargetPeakLevel(
+                              param.get<AutomaticGainControlV1::targetPeakLevelDbFs>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "targetPeakLevelNotSupported");
+            return ndk::ScopedAStatus::ok();
+        }
+        case AutomaticGainControlV1::maxCompressionGainDb: {
+            RETURN_IF(mContext->setMaxCompressionGain(
+                              param.get<AutomaticGainControlV1::maxCompressionGainDb>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "maxCompressionGainNotSupported");
+            return ndk::ScopedAStatus::ok();
+        }
+        case AutomaticGainControlV1::enableLimiter: {
+            RETURN_IF(
+                    mContext->setEnableLimiter(
+                            param.get<AutomaticGainControlV1::enableLimiter>()) != RetCode::SUCCESS,
+                    EX_ILLEGAL_ARGUMENT, "enableLimiterNotSupported");
+            return ndk::ScopedAStatus::ok();
+        }
+        default: {
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+                    EX_ILLEGAL_ARGUMENT, "AutomaticGainControlV1TagNotSupported");
+        }
+    }
+}
+
+ndk::ScopedAStatus AutomaticGainControlV1Sw::getParameterSpecific(const Parameter::Id& id,
+                                                                  Parameter::Specific* specific) {
+    auto tag = id.getTag();
+    RETURN_IF(Parameter::Id::automaticGainControlV1Tag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
+    auto specificId = id.get<Parameter::Id::automaticGainControlV1Tag>();
+    auto specificIdTag = specificId.getTag();
+    switch (specificIdTag) {
+        case AutomaticGainControlV1::Id::commonTag:
+            return getParameterAutomaticGainControlV1(
+                    specificId.get<AutomaticGainControlV1::Id::commonTag>(), specific);
+        default:
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+                    EX_ILLEGAL_ARGUMENT, "AutomaticGainControlV1TagNotSupported");
+    }
+}
+
+ndk::ScopedAStatus AutomaticGainControlV1Sw::getParameterAutomaticGainControlV1(
+        const AutomaticGainControlV1::Tag& tag, Parameter::Specific* specific) {
+    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+    AutomaticGainControlV1 param;
+    switch (tag) {
+        case AutomaticGainControlV1::targetPeakLevelDbFs: {
+            param.set<AutomaticGainControlV1::targetPeakLevelDbFs>(mContext->getTargetPeakLevel());
+            break;
+        }
+        case AutomaticGainControlV1::maxCompressionGainDb: {
+            param.set<AutomaticGainControlV1::maxCompressionGainDb>(
+                    mContext->getMaxCompressionGain());
+            break;
+        }
+        case AutomaticGainControlV1::enableLimiter: {
+            param.set<AutomaticGainControlV1::enableLimiter>(mContext->getEnableLimiter());
+            break;
+        }
+        default: {
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+                    EX_ILLEGAL_ARGUMENT, "AutomaticGainControlV1TagNotSupported");
+        }
+    }
+
+    specific->set<Parameter::Specific::automaticGainControlV1>(param);
+    return ndk::ScopedAStatus::ok();
+}
+
+std::shared_ptr<EffectContext> AutomaticGainControlV1Sw::createContext(
+        const Parameter::Common& common) {
+    if (mContext) {
+        LOG(DEBUG) << __func__ << " context already exist";
+    } else {
+        mContext =
+                std::make_shared<AutomaticGainControlV1SwContext>(1 /* statusFmqDepth */, common);
+    }
+    return mContext;
+}
+
+std::shared_ptr<EffectContext> AutomaticGainControlV1Sw::getContext() {
+    return mContext;
+}
+
+RetCode AutomaticGainControlV1Sw::releaseContext() {
+    if (mContext) {
+        mContext.reset();
+    }
+    return RetCode::SUCCESS;
+}
+
+// Processing method running in EffectWorker thread.
+IEffect::Status AutomaticGainControlV1Sw::effectProcessImpl(float* in, float* out, int samples) {
+    // TODO: get data buffer and process.
+    LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
+    for (int i = 0; i < samples; i++) {
+        *out++ = *in++;
+    }
+    return {STATUS_OK, samples, samples};
+}
+
+RetCode AutomaticGainControlV1SwContext::setTargetPeakLevel(int targetPeakLevel) {
+    mTargetPeakLevel = targetPeakLevel;
+    return RetCode::SUCCESS;
+}
+
+int AutomaticGainControlV1SwContext::getTargetPeakLevel() {
+    return mTargetPeakLevel;
+}
+
+RetCode AutomaticGainControlV1SwContext::setMaxCompressionGain(int maxCompressionGain) {
+    mMaxCompressionGain = maxCompressionGain;
+    return RetCode::SUCCESS;
+}
+
+int AutomaticGainControlV1SwContext::getMaxCompressionGain() {
+    return mMaxCompressionGain;
+}
+
+RetCode AutomaticGainControlV1SwContext::setEnableLimiter(bool enableLimiter) {
+    mEnableLimiter = enableLimiter;
+    return RetCode::SUCCESS;
+}
+
+bool AutomaticGainControlV1SwContext::getEnableLimiter() {
+    return mEnableLimiter;
+}
+
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/automaticGainControlV1/AutomaticGainControlV1Sw.h b/audio/aidl/default/automaticGainControlV1/AutomaticGainControlV1Sw.h
new file mode 100644
index 0000000..7d2a69f
--- /dev/null
+++ b/audio/aidl/default/automaticGainControlV1/AutomaticGainControlV1Sw.h
@@ -0,0 +1,73 @@
+/*
+ * 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 "effect-impl/EffectImpl.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+class AutomaticGainControlV1SwContext final : public EffectContext {
+  public:
+    AutomaticGainControlV1SwContext(int statusDepth, const Parameter::Common& common)
+        : EffectContext(statusDepth, common) {
+        LOG(DEBUG) << __func__;
+    }
+
+    RetCode setTargetPeakLevel(int targetPeakLevel);
+    int getTargetPeakLevel();
+    RetCode setMaxCompressionGain(int maxCompressionGainDb);
+    int getMaxCompressionGain();
+    RetCode setEnableLimiter(bool enableLimiter);
+    bool getEnableLimiter();
+
+  private:
+    int mTargetPeakLevel = 0;
+    int mMaxCompressionGain = 0;
+    bool mEnableLimiter = false;
+};
+
+class AutomaticGainControlV1Sw final : public EffectImpl {
+  public:
+    static const std::string kEffectName;
+    static const bool kStrengthSupported;
+    static const Capability kCapability;
+    static const Descriptor kDescriptor;
+    AutomaticGainControlV1Sw() { LOG(DEBUG) << __func__; }
+    ~AutomaticGainControlV1Sw() {
+        cleanUp();
+        LOG(DEBUG) << __func__;
+    }
+
+    ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
+    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
+    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
+                                            Parameter::Specific* specific) override;
+
+    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
+    std::shared_ptr<EffectContext> getContext() override;
+    RetCode releaseContext() override;
+
+    std::string getEffectName() override { return kEffectName; };
+    IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+
+  private:
+    static const std::vector<Range::AutomaticGainControlV1Range> kRanges;
+    std::shared_ptr<AutomaticGainControlV1SwContext> mContext;
+    ndk::ScopedAStatus getParameterAutomaticGainControlV1(const AutomaticGainControlV1::Tag& tag,
+                                                          Parameter::Specific* specific);
+};
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/automaticGainControl/Android.bp b/audio/aidl/default/automaticGainControlV2/Android.bp
similarity index 95%
rename from audio/aidl/default/automaticGainControl/Android.bp
rename to audio/aidl/default/automaticGainControlV2/Android.bp
index 17d6416..631cf58 100644
--- a/audio/aidl/default/automaticGainControl/Android.bp
+++ b/audio/aidl/default/automaticGainControlV2/Android.bp
@@ -24,14 +24,14 @@
 }
 
 cc_library_shared {
-    name: "libagcsw",
+    name: "libagc2sw",
     defaults: [
         "aidlaudioeffectservice_defaults",
         "latest_android_media_audio_common_types_ndk_shared",
         "latest_android_hardware_audio_effect_ndk_shared",
     ],
     srcs: [
-        "AutomaticGainControlSw.cpp",
+        "AutomaticGainControlV2Sw.cpp",
         ":effectCommonFile",
     ],
     relative_install_path: "soundfx",
diff --git a/audio/aidl/default/automaticGainControlV2/AutomaticGainControlV2Sw.cpp b/audio/aidl/default/automaticGainControlV2/AutomaticGainControlV2Sw.cpp
new file mode 100644
index 0000000..1e336ac
--- /dev/null
+++ b/audio/aidl/default/automaticGainControlV2/AutomaticGainControlV2Sw.cpp
@@ -0,0 +1,232 @@
+/*
+ * 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.
+ */
+
+#include <algorithm>
+#include <cstddef>
+#include <memory>
+#define LOG_TAG "AHAL_AutomaticGainControlV2Sw"
+
+#include <android-base/logging.h>
+#include <fmq/AidlMessageQueue.h>
+#include <system/audio_effects/effect_uuid.h>
+
+#include "AutomaticGainControlV2Sw.h"
+
+using aidl::android::hardware::audio::effect::AutomaticGainControlV2Sw;
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectImplUuidAutomaticGainControlV2Sw;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidAutomaticGainControlV2;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::media::audio::common::AudioUuid;
+
+extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
+                                           std::shared_ptr<IEffect>* instanceSpp) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidAutomaticGainControlV2Sw()) {
+        LOG(ERROR) << __func__ << "uuid not supported";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+    if (instanceSpp) {
+        *instanceSpp = ndk::SharedRefBase::make<AutomaticGainControlV2Sw>();
+        LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
+        return EX_NONE;
+    } else {
+        LOG(ERROR) << __func__ << " invalid input parameter!";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+}
+
+extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidAutomaticGainControlV2Sw()) {
+        LOG(ERROR) << __func__ << "uuid not supported";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+    *_aidl_return = AutomaticGainControlV2Sw::kDescriptor;
+    return EX_NONE;
+}
+
+namespace aidl::android::hardware::audio::effect {
+
+const std::string AutomaticGainControlV2Sw::kEffectName = "AutomaticGainControlV2Sw";
+
+const std::vector<Range::AutomaticGainControlV2Range> AutomaticGainControlV2Sw::kRanges = {
+        MAKE_RANGE(AutomaticGainControlV2, fixedDigitalGainMb, 0, 50000),
+        MAKE_RANGE(AutomaticGainControlV2, saturationMarginMb, 0, 10000)};
+
+const Capability AutomaticGainControlV2Sw::kCapability = {
+        .range = AutomaticGainControlV2Sw::kRanges};
+
+const Descriptor AutomaticGainControlV2Sw::kDescriptor = {
+        .common = {.id = {.type = getEffectTypeUuidAutomaticGainControlV2(),
+                          .uuid = getEffectImplUuidAutomaticGainControlV2Sw(),
+                          .proxy = std::nullopt},
+                   .flags = {.type = Flags::Type::INSERT,
+                             .insert = Flags::Insert::FIRST,
+                             .volume = Flags::Volume::CTRL},
+                   .name = AutomaticGainControlV2Sw::kEffectName,
+                   .implementor = "The Android Open Source Project"},
+        .capability = AutomaticGainControlV2Sw::kCapability};
+
+ndk::ScopedAStatus AutomaticGainControlV2Sw::getDescriptor(Descriptor* _aidl_return) {
+    LOG(DEBUG) << __func__ << kDescriptor.toString();
+    *_aidl_return = kDescriptor;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus AutomaticGainControlV2Sw::setParameterSpecific(
+        const Parameter::Specific& specific) {
+    RETURN_IF(Parameter::Specific::automaticGainControlV2 != specific.getTag(), EX_ILLEGAL_ARGUMENT,
+              "EffectNotSupported");
+    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+
+    auto& param = specific.get<Parameter::Specific::automaticGainControlV2>();
+    RETURN_IF(!inRange(param, kRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
+    auto tag = param.getTag();
+    switch (tag) {
+        case AutomaticGainControlV2::fixedDigitalGainMb: {
+            RETURN_IF(mContext->setDigitalGain(
+                              param.get<AutomaticGainControlV2::fixedDigitalGainMb>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "digitalGainNotSupported");
+            return ndk::ScopedAStatus::ok();
+        }
+        case AutomaticGainControlV2::levelEstimator: {
+            RETURN_IF(mContext->setLevelEstimator(
+                              param.get<AutomaticGainControlV2::levelEstimator>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "levelEstimatorNotSupported");
+            return ndk::ScopedAStatus::ok();
+        }
+        case AutomaticGainControlV2::saturationMarginMb: {
+            RETURN_IF(mContext->setSaturationMargin(
+                              param.get<AutomaticGainControlV2::saturationMarginMb>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "saturationMarginNotSupported");
+            return ndk::ScopedAStatus::ok();
+        }
+        default: {
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+                    EX_ILLEGAL_ARGUMENT, "AutomaticGainControlV2TagNotSupported");
+        }
+    }
+}
+
+ndk::ScopedAStatus AutomaticGainControlV2Sw::getParameterSpecific(const Parameter::Id& id,
+                                                                  Parameter::Specific* specific) {
+    auto tag = id.getTag();
+    RETURN_IF(Parameter::Id::automaticGainControlV2Tag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
+    auto specificId = id.get<Parameter::Id::automaticGainControlV2Tag>();
+    auto specificIdTag = specificId.getTag();
+    switch (specificIdTag) {
+        case AutomaticGainControlV2::Id::commonTag:
+            return getParameterAutomaticGainControlV2(
+                    specificId.get<AutomaticGainControlV2::Id::commonTag>(), specific);
+        default:
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+                    EX_ILLEGAL_ARGUMENT, "AutomaticGainControlV2TagNotSupported");
+    }
+}
+
+ndk::ScopedAStatus AutomaticGainControlV2Sw::getParameterAutomaticGainControlV2(
+        const AutomaticGainControlV2::Tag& tag, Parameter::Specific* specific) {
+    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+    AutomaticGainControlV2 param;
+    switch (tag) {
+        case AutomaticGainControlV2::fixedDigitalGainMb: {
+            param.set<AutomaticGainControlV2::fixedDigitalGainMb>(mContext->getDigitalGain());
+            break;
+        }
+        case AutomaticGainControlV2::levelEstimator: {
+            param.set<AutomaticGainControlV2::levelEstimator>(mContext->getLevelEstimator());
+            break;
+        }
+        case AutomaticGainControlV2::saturationMarginMb: {
+            param.set<AutomaticGainControlV2::saturationMarginMb>(mContext->getSaturationMargin());
+            break;
+        }
+        default: {
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+                    EX_ILLEGAL_ARGUMENT, "AutomaticGainControlV2TagNotSupported");
+        }
+    }
+
+    specific->set<Parameter::Specific::automaticGainControlV2>(param);
+    return ndk::ScopedAStatus::ok();
+}
+
+std::shared_ptr<EffectContext> AutomaticGainControlV2Sw::createContext(
+        const Parameter::Common& common) {
+    if (mContext) {
+        LOG(DEBUG) << __func__ << " context already exist";
+    } else {
+        mContext =
+                std::make_shared<AutomaticGainControlV2SwContext>(1 /* statusFmqDepth */, common);
+    }
+    return mContext;
+}
+
+std::shared_ptr<EffectContext> AutomaticGainControlV2Sw::getContext() {
+    return mContext;
+}
+
+RetCode AutomaticGainControlV2Sw::releaseContext() {
+    if (mContext) {
+        mContext.reset();
+    }
+    return RetCode::SUCCESS;
+}
+
+// Processing method running in EffectWorker thread.
+IEffect::Status AutomaticGainControlV2Sw::effectProcessImpl(float* in, float* out, int samples) {
+    // TODO: get data buffer and process.
+    LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
+    for (int i = 0; i < samples; i++) {
+        *out++ = *in++;
+    }
+    return {STATUS_OK, samples, samples};
+}
+
+RetCode AutomaticGainControlV2SwContext::setDigitalGain(int gain) {
+    mDigitalGain = gain;
+    return RetCode::SUCCESS;
+}
+
+int AutomaticGainControlV2SwContext::getDigitalGain() {
+    return mDigitalGain;
+}
+
+RetCode AutomaticGainControlV2SwContext::setLevelEstimator(
+        AutomaticGainControlV2::LevelEstimator levelEstimator) {
+    mLevelEstimator = levelEstimator;
+    return RetCode::SUCCESS;
+}
+
+AutomaticGainControlV2::LevelEstimator AutomaticGainControlV2SwContext::getLevelEstimator() {
+    return mLevelEstimator;
+}
+
+RetCode AutomaticGainControlV2SwContext::setSaturationMargin(int margin) {
+    mSaturationMargin = margin;
+    return RetCode::SUCCESS;
+}
+
+int AutomaticGainControlV2SwContext::getSaturationMargin() {
+    return mSaturationMargin;
+}
+
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/automaticGainControl/AutomaticGainControlSw.h b/audio/aidl/default/automaticGainControlV2/AutomaticGainControlV2Sw.h
similarity index 68%
rename from audio/aidl/default/automaticGainControl/AutomaticGainControlSw.h
rename to audio/aidl/default/automaticGainControlV2/AutomaticGainControlV2Sw.h
index 2724835..9aa60ea 100644
--- a/audio/aidl/default/automaticGainControl/AutomaticGainControlSw.h
+++ b/audio/aidl/default/automaticGainControlV2/AutomaticGainControlV2Sw.h
@@ -22,39 +22,38 @@
 #include <memory>
 
 #include "effect-impl/EffectImpl.h"
-#include "effect-impl/EffectUUID.h"
 
 namespace aidl::android::hardware::audio::effect {
 
-class AutomaticGainControlSwContext final : public EffectContext {
+class AutomaticGainControlV2SwContext final : public EffectContext {
   public:
-    AutomaticGainControlSwContext(int statusDepth, const Parameter::Common& common)
+    AutomaticGainControlV2SwContext(int statusDepth, const Parameter::Common& common)
         : EffectContext(statusDepth, common) {
         LOG(DEBUG) << __func__;
     }
 
     RetCode setDigitalGain(int gain);
     int getDigitalGain();
-    RetCode setLevelEstimator(AutomaticGainControl::LevelEstimator levelEstimator);
-    AutomaticGainControl::LevelEstimator getLevelEstimator();
+    RetCode setLevelEstimator(AutomaticGainControlV2::LevelEstimator levelEstimator);
+    AutomaticGainControlV2::LevelEstimator getLevelEstimator();
     RetCode setSaturationMargin(int margin);
     int getSaturationMargin();
 
   private:
     int mDigitalGain = 0;
-    AutomaticGainControl::LevelEstimator mLevelEstimator =
-            AutomaticGainControl::LevelEstimator::RMS;
+    AutomaticGainControlV2::LevelEstimator mLevelEstimator =
+            AutomaticGainControlV2::LevelEstimator::RMS;
     int mSaturationMargin = 0;
 };
 
-class AutomaticGainControlSw final : public EffectImpl {
+class AutomaticGainControlV2Sw final : public EffectImpl {
   public:
     static const std::string kEffectName;
     static const bool kStrengthSupported;
-    static const AutomaticGainControl::Capability kCapability;
+    static const Capability kCapability;
     static const Descriptor kDescriptor;
-    AutomaticGainControlSw() { LOG(DEBUG) << __func__; }
-    ~AutomaticGainControlSw() {
+    AutomaticGainControlV2Sw() { LOG(DEBUG) << __func__; }
+    ~AutomaticGainControlV2Sw() {
         cleanUp();
         LOG(DEBUG) << __func__;
     }
@@ -72,8 +71,9 @@
     IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
 
   private:
-    std::shared_ptr<AutomaticGainControlSwContext> mContext;
-    ndk::ScopedAStatus getParameterAutomaticGainControl(const AutomaticGainControl::Tag& tag,
-                                                        Parameter::Specific* specific);
+    static const std::vector<Range::AutomaticGainControlV2Range> kRanges;
+    std::shared_ptr<AutomaticGainControlV2SwContext> mContext;
+    ndk::ScopedAStatus getParameterAutomaticGainControlV2(const AutomaticGainControlV2::Tag& tag,
+                                                          Parameter::Specific* specific);
 };
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/bassboost/BassBoostSw.cpp b/audio/aidl/default/bassboost/BassBoostSw.cpp
index 0c7ebe1..dbf2e15 100644
--- a/audio/aidl/default/bassboost/BassBoostSw.cpp
+++ b/audio/aidl/default/bassboost/BassBoostSw.cpp
@@ -17,25 +17,26 @@
 #include <algorithm>
 #include <cstddef>
 #include <memory>
-#define LOG_TAG "AHAL_BassBoostSw"
-#include <Utils.h>
-#include <unordered_set>
 
+#define LOG_TAG "AHAL_BassBoostSw"
 #include <android-base/logging.h>
 #include <fmq/AidlMessageQueue.h>
+#include <system/audio_effects/effect_uuid.h>
 
 #include "BassBoostSw.h"
 
 using aidl::android::hardware::audio::effect::BassBoostSw;
 using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectImplUuidBassBoostProxy;
+using aidl::android::hardware::audio::effect::getEffectImplUuidBassBoostSw;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidBassBoost;
 using aidl::android::hardware::audio::effect::IEffect;
-using aidl::android::hardware::audio::effect::kBassBoostSwImplUUID;
 using aidl::android::hardware::audio::effect::State;
 using aidl::android::media::audio::common::AudioUuid;
 
 extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
                                            std::shared_ptr<IEffect>* instanceSpp) {
-    if (!in_impl_uuid || *in_impl_uuid != kBassBoostSwImplUUID) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidBassBoostSw()) {
         LOG(ERROR) << __func__ << "uuid not supported";
         return EX_ILLEGAL_ARGUMENT;
     }
@@ -50,7 +51,7 @@
 }
 
 extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
-    if (!in_impl_uuid || *in_impl_uuid != kBassBoostSwImplUUID) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidBassBoostSw()) {
         LOG(ERROR) << __func__ << "uuid not supported";
         return EX_ILLEGAL_ARGUMENT;
     }
@@ -61,19 +62,20 @@
 namespace aidl::android::hardware::audio::effect {
 
 const std::string BassBoostSw::kEffectName = "BassBoostSw";
-const bool BassBoostSw::kStrengthSupported = true;
-const BassBoost::Capability BassBoostSw::kCapability = {.maxStrengthPm = 1000,
-                                                        .strengthSupported = kStrengthSupported};
+
+const std::vector<Range::BassBoostRange> BassBoostSw::kRanges = {
+        MAKE_RANGE(BassBoost, strengthPm, 0, 1000)};
+const Capability BassBoostSw::kCapability = {.range = {BassBoostSw::kRanges}};
 const Descriptor BassBoostSw::kDescriptor = {
-        .common = {.id = {.type = kBassBoostTypeUUID,
-                          .uuid = kBassBoostSwImplUUID,
-                          .proxy = kBassBoostProxyUUID},
+        .common = {.id = {.type = getEffectTypeUuidBassBoost(),
+                          .uuid = getEffectImplUuidBassBoostSw(),
+                          .proxy = getEffectImplUuidBassBoostProxy()},
                    .flags = {.type = Flags::Type::INSERT,
                              .insert = Flags::Insert::FIRST,
                              .volume = Flags::Volume::CTRL},
                    .name = BassBoostSw::kEffectName,
                    .implementor = "The Android Open Source Project"},
-        .capability = Capability::make<Capability::bassBoost>(BassBoostSw::kCapability)};
+        .capability = BassBoostSw::kCapability};
 
 ndk::ScopedAStatus BassBoostSw::getDescriptor(Descriptor* _aidl_return) {
     LOG(DEBUG) << __func__ << kDescriptor.toString();
@@ -87,15 +89,14 @@
     RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
 
     auto& bbParam = specific.get<Parameter::Specific::bassBoost>();
+    RETURN_IF(!inRange(bbParam, kRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
     auto tag = bbParam.getTag();
 
     switch (tag) {
         case BassBoost::strengthPm: {
-            RETURN_IF(!kStrengthSupported, EX_ILLEGAL_ARGUMENT, "SettingStrengthNotSupported");
-
-            RETURN_IF(mContext->setBbStrengthPm(bbParam.get<BassBoost::strengthPm>()) !=
-                              RetCode::SUCCESS,
-                      EX_ILLEGAL_ARGUMENT, "strengthPmNotSupported");
+            const auto strength = bbParam.get<BassBoost::strengthPm>();
+            RETURN_IF(mContext->setBbStrengthPm(strength) != RetCode::SUCCESS, EX_ILLEGAL_ARGUMENT,
+                      "strengthPmNotSupported");
             return ndk::ScopedAStatus::ok();
         }
         default: {
@@ -173,11 +174,6 @@
 }
 
 RetCode BassBoostSwContext::setBbStrengthPm(int strength) {
-    if (strength < 0 || strength > BassBoostSw::kCapability.maxStrengthPm) {
-        LOG(ERROR) << __func__ << " invalid strength: " << strength;
-        return RetCode::ERROR_ILLEGAL_PARAMETER;
-    }
-    // TODO : Add implementation to apply new strength
     mStrength = strength;
     return RetCode::SUCCESS;
 }
diff --git a/audio/aidl/default/bassboost/BassBoostSw.h b/audio/aidl/default/bassboost/BassBoostSw.h
index 65c01c8..1132472 100644
--- a/audio/aidl/default/bassboost/BassBoostSw.h
+++ b/audio/aidl/default/bassboost/BassBoostSw.h
@@ -22,7 +22,6 @@
 #include <memory>
 
 #include "effect-impl/EffectImpl.h"
-#include "effect-impl/EffectUUID.h"
 
 namespace aidl::android::hardware::audio::effect {
 
@@ -43,8 +42,7 @@
 class BassBoostSw final : public EffectImpl {
   public:
     static const std::string kEffectName;
-    static const bool kStrengthSupported;
-    static const BassBoost::Capability kCapability;
+    static const Capability kCapability;
     static const Descriptor kDescriptor;
     BassBoostSw() { LOG(DEBUG) << __func__; }
     ~BassBoostSw() {
@@ -65,6 +63,7 @@
     IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
 
   private:
+    static const std::vector<Range::BassBoostRange> kRanges;
     std::shared_ptr<BassBoostSwContext> mContext;
     ndk::ScopedAStatus getParameterBassBoost(const BassBoost::Tag& tag,
                                              Parameter::Specific* specific);
diff --git a/audio/aidl/default/downmix/DownmixSw.cpp b/audio/aidl/default/downmix/DownmixSw.cpp
index 7bb958d..ce5fe20 100644
--- a/audio/aidl/default/downmix/DownmixSw.cpp
+++ b/audio/aidl/default/downmix/DownmixSw.cpp
@@ -14,27 +14,27 @@
  * limitations under the License.
  */
 
-#include <cstddef>
-#define LOG_TAG "AHAL_DownmixSw"
-#include <Utils.h>
 #include <algorithm>
-#include <unordered_set>
+#include <cstddef>
 
+#define LOG_TAG "AHAL_DownmixSw"
 #include <android-base/logging.h>
 #include <fmq/AidlMessageQueue.h>
+#include <system/audio_effects/effect_uuid.h>
 
 #include "DownmixSw.h"
 
 using aidl::android::hardware::audio::effect::Descriptor;
 using aidl::android::hardware::audio::effect::DownmixSw;
+using aidl::android::hardware::audio::effect::getEffectImplUuidDownmixSw;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidDownmix;
 using aidl::android::hardware::audio::effect::IEffect;
-using aidl::android::hardware::audio::effect::kDownmixSwImplUUID;
 using aidl::android::hardware::audio::effect::State;
 using aidl::android::media::audio::common::AudioUuid;
 
 extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
                                            std::shared_ptr<IEffect>* instanceSpp) {
-    if (!in_impl_uuid || *in_impl_uuid != kDownmixSwImplUUID) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidDownmixSw()) {
         LOG(ERROR) << __func__ << "uuid not supported";
         return EX_ILLEGAL_ARGUMENT;
     }
@@ -49,7 +49,7 @@
 }
 
 extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
-    if (!in_impl_uuid || *in_impl_uuid != kDownmixSwImplUUID) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidDownmixSw()) {
         LOG(ERROR) << __func__ << "uuid not supported";
         return EX_ILLEGAL_ARGUMENT;
     }
@@ -60,17 +60,15 @@
 namespace aidl::android::hardware::audio::effect {
 
 const std::string DownmixSw::kEffectName = "DownmixSw";
-const Downmix::Capability DownmixSw::kCapability;
 const Descriptor DownmixSw::kDescriptor = {
-        .common = {.id = {.type = kDownmixTypeUUID,
-                          .uuid = kDownmixSwImplUUID,
+        .common = {.id = {.type = getEffectTypeUuidDownmix(),
+                          .uuid = getEffectImplUuidDownmixSw(),
                           .proxy = std::nullopt},
                    .flags = {.type = Flags::Type::INSERT,
                              .insert = Flags::Insert::FIRST,
                              .volume = Flags::Volume::CTRL},
                    .name = kEffectName,
-                   .implementor = "The Android Open Source Project"},
-        .capability = Capability::make<Capability::downmix>(kCapability)};
+                   .implementor = "The Android Open Source Project"}};
 
 ndk::ScopedAStatus DownmixSw::getDescriptor(Descriptor* _aidl_return) {
     LOG(DEBUG) << __func__ << kDescriptor.toString();
diff --git a/audio/aidl/default/downmix/DownmixSw.h b/audio/aidl/default/downmix/DownmixSw.h
index 51546c1..3f8a09b 100644
--- a/audio/aidl/default/downmix/DownmixSw.h
+++ b/audio/aidl/default/downmix/DownmixSw.h
@@ -22,7 +22,6 @@
 #include <memory>
 
 #include "effect-impl/EffectImpl.h"
-#include "effect-impl/EffectUUID.h"
 
 namespace aidl::android::hardware::audio::effect {
 
@@ -47,7 +46,7 @@
 class DownmixSw final : public EffectImpl {
   public:
     static const std::string kEffectName;
-    static const Downmix::Capability kCapability;
+    static const Capability kCapability;
     static const Descriptor kDescriptor;
     DownmixSw() { LOG(DEBUG) << __func__; }
     ~DownmixSw() {
diff --git a/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.cpp b/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.cpp
index 0ffbaa1..ed6cfa0 100644
--- a/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.cpp
+++ b/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.cpp
@@ -14,28 +14,29 @@
  * limitations under the License.
  */
 
-#include <cstddef>
-#define LOG_TAG "AHAL_DynamicsProcessingSw"
-#include <Utils.h>
 #include <algorithm>
+#include <cstddef>
 #include <set>
 #include <unordered_set>
 
+#define LOG_TAG "AHAL_DynamicsProcessingSw"
 #include <android-base/logging.h>
 #include <fmq/AidlMessageQueue.h>
+#include <system/audio_effects/effect_uuid.h>
 
 #include "DynamicsProcessingSw.h"
 
 using aidl::android::hardware::audio::effect::Descriptor;
 using aidl::android::hardware::audio::effect::DynamicsProcessingSw;
+using aidl::android::hardware::audio::effect::getEffectImplUuidDynamicsProcessingSw;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidDynamicsProcessing;
 using aidl::android::hardware::audio::effect::IEffect;
-using aidl::android::hardware::audio::effect::kDynamicsProcessingSwImplUUID;
 using aidl::android::hardware::audio::effect::State;
 using aidl::android::media::audio::common::AudioUuid;
 
 extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
                                            std::shared_ptr<IEffect>* instanceSpp) {
-    if (!in_impl_uuid || *in_impl_uuid != kDynamicsProcessingSwImplUUID) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidDynamicsProcessingSw()) {
         LOG(ERROR) << __func__ << "uuid not supported";
         return EX_ILLEGAL_ARGUMENT;
     }
@@ -50,7 +51,7 @@
 }
 
 extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
-    if (!in_impl_uuid || *in_impl_uuid != kDynamicsProcessingSwImplUUID) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidDynamicsProcessingSw()) {
         LOG(ERROR) << __func__ << "uuid not supported";
         return EX_ILLEGAL_ARGUMENT;
     }
@@ -61,19 +62,43 @@
 namespace aidl::android::hardware::audio::effect {
 
 const std::string DynamicsProcessingSw::kEffectName = "DynamicsProcessingSw";
-const DynamicsProcessing::Capability DynamicsProcessingSw::kCapability = {.minCutOffFreq = 220,
-                                                                          .maxCutOffFreq = 20000};
+const DynamicsProcessing::EqBandConfig DynamicsProcessingSw::kEqBandConfigMin =
+        DynamicsProcessing::EqBandConfig({.channel = 0,
+                                          .band = 0,
+                                          .enable = false,
+                                          .cutoffFrequencyHz = 220,
+                                          .gainDb = std::numeric_limits<float>::min()});
+const DynamicsProcessing::EqBandConfig DynamicsProcessingSw::kEqBandConfigMax =
+        DynamicsProcessing::EqBandConfig({.channel = std::numeric_limits<int>::max(),
+                                          .band = std::numeric_limits<int>::max(),
+                                          .enable = true,
+                                          .cutoffFrequencyHz = 20000,
+                                          .gainDb = std::numeric_limits<float>::max()});
+const Range::DynamicsProcessingRange DynamicsProcessingSw::kPreEqBandRange = {
+        .min = DynamicsProcessing::make<DynamicsProcessing::preEqBand>(
+                {DynamicsProcessingSw::kEqBandConfigMin}),
+        .max = DynamicsProcessing::make<DynamicsProcessing::preEqBand>(
+                {DynamicsProcessingSw::kEqBandConfigMax})};
+const Range::DynamicsProcessingRange DynamicsProcessingSw::kPostEqBandRange = {
+        .min = DynamicsProcessing::make<DynamicsProcessing::postEqBand>(
+                {DynamicsProcessingSw::kEqBandConfigMin}),
+        .max = DynamicsProcessing::make<DynamicsProcessing::postEqBand>(
+                {DynamicsProcessingSw::kEqBandConfigMax})};
+
+const std::vector<Range::DynamicsProcessingRange> DynamicsProcessingSw::kRanges = {
+        DynamicsProcessingSw::kPreEqBandRange, DynamicsProcessingSw::kPostEqBandRange};
+const Capability DynamicsProcessingSw::kCapability = {.range = DynamicsProcessingSw::kRanges};
+
 const Descriptor DynamicsProcessingSw::kDescriptor = {
-        .common = {.id = {.type = kDynamicsProcessingTypeUUID,
-                          .uuid = kDynamicsProcessingSwImplUUID,
+        .common = {.id = {.type = getEffectTypeUuidDynamicsProcessing(),
+                          .uuid = getEffectImplUuidDynamicsProcessingSw(),
                           .proxy = std::nullopt},
                    .flags = {.type = Flags::Type::INSERT,
                              .insert = Flags::Insert::FIRST,
                              .volume = Flags::Volume::CTRL},
                    .name = DynamicsProcessingSw::kEffectName,
                    .implementor = "The Android Open Source Project"},
-        .capability = Capability::make<Capability::dynamicsProcessing>(
-                DynamicsProcessingSw::kCapability)};
+        .capability = DynamicsProcessingSw::kCapability};
 
 ndk::ScopedAStatus DynamicsProcessingSw::getDescriptor(Descriptor* _aidl_return) {
     LOG(DEBUG) << __func__ << kDescriptor.toString();
@@ -146,7 +171,7 @@
                       EX_ILLEGAL_ARGUMENT, "inputGainCfgFailed");
             return ndk::ScopedAStatus::ok();
         }
-        case DynamicsProcessing::vendorExtension: {
+        case DynamicsProcessing::vendor: {
             LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
             return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
                     EX_ILLEGAL_ARGUMENT, "DynamicsProcessingTagNotSupported");
@@ -213,7 +238,7 @@
             dpParam.set<DynamicsProcessing::inputGain>(mContext->getInputGainCfgs());
             break;
         }
-        case DynamicsProcessing::vendorExtension: {
+        case DynamicsProcessing::vendor: {
             LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
             return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
                     EX_ILLEGAL_ARGUMENT, "DynamicsProcessingTagNotSupported");
@@ -258,8 +283,8 @@
 
 RetCode DynamicsProcessingSwContext::setCommon(const Parameter::Common& common) {
     mCommon = common;
-    mChannelCount =
-            ::android::hardware::audio::common::getChannelCount(common.input.base.channelMask);
+    mChannelCount = ::aidl::android::hardware::audio::common::getChannelCount(
+            common.input.base.channelMask);
     resizeChannels();
     resizeBands();
     LOG(INFO) << __func__ << mCommon.toString();
@@ -341,7 +366,6 @@
             LOG(WARNING) << __func__ << " skip invalid band " << cfg.toString();
             ret = RetCode::ERROR_ILLEGAL_PARAMETER;
             continue;
-            ;
         }
         targetCfgs[cfg.channel * stage.bandCount + cfg.band] = cfg;
     }
@@ -380,7 +404,6 @@
             LOG(WARNING) << __func__ << " skip invalid band " << it.toString();
             ret = RetCode::ERROR_ILLEGAL_PARAMETER;
             continue;
-            ;
         }
         mMbcChBands[it.channel * bandCount + it.band] = it;
     }
@@ -462,11 +485,6 @@
     return ret;
 }
 
-bool DynamicsProcessingSwContext::validateCutoffFrequency(float freq) {
-    return freq >= DynamicsProcessingSw::kCapability.minCutOffFreq &&
-           freq <= DynamicsProcessingSw::kCapability.maxCutOffFreq;
-}
-
 bool DynamicsProcessingSwContext::validateStageEnablement(
         const DynamicsProcessing::StageEnablement& enablement) {
     return !enablement.inUse || (enablement.inUse && enablement.bandCount > 0);
@@ -484,7 +502,7 @@
         const std::vector<DynamicsProcessing::ChannelConfig>& channelConfig) {
     return band.channel >= 0 && band.channel < maxChannel &&
            (size_t)band.channel < channelConfig.size() && channelConfig[band.channel].enable &&
-           band.band >= 0 && band.band < maxBand && validateCutoffFrequency(band.cutoffFrequencyHz);
+           band.band >= 0 && band.band < maxBand;
 }
 
 bool DynamicsProcessingSwContext::validateMbcBandConfig(
@@ -492,8 +510,7 @@
         const std::vector<DynamicsProcessing::ChannelConfig>& channelConfig) {
     return band.channel >= 0 && band.channel < maxChannel &&
            (size_t)band.channel < channelConfig.size() && channelConfig[band.channel].enable &&
-           band.band >= 0 && band.band < maxBand &&
-           validateCutoffFrequency(band.cutoffFrequencyHz) && band.attackTimeMs >= 0 &&
+           band.band >= 0 && band.band < maxBand && band.attackTimeMs >= 0 &&
            band.releaseTimeMs >= 0 && band.ratio >= 0 && band.thresholdDb <= 0 &&
            band.kneeWidthDb <= 0 && band.noiseGateThresholdDb <= 0 && band.expanderRatio >= 0;
 }
diff --git a/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.h b/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.h
index e336df7..641cf71 100644
--- a/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.h
+++ b/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.h
@@ -16,13 +16,15 @@
 
 #pragma once
 
-#include <aidl/android/hardware/audio/effect/BnEffect.h>
-#include <fmq/AidlMessageQueue.h>
 #include <cstdlib>
 #include <memory>
+#include <vector>
+
+#include <Utils.h>
+#include <aidl/android/hardware/audio/effect/BnEffect.h>
+#include <fmq/AidlMessageQueue.h>
 
 #include "effect-impl/EffectImpl.h"
-#include "effect-impl/EffectUUID.h"
 
 namespace aidl::android::hardware::audio::effect {
 
@@ -30,7 +32,7 @@
   public:
     DynamicsProcessingSwContext(int statusDepth, const Parameter::Common& common)
         : EffectContext(statusDepth, common),
-          mChannelCount(::android::hardware::audio::common::getChannelCount(
+          mChannelCount(::aidl::android::hardware::audio::common::getChannelCount(
                   common.input.base.channelMask)),
           mPreEqChCfgs(mChannelCount, {.channel = kInvalidChannelId}),
           mPostEqChCfgs(mChannelCount, {.channel = kInvalidChannelId}),
@@ -86,8 +88,6 @@
     std::vector<DynamicsProcessing::EqBandConfig> mPreEqChBands;
     std::vector<DynamicsProcessing::EqBandConfig> mPostEqChBands;
     std::vector<DynamicsProcessing::MbcBandConfig> mMbcChBands;
-
-    bool validateCutoffFrequency(float freq);
     bool validateStageEnablement(const DynamicsProcessing::StageEnablement& enablement);
     bool validateEngineConfig(const DynamicsProcessing::EngineArchitecture& engine);
     bool validateEqBandConfig(const DynamicsProcessing::EqBandConfig& band, int maxChannel,
@@ -104,7 +104,7 @@
 class DynamicsProcessingSw final : public EffectImpl {
   public:
     static const std::string kEffectName;
-    static const DynamicsProcessing::Capability kCapability;
+    static const Capability kCapability;
     static const Descriptor kDescriptor;
     DynamicsProcessingSw() { LOG(DEBUG) << __func__; }
     ~DynamicsProcessingSw() {
@@ -125,6 +125,11 @@
     std::string getEffectName() override { return kEffectName; };
 
   private:
+    static const DynamicsProcessing::EqBandConfig kEqBandConfigMin;
+    static const DynamicsProcessing::EqBandConfig kEqBandConfigMax;
+    static const Range::DynamicsProcessingRange kPreEqBandRange;
+    static const Range::DynamicsProcessingRange kPostEqBandRange;
+    static const std::vector<Range::DynamicsProcessingRange> kRanges;
     std::shared_ptr<DynamicsProcessingSwContext> mContext;
     ndk::ScopedAStatus getParameterDynamicsProcessing(const DynamicsProcessing::Tag& tag,
                                                       Parameter::Specific* specific);
diff --git a/audio/aidl/default/envReverb/EnvReverbSw.cpp b/audio/aidl/default/envReverb/EnvReverbSw.cpp
index 905dba4..73975c6 100644
--- a/audio/aidl/default/envReverb/EnvReverbSw.cpp
+++ b/audio/aidl/default/envReverb/EnvReverbSw.cpp
@@ -14,27 +14,28 @@
  * limitations under the License.
  */
 
-#include <cstddef>
-#define LOG_TAG "AHAL_EnvReverbSw"
-#include <Utils.h>
 #include <algorithm>
+#include <cstddef>
 #include <unordered_set>
 
+#define LOG_TAG "AHAL_EnvReverbSw"
 #include <android-base/logging.h>
 #include <fmq/AidlMessageQueue.h>
+#include <system/audio_effects/effect_uuid.h>
 
 #include "EnvReverbSw.h"
 
 using aidl::android::hardware::audio::effect::Descriptor;
 using aidl::android::hardware::audio::effect::EnvReverbSw;
+using aidl::android::hardware::audio::effect::getEffectImplUuidEnvReverbSw;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidEnvReverb;
 using aidl::android::hardware::audio::effect::IEffect;
-using aidl::android::hardware::audio::effect::kEnvReverbSwImplUUID;
 using aidl::android::hardware::audio::effect::State;
 using aidl::android::media::audio::common::AudioUuid;
 
 extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
                                            std::shared_ptr<IEffect>* instanceSpp) {
-    if (!in_impl_uuid || *in_impl_uuid != kEnvReverbSwImplUUID) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidEnvReverbSw()) {
         LOG(ERROR) << __func__ << "uuid not supported";
         return EX_ILLEGAL_ARGUMENT;
     }
@@ -49,7 +50,7 @@
 }
 
 extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
-    if (!in_impl_uuid || *in_impl_uuid != kEnvReverbSwImplUUID) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidEnvReverbSw()) {
         LOG(ERROR) << __func__ << "uuid not supported";
         return EX_ILLEGAL_ARGUMENT;
     }
@@ -60,28 +61,32 @@
 namespace aidl::android::hardware::audio::effect {
 
 const std::string EnvReverbSw::kEffectName = "EnvReverbSw";
-const EnvironmentalReverb::Capability EnvReverbSw::kCapability = {.minRoomLevelMb = -6000,
-                                                                  .maxRoomLevelMb = 0,
-                                                                  .minRoomHfLevelMb = -4000,
-                                                                  .maxRoomHfLevelMb = 0,
-                                                                  .maxDecayTimeMs = 7000,
-                                                                  .minDecayHfRatioPm = 100,
-                                                                  .maxDecayHfRatioPm = 2000,
-                                                                  .minLevelMb = -6000,
-                                                                  .maxLevelMb = 0,
-                                                                  .maxDelayMs = 65,
-                                                                  .maxDiffusionPm = 1000,
-                                                                  .maxDensityPm = 1000};
+
+const std::vector<Range::EnvironmentalReverbRange> EnvReverbSw::kRanges = {
+        MAKE_RANGE(EnvironmentalReverb, roomLevelMb, -6000, 0),
+        MAKE_RANGE(EnvironmentalReverb, roomHfLevelMb, -4000, 0),
+        MAKE_RANGE(EnvironmentalReverb, decayTimeMs, 0, 7000),
+        MAKE_RANGE(EnvironmentalReverb, decayHfRatioPm, 100, 2000),
+        MAKE_RANGE(EnvironmentalReverb, reflectionsLevelMb, -6000, 0),
+        MAKE_RANGE(EnvironmentalReverb, reflectionsDelayMs, 0, 65),
+        MAKE_RANGE(EnvironmentalReverb, levelMb, -6000, 0),
+        MAKE_RANGE(EnvironmentalReverb, delayMs, 0, 65),
+        MAKE_RANGE(EnvironmentalReverb, diffusionPm, 0, 1000),
+        MAKE_RANGE(EnvironmentalReverb, densityPm, 0, 1000)};
+
+const Capability EnvReverbSw::kCapability = {
+        .range = Range::make<Range::environmentalReverb>(EnvReverbSw::kRanges)};
+
 const Descriptor EnvReverbSw::kDescriptor = {
-        .common = {.id = {.type = kEnvReverbTypeUUID,
-                          .uuid = kEnvReverbSwImplUUID,
+        .common = {.id = {.type = getEffectTypeUuidEnvReverb(),
+                          .uuid = getEffectImplUuidEnvReverbSw(),
                           .proxy = std::nullopt},
                    .flags = {.type = Flags::Type::INSERT,
                              .insert = Flags::Insert::FIRST,
                              .volume = Flags::Volume::CTRL},
                    .name = EnvReverbSw::kEffectName,
                    .implementor = "The Android Open Source Project"},
-        .capability = Capability::make<Capability::environmentalReverb>(EnvReverbSw::kCapability)};
+        .capability = EnvReverbSw::kCapability};
 
 ndk::ScopedAStatus EnvReverbSw::getDescriptor(Descriptor* _aidl_return) {
     LOG(DEBUG) << __func__ << kDescriptor.toString();
@@ -94,8 +99,8 @@
               "EffectNotSupported");
 
     auto& erParam = specific.get<Parameter::Specific::environmentalReverb>();
+    RETURN_IF(!inRange(erParam, kRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
     auto tag = erParam.getTag();
-
     switch (tag) {
         case EnvironmentalReverb::roomLevelMb: {
             RETURN_IF(mContext->setErRoomLevel(erParam.get<EnvironmentalReverb::roomLevelMb>()) !=
@@ -123,6 +128,20 @@
                     EX_ILLEGAL_ARGUMENT, "setDecayHfRatioFailed");
             return ndk::ScopedAStatus::ok();
         }
+        case EnvironmentalReverb::reflectionsLevelMb: {
+            RETURN_IF(mContext->setErReflectionsLevel(
+                              erParam.get<EnvironmentalReverb::reflectionsLevelMb>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setReflectionsLevelFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        case EnvironmentalReverb::reflectionsDelayMs: {
+            RETURN_IF(mContext->setErReflectionsDelay(
+                              erParam.get<EnvironmentalReverb::reflectionsDelayMs>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setReflectionsDelayFailed");
+            return ndk::ScopedAStatus::ok();
+        }
         case EnvironmentalReverb::levelMb: {
             RETURN_IF(mContext->setErLevel(erParam.get<EnvironmentalReverb::levelMb>()) !=
                               RetCode::SUCCESS,
@@ -199,6 +218,14 @@
             erParam.set<EnvironmentalReverb::decayHfRatioPm>(mContext->getErDecayHfRatio());
             break;
         }
+        case EnvironmentalReverb::reflectionsLevelMb: {
+            erParam.set<EnvironmentalReverb::reflectionsLevelMb>(mContext->getErReflectionsLevel());
+            break;
+        }
+        case EnvironmentalReverb::reflectionsDelayMs: {
+            erParam.set<EnvironmentalReverb::reflectionsDelayMs>(mContext->getErReflectionsDelay());
+            break;
+        }
         case EnvironmentalReverb::levelMb: {
             erParam.set<EnvironmentalReverb::levelMb>(mContext->getErLevel());
             break;
@@ -262,85 +289,41 @@
 }
 
 RetCode EnvReverbSwContext::setErRoomLevel(int roomLevel) {
-    if (roomLevel < EnvReverbSw::kCapability.minRoomLevelMb ||
-        roomLevel > EnvReverbSw::kCapability.maxRoomLevelMb) {
-        LOG(ERROR) << __func__ << " invalid roomLevel: " << roomLevel;
-        return RetCode::ERROR_ILLEGAL_PARAMETER;
-    }
-    // TODO : Add implementation to apply new room level
     mRoomLevel = roomLevel;
     return RetCode::SUCCESS;
 }
 
 RetCode EnvReverbSwContext::setErRoomHfLevel(int roomHfLevel) {
-    if (roomHfLevel < EnvReverbSw::kCapability.minRoomHfLevelMb ||
-        roomHfLevel > EnvReverbSw::kCapability.maxRoomHfLevelMb) {
-        LOG(ERROR) << __func__ << " invalid roomHfLevel: " << roomHfLevel;
-        return RetCode::ERROR_ILLEGAL_PARAMETER;
-    }
-    // TODO : Add implementation to apply new room HF level
     mRoomHfLevel = roomHfLevel;
     return RetCode::SUCCESS;
 }
 
 RetCode EnvReverbSwContext::setErDecayTime(int decayTime) {
-    if (decayTime < 0 || decayTime > EnvReverbSw::kCapability.maxDecayTimeMs) {
-        LOG(ERROR) << __func__ << " invalid decayTime: " << decayTime;
-        return RetCode::ERROR_ILLEGAL_PARAMETER;
-    }
-    // TODO : Add implementation to apply new decay time
     mDecayTime = decayTime;
     return RetCode::SUCCESS;
 }
 
 RetCode EnvReverbSwContext::setErDecayHfRatio(int decayHfRatio) {
-    if (decayHfRatio < EnvReverbSw::kCapability.minDecayHfRatioPm ||
-        decayHfRatio > EnvReverbSw::kCapability.maxDecayHfRatioPm) {
-        LOG(ERROR) << __func__ << " invalid decayHfRatio: " << decayHfRatio;
-        return RetCode::ERROR_ILLEGAL_PARAMETER;
-    }
-    // TODO : Add implementation to apply new decay HF ratio
     mDecayHfRatio = decayHfRatio;
     return RetCode::SUCCESS;
 }
 
 RetCode EnvReverbSwContext::setErLevel(int level) {
-    if (level < EnvReverbSw::kCapability.minLevelMb ||
-        level > EnvReverbSw::kCapability.maxLevelMb) {
-        LOG(ERROR) << __func__ << " invalid level: " << level;
-        return RetCode::ERROR_ILLEGAL_PARAMETER;
-    }
-    // TODO : Add implementation to apply new level
     mLevel = level;
     return RetCode::SUCCESS;
 }
 
 RetCode EnvReverbSwContext::setErDelay(int delay) {
-    if (delay < 0 || delay > EnvReverbSw::kCapability.maxDelayMs) {
-        LOG(ERROR) << __func__ << " invalid delay: " << delay;
-        return RetCode::ERROR_ILLEGAL_PARAMETER;
-    }
-    // TODO : Add implementation to apply new delay
     mDelay = delay;
     return RetCode::SUCCESS;
 }
 
 RetCode EnvReverbSwContext::setErDiffusion(int diffusion) {
-    if (diffusion < 0 || diffusion > EnvReverbSw::kCapability.maxDiffusionPm) {
-        LOG(ERROR) << __func__ << " invalid diffusion: " << diffusion;
-        return RetCode::ERROR_ILLEGAL_PARAMETER;
-    }
-    // TODO : Add implementation to apply new diffusion
     mDiffusion = diffusion;
     return RetCode::SUCCESS;
 }
 
 RetCode EnvReverbSwContext::setErDensity(int density) {
-    if (density < 0 || density > EnvReverbSw::kCapability.maxDensityPm) {
-        LOG(ERROR) << __func__ << " invalid density: " << density;
-        return RetCode::ERROR_ILLEGAL_PARAMETER;
-    }
-    // TODO : Add implementation to apply new density
     mDensity = density;
     return RetCode::SUCCESS;
 }
diff --git a/audio/aidl/default/envReverb/EnvReverbSw.h b/audio/aidl/default/envReverb/EnvReverbSw.h
index 77f384e..5e31e2f 100644
--- a/audio/aidl/default/envReverb/EnvReverbSw.h
+++ b/audio/aidl/default/envReverb/EnvReverbSw.h
@@ -22,7 +22,6 @@
 #include <memory>
 
 #include "effect-impl/EffectImpl.h"
-#include "effect-impl/EffectUUID.h"
 
 namespace aidl::android::hardware::audio::effect {
 
@@ -58,12 +57,23 @@
     int getErDensity() const { return mDensity; }
 
     RetCode setErBypass(bool bypass) {
-        // TODO : Add implementation to apply new bypass
         mBypass = bypass;
         return RetCode::SUCCESS;
     }
     bool getErBypass() const { return mBypass; }
 
+    RetCode setErReflectionsDelay(int delay) {
+        mReflectionsDelayMs = delay;
+        return RetCode::SUCCESS;
+    }
+    bool getErReflectionsDelay() const { return mReflectionsDelayMs; }
+
+    RetCode setErReflectionsLevel(int level) {
+        mReflectionsLevelMb = level;
+        return RetCode::SUCCESS;
+    }
+    bool getErReflectionsLevel() const { return mReflectionsLevelMb; }
+
   private:
     int mRoomLevel = -6000;                                        // Default room level
     int mRoomHfLevel = 0;                                          // Default room hf level
@@ -71,6 +81,8 @@
     int mDecayHfRatio = 500;                                       // Default decay hf ratio
     int mLevel = -6000;                                            // Default level
     int mDelay = 40;                                               // Default delay
+    int mReflectionsLevelMb = 0;
+    int mReflectionsDelayMs = 0;
     int mDiffusion = 1000;                                         // Default diffusion
     int mDensity = 1000;                                           // Default density
     bool mBypass = false;                                          // Default bypass
@@ -79,7 +91,7 @@
 class EnvReverbSw final : public EffectImpl {
   public:
     static const std::string kEffectName;
-    static const EnvironmentalReverb::Capability kCapability;
+    static const Capability kCapability;
     static const Descriptor kDescriptor;
     EnvReverbSw() { LOG(DEBUG) << __func__; }
     ~EnvReverbSw() {
@@ -100,6 +112,7 @@
     std::string getEffectName() override { return kEffectName; }
 
   private:
+    static const std::vector<Range::EnvironmentalReverbRange> kRanges;
     std::shared_ptr<EnvReverbSwContext> mContext;
     ndk::ScopedAStatus getParameterEnvironmentalReverb(const EnvironmentalReverb::Tag& tag,
                                                        Parameter::Specific* specific);
diff --git a/audio/aidl/default/equalizer/EqualizerSw.cpp b/audio/aidl/default/equalizer/EqualizerSw.cpp
index 984b943..9769924 100644
--- a/audio/aidl/default/equalizer/EqualizerSw.cpp
+++ b/audio/aidl/default/equalizer/EqualizerSw.cpp
@@ -14,27 +14,27 @@
  * limitations under the License.
  */
 
-#include <cstddef>
-#define LOG_TAG "AHAL_EqualizerSw"
-#include <Utils.h>
 #include <algorithm>
-#include <unordered_set>
+#include <cstddef>
 
+#define LOG_TAG "AHAL_EqualizerSw"
 #include <android-base/logging.h>
 #include <fmq/AidlMessageQueue.h>
+#include <system/audio_effects/effect_uuid.h>
 
 #include "EqualizerSw.h"
 
 using aidl::android::hardware::audio::effect::Descriptor;
 using aidl::android::hardware::audio::effect::EqualizerSw;
+using aidl::android::hardware::audio::effect::getEffectImplUuidEqualizerSw;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidEqualizer;
 using aidl::android::hardware::audio::effect::IEffect;
-using aidl::android::hardware::audio::effect::kEqualizerSwImplUUID;
 using aidl::android::hardware::audio::effect::State;
 using aidl::android::media::audio::common::AudioUuid;
 
 extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
                                            std::shared_ptr<IEffect>* instanceSpp) {
-    if (!in_impl_uuid || *in_impl_uuid != kEqualizerSwImplUUID) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidEqualizerSw()) {
         LOG(ERROR) << __func__ << "uuid not supported";
         return EX_ILLEGAL_ARGUMENT;
     }
@@ -49,7 +49,7 @@
 }
 
 extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
-    if (!in_impl_uuid || *in_impl_uuid != kEqualizerSwImplUUID) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidEqualizerSw()) {
         LOG(ERROR) << __func__ << "uuid not supported";
         return EX_ILLEGAL_ARGUMENT;
     }
@@ -60,6 +60,7 @@
 namespace aidl::android::hardware::audio::effect {
 
 const std::string EqualizerSw::kEffectName = "EqualizerSw";
+
 const std::vector<Equalizer::BandFrequency> EqualizerSw::kBandFrequency = {{0, 30000, 120000},
                                                                            {1, 120001, 460000},
                                                                            {2, 460001, 1800000},
@@ -69,19 +70,34 @@
         {0, "Normal"},      {1, "Classical"}, {2, "Dance"}, {3, "Flat"}, {4, "Folk"},
         {5, "Heavy Metal"}, {6, "Hip Hop"},   {7, "Jazz"},  {8, "Pop"},  {9, "Rock"}};
 
-const Equalizer::Capability EqualizerSw::kEqCap = {.bandFrequencies = kBandFrequency,
-                                                   .presets = kPresets};
+/**
+ * Use the same min and max to build a capability represented by Range.
+ */
+const std::vector<Range::EqualizerRange> EqualizerSw::kRanges = {
+        MAKE_RANGE(Equalizer, preset, 0, EqualizerSw::kPresets.size() - 1),
+        MAKE_RANGE(Equalizer, bandLevels,
+                   std::vector<Equalizer::BandLevel>{
+                           Equalizer::BandLevel({.index = 0, .levelMb = -15})},
+                   std::vector<Equalizer::BandLevel>{Equalizer::BandLevel(
+                           {.index = EqualizerSwContext::kMaxBandNumber - 1, .levelMb = 15})}),
+        /* capability definition */
+        MAKE_RANGE(Equalizer, bandFrequencies, EqualizerSw::kBandFrequency,
+                   EqualizerSw::kBandFrequency),
+        MAKE_RANGE(Equalizer, presets, EqualizerSw::kPresets, EqualizerSw::kPresets),
+        /* centerFreqMh is get only, set invalid range min > max */
+        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 = kEqualizerTypeUUID,
-                          .uuid = kEqualizerSwImplUUID,
-                          .proxy = kEqualizerProxyUUID},
+        .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 = Capability::make<Capability::equalizer>(EqualizerSw::kEqCap)};
+        .capability = EqualizerSw::kEqCap};
 
 ndk::ScopedAStatus EqualizerSw::getDescriptor(Descriptor* _aidl_return) {
     LOG(DEBUG) << __func__ << kDesc.toString();
@@ -95,6 +111,7 @@
     RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
 
     auto& eqParam = specific.get<Parameter::Specific::equalizer>();
+    RETURN_IF(!inRange(eqParam, kRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
     auto tag = eqParam.getTag();
     switch (tag) {
         case Equalizer::preset: {
@@ -150,6 +167,18 @@
             eqParam.set<Equalizer::preset>(mContext->getEqPreset());
             break;
         }
+        case Equalizer::centerFreqMh: {
+            eqParam.set<Equalizer::centerFreqMh>(mContext->getCenterFreqs());
+            break;
+        }
+        case Equalizer::bandFrequencies: {
+            eqParam.set<Equalizer::bandFrequencies>(kBandFrequency);
+            break;
+        }
+        case Equalizer::presets: {
+            eqParam.set<Equalizer::presets>(kPresets);
+            break;
+        }
         default: {
             LOG(ERROR) << __func__ << " not handled tag: " << toString(tag);
             return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
diff --git a/audio/aidl/default/equalizer/EqualizerSw.h b/audio/aidl/default/equalizer/EqualizerSw.h
index 65a8002..56af3b5 100644
--- a/audio/aidl/default/equalizer/EqualizerSw.h
+++ b/audio/aidl/default/equalizer/EqualizerSw.h
@@ -22,7 +22,6 @@
 #include <memory>
 
 #include "effect-impl/EffectImpl.h"
-#include "effect-impl/EffectUUID.h"
 
 namespace aidl::android::hardware::audio::effect {
 
@@ -34,7 +33,7 @@
     }
 
     RetCode setEqPreset(const int& presetIdx) {
-        if (presetIdx < 0 || presetIdx >= NUM_OF_PRESETS) {
+        if (presetIdx < 0 || presetIdx >= kMaxPresetNumber) {
             return RetCode::ERROR_ILLEGAL_PARAMETER;
         }
         mPreset = presetIdx;
@@ -43,13 +42,13 @@
     int getEqPreset() { return mPreset; }
 
     RetCode setEqBandLevels(const std::vector<Equalizer::BandLevel>& bandLevels) {
-        if (bandLevels.size() > NUM_OF_BANDS) {
-            LOG(ERROR) << __func__ << " return because size exceed " << NUM_OF_BANDS;
+        if (bandLevels.size() > kMaxBandNumber) {
+            LOG(ERROR) << __func__ << " return because size exceed " << kMaxBandNumber;
             return RetCode::ERROR_ILLEGAL_PARAMETER;
         }
         RetCode ret = RetCode::SUCCESS;
         for (auto& it : bandLevels) {
-            if (it.index >= NUM_OF_BANDS || it.index < 0) {
+            if (it.index >= kMaxBandNumber || it.index < 0) {
                 LOG(ERROR) << __func__ << " index illegal, skip: " << it.index << " - "
                            << it.levelMb;
                 ret = RetCode::ERROR_ILLEGAL_PARAMETER;
@@ -62,19 +61,25 @@
 
     std::vector<Equalizer::BandLevel> getEqBandLevels() {
         std::vector<Equalizer::BandLevel> bandLevels;
-        for (int i = 0; i < NUM_OF_BANDS; i++) {
+        for (int i = 0; i < kMaxBandNumber; i++) {
             bandLevels.push_back({i, mBandLevels[i]});
         }
         return bandLevels;
     }
 
+    std::vector<int> getCenterFreqs() {
+        return {std::begin(kPresetsFrequencies), std::end(kPresetsFrequencies)};
+    }
+    static const int kMaxBandNumber = 5;
+    static const int kMaxPresetNumber = 10;
+    static const int kCustomPreset = -1;
+
   private:
-    static const int NUM_OF_BANDS = 5;
-    static const int NUM_OF_PRESETS = 10;
-    static const int PRESET_CUSTOM = -1;
+    static constexpr std::array<uint16_t, kMaxBandNumber> kPresetsFrequencies = {60, 230, 910, 3600,
+                                                                                 14000};
     // preset band level
-    int mPreset = PRESET_CUSTOM;
-    int32_t mBandLevels[NUM_OF_BANDS] = {3, 0, 0, 0, 3};
+    int mPreset = kCustomPreset;
+    int32_t mBandLevels[kMaxBandNumber] = {3, 0, 0, 0, 3};
 
     // Add equalizer specific context for processing here
 };
@@ -82,9 +87,7 @@
 class EqualizerSw final : public EffectImpl {
   public:
     static const std::string kEffectName;
-    static const std::vector<Equalizer::BandFrequency> kBandFrequency;
-    static const std::vector<Equalizer::Preset> kPresets;
-    static const Equalizer::Capability kEqCap;
+    static const Capability kEqCap;
     static const Descriptor kDesc;
 
     EqualizerSw() { LOG(DEBUG) << __func__; }
@@ -106,6 +109,9 @@
     std::string getEffectName() override { return kEffectName; }
 
   private:
+    static const std::vector<Equalizer::BandFrequency> kBandFrequency;
+    static const std::vector<Equalizer::Preset> kPresets;
+    static const std::vector<Range::EqualizerRange> kRanges;
     ndk::ScopedAStatus getParameterEqualizer(const Equalizer::Tag& tag,
                                              Parameter::Specific* specific);
     std::shared_ptr<EqualizerSwContext> mContext;
diff --git a/audio/aidl/default/automaticGainControl/Android.bp b/audio/aidl/default/extension/Android.bp
similarity index 91%
copy from audio/aidl/default/automaticGainControl/Android.bp
copy to audio/aidl/default/extension/Android.bp
index 17d6416..4e5d352 100644
--- a/audio/aidl/default/automaticGainControl/Android.bp
+++ b/audio/aidl/default/extension/Android.bp
@@ -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.
@@ -24,14 +24,14 @@
 }
 
 cc_library_shared {
-    name: "libagcsw",
+    name: "libextensioneffect",
     defaults: [
         "aidlaudioeffectservice_defaults",
         "latest_android_media_audio_common_types_ndk_shared",
         "latest_android_hardware_audio_effect_ndk_shared",
     ],
     srcs: [
-        "AutomaticGainControlSw.cpp",
+        "ExtensionEffect.cpp",
         ":effectCommonFile",
     ],
     relative_install_path: "soundfx",
diff --git a/audio/aidl/default/extension/ExtensionEffect.cpp b/audio/aidl/default/extension/ExtensionEffect.cpp
new file mode 100644
index 0000000..c4eebc0
--- /dev/null
+++ b/audio/aidl/default/extension/ExtensionEffect.cpp
@@ -0,0 +1,147 @@
+/*
+ * 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 <algorithm>
+#include <cstddef>
+#include <memory>
+#include <unordered_set>
+
+#include <aidl/android/hardware/audio/effect/DefaultExtension.h>
+#define LOG_TAG "AHAL_ExtensionEffect"
+#include <android-base/logging.h>
+#include <fmq/AidlMessageQueue.h>
+#include <system/audio_effects/effect_uuid.h>
+
+#include "ExtensionEffect.h"
+
+using aidl::android::hardware::audio::effect::DefaultExtension;
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::ExtensionEffect;
+using aidl::android::hardware::audio::effect::getEffectUuidExtensionImpl;
+using aidl::android::hardware::audio::effect::getEffectUuidExtensionType;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::Range;
+using aidl::android::hardware::audio::effect::VendorExtension;
+using aidl::android::media::audio::common::AudioUuid;
+
+extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
+                                           std::shared_ptr<IEffect>* instanceSpp) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectUuidExtensionImpl()) {
+        LOG(ERROR) << __func__ << "uuid not supported";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+    if (instanceSpp) {
+        *instanceSpp = ndk::SharedRefBase::make<ExtensionEffect>();
+        LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
+        return EX_NONE;
+    } else {
+        LOG(ERROR) << __func__ << " invalid input parameter!";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+}
+
+extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectUuidExtensionImpl()) {
+        LOG(ERROR) << __func__ << "uuid not supported";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+    *_aidl_return = ExtensionEffect::kDescriptor;
+    return EX_NONE;
+}
+
+namespace aidl::android::hardware::audio::effect {
+
+const std::string ExtensionEffect::kEffectName = "ExtensionEffectExample";
+
+const Descriptor ExtensionEffect::kDescriptor = {
+        .common = {.id = {.type = getEffectUuidExtensionType(),
+                          .uuid = getEffectUuidExtensionImpl(),
+                          .proxy = std::nullopt},
+                   .name = ExtensionEffect::kEffectName,
+                   .implementor = "The Android Open Source Project"}};
+
+ndk::ScopedAStatus ExtensionEffect::getDescriptor(Descriptor* _aidl_return) {
+    LOG(DEBUG) << __func__ << kDescriptor.toString();
+    *_aidl_return = kDescriptor;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ExtensionEffect::setParameterSpecific(const Parameter::Specific& specific) {
+    RETURN_IF(Parameter::Specific::vendorEffect != specific.getTag(), EX_ILLEGAL_ARGUMENT,
+              "EffectNotSupported");
+    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+
+    auto& vendorEffect = specific.get<Parameter::Specific::vendorEffect>();
+    std::optional<DefaultExtension> defaultExt;
+    RETURN_IF(STATUS_OK != vendorEffect.extension.getParcelable(&defaultExt), EX_ILLEGAL_ARGUMENT,
+              "getParcelableFailed");
+    RETURN_IF(!defaultExt.has_value(), EX_ILLEGAL_ARGUMENT, "parcelableNull");
+    RETURN_IF(mContext->setParams(defaultExt->bytes) != RetCode::SUCCESS, EX_ILLEGAL_ARGUMENT,
+              "paramNotSupported");
+
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ExtensionEffect::getParameterSpecific(const Parameter::Id& id,
+                                                         Parameter::Specific* specific) {
+    auto tag = id.getTag();
+    RETURN_IF(Parameter::Id::vendorEffectTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
+    auto extensionId = id.get<Parameter::Id::vendorEffectTag>();
+    std::optional<DefaultExtension> defaultIdExt;
+    RETURN_IF(STATUS_OK != extensionId.extension.getParcelable(&defaultIdExt), EX_ILLEGAL_ARGUMENT,
+              "getIdParcelableFailed");
+    RETURN_IF(!defaultIdExt.has_value(), EX_ILLEGAL_ARGUMENT, "parcelableIdNull");
+
+    VendorExtension extension;
+    DefaultExtension defaultExt;
+    defaultExt.bytes = mContext->getParams(defaultIdExt->bytes);
+    RETURN_IF(STATUS_OK != extension.extension.setParcelable(defaultExt), EX_ILLEGAL_ARGUMENT,
+              "setParcelableFailed");
+    specific->set<Parameter::Specific::vendorEffect>(extension);
+    return ndk::ScopedAStatus::ok();
+}
+
+std::shared_ptr<EffectContext> ExtensionEffect::createContext(const Parameter::Common& common) {
+    if (mContext) {
+        LOG(DEBUG) << __func__ << " context already exist";
+    } else {
+        mContext = std::make_shared<ExtensionEffectContext>(1 /* statusFmqDepth */, common);
+    }
+    return mContext;
+}
+
+std::shared_ptr<EffectContext> ExtensionEffect::getContext() {
+    return mContext;
+}
+
+RetCode ExtensionEffect::releaseContext() {
+    if (mContext) {
+        mContext.reset();
+    }
+    return RetCode::SUCCESS;
+}
+
+// Processing method running in EffectWorker thread.
+IEffect::Status ExtensionEffect::effectProcessImpl(float* in, float* out, int samples) {
+    // TODO: get data buffer and process.
+    LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
+    for (int i = 0; i < samples; i++) {
+        *out++ = *in++;
+    }
+    return {STATUS_OK, samples, samples};
+}
+
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/extension/ExtensionEffect.h b/audio/aidl/default/extension/ExtensionEffect.h
new file mode 100644
index 0000000..e7a068b
--- /dev/null
+++ b/audio/aidl/default/extension/ExtensionEffect.h
@@ -0,0 +1,71 @@
+/*
+ * 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/effect/BnEffect.h>
+#include <fmq/AidlMessageQueue.h>
+#include <memory>
+#include <vector>
+
+#include "effect-impl/EffectImpl.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+class ExtensionEffectContext final : public EffectContext {
+  public:
+    ExtensionEffectContext(int statusDepth, const Parameter::Common& common)
+        : EffectContext(statusDepth, common) {
+        LOG(DEBUG) << __func__;
+    }
+
+    RetCode setParams(const std::vector<uint8_t>& params) {
+        mParams = params;
+        return RetCode::SUCCESS;
+    }
+    std::vector<uint8_t> getParams(std::vector<uint8_t> id __unused) const { return mParams; }
+
+  private:
+    std::vector<uint8_t> mParams;
+};
+
+class ExtensionEffect final : public EffectImpl {
+  public:
+    static const std::string kEffectName;
+    static const Capability kCapability;
+    static const Descriptor kDescriptor;
+    ExtensionEffect() { LOG(DEBUG) << __func__; }
+    ~ExtensionEffect() {
+        cleanUp();
+        LOG(DEBUG) << __func__;
+    }
+
+    ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
+    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
+    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
+                                            Parameter::Specific* specific) override;
+
+    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
+    std::shared_ptr<EffectContext> getContext() override;
+    RetCode releaseContext() override;
+
+    std::string getEffectName() override { return kEffectName; };
+    IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+
+  private:
+    std::shared_ptr<ExtensionEffectContext> mContext;
+};
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/hapticGenerator/HapticGeneratorSw.cpp b/audio/aidl/default/hapticGenerator/HapticGeneratorSw.cpp
index 3c3b66f..27cdac8 100644
--- a/audio/aidl/default/hapticGenerator/HapticGeneratorSw.cpp
+++ b/audio/aidl/default/hapticGenerator/HapticGeneratorSw.cpp
@@ -14,27 +14,27 @@
  * limitations under the License.
  */
 
-#include <cstddef>
-#define LOG_TAG "AHAL_HapticGeneratorSw"
-#include <Utils.h>
 #include <algorithm>
-#include <unordered_set>
+#include <cstddef>
 
+#define LOG_TAG "AHAL_HapticGeneratorSw"
 #include <android-base/logging.h>
 #include <fmq/AidlMessageQueue.h>
+#include <system/audio_effects/effect_uuid.h>
 
 #include "HapticGeneratorSw.h"
 
 using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectImplUuidHapticGeneratorSw;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidHapticGenerator;
 using aidl::android::hardware::audio::effect::HapticGeneratorSw;
 using aidl::android::hardware::audio::effect::IEffect;
-using aidl::android::hardware::audio::effect::kHapticGeneratorSwImplUUID;
 using aidl::android::hardware::audio::effect::State;
 using aidl::android::media::audio::common::AudioUuid;
 
 extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
                                            std::shared_ptr<IEffect>* instanceSpp) {
-    if (!in_impl_uuid || *in_impl_uuid != kHapticGeneratorSwImplUUID) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidHapticGeneratorSw()) {
         LOG(ERROR) << __func__ << "uuid not supported";
         return EX_ILLEGAL_ARGUMENT;
     }
@@ -49,7 +49,7 @@
 }
 
 extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
-    if (!in_impl_uuid || *in_impl_uuid != kHapticGeneratorSwImplUUID) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidHapticGeneratorSw()) {
         LOG(ERROR) << __func__ << "uuid not supported";
         return EX_ILLEGAL_ARGUMENT;
     }
@@ -60,20 +60,16 @@
 namespace aidl::android::hardware::audio::effect {
 
 const std::string HapticGeneratorSw::kEffectName = "HapticGeneratorSw";
-/* capabilities */
-const HapticGenerator::Capability HapticGeneratorSw::kCapability;
 /* Effect descriptor */
 const Descriptor HapticGeneratorSw::kDescriptor = {
-        .common = {.id = {.type = kHapticGeneratorTypeUUID,
-                          .uuid = kHapticGeneratorSwImplUUID,
+        .common = {.id = {.type = getEffectTypeUuidHapticGenerator(),
+                          .uuid = getEffectImplUuidHapticGeneratorSw(),
                           .proxy = std::nullopt},
                    .flags = {.type = Flags::Type::INSERT,
                              .insert = Flags::Insert::FIRST,
                              .volume = Flags::Volume::CTRL},
                    .name = HapticGeneratorSw::kEffectName,
-                   .implementor = "The Android Open Source Project"},
-        .capability =
-                Capability::make<Capability::hapticGenerator>(HapticGeneratorSw::kCapability)};
+                   .implementor = "The Android Open Source Project"}};
 
 ndk::ScopedAStatus HapticGeneratorSw::getDescriptor(Descriptor* _aidl_return) {
     LOG(DEBUG) << __func__ << kDescriptor.toString();
diff --git a/audio/aidl/default/hapticGenerator/HapticGeneratorSw.h b/audio/aidl/default/hapticGenerator/HapticGeneratorSw.h
index 7159501..3bbe41a 100644
--- a/audio/aidl/default/hapticGenerator/HapticGeneratorSw.h
+++ b/audio/aidl/default/hapticGenerator/HapticGeneratorSw.h
@@ -16,13 +16,14 @@
 
 #pragma once
 
-#include <aidl/android/hardware/audio/effect/BnEffect.h>
-#include <fmq/AidlMessageQueue.h>
 #include <cstdlib>
+#include <map>
 #include <memory>
 
+#include <aidl/android/hardware/audio/effect/BnEffect.h>
+#include <fmq/AidlMessageQueue.h>
+
 #include "effect-impl/EffectImpl.h"
-#include "effect-impl/EffectUUID.h"
 
 namespace aidl::android::hardware::audio::effect {
 
@@ -58,7 +59,6 @@
 class HapticGeneratorSw final : public EffectImpl {
   public:
     static const std::string kEffectName;
-    static const HapticGenerator::Capability kCapability;
     static const Descriptor kDescriptor;
     HapticGeneratorSw() { LOG(DEBUG) << __func__; }
     ~HapticGeneratorSw() {
diff --git a/audio/aidl/default/include/core-impl/Bluetooth.h b/audio/aidl/default/include/core-impl/Bluetooth.h
index f2e762d..10e9045 100644
--- a/audio/aidl/default/include/core-impl/Bluetooth.h
+++ b/audio/aidl/default/include/core-impl/Bluetooth.h
@@ -17,6 +17,8 @@
 #pragma once
 
 #include <aidl/android/hardware/audio/core/BnBluetooth.h>
+#include <aidl/android/hardware/audio/core/BnBluetoothA2dp.h>
+#include <aidl/android/hardware/audio/core/BnBluetoothLe.h>
 
 namespace aidl::android::hardware::audio::core {
 
@@ -32,4 +34,34 @@
     HfpConfig mHfpConfig;
 };
 
+class BluetoothA2dp : public BnBluetoothA2dp {
+  public:
+    BluetoothA2dp() = default;
+
+  private:
+    ndk::ScopedAStatus isEnabled(bool* _aidl_return) override;
+    ndk::ScopedAStatus setEnabled(bool in_enabled) override;
+    ndk::ScopedAStatus supportsOffloadReconfiguration(bool* _aidl_return) override;
+    ndk::ScopedAStatus reconfigureOffload(
+            const std::vector<::aidl::android::hardware::audio::core::VendorParameter>&
+                    in_parameters) override;
+
+    bool mEnabled = false;
+};
+
+class BluetoothLe : public BnBluetoothLe {
+  public:
+    BluetoothLe() = default;
+
+  private:
+    ndk::ScopedAStatus isEnabled(bool* _aidl_return) override;
+    ndk::ScopedAStatus setEnabled(bool in_enabled) override;
+    ndk::ScopedAStatus supportsOffloadReconfiguration(bool* _aidl_return) override;
+    ndk::ScopedAStatus reconfigureOffload(
+            const std::vector<::aidl::android::hardware::audio::core::VendorParameter>&
+                    in_parameters) override;
+
+    bool mEnabled = false;
+};
+
 }  // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/include/core-impl/Configuration.h b/audio/aidl/default/include/core-impl/Configuration.h
index 1aca1fe..70320e4 100644
--- a/audio/aidl/default/include/core-impl/Configuration.h
+++ b/audio/aidl/default/include/core-impl/Configuration.h
@@ -22,18 +22,19 @@
 
 #include <aidl/android/hardware/audio/core/AudioPatch.h>
 #include <aidl/android/hardware/audio/core/AudioRoute.h>
-#include <aidl/android/hardware/audio/core/MicrophoneInfo.h>
 #include <aidl/android/media/audio/common/AudioPort.h>
 #include <aidl/android/media/audio/common/AudioPortConfig.h>
+#include <aidl/android/media/audio/common/MicrophoneInfo.h>
 
 namespace aidl::android::hardware::audio::core::internal {
 
 struct Configuration {
-    std::vector<MicrophoneInfo> microphones;
+    std::vector<::aidl::android::media::audio::common::MicrophoneInfo> microphones;
     std::vector<::aidl::android::media::audio::common::AudioPort> ports;
     std::vector<::aidl::android::media::audio::common::AudioPortConfig> portConfigs;
     std::vector<::aidl::android::media::audio::common::AudioPortConfig> initialConfigs;
-    // Port id -> List of profiles to use when the device port state is set to 'connected'.
+    // Port id -> List of profiles to use when the device port state is set to 'connected'
+    // in connection simulation mode.
     std::map<int32_t, std::vector<::aidl::android::media::audio::common::AudioProfile>>
             connectedProfiles;
     std::vector<AudioRoute> routes;
diff --git a/audio/aidl/default/include/core-impl/Module.h b/audio/aidl/default/include/core-impl/Module.h
index fab1c14..83ecfaa 100644
--- a/audio/aidl/default/include/core-impl/Module.h
+++ b/audio/aidl/default/include/core-impl/Module.h
@@ -46,11 +46,33 @@
         bool forceTransientBurst = false;
         bool forceSynchronousDrain = false;
     };
+    // Helper used for interfaces that require a persistent instance. We hold them via a strong
+    // pointer. The binder token is retained for a call to 'setMinSchedulerPolicy'.
+    template <class C>
+    struct ChildInterface : private std::pair<std::shared_ptr<C>, ndk::SpAIBinder> {
+        ChildInterface() {}
+        ChildInterface& operator=(const std::shared_ptr<C>& c) {
+            return operator=(std::shared_ptr<C>(c));
+        }
+        ChildInterface& operator=(std::shared_ptr<C>&& c) {
+            this->first = std::move(c);
+            this->second = this->first->asBinder();
+            AIBinder_setMinSchedulerPolicy(this->second.get(), SCHED_NORMAL,
+                                           ANDROID_PRIORITY_AUDIO);
+            return *this;
+        }
+        explicit operator bool() const { return !!this->first; }
+        C& operator*() const { return *(this->first); }
+        C* operator->() const { return this->first; }
+        std::shared_ptr<C> getPtr() const { return this->first; }
+    };
 
     ndk::ScopedAStatus setModuleDebug(
             const ::aidl::android::hardware::audio::core::ModuleDebug& in_debug) override;
     ndk::ScopedAStatus getTelephony(std::shared_ptr<ITelephony>* _aidl_return) override;
     ndk::ScopedAStatus getBluetooth(std::shared_ptr<IBluetooth>* _aidl_return) override;
+    ndk::ScopedAStatus getBluetoothA2dp(std::shared_ptr<IBluetoothA2dp>* _aidl_return) override;
+    ndk::ScopedAStatus getBluetoothLe(std::shared_ptr<IBluetoothLe>* _aidl_return) override;
     ndk::ScopedAStatus connectExternalDevice(
             const ::aidl::android::media::audio::common::AudioPort& in_templateIdAndAdditionalData,
             ::aidl::android::media::audio::common::AudioPort* _aidl_return) override;
@@ -94,7 +116,9 @@
     ndk::ScopedAStatus setMasterVolume(float in_volume) override;
     ndk::ScopedAStatus getMicMute(bool* _aidl_return) override;
     ndk::ScopedAStatus setMicMute(bool in_mute) override;
-    ndk::ScopedAStatus getMicrophones(std::vector<MicrophoneInfo>* _aidl_return) override;
+    ndk::ScopedAStatus getMicrophones(
+            std::vector<::aidl::android::media::audio::common::MicrophoneInfo>* _aidl_return)
+            override;
     ndk::ScopedAStatus updateAudioMode(
             ::aidl::android::media::audio::common::AudioMode in_mode) override;
     ndk::ScopedAStatus updateScreenRotation(
@@ -141,7 +165,7 @@
     bool isMmapSupported();
 
     // This value is used for all AudioPatches.
-    static constexpr int32_t kMinimumStreamBufferSizeFrames = 16;
+    static constexpr int32_t kMinimumStreamBufferSizeFrames = 256;
     // The maximum stream buffer size is 1 GiB = 2 ** 30 bytes;
     static constexpr int32_t kMaximumStreamBufferSizeBytes = 1 << 30;
 
@@ -149,23 +173,20 @@
     std::unique_ptr<internal::Configuration> mConfig;
     ModuleDebug mDebug;
     VendorDebug mVendorDebug;
-    // For the interfaces requiring to return the same instance, we need to hold them
-    // via a strong pointer. The binder token is retained for a call to 'setMinSchedulerPolicy'.
-    std::shared_ptr<ITelephony> mTelephony;
-    ndk::SpAIBinder mTelephonyBinder;
-    std::shared_ptr<IBluetooth> mBluetooth;
-    ndk::SpAIBinder mBluetoothBinder;
-    // ids of ports created at runtime via 'connectExternalDevice'.
-    std::set<int32_t> mConnectedDevicePorts;
+    ChildInterface<ITelephony> mTelephony;
+    ChildInterface<IBluetooth> mBluetooth;
+    ChildInterface<IBluetoothA2dp> mBluetoothA2dp;
+    ChildInterface<IBluetoothLe> mBluetoothLe;
+    // ids of device ports created at runtime via 'connectExternalDevice'.
+    // Also stores ids of mix ports with dynamic profiles which got populated from the connected
+    // port.
+    std::map<int32_t, std::vector<int32_t>> mConnectedDevicePorts;
     Streams mStreams;
     // Maps port ids and port config ids to patch ids.
     // Multimap because both ports and configs can be used by multiple patches.
     std::multimap<int32_t, int32_t> mPatches;
-    bool mMasterMute = false;
-    float mMasterVolume = 1.0f;
     bool mMicMute = false;
-    std::shared_ptr<sounddose::ISoundDose> mSoundDose;
-    ndk::SpAIBinder mSoundDoseBinder;
+    ChildInterface<sounddose::ISoundDose> mSoundDose;
     std::optional<bool> mIsMmapSupported;
 
   protected:
@@ -178,6 +199,13 @@
     virtual ndk::ScopedAStatus checkAudioPatchEndpointsMatch(
             const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sources,
             const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sinks);
+    virtual void onExternalDeviceConnectionChanged(
+            const ::aidl::android::media::audio::common::AudioPort& audioPort, bool connected);
+    virtual ndk::ScopedAStatus onMasterMuteChanged(bool mute);
+    virtual ndk::ScopedAStatus onMasterVolumeChanged(float volume);
+
+    bool mMasterMute = false;
+    float mMasterVolume = 1.0f;
 };
 
 }  // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/include/core-impl/ModuleUsb.h b/audio/aidl/default/include/core-impl/ModuleUsb.h
index 7b177e8..1aa2244 100644
--- a/audio/aidl/default/include/core-impl/ModuleUsb.h
+++ b/audio/aidl/default/include/core-impl/ModuleUsb.h
@@ -28,10 +28,6 @@
     // IModule interfaces
     ndk::ScopedAStatus getTelephony(std::shared_ptr<ITelephony>* _aidl_return) override;
     ndk::ScopedAStatus getBluetooth(std::shared_ptr<IBluetooth>* _aidl_return) override;
-    ndk::ScopedAStatus getMasterMute(bool* _aidl_return) override;
-    ndk::ScopedAStatus setMasterMute(bool in_mute) override;
-    ndk::ScopedAStatus getMasterVolume(float* _aidl_return) override;
-    ndk::ScopedAStatus setMasterVolume(float in_volume) override;
     ndk::ScopedAStatus getMicMute(bool* _aidl_return) override;
     ndk::ScopedAStatus setMicMute(bool in_mute) override;
 
@@ -42,6 +38,11 @@
             const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sources,
             const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sinks)
             override;
+    void onExternalDeviceConnectionChanged(
+            const ::aidl::android::media::audio::common::AudioPort& audioPort,
+            bool connected) override;
+    ndk::ScopedAStatus onMasterMuteChanged(bool mute) override;
+    ndk::ScopedAStatus onMasterVolumeChanged(float volume) override;
 };
 
 }  // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/include/core-impl/SoundDose.h b/audio/aidl/default/include/core-impl/SoundDose.h
index 306aa04..2a069d9 100644
--- a/audio/aidl/default/include/core-impl/SoundDose.h
+++ b/audio/aidl/default/include/core-impl/SoundDose.h
@@ -29,8 +29,8 @@
   public:
     SoundDose() : mRs2Value(DEFAULT_MAX_RS2){};
 
-    ndk::ScopedAStatus setOutputRs2(float in_rs2ValueDbA) override;
-    ndk::ScopedAStatus getOutputRs2(float* _aidl_return) override;
+    ndk::ScopedAStatus setOutputRs2UpperBound(float in_rs2ValueDbA) override;
+    ndk::ScopedAStatus getOutputRs2UpperBound(float* _aidl_return) override;
     ndk::ScopedAStatus registerSoundDoseCallback(
             const std::shared_ptr<ISoundDose::IHalSoundDoseCallback>& in_callback) override;
 
diff --git a/audio/aidl/default/include/core-impl/Stream.h b/audio/aidl/default/include/core-impl/Stream.h
index f8c12e6..65680df 100644
--- a/audio/aidl/default/include/core-impl/Stream.h
+++ b/audio/aidl/default/include/core-impl/Stream.h
@@ -32,10 +32,10 @@
 #include <aidl/android/hardware/audio/core/BnStreamOut.h>
 #include <aidl/android/hardware/audio/core/IStreamCallback.h>
 #include <aidl/android/hardware/audio/core/IStreamOutEventCallback.h>
-#include <aidl/android/hardware/audio/core/MicrophoneInfo.h>
 #include <aidl/android/hardware/audio/core/StreamDescriptor.h>
 #include <aidl/android/media/audio/common/AudioDevice.h>
 #include <aidl/android/media/audio/common/AudioOffloadInfo.h>
+#include <aidl/android/media/audio/common/MicrophoneInfo.h>
 #include <fmq/AidlMessageQueue.h>
 #include <system/thread_defs.h>
 #include <utils/Errors.h>
@@ -294,6 +294,7 @@
 struct StreamCommonInterface {
     virtual ~StreamCommonInterface() = default;
     virtual ndk::ScopedAStatus close() = 0;
+    virtual ndk::ScopedAStatus prepareToClose() = 0;
     virtual ndk::ScopedAStatus updateHwAvSyncId(int32_t in_hwAvSyncId) = 0;
     virtual ndk::ScopedAStatus getVendorParameters(const std::vector<std::string>& in_ids,
                                                    std::vector<VendorParameter>* _aidl_return) = 0;
@@ -318,6 +319,11 @@
         return delegate != nullptr ? delegate->close()
                                    : ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
     }
+    ndk::ScopedAStatus prepareToClose() override {
+        auto delegate = mDelegate.lock();
+        return delegate != nullptr ? delegate->prepareToClose()
+                                   : ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+    }
     ndk::ScopedAStatus updateHwAvSyncId(int32_t in_hwAvSyncId) override {
         auto delegate = mDelegate.lock();
         return delegate != nullptr ? delegate->updateHwAvSyncId(in_hwAvSyncId)
@@ -359,6 +365,7 @@
 class StreamCommonImpl : public StreamCommonInterface {
   public:
     ndk::ScopedAStatus close() override;
+    ndk::ScopedAStatus prepareToClose() override;
     ndk::ScopedAStatus updateHwAvSyncId(int32_t in_hwAvSyncId) override;
     ndk::ScopedAStatus getVendorParameters(const std::vector<std::string>& in_ids,
                                            std::vector<VendorParameter>* _aidl_return) override;
@@ -413,7 +420,8 @@
                 getStreamCommon(_aidl_return);
     }
     ndk::ScopedAStatus getActiveMicrophones(
-            std::vector<MicrophoneDynamicInfo>* _aidl_return) override;
+            std::vector<::aidl::android::media::audio::common::MicrophoneDynamicInfo>* _aidl_return)
+            override;
     ndk::ScopedAStatus getMicrophoneDirection(MicrophoneDirection* _aidl_return) override;
     ndk::ScopedAStatus setMicrophoneDirection(MicrophoneDirection in_direction) override;
     ndk::ScopedAStatus getMicrophoneFieldDimension(float* _aidl_return) override;
@@ -434,7 +442,7 @@
     StreamIn(const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata,
              StreamContext&& context, const DriverInterface::CreateInstance& createDriver,
              const StreamWorkerInterface::CreateInstance& createWorker,
-             const std::vector<MicrophoneInfo>& microphones);
+             const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones);
     void createStreamCommon(const std::shared_ptr<StreamIn>& myPtr) {
         StreamCommonImpl<
                 ::aidl::android::hardware::audio::common::SinkMetadata>::createStreamCommon(myPtr);
@@ -445,7 +453,8 @@
   public:
     using CreateInstance = std::function<ndk::ScopedAStatus(
             const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata,
-            StreamContext&& context, const std::vector<MicrophoneInfo>& microphones,
+            StreamContext&& context,
+            const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones,
             std::shared_ptr<StreamIn>* result)>;
 };
 
@@ -461,6 +470,9 @@
         return StreamCommonImpl<::aidl::android::hardware::audio::common::SourceMetadata>::
                 updateMetadata(in_sourceMetadata);
     }
+    ndk::ScopedAStatus updateOffloadMetadata(
+            const ::aidl::android::hardware::audio::common::AudioOffloadMetadata&
+                    in_offloadMetadata) override;
     ndk::ScopedAStatus getHwVolume(std::vector<float>* _aidl_return) override;
     ndk::ScopedAStatus setHwVolume(const std::vector<float>& in_channelVolumes) override;
     ndk::ScopedAStatus getAudioDescriptionMixLevel(float* _aidl_return) override;
@@ -498,6 +510,7 @@
                       offloadInfo);
 
     std::optional<::aidl::android::media::audio::common::AudioOffloadInfo> mOffloadInfo;
+    std::optional<::aidl::android::hardware::audio::common::AudioOffloadMetadata> mOffloadMetadata;
 
   public:
     using CreateInstance = std::function<ndk::ScopedAStatus(
diff --git a/audio/aidl/default/include/core-impl/StreamStub.h b/audio/aidl/default/include/core-impl/StreamStub.h
index aea9da5..df0182c 100644
--- a/audio/aidl/default/include/core-impl/StreamStub.h
+++ b/audio/aidl/default/include/core-impl/StreamStub.h
@@ -36,6 +36,8 @@
 
   private:
     const size_t mFrameSizeBytes;
+    const int mSampleRate;
+    const bool mIsAsynchronous;
     const bool mIsInput;
 };
 
@@ -43,13 +45,16 @@
   public:
     static ndk::ScopedAStatus createInstance(
             const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata,
-            StreamContext&& context, const std::vector<MicrophoneInfo>& microphones,
+            StreamContext&& context,
+            const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones,
             std::shared_ptr<StreamIn>* result);
 
   private:
     friend class ndk::SharedRefBase;
-    StreamInStub(const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata,
-                 StreamContext&& context, const std::vector<MicrophoneInfo>& microphones);
+    StreamInStub(
+            const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata,
+            StreamContext&& context,
+            const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones);
 };
 
 class StreamOutStub final : public StreamOut {
diff --git a/audio/aidl/default/include/core-impl/StreamUsb.h b/audio/aidl/default/include/core-impl/StreamUsb.h
index 8ac1f34..36e64cb 100644
--- a/audio/aidl/default/include/core-impl/StreamUsb.h
+++ b/audio/aidl/default/include/core-impl/StreamUsb.h
@@ -17,6 +17,7 @@
 #pragma once
 
 #include <mutex>
+#include <vector>
 
 #include <aidl/android/media/audio/common/AudioChannelLayout.h>
 
@@ -55,23 +56,27 @@
     std::vector<::aidl::android::media::audio::common::AudioDeviceAddress> mConnectedDevices
             GUARDED_BY(mLock);
     std::vector<std::shared_ptr<alsa_device_proxy>> mAlsaDeviceProxies GUARDED_BY(mLock);
-    bool mIsStandby = false;
+    bool mIsStandby = true;
 };
 
 class StreamInUsb final : public StreamIn {
     ndk::ScopedAStatus getActiveMicrophones(
-            std::vector<MicrophoneDynamicInfo>* _aidl_return) override;
+            std::vector<::aidl::android::media::audio::common::MicrophoneDynamicInfo>* _aidl_return)
+            override;
 
   public:
     static ndk::ScopedAStatus createInstance(
             const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata,
-            StreamContext&& context, const std::vector<MicrophoneInfo>& microphones,
+            StreamContext&& context,
+            const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones,
             std::shared_ptr<StreamIn>* result);
 
   private:
     friend class ndk::SharedRefBase;
-    StreamInUsb(const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata,
-                StreamContext&& context, const std::vector<MicrophoneInfo>& microphones);
+    StreamInUsb(
+            const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata,
+            StreamContext&& context,
+            const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones);
 };
 
 class StreamOutUsb final : public StreamOut {
@@ -89,6 +94,12 @@
                  StreamContext&& context,
                  const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>&
                          offloadInfo);
+
+    ndk::ScopedAStatus getHwVolume(std::vector<float>* _aidl_return) override;
+    ndk::ScopedAStatus setHwVolume(const std::vector<float>& in_channelVolumes) override;
+
+    int mChannelCount;
+    std::vector<float> mHwVolumes;
 };
 
 }  // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/include/effect-impl/EffectContext.h b/audio/aidl/default/include/effect-impl/EffectContext.h
index 2ab0ade..8b4a7d2 100644
--- a/audio/aidl/default/include/effect-impl/EffectContext.h
+++ b/audio/aidl/default/include/effect-impl/EffectContext.h
@@ -15,10 +15,10 @@
  */
 
 #pragma once
-#include <Utils.h>
 #include <memory>
 #include <vector>
 
+#include <Utils.h>
 #include <android-base/logging.h>
 #include <fmq/AidlMessageQueue.h>
 
@@ -46,9 +46,9 @@
         LOG_ALWAYS_FATAL_IF(output.base.format.pcm !=
                                     aidl::android::media::audio::common::PcmType::FLOAT_32_BIT,
                             "outputFormatNotFloat");
-        mInputFrameSize = ::android::hardware::audio::common::getFrameSizeInBytes(
+        mInputFrameSize = ::aidl::android::hardware::audio::common::getFrameSizeInBytes(
                 input.base.format, input.base.channelMask);
-        mOutputFrameSize = ::android::hardware::audio::common::getFrameSizeInBytes(
+        mOutputFrameSize = ::aidl::android::hardware::audio::common::getFrameSizeInBytes(
                 output.base.format, output.base.channelMask);
         // in/outBuffer size in float (FMQ data format defined for DataMQ)
         size_t inBufferSizeInFloat = input.frameCount * mInputFrameSize / sizeof(float);
diff --git a/audio/aidl/default/include/effect-impl/EffectRange.h b/audio/aidl/default/include/effect-impl/EffectRange.h
new file mode 100644
index 0000000..a3ea01f
--- /dev/null
+++ b/audio/aidl/default/include/effect-impl/EffectRange.h
@@ -0,0 +1,48 @@
+/*
+ * 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 <algorithm>
+#include <tuple>
+#include <utility>
+#include <vector>
+
+namespace aidl::android::hardware::audio::effect {
+
+template <typename T>
+bool isInRange(const T& value, const T& low, const T& high) {
+    return (value >= low) && (value <= high);
+}
+
+template <typename T, std::size_t... Is>
+bool isTupleInRange(const T& test, const T& min, const T& max, std::index_sequence<Is...>) {
+    return (isInRange(std::get<Is>(test), std::get<Is>(min), std::get<Is>(max)) && ...);
+}
+
+template <typename T, std::size_t TupSize = std::tuple_size_v<T>>
+bool isTupleInRange(const T& test, const T& min, const T& max) {
+    return isTupleInRange(test, min, max, std::make_index_sequence<TupSize>{});
+}
+
+template <typename T, typename F>
+bool isTupleInRange(const std::vector<T>& cfgs, const T& min, const T& max, const F& func) {
+    auto minT = func(min), maxT = func(max);
+    return std::all_of(cfgs.cbegin(), cfgs.cend(),
+                       [&](const T& cfg) { return isTupleInRange(func(cfg), minT, maxT); });
+}
+
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/include/effect-impl/EffectThread.h b/audio/aidl/default/include/effect-impl/EffectThread.h
index 4b6cecd..f9c6a31 100644
--- a/audio/aidl/default/include/effect-impl/EffectThread.h
+++ b/audio/aidl/default/include/effect-impl/EffectThread.h
@@ -35,7 +35,7 @@
 
     // called by effect implementation.
     RetCode createThread(std::shared_ptr<EffectContext> context, const std::string& name,
-                         const int priority = ANDROID_PRIORITY_URGENT_AUDIO);
+                         int priority = ANDROID_PRIORITY_URGENT_AUDIO, int sleepUs = kSleepTimeUs);
     RetCode destroyThread();
     RetCode startThread();
     RetCode stopThread();
@@ -54,6 +54,9 @@
      * EffectThread will make sure effectProcessImpl only be called after startThread() successful
      * and before stopThread() successful.
      *
+     * effectProcessImpl implementation must not call any EffectThread interface, otherwise it will
+     * cause deadlock.
+     *
      * @param in address of input float buffer.
      * @param out address of output float buffer.
      * @param samples number of samples to process.
@@ -62,19 +65,15 @@
     virtual IEffect::Status effectProcessImpl(float* in, float* out, int samples) = 0;
 
     /**
-     * The default EffectThread::process() implementation doesn't need to lock. It will only
-     * access the FMQ and mWorkBuffer in  EffectContext, since they will only be changed in
-     * EffectImpl IEffect::open() (in this case EffectThread just created and not running yet) and
-     * IEffect::command(CommandId::RESET) (in this case EffectThread already stopped).
-     *
-     * process() call effectProcessImpl for effect processing, and because effectProcessImpl is
-     * implemented by effects, process() must not hold lock before call into effectProcessImpl to
-     * avoid deadlock.
+     * process() call effectProcessImpl() for effect data processing, it is necessary for the
+     * processing to be called under Effect thread mutex mThreadMutex, to avoid the effect state
+     * change before/during data processing, and keep the thread and effect state consistent.
      */
-    virtual void process();
+    virtual void process_l() REQUIRES(mThreadMutex);
 
   private:
-    const int kMaxTaskNameLen = 15;
+    static constexpr int kMaxTaskNameLen = 15;
+    static constexpr int kSleepTimeUs = 2000;  // in micro-second
     std::mutex mThreadMutex;
     std::condition_variable mCv;
     bool mExit GUARDED_BY(mThreadMutex) = false;
@@ -82,6 +81,9 @@
     std::shared_ptr<EffectContext> mThreadContext GUARDED_BY(mThreadMutex);
     std::thread mThread;
     int mPriority;
+    int mSleepTimeUs = kSleepTimeUs;  // sleep time in micro-second
     std::string mName;
+
+    RetCode handleStartStop(bool stop);
 };
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/include/effect-impl/EffectTypes.h b/audio/aidl/default/include/effect-impl/EffectTypes.h
index b100a2e..4bda7be 100644
--- a/audio/aidl/default/include/effect-impl/EffectTypes.h
+++ b/audio/aidl/default/include/effect-impl/EffectTypes.h
@@ -15,20 +15,21 @@
  */
 
 #pragma once
-#include <ostream>
 #include <string>
 
 #include <aidl/android/hardware/audio/effect/BnEffect.h>
+#include <aidl/android/hardware/audio/effect/Range.h>
 #include <android-base/logging.h>
+#include <system/audio_effects/aidl_effects_utils.h>
 
 typedef binder_exception_t (*EffectCreateFunctor)(
         const ::aidl::android::media::audio::common::AudioUuid*,
-        std::shared_ptr<aidl::android::hardware::audio::effect::IEffect>*);
+        std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>*);
 typedef binder_exception_t (*EffectDestroyFunctor)(
-        const std::shared_ptr<aidl::android::hardware::audio::effect::IEffect>&);
+        const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>&);
 typedef binder_exception_t (*EffectQueryFunctor)(
         const ::aidl::android::media::audio::common::AudioUuid*,
-        aidl::android::hardware::audio::effect::Descriptor*);
+        ::aidl::android::hardware::audio::effect::Descriptor*);
 
 struct effect_dl_interface_s {
     EffectCreateFunctor createEffectFunc;
@@ -116,23 +117,14 @@
         }                                                                   \
     }
 
-static inline bool stringToUuid(const char* str,
-                                ::aidl::android::media::audio::common::AudioUuid* uuid) {
-    RETURN_VALUE_IF(!uuid || !str, false, "nullPtr");
-
-    uint32_t tmp[10];
-    if (sscanf(str, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x", tmp, tmp + 1, tmp + 2, tmp + 3,
-               tmp + 4, tmp + 5, tmp + 6, tmp + 7, tmp + 8, tmp + 9) < 10) {
-        return false;
-    }
-
-    uuid->timeLow = (uint32_t)tmp[0];
-    uuid->timeMid = (uint16_t)tmp[1];
-    uuid->timeHiAndVersion = (uint16_t)tmp[2];
-    uuid->clockSeq = (uint16_t)tmp[3];
-    uuid->node.insert(uuid->node.end(), {(uint8_t)tmp[4], (uint8_t)tmp[5], (uint8_t)tmp[6],
-                                         (uint8_t)tmp[7], (uint8_t)tmp[8], (uint8_t)tmp[9]});
-    return true;
-}
+/**
+ * Make a Range::$EffectType$Range.
+ * T: The $EffectType$, Visualizer for example.
+ * Tag: The union tag name in $EffectType$ definition, latencyMs for example.
+ * l: The value of Range::$EffectType$Range.min.
+ * r: The value of Range::$EffectType$Range.max.
+ */
+#define MAKE_RANGE(T, Tag, l, r) \
+    { .min = T::make<T::Tag>(l), .max = T::make<T::Tag>(r) }
 
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/include/effect-impl/EffectUUID.h b/audio/aidl/default/include/effect-impl/EffectUUID.h
deleted file mode 100644
index 7703091..0000000
--- a/audio/aidl/default/include/effect-impl/EffectUUID.h
+++ /dev/null
@@ -1,328 +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.
- */
-
-#pragma once
-#include <map>
-
-#include <aidl/android/media/audio/common/AudioUuid.h>
-
-namespace aidl::android::hardware::audio::effect {
-
-using ::aidl::android::media::audio::common::AudioUuid;
-
-// ec7178ec-e5e1-4432-a3f4-4657e6795210
-static const AudioUuid kEffectNullUuid = {static_cast<int32_t>(0xec7178ec),
-                                          0xe5e1,
-                                          0x4432,
-                                          0xa3f4,
-                                          {0x46, 0x57, 0xe6, 0x79, 0x52, 0x10}};
-// Zero UUID
-static const AudioUuid kEffectZeroUuid = {
-        static_cast<int32_t>(0x0), 0x0, 0x0, 0x0, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};
-
-// 7b491460-8d4d-11e0-bd61-0002a5d5c51b.
-static const AudioUuid kAcousticEchoCancelerTypeUUID = {static_cast<int32_t>(0x7b491460),
-                                                        0x8d4d,
-                                                        0x11e0,
-                                                        0xbd61,
-                                                        {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
-// bb392ec0-8d4d-11e0-a896-0002a5d5c51b
-static const AudioUuid kAcousticEchoCancelerSwImplUUID = {static_cast<int32_t>(0xbb392ec0),
-                                                          0x8d4d,
-                                                          0x11e0,
-                                                          0xa896,
-                                                          {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
-// 0xae3c653b-be18-4ab8-8938-418f0a7f06ac
-static const AudioUuid kAutomaticGainControlTypeUUID = {static_cast<int32_t>(0xae3c653b),
-                                                        0xbe18,
-                                                        0x4ab8,
-                                                        0x8938,
-                                                        {0x41, 0x8f, 0x0a, 0x7f, 0x06, 0xac}};
-// 89f38e65-d4d2-4d64-ad0e-2b3e799ea886
-static const AudioUuid kAutomaticGainControlSwImplUUID = {static_cast<int32_t>(0x89f38e65),
-                                                          0xd4d2,
-                                                          0x4d64,
-                                                          0xad0e,
-                                                          {0x2b, 0x3e, 0x79, 0x9e, 0xa8, 0x86}};
-// 0634f220-ddd4-11db-a0fc-0002a5d5c51b
-static const AudioUuid kBassBoostTypeUUID = {static_cast<int32_t>(0x0634f220),
-                                             0xddd4,
-                                             0x11db,
-                                             0xa0fc,
-                                             {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
-// fa8181f2-588b-11ed-9b6a-0242ac120002
-static const AudioUuid kBassBoostSwImplUUID = {static_cast<int32_t>(0xfa8181f2),
-                                               0x588b,
-                                               0x11ed,
-                                               0x9b6a,
-                                               {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
-// 8631f300-72e2-11df-b57e-0002a5d5c51b
-static const AudioUuid kBassBoostBundleImplUUID = {static_cast<int32_t>(0x8631f300),
-                                                   0x72e2,
-                                                   0x11df,
-                                                   0xb57e,
-                                                   {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
-// 14804144-a5ee-4d24-aa88-0002a5d5c51b
-static const AudioUuid kBassBoostProxyUUID = {static_cast<int32_t>(0x14804144),
-                                              0xa5ee,
-                                              0x4d24,
-                                              0xaa88,
-                                              {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
-// fa81862a-588b-11ed-9b6a-0242ac120002
-static const AudioUuid kDownmixTypeUUID = {static_cast<int32_t>(0xfa81862a),
-                                           0x588b,
-                                           0x11ed,
-                                           0x9b6a,
-                                           {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
-// fa8187ba-588b-11ed-9b6a-0242ac120002
-static const AudioUuid kDownmixSwImplUUID = {static_cast<int32_t>(0xfa8187ba),
-                                             0x588b,
-                                             0x11ed,
-                                             0x9b6a,
-                                             {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
-// 93f04452-e4fe-41cc-91f9-e475b6d1d69f
-static const AudioUuid kDownmixImplUUID = {static_cast<int32_t>(0x93f04452),
-                                           0xe4fe,
-                                           0x41cc,
-                                           0x91f9,
-                                           {0xe4, 0x75, 0xb6, 0xd1, 0xd6, 0x9f}};
-// 0bed4300-ddd6-11db-8f34-0002a5d5c51b.
-static const AudioUuid kEqualizerTypeUUID = {static_cast<int32_t>(0x0bed4300),
-                                             0xddd6,
-                                             0x11db,
-                                             0x8f34,
-                                             {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
-// 0bed4300-847d-11df-bb17-0002a5d5c51b
-static const AudioUuid kEqualizerSwImplUUID = {static_cast<int32_t>(0x0bed4300),
-                                               0x847d,
-                                               0x11df,
-                                               0xbb17,
-                                               {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
-// ce772f20-847d-11df-bb17-0002a5d5c51b
-static const AudioUuid kEqualizerBundleImplUUID = {static_cast<int32_t>(0xce772f20),
-                                                   0x847d,
-                                                   0x11df,
-                                                   0xbb17,
-                                                   {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
-// c8e70ecd-48ca-456e-8a4f-0002a5d5c51b
-static const AudioUuid kEqualizerProxyUUID = {static_cast<int32_t>(0xc8e70ecd),
-                                              0x48ca,
-                                              0x456e,
-                                              0x8a4f,
-                                              {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
-// 7261676f-6d75-7369-6364-28e2fd3ac39e
-static const AudioUuid kDynamicsProcessingTypeUUID = {static_cast<int32_t>(0x7261676f),
-                                                      0x6d75,
-                                                      0x7369,
-                                                      0x6364,
-                                                      {0x28, 0xe2, 0xfd, 0x3a, 0xc3, 0x9e}};
-// fa818d78-588b-11ed-9b6a-0242ac120002
-static const AudioUuid kDynamicsProcessingSwImplUUID = {static_cast<int32_t>(0xfa818d78),
-                                                        0x588b,
-                                                        0x11ed,
-                                                        0x9b6a,
-                                                        {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
-// e0e6539b-1781-7261-676f-6d7573696340
-static const AudioUuid kDynamicsProcessingImplUUID = {static_cast<int32_t>(0xe0e6539b),
-                                                      0x1781,
-                                                      0x7261,
-                                                      0x676f,
-                                                      {0x6d, 0x75, 0x73, 0x69, 0x63, 0x40}};
-// 1411e6d6-aecd-4021-a1cf-a6aceb0d71e5
-static const AudioUuid kHapticGeneratorTypeUUID = {static_cast<int32_t>(0x1411e6d6),
-                                                   0xaecd,
-                                                   0x4021,
-                                                   0xa1cf,
-                                                   {0xa6, 0xac, 0xeb, 0x0d, 0x71, 0xe5}};
-// fa819110-588b-11ed-9b6a-0242ac120002
-static const AudioUuid kHapticGeneratorSwImplUUID = {static_cast<int32_t>(0xfa819110),
-                                                     0x588b,
-                                                     0x11ed,
-                                                     0x9b6a,
-                                                     {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
-// 97c4acd1-8b82-4f2f-832e-c2fe5d7a9931
-static const AudioUuid kHapticGeneratorImplUUID = {static_cast<int32_t>(0x97c4acd1),
-                                                   0x8b82,
-                                                   0x4f2f,
-                                                   0x832e,
-                                                   {0xc2, 0xfe, 0x5d, 0x7a, 0x99, 0x31}};
-// fe3199be-aed0-413f-87bb-11260eb63cf1
-static const AudioUuid kLoudnessEnhancerTypeUUID = {static_cast<int32_t>(0xfe3199be),
-                                                    0xaed0,
-                                                    0x413f,
-                                                    0x87bb,
-                                                    {0x11, 0x26, 0x0e, 0xb6, 0x3c, 0xf1}};
-// fa819610-588b-11ed-9b6a-0242ac120002
-static const AudioUuid kLoudnessEnhancerSwImplUUID = {static_cast<int32_t>(0xfa819610),
-                                                      0x588b,
-                                                      0x11ed,
-                                                      0x9b6a,
-                                                      {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
-// fa415329-2034-4bea-b5dc-5b381c8d1e2c
-static const AudioUuid kLoudnessEnhancerImplUUID = {static_cast<int32_t>(0xfa415329),
-                                                    0x2034,
-                                                    0x4bea,
-                                                    0xb5dc,
-                                                    {0x5b, 0x38, 0x1c, 0x8d, 0x1e, 0x2c}};
-// c2e5d5f0-94bd-4763-9cac-4e234d06839e
-static const AudioUuid kEnvReverbTypeUUID = {static_cast<int32_t>(0xc2e5d5f0),
-                                             0x94bd,
-                                             0x4763,
-                                             0x9cac,
-                                             {0x4e, 0x23, 0x4d, 0x06, 0x83, 0x9e}};
-// fa819886-588b-11ed-9b6a-0242ac120002
-static const AudioUuid kEnvReverbSwImplUUID = {static_cast<int32_t>(0xfa819886),
-                                               0x588b,
-                                               0x11ed,
-                                               0x9b6a,
-                                               {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
-// 4a387fc0-8ab3-11df-8bad-0002a5d5c51b
-static const AudioUuid kAuxEnvReverbImplUUID = {static_cast<int32_t>(0x4a387fc0),
-                                                0x8ab3,
-                                                0x11df,
-                                                0x8bad,
-                                                {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
-// c7a511a0-a3bb-11df-860e-0002a5d5c51b
-static const AudioUuid kInsertEnvReverbImplUUID = {static_cast<int32_t>(0xc7a511a0),
-                                                   0xa3bb,
-                                                   0x11df,
-                                                   0x860e,
-                                                   {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
-// 58b4b260-8e06-11e0-aa8e-0002a5d5c51b
-static const AudioUuid kNoiseSuppressionTypeUUID = {static_cast<int32_t>(0x58b4b260),
-                                                    0x8e06,
-                                                    0x11e0,
-                                                    0xaa8e,
-                                                    {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
-// c06c8400-8e06-11e0-9cb6-0002a5d5c51b
-static const AudioUuid kNoiseSuppressionSwImplUUID = {static_cast<int32_t>(0xc06c8400),
-                                                      0x8e06,
-                                                      0x11e0,
-                                                      0x9cb6,
-                                                      {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
-// 47382d60-ddd8-11db-bf3a-0002a5d5c51b
-static const AudioUuid kPresetReverbTypeUUID = {static_cast<int32_t>(0x47382d60),
-                                                0xddd8,
-                                                0x11db,
-                                                0xbf3a,
-                                                {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
-// fa8199c6-588b-11ed-9b6a-0242ac120002
-static const AudioUuid kPresetReverbSwImplUUID = {static_cast<int32_t>(0xfa8199c6),
-                                                  0x588b,
-                                                  0x11ed,
-                                                  0x9b6a,
-                                                  {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
-// f29a1400-a3bb-11df-8ddc-0002a5d5c51b
-static const AudioUuid kAuxPresetReverbImplUUID = {static_cast<int32_t>(0xf29a1400),
-                                                   0xa3bb,
-                                                   0x11df,
-                                                   0x8ddc,
-                                                   {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
-// 172cdf00-a3bc-11df-a72f-0002a5d5c51b
-static const AudioUuid kInsertPresetReverbImplUUID = {static_cast<int32_t>(0x172cdf00),
-                                                      0xa3bc,
-                                                      0x11df,
-                                                      0xa72f,
-                                                      {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
-// 37cc2c00-dddd-11db-8577-0002a5d5c51b
-static const AudioUuid kVirtualizerTypeUUID = {static_cast<int32_t>(0x37cc2c00),
-                                               0xdddd,
-                                               0x11db,
-                                               0x8577,
-                                               {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
-// fa819d86-588b-11ed-9b6a-0242ac120002
-static const AudioUuid kVirtualizerSwImplUUID = {static_cast<int32_t>(0xfa819d86),
-                                                 0x588b,
-                                                 0x11ed,
-                                                 0x9b6a,
-                                                 {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
-// 1d4033c0-8557-11df-9f2d-0002a5d5c51b
-static const AudioUuid kVirtualizerBundleImplUUID = {static_cast<int32_t>(0x1d4033c0),
-                                                     0x8557,
-                                                     0x11df,
-                                                     0x9f2d,
-                                                     {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
-// d3467faa-acc7-4d34-acaf-0002a5d5c51b
-static const AudioUuid kVirtualizerProxyUUID = {static_cast<int32_t>(0xd3467faa),
-                                                0xacc7,
-                                                0x4d34,
-                                                0xacaf,
-                                                {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
-// fa819f3e-588b-11ed-9b6a-0242ac120002
-static const AudioUuid kVisualizerTypeUUID = {static_cast<int32_t>(0xfa819f3e),
-                                              0x588b,
-                                              0x11ed,
-                                              0x9b6a,
-                                              {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
-// fa81a0f6-588b-11ed-9b6a-0242ac120002
-static const AudioUuid kVisualizerSwImplUUID = {static_cast<int32_t>(0xfa81a0f6),
-                                                0x588b,
-                                                0x11ed,
-                                                0x9b6a,
-                                                {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
-// d069d9e0-8329-11df-9168-0002a5d5c51b
-// {0xd069d9e0, 0x8329, 0x11df, 0x9168, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
-static const AudioUuid kVisualizerImplUUID = {static_cast<int32_t>(0xd069d9e0),
-                                              0x8329,
-                                              0x11df,
-                                              0x9168,
-                                              {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
-// fa81a2b8-588b-11ed-9b6a-0242ac120002
-static const AudioUuid kVolumeTypeUUID = {static_cast<int32_t>(0xfa81a2b8),
-                                          0x588b,
-                                          0x11ed,
-                                          0x9b6a,
-                                          {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
-// fa81a718-588b-11ed-9b6a-0242ac120002
-static const AudioUuid kVolumeSwImplUUID = {static_cast<int32_t>(0xfa81a718),
-                                            0x588b,
-                                            0x11ed,
-                                            0x9b6a,
-                                            {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
-// 119341a0-8469-11df-81f9-0002a5d5c51b
-static const AudioUuid kVolumeBundleImplUUID = {static_cast<int32_t>(0x119341a0),
-                                                0x8469,
-                                                0x11df,
-                                                0x81f9,
-                                                {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
-
-/**
- * @brief A map between effect name and effect type UUID.
- * All <name> attribution in effect/effectProxy of audio_effects.xml should be listed in this map.
- * We need this map is because existing audio_effects.xml don't have a type UUID defined.
- */
-static const std::map<const std::string /* effect type */, const AudioUuid&> kUuidNameTypeMap = {
-        {"acoustic_echo_canceler", kAcousticEchoCancelerTypeUUID},
-        {"automatic_gain_control", kAutomaticGainControlTypeUUID},
-        {"bassboost", kBassBoostTypeUUID},
-        {"downmix", kDownmixTypeUUID},
-        {"dynamics_processing", kDynamicsProcessingTypeUUID},
-        {"equalizer", kEqualizerTypeUUID},
-        {"haptic_generator", kHapticGeneratorTypeUUID},
-        {"loudness_enhancer", kLoudnessEnhancerTypeUUID},
-        {"env_reverb", kEnvReverbTypeUUID},
-        {"noise_suppression", kNoiseSuppressionTypeUUID},
-        {"preset_reverb", kPresetReverbTypeUUID},
-        {"reverb_env_aux", kEnvReverbTypeUUID},
-        {"reverb_env_ins", kEnvReverbTypeUUID},
-        {"reverb_pre_aux", kPresetReverbTypeUUID},
-        {"reverb_pre_ins", kPresetReverbTypeUUID},
-        {"virtualizer", kVirtualizerTypeUUID},
-        {"visualizer", kVisualizerTypeUUID},
-        {"volume", kVolumeTypeUUID},
-};
-
-}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/include/effectFactory-impl/EffectConfig.h b/audio/aidl/default/include/effectFactory-impl/EffectConfig.h
index c499811..c627a27 100644
--- a/audio/aidl/default/include/effectFactory-impl/EffectConfig.h
+++ b/audio/aidl/default/include/effectFactory-impl/EffectConfig.h
@@ -17,6 +17,7 @@
 #pragma once
 
 #include <functional>
+#include <map>
 #include <memory>
 #include <string>
 #include <unordered_map>
@@ -62,6 +63,9 @@
         return mProcessingMap;
     }
 
+    static bool findUuid(const std::string& xmlEffectName,
+                         ::aidl::android::media::audio::common::AudioUuid* uuid);
+
   private:
     static constexpr const char* kEffectLibPath[] =
 #ifdef __LP64__
diff --git a/audio/aidl/default/include/effectFactory-impl/EffectFactory.h b/audio/aidl/default/include/effectFactory-impl/EffectFactory.h
index fc9ef02..b7f63af 100644
--- a/audio/aidl/default/include/effectFactory-impl/EffectFactory.h
+++ b/audio/aidl/default/include/effectFactory-impl/EffectFactory.h
@@ -105,7 +105,7 @@
                            const std::string& path);
     void createIdentityWithConfig(
             const EffectConfig::LibraryUuid& configLib,
-            const ::aidl::android::media::audio::common::AudioUuid& typeUuid,
+            const ::aidl::android::media::audio::common::AudioUuid& typeUuidStr,
             const std::optional<::aidl::android::media::audio::common::AudioUuid> proxyUuid);
     void loadEffectLibs();
     /* Get effect_dl_interface_s from library handle */
diff --git a/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.cpp b/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.cpp
index da02076..7954316 100644
--- a/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.cpp
+++ b/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.cpp
@@ -14,27 +14,27 @@
  * limitations under the License.
  */
 
-#include <cstddef>
-#define LOG_TAG "AHAL_LoudnessEnhancerSw"
-#include <Utils.h>
 #include <algorithm>
-#include <unordered_set>
+#include <cstddef>
 
+#define LOG_TAG "AHAL_LoudnessEnhancerSw"
 #include <android-base/logging.h>
 #include <fmq/AidlMessageQueue.h>
+#include <system/audio_effects/effect_uuid.h>
 
 #include "LoudnessEnhancerSw.h"
 
 using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectImplUuidLoudnessEnhancerSw;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidLoudnessEnhancer;
 using aidl::android::hardware::audio::effect::IEffect;
-using aidl::android::hardware::audio::effect::kLoudnessEnhancerSwImplUUID;
 using aidl::android::hardware::audio::effect::LoudnessEnhancerSw;
 using aidl::android::hardware::audio::effect::State;
 using aidl::android::media::audio::common::AudioUuid;
 
 extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
                                            std::shared_ptr<IEffect>* instanceSpp) {
-    if (!in_impl_uuid || *in_impl_uuid != kLoudnessEnhancerSwImplUUID) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidLoudnessEnhancerSw()) {
         LOG(ERROR) << __func__ << "uuid not supported";
         return EX_ILLEGAL_ARGUMENT;
     }
@@ -49,7 +49,7 @@
 }
 
 extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
-    if (!in_impl_uuid || *in_impl_uuid != kLoudnessEnhancerSwImplUUID) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidLoudnessEnhancerSw()) {
         LOG(ERROR) << __func__ << "uuid not supported";
         return EX_ILLEGAL_ARGUMENT;
     }
@@ -61,8 +61,8 @@
 
 const std::string LoudnessEnhancerSw::kEffectName = "LoudnessEnhancerSw";
 const Descriptor LoudnessEnhancerSw::kDescriptor = {
-        .common = {.id = {.type = kLoudnessEnhancerTypeUUID,
-                          .uuid = kLoudnessEnhancerSwImplUUID,
+        .common = {.id = {.type = getEffectTypeUuidLoudnessEnhancer(),
+                          .uuid = getEffectImplUuidLoudnessEnhancerSw(),
                           .proxy = std::nullopt},
                    .flags = {.type = Flags::Type::INSERT,
                              .insert = Flags::Insert::FIRST,
diff --git a/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.h b/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.h
index 5da70c7..25824f2 100644
--- a/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.h
+++ b/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.h
@@ -22,7 +22,6 @@
 #include <memory>
 
 #include "effect-impl/EffectImpl.h"
-#include "effect-impl/EffectUUID.h"
 
 namespace aidl::android::hardware::audio::effect {
 
@@ -47,7 +46,6 @@
 class LoudnessEnhancerSw final : public EffectImpl {
   public:
     static const std::string kEffectName;
-    static const LoudnessEnhancer::Capability kCapability;
     static const Descriptor kDescriptor;
     LoudnessEnhancerSw() { LOG(DEBUG) << __func__; }
     ~LoudnessEnhancerSw() {
diff --git a/audio/aidl/default/main.cpp b/audio/aidl/default/main.cpp
index a861f9d..af71aa8 100644
--- a/audio/aidl/default/main.cpp
+++ b/audio/aidl/default/main.cpp
@@ -41,6 +41,9 @@
     // android::base::SetMinimumLogSeverity(::android::base::VERBOSE);
     ABinderProcess_setThreadPoolMaxThreadCount(16);
 
+    // Guaranteed log for b/210919187 and logd_integration_test
+    LOG(INFO) << "Init for Audio AIDL HAL";
+
     // Make the default config service
     auto config = ndk::SharedRefBase::make<Config>();
     const std::string configName = std::string() + Config::descriptor + "/default";
diff --git a/audio/aidl/default/noiseSuppression/NoiseSuppressionSw.cpp b/audio/aidl/default/noiseSuppression/NoiseSuppressionSw.cpp
index a36cfe0..9b2cb7c 100644
--- a/audio/aidl/default/noiseSuppression/NoiseSuppressionSw.cpp
+++ b/audio/aidl/default/noiseSuppression/NoiseSuppressionSw.cpp
@@ -18,23 +18,24 @@
 #include <cstddef>
 #include <memory>
 #define LOG_TAG "AHAL_NoiseSuppressionSw"
-#include <Utils.h>
-#include <unordered_set>
 
+#define LOG_TAG "AHAL_NoiseSuppressionSw"
 #include <android-base/logging.h>
 #include <fmq/AidlMessageQueue.h>
+#include <system/audio_effects/effect_uuid.h>
 
 #include "NoiseSuppressionSw.h"
 
 using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectImplUuidNoiseSuppressionSw;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidNoiseSuppression;
 using aidl::android::hardware::audio::effect::IEffect;
-using aidl::android::hardware::audio::effect::kNoiseSuppressionSwImplUUID;
 using aidl::android::hardware::audio::effect::NoiseSuppressionSw;
 using aidl::android::media::audio::common::AudioUuid;
 
 extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
                                            std::shared_ptr<IEffect>* instanceSpp) {
-    if (!in_impl_uuid || *in_impl_uuid != kNoiseSuppressionSwImplUUID) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidNoiseSuppressionSw()) {
         LOG(ERROR) << __func__ << "uuid not supported";
         return EX_ILLEGAL_ARGUMENT;
     }
@@ -49,7 +50,7 @@
 }
 
 extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
-    if (!in_impl_uuid || *in_impl_uuid != kNoiseSuppressionSwImplUUID) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidNoiseSuppressionSw()) {
         LOG(ERROR) << __func__ << "uuid not supported";
         return EX_ILLEGAL_ARGUMENT;
     }
@@ -60,18 +61,15 @@
 namespace aidl::android::hardware::audio::effect {
 
 const std::string NoiseSuppressionSw::kEffectName = "NoiseSuppressionSw";
-const NoiseSuppression::Capability NoiseSuppressionSw::kCapability;
 const Descriptor NoiseSuppressionSw::kDescriptor = {
-        .common = {.id = {.type = kNoiseSuppressionTypeUUID,
-                          .uuid = kNoiseSuppressionSwImplUUID,
+        .common = {.id = {.type = getEffectTypeUuidNoiseSuppression(),
+                          .uuid = getEffectImplUuidNoiseSuppressionSw(),
                           .proxy = std::nullopt},
                    .flags = {.type = Flags::Type::INSERT,
                              .insert = Flags::Insert::FIRST,
                              .volume = Flags::Volume::CTRL},
                    .name = NoiseSuppressionSw::kEffectName,
-                   .implementor = "The Android Open Source Project"},
-        .capability =
-                Capability::make<Capability::noiseSuppression>(NoiseSuppressionSw::kCapability)};
+                   .implementor = "The Android Open Source Project"}};
 
 ndk::ScopedAStatus NoiseSuppressionSw::getDescriptor(Descriptor* _aidl_return) {
     LOG(DEBUG) << __func__ << kDescriptor.toString();
@@ -90,10 +88,15 @@
     switch (tag) {
         case NoiseSuppression::level: {
             RETURN_IF(mContext->setLevel(param.get<NoiseSuppression::level>()) != RetCode::SUCCESS,
-                      EX_ILLEGAL_ARGUMENT, "levelSupported");
+                      EX_ILLEGAL_ARGUMENT, "levelNotSupported");
             return ndk::ScopedAStatus::ok();
         }
-        default: {
+        case NoiseSuppression::type: {
+            RETURN_IF(mContext->setType(param.get<NoiseSuppression::type>()) != RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "typeNotSupported");
+            return ndk::ScopedAStatus::ok();
+        }
+        case NoiseSuppression::vendor: {
             LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
             return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
                     EX_ILLEGAL_ARGUMENT, "NoiseSuppressionTagNotSupported");
@@ -111,10 +114,11 @@
         case NoiseSuppression::Id::commonTag:
             return getParameterNoiseSuppression(specificId.get<NoiseSuppression::Id::commonTag>(),
                                                 specific);
-        default:
+        case NoiseSuppression::Id::vendorExtensionTag: {
             LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
             return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
                     EX_ILLEGAL_ARGUMENT, "NoiseSuppressionTagNotSupported");
+        }
     }
 }
 
@@ -127,7 +131,11 @@
             param.set<NoiseSuppression::level>(mContext->getLevel());
             break;
         }
-        default: {
+        case NoiseSuppression::type: {
+            param.set<NoiseSuppression::type>(mContext->getType());
+            break;
+        }
+        case NoiseSuppression::vendor: {
             LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
             return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
                     EX_ILLEGAL_ARGUMENT, "NoiseSuppressionTagNotSupported");
@@ -177,4 +185,9 @@
     return mLevel;
 }
 
+RetCode NoiseSuppressionSwContext::setType(NoiseSuppression::Type type) {
+    mType = type;
+    return RetCode::SUCCESS;
+}
+
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/noiseSuppression/NoiseSuppressionSw.h b/audio/aidl/default/noiseSuppression/NoiseSuppressionSw.h
index f39d8e5..fc1e028 100644
--- a/audio/aidl/default/noiseSuppression/NoiseSuppressionSw.h
+++ b/audio/aidl/default/noiseSuppression/NoiseSuppressionSw.h
@@ -16,13 +16,13 @@
 
 #pragma once
 
-#include <aidl/android/hardware/audio/effect/BnEffect.h>
-#include <fmq/AidlMessageQueue.h>
 #include <cstdlib>
 #include <memory>
 
+#include <aidl/android/hardware/audio/effect/BnEffect.h>
+#include <fmq/AidlMessageQueue.h>
+
 #include "effect-impl/EffectImpl.h"
-#include "effect-impl/EffectUUID.h"
 
 namespace aidl::android::hardware::audio::effect {
 
@@ -35,16 +35,18 @@
 
     RetCode setLevel(NoiseSuppression::Level level);
     NoiseSuppression::Level getLevel();
+    RetCode setType(NoiseSuppression::Type type);
+    NoiseSuppression::Type getType() { return mType; }
 
   private:
     NoiseSuppression::Level mLevel = NoiseSuppression::Level::LOW;
+    NoiseSuppression::Type mType = NoiseSuppression::Type::SINGLE_CHANNEL;
 };
 
 class NoiseSuppressionSw final : public EffectImpl {
   public:
     static const std::string kEffectName;
     static const bool kStrengthSupported;
-    static const NoiseSuppression::Capability kCapability;
     static const Descriptor kDescriptor;
     NoiseSuppressionSw() { LOG(DEBUG) << __func__; }
     ~NoiseSuppressionSw() {
diff --git a/audio/aidl/default/presetReverb/PresetReverbSw.cpp b/audio/aidl/default/presetReverb/PresetReverbSw.cpp
index d038596..3f02eb7 100644
--- a/audio/aidl/default/presetReverb/PresetReverbSw.cpp
+++ b/audio/aidl/default/presetReverb/PresetReverbSw.cpp
@@ -14,28 +14,28 @@
  * limitations under the License.
  */
 
-#include <cstddef>
-#define LOG_TAG "AHAL_PresetReverbSw"
-#include <Utils.h>
 #include <algorithm>
-#include <unordered_set>
+#include <cstddef>
 
+#define LOG_TAG "AHAL_PresetReverbSw"
 #include <android-base/logging.h>
 #include <android/binder_enums.h>
 #include <fmq/AidlMessageQueue.h>
+#include <system/audio_effects/effect_uuid.h>
 
 #include "PresetReverbSw.h"
 
 using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectImplUuidPresetReverbSw;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidPresetReverb;
 using aidl::android::hardware::audio::effect::IEffect;
-using aidl::android::hardware::audio::effect::kPresetReverbSwImplUUID;
 using aidl::android::hardware::audio::effect::PresetReverbSw;
 using aidl::android::hardware::audio::effect::State;
 using aidl::android::media::audio::common::AudioUuid;
 
 extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
                                            std::shared_ptr<IEffect>* instanceSpp) {
-    if (!in_impl_uuid || *in_impl_uuid != kPresetReverbSwImplUUID) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidPresetReverbSw()) {
         LOG(ERROR) << __func__ << "uuid not supported";
         return EX_ILLEGAL_ARGUMENT;
     }
@@ -50,7 +50,7 @@
 }
 
 extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
-    if (!in_impl_uuid || *in_impl_uuid != kPresetReverbSwImplUUID) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidPresetReverbSw()) {
         LOG(ERROR) << __func__ << "uuid not supported";
         return EX_ILLEGAL_ARGUMENT;
     }
@@ -62,22 +62,27 @@
 
 const std::string PresetReverbSw::kEffectName = "PresetReverbSw";
 
-const std::vector<PresetReverb::Presets> kSupportedPresets{
+const std::vector<PresetReverb::Presets> PresetReverbSw::kSupportedPresets{
         ndk::enum_range<PresetReverb::Presets>().begin(),
         ndk::enum_range<PresetReverb::Presets>().end()};
 
-const PresetReverb::Capability PresetReverbSw::kCapability = {.supportedPresets =
-                                                                      kSupportedPresets};
+const std::vector<Range::PresetReverbRange> PresetReverbSw::kRanges = {
+        MAKE_RANGE(PresetReverb, supportedPresets, PresetReverbSw::kSupportedPresets,
+                   PresetReverbSw::kSupportedPresets)};
+
+const Capability PresetReverbSw::kCapability = {
+        .range = Range::make<Range::presetReverb>(PresetReverbSw::kRanges)};
+
 const Descriptor PresetReverbSw::kDescriptor = {
-        .common = {.id = {.type = kPresetReverbTypeUUID,
-                          .uuid = kPresetReverbSwImplUUID,
+        .common = {.id = {.type = getEffectTypeUuidPresetReverb(),
+                          .uuid = getEffectImplUuidPresetReverbSw(),
                           .proxy = std::nullopt},
                    .flags = {.type = Flags::Type::INSERT,
                              .insert = Flags::Insert::FIRST,
                              .volume = Flags::Volume::CTRL},
                    .name = PresetReverbSw::kEffectName,
                    .implementor = "The Android Open Source Project"},
-        .capability = Capability::make<Capability::presetReverb>(PresetReverbSw::kCapability)};
+        .capability = PresetReverbSw::kCapability};
 
 ndk::ScopedAStatus PresetReverbSw::getDescriptor(Descriptor* _aidl_return) {
     LOG(DEBUG) << __func__ << kDescriptor.toString();
@@ -92,6 +97,7 @@
     RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
 
     auto& prParam = specific.get<Parameter::Specific::presetReverb>();
+    RETURN_IF(!inRange(prParam, kRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
     auto tag = prParam.getTag();
 
     switch (tag) {
diff --git a/audio/aidl/default/presetReverb/PresetReverbSw.h b/audio/aidl/default/presetReverb/PresetReverbSw.h
index eb1d80a..9ceee7c 100644
--- a/audio/aidl/default/presetReverb/PresetReverbSw.h
+++ b/audio/aidl/default/presetReverb/PresetReverbSw.h
@@ -22,7 +22,6 @@
 #include <memory>
 
 #include "effect-impl/EffectImpl.h"
-#include "effect-impl/EffectUUID.h"
 
 namespace aidl::android::hardware::audio::effect {
 
@@ -46,7 +45,9 @@
 class PresetReverbSw final : public EffectImpl {
   public:
     static const std::string kEffectName;
-    static const PresetReverb::Capability kCapability;
+    static const std::vector<PresetReverb::Presets> kSupportedPresets;
+    static const std::vector<Range::PresetReverbRange> kRanges;
+    static const Capability kCapability;
     static const Descriptor kDescriptor;
     PresetReverbSw() { LOG(DEBUG) << __func__; }
     ~PresetReverbSw() {
diff --git a/audio/aidl/default/usb/ModuleUsb.cpp b/audio/aidl/default/usb/ModuleUsb.cpp
index e803420..89895bf 100644
--- a/audio/aidl/default/usb/ModuleUsb.cpp
+++ b/audio/aidl/default/usb/ModuleUsb.cpp
@@ -22,6 +22,7 @@
 #include <android-base/logging.h>
 #include <tinyalsa/asoundlib.h>
 
+#include "UsbAlsaMixerControl.h"
 #include "UsbAlsaUtils.h"
 #include "core-impl/ModuleUsb.h"
 
@@ -29,6 +30,7 @@
 #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;
@@ -39,7 +41,6 @@
 using aidl::android::media::audio::common::AudioPortConfig;
 using aidl::android::media::audio::common::AudioPortExt;
 using aidl::android::media::audio::common::AudioProfile;
-using android::hardware::audio::common::isUsbInputDeviceType;
 
 namespace aidl::android::hardware::audio::core {
 
@@ -86,26 +87,6 @@
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus ModuleUsb::getMasterMute(bool* _aidl_return __unused) {
-    LOG(DEBUG) << __func__ << ": is not supported";
-    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
-}
-
-ndk::ScopedAStatus ModuleUsb::setMasterMute(bool in_mute __unused) {
-    LOG(DEBUG) << __func__ << ": is not supported";
-    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
-}
-
-ndk::ScopedAStatus ModuleUsb::getMasterVolume(float* _aidl_return __unused) {
-    LOG(DEBUG) << __func__ << ": is not supported";
-    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
-}
-
-ndk::ScopedAStatus ModuleUsb::setMasterVolume(float in_volume __unused) {
-    LOG(DEBUG) << __func__ << ": is not supported";
-    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
-}
-
 ndk::ScopedAStatus ModuleUsb::getMicMute(bool* _aidl_return __unused) {
     LOG(DEBUG) << __func__ << ": is not supported";
     return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
@@ -139,7 +120,11 @@
     const bool isInput = isUsbInputDeviceType(devicePort.device.type.type);
     alsa_device_profile profile;
     profile_init(&profile, isInput ? PCM_IN : PCM_OUT);
+    profile.card = alsaAddress[0];
+    profile.device = alsaAddress[1];
     if (!profile_read_device_info(&profile)) {
+        LOG(ERROR) << __func__ << ": failed to read device info, card=" << profile.card
+                   << ", device=" << profile.device;
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
     }
 
@@ -180,4 +165,26 @@
     return ndk::ScopedAStatus::ok();
 }
 
+void ModuleUsb::onExternalDeviceConnectionChanged(
+        const ::aidl::android::media::audio::common::AudioPort& audioPort, bool connected) {
+    if (audioPort.ext.getTag() != AudioPortExt::Tag::device) {
+        return;
+    }
+    const auto& address = audioPort.ext.get<AudioPortExt::Tag::device>().device.address;
+    if (address.getTag() != AudioDeviceAddress::alsa) {
+        return;
+    }
+    const int card = address.get<AudioDeviceAddress::alsa>()[0];
+    usb::UsbAlsaMixerControl::getInstance().setDeviceConnectionState(card, mMasterMute,
+                                                                     mMasterVolume, connected);
+}
+
+ndk::ScopedAStatus ModuleUsb::onMasterMuteChanged(bool mute) {
+    return usb::UsbAlsaMixerControl::getInstance().setMasterMute(mute);
+}
+
+ndk::ScopedAStatus ModuleUsb::onMasterVolumeChanged(float volume) {
+    return usb::UsbAlsaMixerControl::getInstance().setMasterVolume(volume);
+}
+
 }  // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/usb/StreamUsb.cpp b/audio/aidl/default/usb/StreamUsb.cpp
index 22e36ac..5d1d7fe 100644
--- a/audio/aidl/default/usb/StreamUsb.cpp
+++ b/audio/aidl/default/usb/StreamUsb.cpp
@@ -17,6 +17,9 @@
 #define LOG_TAG "AHAL_StreamUsb"
 #include <android-base/logging.h>
 
+#include <Utils.h>
+
+#include "UsbAlsaMixerControl.h"
 #include "UsbAlsaUtils.h"
 #include "core-impl/Module.h"
 #include "core-impl/StreamUsb.h"
@@ -25,11 +28,17 @@
 #include "alsa_device_profile.h"
 }
 
+using aidl::android::hardware::audio::common::getChannelCount;
 using aidl::android::hardware::audio::common::SinkMetadata;
 using aidl::android::hardware::audio::common::SourceMetadata;
 using aidl::android::media::audio::common::AudioDevice;
 using aidl::android::media::audio::common::AudioDeviceAddress;
 using aidl::android::media::audio::common::AudioOffloadInfo;
+using aidl::android::media::audio::common::AudioPortExt;
+using aidl::android::media::audio::common::MicrophoneDynamicInfo;
+using aidl::android::media::audio::common::MicrophoneInfo;
+using android::OK;
+using android::status_t;
 
 namespace aidl::android::hardware::audio::core {
 
@@ -98,10 +107,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;
     }
     if (mIsStandby) {
         if (::android::status_t status = exitStandby(); status != ::android::OK) {
+            LOG(ERROR) << __func__ << ": failed to exit standby, status=" << status;
             return status;
         }
     }
@@ -142,6 +154,7 @@
     std::vector<std::shared_ptr<alsa_device_proxy>> alsaDeviceProxies;
     for (const auto& device : connectedDevices) {
         alsa_device_profile profile;
+        profile_init(&profile, mIsInput ? PCM_IN : PCM_OUT);
         profile.card = device.get<AudioDeviceAddress::alsa>()[0];
         profile.device = device.get<AudioDeviceAddress::alsa>()[1];
         if (!profile_read_device_info(&profile)) {
@@ -165,6 +178,11 @@
                        << " error=" << err;
             return ::android::UNKNOWN_ERROR;
         }
+        if (int err = proxy_open(proxy.get()); err != 0) {
+            LOG(ERROR) << __func__ << ": failed to open device, address=" << device.toString()
+                       << " error=" << err;
+            return ::android::UNKNOWN_ERROR;
+        }
         alsaDeviceProxies.push_back(std::move(proxy));
     }
     {
@@ -237,6 +255,31 @@
                   // The default worker implementation is used.
                   return new StreamOutWorker(ctx, driver);
               },
-              offloadInfo) {}
+              offloadInfo) {
+    mChannelCount = getChannelCount(mContext.getChannelLayout());
+}
 
-}  // namespace aidl::android::hardware::audio::core
\ No newline at end of file
+ndk::ScopedAStatus StreamOutUsb::getHwVolume(std::vector<float>* _aidl_return) {
+    *_aidl_return = mHwVolumes;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StreamOutUsb::setHwVolume(const std::vector<float>& in_channelVolumes) {
+    for (const auto& device : mConnectedDevices) {
+        if (device.address.getTag() != AudioDeviceAddress::alsa) {
+            LOG(DEBUG) << __func__ << ": skip as the device address is not alsa";
+            continue;
+        }
+        const int card = device.address.get<AudioDeviceAddress::alsa>()[0];
+        if (auto result =
+                    usb::UsbAlsaMixerControl::getInstance().setVolumes(card, in_channelVolumes);
+            !result.isOk()) {
+            LOG(ERROR) << __func__ << ": failed to set volume for device, card=" << card;
+            return result;
+        }
+    }
+    mHwVolumes = in_channelVolumes;
+    return ndk::ScopedAStatus::ok();
+}
+
+}  // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/usb/UsbAlsaMixerControl.cpp b/audio/aidl/default/usb/UsbAlsaMixerControl.cpp
new file mode 100644
index 0000000..b5337d1
--- /dev/null
+++ b/audio/aidl/default/usb/UsbAlsaMixerControl.cpp
@@ -0,0 +1,239 @@
+/*
+ * 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_UsbAlsaMixerControl"
+#include <android-base/logging.h>
+
+#include <cmath>
+#include <string>
+#include <vector>
+
+#include <android/binder_status.h>
+
+#include "UsbAlsaMixerControl.h"
+
+namespace aidl::android::hardware::audio::core::usb {
+
+//-----------------------------------------------------------------------------
+
+MixerControl::MixerControl(struct mixer_ctl* ctl)
+    : mCtl(ctl),
+      mNumValues(mixer_ctl_get_num_values(ctl)),
+      mMinValue(mixer_ctl_get_range_min(ctl)),
+      mMaxValue(mixer_ctl_get_range_max(ctl)) {}
+
+unsigned int MixerControl::getNumValues() const {
+    return mNumValues;
+}
+
+int MixerControl::getMaxValue() const {
+    return mMaxValue;
+}
+
+int MixerControl::getMinValue() const {
+    return mMinValue;
+}
+
+int MixerControl::setArray(const void* array, size_t count) {
+    const std::lock_guard guard(mLock);
+    return mixer_ctl_set_array(mCtl, array, count);
+}
+
+//-----------------------------------------------------------------------------
+
+// static
+const std::map<AlsaMixer::Control, std::vector<AlsaMixer::ControlNamesAndExpectedCtlType>>
+        AlsaMixer::kPossibleControls = {
+                {AlsaMixer::MASTER_SWITCH, {{"Master Playback Switch", MIXER_CTL_TYPE_BOOL}}},
+                {AlsaMixer::MASTER_VOLUME, {{"Master Playback Volume", MIXER_CTL_TYPE_INT}}},
+                {AlsaMixer::HW_VOLUME,
+                 {{"Headphone Playback Volume", MIXER_CTL_TYPE_INT},
+                  {"Headset Playback Volume", MIXER_CTL_TYPE_INT},
+                  {"PCM Playback Volume", MIXER_CTL_TYPE_INT}}}};
+
+// static
+std::map<AlsaMixer::Control, std::shared_ptr<MixerControl>> AlsaMixer::initializeMixerControls(
+        struct mixer* mixer) {
+    std::map<AlsaMixer::Control, std::shared_ptr<MixerControl>> mixerControls;
+    std::string mixerCtlNames;
+    for (const auto& [control, possibleCtls] : kPossibleControls) {
+        for (const auto& [ctlName, expectedCtlType] : possibleCtls) {
+            struct mixer_ctl* ctl = mixer_get_ctl_by_name(mixer, ctlName.c_str());
+            if (ctl != nullptr && mixer_ctl_get_type(ctl) == expectedCtlType) {
+                mixerControls.emplace(control, std::make_unique<MixerControl>(ctl));
+                if (!mixerCtlNames.empty()) {
+                    mixerCtlNames += ",";
+                }
+                mixerCtlNames += ctlName;
+                break;
+            }
+        }
+    }
+    LOG(DEBUG) << __func__ << ": available mixer control names=[" << mixerCtlNames << "]";
+    return mixerControls;
+}
+
+AlsaMixer::AlsaMixer(struct mixer* mixer)
+    : mMixer(mixer), mMixerControls(initializeMixerControls(mMixer)) {}
+
+AlsaMixer::~AlsaMixer() {
+    mixer_close(mMixer);
+}
+
+namespace {
+
+int volumeFloatToInteger(float fValue, int maxValue, int minValue) {
+    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) {
+    auto it = mMixerControls.find(AlsaMixer::MASTER_SWITCH);
+    if (it == mMixerControls.end()) {
+        return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+    }
+    const int numValues = it->second->getNumValues();
+    std::vector<int> values(numValues, muted ? 0 : 1);
+    if (int err = it->second->setArray(values.data(), numValues); err != 0) {
+        LOG(ERROR) << __func__ << ": failed to set master mute, err=" << err;
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus AlsaMixer::setMasterVolume(float volume) {
+    auto it = mMixerControls.find(AlsaMixer::MASTER_VOLUME);
+    if (it == mMixerControls.end()) {
+        return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+    }
+    const int numValues = it->second->getNumValues();
+    std::vector<int> values(numValues, volumeFloatToInteger(volume, it->second->getMaxValue(),
+                                                            it->second->getMinValue()));
+    if (int err = it->second->setArray(values.data(), numValues); err != 0) {
+        LOG(ERROR) << __func__ << ": failed to set master volume, err=" << err;
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus AlsaMixer::setVolumes(std::vector<float> volumes) {
+    auto it = mMixerControls.find(AlsaMixer::HW_VOLUME);
+    if (it == mMixerControls.end()) {
+        return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+    }
+    const int numValues = it->second->getNumValues();
+    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) {
+        values.emplace_back(volumeFloatToInteger(volumes[i], maxValue, minValue));
+    }
+    if (int err = it->second->setArray(values.data(), values.size()); err != 0) {
+        LOG(ERROR) << __func__ << ": failed to set volume, err=" << err;
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+//-----------------------------------------------------------------------------
+
+// static
+UsbAlsaMixerControl& UsbAlsaMixerControl::getInstance() {
+    static UsbAlsaMixerControl gInstance;
+    return gInstance;
+}
+
+void UsbAlsaMixerControl::setDeviceConnectionState(int card, bool masterMuted, float masterVolume,
+                                                   bool connected) {
+    LOG(DEBUG) << __func__ << ": card=" << card << ", connected=" << connected;
+    if (connected) {
+        struct mixer* mixer = mixer_open(card);
+        if (mixer == nullptr) {
+            PLOG(ERROR) << __func__ << ": failed to open mixer for card=" << card;
+            return;
+        }
+        auto alsaMixer = std::make_shared<AlsaMixer>(mixer);
+        alsaMixer->setMasterMute(masterMuted);
+        alsaMixer->setMasterVolume(masterVolume);
+        const std::lock_guard guard(mLock);
+        mMixerControls.emplace(card, alsaMixer);
+    } else {
+        const std::lock_guard guard(mLock);
+        mMixerControls.erase(card);
+    }
+}
+
+ndk::ScopedAStatus UsbAlsaMixerControl::setMasterMute(bool mute) {
+    auto alsaMixers = getAlsaMixers();
+    for (auto it = alsaMixers.begin(); it != alsaMixers.end(); ++it) {
+        if (auto result = it->second->setMasterMute(mute); !result.isOk()) {
+            // Return illegal state if there are multiple devices connected and one of them fails
+            // to set master mute. Otherwise, return the error from calling `setMasterMute`.
+            LOG(ERROR) << __func__ << ": failed to set master mute for card=" << it->first;
+            return alsaMixers.size() > 1 ? ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE)
+                                         : std::move(result);
+        }
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus UsbAlsaMixerControl::setMasterVolume(float volume) {
+    auto alsaMixers = getAlsaMixers();
+    for (auto it = alsaMixers.begin(); it != alsaMixers.end(); ++it) {
+        if (auto result = it->second->setMasterVolume(volume); !result.isOk()) {
+            // Return illegal state if there are multiple devices connected and one of them fails
+            // to set master volume. Otherwise, return the error from calling `setMasterVolume`.
+            LOG(ERROR) << __func__ << ": failed to set master volume for card=" << it->first;
+            return alsaMixers.size() > 1 ? ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE)
+                                         : std::move(result);
+        }
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus UsbAlsaMixerControl::setVolumes(int card, std::vector<float> volumes) {
+    auto alsaMixer = getAlsaMixer(card);
+    if (alsaMixer == nullptr) {
+        LOG(ERROR) << __func__ << ": no mixer control found for card=" << card;
+        return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+    }
+    return alsaMixer->setVolumes(volumes);
+}
+
+std::shared_ptr<AlsaMixer> UsbAlsaMixerControl::getAlsaMixer(int card) {
+    const std::lock_guard guard(mLock);
+    const auto it = mMixerControls.find(card);
+    return it == mMixerControls.end() ? nullptr : it->second;
+}
+
+std::map<int, std::shared_ptr<AlsaMixer>> UsbAlsaMixerControl::getAlsaMixers() {
+    const std::lock_guard guard(mLock);
+    return mMixerControls;
+}
+
+}  // namespace aidl::android::hardware::audio::core::usb
diff --git a/audio/aidl/default/usb/UsbAlsaMixerControl.h b/audio/aidl/default/usb/UsbAlsaMixerControl.h
new file mode 100644
index 0000000..cbcddd8
--- /dev/null
+++ b/audio/aidl/default/usb/UsbAlsaMixerControl.h
@@ -0,0 +1,106 @@
+/*
+ * 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 <map>
+#include <memory>
+#include <mutex>
+#include <optional>
+#include <string>
+#include <vector>
+
+#include <android-base/thread_annotations.h>
+#include <android/binder_auto_utils.h>
+
+extern "C" {
+#include <tinyalsa/mixer.h>
+}
+
+namespace aidl::android::hardware::audio::core::usb {
+
+class MixerControl {
+  public:
+    explicit MixerControl(struct mixer_ctl* ctl);
+
+    unsigned int getNumValues() const;
+    int getMaxValue() const;
+    int getMinValue() const;
+    int setArray(const void* array, size_t count);
+
+  private:
+    std::mutex mLock;
+    // The mixer_ctl object is owned by ALSA and will be released when the mixer is closed.
+    struct mixer_ctl* mCtl GUARDED_BY(mLock);
+    const unsigned int mNumValues;
+    const int mMinValue;
+    const int mMaxValue;
+};
+
+class AlsaMixer {
+  public:
+    explicit AlsaMixer(struct mixer* mixer);
+
+    ~AlsaMixer();
+
+    bool isValid() const { return mMixer != nullptr; }
+
+    ndk::ScopedAStatus setMasterMute(bool muted);
+    ndk::ScopedAStatus setMasterVolume(float volume);
+    ndk::ScopedAStatus setVolumes(std::vector<float> volumes);
+
+  private:
+    enum Control {
+        MASTER_SWITCH,
+        MASTER_VOLUME,
+        HW_VOLUME,
+    };
+    using ControlNamesAndExpectedCtlType = std::pair<std::string, enum mixer_ctl_type>;
+    static const std::map<Control, std::vector<ControlNamesAndExpectedCtlType>> kPossibleControls;
+    static std::map<Control, std::shared_ptr<MixerControl>> initializeMixerControls(
+            struct mixer* mixer);
+
+    // The mixer object is owned by ALSA and will be released when the mixer is closed.
+    struct mixer* mMixer;
+    // `mMixerControls` will only be initialized in constructor. After that, it wil only be
+    // read but not be modified.
+    const std::map<Control, std::shared_ptr<MixerControl>> mMixerControls;
+};
+
+class UsbAlsaMixerControl {
+  public:
+    static UsbAlsaMixerControl& getInstance();
+
+    void setDeviceConnectionState(int card, bool masterMuted, float masterVolume, bool connected);
+
+    // Master volume settings will be applied to all sound cards, it is only set by the
+    // USB module.
+    ndk::ScopedAStatus setMasterMute(bool muted);
+    ndk::ScopedAStatus setMasterVolume(float volume);
+    // The volume settings can be different on sound cards. It is controlled by streams.
+    ndk::ScopedAStatus setVolumes(int card, std::vector<float> volumes);
+
+  private:
+    std::shared_ptr<AlsaMixer> getAlsaMixer(int card);
+    std::map<int, std::shared_ptr<AlsaMixer>> getAlsaMixers();
+
+    std::mutex mLock;
+    // A map whose key is the card number and value is a shared pointer to corresponding
+    // AlsaMixer object.
+    std::map<int, std::shared_ptr<AlsaMixer>> mMixerControls GUARDED_BY(mLock);
+};
+
+}  // namespace aidl::android::hardware::audio::core::usb
diff --git a/audio/aidl/default/usb/UsbAlsaUtils.cpp b/audio/aidl/default/usb/UsbAlsaUtils.cpp
index 3c79e1d..74d9c28 100644
--- a/audio/aidl/default/usb/UsbAlsaUtils.cpp
+++ b/audio/aidl/default/usb/UsbAlsaUtils.cpp
@@ -24,11 +24,11 @@
 #include "UsbAlsaUtils.h"
 #include "core-impl/utils.h"
 
+using aidl::android::hardware::audio::common::getChannelCount;
 using aidl::android::media::audio::common::AudioChannelLayout;
 using aidl::android::media::audio::common::AudioFormatDescription;
 using aidl::android::media::audio::common::AudioFormatType;
 using aidl::android::media::audio::common::PcmType;
-using android::hardware::audio::common::getChannelCount;
 
 namespace aidl::android::hardware::audio::core::usb {
 
@@ -114,8 +114,8 @@
     static const AudioFormatDescToPcmFormatMap formatDescToPcmFormatMap = {
             {make_AudioFormatDescription(PcmType::UINT_8_BIT), PCM_FORMAT_S8},
             {make_AudioFormatDescription(PcmType::INT_16_BIT), PCM_FORMAT_S16_LE},
-            {make_AudioFormatDescription(PcmType::INT_24_BIT), PCM_FORMAT_S24_LE},
-            {make_AudioFormatDescription(PcmType::FIXED_Q_8_24), PCM_FORMAT_S24_3LE},
+            {make_AudioFormatDescription(PcmType::FIXED_Q_8_24), PCM_FORMAT_S24_LE},
+            {make_AudioFormatDescription(PcmType::INT_24_BIT), PCM_FORMAT_S24_3LE},
             {make_AudioFormatDescription(PcmType::INT_32_BIT), PCM_FORMAT_S32_LE},
             {make_AudioFormatDescription(PcmType::FLOAT_32_BIT), PCM_FORMAT_FLOAT_LE},
     };
@@ -178,4 +178,4 @@
     return findValueOrDefault(getAudioFormatDescriptorToPcmFormatMap(), aidl, PCM_FORMAT_INVALID);
 }
 
-}  // namespace aidl::android::hardware::audio::core::usb
\ No newline at end of file
+}  // namespace aidl::android::hardware::audio::core::usb
diff --git a/audio/aidl/default/virtualizer/VirtualizerSw.cpp b/audio/aidl/default/virtualizer/VirtualizerSw.cpp
index cc51937..e34464f 100644
--- a/audio/aidl/default/virtualizer/VirtualizerSw.cpp
+++ b/audio/aidl/default/virtualizer/VirtualizerSw.cpp
@@ -14,27 +14,31 @@
  * limitations under the License.
  */
 
+#include <algorithm>
 #include <cstddef>
+
 #define LOG_TAG "AHAL_VirtualizerSw"
 #include <Utils.h>
-#include <algorithm>
-#include <unordered_set>
-
 #include <android-base/logging.h>
 #include <fmq/AidlMessageQueue.h>
+#include <system/audio_effects/effect_uuid.h>
 
 #include "VirtualizerSw.h"
 
 using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectImplUuidVirtualizerSw;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidVirtualizer;
 using aidl::android::hardware::audio::effect::IEffect;
-using aidl::android::hardware::audio::effect::kVirtualizerSwImplUUID;
 using aidl::android::hardware::audio::effect::State;
 using aidl::android::hardware::audio::effect::VirtualizerSw;
+using aidl::android::media::audio::common::AudioChannelLayout;
+using aidl::android::media::audio::common::AudioDeviceDescription;
+using aidl::android::media::audio::common::AudioDeviceType;
 using aidl::android::media::audio::common::AudioUuid;
 
 extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
                                            std::shared_ptr<IEffect>* instanceSpp) {
-    if (!in_impl_uuid || *in_impl_uuid != kVirtualizerSwImplUUID) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidVirtualizerSw()) {
         LOG(ERROR) << __func__ << "uuid not supported";
         return EX_ILLEGAL_ARGUMENT;
     }
@@ -49,7 +53,7 @@
 }
 
 extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
-    if (!in_impl_uuid || *in_impl_uuid != kVirtualizerSwImplUUID) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidVirtualizerSw()) {
         LOG(ERROR) << __func__ << "uuid not supported";
         return EX_ILLEGAL_ARGUMENT;
     }
@@ -60,19 +64,26 @@
 namespace aidl::android::hardware::audio::effect {
 
 const std::string VirtualizerSw::kEffectName = "VirtualizerSw";
-const bool VirtualizerSw::kStrengthSupported = true;
-const Virtualizer::Capability VirtualizerSw::kCapability = {
-        .maxStrengthPm = 1000, .strengthSupported = kStrengthSupported};
+
+const std::vector<Range::VirtualizerRange> VirtualizerSw::kRanges = {
+        MAKE_RANGE(Virtualizer, strengthPm, 0, 1000),
+        /* speakerAngle is get-only, set min > max */
+        MAKE_RANGE(Virtualizer, speakerAngles, {Virtualizer::ChannelAngle({.channel = 1})},
+                   {Virtualizer::ChannelAngle({.channel = 0})})};
+
+const Capability VirtualizerSw::kCapability = {
+        .range = Range::make<Range::virtualizer>(VirtualizerSw::kRanges)};
+
 const Descriptor VirtualizerSw::kDescriptor = {
-        .common = {.id = {.type = kVirtualizerTypeUUID,
-                          .uuid = kVirtualizerSwImplUUID,
-                          .proxy = kVirtualizerProxyUUID},
+        .common = {.id = {.type = getEffectTypeUuidVirtualizer(),
+                          .uuid = getEffectImplUuidVirtualizerSw(),
+                          .proxy = getEffectImplUuidVirtualizerProxy()},
                    .flags = {.type = Flags::Type::INSERT,
                              .insert = Flags::Insert::FIRST,
                              .volume = Flags::Volume::CTRL},
                    .name = VirtualizerSw::kEffectName,
                    .implementor = "The Android Open Source Project"},
-        .capability = Capability::make<Capability::virtualizer>(VirtualizerSw::kCapability)};
+        .capability = VirtualizerSw::kCapability};
 
 ndk::ScopedAStatus VirtualizerSw::getDescriptor(Descriptor* _aidl_return) {
     LOG(DEBUG) << __func__ << kDescriptor.toString();
@@ -85,18 +96,25 @@
               "EffectNotSupported");
 
     auto& vrParam = specific.get<Parameter::Specific::virtualizer>();
+    RETURN_IF(!inRange(vrParam, kRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
     auto tag = vrParam.getTag();
 
     switch (tag) {
         case Virtualizer::strengthPm: {
-            RETURN_IF(!kStrengthSupported, EX_ILLEGAL_ARGUMENT, "SettingStrengthNotSupported");
-
             RETURN_IF(mContext->setVrStrength(vrParam.get<Virtualizer::strengthPm>()) !=
                               RetCode::SUCCESS,
-                      EX_ILLEGAL_ARGUMENT, "strengthPmNotSupported");
+                      EX_ILLEGAL_ARGUMENT, "setStrengthPmFailed");
             return ndk::ScopedAStatus::ok();
         }
-        default: {
+        case Virtualizer::device: {
+            RETURN_IF(mContext->setForcedDevice(vrParam.get<Virtualizer::device>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setDeviceFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        case Virtualizer::speakerAngles:
+            FALLTHROUGH_INTENDED;
+        case Virtualizer::vendor: {
             LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
             return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
                                                                     "VirtualizerTagNotSupported");
@@ -113,10 +131,13 @@
     switch (vrIdTag) {
         case Virtualizer::Id::commonTag:
             return getParameterVirtualizer(vrId.get<Virtualizer::Id::commonTag>(), specific);
-        default:
+        case Virtualizer::Id::speakerAnglesPayload:
+            return getSpeakerAngles(vrId.get<Virtualizer::Id::speakerAnglesPayload>(), specific);
+        case Virtualizer::Id::vendorExtensionTag: {
             LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
             return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
                                                                     "VirtualizerTagNotSupported");
+        }
     }
 }
 
@@ -130,7 +151,13 @@
             vrParam.set<Virtualizer::strengthPm>(mContext->getVrStrength());
             break;
         }
-        default: {
+        case Virtualizer::device: {
+            vrParam.set<Virtualizer::device>(mContext->getForcedDevice());
+            break;
+        }
+        case Virtualizer::speakerAngles:
+            FALLTHROUGH_INTENDED;
+        case Virtualizer::vendor: {
             LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
             return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
                                                                     "VirtualizerTagNotSupported");
@@ -141,6 +168,31 @@
     return ndk::ScopedAStatus::ok();
 }
 
+ndk::ScopedAStatus VirtualizerSw::getSpeakerAngles(const Virtualizer::SpeakerAnglesPayload payload,
+                                                   Parameter::Specific* specific) {
+    std::vector<Virtualizer::ChannelAngle> angles;
+    const auto chNum = ::aidl::android::hardware::audio::common::getChannelCount(payload.layout);
+    if (chNum == 1) {
+        angles = {{.channel = (int32_t)AudioChannelLayout::CHANNEL_FRONT_LEFT,
+                   .azimuthDegree = 0,
+                   .elevationDegree = 0}};
+    } else if (chNum == 2) {
+        angles = {{.channel = (int32_t)AudioChannelLayout::CHANNEL_FRONT_LEFT,
+                   .azimuthDegree = -90,
+                   .elevationDegree = 0},
+                  {.channel = (int32_t)AudioChannelLayout::CHANNEL_FRONT_RIGHT,
+                   .azimuthDegree = 90,
+                   .elevationDegree = 0}};
+    } else {
+        return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                "supportUpTo2Ch");
+    }
+
+    Virtualizer param = Virtualizer::make<Virtualizer::speakerAngles>(angles);
+    specific->set<Parameter::Specific::virtualizer>(param);
+    return ndk::ScopedAStatus::ok();
+}
+
 std::shared_ptr<EffectContext> VirtualizerSw::createContext(const Parameter::Common& common) {
     if (mContext) {
         LOG(DEBUG) << __func__ << " context already exist";
@@ -173,11 +225,6 @@
 }
 
 RetCode VirtualizerSwContext::setVrStrength(int strength) {
-    if (strength < 0 || strength > VirtualizerSw::kCapability.maxStrengthPm) {
-        LOG(ERROR) << __func__ << " invalid strength: " << strength;
-        return RetCode::ERROR_ILLEGAL_PARAMETER;
-    }
-    // TODO : Add implementation to apply new strength
     mStrength = strength;
     return RetCode::SUCCESS;
 }
diff --git a/audio/aidl/default/virtualizer/VirtualizerSw.h b/audio/aidl/default/virtualizer/VirtualizerSw.h
index 0f294cd..5e114d9 100644
--- a/audio/aidl/default/virtualizer/VirtualizerSw.h
+++ b/audio/aidl/default/virtualizer/VirtualizerSw.h
@@ -22,7 +22,6 @@
 #include <memory>
 
 #include "effect-impl/EffectImpl.h"
-#include "effect-impl/EffectUUID.h"
 
 namespace aidl::android::hardware::audio::effect {
 
@@ -34,16 +33,24 @@
     }
     RetCode setVrStrength(int strength);
     int getVrStrength() const { return mStrength; }
+    RetCode setForcedDevice(
+            const ::aidl::android::media::audio::common::AudioDeviceDescription& device) {
+        mForceDevice = device;
+        return RetCode::SUCCESS;
+    }
+    aidl::android::media::audio::common::AudioDeviceDescription getForcedDevice() const {
+        return mForceDevice;
+    }
 
   private:
     int mStrength = 0;
+    ::aidl::android::media::audio::common::AudioDeviceDescription mForceDevice;
 };
 
 class VirtualizerSw final : public EffectImpl {
   public:
     static const std::string kEffectName;
-    static const bool kStrengthSupported;
-    static const Virtualizer::Capability kCapability;
+    static const Capability kCapability;
     static const Descriptor kDescriptor;
     VirtualizerSw() { LOG(DEBUG) << __func__; }
     ~VirtualizerSw() {
@@ -64,9 +71,12 @@
     std::string getEffectName() override { return kEffectName; }
 
   private:
+    static const std::vector<Range::VirtualizerRange> kRanges;
     std::shared_ptr<VirtualizerSwContext> mContext;
 
     ndk::ScopedAStatus getParameterVirtualizer(const Virtualizer::Tag& tag,
                                                Parameter::Specific* specific);
+    ndk::ScopedAStatus getSpeakerAngles(const Virtualizer::SpeakerAnglesPayload payload,
+                                        Parameter::Specific* specific);
 };
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/visualizer/VisualizerSw.cpp b/audio/aidl/default/visualizer/VisualizerSw.cpp
index 614988c..0909f25 100644
--- a/audio/aidl/default/visualizer/VisualizerSw.cpp
+++ b/audio/aidl/default/visualizer/VisualizerSw.cpp
@@ -17,19 +17,21 @@
 #define LOG_TAG "AHAL_VisualizerSw"
 
 #include <android-base/logging.h>
+#include <system/audio_effects/effect_uuid.h>
 
 #include "VisualizerSw.h"
 
 using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectImplUuidVisualizerSw;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidVisualizer;
 using aidl::android::hardware::audio::effect::IEffect;
-using aidl::android::hardware::audio::effect::kVisualizerSwImplUUID;
 using aidl::android::hardware::audio::effect::State;
 using aidl::android::hardware::audio::effect::VisualizerSw;
 using aidl::android::media::audio::common::AudioUuid;
 
 extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
                                            std::shared_ptr<IEffect>* instanceSpp) {
-    if (!in_impl_uuid || *in_impl_uuid != kVisualizerSwImplUUID) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidVisualizerSw()) {
         LOG(ERROR) << __func__ << "uuid not supported";
         return EX_ILLEGAL_ARGUMENT;
     }
@@ -44,7 +46,7 @@
 }
 
 extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
-    if (!in_impl_uuid || *in_impl_uuid != kVisualizerSwImplUUID) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidVisualizerSw()) {
         LOG(ERROR) << __func__ << "uuid not supported";
         return EX_ILLEGAL_ARGUMENT;
     }
@@ -55,23 +57,26 @@
 namespace aidl::android::hardware::audio::effect {
 
 const std::string VisualizerSw::kEffectName = "VisualizerSw";
+
 /* capabilities */
-const Visualizer::CaptureSamplesRange VisualizerSwContext::kCaptureSamplesRange = {
-        VisualizerSwContext::kMinCaptureSize, VisualizerSwContext::kMaxCaptureSize};
-const Visualizer::Capability VisualizerSw::kCapability = {
-        .maxLatencyMs = VisualizerSwContext::kMaxLatencyMs,
-        .captureSampleRange = VisualizerSwContext::kCaptureSamplesRange};
+const std::vector<Range::VisualizerRange> VisualizerSw::kRanges = {
+        MAKE_RANGE(Visualizer, latencyMs, 0, VisualizerSwContext::kMaxLatencyMs),
+        MAKE_RANGE(Visualizer, captureSamples, VisualizerSwContext::kMinCaptureSize,
+                   VisualizerSwContext::kMaxCaptureSize)};
+
+const Capability VisualizerSw::kCapability = {
+        .range = Range::make<Range::visualizer>(VisualizerSw::kRanges)};
 
 const Descriptor VisualizerSw::kDescriptor = {
-        .common = {.id = {.type = kVisualizerTypeUUID,
-                          .uuid = kVisualizerSwImplUUID,
+        .common = {.id = {.type = getEffectTypeUuidVisualizer(),
+                          .uuid = getEffectImplUuidVisualizerSw(),
                           .proxy = std::nullopt},
                    .flags = {.type = Flags::Type::INSERT,
                              .insert = Flags::Insert::FIRST,
                              .volume = Flags::Volume::CTRL},
                    .name = VisualizerSw::kEffectName,
                    .implementor = "The Android Open Source Project"},
-        .capability = Capability::make<Capability::visualizer>(VisualizerSw::kCapability)};
+        .capability = VisualizerSw::kCapability};
 
 ndk::ScopedAStatus VisualizerSw::getDescriptor(Descriptor* _aidl_return) {
     LOG(DEBUG) << __func__ << kDescriptor.toString();
@@ -84,34 +89,33 @@
               "EffectNotSupported");
 
     auto& vsParam = specific.get<Parameter::Specific::visualizer>();
+    RETURN_IF(!inRange(vsParam, kRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
     auto tag = vsParam.getTag();
 
     switch (tag) {
         case Visualizer::captureSamples: {
             RETURN_IF(mContext->setVsCaptureSize(vsParam.get<Visualizer::captureSamples>()) !=
                               RetCode::SUCCESS,
-                      EX_ILLEGAL_ARGUMENT, "captureSizeNotSupported");
+                      EX_ILLEGAL_ARGUMENT, "setCaptureSizeFailed");
             return ndk::ScopedAStatus::ok();
         }
         case Visualizer::scalingMode: {
             RETURN_IF(mContext->setVsScalingMode(vsParam.get<Visualizer::scalingMode>()) !=
                               RetCode::SUCCESS,
-                      EX_ILLEGAL_ARGUMENT, "scalingModeNotSupported");
+                      EX_ILLEGAL_ARGUMENT, "setScalingModeFailed");
             return ndk::ScopedAStatus::ok();
         }
         case Visualizer::measurementMode: {
             RETURN_IF(mContext->setVsMeasurementMode(vsParam.get<Visualizer::measurementMode>()) !=
                               RetCode::SUCCESS,
-                      EX_ILLEGAL_ARGUMENT, "measurementModeNotSupported");
+                      EX_ILLEGAL_ARGUMENT, "setMeasurementModeFailed");
             return ndk::ScopedAStatus::ok();
         }
-        case Visualizer::setOnlyParameters: {
-            return setSetOnlyParameterVisualizer(vsParam.get<Visualizer::setOnlyParameters>());
-        }
-        case Visualizer::getOnlyParameters: {
-            LOG(ERROR) << __func__ << " unsupported settable getOnlyParam";
-            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
-                    EX_ILLEGAL_ARGUMENT, "SetofGetOnlyParamsNotSupported");
+        case Visualizer::latencyMs: {
+            RETURN_IF(mContext->setVsLatency(vsParam.get<Visualizer::latencyMs>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setLatencyFailed");
+            return ndk::ScopedAStatus::ok();
         }
         default: {
             LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
@@ -121,18 +125,6 @@
     }
 }
 
-ndk::ScopedAStatus VisualizerSw::setSetOnlyParameterVisualizer(
-        Visualizer::SetOnlyParameters setOnlyParam) {
-    auto tag = setOnlyParam.getTag();
-    RETURN_IF(Visualizer::SetOnlyParameters::latencyMs != tag, EX_ILLEGAL_ARGUMENT,
-              "SetOnlyParametersTagNotSupported");
-    RETURN_IF(
-            mContext->setVsLatency(setOnlyParam.get<Visualizer::SetOnlyParameters::latencyMs>()) !=
-                    RetCode::SUCCESS,
-            EX_ILLEGAL_ARGUMENT, "latencyNotSupported");
-    return ndk::ScopedAStatus::ok();
-}
-
 ndk::ScopedAStatus VisualizerSw::getParameterSpecific(const Parameter::Id& id,
                                                       Parameter::Specific* specific) {
     auto tag = id.getTag();
@@ -142,14 +134,6 @@
     switch (vsIdTag) {
         case Visualizer::Id::commonTag:
             return getParameterVisualizer(vsId.get<Visualizer::Id::commonTag>(), specific);
-        case Visualizer::Id::getOnlyParamTag:
-            return getGetOnlyParameterVisualizer(vsId.get<Visualizer::Id::getOnlyParamTag>(),
-                                                 specific);
-        case Visualizer::Id::setOnlyParamTag: {
-            LOG(ERROR) << __func__ << " unsupported gettable setOnlyParam";
-            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
-                    EX_ILLEGAL_ARGUMENT, "GetofSetOnlyParamsNotSupported");
-        }
         default:
             LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
             return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
@@ -174,6 +158,18 @@
             vsParam.set<Visualizer::measurementMode>(mContext->getVsMeasurementMode());
             break;
         }
+        case Visualizer::measurement: {
+            vsParam.set<Visualizer::measurement>(mContext->getVsMeasurement());
+            break;
+        }
+        case Visualizer::captureSampleBuffer: {
+            vsParam.set<Visualizer::captureSampleBuffer>(mContext->getVsCaptureSampleBuffer());
+            break;
+        }
+        case Visualizer::latencyMs: {
+            vsParam.set<Visualizer::latencyMs>(mContext->getVsLatency());
+            break;
+        }
         default: {
             LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
             return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
@@ -184,32 +180,6 @@
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus VisualizerSw::getGetOnlyParameterVisualizer(
-        const Visualizer::GetOnlyParameters::Tag& tag, Parameter::Specific* specific) {
-    Visualizer::GetOnlyParameters getOnlyParam;
-    switch (tag) {
-        case Visualizer::GetOnlyParameters::measurement: {
-            getOnlyParam.set<Visualizer::GetOnlyParameters::measurement>(
-                    mContext->getVsMeasurement());
-            break;
-        }
-        case Visualizer::GetOnlyParameters::captureSampleBuffer: {
-            getOnlyParam.set<Visualizer::GetOnlyParameters::captureSampleBuffer>(
-                    mContext->getVsCaptureSampleBuffer());
-            break;
-        }
-        default: {
-            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
-            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
-                    EX_ILLEGAL_ARGUMENT, "GetOnlyParameterTagNotSupported");
-        }
-    }
-    Visualizer vsParam;
-    vsParam.set<Visualizer::getOnlyParameters>(getOnlyParam);
-    specific->set<Parameter::Specific::visualizer>(vsParam);
-    return ndk::ScopedAStatus::ok();
-}
-
 std::shared_ptr<EffectContext> VisualizerSw::createContext(const Parameter::Common& common) {
     if (mContext) {
         LOG(DEBUG) << __func__ << " context already exist";
@@ -242,34 +212,21 @@
 }
 
 RetCode VisualizerSwContext::setVsCaptureSize(int captureSize) {
-    if (captureSize < VisualizerSw::kCapability.captureSampleRange.min ||
-        captureSize > VisualizerSw::kCapability.captureSampleRange.max) {
-        LOG(ERROR) << __func__ << " invalid captureSize " << captureSize;
-        return RetCode::ERROR_ILLEGAL_PARAMETER;
-    }
-    // TODO : Add implementation to apply new captureSize
     mCaptureSize = captureSize;
     return RetCode::SUCCESS;
 }
 
 RetCode VisualizerSwContext::setVsScalingMode(Visualizer::ScalingMode scalingMode) {
-    // TODO : Add implementation to apply new scalingMode
     mScalingMode = scalingMode;
     return RetCode::SUCCESS;
 }
 
 RetCode VisualizerSwContext::setVsMeasurementMode(Visualizer::MeasurementMode measurementMode) {
-    // TODO : Add implementation to apply new measurementMode
     mMeasurementMode = measurementMode;
     return RetCode::SUCCESS;
 }
 
 RetCode VisualizerSwContext::setVsLatency(int latency) {
-    if (latency < 0 || latency > VisualizerSw::kCapability.maxLatencyMs) {
-        LOG(ERROR) << __func__ << " invalid latency " << latency;
-        return RetCode::ERROR_ILLEGAL_PARAMETER;
-    }
-    // TODO : Add implementation to modify latency
     mLatency = latency;
     return RetCode::SUCCESS;
 }
diff --git a/audio/aidl/default/visualizer/VisualizerSw.h b/audio/aidl/default/visualizer/VisualizerSw.h
index e9d46d7..995774e 100644
--- a/audio/aidl/default/visualizer/VisualizerSw.h
+++ b/audio/aidl/default/visualizer/VisualizerSw.h
@@ -16,11 +16,10 @@
 
 #pragma once
 
-#include <aidl/android/hardware/audio/effect/BnEffect.h>
 #include <vector>
 
+#include <aidl/android/hardware/audio/effect/BnEffect.h>
 #include "effect-impl/EffectImpl.h"
-#include "effect-impl/EffectUUID.h"
 
 namespace aidl::android::hardware::audio::effect {
 
@@ -30,7 +29,6 @@
     static const int kMaxCaptureSize = 0x400;
     static const int kMaxLatencyMs = 3000;
     static const int kMaxCaptureBufSize = 0xffff;
-    static const Visualizer::CaptureSamplesRange kCaptureSamplesRange;
     VisualizerSwContext(int statusDepth, const Parameter::Common& common)
         : EffectContext(statusDepth, common) {
         LOG(DEBUG) << __func__;
@@ -48,8 +46,9 @@
     Visualizer::MeasurementMode getVsMeasurementMode() const { return mMeasurementMode; }
 
     RetCode setVsLatency(int latency);
+    int getVsLatency() const { return mLatency; }
 
-    Visualizer::GetOnlyParameters::Measurement getVsMeasurement() const { return mMeasurement; }
+    Visualizer::Measurement getVsMeasurement() const { return mMeasurement; }
     std::vector<uint8_t> getVsCaptureSampleBuffer() const { return mCaptureSampleBuffer; }
 
   private:
@@ -57,14 +56,14 @@
     Visualizer::ScalingMode mScalingMode = Visualizer::ScalingMode::NORMALIZED;
     Visualizer::MeasurementMode mMeasurementMode = Visualizer::MeasurementMode::NONE;
     int mLatency = 0;
-    const Visualizer::GetOnlyParameters::Measurement mMeasurement = {0, 0};
+    const Visualizer::Measurement mMeasurement = {0, 0};
     std::vector<uint8_t> mCaptureSampleBuffer;
 };
 
 class VisualizerSw final : public EffectImpl {
   public:
     static const std::string kEffectName;
-    static const Visualizer::Capability kCapability;
+    static const Capability kCapability;
     static const Descriptor kDescriptor;
     VisualizerSw() { LOG(DEBUG) << __func__; }
     ~VisualizerSw() {
@@ -85,12 +84,9 @@
     std::string getEffectName() override { return kEffectName; }
 
   private:
+    static const std::vector<Range::VisualizerRange> kRanges;
     std::shared_ptr<VisualizerSwContext> mContext;
-
-    ndk::ScopedAStatus setSetOnlyParameterVisualizer(Visualizer::SetOnlyParameters setOnlyParam);
     ndk::ScopedAStatus getParameterVisualizer(const Visualizer::Tag& tag,
                                               Parameter::Specific* specific);
-    ndk::ScopedAStatus getGetOnlyParameterVisualizer(const Visualizer::GetOnlyParameters::Tag& tag,
-                                                     Parameter::Specific* specific);
 };
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/volume/VolumeSw.cpp b/audio/aidl/default/volume/VolumeSw.cpp
index 64301dc..8902584 100644
--- a/audio/aidl/default/volume/VolumeSw.cpp
+++ b/audio/aidl/default/volume/VolumeSw.cpp
@@ -14,27 +14,27 @@
  * limitations under the License.
  */
 
-#include <cstddef>
-#define LOG_TAG "AHAL_VolumeSw"
-#include <Utils.h>
 #include <algorithm>
-#include <unordered_set>
+#include <cstddef>
 
+#define LOG_TAG "AHAL_VolumeSw"
 #include <android-base/logging.h>
 #include <fmq/AidlMessageQueue.h>
+#include <system/audio_effects/effect_uuid.h>
 
 #include "VolumeSw.h"
 
 using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectImplUuidVolumeSw;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidVolume;
 using aidl::android::hardware::audio::effect::IEffect;
-using aidl::android::hardware::audio::effect::kVolumeSwImplUUID;
 using aidl::android::hardware::audio::effect::State;
 using aidl::android::hardware::audio::effect::VolumeSw;
 using aidl::android::media::audio::common::AudioUuid;
 
 extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
                                            std::shared_ptr<IEffect>* instanceSpp) {
-    if (!in_impl_uuid || *in_impl_uuid != kVolumeSwImplUUID) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidVolumeSw()) {
         LOG(ERROR) << __func__ << "uuid not supported";
         return EX_ILLEGAL_ARGUMENT;
     }
@@ -49,7 +49,7 @@
 }
 
 extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
-    if (!in_impl_uuid || *in_impl_uuid != kVolumeSwImplUUID) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidVolumeSw()) {
         LOG(ERROR) << __func__ << "uuid not supported";
         return EX_ILLEGAL_ARGUMENT;
     }
@@ -60,17 +60,21 @@
 namespace aidl::android::hardware::audio::effect {
 
 const std::string VolumeSw::kEffectName = "VolumeSw";
-const Volume::Capability VolumeSw::kCapability = {.minLevelDb = -9600, .maxLevelDb = 0};
+
+const std::vector<Range::VolumeRange> VolumeSw::kRanges = {MAKE_RANGE(Volume, levelDb, -9600, 0)};
+
+const Capability VolumeSw::kCapability = {.range = Range::make<Range::volume>(VolumeSw::kRanges)};
+
 const Descriptor VolumeSw::kDescriptor = {
-        .common = {.id = {.type = kVolumeTypeUUID,
-                          .uuid = kVolumeSwImplUUID,
+        .common = {.id = {.type = getEffectTypeUuidVolume(),
+                          .uuid = getEffectImplUuidVolumeSw(),
                           .proxy = std::nullopt},
                    .flags = {.type = Flags::Type::INSERT,
                              .insert = Flags::Insert::FIRST,
                              .volume = Flags::Volume::CTRL},
                    .name = VolumeSw::kEffectName,
                    .implementor = "The Android Open Source Project"},
-        .capability = Capability::make<Capability::volume>(VolumeSw::kCapability)};
+        .capability = VolumeSw::kCapability};
 
 ndk::ScopedAStatus VolumeSw::getDescriptor(Descriptor* _aidl_return) {
     LOG(DEBUG) << __func__ << kDescriptor.toString();
@@ -83,6 +87,7 @@
               "EffectNotSupported");
 
     auto& volParam = specific.get<Parameter::Specific::volume>();
+    RETURN_IF(!inRange(volParam, kRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
     auto tag = volParam.getTag();
 
     switch (tag) {
@@ -177,11 +182,6 @@
 }
 
 RetCode VolumeSwContext::setVolLevel(int level) {
-    if (level < VolumeSw::kCapability.minLevelDb || level > VolumeSw::kCapability.maxLevelDb) {
-        LOG(ERROR) << __func__ << " invalid level " << level;
-        return RetCode::ERROR_ILLEGAL_PARAMETER;
-    }
-    // TODO : Add implementation to apply new level
     mLevel = level;
     return RetCode::SUCCESS;
 }
diff --git a/audio/aidl/default/volume/VolumeSw.h b/audio/aidl/default/volume/VolumeSw.h
index b6f6077..1432b2b 100644
--- a/audio/aidl/default/volume/VolumeSw.h
+++ b/audio/aidl/default/volume/VolumeSw.h
@@ -22,7 +22,6 @@
 #include <memory>
 
 #include "effect-impl/EffectImpl.h"
-#include "effect-impl/EffectUUID.h"
 
 namespace aidl::android::hardware::audio::effect {
 
@@ -49,7 +48,7 @@
 class VolumeSw final : public EffectImpl {
   public:
     static const std::string kEffectName;
-    static const Volume::Capability kCapability;
+    static const Capability kCapability;
     static const Descriptor kDescriptor;
     VolumeSw() { LOG(DEBUG) << __func__; }
     ~VolumeSw() {
@@ -70,6 +69,7 @@
     std::string getEffectName() override { return kEffectName; }
 
   private:
+    static const std::vector<Range::VolumeRange> kRanges;
     std::shared_ptr<VolumeSwContext> mContext;
 
     ndk::ScopedAStatus getParameterVolume(const Volume::Tag& tag, Parameter::Specific* specific);
diff --git a/audio/aidl/vts/Android.bp b/audio/aidl/vts/Android.bp
index f9d12dd..852255d 100644
--- a/audio/aidl/vts/Android.bp
+++ b/audio/aidl/vts/Android.bp
@@ -37,6 +37,7 @@
         "general-tests",
         "vts",
     ],
+    srcs: [":effectCommonFile"],
 }
 
 cc_test {
@@ -83,6 +84,7 @@
 cc_test {
     name: "VtsHalDynamicsProcessingTargetTest",
     defaults: ["VtsHalAudioTargetTestDefaults"],
+    static_libs: ["libaudioaidlranges"],
     srcs: ["VtsHalDynamicsProcessingTest.cpp"],
 }
 
@@ -141,9 +143,15 @@
 }
 
 cc_test {
-    name: "VtsHalAGCTargetTest",
+    name: "VtsHalAGC1TargetTest",
     defaults: ["VtsHalAudioTargetTestDefaults"],
-    srcs: ["VtsHalAGCTargetTest.cpp"],
+    srcs: ["VtsHalAGC1TargetTest.cpp"],
+}
+
+cc_test {
+    name: "VtsHalAGC2TargetTest",
+    defaults: ["VtsHalAudioTargetTestDefaults"],
+    srcs: ["VtsHalAGC2TargetTest.cpp"],
 }
 
 cc_test {
diff --git a/audio/aidl/vts/EffectFactoryHelper.h b/audio/aidl/vts/EffectFactoryHelper.h
index 4add844..a2499fd 100644
--- a/audio/aidl/vts/EffectFactoryHelper.h
+++ b/audio/aidl/vts/EffectFactoryHelper.h
@@ -24,7 +24,6 @@
 #include <android/binder_auto_utils.h>
 
 #include "TestUtils.h"
-#include "effect-impl/EffectUUID.h"
 
 using namespace android;
 
diff --git a/audio/aidl/vts/EffectHelper.h b/audio/aidl/vts/EffectHelper.h
index 7222d4f..831977b 100644
--- a/audio/aidl/vts/EffectHelper.h
+++ b/audio/aidl/vts/EffectHelper.h
@@ -19,14 +19,19 @@
 #include <algorithm>
 #include <memory>
 #include <string>
+#include <type_traits>
 #include <unordered_map>
 #include <vector>
 
+#include <Utils.h>
 #include <aidl/android/hardware/audio/effect/IEffect.h>
 #include <aidl/android/hardware/audio/effect/IFactory.h>
 #include <aidl/android/media/audio/common/AudioChannelLayout.h>
 #include <android/binder_auto_utils.h>
 #include <fmq/AidlMessageQueue.h>
+#include <gtest/gtest.h>
+#include <system/audio_effects/aidl_effects_utils.h>
+#include <system/audio_effects/effect_uuid.h>
 
 #include "AudioHalBinderServiceUtil.h"
 #include "EffectFactoryHelper.h"
@@ -37,6 +42,7 @@
 using aidl::android::hardware::audio::effect::Descriptor;
 using aidl::android::hardware::audio::effect::IEffect;
 using aidl::android::hardware::audio::effect::Parameter;
+using aidl::android::hardware::audio::effect::Range;
 using aidl::android::hardware::audio::effect::State;
 using aidl::android::hardware::common::fmq::SynchronizedReadWrite;
 using aidl::android::media::audio::common::AudioChannelLayout;
@@ -131,7 +137,7 @@
     static void allocateInputData(const Parameter::Common common, std::unique_ptr<DataMQ>& mq,
                                   std::vector<float>& buffer) {
         ASSERT_NE(mq, nullptr);
-        auto frameSize = android::hardware::audio::common::getFrameSizeInBytes(
+        auto frameSize = ::aidl::android::hardware::audio::common::getFrameSizeInBytes(
                 common.input.base.format, common.input.base.channelMask);
         const size_t floatsToWrite = mq->availableToWrite();
         ASSERT_NE(0UL, floatsToWrite);
@@ -148,16 +154,22 @@
     }
     static void readFromFmq(std::unique_ptr<StatusMQ>& statusMq, size_t statusNum,
                             std::unique_ptr<DataMQ>& dataMq, size_t expectFloats,
-                            std::vector<float>& buffer) {
+                            std::vector<float>& buffer,
+                            std::optional<int> expectStatus = STATUS_OK) {
+        if (0 == statusNum) {
+            ASSERT_EQ(0ul, statusMq->availableToRead());
+            return;
+        }
         IEffect::Status status{};
         ASSERT_TRUE(statusMq->readBlocking(&status, statusNum));
-        ASSERT_EQ(STATUS_OK, status.status);
-        if (statusNum != 0) {
-            ASSERT_EQ(expectFloats, (unsigned)status.fmqProduced);
-            ASSERT_EQ(expectFloats, dataMq->availableToRead());
-            if (expectFloats != 0) {
-                ASSERT_TRUE(dataMq->read(buffer.data(), expectFloats));
-            }
+        if (expectStatus.has_value()) {
+            ASSERT_EQ(expectStatus.value(), status.status);
+        }
+
+        ASSERT_EQ(expectFloats, (unsigned)status.fmqProduced);
+        ASSERT_EQ(expectFloats, dataMq->availableToRead());
+        if (expectFloats != 0) {
+            ASSERT_TRUE(dataMq->read(buffer.data(), expectFloats));
         }
     }
     static Parameter::Common createParamCommon(
@@ -199,4 +211,58 @@
         std::unique_ptr<DataMQ> inputMQ;
         std::unique_ptr<DataMQ> outputMQ;
     };
+
+    template <typename T, Range::Tag tag>
+    static bool isParameterValid(const T& target, const Descriptor& desc) {
+        if (desc.capability.range.getTag() != tag) {
+            return true;
+        }
+        const auto& ranges = desc.capability.range.get<tag>();
+        return inRange(target, ranges);
+    }
+
+    /**
+     * Add to test value set: (min+max)/2, minimum/maximum numeric limits, and min-1/max+1 if
+     * result still in numeric limits after -1/+1.
+     * Only use this when the type of test value is basic type (std::is_arithmetic return true).
+     */
+    template <typename S, typename = std::enable_if_t<std::is_arithmetic_v<S>>>
+    static std::set<S> expandTestValueBasic(std::set<S>& s) {
+        const auto minLimit = std::numeric_limits<S>::min(),
+                   maxLimit = std::numeric_limits<S>::max();
+        if (s.size()) {
+            const auto min = *s.begin(), max = *s.rbegin();
+            s.insert(min + (max - min) / 2);
+            if (min != minLimit) {
+                s.insert(min - 1);
+            }
+            if (max != maxLimit) {
+                s.insert(max + 1);
+            }
+        }
+        s.insert(minLimit);
+        s.insert(maxLimit);
+        return s;
+    }
+
+    template <typename T, typename S, Range::Tag R, typename T::Tag tag, typename Functor>
+    static std::set<S> getTestValueSet(
+            std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kFactoryDescList,
+            Functor functor) {
+        std::set<S> result;
+        for (const auto& [_, desc] : kFactoryDescList) {
+            if (desc.capability.range.getTag() == R) {
+                const auto& ranges = desc.capability.range.get<R>();
+                for (const auto& range : ranges) {
+                    if (range.min.getTag() == tag) {
+                        result.insert(range.min.template get<tag>());
+                    }
+                    if (range.max.getTag() == tag) {
+                        result.insert(range.max.template get<tag>());
+                    }
+                }
+            }
+        }
+        return functor(result);
+    }
 };
diff --git a/audio/aidl/vts/ModuleConfig.cpp b/audio/aidl/vts/ModuleConfig.cpp
index 7b002ad..8c448a8 100644
--- a/audio/aidl/vts/ModuleConfig.cpp
+++ b/audio/aidl/vts/ModuleConfig.cpp
@@ -27,6 +27,7 @@
 using namespace android;
 using namespace std::chrono_literals;
 
+using aidl::android::hardware::audio::common::isBitPositionFlagSet;
 using aidl::android::hardware::audio::core::IModule;
 using aidl::android::media::audio::common::AudioChannelLayout;
 using aidl::android::media::audio::common::AudioDeviceType;
@@ -43,7 +44,6 @@
 using aidl::android::media::audio::common::AudioProfile;
 using aidl::android::media::audio::common::AudioUsage;
 using aidl::android::media::audio::common::Int;
-using android::hardware::audio::common::isBitPositionFlagSet;
 
 // static
 std::optional<AudioOffloadInfo> ModuleConfig::generateOffloadInfoIfNeeded(
@@ -56,7 +56,7 @@
         offloadInfo.base.sampleRate = portConfig.sampleRate.value().value;
         offloadInfo.base.channelMask = portConfig.channelMask.value();
         offloadInfo.base.format = portConfig.format.value();
-        offloadInfo.bitRatePerSecond = 256;                                // Arbitrary value.
+        offloadInfo.bitRatePerSecond = 256000;                             // Arbitrary value.
         offloadInfo.durationUs = std::chrono::microseconds(1min).count();  // Arbitrary value.
         offloadInfo.usage = AudioUsage::MEDIA;
         offloadInfo.encapsulationMode = AudioEncapsulationMode::NONE;
diff --git a/audio/aidl/vts/TestUtils.h b/audio/aidl/vts/TestUtils.h
index 4c1d42c..72ca56f 100644
--- a/audio/aidl/vts/TestUtils.h
+++ b/audio/aidl/vts/TestUtils.h
@@ -21,7 +21,7 @@
 #include <iostream>
 
 #include <android/binder_auto_utils.h>
-#include <gtest/gtest_pred_impl.h>
+#include <gtest/gtest.h>
 
 namespace android::hardware::audio::common::testing {
 
diff --git a/audio/aidl/vts/VtsHalAECTargetTest.cpp b/audio/aidl/vts/VtsHalAECTargetTest.cpp
index c3427c8..8828c41 100644
--- a/audio/aidl/vts/VtsHalAECTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAECTargetTest.cpp
@@ -14,25 +14,26 @@
  * limitations under the License.
  */
 
-#include <Utils.h>
-#include <aidl/Vintf.h>
 #include <algorithm>
 #include <string>
 #include <unordered_set>
 
+#include <aidl/Vintf.h>
 #define LOG_TAG "VtsHalAECParamTest"
+#include <android-base/logging.h>
 
 #include "EffectHelper.h"
+#include "effect-impl/EffectTypes.h"
 
 using namespace android;
 
 using aidl::android::hardware::audio::effect::AcousticEchoCanceler;
-using aidl::android::hardware::audio::effect::Capability;
 using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidAcousticEchoCanceler;
 using aidl::android::hardware::audio::effect::IEffect;
 using aidl::android::hardware::audio::effect::IFactory;
-using aidl::android::hardware::audio::effect::kAcousticEchoCancelerTypeUUID;
 using aidl::android::hardware::audio::effect::Parameter;
+using aidl::android::hardware::audio::effect::Range;
 
 enum ParamName { PARAM_INSTANCE_NAME, PARAM_ECHO_DELAY, PARAM_MOBILE_MODE };
 using AECParamTestParam = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>,
@@ -87,7 +88,8 @@
             // validate parameter
             Descriptor desc;
             ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
-            const bool valid = isTagInRange(tag, aec, desc);
+            const bool valid =
+                    isParameterValid<AcousticEchoCanceler, Range::acousticEchoCanceler>(aec, desc);
             const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
 
             // set parameter
@@ -124,54 +126,6 @@
         mTags.push_back({AcousticEchoCanceler::mobileMode, aec});
     }
 
-    bool isTagInRange(const AcousticEchoCanceler::Tag& tag, const AcousticEchoCanceler& aec,
-                      const Descriptor& desc) const {
-        const AcousticEchoCanceler::Capability& aecCap =
-                desc.capability.get<Capability::acousticEchoCanceler>();
-        switch (tag) {
-            case AcousticEchoCanceler::echoDelayUs: {
-                return isEchoDelayInRange(aecCap, aec.get<AcousticEchoCanceler::echoDelayUs>());
-            }
-            case AcousticEchoCanceler::mobileMode: {
-                bool mode = aec.get<AcousticEchoCanceler::mobileMode>();
-                return isMobileModeValid(aecCap, mode);
-            }
-            default:
-                return false;
-        }
-    }
-
-    bool isEchoDelayInRange(const AcousticEchoCanceler::Capability& cap, int delay) const {
-        return (delay >= 0 && delay <= cap.maxEchoDelayUs);
-    }
-
-    bool isMobileModeValid(const AcousticEchoCanceler::Capability& cap, bool mode) const {
-        if (cap.supportMobileMode) {
-            return true;
-        } else {
-            return mode == false;
-        }
-    }
-
-    static std::unordered_set<int> getEchoDelayTestValues() {
-        auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
-                                                                     kAcousticEchoCancelerTypeUUID);
-        const auto max = std::max_element(
-                descList.begin(), descList.end(),
-                [](const std::pair<std::shared_ptr<IFactory>, Descriptor>& a,
-                   const std::pair<std::shared_ptr<IFactory>, Descriptor>& b) {
-                    return a.second.capability.get<Capability::acousticEchoCanceler>()
-                                   .maxEchoDelayUs <
-                           b.second.capability.get<Capability::acousticEchoCanceler>()
-                                   .maxEchoDelayUs;
-                });
-        if (max == descList.end()) {
-            return {0};
-        }
-        int maxDelay =
-                max->second.capability.get<Capability::acousticEchoCanceler>().maxEchoDelayUs;
-        return {-1, 0, maxDelay - 1, maxDelay, maxDelay + 1};
-    }
     static std::unordered_set<bool> getMobileModeValues() { return {true, false}; }
 
   private:
@@ -189,12 +143,21 @@
     SetAndGetParameters();
 }
 
+std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kDescPair;
 INSTANTIATE_TEST_SUITE_P(
         AECParamTest, AECParamTest,
-        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
-                                   IFactory::descriptor, kAcousticEchoCancelerTypeUUID)),
-                           testing::ValuesIn(AECParamTest::getEchoDelayTestValues()),
-                           testing::ValuesIn(AECParamTest::getMobileModeValues())),
+        ::testing::Combine(
+                testing::ValuesIn(kDescPair = EffectFactoryHelper::getAllEffectDescriptors(
+                                          IFactory::descriptor,
+                                          getEffectTypeUuidAcousticEchoCanceler())),
+                testing::ValuesIn(EffectHelper::getTestValueSet<AcousticEchoCanceler, int,
+                                                                Range::acousticEchoCanceler,
+                                                                AcousticEchoCanceler::echoDelayUs>(
+                        kDescPair, EffectHelper::expandTestValueBasic<int>)),
+                testing::ValuesIn(EffectHelper::getTestValueSet<AcousticEchoCanceler, bool,
+                                                                Range::acousticEchoCanceler,
+                                                                AcousticEchoCanceler::mobileMode>(
+                        kDescPair, EffectHelper::expandTestValueBasic<bool>))),
         [](const testing::TestParamInfo<AECParamTest::ParamType>& info) {
             auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
             std::string echoDelay = std::to_string(std::get<PARAM_ECHO_DELAY>(info.param));
@@ -215,4 +178,4 @@
     ABinderProcess_setThreadPoolMaxThreadCount(1);
     ABinderProcess_startThreadPool();
     return RUN_ALL_TESTS();
-}
\ No newline at end of file
+}
diff --git a/audio/aidl/vts/VtsHalAGC1TargetTest.cpp b/audio/aidl/vts/VtsHalAGC1TargetTest.cpp
new file mode 100644
index 0000000..edfcdf6
--- /dev/null
+++ b/audio/aidl/vts/VtsHalAGC1TargetTest.cpp
@@ -0,0 +1,197 @@
+/*
+ * 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 <aidl/Vintf.h>
+#define LOG_TAG "VtsHalAGC1ParamTest"
+#include <android-base/logging.h>
+
+#include "EffectHelper.h"
+
+using namespace android;
+
+using aidl::android::hardware::audio::effect::AutomaticGainControlV1;
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidAutomaticGainControlV1;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::IFactory;
+using aidl::android::hardware::audio::effect::Parameter;
+
+enum ParamName {
+    PARAM_INSTANCE_NAME,
+    PARAM_TARGET_PEAK_LEVEL,
+    PARAM_MAX_COMPRESSION_GAIN,
+    PARAM_ENABLE_LIMITER
+};
+using AGC1ParamTestParam =
+        std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int /* targetPeakLevel */,
+                   int /* maxCompressionGain */, bool /* enableLimiter */>;
+
+class AGC1ParamTest : public ::testing::TestWithParam<AGC1ParamTestParam>, public EffectHelper {
+  public:
+    AGC1ParamTest()
+        : mTargetPeakLevel(std::get<PARAM_TARGET_PEAK_LEVEL>(GetParam())),
+          mMaxCompressionGain(std::get<PARAM_MAX_COMPRESSION_GAIN>(GetParam())),
+          mEnableLimiter(std::get<PARAM_ENABLE_LIMITER>(GetParam())) {
+        std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
+    }
+
+    void SetUp() override {
+        ASSERT_NE(nullptr, mFactory);
+        ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+
+        Parameter::Specific specific = getDefaultParamSpecific();
+        Parameter::Common common = EffectHelper::createParamCommon(
+                0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
+                kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
+        IEffect::OpenEffectReturn ret;
+        ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &ret, EX_NONE));
+        ASSERT_NE(nullptr, mEffect);
+    }
+
+    void TearDown() override {
+        ASSERT_NO_FATAL_FAILURE(close(mEffect));
+        ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+    }
+
+    Parameter::Specific getDefaultParamSpecific() {
+        AutomaticGainControlV1 AGC1 =
+                AutomaticGainControlV1::make<AutomaticGainControlV1::targetPeakLevelDbFs>(0);
+        Parameter::Specific specific =
+                Parameter::Specific::make<Parameter::Specific::automaticGainControlV1>(AGC1);
+        return specific;
+    }
+
+    static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
+    std::shared_ptr<IFactory> mFactory;
+    std::shared_ptr<IEffect> mEffect;
+    Descriptor mDescriptor;
+    int mTargetPeakLevel;
+    int mMaxCompressionGain;
+    bool mEnableLimiter;
+
+    void SetAndGetParameters() {
+        for (auto& it : mTags) {
+            auto& tag = it.first;
+            auto& AGC1 = it.second;
+
+            // validate parameter
+            Descriptor desc;
+            ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
+            const bool valid =
+                    isParameterValid<AutomaticGainControlV1, Range::automaticGainControlV1>(AGC1,
+                                                                                            desc);
+            const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
+
+            // set parameter
+            Parameter expectParam;
+            Parameter::Specific specific;
+            specific.set<Parameter::Specific::automaticGainControlV1>(AGC1);
+            expectParam.set<Parameter::specific>(specific);
+            EXPECT_STATUS(expected, mEffect->setParameter(expectParam)) << expectParam.toString();
+
+            // only get if parameter in range and set success
+            if (expected == EX_NONE) {
+                Parameter getParam;
+                Parameter::Id id;
+                AutomaticGainControlV1::Id specificId;
+                specificId.set<AutomaticGainControlV1::Id::commonTag>(tag);
+                id.set<Parameter::Id::automaticGainControlV1Tag>(specificId);
+                EXPECT_STATUS(EX_NONE, mEffect->getParameter(id, &getParam));
+
+                EXPECT_EQ(expectParam, getParam) << "\nexpect:" << expectParam.toString()
+                                                 << "\ngetParam:" << getParam.toString();
+            }
+        }
+    }
+
+    void addTargetPeakLevelParam(int targetPeakLevel) {
+        AutomaticGainControlV1 AGC1;
+        AGC1.set<AutomaticGainControlV1::targetPeakLevelDbFs>(targetPeakLevel);
+        mTags.push_back({AutomaticGainControlV1::targetPeakLevelDbFs, AGC1});
+    }
+    void addMaxCompressionGainParam(int maxCompressionGainDb) {
+        AutomaticGainControlV1 AGC1;
+        AGC1.set<AutomaticGainControlV1::maxCompressionGainDb>(maxCompressionGainDb);
+        mTags.push_back({AutomaticGainControlV1::maxCompressionGainDb, AGC1});
+    }
+    void addEnableLimiterParam(bool enableLimiter) {
+        AutomaticGainControlV1 AGC1;
+        AGC1.set<AutomaticGainControlV1::enableLimiter>(enableLimiter);
+        mTags.push_back({AutomaticGainControlV1::enableLimiter, AGC1});
+    }
+
+  private:
+    std::vector<std::pair<AutomaticGainControlV1::Tag, AutomaticGainControlV1>> mTags;
+    void CleanUp() { mTags.clear(); }
+};
+
+TEST_P(AGC1ParamTest, SetAndGetTargetPeakLevelParam) {
+    EXPECT_NO_FATAL_FAILURE(addTargetPeakLevelParam(mTargetPeakLevel));
+    SetAndGetParameters();
+}
+
+TEST_P(AGC1ParamTest, SetAndGetMaxCompressionGain) {
+    EXPECT_NO_FATAL_FAILURE(addMaxCompressionGainParam(mMaxCompressionGain));
+    SetAndGetParameters();
+}
+
+TEST_P(AGC1ParamTest, SetAndGetEnableLimiter) {
+    EXPECT_NO_FATAL_FAILURE(addEnableLimiterParam(mEnableLimiter));
+    SetAndGetParameters();
+}
+
+std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kDescPair;
+INSTANTIATE_TEST_SUITE_P(
+        AGC1ParamTest, AGC1ParamTest,
+        ::testing::Combine(
+                testing::ValuesIn(kDescPair = EffectFactoryHelper::getAllEffectDescriptors(
+                                          IFactory::descriptor,
+                                          getEffectTypeUuidAutomaticGainControlV1())),
+                testing::ValuesIn(EffectHelper::getTestValueSet<
+                                  AutomaticGainControlV1, int, Range::automaticGainControlV1,
+                                  AutomaticGainControlV1::targetPeakLevelDbFs>(
+                        kDescPair, EffectHelper::expandTestValueBasic<int>)),
+                testing::ValuesIn(EffectHelper::getTestValueSet<
+                                  AutomaticGainControlV1, int, Range::automaticGainControlV1,
+                                  AutomaticGainControlV1::maxCompressionGainDb>(
+                        kDescPair, EffectHelper::expandTestValueBasic<int>)),
+                testing::Bool()),
+        [](const testing::TestParamInfo<AGC1ParamTest::ParamType>& info) {
+            auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
+            std::string targetPeakLevel =
+                    std::to_string(std::get<PARAM_TARGET_PEAK_LEVEL>(info.param));
+            std::string maxCompressionGain =
+                    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::replace_if(
+                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+            return name;
+        });
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AGC1ParamTest);
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    ABinderProcess_setThreadPoolMaxThreadCount(1);
+    ABinderProcess_startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/audio/aidl/vts/VtsHalAGC2TargetTest.cpp b/audio/aidl/vts/VtsHalAGC2TargetTest.cpp
new file mode 100644
index 0000000..8ba8e45
--- /dev/null
+++ b/audio/aidl/vts/VtsHalAGC2TargetTest.cpp
@@ -0,0 +1,202 @@
+/*
+ * 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.
+ */
+
+#include <aidl/Vintf.h>
+#define LOG_TAG "VtsHalAGC2ParamTest"
+#include <android-base/logging.h>
+#include <android/binder_enums.h>
+
+#include "EffectHelper.h"
+
+using namespace android;
+
+using aidl::android::hardware::audio::effect::AutomaticGainControlV2;
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidAutomaticGainControlV2;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::IFactory;
+using aidl::android::hardware::audio::effect::Parameter;
+
+enum ParamName {
+    PARAM_INSTANCE_NAME,
+    PARAM_DIGITAL_GAIN,
+    PARAM_SATURATION_MARGIN,
+    PARAM_LEVEL_ESTIMATOR
+};
+using AGC2ParamTestParam =
+        std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int /* gain */,
+                   int /* margin */, AutomaticGainControlV2::LevelEstimator>;
+
+class AGC2ParamTest : public ::testing::TestWithParam<AGC2ParamTestParam>, public EffectHelper {
+  public:
+    AGC2ParamTest()
+        : mGain(std::get<PARAM_DIGITAL_GAIN>(GetParam())),
+          mMargin(std::get<PARAM_SATURATION_MARGIN>(GetParam())),
+          mLevelEstimator(std::get<PARAM_LEVEL_ESTIMATOR>(GetParam())) {
+        std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
+    }
+
+    void SetUp() override {
+        ASSERT_NE(nullptr, mFactory);
+        ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+
+        Parameter::Specific specific = getDefaultParamSpecific();
+        Parameter::Common common = EffectHelper::createParamCommon(
+                0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
+                kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
+        IEffect::OpenEffectReturn ret;
+        ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &ret, EX_NONE));
+        ASSERT_NE(nullptr, mEffect);
+    }
+
+    void TearDown() override {
+        ASSERT_NO_FATAL_FAILURE(close(mEffect));
+        ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+    }
+
+    Parameter::Specific getDefaultParamSpecific() {
+        AutomaticGainControlV2 AGC2 =
+                AutomaticGainControlV2::make<AutomaticGainControlV2::fixedDigitalGainMb>(0);
+        Parameter::Specific specific =
+                Parameter::Specific::make<Parameter::Specific::automaticGainControlV2>(AGC2);
+        return specific;
+    }
+
+    static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
+    std::shared_ptr<IFactory> mFactory;
+    std::shared_ptr<IEffect> mEffect;
+    Descriptor mDescriptor;
+    int mGain;
+    int mMargin;
+    AutomaticGainControlV2::LevelEstimator mLevelEstimator;
+
+    void SetAndGetParameters() {
+        for (auto& it : mTags) {
+            auto& tag = it.first;
+            auto& AGC2 = it.second;
+
+            // validate parameter
+            Descriptor desc;
+            ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
+            const bool valid =
+                    isParameterValid<AutomaticGainControlV2, Range::automaticGainControlV2>(AGC2,
+                                                                                            desc);
+            const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
+
+            // set parameter
+            Parameter expectParam;
+            Parameter::Specific specific;
+            specific.set<Parameter::Specific::automaticGainControlV2>(AGC2);
+            expectParam.set<Parameter::specific>(specific);
+            EXPECT_STATUS(expected, mEffect->setParameter(expectParam)) << expectParam.toString();
+
+            // only get if parameter in range and set success
+            if (expected == EX_NONE) {
+                Parameter getParam;
+                Parameter::Id id;
+                AutomaticGainControlV2::Id specificId;
+                specificId.set<AutomaticGainControlV2::Id::commonTag>(tag);
+                id.set<Parameter::Id::automaticGainControlV2Tag>(specificId);
+                EXPECT_STATUS(EX_NONE, mEffect->getParameter(id, &getParam));
+
+                EXPECT_EQ(expectParam, getParam) << "\nexpect:" << expectParam.toString()
+                                                 << "\ngetParam:" << getParam.toString();
+            }
+        }
+    }
+
+    void addDigitalGainParam(int gain) {
+        AutomaticGainControlV2 AGC2;
+        AGC2.set<AutomaticGainControlV2::fixedDigitalGainMb>(gain);
+        mTags.push_back({AutomaticGainControlV2::fixedDigitalGainMb, AGC2});
+    }
+    void addSaturationMarginParam(int margin) {
+        AutomaticGainControlV2 AGC2;
+        AGC2.set<AutomaticGainControlV2::saturationMarginMb>(margin);
+        mTags.push_back({AutomaticGainControlV2::saturationMarginMb, AGC2});
+    }
+    void addLevelEstimatorParam(AutomaticGainControlV2::LevelEstimator levelEstimator) {
+        AutomaticGainControlV2 AGC2;
+        AGC2.set<AutomaticGainControlV2::levelEstimator>(levelEstimator);
+        mTags.push_back({AutomaticGainControlV2::levelEstimator, AGC2});
+    }
+
+    static std::set<AutomaticGainControlV2::LevelEstimator> getLevelEstimatorValues() {
+        return {ndk::enum_range<AutomaticGainControlV2::LevelEstimator>().begin(),
+                ndk::enum_range<AutomaticGainControlV2::LevelEstimator>().end()};
+    }
+
+  private:
+    std::vector<std::pair<AutomaticGainControlV2::Tag, AutomaticGainControlV2>> mTags;
+    void CleanUp() { mTags.clear(); }
+};
+
+TEST_P(AGC2ParamTest, SetAndGetDigitalGainParam) {
+    EXPECT_NO_FATAL_FAILURE(addDigitalGainParam(mGain));
+    SetAndGetParameters();
+}
+
+TEST_P(AGC2ParamTest, SetAndGetSaturationMargin) {
+    EXPECT_NO_FATAL_FAILURE(addSaturationMarginParam(mMargin));
+    SetAndGetParameters();
+}
+
+TEST_P(AGC2ParamTest, SetAndGetLevelEstimator) {
+    EXPECT_NO_FATAL_FAILURE(addLevelEstimatorParam(mLevelEstimator));
+    SetAndGetParameters();
+}
+
+std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kDescPair;
+INSTANTIATE_TEST_SUITE_P(
+        AGC2ParamTest, AGC2ParamTest,
+        ::testing::Combine(
+                testing::ValuesIn(kDescPair = EffectFactoryHelper::getAllEffectDescriptors(
+                                          IFactory::descriptor,
+                                          getEffectTypeUuidAutomaticGainControlV2())),
+                testing::ValuesIn(EffectHelper::getTestValueSet<
+                                  AutomaticGainControlV2, int, Range::automaticGainControlV2,
+                                  AutomaticGainControlV2::fixedDigitalGainMb>(
+                        kDescPair, EffectHelper::expandTestValueBasic<int>)),
+                testing::ValuesIn(EffectHelper::getTestValueSet<
+                                  AutomaticGainControlV2, int, Range::automaticGainControlV2,
+                                  AutomaticGainControlV2::saturationMarginMb>(
+                        kDescPair, EffectHelper::expandTestValueBasic<int>)),
+                testing::ValuesIn(AGC2ParamTest::getLevelEstimatorValues())),
+        [](const testing::TestParamInfo<AGC2ParamTest::ParamType>& info) {
+            auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
+            std::string gain = std::to_string(std::get<PARAM_DIGITAL_GAIN>(info.param));
+            std::string estimator = aidl::android::hardware::audio::effect::toString(
+                    std::get<PARAM_LEVEL_ESTIMATOR>(info.param));
+            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 +
+                               "_level_estimator_" + estimator + "_margin_" + margin;
+            std::replace_if(
+                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+            return name;
+        });
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AGC2ParamTest);
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    ABinderProcess_setThreadPoolMaxThreadCount(1);
+    ABinderProcess_startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/audio/aidl/vts/VtsHalAGCTargetTest.cpp b/audio/aidl/vts/VtsHalAGCTargetTest.cpp
deleted file mode 100644
index 3448ae2..0000000
--- a/audio/aidl/vts/VtsHalAGCTargetTest.cpp
+++ /dev/null
@@ -1,252 +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.
- */
-
-#include <Utils.h>
-#include <aidl/Vintf.h>
-#include <android/binder_enums.h>
-#include <unordered_set>
-
-#define LOG_TAG "VtsHalAGCParamTest"
-
-#include "EffectHelper.h"
-
-using namespace android;
-
-using aidl::android::hardware::audio::effect::AutomaticGainControl;
-using aidl::android::hardware::audio::effect::Capability;
-using aidl::android::hardware::audio::effect::Descriptor;
-using aidl::android::hardware::audio::effect::IEffect;
-using aidl::android::hardware::audio::effect::IFactory;
-using aidl::android::hardware::audio::effect::kAutomaticGainControlTypeUUID;
-using aidl::android::hardware::audio::effect::Parameter;
-
-enum ParamName {
-    PARAM_INSTANCE_NAME,
-    PARAM_DIGITAL_GAIN,
-    PARAM_SATURATION_MARGIN,
-    PARAM_LEVEL_ESTIMATOR
-};
-using AGCParamTestParam =
-        std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int /* gain */,
-                   int /* margin */, AutomaticGainControl::LevelEstimator>;
-
-class AGCParamTest : public ::testing::TestWithParam<AGCParamTestParam>, public EffectHelper {
-  public:
-    AGCParamTest()
-        : mGain(std::get<PARAM_DIGITAL_GAIN>(GetParam())),
-          mMargin(std::get<PARAM_SATURATION_MARGIN>(GetParam())),
-          mLevelEstimator(std::get<PARAM_LEVEL_ESTIMATOR>(GetParam())) {
-        std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
-    }
-
-    void SetUp() override {
-        ASSERT_NE(nullptr, mFactory);
-        ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
-
-        Parameter::Specific specific = getDefaultParamSpecific();
-        Parameter::Common common = EffectHelper::createParamCommon(
-                0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
-                kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
-        IEffect::OpenEffectReturn ret;
-        ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &ret, EX_NONE));
-        ASSERT_NE(nullptr, mEffect);
-    }
-
-    void TearDown() override {
-        ASSERT_NO_FATAL_FAILURE(close(mEffect));
-        ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
-    }
-
-    Parameter::Specific getDefaultParamSpecific() {
-        AutomaticGainControl AGC =
-                AutomaticGainControl::make<AutomaticGainControl::fixedDigitalGainMb>(0);
-        Parameter::Specific specific =
-                Parameter::Specific::make<Parameter::Specific::automaticGainControl>(AGC);
-        return specific;
-    }
-
-    static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
-    std::shared_ptr<IFactory> mFactory;
-    std::shared_ptr<IEffect> mEffect;
-    Descriptor mDescriptor;
-    int mGain;
-    int mMargin;
-    AutomaticGainControl::LevelEstimator mLevelEstimator;
-
-    void SetAndGetParameters() {
-        for (auto& it : mTags) {
-            auto& tag = it.first;
-            auto& AGC = it.second;
-
-            // validate parameter
-            Descriptor desc;
-            ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
-            const bool valid = isTagInRange(tag, AGC, desc);
-            const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
-
-            // set parameter
-            Parameter expectParam;
-            Parameter::Specific specific;
-            specific.set<Parameter::Specific::automaticGainControl>(AGC);
-            expectParam.set<Parameter::specific>(specific);
-            EXPECT_STATUS(expected, mEffect->setParameter(expectParam)) << expectParam.toString();
-
-            // only get if parameter in range and set success
-            if (expected == EX_NONE) {
-                Parameter getParam;
-                Parameter::Id id;
-                AutomaticGainControl::Id specificId;
-                specificId.set<AutomaticGainControl::Id::commonTag>(tag);
-                id.set<Parameter::Id::automaticGainControlTag>(specificId);
-                EXPECT_STATUS(EX_NONE, mEffect->getParameter(id, &getParam));
-
-                EXPECT_EQ(expectParam, getParam) << "\nexpect:" << expectParam.toString()
-                                                 << "\ngetParam:" << getParam.toString();
-            }
-        }
-    }
-
-    void addDigitalGainParam(int gain) {
-        AutomaticGainControl AGC;
-        AGC.set<AutomaticGainControl::fixedDigitalGainMb>(gain);
-        mTags.push_back({AutomaticGainControl::fixedDigitalGainMb, AGC});
-    }
-    void addSaturationMarginParam(int margin) {
-        AutomaticGainControl AGC;
-        AGC.set<AutomaticGainControl::saturationMarginMb>(margin);
-        mTags.push_back({AutomaticGainControl::saturationMarginMb, AGC});
-    }
-    void addLevelEstimatorParam(AutomaticGainControl::LevelEstimator levelEstimator) {
-        AutomaticGainControl AGC;
-        AGC.set<AutomaticGainControl::levelEstimator>(levelEstimator);
-        mTags.push_back({AutomaticGainControl::levelEstimator, AGC});
-    }
-
-    bool isTagInRange(const AutomaticGainControl::Tag& tag, const AutomaticGainControl& AGC,
-                      const Descriptor& desc) const {
-        const AutomaticGainControl::Capability& AGCCap =
-                desc.capability.get<Capability::automaticGainControl>();
-        switch (tag) {
-            case AutomaticGainControl::fixedDigitalGainMb: {
-                auto gain = AGC.get<AutomaticGainControl::fixedDigitalGainMb>();
-                return gain >= 0 && gain <= AGCCap.maxFixedDigitalGainMb;
-            }
-            case AutomaticGainControl::levelEstimator: {
-                return true;
-            }
-            case AutomaticGainControl::saturationMarginMb: {
-                auto margin = AGC.get<AutomaticGainControl::saturationMarginMb>();
-                return margin >= 0 && margin <= AGCCap.maxSaturationMarginMb;
-            }
-            default:
-                return false;
-        }
-    }
-    static std::unordered_set<int> getDigitalGainValues() {
-        auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
-                                                                     kAutomaticGainControlTypeUUID);
-        const auto max = std::max_element(
-                descList.begin(), descList.end(),
-                [](const std::pair<std::shared_ptr<IFactory>, Descriptor>& a,
-                   const std::pair<std::shared_ptr<IFactory>, Descriptor>& b) {
-                    return a.second.capability.get<Capability::automaticGainControl>()
-                                   .maxFixedDigitalGainMb <
-                           b.second.capability.get<Capability::automaticGainControl>()
-                                   .maxFixedDigitalGainMb;
-                });
-        if (max == descList.end()) {
-            return {0};
-        }
-        int maxGain = max->second.capability.get<Capability::automaticGainControl>()
-                              .maxFixedDigitalGainMb;
-        return {-1, 0, maxGain - 1, maxGain, maxGain + 1};
-    }
-    static std::unordered_set<int> getSaturationMarginValues() {
-        auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
-                                                                     kAutomaticGainControlTypeUUID);
-        const auto max = std::max_element(
-                descList.begin(), descList.end(),
-                [](const std::pair<std::shared_ptr<IFactory>, Descriptor>& a,
-                   const std::pair<std::shared_ptr<IFactory>, Descriptor>& b) {
-                    return a.second.capability.get<Capability::automaticGainControl>()
-                                   .maxSaturationMarginMb <
-                           b.second.capability.get<Capability::automaticGainControl>()
-                                   .maxSaturationMarginMb;
-                });
-        if (max == descList.end()) {
-            return {0};
-        }
-        int maxMargin = max->second.capability.get<Capability::automaticGainControl>()
-                                .maxSaturationMarginMb;
-        return {-1, 0, maxMargin - 1, maxMargin, maxMargin + 1};
-    }
-    static std::unordered_set<AutomaticGainControl::LevelEstimator> getLevelEstimatorValues() {
-        return {ndk::enum_range<AutomaticGainControl::LevelEstimator>().begin(),
-                ndk::enum_range<AutomaticGainControl::LevelEstimator>().end()};
-    }
-
-  private:
-    std::vector<std::pair<AutomaticGainControl::Tag, AutomaticGainControl>> mTags;
-    void CleanUp() { mTags.clear(); }
-};
-
-TEST_P(AGCParamTest, SetAndGetDigitalGainParam) {
-    EXPECT_NO_FATAL_FAILURE(addDigitalGainParam(mGain));
-    SetAndGetParameters();
-}
-
-TEST_P(AGCParamTest, SetAndGetSaturationMargin) {
-    EXPECT_NO_FATAL_FAILURE(addSaturationMarginParam(mMargin));
-    SetAndGetParameters();
-}
-
-TEST_P(AGCParamTest, SetAndGetLevelEstimator) {
-    EXPECT_NO_FATAL_FAILURE(addLevelEstimatorParam(mLevelEstimator));
-    SetAndGetParameters();
-}
-
-INSTANTIATE_TEST_SUITE_P(
-        AGCParamTest, AGCParamTest,
-        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
-                                   IFactory::descriptor, kAutomaticGainControlTypeUUID)),
-                           testing::ValuesIn(AGCParamTest::getDigitalGainValues()),
-                           testing::ValuesIn(AGCParamTest::getSaturationMarginValues()),
-                           testing::ValuesIn(AGCParamTest::getLevelEstimatorValues())),
-        [](const testing::TestParamInfo<AGCParamTest::ParamType>& info) {
-            auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
-            std::string gain = std::to_string(std::get<PARAM_DIGITAL_GAIN>(info.param));
-            std::string estimator = aidl::android::hardware::audio::effect::toString(
-                    std::get<PARAM_LEVEL_ESTIMATOR>(info.param));
-            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 +
-                               "_level_estimator_" + estimator + "_margin_" + margin;
-            std::replace_if(
-                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
-            return name;
-        });
-
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AGCParamTest);
-
-int main(int argc, char** argv) {
-    ::testing::InitGoogleTest(&argc, argv);
-    ABinderProcess_setThreadPoolMaxThreadCount(1);
-    ABinderProcess_startThreadPool();
-    return RUN_ALL_TESTS();
-}
\ No newline at end of file
diff --git a/audio/aidl/vts/VtsHalAudioCoreConfigTargetTest.cpp b/audio/aidl/vts/VtsHalAudioCoreConfigTargetTest.cpp
index e7f5817..e5e06eb 100644
--- a/audio/aidl/vts/VtsHalAudioCoreConfigTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioCoreConfigTargetTest.cpp
@@ -1,17 +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.
+ */
+
 #include <set>
 #include <string>
 #include <unordered_map>
 #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"
diff --git a/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
index 3ca51c7..0ae8cfc 100644
--- a/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
@@ -25,6 +25,7 @@
 #include <optional>
 #include <set>
 #include <string>
+#include <string_view>
 #include <variant>
 #include <vector>
 
@@ -52,6 +53,11 @@
 #include "TestUtils.h"
 
 using namespace android;
+using aidl::android::hardware::audio::common::AudioOffloadMetadata;
+using aidl::android::hardware::audio::common::getChannelCount;
+using aidl::android::hardware::audio::common::isBitPositionFlagSet;
+using aidl::android::hardware::audio::common::isTelephonyDeviceType;
+using aidl::android::hardware::audio::common::isValidAudioMode;
 using aidl::android::hardware::audio::common::PlaybackTrackMetadata;
 using aidl::android::hardware::audio::common::RecordTrackMetadata;
 using aidl::android::hardware::audio::common::SinkMetadata;
@@ -59,13 +65,13 @@
 using aidl::android::hardware::audio::core::AudioPatch;
 using aidl::android::hardware::audio::core::AudioRoute;
 using aidl::android::hardware::audio::core::IBluetooth;
+using aidl::android::hardware::audio::core::IBluetoothA2dp;
+using aidl::android::hardware::audio::core::IBluetoothLe;
 using aidl::android::hardware::audio::core::IModule;
 using aidl::android::hardware::audio::core::IStreamCommon;
 using aidl::android::hardware::audio::core::IStreamIn;
 using aidl::android::hardware::audio::core::IStreamOut;
 using aidl::android::hardware::audio::core::ITelephony;
-using aidl::android::hardware::audio::core::MicrophoneDynamicInfo;
-using aidl::android::hardware::audio::core::MicrophoneInfo;
 using aidl::android::hardware::audio::core::ModuleDebug;
 using aidl::android::hardware::audio::core::StreamDescriptor;
 using aidl::android::hardware::audio::core::VendorParameter;
@@ -74,6 +80,7 @@
 using aidl::android::media::audio::common::AudioContentType;
 using aidl::android::media::audio::common::AudioDevice;
 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::AudioDualMonoMode;
 using aidl::android::media::audio::common::AudioFormatType;
@@ -88,16 +95,15 @@
 using aidl::android::media::audio::common::AudioPortConfig;
 using aidl::android::media::audio::common::AudioPortDeviceExt;
 using aidl::android::media::audio::common::AudioPortExt;
+using aidl::android::media::audio::common::AudioPortMixExt;
 using aidl::android::media::audio::common::AudioSource;
 using aidl::android::media::audio::common::AudioUsage;
 using aidl::android::media::audio::common::Boolean;
 using aidl::android::media::audio::common::Float;
 using aidl::android::media::audio::common::Int;
+using aidl::android::media::audio::common::MicrophoneDynamicInfo;
+using aidl::android::media::audio::common::MicrophoneInfo;
 using aidl::android::media::audio::common::Void;
-using android::hardware::audio::common::getChannelCount;
-using android::hardware::audio::common::isBitPositionFlagSet;
-using android::hardware::audio::common::isTelephonyDeviceType;
-using android::hardware::audio::common::isValidAudioMode;
 using android::hardware::audio::common::StreamLogic;
 using android::hardware::audio::common::StreamWorker;
 using ndk::enum_range;
@@ -119,10 +125,51 @@
     return nonExistentIds;
 }
 
-AudioDeviceAddress GenerateUniqueDeviceAddress() {
-    static int nextId = 1;
-    // TODO: Use connection-specific ID.
-    return AudioDeviceAddress::make<AudioDeviceAddress::Tag::id>(std::to_string(++nextId));
+AudioDeviceAddress::Tag suggestDeviceAddressTag(const AudioDeviceDescription& description) {
+    using Tag = AudioDeviceAddress::Tag;
+    if (std::string_view connection = description.connection;
+        connection == AudioDeviceDescription::CONNECTION_BT_A2DP ||
+        // Note: BT LE Broadcast uses a "group id".
+        (description.type != AudioDeviceType::OUT_BROADCAST &&
+         connection == AudioDeviceDescription::CONNECTION_BT_LE) ||
+        connection == AudioDeviceDescription::CONNECTION_BT_SCO ||
+        connection == AudioDeviceDescription::CONNECTION_WIRELESS) {
+        return Tag::mac;
+    } else if (connection == AudioDeviceDescription::CONNECTION_IP_V4) {
+        return Tag::ipv4;
+    } else if (connection == AudioDeviceDescription::CONNECTION_USB) {
+        return Tag::alsa;
+    }
+    return Tag::id;
+}
+
+AudioPort GenerateUniqueDeviceAddress(const AudioPort& port) {
+    static int nextId = 0;
+    using Tag = AudioDeviceAddress::Tag;
+    AudioDeviceAddress address;
+    switch (suggestDeviceAddressTag(port.ext.get<AudioPortExt::Tag::device>().device.type)) {
+        case Tag::id:
+            address = AudioDeviceAddress::make<Tag::id>(std::to_string(++nextId));
+            break;
+        case Tag::mac:
+            address = AudioDeviceAddress::make<Tag::mac>(
+                    std::vector<uint8_t>{1, 2, 3, 4, 5, static_cast<uint8_t>(++nextId & 0xff)});
+            break;
+        case Tag::ipv4:
+            address = AudioDeviceAddress::make<Tag::ipv4>(
+                    std::vector<uint8_t>{192, 168, 0, static_cast<uint8_t>(++nextId & 0xff)});
+            break;
+        case Tag::ipv6:
+            address = AudioDeviceAddress::make<Tag::ipv6>(std::vector<int32_t>{
+                    0xfc00, 0x0123, 0x4567, 0x89ab, 0xcdef, 0, 0, ++nextId & 0xffff});
+            break;
+        case Tag::alsa:
+            address = AudioDeviceAddress::make<Tag::alsa>(std::vector<int32_t>{1, ++nextId});
+            break;
+    }
+    AudioPort result = port;
+    result.ext.get<AudioPortExt::Tag::device>().device.address = std::move(address);
+    return result;
 }
 
 // All 'With*' classes are move-only because they are associated with some
@@ -359,8 +406,9 @@
 // Can be used as a base for any test here, does not depend on the fixture GTest parameters.
 class AudioCoreModuleBase {
   public:
-    // The default buffer size is used mostly for negative tests.
+    // Default buffer sizes are used mostly for negative tests.
     static constexpr int kDefaultBufferSizeFrames = 256;
+    static constexpr int kDefaultLargeBufferSizeFrames = 48000;
 
     void SetUpImpl(const std::string& moduleName) {
         ASSERT_NO_FATAL_FAILURE(ConnectToService(moduleName));
@@ -470,8 +518,6 @@
 class WithDevicePortConnectedState {
   public:
     explicit WithDevicePortConnectedState(const AudioPort& idAndData) : mIdAndData(idAndData) {}
-    WithDevicePortConnectedState(const AudioPort& id, const AudioDeviceAddress& address)
-        : mIdAndData(setAudioPortAddress(id, address)) {}
     WithDevicePortConnectedState(const WithDevicePortConnectedState&) = delete;
     WithDevicePortConnectedState& operator=(const WithDevicePortConnectedState&) = delete;
     ~WithDevicePortConnectedState() {
@@ -491,12 +537,6 @@
     const AudioPort& get() { return mConnectedPort; }
 
   private:
-    static AudioPort setAudioPortAddress(const AudioPort& id, const AudioDeviceAddress& address) {
-        AudioPort result = id;
-        result.ext.get<AudioPortExt::Tag::device>().device.address = address;
-        return result;
-    }
-
     const AudioPort mIdAndData;
     IModule* mModule = nullptr;
     AudioPort mConnectedPort;
@@ -1033,6 +1073,8 @@
         std::shared_ptr<IStreamCommon> common;
         ndk::ScopedAStatus status = stream->getStreamCommon(&common);
         if (!status.isOk()) return status;
+        status = common->prepareToClose();
+        if (!status.isOk()) return status;
         return common->close();
     }
 
@@ -1378,9 +1420,7 @@
         GTEST_SKIP() << "No external devices in the module.";
     }
     for (const auto& port : ports) {
-        AudioPort portWithData = port;
-        portWithData.ext.get<AudioPortExt::Tag::device>().device.address =
-                GenerateUniqueDeviceAddress();
+        AudioPort portWithData = GenerateUniqueDeviceAddress(port);
         WithDevicePortConnectedState portConnected(portWithData);
         ASSERT_NO_FATAL_FAILURE(portConnected.SetUp(module.get()));
         const int32_t connectedPortId = portConnected.getId();
@@ -1493,6 +1533,8 @@
     AudioPortConfig portConfig;
     AudioPortConfig suggestedConfig;
     portConfig.portId = srcMixPort.value().id;
+    const int32_t kIoHandle = 42;
+    portConfig.ext = AudioPortMixExt{.handle = kIoHandle};
     {
         bool applied = true;
         ASSERT_IS_OK(module->setAudioPortConfig(portConfig, &suggestedConfig, &applied))
@@ -1504,18 +1546,22 @@
     EXPECT_TRUE(suggestedConfig.channelMask.has_value());
     EXPECT_TRUE(suggestedConfig.format.has_value());
     EXPECT_TRUE(suggestedConfig.flags.has_value());
+    ASSERT_EQ(AudioPortExt::Tag::mix, suggestedConfig.ext.getTag());
+    EXPECT_EQ(kIoHandle, suggestedConfig.ext.get<AudioPortExt::Tag::mix>().handle);
     WithAudioPortConfig applied(suggestedConfig);
     ASSERT_NO_FATAL_FAILURE(applied.SetUp(module.get()));
     const AudioPortConfig& appliedConfig = applied.get();
     EXPECT_NE(0, appliedConfig.id);
-    EXPECT_TRUE(appliedConfig.sampleRate.has_value());
+    ASSERT_TRUE(appliedConfig.sampleRate.has_value());
     EXPECT_EQ(suggestedConfig.sampleRate.value(), appliedConfig.sampleRate.value());
-    EXPECT_TRUE(appliedConfig.channelMask.has_value());
+    ASSERT_TRUE(appliedConfig.channelMask.has_value());
     EXPECT_EQ(suggestedConfig.channelMask.value(), appliedConfig.channelMask.value());
-    EXPECT_TRUE(appliedConfig.format.has_value());
+    ASSERT_TRUE(appliedConfig.format.has_value());
     EXPECT_EQ(suggestedConfig.format.value(), appliedConfig.format.value());
-    EXPECT_TRUE(appliedConfig.flags.has_value());
+    ASSERT_TRUE(appliedConfig.flags.has_value());
     EXPECT_EQ(suggestedConfig.flags.value(), appliedConfig.flags.value());
+    ASSERT_EQ(AudioPortExt::Tag::mix, appliedConfig.ext.getTag());
+    EXPECT_EQ(kIoHandle, appliedConfig.ext.get<AudioPortExt::Tag::mix>().handle);
 }
 
 TEST_P(AudioCoreModule, SetAllAttachedDevicePortConfigs) {
@@ -1531,7 +1577,7 @@
         GTEST_SKIP() << "No external devices in the module.";
     }
     for (const auto& port : ports) {
-        WithDevicePortConnectedState portConnected(port, GenerateUniqueDeviceAddress());
+        WithDevicePortConnectedState portConnected(GenerateUniqueDeviceAddress(port));
         ASSERT_NO_FATAL_FAILURE(portConnected.SetUp(module.get()));
         ASSERT_NO_FATAL_FAILURE(
                 ApplyEveryConfig(moduleConfig->getPortConfigsForDevicePort(portConnected.get())));
@@ -1586,9 +1632,7 @@
     doNotSimulateConnections.flags().simulateDeviceConnections = false;
     ASSERT_NO_FATAL_FAILURE(doNotSimulateConnections.SetUp(module.get()));
     for (const auto& port : ports) {
-        AudioPort portWithData = port;
-        portWithData.ext.get<AudioPortExt::Tag::device>().device.address =
-                GenerateUniqueDeviceAddress();
+        AudioPort portWithData = GenerateUniqueDeviceAddress(port);
         EXPECT_STATUS(EX_ILLEGAL_STATE, module->connectExternalDevice(portWithData, &ignored))
                 << "static port " << portWithData.toString();
     }
@@ -1600,7 +1644,7 @@
     if (ports.empty()) {
         GTEST_SKIP() << "No external devices in the module.";
     }
-    WithDevicePortConnectedState portConnected(*ports.begin(), GenerateUniqueDeviceAddress());
+    WithDevicePortConnectedState portConnected(GenerateUniqueDeviceAddress(*ports.begin()));
     ASSERT_NO_FATAL_FAILURE(portConnected.SetUp(module.get()));
     ModuleDebug midwayDebugChange = debug->flags();
     midwayDebugChange.simulateDeviceConnections = false;
@@ -1654,9 +1698,7 @@
     for (const auto& port : ports) {
         EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, module->disconnectExternalDevice(port.id))
                 << "when disconnecting already disconnected device port ID " << port.id;
-        AudioPort portWithData = port;
-        portWithData.ext.get<AudioPortExt::Tag::device>().device.address =
-                GenerateUniqueDeviceAddress();
+        AudioPort portWithData = GenerateUniqueDeviceAddress(port);
         WithDevicePortConnectedState portConnected(portWithData);
         ASSERT_NO_FATAL_FAILURE(portConnected.SetUp(module.get()));
         EXPECT_STATUS(EX_ILLEGAL_ARGUMENT,
@@ -1679,7 +1721,7 @@
         GTEST_SKIP() << "No external devices in the module.";
     }
     for (const auto& port : ports) {
-        WithDevicePortConnectedState portConnected(port, GenerateUniqueDeviceAddress());
+        WithDevicePortConnectedState portConnected(GenerateUniqueDeviceAddress(port));
         ASSERT_NO_FATAL_FAILURE(portConnected.SetUp(module.get()));
         const auto portConfig = moduleConfig->getSingleConfigForDevicePort(portConnected.get());
         {
@@ -1707,7 +1749,7 @@
 
         int32_t connectedPortId;
         {
-            WithDevicePortConnectedState portConnected(port, GenerateUniqueDeviceAddress());
+            WithDevicePortConnectedState portConnected(GenerateUniqueDeviceAddress(port));
             ASSERT_NO_FATAL_FAILURE(portConnected.SetUp(module.get()));
             connectedPortId = portConnected.getId();
             std::vector<AudioRoute> connectedPortRoutes;
@@ -1738,6 +1780,42 @@
     }
 }
 
+// Note: This test relies on simulation of external device connections by the HAL module.
+TEST_P(AudioCoreModule, ExternalDeviceMixPortConfigs) {
+    // After an external device has been connected, all mix ports that can be routed
+    // to the device port for the connected device must have non-empty profiles.
+    ASSERT_NO_FATAL_FAILURE(SetUpModuleConfig());
+    std::vector<AudioPort> externalDevicePorts = moduleConfig->getExternalDevicePorts();
+    if (externalDevicePorts.empty()) {
+        GTEST_SKIP() << "No external devices in the module.";
+    }
+    for (const auto& port : externalDevicePorts) {
+        WithDevicePortConnectedState portConnected(GenerateUniqueDeviceAddress(port));
+        ASSERT_NO_FATAL_FAILURE(portConnected.SetUp(module.get()));
+        std::vector<AudioRoute> routes;
+        ASSERT_IS_OK(module->getAudioRoutesForAudioPort(portConnected.getId(), &routes));
+        std::vector<AudioPort> allPorts;
+        ASSERT_IS_OK(module->getAudioPorts(&allPorts));
+        for (const auto& r : routes) {
+            if (r.sinkPortId == portConnected.getId()) {
+                for (const auto& srcPortId : r.sourcePortIds) {
+                    const auto srcPortIt = findById(allPorts, srcPortId);
+                    ASSERT_NE(allPorts.end(), srcPortIt) << "port ID " << srcPortId;
+                    EXPECT_NE(0UL, srcPortIt->profiles.size())
+                            << " source port " << srcPortIt->toString() << " must have its profiles"
+                            << " populated following external device connection";
+                }
+            } else {
+                const auto sinkPortIt = findById(allPorts, r.sinkPortId);
+                ASSERT_NE(allPorts.end(), sinkPortIt) << "port ID " << r.sinkPortId;
+                EXPECT_NE(0UL, sinkPortIt->profiles.size())
+                        << " source port " << sinkPortIt->toString() << " must have its"
+                        << " profiles populated following external device connection";
+            }
+        }
+    }
+}
+
 TEST_P(AudioCoreModule, MasterMute) {
     bool isSupported = false;
     EXPECT_NO_FATAL_FAILURE(TestAccessors<bool>(module.get(), &IModule::getMasterMute,
@@ -2019,6 +2097,112 @@
                                           &hfpConfig));
 }
 
+class AudioCoreBluetoothA2dp : public AudioCoreModuleBase,
+                               public testing::TestWithParam<std::string> {
+  public:
+    void SetUp() override {
+        ASSERT_NO_FATAL_FAILURE(SetUpImpl(GetParam()));
+        ASSERT_IS_OK(module->getBluetoothA2dp(&bluetooth));
+    }
+
+    void TearDown() override { ASSERT_NO_FATAL_FAILURE(TearDownImpl()); }
+
+    std::shared_ptr<IBluetoothA2dp> bluetooth;
+};
+
+TEST_P(AudioCoreBluetoothA2dp, SameInstance) {
+    if (bluetooth == nullptr) {
+        GTEST_SKIP() << "BluetoothA2dp is not supported";
+    }
+    std::shared_ptr<IBluetoothA2dp> bluetooth2;
+    EXPECT_IS_OK(module->getBluetoothA2dp(&bluetooth2));
+    ASSERT_NE(nullptr, bluetooth2.get());
+    EXPECT_EQ(bluetooth->asBinder(), bluetooth2->asBinder())
+            << "getBluetoothA2dp must return the same interface instance across invocations";
+}
+
+TEST_P(AudioCoreBluetoothA2dp, Enabled) {
+    if (bluetooth == nullptr) {
+        GTEST_SKIP() << "BluetoothA2dp is not supported";
+    }
+    // Since enabling A2DP may require having an actual device connection,
+    // limit testing to setting back the current value.
+    bool enabled;
+    ASSERT_IS_OK(bluetooth->isEnabled(&enabled));
+    EXPECT_IS_OK(bluetooth->setEnabled(enabled))
+            << "setEnabled without actual state change must not fail";
+}
+
+TEST_P(AudioCoreBluetoothA2dp, OffloadReconfiguration) {
+    if (bluetooth == nullptr) {
+        GTEST_SKIP() << "BluetoothA2dp is not supported";
+    }
+    bool isSupported;
+    ASSERT_IS_OK(bluetooth->supportsOffloadReconfiguration(&isSupported));
+    bool isSupported2;
+    ASSERT_IS_OK(bluetooth->supportsOffloadReconfiguration(&isSupported2));
+    EXPECT_EQ(isSupported, isSupported2);
+    if (isSupported) {
+        static const auto kStatuses = {EX_NONE, EX_ILLEGAL_STATE};
+        EXPECT_STATUS(kStatuses, bluetooth->reconfigureOffload({}));
+    } else {
+        EXPECT_STATUS(EX_UNSUPPORTED_OPERATION, bluetooth->reconfigureOffload({}));
+    }
+}
+
+class AudioCoreBluetoothLe : public AudioCoreModuleBase,
+                             public testing::TestWithParam<std::string> {
+  public:
+    void SetUp() override {
+        ASSERT_NO_FATAL_FAILURE(SetUpImpl(GetParam()));
+        ASSERT_IS_OK(module->getBluetoothLe(&bluetooth));
+    }
+
+    void TearDown() override { ASSERT_NO_FATAL_FAILURE(TearDownImpl()); }
+
+    std::shared_ptr<IBluetoothLe> bluetooth;
+};
+
+TEST_P(AudioCoreBluetoothLe, SameInstance) {
+    if (bluetooth == nullptr) {
+        GTEST_SKIP() << "BluetoothLe is not supported";
+    }
+    std::shared_ptr<IBluetoothLe> bluetooth2;
+    EXPECT_IS_OK(module->getBluetoothLe(&bluetooth2));
+    ASSERT_NE(nullptr, bluetooth2.get());
+    EXPECT_EQ(bluetooth->asBinder(), bluetooth2->asBinder())
+            << "getBluetoothLe must return the same interface instance across invocations";
+}
+
+TEST_P(AudioCoreBluetoothLe, Enabled) {
+    if (bluetooth == nullptr) {
+        GTEST_SKIP() << "BluetoothLe is not supported";
+    }
+    // Since enabling LE may require having an actual device connection,
+    // limit testing to setting back the current value.
+    bool enabled;
+    ASSERT_IS_OK(bluetooth->isEnabled(&enabled));
+    EXPECT_IS_OK(bluetooth->setEnabled(enabled))
+            << "setEnabled without actual state change must not fail";
+}
+
+TEST_P(AudioCoreBluetoothLe, OffloadReconfiguration) {
+    if (bluetooth == nullptr) {
+        GTEST_SKIP() << "BluetoothLe is not supported";
+    }
+    bool isSupported;
+    ASSERT_IS_OK(bluetooth->supportsOffloadReconfiguration(&isSupported));
+    bool isSupported2;
+    ASSERT_IS_OK(bluetooth->supportsOffloadReconfiguration(&isSupported2));
+    EXPECT_EQ(isSupported, isSupported2);
+    if (isSupported) {
+        static const auto kStatuses = {EX_NONE, EX_ILLEGAL_STATE};
+        EXPECT_STATUS(kStatuses, bluetooth->reconfigureOffload({}));
+    } else {
+        EXPECT_STATUS(EX_UNSUPPORTED_OPERATION, bluetooth->reconfigureOffload({}));
+    }
+}
+
 class AudioCoreTelephony : public AudioCoreModuleBase, public testing::TestWithParam<std::string> {
   public:
     void SetUp() override {
@@ -2212,6 +2396,26 @@
                 << "when closing the stream twice";
     }
 
+    void PrepareToCloseTwice() {
+        const auto portConfig = moduleConfig->getSingleConfigForMixPort(IOTraits<Stream>::is_input);
+        if (!portConfig.has_value()) {
+            GTEST_SKIP() << "No mix port for attached devices";
+        }
+        std::shared_ptr<IStreamCommon> heldStreamCommon;
+        {
+            WithStream<Stream> stream(portConfig.value());
+            ASSERT_NO_FATAL_FAILURE(stream.SetUp(module.get(), kDefaultBufferSizeFrames));
+            std::shared_ptr<IStreamCommon> streamCommon;
+            ASSERT_IS_OK(stream.get()->getStreamCommon(&streamCommon));
+            heldStreamCommon = streamCommon;
+            EXPECT_IS_OK(streamCommon->prepareToClose());
+            EXPECT_IS_OK(streamCommon->prepareToClose())
+                    << "when calling prepareToClose second time";
+        }
+        EXPECT_STATUS(EX_ILLEGAL_STATE, heldStreamCommon->prepareToClose())
+                << "when calling prepareToClose on a closed stream";
+    }
+
     void OpenAllConfigs() {
         const auto allPortConfigs =
                 moduleConfig->getPortConfigsForMixPorts(IOTraits<Stream>::is_input);
@@ -2507,6 +2711,7 @@
     }
 
 TEST_IN_AND_OUT_STREAM(CloseTwice);
+TEST_IN_AND_OUT_STREAM(PrepareToCloseTwice);
 TEST_IN_AND_OUT_STREAM(GetStreamCommon);
 TEST_IN_AND_OUT_STREAM(OpenAllConfigs);
 TEST_IN_AND_OUT_STREAM(OpenInvalidBufferSize);
@@ -2662,7 +2867,7 @@
     aidl::android::hardware::audio::core::IModule::OpenOutputStreamArguments args;
     args.portConfigId = portConfig.getId();
     args.sourceMetadata = GenerateSourceMetadata(portConfig.get());
-    args.bufferSizeFrames = kDefaultBufferSizeFrames;
+    args.bufferSizeFrames = kDefaultLargeBufferSizeFrames;
     aidl::android::hardware::audio::core::IModule::OpenOutputStreamReturn ret;
     EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, module->openOutputStream(args, &ret))
             << "when no offload info is provided for a compressed offload mix port";
@@ -2842,7 +3047,7 @@
         const auto portConfig = moduleConfig->getSingleConfigForMixPort(false, port);
         ASSERT_TRUE(portConfig.has_value()) << "No profiles specified for output mix port";
         WithStream<IStreamOut> stream(portConfig.value());
-        ASSERT_NO_FATAL_FAILURE(stream.SetUp(module.get(), kDefaultBufferSizeFrames));
+        ASSERT_NO_FATAL_FAILURE(stream.SetUp(module.get(), kDefaultLargeBufferSizeFrames));
         bool isSupported = false;
         EXPECT_NO_FATAL_FAILURE(TestAccessors<AudioPlaybackRate>(
                 stream.get(), &IStreamOut::getPlaybackRateParameters,
@@ -2867,7 +3072,7 @@
         const auto portConfig = moduleConfig->getSingleConfigForMixPort(false, port);
         ASSERT_TRUE(portConfig.has_value()) << "No profiles specified for output mix port";
         WithStream<IStreamOut> stream(portConfig.value());
-        ASSERT_NO_FATAL_FAILURE(stream.SetUp(module.get(), kDefaultBufferSizeFrames));
+        ASSERT_NO_FATAL_FAILURE(stream.SetUp(module.get(), kDefaultLargeBufferSizeFrames));
         ndk::ScopedAStatus status;
         EXPECT_STATUS(kStatuses, status = stream.get()->selectPresentation(0, 0));
         if (status.getExceptionCode() != EX_UNSUPPORTED_OPERATION) atLeastOneSupports = true;
@@ -2877,6 +3082,33 @@
     }
 }
 
+TEST_P(AudioStreamOut, UpdateOffloadMetadata) {
+    const auto offloadMixPorts =
+            moduleConfig->getOffloadMixPorts(true /*attachedOnly*/, false /*singlePort*/);
+    if (offloadMixPorts.empty()) {
+        GTEST_SKIP()
+                << "No mix port for compressed offload that could be routed to attached devices";
+    }
+    for (const auto& port : offloadMixPorts) {
+        const auto portConfig = moduleConfig->getSingleConfigForMixPort(false, port);
+        ASSERT_TRUE(portConfig.has_value()) << "No profiles specified for output mix port";
+        WithStream<IStreamOut> stream(portConfig.value());
+        ASSERT_NO_FATAL_FAILURE(stream.SetUp(module.get(), kDefaultLargeBufferSizeFrames));
+        AudioOffloadMetadata validMetadata{
+                .sampleRate = portConfig.value().sampleRate.value().value,
+                .channelMask = portConfig.value().channelMask.value(),
+                .averageBitRatePerSecond = 256000,
+                .delayFrames = 0,
+                .paddingFrames = 0};
+        EXPECT_IS_OK(stream.get()->updateOffloadMetadata(validMetadata));
+        AudioOffloadMetadata invalidMetadata{.sampleRate = -1,
+                                             .averageBitRatePerSecond = -1,
+                                             .delayFrames = -1,
+                                             .paddingFrames = -1};
+        EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, stream.get()->updateOffloadMetadata(invalidMetadata));
+    }
+}
+
 class StreamLogicDefaultDriver : public StreamLogicDriver {
   public:
     StreamLogicDefaultDriver(std::shared_ptr<StateSequence> commands, size_t frameSizeBytes)
@@ -3349,26 +3581,27 @@
             << "getSoundDose must return the same interface instance across invocations";
 }
 
-TEST_P(AudioCoreSoundDose, GetSetOutputRs2) {
+TEST_P(AudioCoreSoundDose, GetSetOutputRs2UpperBound) {
     if (soundDose == nullptr) {
         GTEST_SKIP() << "SoundDose is not supported";
     }
 
     bool isSupported = false;
-    EXPECT_NO_FATAL_FAILURE(TestAccessors<float>(soundDose.get(), &ISoundDose::getOutputRs2,
-                                                 &ISoundDose::setOutputRs2,
+    EXPECT_NO_FATAL_FAILURE(TestAccessors<float>(soundDose.get(),
+                                                 &ISoundDose::getOutputRs2UpperBound,
+                                                 &ISoundDose::setOutputRs2UpperBound,
                                                  /*validValues=*/{80.f, 90.f, 100.f},
                                                  /*invalidValues=*/{79.f, 101.f}, &isSupported));
-    EXPECT_TRUE(isSupported) << "Getting/Setting RS2 must be supported";
+    EXPECT_TRUE(isSupported) << "Getting/Setting RS2 upper bound must be supported";
 }
 
-TEST_P(AudioCoreSoundDose, CheckDefaultRs2Value) {
+TEST_P(AudioCoreSoundDose, CheckDefaultRs2UpperBound) {
     if (soundDose == nullptr) {
         GTEST_SKIP() << "SoundDose is not supported";
     }
 
     float rs2Value;
-    ASSERT_IS_OK(soundDose->getOutputRs2(&rs2Value));
+    ASSERT_IS_OK(soundDose->getOutputRs2UpperBound(&rs2Value));
     EXPECT_EQ(rs2Value, ISoundDose::DEFAULT_MAX_RS2);
 }
 
@@ -3399,6 +3632,14 @@
                          testing::ValuesIn(android::getAidlHalInstanceNames(IModule::descriptor)),
                          android::PrintInstanceNameToString);
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioCoreBluetooth);
+INSTANTIATE_TEST_SUITE_P(AudioCoreBluetoothA2dpTest, AudioCoreBluetoothA2dp,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(IModule::descriptor)),
+                         android::PrintInstanceNameToString);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioCoreBluetoothA2dp);
+INSTANTIATE_TEST_SUITE_P(AudioCoreBluetoothLeTest, AudioCoreBluetoothLe,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(IModule::descriptor)),
+                         android::PrintInstanceNameToString);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioCoreBluetoothLe);
 INSTANTIATE_TEST_SUITE_P(AudioCoreTelephonyTest, AudioCoreTelephony,
                          testing::ValuesIn(android::getAidlHalInstanceNames(IModule::descriptor)),
                          android::PrintInstanceNameToString);
diff --git a/audio/aidl/vts/VtsHalAudioCoreTargetTest.xml b/audio/aidl/vts/VtsHalAudioCoreTargetTest.xml
new file mode 100644
index 0000000..dfc1039
--- /dev/null
+++ b/audio/aidl/vts/VtsHalAudioCoreTargetTest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<configuration description="Runs VtsHalAudioCoreTargetTest.">
+    <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 class="com.android.tradefed.targetprep.StopServicesSetup"/>
+
+    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+        <option name="run-command" value="setprop vts.native_server.on 1"/>
+        <option name="teardown-command" value="setprop vts.native_server.on 0"/>
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="VtsHalAudioCoreTargetTest" />
+        <option name="native-test-timeout" value="10m" />
+    </test>
+</configuration>
diff --git a/audio/aidl/vts/VtsHalAudioEffectFactoryTargetTest.cpp b/audio/aidl/vts/VtsHalAudioEffectFactoryTargetTest.cpp
index 21f5eb5..7b9477d 100644
--- a/audio/aidl/vts/VtsHalAudioEffectFactoryTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioEffectFactoryTargetTest.cpp
@@ -28,6 +28,7 @@
 #include <android/binder_interface_utils.h>
 #include <android/binder_manager.h>
 #include <android/binder_process.h>
+#include <system/audio_effects/effect_uuid.h>
 
 #include <aidl/android/hardware/audio/effect/IFactory.h>
 
@@ -38,10 +39,10 @@
 using namespace android;
 
 using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectUuidNull;
+using aidl::android::hardware::audio::effect::getEffectUuidZero;
 using aidl::android::hardware::audio::effect::IEffect;
 using aidl::android::hardware::audio::effect::IFactory;
-using aidl::android::hardware::audio::effect::kEffectNullUuid;
-using aidl::android::hardware::audio::effect::kEffectZeroUuid;
 using aidl::android::hardware::audio::effect::Processing;
 using aidl::android::media::audio::common::AudioSource;
 using aidl::android::media::audio::common::AudioStreamType;
@@ -65,8 +66,8 @@
     std::unique_ptr<EffectFactoryHelper> mFactoryHelper;
     std::shared_ptr<IFactory> mEffectFactory;
     std::vector<std::shared_ptr<IEffect>> mEffects;
-    const Descriptor::Identity kNullId = {.uuid = kEffectNullUuid};
-    const Descriptor::Identity kZeroId = {.uuid = kEffectZeroUuid};
+    const Descriptor::Identity kNullId = {.uuid = getEffectUuidNull()};
+    const Descriptor::Identity kZeroId = {.uuid = getEffectUuidZero()};
     const Descriptor kNullDesc = {.common.id = kNullId};
     const Descriptor kZeroDesc = {.common.id = kZeroId};
 
@@ -132,13 +133,13 @@
 TEST_P(EffectFactoryTest, ExpectAllAospEffectTypes) {
     std::vector<Descriptor> descs;
     std::set<AudioUuid> typeUuidSet(
-            {aidl::android::hardware::audio::effect::kBassBoostTypeUUID,
-             aidl::android::hardware::audio::effect::kEqualizerTypeUUID,
-             aidl::android::hardware::audio::effect::kEnvReverbTypeUUID,
-             aidl::android::hardware::audio::effect::kPresetReverbTypeUUID,
-             aidl::android::hardware::audio::effect::kDynamicsProcessingTypeUUID,
-             aidl::android::hardware::audio::effect::kHapticGeneratorTypeUUID,
-             aidl::android::hardware::audio::effect::kVirtualizerTypeUUID});
+            {aidl::android::hardware::audio::effect::getEffectTypeUuidBassBoost(),
+             aidl::android::hardware::audio::effect::getEffectTypeUuidEqualizer(),
+             aidl::android::hardware::audio::effect::getEffectTypeUuidEnvReverb(),
+             aidl::android::hardware::audio::effect::getEffectTypeUuidPresetReverb(),
+             aidl::android::hardware::audio::effect::getEffectTypeUuidDynamicsProcessing(),
+             aidl::android::hardware::audio::effect::getEffectTypeUuidHapticGenerator(),
+             aidl::android::hardware::audio::effect::getEffectTypeUuidVirtualizer()});
 
     EXPECT_IS_OK(mEffectFactory->queryEffects(std::nullopt, std::nullopt, std::nullopt, &descs));
     EXPECT_TRUE(descs.size() >= typeUuidSet.size());
@@ -155,19 +156,22 @@
 
 TEST_P(EffectFactoryTest, QueryNullTypeUuid) {
     std::vector<Descriptor> descs;
-    EXPECT_IS_OK(mEffectFactory->queryEffects(kEffectNullUuid, std::nullopt, std::nullopt, &descs));
+    EXPECT_IS_OK(
+            mEffectFactory->queryEffects(getEffectUuidNull(), std::nullopt, std::nullopt, &descs));
     EXPECT_EQ(descs.size(), 0UL);
 }
 
 TEST_P(EffectFactoryTest, QueriedNullImplUuid) {
     std::vector<Descriptor> descs;
-    EXPECT_IS_OK(mEffectFactory->queryEffects(std::nullopt, kEffectNullUuid, std::nullopt, &descs));
+    EXPECT_IS_OK(
+            mEffectFactory->queryEffects(std::nullopt, getEffectUuidNull(), std::nullopt, &descs));
     EXPECT_EQ(descs.size(), 0UL);
 }
 
 TEST_P(EffectFactoryTest, QueriedNullProxyUuid) {
     std::vector<Descriptor> descs;
-    EXPECT_IS_OK(mEffectFactory->queryEffects(std::nullopt, std::nullopt, kEffectNullUuid, &descs));
+    EXPECT_IS_OK(
+            mEffectFactory->queryEffects(std::nullopt, std::nullopt, getEffectUuidNull(), &descs));
     EXPECT_EQ(descs.size(), 0UL);
 }
 
diff --git a/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp b/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
index c5a0943..d8ad6c9 100644
--- a/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
@@ -21,7 +21,6 @@
 #include <string>
 #include <vector>
 
-#include <Utils.h>
 #include <aidl/Gtest.h>
 #include <aidl/Vintf.h>
 #include <aidl/android/hardware/audio/effect/IEffect.h>
@@ -82,7 +81,7 @@
         Parameter get;
         EXPECT_IS_OK(mEffect->setParameter(set));
         EXPECT_IS_OK(mEffect->getParameter(id, &get));
-        EXPECT_EQ(set, get) << set.toString() << " vs " << get.toString();
+        EXPECT_EQ(set, get) << set.toString() << "\n vs \n" << get.toString();
     }
 };
 
@@ -140,7 +139,10 @@
     Descriptor desc;
     ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
     ASSERT_NO_FATAL_FAILURE(getDescriptor(mEffect, desc));
-    EXPECT_EQ(mDescriptor.common, desc.common);
+    EXPECT_EQ(mDescriptor.common.id.type, desc.common.id.type);
+    EXPECT_EQ(mDescriptor.common.id.uuid, desc.common.id.uuid);
+    EXPECT_EQ(mDescriptor.common.name, desc.common.name);
+    EXPECT_EQ(mDescriptor.common.implementor, desc.common.implementor);
     // Effect implementation Must fill in implementor and name
     EXPECT_NE("", desc.common.name);
     EXPECT_NE("", desc.common.implementor);
@@ -177,7 +179,11 @@
 
     ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
     ASSERT_NO_FATAL_FAILURE(getDescriptor(mEffect, desc));
-    EXPECT_EQ(1ul, idSet.count(desc.common.id));
+    int uuidCount = std::count_if(idSet.begin(), idSet.end(), [&](const auto& id) {
+        return id.uuid == desc.common.id.uuid && id.type == desc.common.id.type;
+    });
+
+    EXPECT_EQ(1, uuidCount);
     ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
 }
 
@@ -390,7 +396,7 @@
     Parameter::Id id;
     id.set<Parameter::Id::commonTag>(Parameter::common);
     EXPECT_IS_OK(mEffect->getParameter(id, &get));
-    EXPECT_EQ(expect, get) << expect.toString() << " vs " << get.toString();
+    EXPECT_EQ(expect, get) << expect.toString() << "\n vs \n" << get.toString();
 
     ASSERT_NO_FATAL_FAILURE(close(mEffect));
     ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
@@ -590,12 +596,14 @@
     ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
 
     std::vector<float> buffer;
-    EffectHelper::allocateInputData(common, inputMQ, buffer);
-    EffectHelper::writeToFmq(inputMQ, buffer);
-    EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer);
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(
+            EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer));
 
     ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
     ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer));
 
     ASSERT_NO_FATAL_FAILURE(close(mEffect));
     ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
@@ -617,20 +625,24 @@
     auto outputMQ = std::make_unique<EffectHelper::DataMQ>(ret.outputDataMQ);
     ASSERT_TRUE(outputMQ->isValid());
 
-    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
-    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
-    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
-    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
-    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
-    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
-
     std::vector<float> buffer;
-    EffectHelper::allocateInputData(common, inputMQ, buffer);
-    EffectHelper::writeToFmq(inputMQ, buffer);
-    EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer);
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    EXPECT_NO_FATAL_FAILURE(
+            EffectHelper::readFromFmq(statusMQ, 0, outputMQ, buffer.size(), buffer));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(
+            EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer));
 
     ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
     ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer));
 
     ASSERT_NO_FATAL_FAILURE(close(mEffect));
     ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
@@ -653,14 +665,14 @@
     ASSERT_TRUE(outputMQ->isValid());
 
     std::vector<float> buffer;
-    EffectHelper::allocateInputData(common, inputMQ, buffer);
-    EffectHelper::writeToFmq(inputMQ, buffer);
-    EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer);
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(inputMQ, buffer));
 
     ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
     ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
 
-    EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer);
+    EXPECT_NO_FATAL_FAILURE(
+            EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer));
 
     ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
     ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
@@ -686,31 +698,30 @@
     ASSERT_TRUE(outputMQ->isValid());
 
     std::vector<float> buffer;
-    EffectHelper::allocateInputData(common, inputMQ, buffer);
-    EffectHelper::writeToFmq(inputMQ, buffer);
-    EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer);
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer));
 
     ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
     ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
 
-    EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer);
-    // expect no status and data after consume
-    EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer);
+    EXPECT_NO_FATAL_FAILURE(
+            EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer));
 
-    EffectHelper::writeToFmq(inputMQ, buffer);
-    EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer);
-    // expect no status and data after consume
-    EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer);
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(
+            EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer));
 
     ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
     ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer));
 
     ASSERT_NO_FATAL_FAILURE(close(mEffect));
     ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
 }
 
-// Send data to IDLE state effects and expect it not be consumed.
-TEST_P(AudioEffectTest, NotConsumeDataInIdleState) {
+// Send data to processing state effects, stop, and restart.
+TEST_P(AudioEffectTest, ConsumeDataAndRestart) {
     ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
 
     Parameter::Common common = EffectHelper::createParamCommon(
@@ -727,17 +738,21 @@
 
     ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
     ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+    std::vector<float> buffer;
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(
+            EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer));
+
     ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
     ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
-
-    std::vector<float> buffer;
-    EffectHelper::allocateInputData(common, inputMQ, buffer);
-    EffectHelper::writeToFmq(inputMQ, buffer);
-    EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer);
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer));
 
     ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
     ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
-    EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer);
+    EXPECT_NO_FATAL_FAILURE(
+            EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer));
 
     ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
     ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
@@ -765,9 +780,9 @@
     ASSERT_TRUE(outputMQ->isValid());
 
     std::vector<float> buffer;
-    EffectHelper::allocateInputData(common, inputMQ, buffer);
-    EffectHelper::writeToFmq(inputMQ, buffer);
-    EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer);
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer));
 
     ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
 }
@@ -800,9 +815,10 @@
     ASSERT_TRUE(outputMQ1->isValid());
 
     std::vector<float> buffer1, buffer2;
-    EffectHelper::allocateInputData(common1, inputMQ1, buffer1);
-    EffectHelper::writeToFmq(inputMQ1, buffer1);
-    EffectHelper::readFromFmq(statusMQ1, 1, outputMQ1, buffer1.size(), buffer1);
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common1, inputMQ1, buffer1));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(inputMQ1, buffer1));
+    EXPECT_NO_FATAL_FAILURE(
+            EffectHelper::readFromFmq(statusMQ1, 1, outputMQ1, buffer1.size(), buffer1));
 
     auto statusMQ2 = std::make_unique<EffectHelper::StatusMQ>(ret2.statusMQ);
     ASSERT_TRUE(statusMQ2->isValid());
@@ -810,9 +826,10 @@
     ASSERT_TRUE(inputMQ2->isValid());
     auto outputMQ2 = std::make_unique<EffectHelper::DataMQ>(ret2.outputDataMQ);
     ASSERT_TRUE(outputMQ2->isValid());
-    EffectHelper::allocateInputData(common2, inputMQ2, buffer2);
-    EffectHelper::writeToFmq(inputMQ2, buffer2);
-    EffectHelper::readFromFmq(statusMQ2, 1, outputMQ2, buffer2.size(), buffer2);
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common2, inputMQ2, buffer2));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(inputMQ2, buffer2));
+    EXPECT_NO_FATAL_FAILURE(
+            EffectHelper::readFromFmq(statusMQ2, 1, outputMQ2, buffer2.size(), buffer2));
 
     ASSERT_NO_FATAL_FAILURE(command(effect1, CommandId::STOP));
     ASSERT_NO_FATAL_FAILURE(expectState(effect1, State::IDLE));
diff --git a/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp b/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp
index d49a865..9cfdc50 100644
--- a/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp
@@ -14,12 +14,12 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "VtsHalBassBoostTest"
-
-#include <Utils.h>
-#include <aidl/Vintf.h>
 #include <limits.h>
 
+#include <aidl/Vintf.h>
+#define LOG_TAG "VtsHalBassBoostTest"
+#include <android-base/logging.h>
+
 #include "EffectHelper.h"
 
 using namespace android;
@@ -27,10 +27,11 @@
 using aidl::android::hardware::audio::effect::BassBoost;
 using aidl::android::hardware::audio::effect::Capability;
 using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidBassBoost;
 using aidl::android::hardware::audio::effect::IEffect;
 using aidl::android::hardware::audio::effect::IFactory;
-using aidl::android::hardware::audio::effect::kBassBoostTypeUUID;
 using aidl::android::hardware::audio::effect::Parameter;
+using aidl::android::hardware::audio::effect::Range;
 
 /**
  * Here we focus on specific parameter checking, general IEffect interfaces testing performed in
@@ -92,7 +93,7 @@
             // validate parameter
             Descriptor desc;
             ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
-            const bool valid = isTagInRange(it.first, it.second, desc);
+            const bool valid = isParameterValid<BassBoost, Range::bassBoost>(it.second, desc);
             const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
 
             // set parameter
@@ -122,46 +123,6 @@
         mTags.push_back({BassBoost::strengthPm, bb});
     }
 
-    bool isTagInRange(const BassBoost::Tag& tag, const BassBoost& bb,
-                      const Descriptor& desc) const {
-        const BassBoost::Capability& bbCap = desc.capability.get<Capability::bassBoost>();
-        switch (tag) {
-            case BassBoost::strengthPm: {
-                int strength = bb.get<BassBoost::strengthPm>();
-                return isStrengthInRange(bbCap, strength);
-            }
-            default:
-                return false;
-        }
-        return false;
-    }
-
-    bool isStrengthInRange(const BassBoost::Capability& cap, int strength) const {
-        return cap.strengthSupported && strength >= 0 && strength <= cap.maxStrengthPm;
-    }
-
-    static std::vector<int> getStrengthTestValues(
-            std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kFactoryDescList) {
-        const auto max = std::max_element(
-                kFactoryDescList.begin(), kFactoryDescList.end(),
-                [](const std::pair<std::shared_ptr<IFactory>, Descriptor>& a,
-                   const std::pair<std::shared_ptr<IFactory>, Descriptor>& b) {
-                    return a.second.capability.get<Capability::bassBoost>().maxStrengthPm <
-                           b.second.capability.get<Capability::bassBoost>().maxStrengthPm;
-                });
-        if (max == kFactoryDescList.end()) {
-            return {0};
-        }
-        int maxStrength = max->second.capability.get<Capability::bassBoost>().maxStrengthPm;
-        return {std::numeric_limits<int>::min(),
-                -1,
-                0,
-                maxStrength >> 1,
-                maxStrength,
-                maxStrength + 1,
-                std::numeric_limits<int>::max()};
-    }
-
   private:
     std::vector<std::pair<BassBoost::Tag, BassBoost>> mTags;
     void CleanUp() { mTags.clear(); }
@@ -172,14 +133,15 @@
     SetAndGetBassBoostParameters();
 }
 
+std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kDescPair;
 INSTANTIATE_TEST_SUITE_P(
         BassBoostTest, BassBoostParamTest,
         ::testing::Combine(
-                testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
-                                                                               kBassBoostTypeUUID)),
-                testing::ValuesIn(BassBoostParamTest::getStrengthTestValues(
-                        EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
-                                                                     kBassBoostTypeUUID)))),
+                testing::ValuesIn(kDescPair = EffectFactoryHelper::getAllEffectDescriptors(
+                                          IFactory::descriptor, getEffectTypeUuidBassBoost())),
+                testing::ValuesIn(EffectHelper::getTestValueSet<BassBoost, int, Range::bassBoost,
+                                                                BassBoost::strengthPm>(
+                        kDescPair, EffectHelper::expandTestValueBasic<int>))),
         [](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));
diff --git a/audio/aidl/vts/VtsHalDownmixTargetTest.cpp b/audio/aidl/vts/VtsHalDownmixTargetTest.cpp
index 8612660..5aeebde 100644
--- a/audio/aidl/vts/VtsHalDownmixTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalDownmixTargetTest.cpp
@@ -14,21 +14,19 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "VtsHalDownmixTargetTest"
-
-#include <Utils.h>
 #include <aidl/Vintf.h>
+#define LOG_TAG "VtsHalDownmixTargetTest"
+#include <android-base/logging.h>
+
 #include "EffectHelper.h"
 
 using namespace android;
 
-using aidl::android::hardware::audio::effect::Capability;
 using aidl::android::hardware::audio::effect::Descriptor;
 using aidl::android::hardware::audio::effect::Downmix;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidDownmix;
 using aidl::android::hardware::audio::effect::IEffect;
 using aidl::android::hardware::audio::effect::IFactory;
-using aidl::android::hardware::audio::effect::kDownmixTypeUUID;
-using aidl::android::hardware::audio::effect::kEffectNullUuid;
 using aidl::android::hardware::audio::effect::Parameter;
 
 /**
@@ -123,7 +121,7 @@
 INSTANTIATE_TEST_SUITE_P(
         DownmixTest, DownmixParamTest,
         ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
-                                   IFactory::descriptor, kDownmixTypeUUID)),
+                                   IFactory::descriptor, getEffectTypeUuidDownmix())),
                            testing::ValuesIn(kTypeValues)),
         [](const testing::TestParamInfo<DownmixParamTest::ParamType>& info) {
             auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
diff --git a/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp b/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp
index 9feff91..033e3b5 100644
--- a/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp
+++ b/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp
@@ -14,26 +14,27 @@
  * limitations under the License.
  */
 
-#include <aidl/Vintf.h>
-
-#define LOG_TAG "VtsHalDynamicsProcessingTest"
-
 #include <set>
 #include <string>
-#include <unordered_map>
 #include <unordered_set>
 
+#include <aidl/Vintf.h>
+#define LOG_TAG "VtsHalDynamicsProcessingTest"
+#include <android-base/logging.h>
+
 #include <Utils.h>
+
 #include "EffectHelper.h"
+#include "EffectRangeSpecific.h"
 
 using namespace android;
+using namespace aidl::android::hardware::audio::effect::DynamicsProcessingRanges;
 
-using aidl::android::hardware::audio::effect::Capability;
 using aidl::android::hardware::audio::effect::Descriptor;
 using aidl::android::hardware::audio::effect::DynamicsProcessing;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidDynamicsProcessing;
 using aidl::android::hardware::audio::effect::IEffect;
 using aidl::android::hardware::audio::effect::IFactory;
-using aidl::android::hardware::audio::effect::kDynamicsProcessingTypeUUID;
 using aidl::android::hardware::audio::effect::Parameter;
 
 /**
@@ -46,7 +47,7 @@
                                  int32_t channelLayOut = AudioChannelLayout::LAYOUT_STEREO) {
         std::tie(mFactory, mDescriptor) = pair;
         mChannelLayout = channelLayOut;
-        mChannelCount = ::android::hardware::audio::common::getChannelCount(
+        mChannelCount = ::aidl::android::hardware::audio::common::getChannelCount(
                 AudioChannelLayout::make<AudioChannelLayout::layoutMask>(mChannelLayout));
     }
 
@@ -82,31 +83,8 @@
     }
 
     // utils functions for parameter checking
-    bool isParamValid(const DynamicsProcessing::Tag& tag, const DynamicsProcessing& dp,
-                      const Descriptor& desc);
     bool isParamEqual(const DynamicsProcessing::Tag& tag, const DynamicsProcessing& dpRef,
                       const DynamicsProcessing& dpTest);
-
-    bool isEnablementValid(const DynamicsProcessing::StageEnablement& enablement);
-    bool isEngineConfigValid(const DynamicsProcessing::EngineArchitecture& cfg);
-
-    bool isCutoffFrequencyValid(float freq, const DynamicsProcessing::Capability& cap);
-    bool isChannelConfigValid(const std::vector<DynamicsProcessing::ChannelConfig>& cfgs,
-                              bool stageInUse);
-
-    bool isPreEqBandConfigValid(const DynamicsProcessing::Capability& cap,
-                                const std::vector<DynamicsProcessing::EqBandConfig>& cfgs,
-                                bool stageInUse, int bandCount);
-    bool isPostEqBandConfigValid(const DynamicsProcessing::Capability& cap,
-                                 const std::vector<DynamicsProcessing::EqBandConfig>& cfgs,
-                                 bool stageInUse, int bandCount);
-    bool isMbcBandConfigValid(const DynamicsProcessing::Capability& cap,
-                              const std::vector<DynamicsProcessing::MbcBandConfig>& cfgs,
-                              bool stageInUse, int bandCount);
-    bool isLimiterConfigValid(const std::vector<DynamicsProcessing::LimiterConfig>& cfgs,
-                              bool stageInUse);
-    bool isInputGainValid(const std::vector<DynamicsProcessing::InputGain>& cfgs);
-
     bool isEngineConfigEqual(const DynamicsProcessing::EngineArchitecture& refCfg,
                              const DynamicsProcessing::EngineArchitecture& testCfg);
 
@@ -119,6 +97,19 @@
     template <typename T>
     bool isAidlVectorEqual(const std::vector<T>& source, const std::vector<T>& target);
 
+    template <typename T>
+    bool isChannelConfigValid(const std::vector<T>& cfgs) {
+        auto& channelCount = mChannelCount;
+        return std::all_of(cfgs.cbegin(), cfgs.cend(), [channelCount](const T& cfg) {
+            return (cfg.channel >= 0 && cfg.channel < channelCount);
+        });
+    }
+
+    template <typename T>
+    bool isBandConfigValid(const std::vector<T>& cfgs, int bandCount);
+
+    bool isParamValid(const DynamicsProcessing::Tag& tag, const DynamicsProcessing& dp);
+
     // get set params and validate
     void SetAndGetDynamicsProcessingParameters();
 
@@ -157,9 +148,11 @@
     static const std::set<DynamicsProcessing::StageEnablement> kStageEnablementTestSet;
     static const std::set<std::vector<DynamicsProcessing::InputGain>> kInputGainTestSet;
 
+  protected:
+    int mChannelCount;
+
   private:
     int32_t mChannelLayout;
-    int mChannelCount;
     std::vector<std::pair<DynamicsProcessing::Tag, DynamicsProcessing>> mTags;
     void CleanUp() {
         mTags.clear();
@@ -176,6 +169,8 @@
                 {.inUse = true, .bandCount = DynamicsProcessingTestHelper::kBandCount},
                 {.inUse = true, .bandCount = 0},
                 {.inUse = true, .bandCount = -1},
+                {.inUse = false, .bandCount = 0},
+                {.inUse = false, .bandCount = -1},
                 {.inUse = false, .bandCount = DynamicsProcessingTestHelper::kBandCount}};
 
 // test value set for DynamicsProcessing::ChannelConfig
@@ -185,9 +180,7 @@
                  {.channel = 0, .enable = true},
                  {.channel = 1, .enable = false},
                  {.channel = 2, .enable = true}},
-
                 {{.channel = -1, .enable = false}, {.channel = 2, .enable = true}},
-
                 {{.channel = 0, .enable = true}, {.channel = 1, .enable = true}}};
 
 // test value set for DynamicsProcessing::InputGain
@@ -196,55 +189,60 @@
                 {{.channel = 0, .gainDb = 10.f},
                  {.channel = 1, .gainDb = 0.f},
                  {.channel = 2, .gainDb = -10.f}},
-
                 {{.channel = -1, .gainDb = -10.f}, {.channel = -2, .gainDb = 10.f}},
+                {{.channel = -1, .gainDb = 10.f}, {.channel = 0, .gainDb = -10.f}},
+                {{.channel = 0, .gainDb = 10.f}, {.channel = 1, .gainDb = -10.f}}};
 
-                {{.channel = -1, .gainDb = 10.f}, {.channel = 0, .gainDb = -10.f}}};
+template <typename T>
+bool DynamicsProcessingTestHelper::isBandConfigValid(const std::vector<T>& cfgs, int bandCount) {
+    std::vector<float> freqs(cfgs.size(), -1);
+    for (auto cfg : cfgs) {
+        if (cfg.channel < 0 || cfg.channel >= mChannelCount) return false;
+        if (cfg.band < 0 || cfg.band >= bandCount) return false;
+        freqs[cfg.band] = cfg.cutoffFrequencyHz;
+    }
+    if (std::count(freqs.begin(), freqs.end(), -1)) return false;
+    return std::is_sorted(freqs.begin(), freqs.end());
+}
 
 bool DynamicsProcessingTestHelper::isParamValid(const DynamicsProcessing::Tag& tag,
-                                                const DynamicsProcessing& dp,
-                                                const Descriptor& desc) {
-    const DynamicsProcessing::Capability& dpCap =
-            desc.capability.get<Capability::dynamicsProcessing>();
+                                                const DynamicsProcessing& dp) {
     switch (tag) {
-        case DynamicsProcessing::engineArchitecture: {
-            return isEngineConfigValid(dp.get<DynamicsProcessing::engineArchitecture>());
-        }
         case DynamicsProcessing::preEq: {
-            return isChannelConfigValid(dp.get<DynamicsProcessing::preEq>(),
-                                        mEngineConfigApplied.preEqStage.inUse);
+            if (!mEngineConfigApplied.preEqStage.inUse) return false;
+            return isChannelConfigValid(dp.get<DynamicsProcessing::preEq>());
         }
         case DynamicsProcessing::postEq: {
-            return isChannelConfigValid(dp.get<DynamicsProcessing::postEq>(),
-                                        mEngineConfigApplied.postEqStage.inUse);
+            if (!mEngineConfigApplied.postEqStage.inUse) return false;
+            return isChannelConfigValid(dp.get<DynamicsProcessing::postEq>());
         }
         case DynamicsProcessing::mbc: {
-            return isChannelConfigValid(dp.get<DynamicsProcessing::mbc>(),
-                                        mEngineConfigApplied.mbcStage.inUse);
+            if (!mEngineConfigApplied.mbcStage.inUse) return false;
+            return isChannelConfigValid(dp.get<DynamicsProcessing::mbc>());
         }
         case DynamicsProcessing::preEqBand: {
-            return isPreEqBandConfigValid(dpCap, dp.get<DynamicsProcessing::preEqBand>(),
-                                          mEngineConfigApplied.preEqStage.inUse,
-                                          mEngineConfigApplied.preEqStage.bandCount);
+            if (!mEngineConfigApplied.preEqStage.inUse) return false;
+            return isBandConfigValid(dp.get<DynamicsProcessing::preEqBand>(),
+                                     mEngineConfigApplied.preEqStage.bandCount);
         }
         case DynamicsProcessing::postEqBand: {
-            return isPostEqBandConfigValid(dpCap, dp.get<DynamicsProcessing::postEqBand>(),
-                                           mEngineConfigApplied.postEqStage.inUse,
-                                           mEngineConfigApplied.postEqStage.bandCount);
+            if (!mEngineConfigApplied.postEqStage.inUse) return false;
+            return isBandConfigValid(dp.get<DynamicsProcessing::postEqBand>(),
+                                     mEngineConfigApplied.postEqStage.bandCount);
         }
         case DynamicsProcessing::mbcBand: {
-            return isMbcBandConfigValid(dpCap, dp.get<DynamicsProcessing::mbcBand>(),
-                                        mEngineConfigApplied.mbcStage.inUse,
-                                        mEngineConfigApplied.mbcStage.bandCount);
+            if (!mEngineConfigApplied.mbcStage.inUse) return false;
+            return isBandConfigValid(dp.get<DynamicsProcessing::mbcBand>(),
+                                     mEngineConfigApplied.mbcStage.bandCount);
         }
         case DynamicsProcessing::limiter: {
-            return isLimiterConfigValid(dp.get<DynamicsProcessing::limiter>(),
-                                        mEngineConfigApplied.limiterInUse);
+            if (!mEngineConfigApplied.limiterInUse) return false;
+            return isChannelConfigValid(dp.get<DynamicsProcessing::limiter>());
         }
         case DynamicsProcessing::inputGain: {
-            return isInputGainValid(dp.get<DynamicsProcessing::inputGain>());
+            return isChannelConfigValid(dp.get<DynamicsProcessing::inputGain>());
         }
-        case DynamicsProcessing::vendorExtension: {
+        default: {
             return true;
         }
     }
@@ -298,123 +296,12 @@
                     dpRef.get<DynamicsProcessing::inputGain>(),
                     dpTest.get<DynamicsProcessing::inputGain>());
         }
-        case DynamicsProcessing::vendorExtension: {
+        case DynamicsProcessing::vendor: {
             return false;
         }
     }
 }
 
-bool DynamicsProcessingTestHelper::isEnablementValid(
-        const DynamicsProcessing::StageEnablement& enablement) {
-    return !enablement.inUse || (enablement.inUse && enablement.bandCount > 0);
-}
-
-bool DynamicsProcessingTestHelper::isEngineConfigValid(
-        const DynamicsProcessing::EngineArchitecture& cfg) {
-    return cfg.preferredProcessingDurationMs >= 0 && isEnablementValid(cfg.preEqStage) &&
-           isEnablementValid(cfg.postEqStage) && isEnablementValid(cfg.mbcStage);
-}
-
-bool DynamicsProcessingTestHelper::isChannelConfigValid(
-        const std::vector<DynamicsProcessing::ChannelConfig>& cfgs, bool stageInUse) {
-    std::unordered_set<int> channelSet;
-    if (!stageInUse) return false;
-    for (auto cfg : cfgs) {
-        if (cfg.channel < 0 || cfg.channel >= mChannelCount || 0 != channelSet.count(cfg.channel)) {
-            return false;
-        }
-        channelSet.insert(cfg.channel);
-    }
-    return true;
-}
-
-bool DynamicsProcessingTestHelper::isCutoffFrequencyValid(
-        float freq, const DynamicsProcessing::Capability& cap) {
-    return freq >= cap.minCutOffFreq && freq <= cap.maxCutOffFreq;
-}
-
-bool DynamicsProcessingTestHelper::isPreEqBandConfigValid(
-        const DynamicsProcessing::Capability& cap,
-        const std::vector<DynamicsProcessing::EqBandConfig>& cfgs, bool stageInUse, int bandCount) {
-    std::set<std::pair<int /* channelID */, int /* bandID */>> bandSet;
-    if (!stageInUse) return false;
-    for (auto cfg : cfgs) {
-        if (0 == mPreEqChannelEnable.count(cfg.channel) || cfg.channel < 0 ||
-            cfg.channel >= mChannelCount || cfg.band < 0 || cfg.band >= bandCount ||
-            !isCutoffFrequencyValid(cfg.cutoffFrequencyHz, cap) ||
-            0 != bandSet.count({cfg.channel, cfg.band})) {
-            return false;
-        }
-        bandSet.insert({cfg.channel, cfg.band});
-    }
-    return true;
-}
-
-bool DynamicsProcessingTestHelper::isPostEqBandConfigValid(
-        const DynamicsProcessing::Capability& cap,
-        const std::vector<DynamicsProcessing::EqBandConfig>& cfgs, bool stageInUse, int bandCount) {
-    std::set<std::pair<int /* channelID */, int /* bandID */>> bandSet;
-    // not able to set/get parameter when stage not in use.
-    if (!stageInUse) return false;
-    for (auto cfg : cfgs) {
-        if (0 == mPostEqChannelEnable.count(cfg.channel) || cfg.channel < 0 ||
-            cfg.channel >= mChannelCount || cfg.band < 0 || cfg.band >= bandCount ||
-            !isCutoffFrequencyValid(cfg.cutoffFrequencyHz, cap) ||
-            0 != bandSet.count({cfg.channel, cfg.band})) {
-            return false;
-        }
-        bandSet.insert({cfg.channel, cfg.band});
-    }
-    return true;
-}
-
-bool DynamicsProcessingTestHelper::isMbcBandConfigValid(
-        const DynamicsProcessing::Capability& cap,
-        const std::vector<DynamicsProcessing::MbcBandConfig>& cfgs, bool stageInUse,
-        int bandCount) {
-    std::set<std::pair<int /* channelID */, int /* bandID */>> bandSet;
-    if (!stageInUse) return false;
-    for (auto cfg : cfgs) {
-        if (0 == mMbcChannelEnable.count(cfg.channel) || cfg.channel < 0 ||
-            cfg.channel >= mChannelCount || cfg.band < 0 || cfg.band >= bandCount ||
-            (cfg.attackTimeMs < 0) || cfg.releaseTimeMs < 0 || cfg.ratio < 0 ||
-            cfg.thresholdDb > 0 || cfg.kneeWidthDb < 0 || cfg.noiseGateThresholdDb > 0 ||
-            cfg.expanderRatio < 0 || !isCutoffFrequencyValid(cfg.cutoffFrequencyHz, cap) ||
-            0 != bandSet.count({cfg.channel, cfg.band})) {
-            return false;
-        }
-        bandSet.insert({cfg.channel, cfg.band});
-    }
-    return true;
-}
-
-bool DynamicsProcessingTestHelper::isLimiterConfigValid(
-        const std::vector<DynamicsProcessing::LimiterConfig>& cfgs, bool stageInUse) {
-    std::set<int> channelSet;
-    if (!stageInUse) return false;
-    for (auto cfg : cfgs) {
-        if (0 == mLimiterChannelEnable.count(cfg.channel) || cfg.channel < 0 ||
-            cfg.channel >= mChannelCount || cfg.attackTimeMs < 0 || cfg.releaseTimeMs < 0 ||
-            cfg.ratio < 0 || cfg.thresholdDb > 0 || 0 != channelSet.count(cfg.channel)) {
-            return false;
-        }
-        channelSet.insert(cfg.channel);
-    }
-    return true;
-}
-
-bool DynamicsProcessingTestHelper::isInputGainValid(
-        const std::vector<DynamicsProcessing::InputGain>& cfgs) {
-    std::set<int> channelSet;
-    for (auto cfg : cfgs) {
-        if (cfg.channel < 0 || cfg.channel >= mChannelCount || 0 != channelSet.count(cfg.channel)) {
-            return false;
-        }
-        channelSet.insert(cfg.channel);
-    }
-    return true;
-}
-
 bool DynamicsProcessingTestHelper::isEngineConfigEqual(
         const DynamicsProcessing::EngineArchitecture& ref,
         const DynamicsProcessing::EngineArchitecture& test) {
@@ -455,7 +342,8 @@
         // validate parameter
         Descriptor desc;
         ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
-        const bool valid = isParamValid(tag, dp, desc);
+        bool valid = isParamInRange(dp, desc.capability.range.get<Range::dynamicsProcessing>());
+        if (valid) valid = isParamValid(tag, dp);
         const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
 
         // set parameter
@@ -463,7 +351,10 @@
         Parameter::Specific specific;
         specific.set<Parameter::Specific::dynamicsProcessing>(dp);
         expectParam.set<Parameter::specific>(specific);
-        ASSERT_STATUS(expected, mEffect->setParameter(expectParam)) << expectParam.toString();
+        ASSERT_STATUS(expected, mEffect->setParameter(expectParam))
+                << "\n"
+                << expectParam.toString() << "\n"
+                << desc.toString();
 
         // only get if parameter in range and set success
         if (expected == EX_NONE) {
@@ -609,11 +500,12 @@
         DynamicsProcessingTest, DynamicsProcessingTestEngineArchitecture,
         ::testing::Combine(
                 testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
-                        IFactory::descriptor, kDynamicsProcessingTypeUUID)),
-                testing::Values(DynamicsProcessing::ResolutionPreference::FAVOR_TIME_RESOLUTION,
-                                DynamicsProcessing::ResolutionPreference::
-                                        FAVOR_FREQUENCY_RESOLUTION),  // variant
-                testing::Values(-10.f, 0.f, 10.f),                    // processing duration
+                        IFactory::descriptor, getEffectTypeUuidDynamicsProcessing())),
+                testing::Values(
+                        DynamicsProcessing::ResolutionPreference::FAVOR_TIME_RESOLUTION,
+                        DynamicsProcessing::ResolutionPreference::FAVOR_FREQUENCY_RESOLUTION,
+                        static_cast<DynamicsProcessing::ResolutionPreference>(-1)),  // variant
+                testing::Values(-10.f, 0.f, 10.f),  // processing duration
                 testing::ValuesIn(
                         DynamicsProcessingTestHelper::kStageEnablementTestSet),  // preEQ/postEQ/mbc
                 testing::Bool()),                                                // limiter enable
@@ -661,7 +553,7 @@
 INSTANTIATE_TEST_SUITE_P(
         DynamicsProcessingTest, DynamicsProcessingTestInputGain,
         ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
-                                   IFactory::descriptor, kDynamicsProcessingTypeUUID)),
+                                   IFactory::descriptor, getEffectTypeUuidDynamicsProcessing())),
                            testing::ValuesIn(DynamicsProcessingTestInputGain::kInputGainTestSet)),
         [](const auto& info) {
             auto descriptor = std::get<INPUT_GAIN_INSTANCE_NAME>(info.param).second;
@@ -696,12 +588,12 @@
     LIMITER_MAX_NUM,
 };
 using LimiterConfigTestAdditional = std::array<float, LIMITER_MAX_NUM>;
-// attachTime, releaseTime, ratio, thresh, postGain
+// attackTime, releaseTime, ratio, thresh, postGain
 static constexpr std::array<LimiterConfigTestAdditional, 4> kLimiterConfigTestAdditionalParam = {
         {{-1, -60, -2.5, -2, -3.14},
          {-1, 60, -2.5, 2, -3.14},
          {1, -60, 2.5, -2, 3.14},
-         {1, 60, 2.5, 2, 3.14}}};
+         {1, 60, 2.5, -2, 3.14}}};
 
 using LimiterConfigTestParams =
         std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int32_t, bool, int32_t, bool,
@@ -748,7 +640,7 @@
 INSTANTIATE_TEST_SUITE_P(
         DynamicsProcessingTest, DynamicsProcessingTestLimiterConfig,
         ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
-                                   IFactory::descriptor, kDynamicsProcessingTypeUUID)),
+                                   IFactory::descriptor, getEffectTypeUuidDynamicsProcessing())),
                            testing::Values(-1, 0, 1, 2),  // channel count
                            testing::Bool(),               // enable
                            testing::Values(3),            // link group
@@ -823,7 +715,7 @@
         DynamicsProcessingTest, DynamicsProcessingTestChannelConfig,
         ::testing::Combine(
                 testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
-                        IFactory::descriptor, kDynamicsProcessingTypeUUID)),
+                        IFactory::descriptor, getEffectTypeUuidDynamicsProcessing())),
                 testing::ValuesIn(
                         DynamicsProcessingTestHelper::kChannelConfigTestSet),  // channel config
                 testing::Bool()),                                              // Engine inUse
@@ -850,15 +742,13 @@
 enum EqBandConfigTestParamName {
     EQ_BAND_INSTANCE_NAME,
     EQ_BAND_CHANNEL,
-    EQ_BAND_CHANNEL_ENABLE,
     EQ_BAND_ENABLE,
     EQ_BAND_CUT_OFF_FREQ,
     EQ_BAND_GAIN,
     EQ_BAND_STAGE_IN_USE
 };
 using EqBandConfigTestParams = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int32_t,
-                                          std::vector<DynamicsProcessing::ChannelConfig>, bool,
-                                          std::vector<std::pair<int, float>>, float, bool>;
+                                          bool, std::vector<std::pair<int, float>>, float, bool>;
 
 void fillEqBandConfig(std::vector<DynamicsProcessing::EqBandConfig>& cfgs,
                       const EqBandConfigTestParams& params) {
@@ -879,8 +769,7 @@
   public:
     DynamicsProcessingTestEqBandConfig()
         : DynamicsProcessingTestHelper(std::get<EQ_BAND_INSTANCE_NAME>(GetParam())),
-          mStageInUse(std::get<EQ_BAND_STAGE_IN_USE>(GetParam())),
-          mChannelConfig(std::get<EQ_BAND_CHANNEL_ENABLE>(GetParam())) {
+          mStageInUse(std::get<EQ_BAND_STAGE_IN_USE>(GetParam())) {
         fillEqBandConfig(mCfgs, GetParam());
     }
 
@@ -890,14 +779,18 @@
 
     std::vector<DynamicsProcessing::EqBandConfig> mCfgs;
     const bool mStageInUse;
-    const std::vector<DynamicsProcessing::ChannelConfig> mChannelConfig;
 };
 
 TEST_P(DynamicsProcessingTestEqBandConfig, SetAndGetPreEqBandConfig) {
     mEngineConfigPreset.preEqStage.inUse = mStageInUse;
     mEngineConfigPreset.preEqStage.bandCount = mCfgs.size();
     EXPECT_NO_FATAL_FAILURE(addEngineConfig(mEngineConfigPreset));
-    EXPECT_NO_FATAL_FAILURE(addPreEqChannelConfig(mChannelConfig));
+    std::vector<DynamicsProcessing::ChannelConfig> cfgs(mChannelCount);
+    for (int i = 0; i < mChannelCount; i++) {
+        cfgs[i].channel = i;
+        cfgs[i].enable = true;
+    }
+    EXPECT_NO_FATAL_FAILURE(addPreEqChannelConfig(cfgs));
     EXPECT_NO_FATAL_FAILURE(addPreEqBandConfigs(mCfgs));
     SetAndGetDynamicsProcessingParameters();
 }
@@ -906,7 +799,12 @@
     mEngineConfigPreset.postEqStage.inUse = mStageInUse;
     mEngineConfigPreset.postEqStage.bandCount = mCfgs.size();
     EXPECT_NO_FATAL_FAILURE(addEngineConfig(mEngineConfigPreset));
-    EXPECT_NO_FATAL_FAILURE(addPostEqChannelConfig(mChannelConfig));
+    std::vector<DynamicsProcessing::ChannelConfig> cfgs(mChannelCount);
+    for (int i = 0; i < mChannelCount; i++) {
+        cfgs[i].channel = i;
+        cfgs[i].enable = true;
+    }
+    EXPECT_NO_FATAL_FAILURE(addPostEqChannelConfig(cfgs));
     EXPECT_NO_FATAL_FAILURE(addPostEqBandConfigs(mCfgs));
     SetAndGetDynamicsProcessingParameters();
 }
@@ -957,28 +855,23 @@
 
 INSTANTIATE_TEST_SUITE_P(
         DynamicsProcessingTest, DynamicsProcessingTestEqBandConfig,
-        ::testing::Combine(
-                testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
-                        IFactory::descriptor, kDynamicsProcessingTypeUUID)),
-                testing::Values(-1, 0, 10),  // channel ID
-                testing::ValuesIn(
-                        DynamicsProcessingTestHelper::kChannelConfigTestSet),  // channel enable
-                testing::Bool(),                                               // band enable
-                testing::ValuesIn(kBands),       // cut off frequencies
-                testing::Values(-3.14f, 3.14f),  // gain
-                testing::Bool()),                // stage in use
+        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+                                   IFactory::descriptor, getEffectTypeUuidDynamicsProcessing())),
+                           testing::Values(-1, 0, 10),      // channel ID
+                           testing::Bool(),                 // band enable
+                           testing::ValuesIn(kBands),       // cut off frequencies
+                           testing::Values(-3.14f, 3.14f),  // gain
+                           testing::Values(true)),          // stage in use
         [](const auto& info) {
             auto descriptor = std::get<EQ_BAND_INSTANCE_NAME>(info.param).second;
             std::vector<DynamicsProcessing::EqBandConfig> cfgs;
             fillEqBandConfig(cfgs, info.param);
-            std::string enable =
-                    ::android::internal::ToString(std::get<EQ_BAND_CHANNEL_ENABLE>(info.param));
             std::string bands = ::android::internal::ToString(cfgs);
             std::string stageInUse = std::to_string(std::get<EQ_BAND_STAGE_IN_USE>(info.param));
             std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
                                descriptor.common.name + "_UUID_" +
-                               descriptor.common.id.uuid.toString() + "_" + enable + "_bands_" +
-                               bands + "_stageInUse_" + stageInUse;
+                               descriptor.common.id.uuid.toString() + "_bands_" + bands +
+                               "_stageInUse_" + stageInUse;
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
@@ -992,7 +885,6 @@
 enum MbcBandConfigParamName {
     MBC_BAND_INSTANCE_NAME,
     MBC_BAND_CHANNEL,
-    MBC_BAND_CHANNEL_CONFIG,
     MBC_BAND_ENABLE,
     MBC_BAND_CUTOFF_FREQ,
     MBC_BAND_STAGE_IN_USE,
@@ -1012,16 +904,15 @@
 };
 using TestParamsMbcBandConfigAdditional = std::array<float, MBC_ADD_MAX_NUM>;
 
-// attachTime, releaseTime, ratio, thresh, kneeWidth, noise, expander, preGain, postGain
+// attackTime, releaseTime, ratio, thresh, kneeWidth, noise, expander, preGain, postGain
 static constexpr std::array<TestParamsMbcBandConfigAdditional, 4> kMbcBandConfigAdditionalParam = {
         {{-3, -10, -2, -2, -5, -90, -2.5, -2, -2},
          {0, 0, 0, 0, 0, 0, 0, 0, 0},
          {-3, 10, -2, 2, -5, 90, -2.5, 2, -2},
-         {3, 10, 2, 2, 5, 90, 2.5, 2, 2}}};
+         {3, 10, 2, -2, -5, 90, 2.5, 2, 2}}};
 
 using TestParamsMbcBandConfig =
-        std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int32_t,
-                   std::vector<DynamicsProcessing::ChannelConfig>, bool,
+        std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int32_t, bool,
                    std::vector<std::pair<int, float>>, bool, TestParamsMbcBandConfigAdditional>;
 
 void fillMbcBandConfig(std::vector<DynamicsProcessing::MbcBandConfig>& cfgs,
@@ -1054,8 +945,7 @@
   public:
     DynamicsProcessingTestMbcBandConfig()
         : DynamicsProcessingTestHelper(std::get<MBC_BAND_INSTANCE_NAME>(GetParam())),
-          mStageInUse(std::get<MBC_BAND_STAGE_IN_USE>(GetParam())),
-          mChannelConfig(std::get<MBC_BAND_CHANNEL_CONFIG>(GetParam())) {
+          mStageInUse(std::get<MBC_BAND_STAGE_IN_USE>(GetParam())) {
         fillMbcBandConfig(mCfgs, GetParam());
     }
 
@@ -1065,42 +955,41 @@
 
     std::vector<DynamicsProcessing::MbcBandConfig> mCfgs;
     const bool mStageInUse;
-    const std::vector<DynamicsProcessing::ChannelConfig> mChannelConfig;
 };
 
 TEST_P(DynamicsProcessingTestMbcBandConfig, SetAndGetMbcBandConfig) {
     mEngineConfigPreset.mbcStage.inUse = mStageInUse;
     mEngineConfigPreset.mbcStage.bandCount = mCfgs.size();
     EXPECT_NO_FATAL_FAILURE(addEngineConfig(mEngineConfigPreset));
-    EXPECT_NO_FATAL_FAILURE(addMbcChannelConfig(mChannelConfig));
+    std::vector<DynamicsProcessing::ChannelConfig> cfgs(mChannelCount);
+    for (int i = 0; i < mChannelCount; i++) {
+        cfgs[i].channel = i;
+        cfgs[i].enable = true;
+    }
+    EXPECT_NO_FATAL_FAILURE(addMbcChannelConfig(cfgs));
     EXPECT_NO_FATAL_FAILURE(addMbcBandConfigs(mCfgs));
     SetAndGetDynamicsProcessingParameters();
 }
 
 INSTANTIATE_TEST_SUITE_P(
         DynamicsProcessingTest, DynamicsProcessingTestMbcBandConfig,
-        ::testing::Combine(
-                testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
-                        IFactory::descriptor, kDynamicsProcessingTypeUUID)),
-                testing::Values(-1, 0, 10),  // channel count
-                testing::ValuesIn(
-                        DynamicsProcessingTestHelper::kChannelConfigTestSet),  // channel config
-                testing::Bool(),                                               // enable
-                testing::ValuesIn(kBands),                          // cut off frequencies
-                testing::Bool(),                                    // stage in use
-                testing::ValuesIn(kMbcBandConfigAdditionalParam)),  // Additional
+        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+                                   IFactory::descriptor, getEffectTypeUuidDynamicsProcessing())),
+                           testing::Values(-1, 0, 10),  // channel count
+                           testing::Bool(),             // enable
+                           testing::ValuesIn(kBands),   // cut off frequencies
+                           testing::Bool(),             // stage in use
+                           testing::ValuesIn(kMbcBandConfigAdditionalParam)),  // Additional
         [](const auto& info) {
             auto descriptor = std::get<MBC_BAND_INSTANCE_NAME>(info.param).second;
             std::vector<DynamicsProcessing::MbcBandConfig> cfgs;
             fillMbcBandConfig(cfgs, info.param);
-            std::string enable =
-                    ::android::internal::ToString(std::get<MBC_BAND_CHANNEL_CONFIG>(info.param));
             std::string mbcBands = ::android::internal::ToString(cfgs);
             std::string stageInUse = std::to_string(std::get<MBC_BAND_STAGE_IN_USE>(info.param));
             std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
                                descriptor.common.name + "_UUID_" +
-                               descriptor.common.id.uuid.toString() + "_enable_" + enable +
-                               "_bands_" + mbcBands + "_stageInUse_" + stageInUse;
+                               descriptor.common.id.uuid.toString() + "_bands_" + mbcBands +
+                               "_stageInUse_" + stageInUse;
             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 82c8757..05c2c5b 100644
--- a/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp
@@ -14,21 +14,19 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "VtsHalEnvironmentalReverbTest"
-
-#include <Utils.h>
 #include <aidl/Vintf.h>
-#include <unordered_set>
+#define LOG_TAG "VtsHalEnvironmentalReverbTest"
+#include <android-base/logging.h>
+
 #include "EffectHelper.h"
 
 using namespace android;
 
-using aidl::android::hardware::audio::effect::Capability;
 using aidl::android::hardware::audio::effect::Descriptor;
 using aidl::android::hardware::audio::effect::EnvironmentalReverb;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidEnvReverb;
 using aidl::android::hardware::audio::effect::IEffect;
 using aidl::android::hardware::audio::effect::IFactory;
-using aidl::android::hardware::audio::effect::kEnvReverbTypeUUID;
 using aidl::android::hardware::audio::effect::Parameter;
 
 /**
@@ -93,7 +91,8 @@
             // validate parameter
             Descriptor desc;
             ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
-            const bool valid = isTagInRange(it.first, it.second, desc);
+            const bool valid = isParameterValid<EnvironmentalReverb, Range::environmentalReverb>(
+                    it.second, desc);
             const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
 
             // set
@@ -171,239 +170,6 @@
         mTags.push_back({EnvironmentalReverb::bypass, er});
     }
 
-    bool isTagInRange(const EnvironmentalReverb::Tag& tag, const EnvironmentalReverb er,
-                      const Descriptor& desc) const {
-        const EnvironmentalReverb::Capability& erCap =
-                desc.capability.get<Capability::environmentalReverb>();
-        switch (tag) {
-            case EnvironmentalReverb::roomLevelMb: {
-                int roomLevel = er.get<EnvironmentalReverb::roomLevelMb>();
-                return isRoomLevelInRange(erCap, roomLevel);
-            }
-            case EnvironmentalReverb::roomHfLevelMb: {
-                int roomHfLevel = er.get<EnvironmentalReverb::roomHfLevelMb>();
-                return isRoomHfLevelInRange(erCap, roomHfLevel);
-            }
-            case EnvironmentalReverb::decayTimeMs: {
-                int decayTime = er.get<EnvironmentalReverb::decayTimeMs>();
-                return isDecayTimeInRange(erCap, decayTime);
-            }
-            case EnvironmentalReverb::decayHfRatioPm: {
-                int decayHfRatio = er.get<EnvironmentalReverb::decayHfRatioPm>();
-                return isDecayHfRatioInRange(erCap, decayHfRatio);
-            }
-            case EnvironmentalReverb::levelMb: {
-                int level = er.get<EnvironmentalReverb::levelMb>();
-                return isLevelInRange(erCap, level);
-            }
-            case EnvironmentalReverb::delayMs: {
-                int delay = er.get<EnvironmentalReverb::delayMs>();
-                return isDelayInRange(erCap, delay);
-            }
-            case EnvironmentalReverb::diffusionPm: {
-                int diffusion = er.get<EnvironmentalReverb::diffusionPm>();
-                return isDiffusionInRange(erCap, diffusion);
-            }
-            case EnvironmentalReverb::densityPm: {
-                int density = er.get<EnvironmentalReverb::densityPm>();
-                return isDensityInRange(erCap, density);
-            }
-            case EnvironmentalReverb::bypass: {
-                return true;
-            }
-            default:
-                return false;
-        }
-        return false;
-    }
-
-    bool isRoomLevelInRange(const EnvironmentalReverb::Capability& cap, int roomLevel) const {
-        return roomLevel >= cap.minRoomLevelMb && roomLevel <= cap.maxRoomLevelMb;
-    }
-
-    bool isRoomHfLevelInRange(const EnvironmentalReverb::Capability& cap, int roomHfLevel) const {
-        return roomHfLevel >= cap.minRoomHfLevelMb && roomHfLevel <= cap.maxRoomHfLevelMb;
-    }
-
-    bool isDecayTimeInRange(const EnvironmentalReverb::Capability& cap, int decayTime) const {
-        return decayTime >= 0 && decayTime <= cap.maxDecayTimeMs;
-    }
-
-    bool isDecayHfRatioInRange(const EnvironmentalReverb::Capability& cap, int decayHfRatio) const {
-        return decayHfRatio >= cap.minDecayHfRatioPm && decayHfRatio <= cap.maxDecayHfRatioPm;
-    }
-
-    bool isLevelInRange(const EnvironmentalReverb::Capability& cap, int level) const {
-        return level >= cap.minLevelMb && level <= cap.maxLevelMb;
-    }
-
-    bool isDelayInRange(const EnvironmentalReverb::Capability& cap, int delay) const {
-        return delay >= 0 && delay <= cap.maxDelayMs;
-    }
-
-    bool isDiffusionInRange(const EnvironmentalReverb::Capability& cap, int diffusion) const {
-        return diffusion >= 0 && diffusion <= cap.maxDiffusionPm;
-    }
-
-    bool isDensityInRange(const EnvironmentalReverb::Capability& cap, int density) const {
-        return density >= 0 && density <= cap.maxDensityPm;
-    }
-
-    static std::unordered_set<int> getRoomLevelValues() {
-        auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
-                                                                     kEnvReverbTypeUUID);
-        int minRoomLevelMb = std::numeric_limits<int>::max();
-        int maxRoomLevelMb = std::numeric_limits<int>::min();
-        for (const auto& it : descList) {
-            maxRoomLevelMb = std::max(
-                    it.second.capability.get<Capability::environmentalReverb>().maxRoomLevelMb,
-                    maxRoomLevelMb);
-            minRoomLevelMb = std::min(
-                    it.second.capability.get<Capability::environmentalReverb>().minRoomLevelMb,
-                    minRoomLevelMb);
-        }
-        return {std::numeric_limits<int>::min(),        minRoomLevelMb - 1, minRoomLevelMb,
-                (minRoomLevelMb + maxRoomLevelMb) >> 1, maxRoomLevelMb,     maxRoomLevelMb + 1,
-                std::numeric_limits<int>::max()};
-    }
-
-    static std::unordered_set<int> getRoomHfLevelValues() {
-        auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
-                                                                     kEnvReverbTypeUUID);
-        int minRoomHfLevelMb = std::numeric_limits<int>::max();
-        int maxRoomHfLevelMb = std::numeric_limits<int>::min();
-        for (const auto& it : descList) {
-            maxRoomHfLevelMb = std::max(
-                    it.second.capability.get<Capability::environmentalReverb>().maxRoomHfLevelMb,
-                    maxRoomHfLevelMb);
-            minRoomHfLevelMb = std::min(
-                    it.second.capability.get<Capability::environmentalReverb>().minRoomHfLevelMb,
-                    minRoomHfLevelMb);
-        }
-        return {std::numeric_limits<int>::min(),
-                minRoomHfLevelMb - 1,
-                minRoomHfLevelMb,
-                (minRoomHfLevelMb + maxRoomHfLevelMb) >> 1,
-                maxRoomHfLevelMb,
-                maxRoomHfLevelMb + 1,
-                std::numeric_limits<int>::max()};
-    }
-
-    static std::unordered_set<int> getDecayTimeValues() {
-        auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
-                                                                     kEnvReverbTypeUUID);
-        const auto max = std::max_element(
-                descList.begin(), descList.end(),
-                [](const std::pair<std::shared_ptr<IFactory>, Descriptor>& a,
-                   const std::pair<std::shared_ptr<IFactory>, Descriptor>& b) {
-                    return a.second.capability.get<Capability::environmentalReverb>()
-                                   .maxDecayTimeMs <
-                           b.second.capability.get<Capability::environmentalReverb>()
-                                   .maxDecayTimeMs;
-                });
-        if (max == descList.end()) {
-            return {0};
-        }
-        int maxDecayTimeMs =
-                max->second.capability.get<Capability::environmentalReverb>().maxDecayTimeMs;
-        return {-1, 0, maxDecayTimeMs >> 1, maxDecayTimeMs - 1, maxDecayTimeMs, maxDecayTimeMs + 1};
-    }
-
-    static std::unordered_set<int> getDecayHfRatioValues() {
-        auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
-                                                                     kEnvReverbTypeUUID);
-        int minDecayHfRatioPm = std::numeric_limits<int>::max();
-        int maxDecayHfRatioPm = std::numeric_limits<int>::min();
-        for (const auto& it : descList) {
-            maxDecayHfRatioPm = std::max(
-                    it.second.capability.get<Capability::environmentalReverb>().maxDecayHfRatioPm,
-                    maxDecayHfRatioPm);
-            minDecayHfRatioPm = std::min(
-                    it.second.capability.get<Capability::environmentalReverb>().minDecayHfRatioPm,
-                    minDecayHfRatioPm);
-        }
-        return {std::numeric_limits<int>::min(),
-                minDecayHfRatioPm - 1,
-                minDecayHfRatioPm,
-                (minDecayHfRatioPm + maxDecayHfRatioPm) >> 1,
-                maxDecayHfRatioPm,
-                maxDecayHfRatioPm + 1,
-                std::numeric_limits<int>::max()};
-    }
-
-    static std::unordered_set<int> getLevelValues() {
-        auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
-                                                                     kEnvReverbTypeUUID);
-        int minLevelMb = std::numeric_limits<int>::max();
-        int maxLevelMb = std::numeric_limits<int>::min();
-        for (const auto& it : descList) {
-            maxLevelMb =
-                    std::max(it.second.capability.get<Capability::environmentalReverb>().maxLevelMb,
-                             maxLevelMb);
-            minLevelMb =
-                    std::min(it.second.capability.get<Capability::environmentalReverb>().minLevelMb,
-                             minLevelMb);
-        }
-        return {std::numeric_limits<int>::min(), minLevelMb - 1, minLevelMb,
-                (minLevelMb + maxLevelMb) >> 1,  maxLevelMb,     maxLevelMb + 1,
-                std::numeric_limits<int>::max()};
-    }
-
-    static std::unordered_set<int> getDelayValues() {
-        auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
-                                                                     kEnvReverbTypeUUID);
-        const auto max = std::max_element(
-                descList.begin(), descList.end(),
-                [](const std::pair<std::shared_ptr<IFactory>, Descriptor>& a,
-                   const std::pair<std::shared_ptr<IFactory>, Descriptor>& b) {
-                    return a.second.capability.get<Capability::environmentalReverb>().maxDelayMs <
-                           b.second.capability.get<Capability::environmentalReverb>().maxDelayMs;
-                });
-        if (max == descList.end()) {
-            return {0};
-        }
-        int maxDelayMs = max->second.capability.get<Capability::environmentalReverb>().maxDelayMs;
-        return {-1, 0, maxDelayMs >> 1, maxDelayMs - 1, maxDelayMs, maxDelayMs + 1};
-    }
-
-    static std::unordered_set<int> getDiffusionValues() {
-        auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
-                                                                     kEnvReverbTypeUUID);
-        const auto max = std::max_element(
-                descList.begin(), descList.end(),
-                [](const std::pair<std::shared_ptr<IFactory>, Descriptor>& a,
-                   const std::pair<std::shared_ptr<IFactory>, Descriptor>& b) {
-                    return a.second.capability.get<Capability::environmentalReverb>()
-                                   .maxDiffusionPm <
-                           b.second.capability.get<Capability::environmentalReverb>()
-                                   .maxDiffusionPm;
-                });
-        if (max == descList.end()) {
-            return {0};
-        }
-        int maxDiffusionPm =
-                max->second.capability.get<Capability::environmentalReverb>().maxDiffusionPm;
-        return {-1, 0, maxDiffusionPm >> 1, maxDiffusionPm - 1, maxDiffusionPm, maxDiffusionPm + 1};
-    }
-
-    static std::unordered_set<int> getDensityValues() {
-        auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
-                                                                     kEnvReverbTypeUUID);
-        const auto max = std::max_element(
-                descList.begin(), descList.end(),
-                [](const std::pair<std::shared_ptr<IFactory>, Descriptor>& a,
-                   const std::pair<std::shared_ptr<IFactory>, Descriptor>& b) {
-                    return a.second.capability.get<Capability::environmentalReverb>().maxDensityPm <
-                           b.second.capability.get<Capability::environmentalReverb>().maxDensityPm;
-                });
-        if (max == descList.end()) {
-            return {0};
-        }
-        int maxDensityPm =
-                max->second.capability.get<Capability::environmentalReverb>().maxDensityPm;
-        return {-1, 0, maxDensityPm >> 1, maxDensityPm - 1, maxDensityPm, maxDensityPm + 1};
-    }
-
   private:
     std::vector<std::pair<EnvironmentalReverb::Tag, EnvironmentalReverb>> mTags;
     void CleanUp() { mTags.clear(); }
@@ -428,11 +194,17 @@
     SetAndGetReverbParameters();
 }
 
+std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kDescPair;
+
 INSTANTIATE_TEST_SUITE_P(
         EnvironmentalReverbTest, EnvironmentalReverbRoomLevelTest,
-        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
-                                   IFactory::descriptor, kEnvReverbTypeUUID)),
-                           testing::ValuesIn(EnvironmentalReverbHelper::getRoomLevelValues())),
+        ::testing::Combine(
+                testing::ValuesIn(kDescPair = EffectFactoryHelper::getAllEffectDescriptors(
+                                          IFactory::descriptor, getEffectTypeUuidEnvReverb())),
+                testing::ValuesIn(EffectHelper::getTestValueSet<EnvironmentalReverb, int,
+                                                                Range::environmentalReverb,
+                                                                EnvironmentalReverb::roomLevelMb>(
+                        kDescPair, EffectHelper::expandTestValueBasic<int>))),
         [](const testing::TestParamInfo<EnvironmentalReverbRoomLevelTest::ParamType>& info) {
             auto descriptor = std::get<0>(info.param).second;
             std::string roomLevel = std::to_string(std::get<1>(info.param));
@@ -468,8 +240,11 @@
 INSTANTIATE_TEST_SUITE_P(
         EnvironmentalReverbTest, EnvironmentalReverbRoomHfLevelTest,
         ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
-                                   IFactory::descriptor, kEnvReverbTypeUUID)),
-                           testing::ValuesIn(EnvironmentalReverbHelper::getRoomHfLevelValues())),
+                                   IFactory::descriptor, getEffectTypeUuidEnvReverb())),
+                           testing::ValuesIn(EffectHelper::getTestValueSet<
+                                             EnvironmentalReverb, int, Range::environmentalReverb,
+                                             EnvironmentalReverb::roomHfLevelMb>(
+                                   kDescPair, EffectHelper::expandTestValueBasic<int>))),
         [](const testing::TestParamInfo<EnvironmentalReverbRoomHfLevelTest::ParamType>& info) {
             auto descriptor = std::get<0>(info.param).second;
             std::string roomHfLevel = std::to_string(std::get<1>(info.param));
@@ -505,8 +280,11 @@
 INSTANTIATE_TEST_SUITE_P(
         EnvironmentalReverbTest, EnvironmentalReverbDecayTimeTest,
         ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
-                                   IFactory::descriptor, kEnvReverbTypeUUID)),
-                           testing::ValuesIn(EnvironmentalReverbHelper::getDecayTimeValues())),
+                                   IFactory::descriptor, getEffectTypeUuidEnvReverb())),
+                           testing::ValuesIn(EffectHelper::getTestValueSet<
+                                             EnvironmentalReverb, int, Range::environmentalReverb,
+                                             EnvironmentalReverb::decayTimeMs>(
+                                   kDescPair, EffectHelper::expandTestValueBasic<int>))),
         [](const testing::TestParamInfo<EnvironmentalReverbDecayTimeTest::ParamType>& info) {
             auto descriptor = std::get<0>(info.param).second;
             std::string decayTime = std::to_string(std::get<1>(info.param));
@@ -542,8 +320,11 @@
 INSTANTIATE_TEST_SUITE_P(
         EnvironmentalReverbTest, EnvironmentalReverbDecayHfRatioTest,
         ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
-                                   IFactory::descriptor, kEnvReverbTypeUUID)),
-                           testing::ValuesIn(EnvironmentalReverbHelper::getDecayHfRatioValues())),
+                                   IFactory::descriptor, getEffectTypeUuidEnvReverb())),
+                           testing::ValuesIn(EffectHelper::getTestValueSet<
+                                             EnvironmentalReverb, int, Range::environmentalReverb,
+                                             EnvironmentalReverb::decayHfRatioPm>(
+                                   kDescPair, EffectHelper::expandTestValueBasic<int>))),
         [](const testing::TestParamInfo<EnvironmentalReverbDecayHfRatioTest::ParamType>& info) {
             auto descriptor = std::get<0>(info.param).second;
             std::string decayHfRatio = std::to_string(std::get<1>(info.param));
@@ -580,8 +361,11 @@
 INSTANTIATE_TEST_SUITE_P(
         EnvironmentalReverbTest, EnvironmentalReverbLevelTest,
         ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
-                                   IFactory::descriptor, kEnvReverbTypeUUID)),
-                           testing::ValuesIn(EnvironmentalReverbHelper::getLevelValues())),
+                                   IFactory::descriptor, getEffectTypeUuidEnvReverb())),
+                           testing::ValuesIn(EffectHelper::getTestValueSet<
+                                             EnvironmentalReverb, int, Range::environmentalReverb,
+                                             EnvironmentalReverb::levelMb>(
+                                   kDescPair, EffectHelper::expandTestValueBasic<int>))),
         [](const testing::TestParamInfo<EnvironmentalReverbDecayHfRatioTest::ParamType>& info) {
             auto descriptor = std::get<0>(info.param).second;
             std::string level = std::to_string(std::get<1>(info.param));
@@ -617,8 +401,11 @@
 INSTANTIATE_TEST_SUITE_P(
         EnvironmentalReverbTest, EnvironmentalReverbDelayTest,
         ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
-                                   IFactory::descriptor, kEnvReverbTypeUUID)),
-                           testing::ValuesIn(EnvironmentalReverbHelper::getDelayValues())),
+                                   IFactory::descriptor, getEffectTypeUuidEnvReverb())),
+                           testing::ValuesIn(EffectHelper::getTestValueSet<
+                                             EnvironmentalReverb, int, Range::environmentalReverb,
+                                             EnvironmentalReverb::delayMs>(
+                                   kDescPair, EffectHelper::expandTestValueBasic<int>))),
         [](const testing::TestParamInfo<EnvironmentalReverbDelayTest::ParamType>& info) {
             auto descriptor = std::get<0>(info.param).second;
             std::string delay = std::to_string(std::get<1>(info.param));
@@ -654,8 +441,11 @@
 INSTANTIATE_TEST_SUITE_P(
         EnvironmentalReverbTest, EnvironmentalReverbDiffusionTest,
         ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
-                                   IFactory::descriptor, kEnvReverbTypeUUID)),
-                           testing::ValuesIn(EnvironmentalReverbHelper::getDiffusionValues())),
+                                   IFactory::descriptor, getEffectTypeUuidEnvReverb())),
+                           testing::ValuesIn(EffectHelper::getTestValueSet<
+                                             EnvironmentalReverb, int, Range::environmentalReverb,
+                                             EnvironmentalReverb::diffusionPm>(
+                                   kDescPair, EffectHelper::expandTestValueBasic<int>))),
         [](const testing::TestParamInfo<EnvironmentalReverbDiffusionTest::ParamType>& info) {
             auto descriptor = std::get<0>(info.param).second;
             std::string diffusion = std::to_string(std::get<1>(info.param));
@@ -691,8 +481,11 @@
 INSTANTIATE_TEST_SUITE_P(
         EnvironmentalReverbTest, EnvironmentalReverbDensityTest,
         ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
-                                   IFactory::descriptor, kEnvReverbTypeUUID)),
-                           testing::ValuesIn(EnvironmentalReverbHelper::getDensityValues())),
+                                   IFactory::descriptor, getEffectTypeUuidEnvReverb())),
+                           testing::ValuesIn(EffectHelper::getTestValueSet<
+                                             EnvironmentalReverb, int, Range::environmentalReverb,
+                                             EnvironmentalReverb::densityPm>(
+                                   kDescPair, EffectHelper::expandTestValueBasic<int>))),
         [](const testing::TestParamInfo<EnvironmentalReverbDensityTest::ParamType>& info) {
             auto descriptor = std::get<0>(info.param).second;
             std::string density = std::to_string(std::get<1>(info.param));
@@ -728,7 +521,7 @@
 INSTANTIATE_TEST_SUITE_P(
         EnvironmentalReverbTest, EnvironmentalReverbBypassTest,
         ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
-                                   IFactory::descriptor, kEnvReverbTypeUUID)),
+                                   IFactory::descriptor, getEffectTypeUuidEnvReverb())),
                            testing::Bool()),
         [](const testing::TestParamInfo<EnvironmentalReverbBypassTest::ParamType>& info) {
             auto descriptor = std::get<0>(info.param).second;
diff --git a/audio/aidl/vts/VtsHalEqualizerTargetTest.cpp b/audio/aidl/vts/VtsHalEqualizerTargetTest.cpp
index e11a936..716a2c6 100644
--- a/audio/aidl/vts/VtsHalEqualizerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalEqualizerTargetTest.cpp
@@ -18,13 +18,15 @@
 #include <limits>
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
-#define LOG_TAG "VtsHalEqualizerTest"
-
 #include <aidl/Gtest.h>
 #include <aidl/Vintf.h>
+#include <aidl/android/hardware/audio/effect/IEffect.h>
+#include <aidl/android/hardware/audio/effect/IFactory.h>
+#define LOG_TAG "VtsHalEqualizerTest"
 #include <android-base/logging.h>
 #include <android-base/properties.h>
 #include <android/binder_interface_utils.h>
@@ -32,23 +34,17 @@
 #include <android/binder_process.h>
 #include <gtest/gtest.h>
 
-#include <Utils.h>
-#include <aidl/android/hardware/audio/effect/IEffect.h>
-#include <aidl/android/hardware/audio/effect/IFactory.h>
-
 #include "AudioHalBinderServiceUtil.h"
 #include "EffectHelper.h"
 #include "TestUtils.h"
-#include "effect-impl/EffectUUID.h"
 
 using namespace android;
 
-using aidl::android::hardware::audio::effect::Capability;
 using aidl::android::hardware::audio::effect::Descriptor;
 using aidl::android::hardware::audio::effect::Equalizer;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidEqualizer;
 using aidl::android::hardware::audio::effect::IEffect;
 using aidl::android::hardware::audio::effect::IFactory;
-using aidl::android::hardware::audio::effect::kEqualizerTypeUUID;
 using aidl::android::hardware::audio::effect::Parameter;
 
 /**
@@ -56,8 +52,9 @@
  * testing performed in VtsAudioEfectTargetTest.
  */
 
-enum ParamName { PARAM_INSTANCE_NAME, PARAM_BAND_LEVEL };
-using EqualizerParamTestParam = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int>;
+enum ParamName { PARAM_INSTANCE_NAME, PARAM_PRESET, PARAM_BAND_LEVEL };
+using EqualizerParamTestParam = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int,
+                                           std::vector<Equalizer::BandLevel>>;
 
 /*
 Testing parameter range, assuming the parameter supported by effect is in this range.
@@ -69,7 +66,9 @@
 class EqualizerTest : public ::testing::TestWithParam<EqualizerParamTestParam>,
                       public EffectHelper {
   public:
-    EqualizerTest() : mBandLevel(std::get<PARAM_BAND_LEVEL>(GetParam())) {
+    EqualizerTest()
+        : mPresetIndex(std::get<PARAM_PRESET>(GetParam())),
+          mBandLevel(std::get<PARAM_BAND_LEVEL>(GetParam())) {
         std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
     }
 
@@ -77,48 +76,24 @@
         ASSERT_NE(nullptr, mFactory);
         ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
 
-        Parameter::Specific specific = getDefaultParamSpecific();
         Parameter::Common common = EffectHelper::createParamCommon(
                 0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
                 kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
         IEffect::OpenEffectReturn ret;
-        ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &ret, EX_NONE));
+        ASSERT_NO_FATAL_FAILURE(open(mEffect, common, std::nullopt, &ret, EX_NONE));
         ASSERT_NE(nullptr, mEffect);
-        ASSERT_NO_FATAL_FAILURE(setTagRange());
     }
     void TearDown() override {
         ASSERT_NO_FATAL_FAILURE(close(mEffect));
         ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
     }
 
-    std::pair<int, int> setPresetIndexRange(const Equalizer::Capability& cap) const {
-        const auto [min, max] =
-                std::minmax_element(cap.presets.begin(), cap.presets.end(),
-                                    [](const auto& a, const auto& b) { return a.index < b.index; });
-        return {min->index, max->index};
-    }
-    std::pair<int, int> setBandIndexRange(const Equalizer::Capability& cap) const {
-        const auto [min, max] =
-                std::minmax_element(cap.bandFrequencies.begin(), cap.bandFrequencies.end(),
-                                    [](const auto& a, const auto& b) { return a.index < b.index; });
-        return {min->index, max->index};
-    }
-    void setTagRange() {
-        Descriptor desc;
-        ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
-        Equalizer::Capability& eqCap = desc.capability.get<Capability::equalizer>();
-        mPresetIndex = setPresetIndexRange(eqCap);
-        mBandIndex = setBandIndexRange(eqCap);
-    }
-
     static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
     std::shared_ptr<IFactory> mFactory;
     std::shared_ptr<IEffect> mEffect;
     Descriptor mDescriptor;
-    std::pair<int, int> mPresetIndex;
-    std::pair<int, int> mBandIndex;
-    const int mBandLevel;
-    Descriptor mDesc;
+    int mPresetIndex;
+    std::vector<Equalizer::BandLevel> mBandLevel;
 
     void SetAndGetEqualizerParameters() {
         ASSERT_NE(nullptr, mEffect);
@@ -127,25 +102,22 @@
             auto& eq = it.second;
 
             // validate parameter
-            const bool valid = isTagInRange(it.first, it.second);
+            const bool valid = isParameterValid<Equalizer, Range::equalizer>(eq, mDescriptor);
             const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
 
             // set
-            Parameter expectParam;
-            Parameter::Specific specific;
-            specific.set<Parameter::Specific::equalizer>(eq);
-            expectParam.set<Parameter::specific>(specific);
+            Parameter::Specific specific =
+                    Parameter::Specific::make<Parameter::Specific::equalizer>(eq);
+            Parameter expectParam = Parameter::make<Parameter::specific>(specific);
             EXPECT_STATUS(expected, mEffect->setParameter(expectParam))
                     << expectParam.toString() << "\n"
-                    << mDesc.toString();
+                    << mDescriptor.toString();
 
             // only get if parameter in range and set success
             if (expected == EX_NONE) {
                 Parameter getParam;
-                Parameter::Id id;
-                Equalizer::Id eqId;
-                eqId.set<Equalizer::Id::commonTag>(tag);
-                id.set<Parameter::Id::equalizerTag>(eqId);
+                Equalizer::Id eqId = Equalizer::Id::make<Equalizer::Id::commonTag>(tag);
+                Parameter::Id id = Parameter::Id::make<Parameter::Id::equalizerTag>(eqId);
                 // if set success, then get should match
                 EXPECT_STATUS(expected, mEffect->getParameter(id, &getParam));
                 EXPECT_TRUE(isEqParameterExpected(expectParam, getParam))
@@ -197,140 +169,51 @@
     }
 
     void addPresetParam(int preset) {
-        Equalizer eq;
-        eq.set<Equalizer::preset>(preset);
-        mTags.push_back({Equalizer::preset, eq});
+        mTags.push_back({Equalizer::preset, Equalizer::make<Equalizer::preset>(preset)});
     }
 
     void addBandLevelsParam(std::vector<Equalizer::BandLevel>& bandLevels) {
-        Equalizer eq;
-        eq.set<Equalizer::bandLevels>(bandLevels);
-        mTags.push_back({Equalizer::bandLevels, eq});
-    }
-
-    bool isTagInRange(const Equalizer::Tag& tag, const Equalizer& eq) const {
-        switch (tag) {
-            case Equalizer::preset: {
-                int index = eq.get<Equalizer::preset>();
-                return index >= mPresetIndex.first && index <= mPresetIndex.second;
-            }
-            case Equalizer::bandLevels: {
-                auto& bandLevel = eq.get<Equalizer::bandLevels>();
-                return isBandInRange(bandLevel);
-            }
-            default:
-                return false;
-        }
-        return false;
-    }
-
-    bool isBandInRange(const std::vector<Equalizer::BandLevel>& bandLevel) const {
-        for (auto& it : bandLevel) {
-            if (it.index < mBandIndex.first || it.index > mBandIndex.second) return false;
-        }
-        return true;
-    }
-
-    Parameter::Specific getDefaultParamSpecific() {
-        Equalizer eq = Equalizer::make<Equalizer::preset>(0);
-        Parameter::Specific specific =
-                Parameter::Specific::make<Parameter::Specific::equalizer>(eq);
-        return specific;
+        mTags.push_back(
+                {Equalizer::bandLevels, Equalizer::make<Equalizer::bandLevels>(bandLevels)});
     }
 
   private:
     std::vector<std::pair<Equalizer::Tag, Equalizer>> mTags;
 
-    bool validCapabilityTag(Capability& cap) { return cap.getTag() == Capability::equalizer; }
-
     void CleanUp() { mTags.clear(); }
 };
 
-TEST_P(EqualizerTest, SetAndGetPresetOutOfLowerBound) {
-    addPresetParam(mPresetIndex.second - 1);
-    ASSERT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
-}
-
-TEST_P(EqualizerTest, SetAndGetPresetOutOfUpperBound) {
-    addPresetParam(mPresetIndex.second + 1);
+TEST_P(EqualizerTest, SetAndGetParams) {
+    addBandLevelsParam(mBandLevel);
+    addPresetParam(mPresetIndex);
     EXPECT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
 }
 
-TEST_P(EqualizerTest, SetAndGetPresetAtLowerBound) {
-    addPresetParam(mPresetIndex.first);
-    EXPECT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
-}
-
-TEST_P(EqualizerTest, SetAndGetPresetAtHigherBound) {
-    addPresetParam(mPresetIndex.second);
-    EXPECT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
-}
-
-TEST_P(EqualizerTest, SetAndGetPresetInBound) {
-    addPresetParam((mPresetIndex.first + mPresetIndex.second) >> 1);
-    EXPECT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
-}
-
-TEST_P(EqualizerTest, SetAndGetBandOutOfLowerBound) {
-    std::vector<Equalizer::BandLevel> bandLevels{{mBandIndex.first - 1, mBandLevel}};
-    addBandLevelsParam(bandLevels);
-    EXPECT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
-}
-
-TEST_P(EqualizerTest, SetAndGetBandOutOfUpperBound) {
-    std::vector<Equalizer::BandLevel> bandLevels{{mBandIndex.second + 1, mBandLevel}};
-    addBandLevelsParam(bandLevels);
-    EXPECT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
-}
-
-TEST_P(EqualizerTest, SetAndGetBandAtLowerBound) {
-    std::vector<Equalizer::BandLevel> bandLevels{{mBandIndex.first, mBandLevel}};
-    addBandLevelsParam(bandLevels);
-    EXPECT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
-}
-
-TEST_P(EqualizerTest, SetAndGetBandAtHigherBound) {
-    std::vector<Equalizer::BandLevel> bandLevels{{mBandIndex.second, mBandLevel}};
-    addBandLevelsParam(bandLevels);
-    EXPECT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
-}
-
-TEST_P(EqualizerTest, SetAndGetBandInBound) {
-    std::vector<Equalizer::BandLevel> bandLevels{
-            {(mBandIndex.first + mBandIndex.second) >> 1, mBandLevel}};
-    addBandLevelsParam(bandLevels);
-    EXPECT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
-}
-
-TEST_P(EqualizerTest, SetAndGetMultiBands) {
-    addPresetParam(mPresetIndex.first);
-    std::vector<Equalizer::BandLevel> bandLevels{
-            {mBandIndex.first, mBandLevel},
-            {mBandIndex.second, mBandLevel},
-            {(mBandIndex.first + mBandIndex.second) >> 1, mBandLevel}};
-    addBandLevelsParam(bandLevels);
-    EXPECT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
-}
-
-TEST_P(EqualizerTest, SetAndGetMultipleParams) {
-    std::vector<Equalizer::BandLevel> bandLevels{
-            {(mBandIndex.first + mBandIndex.second) >> 1, mBandLevel}};
-    addBandLevelsParam(bandLevels);
-    addPresetParam((mPresetIndex.first + mPresetIndex.second) >> 1);
-    EXPECT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
-}
-
+std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kDescPair;
 INSTANTIATE_TEST_SUITE_P(
         EqualizerTest, EqualizerTest,
-        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
-                                   IFactory::descriptor, kEqualizerTypeUUID)),
-                           testing::ValuesIn(kBandLevels)),
+        ::testing::Combine(
+                testing::ValuesIn(kDescPair = EffectFactoryHelper::getAllEffectDescriptors(
+                                          IFactory::descriptor, getEffectTypeUuidEqualizer())),
+                testing::ValuesIn(EffectHelper::getTestValueSet<Equalizer, int, Range::equalizer,
+                                                                Equalizer::preset>(
+                        kDescPair, EffectHelper::expandTestValueBasic<int>)),
+                testing::ValuesIn(
+                        EffectHelper::getTestValueSet<Equalizer, std::vector<Equalizer::BandLevel>,
+                                                      Range::equalizer, Equalizer::bandLevels>(
+                                kDescPair,
+                                [](std::set<std::vector<Equalizer::BandLevel>>& bandLevels) {
+                                    return bandLevels;
+                                }))),
         [](const testing::TestParamInfo<EqualizerTest::ParamType>& info) {
             auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
-            std::string bandLevel = std::to_string(std::get<PARAM_BAND_LEVEL>(info.param));
+            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() + "_bandLevel_" + bandLevel;
+                               descriptor.common.id.uuid.toString() + "_preset_" +
+                               std::to_string(std::get<PARAM_PRESET>(info.param)) + "_bandLevel_" +
+                               bandLevel;
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
diff --git a/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp b/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp
index b8ea9c1..7c79d1b 100644
--- a/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp
@@ -14,25 +14,24 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "VtsHalHapticGeneratorTargetTest"
-
-#include <Utils.h>
-#include <aidl/Vintf.h>
-#include <android/binder_enums.h>
 #include <map>
 #include <utility>
 #include <vector>
 
+#include <aidl/Vintf.h>
+#define LOG_TAG "VtsHalHapticGeneratorTargetTest"
+#include <android-base/logging.h>
+#include <android/binder_enums.h>
+
 #include "EffectHelper.h"
 
 using namespace android;
 
-using aidl::android::hardware::audio::effect::Capability;
 using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidHapticGenerator;
 using aidl::android::hardware::audio::effect::HapticGenerator;
 using aidl::android::hardware::audio::effect::IEffect;
 using aidl::android::hardware::audio::effect::IFactory;
-using aidl::android::hardware::audio::effect::kHapticGeneratorTypeUUID;
 using aidl::android::hardware::audio::effect::Parameter;
 
 /**
@@ -180,7 +179,7 @@
 INSTANTIATE_TEST_SUITE_P(
         HapticGeneratorValidTest, HapticGeneratorParamTest,
         ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
-                                   IFactory::descriptor, kHapticGeneratorTypeUUID)),
+                                   IFactory::descriptor, getEffectTypeUuidHapticGenerator())),
                            testing::ValuesIn(kHapticScaleIdValues),
                            testing::ValuesIn(kVibratorScaleValues),
                            testing::ValuesIn(kResonantFrequencyValues),
@@ -210,7 +209,7 @@
 INSTANTIATE_TEST_SUITE_P(
         HapticGeneratorInvalidTest, HapticGeneratorParamTest,
         ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
-                                   IFactory::descriptor, kHapticGeneratorTypeUUID)),
+                                   IFactory::descriptor, getEffectTypeUuidHapticGenerator())),
                            testing::Values(MIN_ID - 1),
                            testing::Values(HapticGenerator::VibratorScale::NONE),
                            testing::Values(MIN_FLOAT), testing::Values(MIN_FLOAT),
@@ -420,7 +419,7 @@
 INSTANTIATE_TEST_SUITE_P(
         HapticGeneratorScalesTest, HapticGeneratorScalesTest,
         ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
-                IFactory::descriptor, kHapticGeneratorTypeUUID))),
+                IFactory::descriptor, getEffectTypeUuidHapticGenerator()))),
         [](const testing::TestParamInfo<HapticGeneratorScalesTest::ParamType>& info) {
             auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
             std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
diff --git a/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp b/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
index 305c243..96b048e 100644
--- a/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
@@ -14,21 +14,20 @@
  * limitations under the License.
  */
 
-#include <aidl/Vintf.h>
 #include <string>
 
+#include <aidl/Vintf.h>
 #define LOG_TAG "VtsHalLoudnessEnhancerTest"
+#include <android-base/logging.h>
 
-#include <Utils.h>
 #include "EffectHelper.h"
 
 using namespace android;
 
-using aidl::android::hardware::audio::effect::Capability;
 using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidLoudnessEnhancer;
 using aidl::android::hardware::audio::effect::IEffect;
 using aidl::android::hardware::audio::effect::IFactory;
-using aidl::android::hardware::audio::effect::kLoudnessEnhancerTypeUUID;
 using aidl::android::hardware::audio::effect::LoudnessEnhancer;
 using aidl::android::hardware::audio::effect::Parameter;
 
@@ -127,7 +126,7 @@
 INSTANTIATE_TEST_SUITE_P(
         LoudnessEnhancerTest, LoudnessEnhancerParamTest,
         ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
-                                   IFactory::descriptor, kLoudnessEnhancerTypeUUID)),
+                                   IFactory::descriptor, getEffectTypeUuidLoudnessEnhancer())),
                            testing::ValuesIn(kGainMbValues)),
         [](const testing::TestParamInfo<LoudnessEnhancerParamTest::ParamType>& info) {
             auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
diff --git a/audio/aidl/vts/VtsHalNSTargetTest.cpp b/audio/aidl/vts/VtsHalNSTargetTest.cpp
index 93ad86d..5525c80 100644
--- a/audio/aidl/vts/VtsHalNSTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalNSTargetTest.cpp
@@ -14,33 +14,33 @@
  * limitations under the License.
  */
 
-#include <Utils.h>
-#include <aidl/Vintf.h>
-#include <android/binder_enums.h>
 #include <unordered_set>
 
-#define LOG_TAG "VtsHalNSParamTest"
-
+#include <aidl/Vintf.h>
 #include <aidl/android/hardware/audio/effect/NoiseSuppression.h>
+#define LOG_TAG "VtsHalNSParamTest"
+#include <android-base/logging.h>
+#include <android/binder_enums.h>
+
 #include "EffectHelper.h"
 
 using namespace android;
 
-using aidl::android::hardware::audio::effect::Capability;
 using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidNoiseSuppression;
 using aidl::android::hardware::audio::effect::IEffect;
 using aidl::android::hardware::audio::effect::IFactory;
-using aidl::android::hardware::audio::effect::kNoiseSuppressionTypeUUID;
 using aidl::android::hardware::audio::effect::NoiseSuppression;
 using aidl::android::hardware::audio::effect::Parameter;
 
-enum ParamName { PARAM_INSTANCE_NAME, PARAM_LEVEL };
-using NSParamTestParam =
-        std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, NoiseSuppression::Level>;
+enum ParamName { PARAM_INSTANCE_NAME, PARAM_LEVEL, PARAM_TYPE };
+using NSParamTestParam = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>,
+                                    NoiseSuppression::Level, NoiseSuppression::Type>;
 
 class NSParamTest : public ::testing::TestWithParam<NSParamTestParam>, public EffectHelper {
   public:
-    NSParamTest() : mLevel(std::get<PARAM_LEVEL>(GetParam())) {
+    NSParamTest()
+        : mLevel(std::get<PARAM_LEVEL>(GetParam())), mType(std::get<PARAM_TYPE>(GetParam())) {
         std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
     }
 
@@ -75,6 +75,7 @@
     std::shared_ptr<IEffect> mEffect;
     Descriptor mDescriptor;
     NoiseSuppression::Level mLevel;
+    NoiseSuppression::Type mType;
 
     void SetAndGetParameters() {
         for (auto& it : mTags) {
@@ -113,10 +114,19 @@
         ns.set<NoiseSuppression::level>(level);
         mTags.push_back({NoiseSuppression::level, ns});
     }
+    void addTypeParam(NoiseSuppression::Type type) {
+        NoiseSuppression ns;
+        ns.set<NoiseSuppression::type>(type);
+        mTags.push_back({NoiseSuppression::type, ns});
+    }
     static std::unordered_set<NoiseSuppression::Level> getLevelValues() {
         return {ndk::enum_range<NoiseSuppression::Level>().begin(),
                 ndk::enum_range<NoiseSuppression::Level>().end()};
     }
+    static std::unordered_set<NoiseSuppression::Type> getTypeValues() {
+        return {ndk::enum_range<NoiseSuppression::Type>().begin(),
+                ndk::enum_range<NoiseSuppression::Type>().end()};
+    }
 
   private:
     std::vector<std::pair<NoiseSuppression::Tag, NoiseSuppression>> mTags;
@@ -128,18 +138,27 @@
     SetAndGetParameters();
 }
 
+TEST_P(NSParamTest, SetAndGetType) {
+    EXPECT_NO_FATAL_FAILURE(addLevelParam(mLevel));
+    SetAndGetParameters();
+}
+
 INSTANTIATE_TEST_SUITE_P(
         NSParamTest, NSParamTest,
         ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
-                                   IFactory::descriptor, kNoiseSuppressionTypeUUID)),
-                           testing::ValuesIn(NSParamTest::getLevelValues())),
+                                   IFactory::descriptor, getEffectTypeUuidNoiseSuppression())),
+                           testing::ValuesIn(NSParamTest::getLevelValues()),
+                           testing::ValuesIn(NSParamTest::getTypeValues())),
         [](const testing::TestParamInfo<NSParamTest::ParamType>& info) {
             auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
             std::string level = aidl::android::hardware::audio::effect::toString(
                     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;
+                               descriptor.common.id.uuid.toString() + "_level_" + level + "_type_" +
+                               type;
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
@@ -152,4 +171,4 @@
     ABinderProcess_setThreadPoolMaxThreadCount(1);
     ABinderProcess_startThreadPool();
     return RUN_ALL_TESTS();
-}
\ No newline at end of file
+}
diff --git a/audio/aidl/vts/VtsHalPresetReverbTargetTest.cpp b/audio/aidl/vts/VtsHalPresetReverbTargetTest.cpp
index 19d5747..8fb4ebf 100644
--- a/audio/aidl/vts/VtsHalPresetReverbTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalPresetReverbTargetTest.cpp
@@ -14,21 +14,19 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "VtsHalPresetReverbTargetTest"
-
-#include <Utils.h>
 #include <aidl/Vintf.h>
+#define LOG_TAG "VtsHalPresetReverbTargetTest"
+#include <android-base/logging.h>
 #include <android/binder_enums.h>
+
 #include "EffectHelper.h"
 
 using namespace android;
 
-using aidl::android::hardware::audio::effect::Capability;
 using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidPresetReverb;
 using aidl::android::hardware::audio::effect::IEffect;
 using aidl::android::hardware::audio::effect::IFactory;
-using aidl::android::hardware::audio::effect::kEffectNullUuid;
-using aidl::android::hardware::audio::effect::kPresetReverbTypeUUID;
 using aidl::android::hardware::audio::effect::Parameter;
 using aidl::android::hardware::audio::effect::PresetReverb;
 
@@ -84,7 +82,7 @@
             // validate parameter
             Descriptor desc;
             ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
-            const bool valid = isTagInRange(it.first, it.second, desc);
+            const bool valid = isParameterValid<PresetReverb, Range::presetReverb>(it.second, desc);
             const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
 
             // set parameter
@@ -113,27 +111,6 @@
         mTags.push_back({PresetReverb::preset, pr});
     }
 
-    bool isTagInRange(const PresetReverb::Tag& tag, const PresetReverb& pr,
-                      const Descriptor& desc) const {
-        const PresetReverb::Capability& prCap = desc.capability.get<Capability::presetReverb>();
-        switch (tag) {
-            case PresetReverb::preset: {
-                PresetReverb::Presets preset = pr.get<PresetReverb::preset>();
-                return isPresetInRange(prCap, preset);
-            }
-            default:
-                return false;
-        }
-        return false;
-    }
-
-    bool isPresetInRange(const PresetReverb::Capability& cap, PresetReverb::Presets preset) const {
-        for (auto i : cap.supportedPresets) {
-            if (preset == i) return true;
-        }
-        return false;
-    }
-
     Parameter::Specific getDefaultParamSpecific() {
         PresetReverb pr = PresetReverb::make<PresetReverb::preset>(PresetReverb::Presets::NONE);
         Parameter::Specific specific =
@@ -154,7 +131,7 @@
 INSTANTIATE_TEST_SUITE_P(
         PresetReverbTest, PresetReverbParamTest,
         ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
-                                   IFactory::descriptor, kPresetReverbTypeUUID)),
+                                   IFactory::descriptor, getEffectTypeUuidPresetReverb())),
                            testing::ValuesIn(kPresetsValues)),
         [](const testing::TestParamInfo<PresetReverbParamTest::ParamType>& info) {
             auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
diff --git a/audio/aidl/vts/VtsHalVirtualizerTargetTest.cpp b/audio/aidl/vts/VtsHalVirtualizerTargetTest.cpp
index 090de17..6b1da63 100644
--- a/audio/aidl/vts/VtsHalVirtualizerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalVirtualizerTargetTest.cpp
@@ -14,19 +14,18 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "VtsHalVirtualizerTest"
-
-#include <Utils.h>
 #include <aidl/Vintf.h>
+#define LOG_TAG "VtsHalVirtualizerTest"
+#include <android-base/logging.h>
+
 #include "EffectHelper.h"
 
 using namespace android;
 
-using aidl::android::hardware::audio::effect::Capability;
 using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidVirtualizer;
 using aidl::android::hardware::audio::effect::IEffect;
 using aidl::android::hardware::audio::effect::IFactory;
-using aidl::android::hardware::audio::effect::kVirtualizerTypeUUID;
 using aidl::android::hardware::audio::effect::Parameter;
 using aidl::android::hardware::audio::effect::Virtualizer;
 
@@ -90,7 +89,7 @@
             // validate parameter
             Descriptor desc;
             ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
-            const bool valid = isTagInRange(it.first, it.second, desc);
+            const bool valid = isParameterValid<Virtualizer, Range::virtualizer>(it.second, desc);
             const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
 
             // set parameter
@@ -120,46 +119,6 @@
         mTags.push_back({Virtualizer::strengthPm, vr});
     }
 
-    bool isTagInRange(const Virtualizer::Tag& tag, const Virtualizer& vr,
-                      const Descriptor& desc) const {
-        const Virtualizer::Capability& vrCap = desc.capability.get<Capability::virtualizer>();
-        switch (tag) {
-            case Virtualizer::strengthPm: {
-                int strength = vr.get<Virtualizer::strengthPm>();
-                return isStrengthInRange(vrCap, strength);
-            }
-            default:
-                return false;
-        }
-        return false;
-    }
-
-    bool isStrengthInRange(const Virtualizer::Capability& cap, int strength) const {
-        return cap.strengthSupported && strength >= 0 && strength <= cap.maxStrengthPm;
-    }
-
-    static std::vector<int> getStrengthTestValues(
-            std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kFactoryDescList) {
-        const auto max = std::max_element(
-                kFactoryDescList.begin(), kFactoryDescList.end(),
-                [](const std::pair<std::shared_ptr<IFactory>, Descriptor>& a,
-                   const std::pair<std::shared_ptr<IFactory>, Descriptor>& b) {
-                    return a.second.capability.get<Capability::virtualizer>().maxStrengthPm <
-                           b.second.capability.get<Capability::virtualizer>().maxStrengthPm;
-                });
-        if (max == kFactoryDescList.end()) {
-            return {0};
-        }
-        int maxStrength = max->second.capability.get<Capability::virtualizer>().maxStrengthPm;
-        return {std::numeric_limits<int>::min(),
-                -1,
-                0,
-                maxStrength >> 1,
-                maxStrength,
-                maxStrength + 1,
-                std::numeric_limits<int>::max()};
-    }
-
   private:
     std::vector<std::pair<Virtualizer::Tag, Virtualizer>> mTags;
     void CleanUp() { mTags.clear(); }
@@ -170,13 +129,15 @@
     SetAndGetVirtualizerParameters();
 }
 
+std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kDescPair;
 INSTANTIATE_TEST_SUITE_P(
         VirtualizerTest, VirtualizerParamTest,
-        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
-                                   IFactory::descriptor, kVirtualizerTypeUUID)),
-                           testing::ValuesIn(VirtualizerParamTest::getStrengthTestValues(
-                                   EffectFactoryHelper::getAllEffectDescriptors(
-                                           IFactory::descriptor, kVirtualizerTypeUUID)))),
+        ::testing::Combine(
+                testing::ValuesIn(kDescPair = EffectFactoryHelper::getAllEffectDescriptors(
+                                          IFactory::descriptor, getEffectTypeUuidVirtualizer())),
+                testing::ValuesIn(EffectHelper::getTestValueSet<
+                                  Virtualizer, int, Range::virtualizer, Virtualizer::strengthPm>(
+                        kDescPair, EffectHelper::expandTestValueBasic<int>))),
         [](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));
diff --git a/audio/aidl/vts/VtsHalVisualizerTargetTest.cpp b/audio/aidl/vts/VtsHalVisualizerTargetTest.cpp
index 242be3f..f41ba30 100644
--- a/audio/aidl/vts/VtsHalVisualizerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalVisualizerTargetTest.cpp
@@ -14,23 +14,21 @@
  * limitations under the License.
  */
 
-#include <aidl/Vintf.h>
-
-#define LOG_TAG "VtsHalVisualizerTest"
-
-#include <Utils.h>
-#include <android/binder_enums.h>
 #include <unordered_set>
 
+#include <aidl/Vintf.h>
+#define LOG_TAG "VtsHalVisualizerTest"
+#include <android-base/logging.h>
+#include <android/binder_enums.h>
+
 #include "EffectHelper.h"
 
 using namespace android;
 
-using aidl::android::hardware::audio::effect::Capability;
 using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidVisualizer;
 using aidl::android::hardware::audio::effect::IEffect;
 using aidl::android::hardware::audio::effect::IFactory;
-using aidl::android::hardware::audio::effect::kVisualizerTypeUUID;
 using aidl::android::hardware::audio::effect::Parameter;
 using aidl::android::hardware::audio::effect::Visualizer;
 
@@ -64,12 +62,11 @@
         ASSERT_NE(nullptr, mFactory);
         ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
 
-        Parameter::Specific specific = getDefaultParamSpecific();
         Parameter::Common common = EffectHelper::createParamCommon(
                 0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
                 kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
         IEffect::OpenEffectReturn ret;
-        ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &ret, EX_NONE));
+        ASSERT_NO_FATAL_FAILURE(open(mEffect, common, std::nullopt, &ret, EX_NONE));
         ASSERT_NE(nullptr, mEffect);
     }
 
@@ -77,13 +74,6 @@
         ASSERT_NO_FATAL_FAILURE(close(mEffect));
         ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
     }
-    Parameter::Specific getDefaultParamSpecific() {
-        Visualizer vs = Visualizer::make<Visualizer::captureSamples>(
-                mDescriptor.capability.get<Capability::visualizer>().captureSampleRange.max);
-        Parameter::Specific specific =
-                Parameter::Specific::make<Parameter::Specific::visualizer>(vs);
-        return specific;
-    }
 
     static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
     std::shared_ptr<IFactory> mFactory;
@@ -94,7 +84,7 @@
     Visualizer::MeasurementMode mMeasurementMode = Visualizer::MeasurementMode::NONE;
     int mLatency = 0;
 
-    void SetAndGetCommonParameters() {
+    void SetAndGetParameters() {
         for (auto& it : mCommonTags) {
             auto& tag = it.first;
             auto& vs = it.second;
@@ -102,7 +92,7 @@
             // validate parameter
             Descriptor desc;
             ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
-            const bool valid = isTagInRange(tag, vs, desc);
+            const bool valid = isParameterValid<Visualizer, Range::visualizer>(vs, desc);
             const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
 
             // set parameter
@@ -119,170 +109,39 @@
                 Visualizer::Id vsId;
                 vsId.set<Visualizer::Id::commonTag>(tag);
                 id.set<Parameter::Id::visualizerTag>(vsId);
-                EXPECT_STATUS(EX_NONE, mEffect->getParameter(id, &getParam));
-
+                EXPECT_STATUS(EX_NONE, mEffect->getParameter(id, &getParam))
+                        << " with: " << id.toString();
                 EXPECT_EQ(expectParam, getParam) << "\nexpect:" << expectParam.toString()
                                                  << "\ngetParam:" << getParam.toString();
             }
         }
     }
 
-    void SetAndGetSetOnlyParameters() {
-        for (auto& it : mSetOnlyParamTags) {
-            auto& tag = it.first;
-            auto& vs = it.second;
-
-            // validate parameter
-            Descriptor desc;
-            ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
-            const bool valid = isSetOnlyParamTagInRange(vs, desc);
-            const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
-
-            // set parameter
-            Parameter expectParam;
-            Parameter::Specific specific;
-            specific.set<Parameter::Specific::visualizer>(vs);
-            expectParam.set<Parameter::specific>(specific);
-            ASSERT_STATUS(expected, mEffect->setParameter(expectParam));
-
-            //  parameter defined in this setOnlyParameter union must be settable via
-            //  setParameter(), but must not be gettable
-            Parameter getParam;
-            Parameter::Id id;
-            Visualizer::Id vsId;
-            vsId.set<Visualizer::Id::setOnlyParamTag>(tag);
-            id.set<Parameter::Id::visualizerTag>(vsId);
-            EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, mEffect->getParameter(id, &getParam));
-        }
-    }
-
-    void GetandSetGetOnlyParameters() {
-        for (auto& tag : mGetOnlyParamTags) {
-            // get parameter
-            Parameter getParam;
-            Parameter::Id id;
-            Visualizer::Id vsId;
-            vsId.set<Visualizer::Id::getOnlyParamTag>(tag);
-            id.set<Parameter::Id::visualizerTag>(vsId);
-            ASSERT_STATUS(EX_NONE, mEffect->getParameter(id, &getParam));
-
-            //  parameter defined in this getOnlyParameter union must be gettable via
-            //  getParameter(), but must not be settable
-            // set parameter
-            ASSERT_STATUS(EX_ILLEGAL_ARGUMENT, mEffect->setParameter(getParam));
-        }
-    }
-
     void addCaptureSizeParam(int captureSize) {
-        Visualizer vs;
-        vs.set<Visualizer::captureSamples>(captureSize);
-        mCommonTags.push_back({Visualizer::captureSamples, vs});
+        mCommonTags.push_back({Visualizer::captureSamples,
+                               Visualizer::make<Visualizer::captureSamples>(captureSize)});
     }
 
     void addScalingModeParam(Visualizer::ScalingMode scalingMode) {
-        Visualizer vs;
-        vs.set<Visualizer::scalingMode>(scalingMode);
-        mCommonTags.push_back({Visualizer::scalingMode, vs});
+        mCommonTags.push_back(
+                {Visualizer::scalingMode, Visualizer::make<Visualizer::scalingMode>(scalingMode)});
     }
 
     void addMeasurementModeParam(Visualizer::MeasurementMode measurementMode) {
-        Visualizer vs;
-        vs.set<Visualizer::measurementMode>(measurementMode);
-        mCommonTags.push_back({Visualizer::measurementMode, vs});
+        mCommonTags.push_back({Visualizer::measurementMode,
+                               Visualizer::make<Visualizer::measurementMode>(measurementMode)});
     }
 
     void addLatencyParam(int latency) {
-        Visualizer vs;
-        Visualizer::SetOnlyParameters setOnlyParam;
-        setOnlyParam.set<Visualizer::SetOnlyParameters::latencyMs>(latency);
-        vs.set<Visualizer::setOnlyParameters>(setOnlyParam);
-        mSetOnlyParamTags.push_back({Visualizer::SetOnlyParameters::latencyMs, vs});
+        mCommonTags.push_back(
+                {Visualizer::latencyMs, Visualizer::make<Visualizer::latencyMs>(latency)});
     }
 
-    void addMeasurementTag() {
-        mGetOnlyParamTags.push_back(Visualizer::GetOnlyParameters::measurement);
-    }
-
-    void addCaptureBytesTag() {
-        mGetOnlyParamTags.push_back(Visualizer::GetOnlyParameters::captureSampleBuffer);
-    }
-
-    bool isTagInRange(const Visualizer::Tag& tag, const Visualizer& vs,
-                      const Descriptor& desc) const {
-        const Visualizer::Capability& vsCap = desc.capability.get<Capability::visualizer>();
-        switch (tag) {
-            case Visualizer::captureSamples: {
-                int captureSize = vs.get<Visualizer::captureSamples>();
-                return captureSize >= vsCap.captureSampleRange.min &&
-                       captureSize <= vsCap.captureSampleRange.max;
-            }
-            case Visualizer::scalingMode:
-            case Visualizer::measurementMode:
-                return true;
-            case Visualizer::setOnlyParameters: {
-                auto setOnly = vs.get<Visualizer::setOnlyParameters>();
-                if (setOnly.getTag() != Visualizer::SetOnlyParameters::latencyMs) {
-                    return false;
-                }
-                auto latencyMs = setOnly.get<Visualizer::SetOnlyParameters::latencyMs>();
-                return latencyMs >= 0 && latencyMs <= vsCap.maxLatencyMs;
-            }
-            default:
-                return false;
-        }
-    }
-
-    bool isSetOnlyParamTagInRange(const Visualizer& vs, const Descriptor& desc) const {
-        const Visualizer::Capability& vsCap = desc.capability.get<Capability::visualizer>();
-        if (vs.getTag() != Visualizer::setOnlyParameters) return false;
-        Visualizer::SetOnlyParameters setOnlyParam = vs.get<Visualizer::setOnlyParameters>();
-        if (setOnlyParam.getTag() != Visualizer::SetOnlyParameters::latencyMs) return false;
-        int latency = setOnlyParam.get<Visualizer::SetOnlyParameters::latencyMs>();
-        return isLatencyInRange(vsCap, latency);
-    }
-
-    bool isLatencyInRange(const Visualizer::Capability& cap, int latency) const {
-        return (latency >= 0 && latency <= cap.maxLatencyMs);
-    }
-
-    static std::unordered_set<int> getCaptureSizeValues() {
-        auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
-                                                                     kVisualizerTypeUUID);
-        int minCaptureSize = std::numeric_limits<int>::max();
-        int maxCaptureSize = std::numeric_limits<int>::min();
-        for (const auto& it : descList) {
-            maxCaptureSize = std::max(
-                    it.second.capability.get<Capability::visualizer>().captureSampleRange.max,
-                    maxCaptureSize);
-            minCaptureSize = std::min(
-                    it.second.capability.get<Capability ::visualizer>().captureSampleRange.min,
-                    minCaptureSize);
-        }
-        return {std::numeric_limits<int>::min(),        minCaptureSize - 1, minCaptureSize,
-                (minCaptureSize + maxCaptureSize) >> 1, maxCaptureSize,     maxCaptureSize + 1,
-                std::numeric_limits<int>::max()};
-    }
-
-    static std::unordered_set<int> getLatencyValues() {
-        auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
-                                                                     kVisualizerTypeUUID);
-        const auto max = std::max_element(
-                descList.begin(), descList.end(),
-                [](const std::pair<std::shared_ptr<IFactory>, Descriptor>& a,
-                   const std::pair<std::shared_ptr<IFactory>, Descriptor>& b) {
-                    return a.second.capability.get<Capability::visualizer>().maxLatencyMs <
-                           b.second.capability.get<Capability::visualizer>().maxLatencyMs;
-                });
-        if (max == descList.end()) {
-            return {0};
-        }
-        int maxDelay = max->second.capability.get<Capability::visualizer>().maxLatencyMs;
-        return {-1, 0, maxDelay >> 1, maxDelay - 1, maxDelay, maxDelay + 1};
-    }
     static std::unordered_set<Visualizer::MeasurementMode> getMeasurementModeValues() {
         return {ndk::enum_range<Visualizer::MeasurementMode>().begin(),
                 ndk::enum_range<Visualizer::MeasurementMode>().end()};
     }
+
     static std::unordered_set<Visualizer::ScalingMode> getScalingModeValues() {
         return {ndk::enum_range<Visualizer::ScalingMode>().begin(),
                 ndk::enum_range<Visualizer::ScalingMode>().end()};
@@ -290,53 +149,43 @@
 
   private:
     std::vector<std::pair<Visualizer::Tag, Visualizer>> mCommonTags;
-    std::vector<std::pair<Visualizer::SetOnlyParameters::Tag, Visualizer>> mSetOnlyParamTags;
-    std::vector<Visualizer::GetOnlyParameters::Tag> mGetOnlyParamTags;
-    void CleanUp() {
-        mCommonTags.clear();
-        mSetOnlyParamTags.clear();
-        mGetOnlyParamTags.clear();
-    }
+    void CleanUp() { mCommonTags.clear(); }
 };
 
 TEST_P(VisualizerParamTest, SetAndGetCaptureSize) {
     EXPECT_NO_FATAL_FAILURE(addCaptureSizeParam(mCaptureSize));
-    SetAndGetCommonParameters();
+    SetAndGetParameters();
 }
 
 TEST_P(VisualizerParamTest, SetAndGetScalingMode) {
     EXPECT_NO_FATAL_FAILURE(addScalingModeParam(mScalingMode));
-    SetAndGetCommonParameters();
+    SetAndGetParameters();
 }
 
 TEST_P(VisualizerParamTest, SetAndGetMeasurementMode) {
     EXPECT_NO_FATAL_FAILURE(addMeasurementModeParam(mMeasurementMode));
-    SetAndGetCommonParameters();
+    SetAndGetParameters();
 }
 
 TEST_P(VisualizerParamTest, SetAndGetLatency) {
     EXPECT_NO_FATAL_FAILURE(addLatencyParam(mLatency));
-    SetAndGetSetOnlyParameters();
+    SetAndGetParameters();
 }
 
-TEST_P(VisualizerParamTest, GetAndSetMeasurement) {
-    EXPECT_NO_FATAL_FAILURE(addMeasurementTag());
-    GetandSetGetOnlyParameters();
-}
-
-TEST_P(VisualizerParamTest, GetAndSetCaptureBytes) {
-    EXPECT_NO_FATAL_FAILURE(addCaptureBytesTag());
-    GetandSetGetOnlyParameters();
-}
-
+std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kDescPair;
 INSTANTIATE_TEST_SUITE_P(
         VisualizerParamTest, VisualizerParamTest,
-        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
-                                   IFactory::descriptor, kVisualizerTypeUUID)),
-                           testing::ValuesIn(VisualizerParamTest::getCaptureSizeValues()),
-                           testing::ValuesIn(VisualizerParamTest::getScalingModeValues()),
-                           testing::ValuesIn(VisualizerParamTest::getMeasurementModeValues()),
-                           testing::ValuesIn(VisualizerParamTest::getLatencyValues())),
+        ::testing::Combine(
+                testing::ValuesIn(kDescPair = EffectFactoryHelper::getAllEffectDescriptors(
+                                          IFactory::descriptor, getEffectTypeUuidVisualizer())),
+                testing::ValuesIn(EffectHelper::getTestValueSet<Visualizer, int, Range::visualizer,
+                                                                Visualizer::captureSamples>(
+                        kDescPair, EffectHelper::expandTestValueBasic<int>)),
+                testing::ValuesIn(VisualizerParamTest::getScalingModeValues()),
+                testing::ValuesIn(VisualizerParamTest::getMeasurementModeValues()),
+                testing::ValuesIn(EffectHelper::getTestValueSet<Visualizer, int, Range::visualizer,
+                                                                Visualizer::latencyMs>(
+                        kDescPair, EffectHelper::expandTestValueBasic<int>))),
         [](const testing::TestParamInfo<VisualizerParamTest::ParamType>& info) {
             auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
             std::string captureSize = std::to_string(std::get<PARAM_CAPTURE_SIZE>(info.param));
@@ -363,4 +212,4 @@
     ABinderProcess_setThreadPoolMaxThreadCount(1);
     ABinderProcess_startThreadPool();
     return RUN_ALL_TESTS();
-}
\ No newline at end of file
+}
diff --git a/audio/aidl/vts/VtsHalVolumeTargetTest.cpp b/audio/aidl/vts/VtsHalVolumeTargetTest.cpp
index 34625e7..90b7f37 100644
--- a/audio/aidl/vts/VtsHalVolumeTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalVolumeTargetTest.cpp
@@ -14,19 +14,18 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "VtsHalVolumeTest"
-
-#include <Utils.h>
 #include <aidl/Vintf.h>
+#define LOG_TAG "VtsHalVolumeTest"
+#include <android-base/logging.h>
+
 #include "EffectHelper.h"
 
 using namespace android;
 
-using aidl::android::hardware::audio::effect::Capability;
 using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidVolume;
 using aidl::android::hardware::audio::effect::IEffect;
 using aidl::android::hardware::audio::effect::IFactory;
-using aidl::android::hardware::audio::effect::kVolumeTypeUUID;
 using aidl::android::hardware::audio::effect::Parameter;
 using aidl::android::hardware::audio::effect::Volume;
 
@@ -84,9 +83,7 @@
             // validate parameter
             Descriptor desc;
             ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
-            // only set and get parameter if capability is valid
-            ASSERT_TRUE(isCapabilityValid(desc));
-            const bool valid = isTagInRange(it.first, it.second, desc);
+            const bool valid = isParameterValid<Volume, Range::volume>(it.second, desc);
             const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
 
             // set parameter
@@ -123,42 +120,6 @@
         mTags.push_back({Volume::mute, vol});
     }
 
-    bool isCapabilityValid(const Descriptor& desc) {
-        const Volume::Capability& volCap = desc.capability.get<Capability::volume>();
-        return (volCap.minLevelDb <= volCap.maxLevelDb);
-    }
-
-    bool isTagInRange(const Volume::Tag& tag, const Volume& vol, const Descriptor& desc) const {
-        const Volume::Capability& volCap = desc.capability.get<Capability::volume>();
-        switch (tag) {
-            case Volume::levelDb: {
-                int level = vol.get<Volume::levelDb>();
-                return isLevelInRange(volCap, level);
-            }
-            case Volume::mute:
-                return true;
-            default:
-                return false;
-        }
-    }
-
-    static std::vector<int> getLevelTestValues(
-            std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kFactoryDescList) {
-        int minLevelDb = std::numeric_limits<int>::max();
-        int maxLevelDb = std::numeric_limits<int>::min();
-        for (const auto& it : kFactoryDescList) {
-            maxLevelDb =
-                    std::max(it.second.capability.get<Capability::volume>().maxLevelDb, maxLevelDb);
-            minLevelDb = std::min(it.second.capability.get<Capability ::volume>().minLevelDb,
-                                  minLevelDb);
-        }
-        return {minLevelDb - 1, minLevelDb, -100, maxLevelDb, maxLevelDb + 1};
-    }
-
-    bool isLevelInRange(const Volume::Capability& volCap, int level) const {
-        return level >= volCap.minLevelDb && level <= volCap.maxLevelDb;
-    }
-
   private:
     std::vector<std::pair<Volume::Tag, Volume>> mTags;
     void CleanUp() { mTags.clear(); }
@@ -174,14 +135,15 @@
     SetAndGetParameters();
 }
 
+std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kDescPair;
 INSTANTIATE_TEST_SUITE_P(
         VolumeTest, VolumeParamTest,
         ::testing::Combine(
-                testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
-                                                                               kVolumeTypeUUID)),
-                testing::ValuesIn(VolumeParamTest::getLevelTestValues(
-                        EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
-                                                                     kVolumeTypeUUID))),
+                testing::ValuesIn(kDescPair = EffectFactoryHelper::getAllEffectDescriptors(
+                                          IFactory::descriptor, getEffectTypeUuidVolume())),
+                testing::ValuesIn(
+                        EffectHelper::getTestValueSet<Volume, int, Range::volume, Volume::levelDb>(
+                                kDescPair, EffectHelper::expandTestValueBasic<int>)),
                 testing::Bool() /* mute */),
         [](const testing::TestParamInfo<VolumeParamTest::ParamType>& info) {
             auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
diff --git a/audio/common/all-versions/default/HidlUtils.h b/audio/common/all-versions/default/HidlUtils.h
index ad9dee2..844a651 100644
--- a/audio/common/all-versions/default/HidlUtils.h
+++ b/audio/common/all-versions/default/HidlUtils.h
@@ -81,7 +81,7 @@
 #endif
 
 #if MAJOR_VERSION >= 7
-    static constexpr char sAudioTagSeparator = ';';
+    static constexpr char sAudioTagSeparator = AUDIO_ATTRIBUTES_TAGS_SEPARATOR;
 
     static status_t audioChannelMaskFromHal(audio_channel_mask_t halChannelMask, bool isInput,
                                             AudioChannelMask* channelMask);
diff --git a/audio/common/all-versions/default/service/service.cpp b/audio/common/all-versions/default/service/service.cpp
index e79ad75..7b5a932 100644
--- a/audio/common/all-versions/default/service/service.cpp
+++ b/audio/common/all-versions/default/service/service.cpp
@@ -81,9 +81,10 @@
 int main(int /* argc */, char* /* argv */ []) {
     signal(SIGPIPE, SIG_IGN);
 
-    ::android::ProcessState::initWithDriver("/dev/vndbinder");
-    // start a threadpool for vndbinder interactions
-    ::android::ProcessState::self()->startThreadPool();
+    if (::android::ProcessState::isVndservicemanagerEnabled()) {
+        ::android::ProcessState::initWithDriver("/dev/vndbinder");
+        ::android::ProcessState::self()->startThreadPool();
+    }
 
     ABinderProcess_setThreadPoolMaxThreadCount(1);
     ABinderProcess_startThreadPool();
diff --git a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
index 98e49a2..478482d 100644
--- a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
+++ b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
@@ -1698,26 +1698,6 @@
     ASSERT_EQ(0U, framesLost);
 }
 
-TEST_P(InputStreamTest, getCapturePosition) {
-    doc::test(
-        "The capture position of a non prepared stream should not be "
-        "retrievable or 0");
-    uint64_t frames;
-    uint64_t time;
-    ASSERT_OK(stream->getCapturePosition(returnIn(res, frames, time)));
-    // Although 'getCapturePosition' is mandatory in V7, legacy implementations
-    // may return -ENOSYS (which is translated to NOT_SUPPORTED) in cases when
-    // the capture position can't be retrieved, e.g. when the stream isn't
-    // running. Because of this, we don't fail when getting NOT_SUPPORTED
-    // in this test. Behavior of 'getCapturePosition' for running streams is
-    // tested in 'PcmOnlyConfigInputStreamTest' for V7.
-    ASSERT_RESULT(okOrInvalidStateOrNotSupported, res);
-    if (res == Result::OK) {
-        ASSERT_EQ(0U, frames);
-        ASSERT_LE(0U, time);
-    }
-}
-
 //////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////// StreamOut //////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////
diff --git a/automotive/audiocontrol/1.0/default/test/fuzzer/Android.bp b/automotive/audiocontrol/1.0/default/test/fuzzer/Android.bp
index 78f5b52..4308d52 100644
--- a/automotive/audiocontrol/1.0/default/test/fuzzer/Android.bp
+++ b/automotive/audiocontrol/1.0/default/test/fuzzer/Android.bp
@@ -48,5 +48,13 @@
             "android-media-fuzzing-reports@google.com",
         ],
         componentid: 533764,
+        hotlists: [
+            "4593311",
+        ],
+        description: "The fuzzer targets the APIs of android.hardware.automotive.audiocontrol@1.0-service binary",
+        vector: "local_privileges_required",
+        service_privilege: "privileged",
+        users: "multi_user",
+        fuzzed_code_usage: "shipped",
     },
 }
diff --git a/automotive/audiocontrol/aidl/vts/Android.bp b/automotive/audiocontrol/aidl/vts/Android.bp
index edac160..da92d38 100644
--- a/automotive/audiocontrol/aidl/vts/Android.bp
+++ b/automotive/audiocontrol/aidl/vts/Android.bp
@@ -25,7 +25,6 @@
     name: "VtsAidlHalAudioControlTest",
     defaults: [
         "latest_android_media_audio_common_types_cpp_static",
-        "latest_android_hardware_audio_common_cpp_static",
         "VtsHalTargetTestDefaults",
         "use_libaidlvintf_gtest_helper_static",
     ],
@@ -39,6 +38,7 @@
         "libxml2",
     ],
     static_libs: [
+        "android.hardware.audio.common-V1-cpp",
         "android.hardware.automotive.audiocontrol-V2-cpp",
         "libgmock",
     ],
diff --git a/automotive/can/1.0/default/libc++fs/src/filesystem/directory_iterator.cpp b/automotive/can/1.0/default/libc++fs/src/filesystem/directory_iterator.cpp
index 624538b..37c863b 100644
--- a/automotive/can/1.0/default/libc++fs/src/filesystem/directory_iterator.cpp
+++ b/automotive/can/1.0/default/libc++fs/src/filesystem/directory_iterator.cpp
@@ -169,8 +169,8 @@
   __dir_stream& operator=(const __dir_stream&) = delete;
 
   __dir_stream(__dir_stream&& other) noexcept : __stream_(other.__stream_),
-                                                __root_(move(other.__root_)),
-                                                __entry_(move(other.__entry_)) {
+                                                __root_(std::move(other.__root_)),
+                                                __entry_(std::move(other.__entry_)) {
     other.__stream_ = nullptr;
   }
 
@@ -252,7 +252,7 @@
 
   error_code m_ec;
   if (!__imp_->advance(m_ec)) {
-    path root = move(__imp_->__root_);
+    path root = std::move(__imp_->__root_);
     __imp_.reset();
     if (m_ec)
       err.report(m_ec, "at root \"%s\"", root);
@@ -286,7 +286,7 @@
 
   __imp_ = make_shared<__shared_imp>();
   __imp_->__options_ = opt;
-  __imp_->__stack_.push(move(new_s));
+  __imp_->__stack_.push(std::move(new_s));
 }
 
 void recursive_directory_iterator::__pop(error_code* ec) {
@@ -340,7 +340,7 @@
   }
 
   if (m_ec) {
-    path root = move(stack.top().__root_);
+    path root = std::move(stack.top().__root_);
     __imp_.reset();
     err.report(m_ec, "at root \"%s\"", root);
   } else {
@@ -374,7 +374,7 @@
   if (!skip_rec) {
     __dir_stream new_it(curr_it.__entry_.path(), __imp_->__options_, m_ec);
     if (new_it.good()) {
-      __imp_->__stack_.push(move(new_it));
+      __imp_->__stack_.push(std::move(new_it));
       return true;
     }
   }
@@ -385,7 +385,7 @@
       if (ec)
         ec->clear();
     } else {
-      path at_ent = move(curr_it.__entry_.__p_);
+      path at_ent = std::move(curr_it.__entry_.__p_);
       __imp_.reset();
       err.report(m_ec, "attempting recursion into \"%s\"", at_ent);
     }
diff --git a/automotive/can/1.0/default/tests/fuzzer/Android.bp b/automotive/can/1.0/default/tests/fuzzer/Android.bp
index 52b43b0..de0b96f 100644
--- a/automotive/can/1.0/default/tests/fuzzer/Android.bp
+++ b/automotive/can/1.0/default/tests/fuzzer/Android.bp
@@ -50,5 +50,13 @@
             "android-media-fuzzing-reports@google.com",
         ],
         componentid: 533764,
+        hotlists: [
+            "4593311",
+        ],
+        description: "The fuzzer targets the APIs of android.hardware.automotive.can@1.0-service",
+        vector: "local_no_privileges_required",
+        service_privilege: "privileged",
+        users: "multi_user",
+        fuzzed_code_usage: "shipped",
     },
 }
diff --git a/automotive/evs/OWNERS b/automotive/evs/OWNERS
index b973e91..15de48f 100644
--- a/automotive/evs/OWNERS
+++ b/automotive/evs/OWNERS
@@ -1,3 +1,2 @@
 ankitarora@google.com
-changyeon@google.com
 jwhpryor@google.com
diff --git a/automotive/occupant_awareness/aidl/default/Android.bp b/automotive/occupant_awareness/aidl/default/Android.bp
index 66af9de..1ae8689 100644
--- a/automotive/occupant_awareness/aidl/default/Android.bp
+++ b/automotive/occupant_awareness/aidl/default/Android.bp
@@ -26,6 +26,7 @@
 cc_binary {
     name: "android.hardware.automotive.occupant_awareness@1.0-service",
     init_rc: ["android.hardware.automotive.occupant_awareness@1.0-service.rc"],
+    vintf_fragments: ["android.hardware.automotive.occupant_awareness-service.xml"],
     relative_install_path: "hw",
     vendor: true,
     srcs: [
diff --git a/automotive/occupant_awareness/aidl/default/android.hardware.automotive.occupant_awareness-service.xml b/automotive/occupant_awareness/aidl/default/android.hardware.automotive.occupant_awareness-service.xml
new file mode 100644
index 0000000..b4f8fa5
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/default/android.hardware.automotive.occupant_awareness-service.xml
@@ -0,0 +1,7 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.automotive.occupant_awareness</name>
+        <version>1</version>
+        <fqname>IOccupantAwareness/default</fqname>
+    </hal>
+</manifest>
diff --git a/automotive/sv/1.0/default/tests/fuzzer/Android.bp b/automotive/sv/1.0/default/tests/fuzzer/Android.bp
index 394c532..696bfad 100644
--- a/automotive/sv/1.0/default/tests/fuzzer/Android.bp
+++ b/automotive/sv/1.0/default/tests/fuzzer/Android.bp
@@ -47,5 +47,13 @@
             "android-media-fuzzing-reports@google.com",
         ],
         componentid: 533764,
+        hotlists: [
+            "4593311",
+        ],
+        description: "The fuzzer targets the APIs of android.hardware.automotive.sv@1.0-service",
+        vector: "local_no_privileges_required",
+        service_privilege: "privileged",
+        users: "multi_user",
+        fuzzed_code_usage: "shipped",
     },
 }
diff --git a/automotive/vehicle/2.0/default/Android.bp b/automotive/vehicle/2.0/default/Android.bp
index 33e211c..586a98e 100644
--- a/automotive/vehicle/2.0/default/Android.bp
+++ b/automotive/vehicle/2.0/default/Android.bp
@@ -292,5 +292,13 @@
             "android-media-fuzzing-reports@google.com",
         ],
         componentid: 533764,
+        hotlists: [
+            "4593311",
+        ],
+        description: "The fuzzer targets the APIs of android.hardware.automotive.vehicle@2.0-manager-lib",
+        vector: "local_no_privileges_required",
+        service_privilege: "privileged",
+        users: "multi_user",
+        fuzzed_code_usage: "shipped",
     },
 }
diff --git a/automotive/vehicle/aidl/impl/default_config/include/DefaultConfig.h b/automotive/vehicle/aidl/impl/default_config/include/DefaultConfig.h
index 9a93e1a..622846a 100644
--- a/automotive/vehicle/aidl/impl/default_config/include/DefaultConfig.h
+++ b/automotive/vehicle/aidl/impl/default_config/include/DefaultConfig.h
@@ -190,6 +190,40 @@
                  },
          .initialValue = {.int32Values = {toInt(VehicleUnit::KILOWATT_HOUR)}}},
 
+        {.config = {.prop = toInt(VehicleProperty::SEAT_MEMORY_SELECT),
+                    .access = VehiclePropertyAccess::WRITE,
+                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                    .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+                                                      .minInt32Value = 0,
+                                                      .maxInt32Value = 3},
+                                    VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+                                                      .minInt32Value = 0,
+                                                      .maxInt32Value = 3},
+                                    VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+                                                      .minInt32Value = 0,
+                                                      .maxInt32Value = 3},
+                                    VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+                                                      .minInt32Value = 0,
+                                                      .maxInt32Value = 3}}},
+         .initialValue = {.int32Values = {1}}},
+
+        {.config = {.prop = toInt(VehicleProperty::SEAT_MEMORY_SET),
+                    .access = VehiclePropertyAccess::WRITE,
+                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                    .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+                                                      .minInt32Value = 0,
+                                                      .maxInt32Value = 3},
+                                    VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+                                                      .minInt32Value = 0,
+                                                      .maxInt32Value = 3},
+                                    VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+                                                      .minInt32Value = 0,
+                                                      .maxInt32Value = 3},
+                                    VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+                                                      .minInt32Value = 0,
+                                                      .maxInt32Value = 3}}},
+         .initialValue = {.int32Values = {1}}},
+
         {.config = {.prop = toInt(VehicleProperty::SEAT_BELT_BUCKLED),
                     .access = VehiclePropertyAccess::READ_WRITE,
                     .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/RecurrentTimer.h b/automotive/vehicle/aidl/impl/utils/common/include/RecurrentTimer.h
index 5f0f716..cd2b727 100644
--- a/automotive/vehicle/aidl/impl/utils/common/include/RecurrentTimer.h
+++ b/automotive/vehicle/aidl/impl/utils/common/include/RecurrentTimer.h
@@ -83,8 +83,9 @@
     // each time we might introduce outdated elements to the top. We must make sure the heap is
     // always valid from the top.
     void removeInvalidCallbackLocked() REQUIRES(mLock);
-    // Pops the next closest callback (must be valid) from the heap.
-    std::unique_ptr<CallbackInfo> popNextCallbackLocked() REQUIRES(mLock);
+    // Gets the next calblack to run (must be valid) from the heap, update its nextTime and put
+    // it back to the heap.
+    std::shared_ptr<Callback> getNextCallbackLocked(int64_t now) REQUIRES(mLock);
 };
 
 }  // namespace vehicle
diff --git a/automotive/vehicle/aidl/impl/utils/common/src/RecurrentTimer.cpp b/automotive/vehicle/aidl/impl/utils/common/src/RecurrentTimer.cpp
index 2eca6b7..908564c 100644
--- a/automotive/vehicle/aidl/impl/utils/common/src/RecurrentTimer.cpp
+++ b/automotive/vehicle/aidl/impl/utils/common/src/RecurrentTimer.cpp
@@ -101,68 +101,71 @@
     }
 }
 
-std::unique_ptr<RecurrentTimer::CallbackInfo> RecurrentTimer::popNextCallbackLocked() {
+std::shared_ptr<RecurrentTimer::Callback> RecurrentTimer::getNextCallbackLocked(int64_t now) {
     std::pop_heap(mCallbackQueue.begin(), mCallbackQueue.end(), CallbackInfo::cmp);
-    std::unique_ptr<CallbackInfo> info = std::move(mCallbackQueue[mCallbackQueue.size() - 1]);
-    mCallbackQueue.pop_back();
+    auto& callbackInfo = mCallbackQueue[mCallbackQueue.size() - 1];
+    auto nextCallback = callbackInfo->callback;
+    // intervalCount is the number of interval we have to advance until we pass now.
+    size_t intervalCount = (now - callbackInfo->nextTime) / callbackInfo->interval + 1;
+    callbackInfo->nextTime += intervalCount * callbackInfo->interval;
+    std::push_heap(mCallbackQueue.begin(), mCallbackQueue.end(), CallbackInfo::cmp);
+
     // Make sure the first element is always valid.
     removeInvalidCallbackLocked();
-    return info;
+
+    return nextCallback;
 }
 
 void RecurrentTimer::loop() {
-    std::unique_lock<std::mutex> uniqueLock(mLock);
-
+    std::vector<std::shared_ptr<Callback>> callbacksToRun;
     while (true) {
-        // Wait until the timer exits or we have at least one recurrent callback.
-        mCond.wait(uniqueLock, [this] {
-            ScopedLockAssertion lockAssertion(mLock);
-            return mStopRequested || mCallbackQueue.size() != 0;
-        });
-
-        int64_t interval;
         {
+            std::unique_lock<std::mutex> uniqueLock(mLock);
             ScopedLockAssertion lockAssertion(mLock);
+            // Wait until the timer exits or we have at least one recurrent callback.
+            mCond.wait(uniqueLock, [this] {
+                ScopedLockAssertion lockAssertion(mLock);
+                return mStopRequested || mCallbackQueue.size() != 0;
+            });
+
+            int64_t interval;
             if (mStopRequested) {
                 return;
             }
             // The first element is the nearest next event.
             int64_t nextTime = mCallbackQueue[0]->nextTime;
             int64_t now = uptimeNanos();
+
             if (nextTime > now) {
                 interval = nextTime - now;
             } else {
                 interval = 0;
             }
-        }
 
-        // Wait for the next event or the timer exits.
-        if (mCond.wait_for(uniqueLock, std::chrono::nanoseconds(interval), [this] {
-                ScopedLockAssertion lockAssertion(mLock);
-                return mStopRequested;
-            })) {
-            return;
-        }
+            // Wait for the next event or the timer exits.
+            if (mCond.wait_for(uniqueLock, std::chrono::nanoseconds(interval), [this] {
+                    ScopedLockAssertion lockAssertion(mLock);
+                    return mStopRequested;
+                })) {
+                return;
+            }
 
-        {
-            ScopedLockAssertion lockAssertion(mLock);
-            int64_t now = uptimeNanos();
+            now = uptimeNanos();
+            callbacksToRun.clear();
             while (mCallbackQueue.size() > 0) {
                 int64_t nextTime = mCallbackQueue[0]->nextTime;
                 if (nextTime > now) {
                     break;
                 }
 
-                std::unique_ptr<CallbackInfo> info = popNextCallbackLocked();
-                info->nextTime += info->interval;
-
-                auto callback = info->callback;
-                mCallbackQueue.push_back(std::move(info));
-                std::push_heap(mCallbackQueue.begin(), mCallbackQueue.end(), CallbackInfo::cmp);
-
-                (*callback)();
+                callbacksToRun.push_back(getNextCallbackLocked(now));
             }
         }
+
+        // Do not execute the callback while holding the lock.
+        for (size_t i = 0; i < callbacksToRun.size(); i++) {
+            (*callbacksToRun[i])();
+        }
     }
 }
 
diff --git a/automotive/vehicle/aidl/impl/utils/common/test/RecurrentTimerTest.cpp b/automotive/vehicle/aidl/impl/utils/common/test/RecurrentTimerTest.cpp
index a033a24..141efc1 100644
--- a/automotive/vehicle/aidl/impl/utils/common/test/RecurrentTimerTest.cpp
+++ b/automotive/vehicle/aidl/impl/utils/common/test/RecurrentTimerTest.cpp
@@ -186,6 +186,33 @@
     ASSERT_EQ(countTimerCallbackQueue(&timer), static_cast<size_t>(0));
 }
 
+TEST_F(RecurrentTimerTest, testRegisterCallbackMultipleTimesNoDeadLock) {
+    // We want to avoid the following situation:
+    // Caller holds a lock while calling registerTimerCallback, registerTimerCallback will try
+    // to obtain an internal lock inside timer.
+    // Meanwhile an recurrent action happens with timer holding an internal lock. The action
+    // tries to obtain the lock currently hold by the caller.
+    // The solution is that while calling recurrent actions, timer must not hold the internal lock.
+
+    std::unique_ptr<RecurrentTimer> timer = std::make_unique<RecurrentTimer>();
+    std::mutex lock;
+    for (size_t i = 0; i < 1000; i++) {
+        std::scoped_lock<std::mutex> lockGuard(lock);
+        auto action = std::make_shared<RecurrentTimer::Callback>([&lock] {
+            // While calling this function, the timer must not hold lock in order not to dead
+            // lock.
+            std::scoped_lock<std::mutex> lockGuard(lock);
+        });
+        // 10ms
+        int64_t interval = 10'000'000;
+        timer->registerTimerCallback(interval, action);
+        // Sleep for a little while to let the recurrent actions begin.
+        std::this_thread::sleep_for(std::chrono::milliseconds(1));
+    }
+    // Make sure we stop the timer before we destroy lock.
+    timer.reset();
+}
+
 }  // namespace vehicle
 }  // namespace automotive
 }  // namespace hardware
diff --git a/bluetooth/1.0/default/test/fuzzer/Android.bp b/bluetooth/1.0/default/test/fuzzer/Android.bp
index 691136f..de2b46d 100644
--- a/bluetooth/1.0/default/test/fuzzer/Android.bp
+++ b/bluetooth/1.0/default/test/fuzzer/Android.bp
@@ -60,5 +60,13 @@
             "android-media-fuzzing-reports@google.com",
         ],
         componentid: 533764,
+        hotlists: [
+            "4593311",
+        ],
+        description: "The fuzzer targets the APIs of android.hardware.bluetooth@1.0-impl library",
+        vector: "local_no_privileges_required",
+        service_privilege: "privileged",
+        users: "multi_user",
+        fuzzed_code_usage: "shipped",
     },
 }
diff --git a/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp b/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp
index 8ea1ddd..9451087 100644
--- a/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp
+++ b/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp
@@ -516,12 +516,15 @@
 // Return the number of completed packets reported by the controller.
 int BluetoothHidlTest::wait_for_completed_packets_event(uint16_t handle) {
   int packets_processed = 0;
-  wait_for_event(false);
-  if (event_queue.size() == 0) {
-    ALOGW("%s: WaitForCallback timed out.", __func__);
-    return packets_processed;
-  }
-  while (event_queue.size() > 0) {
+  while (true) {
+    // There should be at least one event.
+    wait_for_event(packets_processed == 0);
+    if (event_queue.empty()) {
+      if (packets_processed == 0) {
+        ALOGW("%s: WaitForCallback timed out.", __func__);
+      }
+      return packets_processed;
+    }
     hidl_vec<uint8_t> event = event_queue.front();
     event_queue.pop();
 
diff --git a/bluetooth/1.1/vts/functional/VtsHalBluetoothV1_1TargetTest.cpp b/bluetooth/1.1/vts/functional/VtsHalBluetoothV1_1TargetTest.cpp
index 9ae3837..28ac603 100644
--- a/bluetooth/1.1/vts/functional/VtsHalBluetoothV1_1TargetTest.cpp
+++ b/bluetooth/1.1/vts/functional/VtsHalBluetoothV1_1TargetTest.cpp
@@ -539,12 +539,15 @@
 // Return the number of completed packets reported by the controller.
 int BluetoothHidlTest::wait_for_completed_packets_event(uint16_t handle) {
   int packets_processed = 0;
-  wait_for_event(false);
-  if (event_queue.size() == 0) {
-    ALOGW("%s: WaitForCallback timed out.", __func__);
-    return packets_processed;
-  }
-  while (event_queue.size() > 0) {
+  while (true) {
+    // There should be at least one event.
+    wait_for_event(packets_processed == 0);
+    if (event_queue.empty()) {
+      if (packets_processed == 0) {
+        ALOGW("%s: WaitForCallback timed out.", __func__);
+      }
+      return packets_processed;
+    }
     hidl_vec<uint8_t> event = event_queue.front();
     event_queue.pop();
 
diff --git a/bluetooth/aidl/TEST_MAPPING b/bluetooth/aidl/TEST_MAPPING
index 342a1e4..f059c04 100644
--- a/bluetooth/aidl/TEST_MAPPING
+++ b/bluetooth/aidl/TEST_MAPPING
@@ -1,7 +1,13 @@
 {
   "presubmit" : [
     {
-      "name" : "VtsHalBluetoothTargetTest"
+      "name" : "VtsHalBluetoothTargetTest",
+      "options": [
+        {
+          // TODO(b/275847929)
+          "exclude-filter": "VtsHalBluetoothTargetTest.PerInstance/BluetoothAidlTest#Cdd_C_12_1_Bluetooth5Requirements/0_android_hardware_bluetooth_IBluetoothHci_default"
+        }
+      ]
     }
   ]
 }
diff --git a/bluetooth/aidl/vts/Android.bp b/bluetooth/aidl/vts/Android.bp
index 414f707..5fc0b2e 100644
--- a/bluetooth/aidl/vts/Android.bp
+++ b/bluetooth/aidl/vts/Android.bp
@@ -13,7 +13,17 @@
         "VtsHalTargetTestDefaults",
         "use_libaidlvintf_gtest_helper_static",
     ],
-    srcs: ["VtsHalBluetoothTargetTest.cpp"],
+    srcs: [
+        "VtsHalBluetoothTargetTest.cpp",
+        ":BluetoothPacketSources",
+        ":BluetoothHciPacketSources",
+    ],
+    generated_headers: [
+        "BluetoothGeneratedPackets_h",
+    ],
+    include_dirs: [
+        "packages/modules/Bluetooth/system/gd",
+    ],
     shared_libs: [
         "libbase",
         "libbinder_ndk",
@@ -45,4 +55,8 @@
     tidy_flags: [
         "--header-filter=^.*tools\\/rootcanal\\/(model|include|net|desktop)\\/(.(?!\\.pb\\.h))*$",
     ],
+    tidy_disabled_srcs: [
+        ":BluetoothPacketSources",
+        ":BluetoothHciPacketSources",
+    ],
 }
diff --git a/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp b/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp
index 3704c3d..529e092 100644
--- a/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp
+++ b/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp
@@ -24,27 +24,50 @@
 #include <android/binder_manager.h>
 #include <android/binder_process.h>
 #include <binder/IServiceManager.h>
-#include <binder/ProcessState.h>
 
 #include <atomic>
 #include <chrono>
 #include <condition_variable>
 #include <future>
-#include <mutex>
 #include <queue>
 #include <thread>
+#include <utility>
 #include <vector>
 
+// TODO: Remove custom logging defines from PDL packets.
+#undef LOG_INFO
+#undef LOG_DEBUG
+#undef LOG_TAG
+#define LOG_TAG "VtsHalBluetooth"
+#include "hci/hci_packets.h"
+#include "packet/raw_builder.h"
+
 using aidl::android::hardware::bluetooth::IBluetoothHci;
 using aidl::android::hardware::bluetooth::IBluetoothHciCallbacks;
 using aidl::android::hardware::bluetooth::Status;
 using ndk::ScopedAStatus;
 using ndk::SpAIBinder;
 
-// Bluetooth Core Specification 3.0 + HS
-static constexpr uint8_t kHciMinimumHciVersion = 5;
-// Bluetooth Core Specification 3.0 + HS
-static constexpr uint8_t kHciMinimumLmpVersion = 5;
+using ::bluetooth::hci::CommandBuilder;
+using ::bluetooth::hci::CommandCompleteView;
+using ::bluetooth::hci::CommandView;
+using ::bluetooth::hci::ErrorCode;
+using ::bluetooth::hci::EventView;
+using ::bluetooth::hci::LeReadLocalSupportedFeaturesBuilder;
+using ::bluetooth::hci::LeReadLocalSupportedFeaturesCompleteView;
+using ::bluetooth::hci::LeReadNumberOfSupportedAdvertisingSetsBuilder;
+using ::bluetooth::hci::LeReadNumberOfSupportedAdvertisingSetsCompleteView;
+using ::bluetooth::hci::LeReadResolvingListSizeBuilder;
+using ::bluetooth::hci::LeReadResolvingListSizeCompleteView;
+using ::bluetooth::hci::LLFeaturesBits;
+using ::bluetooth::hci::OpCode;
+using ::bluetooth::hci::OpCodeText;
+using ::bluetooth::hci::PacketView;
+using ::bluetooth::hci::ReadLocalVersionInformationBuilder;
+using ::bluetooth::hci::ReadLocalVersionInformationCompleteView;
+
+static constexpr uint8_t kMinLeAdvSetForBt5 = 16;
+static constexpr uint8_t kMinLeResolvingListForBt5 = 8;
 
 static constexpr size_t kNumHciCommandsBandwidth = 100;
 static constexpr size_t kNumScoPacketsBandwidth = 100;
@@ -55,65 +78,14 @@
 static constexpr std::chrono::milliseconds kWaitForAclDataTimeout(1000);
 static constexpr std::chrono::milliseconds kInterfaceCloseDelayMs(200);
 
-static constexpr uint8_t kCommandHciShouldBeUnknown[] = {
-    0xff, 0x3B, 0x08, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
-static constexpr uint8_t kCommandHciReadLocalVersionInformation[] = {0x01, 0x10,
-                                                                     0x00};
-static constexpr uint8_t kCommandHciReadBufferSize[] = {0x05, 0x10, 0x00};
-static constexpr uint8_t kCommandHciWriteLoopbackModeLocal[] = {0x02, 0x18,
-                                                                0x01, 0x01};
-static constexpr uint8_t kCommandHciReset[] = {0x03, 0x0c, 0x00};
-static constexpr uint8_t kCommandHciSynchronousFlowControlEnable[] = {
-    0x2f, 0x0c, 0x01, 0x01};
-static constexpr uint8_t kCommandHciWriteLocalName[] = {0x13, 0x0c, 0xf8};
-static constexpr uint8_t kHciStatusSuccess = 0x00;
-static constexpr uint8_t kHciStatusUnknownHciCommand = 0x01;
-
-static constexpr uint8_t kEventConnectionComplete = 0x03;
-static constexpr uint8_t kEventCommandComplete = 0x0e;
-static constexpr uint8_t kEventCommandStatus = 0x0f;
-static constexpr uint8_t kEventNumberOfCompletedPackets = 0x13;
-static constexpr uint8_t kEventLoopbackCommand = 0x19;
-
-static constexpr size_t kEventCodeByte = 0;
-static constexpr size_t kEventLengthByte = 1;
-static constexpr size_t kEventFirstPayloadByte = 2;
-static constexpr size_t kEventCommandStatusStatusByte = 2;
-static constexpr size_t kEventCommandStatusOpcodeLsByte = 4;    // Bytes 4 and 5
-static constexpr size_t kEventCommandCompleteOpcodeLsByte = 3;  // Bytes 3 and 4
-static constexpr size_t kEventCommandCompleteStatusByte = 5;
-static constexpr size_t kEventCommandCompleteFirstParamByte = 6;
-static constexpr size_t kEventLocalHciVersionByte =
-    kEventCommandCompleteFirstParamByte;
-static constexpr size_t kEventLocalLmpVersionByte =
-    kEventLocalHciVersionByte + 3;
-
-static constexpr size_t kEventConnectionCompleteParamLength = 11;
-static constexpr size_t kEventConnectionCompleteType = 11;
-static constexpr size_t kEventConnectionCompleteTypeSco = 0;
-static constexpr size_t kEventConnectionCompleteTypeAcl = 1;
-static constexpr size_t kEventConnectionCompleteHandleLsByte = 3;
-
-static constexpr size_t kEventNumberOfCompletedPacketsNumHandles = 2;
-
-static constexpr size_t kAclBroadcastFlagOffset = 6;
-static constexpr uint8_t kAclBroadcastFlagPointToPoint = 0x0;
-static constexpr uint8_t kAclBroadcastPointToPoint =
-    (kAclBroadcastFlagPointToPoint << kAclBroadcastFlagOffset);
-
-static constexpr uint8_t kAclPacketBoundaryFlagOffset = 4;
-static constexpr uint8_t kAclPacketBoundaryFlagFirstAutoFlushable = 0x2;
-static constexpr uint8_t kAclPacketBoundaryFirstAutoFlushable =
-    kAclPacketBoundaryFlagFirstAutoFlushable << kAclPacketBoundaryFlagOffset;
-
 // To discard Qualcomm ACL debugging
 static constexpr uint16_t kAclHandleQcaDebugMessage = 0xedc;
 
 class ThroughputLogger {
  public:
-  ThroughputLogger(std::string task)
+  explicit ThroughputLogger(std::string task)
       : total_bytes_(0),
-        task_(task),
+        task_(std::move(task)),
         start_time_(std::chrono::steady_clock::now()) {}
 
   ~ThroughputLogger() {
@@ -142,7 +114,7 @@
 // The main test class for Bluetooth HAL.
 class BluetoothAidlTest : public ::testing::TestWithParam<std::string> {
  public:
-  virtual void SetUp() override {
+  void SetUp() override {
     // currently test passthrough mode only
     hci = IBluetoothHci::fromBinder(
         SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
@@ -158,7 +130,7 @@
     ASSERT_NE(bluetooth_hci_death_recipient, nullptr);
     ASSERT_EQ(STATUS_OK,
               AIBinder_linkToDeath(hci->asBinder().get(),
-                                   bluetooth_hci_death_recipient, 0));
+                                   bluetooth_hci_death_recipient, nullptr));
 
     hci_cb = ndk::SharedRefBase::make<BluetoothHciCallbacks>(*this);
     ASSERT_NE(hci_cb, nullptr);
@@ -179,7 +151,7 @@
     ASSERT_TRUE(future.get());
   }
 
-  virtual void TearDown() override {
+  void TearDown() override {
     ALOGI("TearDown");
     // Should not be checked in production code
     ASSERT_TRUE(hci->close().isOk());
@@ -205,8 +177,14 @@
   void handle_no_ops();
   void discard_qca_debugging();
   void wait_for_event(bool timeout_is_error);
-  void wait_for_command_complete_event(std::vector<uint8_t> cmd);
+  void wait_for_command_complete_event(OpCode opCode,
+                                       std::vector<uint8_t>& complete_event);
+  // Wait until a command complete is received.
+  // Command complete will be consumed after this method
+  void wait_and_validate_command_complete_event(OpCode opCode);
   int wait_for_completed_packets_event(uint16_t handle);
+  void send_and_wait_for_cmd_complete(std::unique_ptr<CommandBuilder> cmd,
+                                      std::vector<uint8_t>& cmd_complete);
 
   // A simple test implementation of BluetoothHciCallbacks.
   class BluetoothHciCallbacks
@@ -214,36 +192,41 @@
     BluetoothAidlTest& parent_;
 
    public:
-    BluetoothHciCallbacks(BluetoothAidlTest& parent) : parent_(parent){};
+    explicit BluetoothHciCallbacks(BluetoothAidlTest& parent)
+        : parent_(parent){};
 
-    virtual ~BluetoothHciCallbacks() = default;
+    ~BluetoothHciCallbacks() override = default;
 
-    ndk::ScopedAStatus initializationComplete(Status status) {
+    ndk::ScopedAStatus initializationComplete(Status status) override {
       parent_.initialized_promise.set_value(status == Status::SUCCESS);
       ALOGV("%s (status = %d)", __func__, static_cast<int>(status));
       return ScopedAStatus::ok();
     };
 
-    ndk::ScopedAStatus hciEventReceived(const std::vector<uint8_t>& event) {
+    ndk::ScopedAStatus hciEventReceived(
+        const std::vector<uint8_t>& event) override {
       parent_.event_cb_count++;
       parent_.event_queue.push(event);
-      ALOGV("Event received (length = %d)", static_cast<int>(event.size()));
+      ALOGI("Event received (length = %d)", static_cast<int>(event.size()));
       return ScopedAStatus::ok();
     };
 
-    ndk::ScopedAStatus aclDataReceived(const std::vector<uint8_t>& data) {
+    ndk::ScopedAStatus aclDataReceived(
+        const std::vector<uint8_t>& data) override {
       parent_.acl_cb_count++;
       parent_.acl_queue.push(data);
       return ScopedAStatus::ok();
     };
 
-    ndk::ScopedAStatus scoDataReceived(const std::vector<uint8_t>& data) {
+    ndk::ScopedAStatus scoDataReceived(
+        const std::vector<uint8_t>& data) override {
       parent_.sco_cb_count++;
       parent_.sco_queue.push(data);
       return ScopedAStatus::ok();
     };
 
-    ndk::ScopedAStatus isoDataReceived(const std::vector<uint8_t>& data) {
+    ndk::ScopedAStatus isoDataReceived(
+        const std::vector<uint8_t>& data) override {
       parent_.iso_cb_count++;
       parent_.iso_queue.push(data);
       return ScopedAStatus::ok();
@@ -253,7 +236,8 @@
   template <class T>
   class WaitQueue {
    public:
-    WaitQueue(){};
+    WaitQueue() = default;
+    ;
 
     virtual ~WaitQueue() = default;
 
@@ -283,6 +267,14 @@
       return true;
     };
 
+    void pop() {
+      std::lock_guard<std::mutex> lock(m_);
+      if (q_.empty()) {
+        return;
+      }
+      q_.pop();
+    };
+
     bool front(T& v) {
       std::lock_guard<std::mutex> lock(m_);
       if (q_.empty()) {
@@ -329,22 +321,22 @@
 
   std::shared_ptr<IBluetoothHci> hci;
   std::shared_ptr<BluetoothHciCallbacks> hci_cb;
-  AIBinder_DeathRecipient* bluetooth_hci_death_recipient;
+  AIBinder_DeathRecipient* bluetooth_hci_death_recipient{};
   WaitQueue<std::vector<uint8_t>> event_queue;
   WaitQueue<std::vector<uint8_t>> acl_queue;
   WaitQueue<std::vector<uint8_t>> sco_queue;
   WaitQueue<std::vector<uint8_t>> iso_queue;
 
   std::promise<bool> initialized_promise;
-  int event_cb_count;
-  int sco_cb_count;
-  int acl_cb_count;
-  int iso_cb_count;
+  int event_cb_count{};
+  int sco_cb_count{};
+  int acl_cb_count{};
+  int iso_cb_count{};
 
-  int max_acl_data_packet_length;
-  int max_sco_data_packet_length;
-  int max_acl_data_packets;
-  int max_sco_data_packets;
+  int max_acl_data_packet_length{};
+  int max_sco_data_packet_length{};
+  int max_acl_data_packets{};
+  int max_sco_data_packets{};
 
   std::vector<uint16_t> sco_connection_handles;
   std::vector<uint16_t> acl_connection_handles;
@@ -355,17 +347,20 @@
   while (!event_queue.empty()) {
     std::vector<uint8_t> event;
     event_queue.front(event);
-    ASSERT_GE(event.size(),
-              static_cast<size_t>(kEventCommandCompleteStatusByte));
-    bool event_is_no_op =
-        (event[kEventCodeByte] == kEventCommandComplete) &&
-        (event[kEventCommandCompleteOpcodeLsByte] == 0x00) &&
-        (event[kEventCommandCompleteOpcodeLsByte + 1] == 0x00);
-    event_is_no_op |= (event[kEventCodeByte] == kEventCommandStatus) &&
-                      (event[kEventCommandStatusOpcodeLsByte] == 0x00) &&
-                      (event[kEventCommandStatusOpcodeLsByte + 1] == 0x00);
-    if (event_is_no_op) {
-      event_queue.pop(event);
+    auto complete_view = ::bluetooth::hci::CommandCompleteView::Create(
+        ::bluetooth::hci::EventView::Create(::bluetooth::hci::PacketView<true>(
+            std::make_shared<std::vector<uint8_t>>(event))));
+    auto status_view = ::bluetooth::hci::CommandCompleteView::Create(
+        ::bluetooth::hci::EventView::Create(::bluetooth::hci::PacketView<true>(
+            std::make_shared<std::vector<uint8_t>>(event))));
+    bool is_complete_no_op =
+        complete_view.IsValid() &&
+        complete_view.GetCommandOpCode() == ::bluetooth::hci::OpCode::NONE;
+    bool is_status_no_op =
+        status_view.IsValid() &&
+        status_view.GetCommandOpCode() == ::bluetooth::hci::OpCode::NONE;
+    if (is_complete_no_op || is_status_no_op) {
+      event_queue.pop();
     } else {
       break;
     }
@@ -377,12 +372,12 @@
   while (!acl_queue.empty()) {
     std::vector<uint8_t> acl_packet;
     acl_queue.front(acl_packet);
-    uint16_t connection_handle = acl_packet[1] & 0xF;
-    connection_handle <<= 8;
-    connection_handle |= acl_packet[0];
-    bool packet_is_no_op = connection_handle == kAclHandleQcaDebugMessage;
-    if (packet_is_no_op) {
-      acl_queue.pop(acl_packet);
+    auto acl_view =
+        ::bluetooth::hci::AclView::Create(::bluetooth::hci::PacketView<true>(
+            std::make_shared<std::vector<uint8_t>>(acl_packet)));
+    EXPECT_TRUE(acl_view.IsValid());
+    if (acl_view.GetHandle() == kAclHandleQcaDebugMessage) {
+      acl_queue.pop();
     } else {
       break;
     }
@@ -407,48 +402,49 @@
   }
 }
 
-// Wait until a command complete is received.
 void BluetoothAidlTest::wait_for_command_complete_event(
-    std::vector<uint8_t> cmd) {
+    OpCode opCode, std::vector<uint8_t>& complete_event) {
   ASSERT_NO_FATAL_FAILURE(wait_for_event());
-  std::vector<uint8_t> event;
   ASSERT_FALSE(event_queue.empty());
-  ASSERT_TRUE(event_queue.pop(event));
+  ASSERT_TRUE(event_queue.pop(complete_event));
+  auto complete_view = ::bluetooth::hci::CommandCompleteView::Create(
+      ::bluetooth::hci::EventView::Create(::bluetooth::hci::PacketView<true>(
+          std::make_shared<std::vector<uint8_t>>(complete_event))));
+  ASSERT_TRUE(complete_view.IsValid());
+  ASSERT_EQ(complete_view.GetCommandOpCode(), opCode);
+  ASSERT_EQ(complete_view.GetPayload()[0],
+            static_cast<uint8_t>(::bluetooth::hci::ErrorCode::SUCCESS));
+}
 
-  ASSERT_GT(event.size(), static_cast<size_t>(kEventCommandCompleteStatusByte));
-  ASSERT_EQ(kEventCommandComplete, event[kEventCodeByte]);
-  ASSERT_EQ(cmd[0], event[kEventCommandCompleteOpcodeLsByte]);
-  ASSERT_EQ(cmd[1], event[kEventCommandCompleteOpcodeLsByte + 1]);
-  ASSERT_EQ(kHciStatusSuccess, event[kEventCommandCompleteStatusByte]);
+void BluetoothAidlTest::wait_and_validate_command_complete_event(
+    ::bluetooth::hci::OpCode opCode) {
+  std::vector<uint8_t> complete_event;
+  ASSERT_NO_FATAL_FAILURE(
+      wait_for_command_complete_event(opCode, complete_event));
 }
 
 // Send the command to read the controller's buffer sizes.
 void BluetoothAidlTest::setBufferSizes() {
-  std::vector<uint8_t> cmd{
-      kCommandHciReadBufferSize,
-      kCommandHciReadBufferSize + sizeof(kCommandHciReadBufferSize)};
+  std::vector<uint8_t> cmd;
+  ::bluetooth::packet::BitInserter bi{cmd};
+  ::bluetooth::hci::ReadBufferSizeBuilder::Create()->Serialize(bi);
   hci->sendHciCommand(cmd);
 
   ASSERT_NO_FATAL_FAILURE(wait_for_event());
-  if (event_queue.empty()) {
-    return;
-  }
   std::vector<uint8_t> event;
   ASSERT_TRUE(event_queue.pop(event));
+  auto complete_view = ::bluetooth::hci::ReadBufferSizeCompleteView::Create(
+      ::bluetooth::hci::CommandCompleteView::Create(
+          ::bluetooth::hci::EventView::Create(
+              ::bluetooth::hci::PacketView<true>(
+                  std::make_shared<std::vector<uint8_t>>(event)))));
 
-  ASSERT_EQ(kEventCommandComplete, event[kEventCodeByte]);
-  ASSERT_EQ(cmd[0], event[kEventCommandCompleteOpcodeLsByte]);
-  ASSERT_EQ(cmd[1], event[kEventCommandCompleteOpcodeLsByte + 1]);
-  ASSERT_EQ(kHciStatusSuccess, event[kEventCommandCompleteStatusByte]);
-
-  max_acl_data_packet_length =
-      event[kEventCommandCompleteStatusByte + 1] +
-      (event[kEventCommandCompleteStatusByte + 2] << 8);
-  max_sco_data_packet_length = event[kEventCommandCompleteStatusByte + 3];
-  max_acl_data_packets = event[kEventCommandCompleteStatusByte + 4] +
-                         (event[kEventCommandCompleteStatusByte + 5] << 8);
-  max_sco_data_packets = event[kEventCommandCompleteStatusByte + 6] +
-                         (event[kEventCommandCompleteStatusByte + 7] << 8);
+  ASSERT_TRUE(complete_view.IsValid());
+  ASSERT_EQ(complete_view.GetStatus(), ::bluetooth::hci::ErrorCode::SUCCESS);
+  max_acl_data_packet_length = complete_view.GetAclDataPacketLength();
+  max_sco_data_packet_length = complete_view.GetSynchronousDataPacketLength();
+  max_acl_data_packets = complete_view.GetTotalNumAclDataPackets();
+  max_sco_data_packets = complete_view.GetTotalNumSynchronousDataPackets();
 
   ALOGD("%s: ACL max %d num %d SCO max %d num %d", __func__,
         static_cast<int>(max_acl_data_packet_length),
@@ -459,39 +455,39 @@
 
 // Enable flow control packets for SCO
 void BluetoothAidlTest::setSynchronousFlowControlEnable() {
-  std::vector<uint8_t> cmd{kCommandHciSynchronousFlowControlEnable,
-                           kCommandHciSynchronousFlowControlEnable +
-                               sizeof(kCommandHciSynchronousFlowControlEnable)};
+  std::vector<uint8_t> cmd;
+  ::bluetooth::packet::BitInserter bi{cmd};
+  ::bluetooth::hci::WriteSynchronousFlowControlEnableBuilder::Create(
+      ::bluetooth::hci::Enable::ENABLED)
+      ->Serialize(bi);
   hci->sendHciCommand(cmd);
 
-  wait_for_command_complete_event(cmd);
+  wait_and_validate_command_complete_event(
+      ::bluetooth::hci::OpCode::WRITE_SYNCHRONOUS_FLOW_CONTROL_ENABLE);
 }
 
 // Send an HCI command (in Loopback mode) and check the response.
 void BluetoothAidlTest::sendAndCheckHci(int num_packets) {
-  ThroughputLogger logger = {__func__};
-  int command_size = 0;
+  ThroughputLogger logger{__func__};
+  size_t command_size = 0;
+  char new_name[] = "John Jacob Jingleheimer Schmidt ___________________";
+  size_t new_name_length = strlen(new_name);
   for (int n = 0; n < num_packets; n++) {
-    // Send an HCI packet
-    std::vector<uint8_t> write_name{
-        kCommandHciWriteLocalName,
-        kCommandHciWriteLocalName + sizeof(kCommandHciWriteLocalName)};
-    // With a name
-    char new_name[] = "John Jacob Jingleheimer Schmidt ___________________0";
-    size_t new_name_length = strlen(new_name);
+    // The name to set is new_name
+    std::array<uint8_t, 248> name_array{};
     for (size_t i = 0; i < new_name_length; i++) {
-      write_name.push_back(static_cast<uint8_t>(new_name[i]));
+      name_array[i] = new_name[i];
     }
     // And the packet number
-    size_t i = new_name_length - 1;
-    for (int digits = n; digits > 0; digits = digits / 10, i--) {
-      write_name[i] = static_cast<uint8_t>('0' + digits % 10);
+    char number[11] = "0000000000";
+    snprintf(number, sizeof(number), "%010d", static_cast<int>(n));
+    for (size_t i = new_name_length; i < new_name_length + sizeof(number) - 1;
+         i++) {
+      name_array[new_name_length + i] = number[i];
     }
-    // And padding
-    for (size_t i = 0; i < 248 - new_name_length; i++) {
-      write_name.push_back(static_cast<uint8_t>(0));
-    }
-
+    std::vector<uint8_t> write_name;
+    ::bluetooth::packet::BitInserter bi{write_name};
+    ::bluetooth::hci::WriteLocalNameBuilder::Create(name_array)->Serialize(bi);
     hci->sendHciCommand(write_name);
 
     // Check the loopback of the HCI packet
@@ -499,28 +495,17 @@
 
     std::vector<uint8_t> event;
     ASSERT_TRUE(event_queue.pop(event));
-
-    size_t compare_length = (write_name.size() > static_cast<size_t>(0xff)
-                                 ? static_cast<size_t>(0xff)
-                                 : write_name.size());
-    ASSERT_GT(event.size(), compare_length + kEventFirstPayloadByte - 1);
-
-    ASSERT_EQ(kEventLoopbackCommand, event[kEventCodeByte]);
-    ASSERT_EQ(compare_length, event[kEventLengthByte]);
-
-    // Don't compare past the end of the event.
-    if (compare_length + kEventFirstPayloadByte > event.size()) {
-      compare_length = event.size() - kEventFirstPayloadByte;
-      ALOGE("Only comparing %d bytes", static_cast<int>(compare_length));
-    }
+    auto event_view = ::bluetooth::hci::LoopbackCommandView::Create(
+        ::bluetooth::hci::EventView::Create(::bluetooth::hci::PacketView<true>(
+            std::make_shared<std::vector<uint8_t>>(event))));
+    ASSERT_TRUE(event_view.IsValid());
+    std::vector<uint8_t> looped_back_command{event_view.GetPayload().begin(),
+                                             event_view.GetPayload().end()};
+    ASSERT_EQ(looped_back_command, write_name);
 
     if (n == num_packets - 1) {
       command_size = write_name.size();
     }
-
-    for (size_t i = 0; i < compare_length; i++) {
-      ASSERT_EQ(write_name[i], event[kEventFirstPayloadByte + i]);
-    }
   }
   logger.setTotalBytes(command_size * num_packets * 2);
 }
@@ -528,16 +513,18 @@
 // Send a SCO data packet (in Loopback mode) and check the response.
 void BluetoothAidlTest::sendAndCheckSco(int num_packets, size_t size,
                                         uint16_t handle) {
-  ThroughputLogger logger = {__func__};
+  ThroughputLogger logger{__func__};
   for (int n = 0; n < num_packets; n++) {
     // Send a SCO packet
     std::vector<uint8_t> sco_packet;
-    sco_packet.push_back(static_cast<uint8_t>(handle & 0xff));
-    sco_packet.push_back(static_cast<uint8_t>((handle & 0x0f00) >> 8));
-    sco_packet.push_back(static_cast<uint8_t>(size & 0xff));
+    std::vector<uint8_t> payload;
     for (size_t i = 0; i < size; i++) {
-      sco_packet.push_back(static_cast<uint8_t>(i + n));
+      payload.push_back(static_cast<uint8_t>(i + n));
     }
+    ::bluetooth::packet::BitInserter bi{sco_packet};
+    ::bluetooth::hci::ScoBuilder::Create(
+        handle, ::bluetooth::hci::PacketStatusFlag::CORRECTLY_RECEIVED, payload)
+        ->Serialize(bi);
     hci->sendScoData(sco_packet);
 
     // Check the loopback of the SCO packet
@@ -545,21 +532,7 @@
     ASSERT_TRUE(
         sco_queue.tryPopWithTimeout(sco_loopback, kWaitForScoDataTimeout));
 
-    ASSERT_EQ(sco_packet.size(), sco_loopback.size());
-    size_t successful_bytes = 0;
-
-    for (size_t i = 0; i < sco_packet.size(); i++) {
-      if (sco_packet[i] == sco_loopback[i]) {
-        successful_bytes = i;
-      } else {
-        ALOGE("Miscompare at %d (expected %x, got %x)", static_cast<int>(i),
-              sco_packet[i], sco_loopback[i]);
-        ALOGE("At %d (expected %x, got %x)", static_cast<int>(i + 1),
-              sco_packet[i + 1], sco_loopback[i + 1]);
-        break;
-      }
-    }
-    ASSERT_EQ(sco_packet.size(), successful_bytes + 1);
+    ASSERT_EQ(sco_packet, sco_loopback);
   }
   logger.setTotalBytes(num_packets * size * 2);
 }
@@ -567,19 +540,20 @@
 // Send an ACL data packet (in Loopback mode) and check the response.
 void BluetoothAidlTest::sendAndCheckAcl(int num_packets, size_t size,
                                         uint16_t handle) {
-  ThroughputLogger logger = {__func__};
+  ThroughputLogger logger{__func__};
   for (int n = 0; n < num_packets; n++) {
-    // Send an ACL packet
-    std::vector<uint8_t> acl_packet;
-    acl_packet.push_back(static_cast<uint8_t>(handle & 0xff));
-    acl_packet.push_back(static_cast<uint8_t>((handle & 0x0f00) >> 8) |
-                         kAclBroadcastPointToPoint |
-                         kAclPacketBoundaryFirstAutoFlushable);
-    acl_packet.push_back(static_cast<uint8_t>(size & 0xff));
-    acl_packet.push_back(static_cast<uint8_t>((size & 0xff00) >> 8));
+    // Send an ACL packet with counting data
+    auto payload = std::make_unique<::bluetooth::packet::RawBuilder>();
     for (size_t i = 0; i < size; i++) {
-      acl_packet.push_back(static_cast<uint8_t>(i + n));
+      payload->AddOctets1(static_cast<uint8_t>(i + n));
     }
+    std::vector<uint8_t> acl_packet;
+    ::bluetooth::packet::BitInserter bi{acl_packet};
+    ::bluetooth::hci::AclBuilder::Create(
+        handle,
+        ::bluetooth::hci::PacketBoundaryFlag::FIRST_AUTOMATICALLY_FLUSHABLE,
+        ::bluetooth::hci::BroadcastFlag::POINT_TO_POINT, std::move(payload))
+        ->Serialize(bi);
     hci->sendAclData(acl_packet);
 
     std::vector<uint8_t> acl_loopback;
@@ -587,21 +561,7 @@
     ASSERT_TRUE(
         acl_queue.tryPopWithTimeout(acl_loopback, kWaitForAclDataTimeout));
 
-    ASSERT_EQ(acl_packet.size(), acl_loopback.size());
-    size_t successful_bytes = 0;
-
-    for (size_t i = 0; i < acl_packet.size(); i++) {
-      if (acl_packet[i] == acl_loopback[i]) {
-        successful_bytes = i;
-      } else {
-        ALOGE("Miscompare at %d (expected %x, got %x)", static_cast<int>(i),
-              acl_packet[i], acl_loopback[i]);
-        ALOGE("At %d (expected %x, got %x)", static_cast<int>(i + 1),
-              acl_packet[i + 1], acl_loopback[i + 1]);
-        break;
-      }
-    }
-    ASSERT_EQ(acl_packet.size(), successful_bytes + 1);
+    ASSERT_EQ(acl_packet, acl_loopback);
   }
   logger.setTotalBytes(num_packets * size * 2);
 }
@@ -620,23 +580,29 @@
     }
     std::vector<uint8_t> event;
     EXPECT_TRUE(event_queue.pop(event));
-
-    EXPECT_EQ(kEventNumberOfCompletedPackets, event[kEventCodeByte]);
-    EXPECT_EQ(1, event[kEventNumberOfCompletedPacketsNumHandles]);
-
-    uint16_t event_handle = event[3] + (event[4] << 8);
-    EXPECT_EQ(handle, event_handle);
-
-    packets_processed += event[5] + (event[6] << 8);
+    auto event_view = ::bluetooth::hci::NumberOfCompletedPacketsView::Create(
+        ::bluetooth::hci::EventView::Create(::bluetooth::hci::PacketView<true>(
+            std::make_shared<std::vector<uint8_t>>(event))));
+    if (!event_view.IsValid()) {
+      ADD_FAILURE();
+      return packets_processed;
+    }
+    auto completed_packets = event_view.GetCompletedPackets();
+    for (const auto& entry : completed_packets) {
+      EXPECT_EQ(handle, entry.connection_handle_);
+      packets_processed += entry.host_num_of_completed_packets_;
+    }
   }
   return packets_processed;
 }
 
 // Send local loopback command and initialize SCO and ACL handles.
 void BluetoothAidlTest::enterLoopbackMode() {
-  std::vector<uint8_t> cmd{kCommandHciWriteLoopbackModeLocal,
-                           kCommandHciWriteLoopbackModeLocal +
-                               sizeof(kCommandHciWriteLoopbackModeLocal)};
+  std::vector<uint8_t> cmd;
+  ::bluetooth::packet::BitInserter bi{cmd};
+  ::bluetooth::hci::WriteLoopbackModeBuilder::Create(
+      bluetooth::hci::LoopbackMode::ENABLE_LOCAL)
+      ->Serialize(bi);
   hci->sendHciCommand(cmd);
 
   // Receive connection complete events with data channels
@@ -652,97 +618,128 @@
     }
     std::vector<uint8_t> event;
     ASSERT_TRUE(event_queue.pop(event));
-    ASSERT_GT(event.size(),
-              static_cast<size_t>(kEventCommandCompleteStatusByte));
-    if (event[kEventCodeByte] == kEventConnectionComplete) {
-      ASSERT_GT(event.size(),
-                static_cast<size_t>(kEventConnectionCompleteType));
-      ASSERT_EQ(event[kEventLengthByte], kEventConnectionCompleteParamLength);
-      uint8_t connection_type = event[kEventConnectionCompleteType];
+    auto event_view =
+        ::bluetooth::hci::EventView::Create(::bluetooth::hci::PacketView<true>(
+            std::make_shared<std::vector<uint8_t>>(event)));
+    ASSERT_TRUE(event_view.IsValid());
 
-      ASSERT_TRUE(connection_type == kEventConnectionCompleteTypeSco ||
-                  connection_type == kEventConnectionCompleteTypeAcl);
-
-      // Save handles
-      uint16_t handle = event[kEventConnectionCompleteHandleLsByte] |
-                        event[kEventConnectionCompleteHandleLsByte + 1] << 8;
-      if (connection_type == kEventConnectionCompleteTypeSco) {
-        sco_connection_handles.push_back(handle);
-      } else {
-        acl_connection_handles.push_back(handle);
+    if (event_view.GetEventCode() ==
+        ::bluetooth::hci::EventCode::CONNECTION_COMPLETE) {
+      auto complete_view =
+          ::bluetooth::hci::ConnectionCompleteView::Create(event_view);
+      ASSERT_TRUE(complete_view.IsValid());
+      switch (complete_view.GetLinkType()) {
+        case ::bluetooth::hci::LinkType::ACL:
+          acl_connection_handles.push_back(complete_view.GetConnectionHandle());
+          break;
+        case ::bluetooth::hci::LinkType::SCO:
+          sco_connection_handles.push_back(complete_view.GetConnectionHandle());
+          break;
+        default:
+          ASSERT_EQ(complete_view.GetLinkType(),
+                    ::bluetooth::hci::LinkType::ACL);
       }
-
-      ALOGD("Connect complete type = %d handle = %d",
-            event[kEventConnectionCompleteType], handle);
       connection_event_count++;
     } else {
-      ASSERT_EQ(kEventCommandComplete, event[kEventCodeByte]);
-      ASSERT_EQ(cmd[0], event[kEventCommandCompleteOpcodeLsByte]);
-      ASSERT_EQ(cmd[1], event[kEventCommandCompleteOpcodeLsByte + 1]);
-      ASSERT_EQ(kHciStatusSuccess, event[kEventCommandCompleteStatusByte]);
+      auto command_complete_view =
+          ::bluetooth::hci::WriteLoopbackModeCompleteView::Create(
+              ::bluetooth::hci::CommandCompleteView::Create(event_view));
+      ASSERT_TRUE(command_complete_view.IsValid());
+      ASSERT_EQ(::bluetooth::hci::ErrorCode::SUCCESS,
+                command_complete_view.GetStatus());
       command_complete_received = true;
     }
   }
 }
 
+void BluetoothAidlTest::send_and_wait_for_cmd_complete(
+    std::unique_ptr<CommandBuilder> cmd, std::vector<uint8_t>& cmd_complete) {
+  std::vector<uint8_t> cmd_bytes = cmd->SerializeToBytes();
+  hci->sendHciCommand(cmd_bytes);
+
+  auto view = CommandView::Create(
+      PacketView<true>(std::make_shared<std::vector<uint8_t>>(cmd_bytes)));
+  ASSERT_TRUE(view.IsValid());
+  ALOGI("Waiting for %s[0x%x]", OpCodeText(view.GetOpCode()).c_str(),
+        static_cast<int>(view.GetOpCode()));
+  ASSERT_NO_FATAL_FAILURE(
+      wait_for_command_complete_event(view.GetOpCode(), cmd_complete));
+}
+
 // Empty test: Initialize()/Close() are called in SetUp()/TearDown().
 TEST_P(BluetoothAidlTest, InitializeAndClose) {}
 
 // Send an HCI Reset with sendHciCommand and wait for a command complete event.
 TEST_P(BluetoothAidlTest, HciReset) {
-  std::vector<uint8_t> reset{kCommandHciReset,
-                             kCommandHciReset + sizeof(kCommandHciReset)};
+  std::vector<uint8_t> reset;
+  ::bluetooth::packet::BitInserter bi{reset};
+  ::bluetooth::hci::ResetBuilder::Create()->Serialize(bi);
   hci->sendHciCommand(reset);
 
-  wait_for_command_complete_event(reset);
+  wait_and_validate_command_complete_event(::bluetooth::hci::OpCode::RESET);
 }
 
 // Read and check the HCI version of the controller.
 TEST_P(BluetoothAidlTest, HciVersionTest) {
-  std::vector<uint8_t> cmd{kCommandHciReadLocalVersionInformation,
-                           kCommandHciReadLocalVersionInformation +
-                               sizeof(kCommandHciReadLocalVersionInformation)};
+  std::vector<uint8_t> cmd;
+  ::bluetooth::packet::BitInserter bi{cmd};
+  ::bluetooth::hci::ReadLocalVersionInformationBuilder::Create()->Serialize(bi);
   hci->sendHciCommand(cmd);
 
   ASSERT_NO_FATAL_FAILURE(wait_for_event());
 
   std::vector<uint8_t> event;
   ASSERT_TRUE(event_queue.pop(event));
-  ASSERT_GT(event.size(), static_cast<size_t>(kEventLocalLmpVersionByte));
-
-  ASSERT_EQ(kEventCommandComplete, event[kEventCodeByte]);
-  ASSERT_EQ(cmd[0], event[kEventCommandCompleteOpcodeLsByte]);
-  ASSERT_EQ(cmd[1], event[kEventCommandCompleteOpcodeLsByte + 1]);
-  ASSERT_EQ(kHciStatusSuccess, event[kEventCommandCompleteStatusByte]);
-
-  ASSERT_LE(kHciMinimumHciVersion, event[kEventLocalHciVersionByte]);
-  ASSERT_LE(kHciMinimumLmpVersion, event[kEventLocalLmpVersionByte]);
+  auto complete_view =
+      ::bluetooth::hci::ReadLocalVersionInformationCompleteView::Create(
+          ::bluetooth::hci::CommandCompleteView::Create(
+              ::bluetooth::hci::EventView::Create(
+                  ::bluetooth::hci::PacketView<true>(
+                      std::make_shared<std::vector<uint8_t>>(event)))));
+  ASSERT_TRUE(complete_view.IsValid());
+  ASSERT_EQ(::bluetooth::hci::ErrorCode::SUCCESS, complete_view.GetStatus());
+  auto version = complete_view.GetLocalVersionInformation();
+  ASSERT_LE(::bluetooth::hci::HciVersion::V_3_0, version.hci_version_);
+  ASSERT_LE(::bluetooth::hci::LmpVersion::V_3_0, version.lmp_version_);
 }
 
 // Send an unknown HCI command and wait for the error message.
 TEST_P(BluetoothAidlTest, HciUnknownCommand) {
-  std::vector<uint8_t> cmd{
-      kCommandHciShouldBeUnknown,
-      kCommandHciShouldBeUnknown + sizeof(kCommandHciShouldBeUnknown)};
+  std::vector<uint8_t> cmd;
+  ::bluetooth::packet::BitInserter bi{cmd};
+  ::bluetooth::hci::CommandBuilder::Create(
+      static_cast<::bluetooth::hci::OpCode>(0x3cff),
+      std::make_unique<::bluetooth::packet::RawBuilder>())
+      ->Serialize(bi);
   hci->sendHciCommand(cmd);
 
   ASSERT_NO_FATAL_FAILURE(wait_for_event());
 
   std::vector<uint8_t> event;
   ASSERT_TRUE(event_queue.pop(event));
+  auto event_view =
+      ::bluetooth::hci::EventView::Create(::bluetooth::hci::PacketView<true>(
+          std::make_shared<std::vector<uint8_t>>(event)));
+  ASSERT_TRUE(event_view.IsValid());
 
-  ASSERT_GT(event.size(), static_cast<size_t>(kEventCommandCompleteStatusByte));
-  if (event[kEventCodeByte] == kEventCommandComplete) {
-    ASSERT_EQ(cmd[0], event[kEventCommandCompleteOpcodeLsByte]);
-    ASSERT_EQ(cmd[1], event[kEventCommandCompleteOpcodeLsByte + 1]);
-    ASSERT_EQ(kHciStatusUnknownHciCommand,
-              event[kEventCommandCompleteStatusByte]);
-  } else {
-    ASSERT_EQ(kEventCommandStatus, event[kEventCodeByte]);
-    ASSERT_EQ(cmd[0], event[kEventCommandStatusOpcodeLsByte]);
-    ASSERT_EQ(cmd[1], event[kEventCommandStatusOpcodeLsByte + 1]);
-    ASSERT_EQ(kHciStatusUnknownHciCommand,
-              event[kEventCommandStatusStatusByte]);
+  switch (event_view.GetEventCode()) {
+    case ::bluetooth::hci::EventCode::COMMAND_COMPLETE: {
+      auto command_complete =
+          ::bluetooth::hci::CommandCompleteView::Create(event_view);
+      ASSERT_TRUE(command_complete.IsValid());
+      ASSERT_EQ(command_complete.GetPayload()[0],
+                static_cast<uint8_t>(
+                    ::bluetooth::hci::ErrorCode::UNKNOWN_HCI_COMMAND));
+    } break;
+    case ::bluetooth::hci::EventCode::COMMAND_STATUS: {
+      auto command_status =
+          ::bluetooth::hci::CommandStatusView::Create(event_view);
+      ASSERT_TRUE(command_status.IsValid());
+      ASSERT_EQ(command_status.GetStatus(),
+                ::bluetooth::hci::ErrorCode::UNKNOWN_HCI_COMMAND);
+    } break;
+    default:
+      ADD_FAILURE();
   }
 }
 
@@ -851,20 +848,24 @@
 
 // Set all bits in the event mask
 TEST_P(BluetoothAidlTest, SetEventMask) {
-  std::vector<uint8_t> set_event_mask{
-      0x01, 0x0c, 0x08 /*parameter bytes*/, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-      0xff, 0xff};
-  hci->sendHciCommand({set_event_mask});
-  wait_for_command_complete_event(set_event_mask);
+  std::vector<uint8_t> cmd;
+  ::bluetooth::packet::BitInserter bi{cmd};
+  uint64_t full_mask = UINT64_MAX;
+  ::bluetooth::hci::SetEventMaskBuilder::Create(full_mask)->Serialize(bi);
+  hci->sendHciCommand(cmd);
+  wait_and_validate_command_complete_event(
+      ::bluetooth::hci::OpCode::SET_EVENT_MASK);
 }
 
 // Set all bits in the LE event mask
 TEST_P(BluetoothAidlTest, SetLeEventMask) {
-  std::vector<uint8_t> set_event_mask{
-      0x20, 0x0c, 0x08 /*parameter bytes*/, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-      0xff, 0xff};
-  hci->sendHciCommand({set_event_mask});
-  wait_for_command_complete_event(set_event_mask);
+  std::vector<uint8_t> cmd;
+  ::bluetooth::packet::BitInserter bi{cmd};
+  uint64_t full_mask = UINT64_MAX;
+  ::bluetooth::hci::LeSetEventMaskBuilder::Create(full_mask)->Serialize(bi);
+  hci->sendHciCommand(cmd);
+  wait_and_validate_command_complete_event(
+      ::bluetooth::hci::OpCode::LE_SET_EVENT_MASK);
 }
 
 // Call initialize twice, second one should fail.
@@ -872,28 +873,32 @@
   class SecondCb
       : public aidl::android::hardware::bluetooth::BnBluetoothHciCallbacks {
    public:
-    ndk::ScopedAStatus initializationComplete(Status status) {
+    ndk::ScopedAStatus initializationComplete(Status status) override {
       EXPECT_EQ(status, Status::ALREADY_INITIALIZED);
       init_promise.set_value();
       return ScopedAStatus::ok();
     };
 
-    ndk::ScopedAStatus hciEventReceived(const std::vector<uint8_t>& /*event*/) {
+    ndk::ScopedAStatus hciEventReceived(
+        const std::vector<uint8_t>& /*event*/) override {
       ADD_FAILURE();
       return ScopedAStatus::ok();
     };
 
-    ndk::ScopedAStatus aclDataReceived(const std::vector<uint8_t>& /*data*/) {
+    ndk::ScopedAStatus aclDataReceived(
+        const std::vector<uint8_t>& /*data*/) override {
       ADD_FAILURE();
       return ScopedAStatus::ok();
     };
 
-    ndk::ScopedAStatus scoDataReceived(const std::vector<uint8_t>& /*data*/) {
+    ndk::ScopedAStatus scoDataReceived(
+        const std::vector<uint8_t>& /*data*/) override {
       ADD_FAILURE();
       return ScopedAStatus::ok();
     };
 
-    ndk::ScopedAStatus isoDataReceived(const std::vector<uint8_t>& /*data*/) {
+    ndk::ScopedAStatus isoDataReceived(
+        const std::vector<uint8_t>& /*data*/) override {
       ADD_FAILURE();
       return ScopedAStatus::ok();
     };
@@ -909,6 +914,66 @@
   ASSERT_EQ(status, std::future_status::ready);
 }
 
+TEST_P(BluetoothAidlTest, Cdd_C_12_1_Bluetooth5Requirements) {
+  std::vector<uint8_t> version_event;
+  send_and_wait_for_cmd_complete(ReadLocalVersionInformationBuilder::Create(),
+                                 version_event);
+  auto version_view = ReadLocalVersionInformationCompleteView::Create(
+      CommandCompleteView::Create(EventView::Create(PacketView<true>(
+          std::make_shared<std::vector<uint8_t>>(version_event)))));
+  ASSERT_TRUE(version_view.IsValid());
+  ASSERT_EQ(::bluetooth::hci::ErrorCode::SUCCESS, version_view.GetStatus());
+  auto version = version_view.GetLocalVersionInformation();
+  if (version.hci_version_ < ::bluetooth::hci::HciVersion::V_5_0) {
+    // This test does not apply to controllers below 5.0
+    return;
+  };
+  // When HCI version is 5.0, LMP version must also be at least 5.0
+  ASSERT_GE(static_cast<int>(version.lmp_version_),
+            static_cast<int>(version.hci_version_));
+
+  std::vector<uint8_t> le_features_event;
+  send_and_wait_for_cmd_complete(LeReadLocalSupportedFeaturesBuilder::Create(),
+                                 le_features_event);
+  auto le_features_view = LeReadLocalSupportedFeaturesCompleteView::Create(
+      CommandCompleteView::Create(EventView::Create(PacketView<true>(
+          std::make_shared<std::vector<uint8_t>>(le_features_event)))));
+  ASSERT_TRUE(le_features_view.IsValid());
+  ASSERT_EQ(::bluetooth::hci::ErrorCode::SUCCESS, le_features_view.GetStatus());
+  auto le_features = le_features_view.GetLeFeatures();
+  ASSERT_TRUE(le_features & static_cast<uint64_t>(LLFeaturesBits::LL_PRIVACY));
+  ASSERT_TRUE(le_features & static_cast<uint64_t>(LLFeaturesBits::LE_2M_PHY));
+  ASSERT_TRUE(le_features &
+              static_cast<uint64_t>(LLFeaturesBits::LE_CODED_PHY));
+  ASSERT_TRUE(le_features &
+              static_cast<uint64_t>(LLFeaturesBits::LE_EXTENDED_ADVERTISING));
+
+  std::vector<uint8_t> num_adv_set_event;
+  send_and_wait_for_cmd_complete(
+      LeReadNumberOfSupportedAdvertisingSetsBuilder::Create(),
+      num_adv_set_event);
+  auto num_adv_set_view =
+      LeReadNumberOfSupportedAdvertisingSetsCompleteView::Create(
+          CommandCompleteView::Create(EventView::Create(PacketView<true>(
+              std::make_shared<std::vector<uint8_t>>(num_adv_set_event)))));
+  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);
+
+  std::vector<uint8_t> num_resolving_list_event;
+  send_and_wait_for_cmd_complete(LeReadResolvingListSizeBuilder::Create(),
+                                 num_resolving_list_event);
+  auto num_resolving_list_view = LeReadResolvingListSizeCompleteView::Create(
+      CommandCompleteView::Create(EventView::Create(PacketView<true>(
+          std::make_shared<std::vector<uint8_t>>(num_resolving_list_event)))));
+  ASSERT_TRUE(num_resolving_list_view.IsValid());
+  ASSERT_EQ(::bluetooth::hci::ErrorCode::SUCCESS,
+            num_resolving_list_view.GetStatus());
+  auto num_resolving_list = num_resolving_list_view.GetResolvingListSize();
+  ASSERT_GE(num_resolving_list, kMinLeResolvingListForBt5);
+}
+
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BluetoothAidlTest);
 INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAidlTest,
                          testing::ValuesIn(android::getAidlHalInstanceNames(
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacCapabilities.aidl
index 899b8ca..e548cd3 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacCapabilities.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacCapabilities.aidl
@@ -39,4 +39,5 @@
   android.hardware.bluetooth.audio.ChannelMode[] channelMode;
   boolean variableBitRateSupported;
   byte[] bitsPerSample;
+  boolean adaptiveBitRateSupported;
 }
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacConfiguration.aidl
index 6adef6d..29ab8ce 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacConfiguration.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacConfiguration.aidl
@@ -39,4 +39,5 @@
   android.hardware.bluetooth.audio.ChannelMode channelMode;
   boolean variableBitRateEnabled;
   byte bitsPerSample;
+  boolean adaptiveBitRateSupported;
 }
diff --git a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/Signature.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxAdaptiveLeCapabilities.aidl
similarity index 82%
copy from security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/Signature.aidl
copy to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxAdaptiveLeCapabilities.aidl
index 294170d..c9d3cde 100644
--- a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/Signature.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxAdaptiveLeCapabilities.aidl
@@ -1,11 +1,11 @@
 /*
- * Copyright 2021, The Android Open Source Project
+ * Copyright 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
+ *      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,
@@ -31,9 +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.security.dice;
-/* @hide */
-@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability
-parcelable Signature {
-  byte[] data;
+package android.hardware.bluetooth.audio;
+@VintfStability
+parcelable AptxAdaptiveLeCapabilities {
+  byte[] pcmBitDepth;
+  int[] samplingFrequencyHz;
+  int[] frameDurationUs;
+  int[] octetsPerFrame;
+  byte[] blocksPerSdu;
 }
diff --git a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/Signature.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxAdaptiveLeConfiguration.aidl
similarity index 82%
rename from security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/Signature.aidl
rename to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxAdaptiveLeConfiguration.aidl
index 294170d..76df4ed 100644
--- a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/Signature.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxAdaptiveLeConfiguration.aidl
@@ -1,11 +1,11 @@
 /*
- * Copyright 2021, The Android Open Source Project
+ * Copyright 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
+ *      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,
@@ -31,9 +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.security.dice;
-/* @hide */
-@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability
-parcelable Signature {
-  byte[] data;
+package android.hardware.bluetooth.audio;
+@VintfStability
+parcelable AptxAdaptiveLeConfiguration {
+  byte pcmBitDepth;
+  int samplingFrequencyHz;
+  int frameDurationUs;
+  int octetsPerFrame;
+  byte blocksPerSdu;
+  int codecMode;
 }
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecType.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecType.aidl
index d1723e6..3e204f9 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecType.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecType.aidl
@@ -44,4 +44,6 @@
   VENDOR = 7,
   APTX_ADAPTIVE = 8,
   OPUS = 9,
+  APTX_ADAPTIVE_LE = 10,
+  APTX_ADAPTIVE_LEX = 11,
 }
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LatencyMode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LatencyMode.aidl
index 5583679..1140f9e 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LatencyMode.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LatencyMode.aidl
@@ -34,7 +34,9 @@
 package android.hardware.bluetooth.audio;
 @Backing(type="int") @VintfStability
 enum LatencyMode {
-  UNKNOWN = 0,
-  LOW_LATENCY = 1,
-  FREE = 2,
+  UNKNOWN,
+  LOW_LATENCY,
+  FREE,
+  DYNAMIC_SPATIAL_AUDIO_SOFTWARE,
+  DYNAMIC_SPATIAL_AUDIO_HARDWARE,
 }
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl
index 7d53b0c..2945710 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl
@@ -41,5 +41,6 @@
     char streamHandle;
     int audioChannelAllocation;
     android.hardware.bluetooth.audio.LeAudioCodecConfiguration leAudioCodecConfig;
+    char pcmStreamId;
   }
 }
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl
index bb3d7e4..031ee67 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl
@@ -36,6 +36,7 @@
 union LeAudioCodecConfiguration {
   android.hardware.bluetooth.audio.Lc3Configuration lc3Config;
   android.hardware.bluetooth.audio.LeAudioCodecConfiguration.VendorConfiguration vendorConfig;
+  android.hardware.bluetooth.audio.AptxAdaptiveLeConfiguration aptxAdaptiveLeConfig;
   @VintfStability
   parcelable VendorConfiguration {
     ParcelableHolder extension;
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
index edb6795..2d9ebae 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
@@ -38,9 +38,11 @@
   android.hardware.bluetooth.audio.LeAudioConfiguration.StreamMap[] streamMap;
   int peerDelayUs;
   android.hardware.bluetooth.audio.LeAudioCodecConfiguration leAudioCodecConfig;
+  @nullable byte[] vendorSpecificMetadata;
   @VintfStability
   parcelable StreamMap {
     char streamHandle;
     int audioChannelAllocation;
+    boolean isStreamActive;
   }
 }
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/OpusCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/OpusCapabilities.aidl
index 2781893..2c04b0f 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/OpusCapabilities.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/OpusCapabilities.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright 2021 The Android Open Source Project
+ * Copyright 2022 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/OpusConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/OpusConfiguration.aidl
index 067690e..811d32a 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/OpusConfiguration.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/OpusConfiguration.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright 2021 The Android Open Source Project
+ * Copyright 2022 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/UnicastCapability.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/UnicastCapability.aidl
index 130fef9..894a2f3 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/UnicastCapability.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/UnicastCapability.aidl
@@ -47,5 +47,6 @@
   union LeAudioCodecCapabilities {
     android.hardware.bluetooth.audio.Lc3Capabilities lc3Capabilities;
     android.hardware.bluetooth.audio.UnicastCapability.VendorCapabilities vendorCapabillities;
+    android.hardware.bluetooth.audio.AptxAdaptiveLeCapabilities aptxAdaptiveLeCapabilities;
   }
 }
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacCapabilities.aidl
index c4153e9..d7d67de 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacCapabilities.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacCapabilities.aidl
@@ -29,4 +29,5 @@
     ChannelMode[] channelMode;
     boolean variableBitRateSupported;
     byte[] bitsPerSample;
+    boolean adaptiveBitRateSupported;
 }
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacConfiguration.aidl
index 30338e7..34998cd 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacConfiguration.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacConfiguration.aidl
@@ -29,4 +29,5 @@
     ChannelMode channelMode;
     boolean variableBitRateEnabled;
     byte bitsPerSample;
+    boolean adaptiveBitRateSupported;
 }
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxAdaptiveLeCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxAdaptiveLeCapabilities.aidl
new file mode 100644
index 0000000..b3fe71c
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxAdaptiveLeCapabilities.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright 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.bluetooth.audio;
+
+/**
+ * Used for Hardware Encoding/Decoding Aptx Adaptive LE codec capabilities.
+ */
+@VintfStability
+parcelable AptxAdaptiveLeCapabilities {
+    /*
+     * PCM is Input for encoder, Output for decoder
+     */
+    byte[] pcmBitDepth;
+    /*
+     * codec-specific parameters
+     */
+    int[] samplingFrequencyHz;
+    /*
+     * FrameDuration based on microseconds.
+     */
+    int[] frameDurationUs;
+    /*
+     * length in octets of a codec frame
+     */
+    int[] octetsPerFrame;
+    /*
+     * Number of blocks of codec frames per single SDU (Service Data Unit)
+     */
+    byte[] blocksPerSdu;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxAdaptiveLeConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxAdaptiveLeConfiguration.aidl
new file mode 100644
index 0000000..060d5d5
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxAdaptiveLeConfiguration.aidl
@@ -0,0 +1,51 @@
+/*
+ * Copyright 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.bluetooth.audio;
+
+/**
+ * Used for Hardware Encoding/Decoding Aptx Adaptive LE/LEX codec configuration.
+ */
+@VintfStability
+parcelable AptxAdaptiveLeConfiguration {
+    /*
+     * PCM is Input for encoder, Output for decoder
+     */
+    byte pcmBitDepth;
+    /*
+     * codec-specific parameters
+     */
+    int samplingFrequencyHz;
+    /*
+     * FrameDuration based on microseconds.
+     */
+    int frameDurationUs;
+    /*
+     * length in octets of a codec frame
+     */
+    int octetsPerFrame;
+    /*
+     * Number of blocks of codec frames per single SDU (Service Data Unit)
+     */
+    byte blocksPerSdu;
+    /*
+     * Currently being used for Aptx Adaptive LEX,
+     * RFU for Aptx Adaptive LE
+     * Based on this value, the codec will determine the quality of stream
+     * during initialization for Music/Game
+     */
+    int codecMode;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecType.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecType.aidl
index 3499155..1d8acdf 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecType.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecType.aidl
@@ -29,4 +29,6 @@
     VENDOR,
     APTX_ADAPTIVE,
     OPUS,
+    APTX_ADAPTIVE_LE,
+    APTX_ADAPTIVE_LEX,
 }
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LatencyMode.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LatencyMode.aidl
index 0c354f7..ec181c1 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LatencyMode.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LatencyMode.aidl
@@ -22,4 +22,6 @@
     UNKNOWN,
     LOW_LATENCY,
     FREE,
+    DYNAMIC_SPATIAL_AUDIO_SOFTWARE,
+    DYNAMIC_SPATIAL_AUDIO_HARDWARE
 }
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl
index e9a1a0c..16503fb 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl
@@ -35,6 +35,10 @@
          */
         int audioChannelAllocation;
         LeAudioCodecConfiguration leAudioCodecConfig;
+        /*
+         * Pcm stream id to identify the source for given streamHandle.
+         */
+        char pcmStreamId;
     }
     CodecType codecType;
     BroadcastStreamMap[] streamMap;
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl
index 421eeb2..7ce6ff3 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl
@@ -17,6 +17,7 @@
 package android.hardware.bluetooth.audio;
 
 import android.hardware.bluetooth.audio.Lc3Configuration;
+import android.hardware.bluetooth.audio.AptxAdaptiveLeConfiguration;
 
 @VintfStability
 union LeAudioCodecConfiguration {
@@ -26,4 +27,5 @@
     }
     Lc3Configuration lc3Config;
     VendorConfiguration vendorConfig;
+    AptxAdaptiveLeConfiguration aptxAdaptiveLeConfig;
 }
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
index 0d1e3de..7302aea 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
@@ -35,9 +35,25 @@
          * Audio Location assigned number.
          */
         int audioChannelAllocation;
+        /*
+         * The stream handle status
+         */
+        boolean isStreamActive;
     }
     CodecType codecType;
     StreamMap[] streamMap;
     int peerDelayUs;
     LeAudioCodecConfiguration leAudioCodecConfig;
+
+    /*
+     * Bluetooth LTV format for vendor metadata is defined in the
+     * Section 6.12.6.9 Vendor_Specific of Bluetooth Assigned Numbers
+     *
+     * Octet 0 = Length
+     * Octet 1 = Type (Vendor specific - 0xFF)
+     * Octet 2-3 = Company_ID
+     * Company ID values are defined in Bluetooth Assigned Numbers.
+     * Octet 4 onwards = Vendor specific Metadata
+     */
+    @nullable byte[] vendorSpecificMetadata;
 }
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/UnicastCapability.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/UnicastCapability.aidl
index f8a924a..07688a7 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/UnicastCapability.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/UnicastCapability.aidl
@@ -19,6 +19,7 @@
 import android.hardware.bluetooth.audio.AudioLocation;
 import android.hardware.bluetooth.audio.CodecType;
 import android.hardware.bluetooth.audio.Lc3Capabilities;
+import android.hardware.bluetooth.audio.AptxAdaptiveLeCapabilities;
 
 /**
  * Used to specify the le audio unicast codec capabilities for hardware offload.
@@ -33,6 +34,7 @@
     union LeAudioCodecCapabilities {
         Lc3Capabilities lc3Capabilities;
         VendorCapabilities vendorCapabillities;
+        AptxAdaptiveLeCapabilities aptxAdaptiveLeCapabilities;
     }
     CodecType codecType;
     AudioLocation supportedChannel;
diff --git a/bluetooth/audio/aidl/default/Android.bp b/bluetooth/audio/aidl/default/Android.bp
index cbf23dc..e4c2844 100644
--- a/bluetooth/audio/aidl/default/Android.bp
+++ b/bluetooth/audio/aidl/default/Android.bp
@@ -29,7 +29,7 @@
         "libcutils",
         "libfmq",
         "liblog",
-        "android.hardware.bluetooth.audio-V2-ndk",
+        "android.hardware.bluetooth.audio-V3-ndk",
         "libbluetooth_audio_session_aidl",
     ],
 }
diff --git a/bluetooth/audio/aidl/default/bluetooth_audio.xml b/bluetooth/audio/aidl/default/bluetooth_audio.xml
index c4b1872..c0bc55e 100644
--- a/bluetooth/audio/aidl/default/bluetooth_audio.xml
+++ b/bluetooth/audio/aidl/default/bluetooth_audio.xml
@@ -1,7 +1,7 @@
 <manifest version="1.0" type="device">
     <hal format="aidl">
         <name>android.hardware.bluetooth.audio</name>
-        <version>2</version>
+        <version>3</version>
         <fqname>IBluetoothAudioProviderFactory/default</fqname>
     </hal>
 </manifest>
diff --git a/bluetooth/audio/aidl/vts/Android.bp b/bluetooth/audio/aidl/vts/Android.bp
index 3aed1b3..e03fb58 100644
--- a/bluetooth/audio/aidl/vts/Android.bp
+++ b/bluetooth/audio/aidl/vts/Android.bp
@@ -17,7 +17,7 @@
     srcs: ["VtsHalBluetoothAudioTargetTest.cpp"],
     shared_libs: [
         "android.hardware.audio.common-V1-ndk",
-        "android.hardware.bluetooth.audio-V2-ndk",
+        "android.hardware.bluetooth.audio-V3-ndk",
         "android.hardware.common-V2-ndk",
         "android.hardware.common.fmq-V1-ndk",
         "libbase",
diff --git a/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp b/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
index 128ef61..858fa38 100644
--- a/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
+++ b/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
@@ -35,6 +35,8 @@
 using aidl::android::hardware::audio::common::SourceMetadata;
 using aidl::android::hardware::bluetooth::audio::AacCapabilities;
 using aidl::android::hardware::bluetooth::audio::AacConfiguration;
+using aidl::android::hardware::bluetooth::audio::AptxAdaptiveLeCapabilities;
+using aidl::android::hardware::bluetooth::audio::AptxAdaptiveLeConfiguration;
 using aidl::android::hardware::bluetooth::audio::AptxCapabilities;
 using aidl::android::hardware::bluetooth::audio::AptxConfiguration;
 using aidl::android::hardware::bluetooth::audio::AudioCapabilities;
@@ -87,10 +89,6 @@
 static constexpr int8_t a2dp_bits_per_samples[] = {0, 16, 24, 32};
 static constexpr ChannelMode a2dp_channel_modes[] = {
     ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
-static constexpr CodecType a2dp_codec_types[] = {
-    CodecType::UNKNOWN, CodecType::SBC,          CodecType::AAC,
-    CodecType::APTX,    CodecType::APTX_HD,      CodecType::LDAC,
-    CodecType::LC3,     CodecType::APTX_ADAPTIVE};
 static std::vector<LatencyMode> latency_modes = {LatencyMode::FREE};
 // Helpers
 
@@ -238,6 +236,8 @@
                         CodecCapabilities::Capabilities::opusCapabilities);
               break;
             case CodecType::APTX_ADAPTIVE:
+            case CodecType::APTX_ADAPTIVE_LE:
+            case CodecType::APTX_ADAPTIVE_LEX:
             case CodecType::LC3:
             case CodecType::VENDOR:
             case CodecType::UNKNOWN:
@@ -387,6 +387,11 @@
       variable_bit_rate_enableds.push_back(true);
     }
 
+    std::vector<bool> adaptive_bit_rate_supporteds = {false};
+    if (aac_capability.adaptiveBitRateSupported) {
+      adaptive_bit_rate_supporteds.push_back(true);
+    }
+
     // combine those parameters into one list of
     // CodecConfiguration::CodecSpecific
     for (auto object_type : aac_capability.objectType) {
@@ -394,14 +399,18 @@
         for (auto channel_mode : aac_capability.channelMode) {
           for (int8_t bits_per_sample : aac_capability.bitsPerSample) {
             for (auto variable_bit_rate_enabled : variable_bit_rate_enableds) {
-              AacConfiguration aac_data{
-                  .objectType = object_type,
-                  .sampleRateHz = sample_rate,
-                  .channelMode = channel_mode,
-                  .variableBitRateEnabled = variable_bit_rate_enabled,
-                  .bitsPerSample = bits_per_sample};
-              aac_codec_specifics.push_back(
-                  CodecConfiguration::CodecSpecific(aac_data));
+              for (auto adaptive_bit_rate_supported :
+                   adaptive_bit_rate_supporteds) {
+                AacConfiguration aac_data{
+                    .objectType = object_type,
+                    .sampleRateHz = sample_rate,
+                    .channelMode = channel_mode,
+                    .variableBitRateEnabled = variable_bit_rate_enabled,
+                    .bitsPerSample = bits_per_sample,
+                    .adaptiveBitRateSupported = adaptive_bit_rate_supported};
+                aac_codec_specifics.push_back(
+                    CodecConfiguration::CodecSpecific(aac_data));
+              }
             }
           }
         }
@@ -845,7 +854,7 @@
   ASSERT_NE(audio_provider_, nullptr);
 
   std::vector<CodecConfiguration::CodecSpecific> codec_specifics;
-  for (auto codec_type : a2dp_codec_types) {
+  for (auto codec_type : ndk::enum_range<CodecType>()) {
     switch (codec_type) {
       case CodecType::SBC:
         codec_specifics = GetSbcCodecSpecificSupportedList(false);
@@ -866,6 +875,8 @@
         codec_specifics = GetOpusCodecSpecificSupportedList(false);
         continue;
       case CodecType::APTX_ADAPTIVE:
+      case CodecType::APTX_ADAPTIVE_LE:
+      case CodecType::APTX_ADAPTIVE_LEX:
       case CodecType::LC3:
       case CodecType::VENDOR:
       case CodecType::UNKNOWN:
@@ -1192,6 +1203,73 @@
     return le_audio_codec_configs;
   }
 
+  static constexpr int32_t apx_adaptive_le_config_codec_modes[] = {0, 1, 2, 3};
+
+  std::vector<AptxAdaptiveLeConfiguration>
+  GetUnicastAptxAdaptiveLeSupportedList(bool decoding, bool supported,
+                                        bool is_le_extended) {
+    std::vector<AptxAdaptiveLeConfiguration> le_audio_codec_configs;
+    if (!supported) {
+      AptxAdaptiveLeConfiguration aptx_adaptive_le_config{
+          .pcmBitDepth = 0, .samplingFrequencyHz = 0};
+      le_audio_codec_configs.push_back(aptx_adaptive_le_config);
+      return le_audio_codec_configs;
+    }
+
+    // There might be more than one LeAudioCodecCapabilitiesSetting
+    std::vector<AptxAdaptiveLeCapabilities> aptx_adaptive_le_capabilities;
+    for (auto& capability : temp_provider_capabilities_) {
+      if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
+        continue;
+      }
+      auto& le_audio_capability =
+          capability.get<AudioCapabilities::leAudioCapabilities>();
+      auto& unicast_capability =
+          decoding ? le_audio_capability.unicastDecodeCapability
+                   : le_audio_capability.unicastEncodeCapability;
+      if ((!is_le_extended &&
+           unicast_capability.codecType != CodecType::APTX_ADAPTIVE_LE) ||
+          (is_le_extended &&
+           unicast_capability.codecType != CodecType::APTX_ADAPTIVE_LEX)) {
+        continue;
+      }
+
+      auto& aptx_adaptive_le_capability =
+          unicast_capability.leAudioCodecCapabilities
+              .get<UnicastCapability::LeAudioCodecCapabilities::
+                       aptxAdaptiveLeCapabilities>();
+
+      aptx_adaptive_le_capabilities.push_back(aptx_adaptive_le_capability);
+    }
+
+    for (auto& aptx_adaptive_le_capability : aptx_adaptive_le_capabilities) {
+      for (int32_t samplingFrequencyHz :
+           aptx_adaptive_le_capability.samplingFrequencyHz) {
+        for (int32_t frameDurationUs :
+             aptx_adaptive_le_capability.frameDurationUs) {
+          for (int32_t octetsPerFrame :
+               aptx_adaptive_le_capability.octetsPerFrame) {
+            for (int8_t blocksPerSdu :
+                 aptx_adaptive_le_capability.blocksPerSdu) {
+              for (int32_t codecMode : apx_adaptive_le_config_codec_modes) {
+                AptxAdaptiveLeConfiguration aptx_adaptive_le_config = {
+                    .samplingFrequencyHz = samplingFrequencyHz,
+                    .frameDurationUs = frameDurationUs,
+                    .octetsPerFrame = octetsPerFrame,
+                    .blocksPerSdu = blocksPerSdu,
+                    .codecMode = codecMode,
+                };
+                le_audio_codec_configs.push_back(aptx_adaptive_le_config);
+              }
+            }
+          }
+        }
+      }
+    }
+
+    return le_audio_codec_configs;
+  }
+
   LeAudioCodecCapabilitiesSetting temp_le_audio_capabilities_;
 };
 
@@ -1268,6 +1346,87 @@
   }
 }
 
+static std::vector<uint8_t> vendorMetadata = {0x0B,  // Length
+                                              0xFF,  // Type: Vendor-specific
+                                              0x0A, 0x00,  // Company_ID
+                                              0x01, 0x02, 0x03, 0x04,  // Data
+                                              0x05, 0x06, 0x07, 0x08};
+
+/**
+ * Test whether each provider of type
+ * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
+ * stopped with Unicast hardware encoding config
+ */
+TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
+       StartAndEndLeAudioOutputSessionWithAptxAdaptiveLeUnicastConfig) {
+  if (!IsOffloadOutputSupported()) {
+    return;
+  }
+  for (auto codec_type :
+       {CodecType::APTX_ADAPTIVE_LE, CodecType::APTX_ADAPTIVE_LEX}) {
+    bool is_le_extended = (codec_type == CodecType::APTX_ADAPTIVE_LEX);
+    auto aptx_adaptive_le_codec_configs =
+        GetUnicastAptxAdaptiveLeSupportedList(false, true, is_le_extended);
+    LeAudioConfiguration le_audio_config = {
+        .codecType = codec_type,
+        .peerDelayUs = 0,
+        .vendorSpecificMetadata = vendorMetadata,
+    };
+
+    for (auto& aptx_adaptive_le_config : aptx_adaptive_le_codec_configs) {
+      le_audio_config.leAudioCodecConfig
+          .set<LeAudioCodecConfiguration::aptxAdaptiveLeConfig>(
+              aptx_adaptive_le_config);
+      DataMQDesc mq_desc;
+      auto aidl_retval = audio_provider_->startSession(
+          audio_port_, AudioConfiguration(le_audio_config), latency_modes,
+          &mq_desc);
+
+      ASSERT_TRUE(aidl_retval.isOk());
+      EXPECT_TRUE(audio_provider_->endSession().isOk());
+    }
+  }
+}
+
+/**
+ * Test whether each provider of type
+ * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
+ * stopped with Unicast hardware encoding config
+ */
+TEST_P(
+    BluetoothAudioProviderLeAudioOutputHardwareAidl,
+    BluetoothAudioProviderLeAudioOutputHardwareAidl_StartAndEndLeAudioOutputSessionWithInvalidAptxAdaptiveLeAudioConfiguration) {
+  if (!IsOffloadOutputSupported()) {
+    return;
+  }
+
+  for (auto codec_type :
+       {CodecType::APTX_ADAPTIVE_LE, CodecType::APTX_ADAPTIVE_LEX}) {
+    bool is_le_extended = (codec_type == CodecType::APTX_ADAPTIVE_LEX);
+    auto aptx_adaptive_le_codec_configs =
+        GetUnicastAptxAdaptiveLeSupportedList(false, true, is_le_extended);
+    LeAudioConfiguration le_audio_config = {
+        .codecType = codec_type,
+        .peerDelayUs = 0,
+        .vendorSpecificMetadata = vendorMetadata,
+    };
+
+    for (auto& aptx_adaptive_le_config : aptx_adaptive_le_codec_configs) {
+      le_audio_config.leAudioCodecConfig
+          .set<LeAudioCodecConfiguration::aptxAdaptiveLeConfig>(
+              aptx_adaptive_le_config);
+      DataMQDesc mq_desc;
+      auto aidl_retval = audio_provider_->startSession(
+          audio_port_, AudioConfiguration(le_audio_config), latency_modes,
+          &mq_desc);
+
+      // AIDL call should fail on invalid codec
+      ASSERT_FALSE(aidl_retval.isOk());
+      EXPECT_TRUE(audio_provider_->endSession().isOk());
+    }
+  }
+}
+
 /**
  * openProvider LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH
  */
@@ -1570,6 +1729,10 @@
     le_audio_broadcast_config.streamMap[0]
         .leAudioCodecConfig.set<LeAudioCodecConfiguration::lc3Config>(
             lc3_config);
+    le_audio_broadcast_config.streamMap[0].streamHandle = 0x0;
+    le_audio_broadcast_config.streamMap[0].pcmStreamId = 0x0;
+    le_audio_broadcast_config.streamMap[0].audioChannelAllocation = 0x1 << 0;
+
     DataMQDesc mq_desc;
     auto aidl_retval = audio_provider_->startSession(
         audio_port_, AudioConfiguration(le_audio_broadcast_config),
@@ -1873,7 +2036,7 @@
   ASSERT_NE(audio_provider_, nullptr);
 
   std::vector<CodecConfiguration::CodecSpecific> codec_specifics;
-  for (auto codec_type : a2dp_codec_types) {
+  for (auto codec_type : ndk::enum_range<CodecType>()) {
     switch (codec_type) {
       case CodecType::SBC:
         codec_specifics = GetSbcCodecSpecificSupportedList(false);
@@ -1894,6 +2057,8 @@
         codec_specifics = GetOpusCodecSpecificSupportedList(false);
         continue;
       case CodecType::APTX_ADAPTIVE:
+      case CodecType::APTX_ADAPTIVE_LE:
+      case CodecType::APTX_ADAPTIVE_LEX:
       case CodecType::LC3:
       case CodecType::VENDOR:
       case CodecType::UNKNOWN:
diff --git a/bluetooth/audio/utils/Android.bp b/bluetooth/audio/utils/Android.bp
index 70797a7..914d2b2 100644
--- a/bluetooth/audio/utils/Android.bp
+++ b/bluetooth/audio/utils/Android.bp
@@ -55,7 +55,7 @@
         "libbinder_ndk",
         "libfmq",
         "liblog",
-        "android.hardware.bluetooth.audio-V2-ndk",
+        "android.hardware.bluetooth.audio-V3-ndk",
         "libhidlbase",
         "libxml2",
     ],
@@ -75,7 +75,7 @@
     shared_libs: [
         "libbase",
         "libbinder_ndk",
-        "android.hardware.bluetooth.audio-V2-ndk",
+        "android.hardware.bluetooth.audio-V3-ndk",
         "libxml2",
     ],
     test_suites: [
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp
index faebbbf..3ed9e07 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp
@@ -20,6 +20,8 @@
 
 #include <aidl/android/hardware/bluetooth/audio/AacCapabilities.h>
 #include <aidl/android/hardware/bluetooth/audio/AacObjectType.h>
+#include <aidl/android/hardware/bluetooth/audio/AptxAdaptiveLeCapabilities.h>
+#include <aidl/android/hardware/bluetooth/audio/AptxAdaptiveLeConfiguration.h>
 #include <aidl/android/hardware/bluetooth/audio/AptxCapabilities.h>
 #include <aidl/android/hardware/bluetooth/audio/ChannelMode.h>
 #include <aidl/android/hardware/bluetooth/audio/LdacCapabilities.h>
@@ -98,6 +100,55 @@
 
 std::vector<LeAudioCodecCapabilitiesSetting> kDefaultOffloadLeAudioCapabilities;
 
+static const UnicastCapability kInvalidUnicastCapability = {
+    .codecType = CodecType::UNKNOWN};
+
+static const AptxAdaptiveLeCapabilities
+    kDefaultOffloadAptxAdaptiveLeCapability_48k = {
+        .samplingFrequencyHz = {48000},
+        .frameDurationUs = {10000},
+        .octetsPerFrame = {816}};
+
+static const AptxAdaptiveLeCapabilities
+    kDefaultOffloadAptxAdaptiveLeCapability_96k = {
+        .samplingFrequencyHz = {96000},
+        .frameDurationUs = {10000},
+        .octetsPerFrame = {816}};
+
+static const AptxAdaptiveLeCapabilities
+    kDefaultOffloadAptxAdaptiveLeXCapability_48k = {
+        .samplingFrequencyHz = {48000},
+        .frameDurationUs = {10000},
+        .octetsPerFrame = {816}};
+
+static const AptxAdaptiveLeCapabilities
+    kDefaultOffloadAptxAdaptiveLeXCapability_96k = {
+        .samplingFrequencyHz = {96000},
+        .frameDurationUs = {10000},
+        .octetsPerFrame = {816}};
+
+static const BroadcastCapability kInvalidBroadcastCapability = {
+    .codecType = CodecType::UNKNOWN};
+
+static AudioLocation stereoAudio = static_cast<AudioLocation>(
+    static_cast<uint8_t>(AudioLocation::FRONT_LEFT) |
+    static_cast<uint8_t>(AudioLocation::FRONT_RIGHT));
+
+static const std::vector<AptxAdaptiveLeCapabilities>
+    supportedAptxAdaptiveLeCapabilityList = {
+        kDefaultOffloadAptxAdaptiveLeCapability_48k,
+        kDefaultOffloadAptxAdaptiveLeCapability_96k,
+        kDefaultOffloadAptxAdaptiveLeXCapability_48k,
+        kDefaultOffloadAptxAdaptiveLeXCapability_96k};
+
+// Stores the supported setting of audio location, connected device, and the
+// channel count for each device
+std::vector<std::tuple<AudioLocation, uint8_t, uint8_t>>
+    supportedDeviceSetting = {
+        // Stereo, one connected device for both L and R
+        std::make_tuple(stereoAudio, 1, 2),
+};
+
 template <class T>
 bool BluetoothAudioCodecs::ContainedInVector(
     const std::vector<T>& vector, const typename identity<T>::type& target) {
@@ -312,6 +363,8 @@
       case CodecType::VENDOR:
       case CodecType::LC3:
       case CodecType::APTX_ADAPTIVE:
+      case CodecType::APTX_ADAPTIVE_LE:
+      case CodecType::APTX_ADAPTIVE_LEX:
         break;
     }
   }
@@ -377,6 +430,8 @@
       }
       break;
     case CodecType::APTX_ADAPTIVE:
+    case CodecType::APTX_ADAPTIVE_LE:
+    case CodecType::APTX_ADAPTIVE_LEX:
     case CodecType::LC3:
     case CodecType::UNKNOWN:
     case CodecType::VENDOR:
@@ -403,8 +458,33 @@
     kDefaultOffloadLeAudioCapabilities =
         BluetoothLeAudioCodecsProvider::GetLeAudioCodecCapabilities(
             le_audio_offload_setting);
-  }
 
+    for (auto [audioLocation, deviceCnt, channelCount] :
+         supportedDeviceSetting) {
+      for (auto capability : supportedAptxAdaptiveLeCapabilityList) {
+        for (auto codec_type :
+             {CodecType::APTX_ADAPTIVE_LE, CodecType::APTX_ADAPTIVE_LEX}) {
+          if (session_type ==
+              SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
+            UnicastCapability aptx_adaptive_le_cap = {
+                .codecType = codec_type,
+                .supportedChannel = audioLocation,
+                .deviceCount = deviceCnt,
+                .channelCountPerDevice = channelCount,
+                .leAudioCodecCapabilities =
+                    UnicastCapability::LeAudioCodecCapabilities(capability),
+            };
+
+            // Adds the capability for encode only
+            kDefaultOffloadLeAudioCapabilities.push_back(
+                {.unicastEncodeCapability = aptx_adaptive_le_cap,
+                 .unicastDecodeCapability = kInvalidUnicastCapability,
+                 .broadcastCapability = kInvalidBroadcastCapability});
+          }
+        }
+      }
+    }
+  }
   return kDefaultOffloadLeAudioCapabilities;
 }
 
diff --git a/bluetooth/hci/test/h4_protocol_unittest.cc b/bluetooth/hci/test/h4_protocol_unittest.cc
index d6f74fc..d3fab61 100644
--- a/bluetooth/hci/test/h4_protocol_unittest.cc
+++ b/bluetooth/hci/test/h4_protocol_unittest.cc
@@ -50,6 +50,9 @@
 static char iso_data[100] =
     "A plane angle is the inclination to one another of two lines in a ...";
 
+// 5 seconds.  Just don't hang.
+static constexpr size_t kTimeoutMs = 5000;
+
 MATCHER_P3(PacketMatches, header_, header_length, payload,
            "Match header_length bytes of header and then the payload") {
   size_t payload_length = strlen(payload);
@@ -131,9 +134,9 @@
         .WillOnce(Notify(promise));
   }
 
-  void WaitForTimeout(size_t timeout_ms, std::promise<void>* promise) {
+  void WaitForTimeout(std::promise<void>* promise) {
     auto future = promise->get_future();
-    auto status = future.wait_for(std::chrono::milliseconds(timeout_ms));
+    auto status = future.wait_for(std::chrono::milliseconds(kTimeoutMs));
     EXPECT_EQ(status, std::future_status::ready);
   }
 
@@ -263,10 +266,10 @@
   WriteInboundIsoData(iso_data);
   CallDataReady();
 
-  WaitForTimeout(100, &acl_promise);
-  WaitForTimeout(100, &sco_promise);
-  WaitForTimeout(100, &event_promise);
-  WaitForTimeout(100, &iso_promise);
+  WaitForTimeout(&acl_promise);
+  WaitForTimeout(&sco_promise);
+  WaitForTimeout(&event_promise);
+  WaitForTimeout(&iso_promise);
 }
 
 TEST_F(H4ProtocolTest, TestMultiplePackets) {
@@ -363,28 +366,28 @@
     std::promise<void> promise;
     ExpectInboundAclData(payload, &promise);
     WriteInboundAclData(payload);
-    WaitForTimeout(100, &promise);
+    WaitForTimeout(&promise);
   }
 
   void WriteAndExpectInboundScoData(char* payload) {
     std::promise<void> promise;
     ExpectInboundScoData(payload, &promise);
     WriteInboundScoData(payload);
-    WaitForTimeout(100, &promise);
+    WaitForTimeout(&promise);
   }
 
   void WriteAndExpectInboundEvent(char* payload) {
     std::promise<void> promise;
     ExpectInboundEvent(payload, &promise);
     WriteInboundEvent(payload);
-    WaitForTimeout(100, &promise);
+    WaitForTimeout(&promise);
   }
 
   void WriteAndExpectInboundIsoData(char* payload) {
     std::promise<void> promise;
     ExpectInboundIsoData(payload, &promise);
     WriteInboundIsoData(payload);
-    WaitForTimeout(100, &promise);
+    WaitForTimeout(&promise);
   }
 
   void WriteAndExpectManyInboundAclDataPackets(char* payload) {
@@ -436,6 +439,5 @@
   EXPECT_CALL(disconnect_cb_, Call()).WillOnce(Notify(&promise));
   close(chip_uart_fd_);
 
-  // Fail if it takes longer than 100 ms.
-  WaitForTimeout(100, &promise);
+  WaitForTimeout(&promise);
 }
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index b0ae20e..5ea6ae2 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -6318,8 +6318,6 @@
                                                  std::vector<AvailableStream>& outputStreams,
                                                  const AvailableStream* threshold,
                                                  bool maxResolution) {
-    AvailableStream depthPreviewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
-                                             static_cast<int32_t>(PixelFormat::Y16)};
     if (nullptr == staticMeta) {
         return Status::ILLEGAL_ARGUMENT;
     }
@@ -6345,8 +6343,12 @@
     }
 
     if(foundDepth == 0 && (0 == (depthEntry.count % 4))) {
-        fillOutputStreams(&depthEntry, outputStreams, &depthPreviewThreshold,
-                ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_OUTPUT);
+        AvailableStream depthPreviewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
+                                                 static_cast<int32_t>(PixelFormat::Y16)};
+        const AvailableStream* depthThreshold =
+                (threshold != nullptr) ? threshold : &depthPreviewThreshold;
+        fillOutputStreams(&depthEntry, outputStreams, depthThreshold,
+                          ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_OUTPUT);
     }
 
     return Status::OK;
diff --git a/camera/provider/aidl/vts/camera_aidl_test.cpp b/camera/provider/aidl/vts/camera_aidl_test.cpp
index 48816ad9..573b8f1 100644
--- a/camera/provider/aidl/vts/camera_aidl_test.cpp
+++ b/camera/provider/aidl/vts/camera_aidl_test.cpp
@@ -751,8 +751,6 @@
                                                  std::vector<AvailableStream>& outputStreams,
                                                  const AvailableStream* threshold,
                                                  bool maxResolution) {
-    AvailableStream depthPreviewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
-                                             static_cast<int32_t>(PixelFormat::Y16)};
     if (nullptr == staticMeta) {
         return Status::ILLEGAL_ARGUMENT;
     }
@@ -778,7 +776,11 @@
     }
 
     if (foundDepth == 0 && (0 == (depthEntry.count % 4))) {
-        fillOutputStreams(&depthEntry, outputStreams, &depthPreviewThreshold,
+        AvailableStream depthPreviewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
+                                                 static_cast<int32_t>(PixelFormat::Y16)};
+        const AvailableStream* depthThreshold =
+                (threshold != nullptr) ? threshold : &depthPreviewThreshold;
+        fillOutputStreams(&depthEntry, outputStreams, depthThreshold,
                           ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_OUTPUT);
     }
 
@@ -2332,6 +2334,7 @@
         request.fmqSettingsSize = 0;
         request.settings.metadata =
                 std::vector(rawMetadata, rawMetadata + get_camera_metadata_size(releasedMetadata));
+        overrideRotateAndCrop(&request.settings);
         request.outputBuffers = std::vector<StreamBuffer>(1);
         StreamBuffer& outputBuffer = request.outputBuffers[0];
         if (useHalBufManager) {
diff --git a/cas/aidl/default/OWNERS b/cas/aidl/OWNERS
similarity index 100%
rename from cas/aidl/default/OWNERS
rename to cas/aidl/OWNERS
diff --git a/common/fmq/aidl/Android.bp b/common/fmq/aidl/Android.bp
index 95fcc41..40ceb32 100644
--- a/common/fmq/aidl/Android.bp
+++ b/common/fmq/aidl/Android.bp
@@ -38,5 +38,10 @@
         },
     },
     frozen: true,
-    versions: ["1"],
+    versions_with_info: [
+        {
+            version: "1",
+            imports: ["android.hardware.common-V2"],
+        },
+    ],
 }
diff --git a/compatibility_matrices/Android.bp b/compatibility_matrices/Android.bp
index e1ad1f3..622835e 100644
--- a/compatibility_matrices/Android.bp
+++ b/compatibility_matrices/Android.bp
@@ -78,7 +78,7 @@
         "compatibility_matrix.8.xml",
     ],
     kernel_configs: [
-        "kernel_config_current_5.10",
         "kernel_config_current_5.15",
+        "kernel_config_current_6.1",
     ],
 }
diff --git a/compatibility_matrices/compatibility_matrix.7.xml b/compatibility_matrices/compatibility_matrix.7.xml
index 3c6c3de..e5ef954 100644
--- a/compatibility_matrices/compatibility_matrix.7.xml
+++ b/compatibility_matrices/compatibility_matrix.7.xml
@@ -400,14 +400,6 @@
         </interface>
     </hal>
     <hal format="aidl" optional="true">
-        <name>android.hardware.security.dice</name>
-        <version>1</version>
-        <interface>
-            <name>IDiceDevice</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
         <name>android.hardware.security.keymint</name>
         <version>1-2</version>
         <interface>
diff --git a/compatibility_matrices/compatibility_matrix.8.xml b/compatibility_matrices/compatibility_matrix.8.xml
index eb649bf..f5a1b20 100644
--- a/compatibility_matrices/compatibility_matrix.8.xml
+++ b/compatibility_matrices/compatibility_matrix.8.xml
@@ -167,7 +167,7 @@
     </hal>
     <hal format="aidl" optional="true">
         <name>android.hardware.bluetooth.audio</name>
-        <version>2</version>
+        <version>3</version>
         <interface>
             <name>IBluetoothAudioProviderFactory</name>
             <instance>default</instance>
@@ -403,14 +403,6 @@
         </interface>
     </hal>
     <hal format="aidl" optional="true">
-        <name>android.hardware.security.dice</name>
-        <version>1</version>
-        <interface>
-            <name>IDiceDevice</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
         <name>android.hardware.security.keymint</name>
         <version>1-3</version>
         <interface>
diff --git a/confirmationui/1.0/default/OWNERS b/confirmationui/1.0/default/OWNERS
index 335660d..17aed51 100644
--- a/confirmationui/1.0/default/OWNERS
+++ b/confirmationui/1.0/default/OWNERS
@@ -1,2 +1,3 @@
+# Bug component: 1124672
 jdanis@google.com
 swillden@google.com
diff --git a/confirmationui/1.0/vts/OWNERS b/confirmationui/1.0/vts/OWNERS
index e7aa8b4..aa07242 100644
--- a/confirmationui/1.0/vts/OWNERS
+++ b/confirmationui/1.0/vts/OWNERS
@@ -1,3 +1,4 @@
+# Bug component: 1124672
 jdanis@google.com
 swillden@google.com
 yim@google.com
diff --git a/confirmationui/OWNERS b/confirmationui/OWNERS
index 2bcdb0e..d3896df 100644
--- a/confirmationui/OWNERS
+++ b/confirmationui/OWNERS
@@ -1,2 +1,3 @@
+# Bug component: 1124672
 swillden@google.com
 subrahmanyaman@google.com
diff --git a/confirmationui/aidl/vts/functional/Android.bp b/confirmationui/aidl/vts/functional/Android.bp
index 3649c87..ac2d53a 100644
--- a/confirmationui/aidl/vts/functional/Android.bp
+++ b/confirmationui/aidl/vts/functional/Android.bp
@@ -23,7 +23,7 @@
     name: "VtsHalConfirmationUITargetTest",
     defaults: [
         "VtsHalTargetTestDefaults",
-        "keymint_use_latest_hal_aidl_ndk_shared",
+        "keymint_use_latest_hal_aidl_ndk_static",
         "use_libaidlvintf_gtest_helper_static",
     ],
     srcs: [
@@ -31,8 +31,9 @@
     ],
     static_libs: [
         "android.hardware.confirmationui-V1-ndk",
-        "libcn-cbor",
         "android.hardware.confirmationui-support-lib",
+        "android.hardware.security.secureclock-V1-ndk",
+        "libcn-cbor",
     ],
     shared_libs: [
         "libbinder_ndk",
diff --git a/confirmationui/support/OWNERS b/confirmationui/support/OWNERS
index 335660d..17aed51 100644
--- a/confirmationui/support/OWNERS
+++ b/confirmationui/support/OWNERS
@@ -1,2 +1,3 @@
+# Bug component: 1124672
 jdanis@google.com
 swillden@google.com
diff --git a/gatekeeper/1.0/default/OWNERS b/gatekeeper/1.0/default/OWNERS
index 335660d..c97fba6 100644
--- a/gatekeeper/1.0/default/OWNERS
+++ b/gatekeeper/1.0/default/OWNERS
@@ -1,2 +1,3 @@
+# Bug component: 1124862
 jdanis@google.com
 swillden@google.com
diff --git a/gatekeeper/1.0/software/OWNERS b/gatekeeper/1.0/software/OWNERS
index 335660d..c97fba6 100644
--- a/gatekeeper/1.0/software/OWNERS
+++ b/gatekeeper/1.0/software/OWNERS
@@ -1,2 +1,3 @@
+# Bug component: 1124862
 jdanis@google.com
 swillden@google.com
diff --git a/gatekeeper/OWNERS b/gatekeeper/OWNERS
index fddc2ff..5262dce 100644
--- a/gatekeeper/OWNERS
+++ b/gatekeeper/OWNERS
@@ -1,4 +1,6 @@
 # Bug component: 1124862
-swillden@google.com
+drysdale@google.com
 guangzhu@google.com
+oarbildo@google.com
 subrahmanyaman@google.com
+swillden@google.com
diff --git a/gatekeeper/aidl/vts/functional/Android.bp b/gatekeeper/aidl/vts/functional/Android.bp
index 2fa80de..008f25c 100644
--- a/gatekeeper/aidl/vts/functional/Android.bp
+++ b/gatekeeper/aidl/vts/functional/Android.bp
@@ -24,14 +24,17 @@
     defaults: [
         "VtsHalTargetTestDefaults",
         "use_libaidlvintf_gtest_helper_static",
-        "keymint_use_latest_hal_aidl_ndk_shared",
+        "keymint_use_latest_hal_aidl_ndk_static",
     ],
     srcs: ["VtsHalGatekeeperTargetTest.cpp"],
     shared_libs: [
         "libbinder_ndk",
         "libbase",
     ],
-    static_libs: ["android.hardware.gatekeeper-V1-ndk"],
+    static_libs: [
+        "android.hardware.gatekeeper-V1-ndk",
+        "android.hardware.security.secureclock-V1-ndk",
+    ],
     test_suites: [
         "general-tests",
         "vts",
diff --git a/gnss/aidl/default/Gnss.cpp b/gnss/aidl/default/Gnss.cpp
index cf2c90d..2d6490c 100644
--- a/gnss/aidl/default/Gnss.cpp
+++ b/gnss/aidl/default/Gnss.cpp
@@ -68,7 +68,7 @@
 
     IGnssCallback::GnssSystemInfo systemInfo = {
             .yearOfHw = 2022,
-            .name = "Google Mock GNSS Implementation AIDL v2",
+            .name = "Google, Cuttlefish, AIDL v2",
     };
     status = sGnssCallback->gnssSetSystemInfoCb(systemInfo);
     if (!status.isOk()) {
diff --git a/gnss/aidl/vts/gnss_hal_test.cpp b/gnss/aidl/vts/gnss_hal_test.cpp
index 3907f57..64e51c7 100644
--- a/gnss/aidl/vts/gnss_hal_test.cpp
+++ b/gnss/aidl/vts/gnss_hal_test.cpp
@@ -447,6 +447,7 @@
                                               const int numMeasurementEvents,
                                               const int timeoutSeconds,
                                               std::vector<int>& deltasMs) {
+    callback->gnss_data_cbq_.reset();  // throw away the initial measurements if any
     int64_t lastElapsedRealtimeMillis = 0;
     for (int i = 0; i < numMeasurementEvents; i++) {
         GnssData lastGnssData;
diff --git a/graphics/mapper/3.0/utils/vts/MapperVts.cpp b/graphics/mapper/3.0/utils/vts/MapperVts.cpp
index c470a4a..48e5736 100644
--- a/graphics/mapper/3.0/utils/vts/MapperVts.cpp
+++ b/graphics/mapper/3.0/utils/vts/MapperVts.cpp
@@ -99,11 +99,7 @@
             descriptor, count,
             [&](const auto& tmpError, const auto& tmpStride, const auto& tmpBuffers) {
                 if (tmpError != Error::NONE) {
-                    if (base::GetIntProperty("ro.vendor.build.version.sdk", 0, 0, INT_MAX) < 33) {
-                        GTEST_SKIP() << "Old vendor grallocs may not support P010";
-                    } else {
-                        GTEST_FAIL() << "failed to allocate buffers";
-                    }
+                    GTEST_FAIL() << "failed to allocate buffers";
                 }
                 ASSERT_EQ(count, tmpBuffers.size()) << "invalid buffer array";
 
diff --git a/graphics/mapper/3.0/vts/functional/VtsHalGraphicsMapperV3_0TargetTest.cpp b/graphics/mapper/3.0/vts/functional/VtsHalGraphicsMapperV3_0TargetTest.cpp
index 3b1bfab..997af97 100644
--- a/graphics/mapper/3.0/vts/functional/VtsHalGraphicsMapperV3_0TargetTest.cpp
+++ b/graphics/mapper/3.0/vts/functional/VtsHalGraphicsMapperV3_0TargetTest.cpp
@@ -21,6 +21,7 @@
 #include <vector>
 
 #include <android-base/logging.h>
+#include <android-base/properties.h>
 #include <gtest/gtest.h>
 #include <hidl/GtestPrinter.h>
 #include <hidl/ServiceManagement.h>
@@ -330,6 +331,9 @@
  * Test IMapper::lockYCbCr.  This locks a YCbCr_P010 buffer and verifies that it's initialized.
  */
 TEST_P(GraphicsMapperHidlTest, LockYCbCrP010) {
+    if (base::GetIntProperty("ro.vendor.api_level", __ANDROID_API_FUTURE__) < __ANDROID_API_T__) {
+        GTEST_SKIP() << "Old vendor grallocs may not support P010";
+    }
     auto info = mDummyDescriptorInfo;
     info.format = PixelFormat::YCBCR_P010;
 
diff --git a/graphics/mapper/4.0/utils/vts/MapperVts.cpp b/graphics/mapper/4.0/utils/vts/MapperVts.cpp
index c6c9834..d70c6ef 100644
--- a/graphics/mapper/4.0/utils/vts/MapperVts.cpp
+++ b/graphics/mapper/4.0/utils/vts/MapperVts.cpp
@@ -111,11 +111,7 @@
         }
 
         if (error != Error::NONE) {
-            if (base::GetIntProperty("ro.vendor.build.version.sdk", 0, 0, INT_MAX) < 33) {
-                GTEST_SKIP() << "Old vendor grallocs may not support P010";
-            } else {
-                GTEST_FAIL() << "failed to allocate buffers";
-            }
+            GTEST_FAIL() << "failed to allocate buffers";
         }
         ASSERT_EQ(count, buffers.size()) << "invalid buffer array";
 
diff --git a/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp b/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
index 5a450e3..2ec98d4 100644
--- a/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
+++ b/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
@@ -29,12 +29,14 @@
 #include <aidlcommonsupport/NativeHandle.h>
 
 #include <android-base/logging.h>
+#include <android-base/properties.h>
 #include <android-base/unique_fd.h>
 #include <android/sync.h>
 #include <gralloctypes/Gralloc4.h>
 #include <gtest/gtest.h>
 #include <hidl/GtestPrinter.h>
 #include <hidl/ServiceManagement.h>
+
 #include <mapper-vts/4.0/MapperVts.h>
 #include <system/graphics.h>
 
@@ -1000,6 +1002,9 @@
 }
 
 TEST_P(GraphicsMapperHidlTest, Lock_YCBCR_P010) {
+    if (base::GetIntProperty("ro.vendor.api_level", __ANDROID_API_FUTURE__) < __ANDROID_API_T__) {
+        GTEST_SKIP() << "Old vendor grallocs may not support P010";
+    }
     auto info = mDummyDescriptorInfo;
     info.format = PixelFormat::YCBCR_P010;
 
diff --git a/health/aidl/OWNERS b/health/aidl/OWNERS
index 9bbcef8..0f1bee2 100644
--- a/health/aidl/OWNERS
+++ b/health/aidl/OWNERS
@@ -2,3 +2,4 @@
 elsk@google.com
 smoreland@google.com
 wjack@google.com
+apelosi@google.com
diff --git a/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryCapacityLevel.aidl b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryCapacityLevel.aidl
index e543886..4d70588 100644
--- a/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryCapacityLevel.aidl
+++ b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryCapacityLevel.aidl
@@ -34,11 +34,11 @@
 package android.hardware.health;
 @Backing(type="int") @VintfStability
 enum BatteryCapacityLevel {
-  UNSUPPORTED = -1,
-  UNKNOWN = 0,
-  CRITICAL = 1,
-  LOW = 2,
-  NORMAL = 3,
-  HIGH = 4,
-  FULL = 5,
+  UNSUPPORTED = (-1) /* -1 */,
+  UNKNOWN,
+  CRITICAL,
+  LOW,
+  NORMAL,
+  HIGH,
+  FULL,
 }
diff --git a/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryHealthData.aidl b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryHealthData.aidl
index d523fad..2dd01b1 100644
--- a/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryHealthData.aidl
+++ b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryHealthData.aidl
@@ -36,4 +36,5 @@
 parcelable BatteryHealthData {
   long batteryManufacturingDateSeconds;
   long batteryFirstUsageSeconds;
+  long batteryStateOfHealth;
 }
diff --git a/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/HealthInfo.aidl b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/HealthInfo.aidl
index 664cc70..bfa1475 100644
--- a/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/HealthInfo.aidl
+++ b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/HealthInfo.aidl
@@ -57,9 +57,8 @@
   android.hardware.health.BatteryCapacityLevel batteryCapacityLevel;
   long batteryChargeTimeToFullNowSeconds;
   int batteryFullChargeDesignCapacityUah;
-  int batteryStateOfHealth;
   android.hardware.health.BatteryChargingState chargingState;
   android.hardware.health.BatteryChargingPolicy chargingPolicy;
   @nullable android.hardware.health.BatteryHealthData batteryHealthData;
-  const int BATTERY_CHARGE_TIME_TO_FULL_NOW_SECONDS_UNSUPPORTED = -1;
+  const int BATTERY_CHARGE_TIME_TO_FULL_NOW_SECONDS_UNSUPPORTED = (-1) /* -1 */;
 }
diff --git a/health/aidl/android/hardware/health/BatteryHealthData.aidl b/health/aidl/android/hardware/health/BatteryHealthData.aidl
index fb17f63..594bcce 100644
--- a/health/aidl/android/hardware/health/BatteryHealthData.aidl
+++ b/health/aidl/android/hardware/health/BatteryHealthData.aidl
@@ -29,4 +29,11 @@
      * The date of first usage is reported in epoch.
      */
     long batteryFirstUsageSeconds;
+    /**
+     * Measured battery state of health (remaining estimate full charge capacity
+     * relative to the rated capacity in %).
+     * Value must be 0 if batteryStatus is UNKNOWN.
+     * Otherwise, value must be in the range 0 to 100.
+     */
+    long batteryStateOfHealth;
 }
diff --git a/health/aidl/android/hardware/health/HealthInfo.aidl b/health/aidl/android/hardware/health/HealthInfo.aidl
index 238f524..af84089 100644
--- a/health/aidl/android/hardware/health/HealthInfo.aidl
+++ b/health/aidl/android/hardware/health/HealthInfo.aidl
@@ -137,13 +137,6 @@
      */
     int batteryFullChargeDesignCapacityUah;
     /**
-     * Measured battery state of health (remaining estimate full charge capacity
-     * relative to the rated capacity in %).
-     * Value must be 0 if batteryStatus is UNKNOWN.
-     * Otherwise, value must be in the range 0 to 100.
-     */
-    int batteryStateOfHealth;
-    /**
      * Battery charging state
      */
     BatteryChargingState chargingState;
diff --git a/health/aidl/default/Health.cpp b/health/aidl/default/Health.cpp
index 15a3dbc..f401643 100644
--- a/health/aidl/default/Health.cpp
+++ b/health/aidl/default/Health.cpp
@@ -148,6 +148,11 @@
         !res.isOk()) {
         LOG(WARNING) << "Cannot get First_usage_date: " << res.getDescription();
     }
+    if (auto res = GetProperty<int64_t>(&battery_monitor_, ::android::BATTERY_PROP_STATE_OF_HEALTH,
+                                        0, &out->batteryStateOfHealth);
+        !res.isOk()) {
+        LOG(WARNING) << "Cannot get Battery_state_of_health: " << res.getDescription();
+    }
     return ndk::ScopedAStatus::ok();
 }
 
diff --git a/health/aidl/vts/functional/VtsHalHealthTargetTest.cpp b/health/aidl/vts/functional/VtsHalHealthTargetTest.cpp
index 6506ea2..783ce11 100644
--- a/health/aidl/vts/functional/VtsHalHealthTargetTest.cpp
+++ b/health/aidl/vts/functional/VtsHalHealthTargetTest.cpp
@@ -257,7 +257,7 @@
     BatteryChargingPolicy value;
 
     /* set ChargingPolicy*/
-    status = health->setChargingPolicy(static_cast<BatteryChargingPolicy>(2));  // LONG_LIFE
+    status = health->setChargingPolicy(BatteryChargingPolicy::LONG_LIFE);
     ASSERT_THAT(status, AnyOf(IsOk(), ExceptionIs(EX_UNSUPPORTED_OPERATION)));
     if (!status.isOk()) return;
 
@@ -265,7 +265,9 @@
     status = health->getChargingPolicy(&value);
     ASSERT_THAT(status, AnyOf(IsOk(), ExceptionIs(EX_UNSUPPORTED_OPERATION)));
     if (!status.isOk()) return;
-    ASSERT_THAT(static_cast<int>(value), Eq(2));
+    // the result of getChargingPolicy will be one of default(1), ADAPTIVE_AON(2)
+    // ADAPTIVE_AC(3) or LONG_LIFE(4). default(1) means NOT_SUPPORT
+    ASSERT_THAT(static_cast<int>(value), AnyOf(Eq(1), Eq(4)));
 }
 
 MATCHER(IsValidHealthData, "") {
@@ -278,6 +280,10 @@
         *result_listener << " for batteryFirstUsageSeconds.";
         return false;
     }
+    if (!ExplainMatchResult(Ge(-1), arg.batteryStateOfHealth, result_listener)) {
+        *result_listener << " for batteryStateOfHealth.";
+        return false;
+    }
 
     return true;
 }
diff --git a/identity/OWNERS b/identity/OWNERS
index 6969910..9353bbc 100644
--- a/identity/OWNERS
+++ b/identity/OWNERS
@@ -1,2 +1,4 @@
+# Bug component: 1084909
+
 swillden@google.com
 zeuthen@google.com
diff --git a/identity/aidl/android/hardware/identity/IIdentityCredential.aidl b/identity/aidl/android/hardware/identity/IIdentityCredential.aidl
index abdb00b..df8e2bd 100644
--- a/identity/aidl/android/hardware/identity/IIdentityCredential.aidl
+++ b/identity/aidl/android/hardware/identity/IIdentityCredential.aidl
@@ -370,7 +370,8 @@
      *  - issuer: CN shall be set to "Android Identity Credential Key". (fixed value:
      *    same on all certs)
      *
-     *  - validity: should be from current time and one year in the future (365 days).
+     *  - validity: should be from current time and 31536000 seconds in the
+     *    future (approximately 365 days).
      *
      *  - subjectPublicKeyInfo: must contain attested public key.
      *
diff --git a/identity/aidl/vts/Android.bp b/identity/aidl/vts/Android.bp
index 5e303bb..6f7ab54 100644
--- a/identity/aidl/vts/Android.bp
+++ b/identity/aidl/vts/Android.bp
@@ -61,16 +61,3 @@
     ],
     require_root: true,
 }
-
-java_test_host {
-    name: "IdentityCredentialImplementedTest",
-    libs: [
-        "tradefed",
-        "vts-core-tradefed-harness",
-    ],
-    srcs: ["src/**/*.java"],
-    test_suites: [
-        "vts",
-    ],
-    test_config: "IdentityCredentialImplementedTest.xml",
-}
diff --git a/identity/aidl/vts/IdentityCredentialImplementedTest.xml b/identity/aidl/vts/IdentityCredentialImplementedTest.xml
deleted file mode 100644
index 4276ae6..0000000
--- a/identity/aidl/vts/IdentityCredentialImplementedTest.xml
+++ /dev/null
@@ -1,22 +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 IdentityCredentialImplementedTest">
-  <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" />
-
-  <test class="com.android.tradefed.testtype.HostTest" >
-    <option name="jar" value="IdentityCredentialImplementedTest.jar" />
-  </test>
-</configuration>
diff --git a/identity/aidl/vts/Util.cpp b/identity/aidl/vts/Util.cpp
index f3d7c30..4f5c121 100644
--- a/identity/aidl/vts/Util.cpp
+++ b/identity/aidl/vts/Util.cpp
@@ -523,8 +523,24 @@
     int64_t allowDriftSecs = 10;
     EXPECT_LE(-allowDriftSecs, diffSecs);
     EXPECT_GE(allowDriftSecs, diffSecs);
-    constexpr uint64_t kSecsInOneYear = 365 * 24 * 60 * 60;
-    EXPECT_EQ(notBefore + kSecsInOneYear, notAfter);
+
+    // The AIDL spec used to call for "one year in the future (365
+    // days)" but was updated to say "current time and 31536000
+    // seconds in the future (approximately 365 days)" to clarify that
+    // this was the original intention.
+    //
+    // However a number of implementations interpreted this as a
+    // "literal year" which started causing problems in March 2023
+    // because 2024 is a leap year. Since the extra day doesn't really
+    // matter (the validity period is specified in the MSO anyway and
+    // that's what RPs use), we allow both interpretations.
+    //
+    // For simplicity, we just require that that notAfter is after
+    // 31536000 and which also covers the case if there's a leap-day
+    // and possible leap-seconds.
+    //
+    constexpr uint64_t kSecsIn365Days = 365 * 24 * 60 * 60;
+    EXPECT_LE(notBefore + kSecsIn365Days, notAfter);
 }
 
 vector<RequestNamespace> buildRequestNamespaces(const vector<TestEntryData> entries) {
diff --git a/identity/aidl/vts/src/com/android/tests/security/identity/IdentityCredentialImplementedTest.java b/identity/aidl/vts/src/com/android/tests/security/identity/IdentityCredentialImplementedTest.java
deleted file mode 100644
index 4936f8c..0000000
--- a/identity/aidl/vts/src/com/android/tests/security/identity/IdentityCredentialImplementedTest.java
+++ /dev/null
@@ -1,68 +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 com.android.tests.security.identity;
-
-import static org.junit.Assert.fail;
-import static org.junit.Assume.assumeTrue;
-
-import android.platform.test.annotations.RequiresDevice;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-// This is a host-test which executes shell commands on the device. It would be
-// nicer to have this be a Device test (like CTS) but this is currently not
-// possible, see https://source.android.com/docs/core/tests/vts
-
-@RunWith(DeviceJUnit4ClassRunner.class)
-public class IdentityCredentialImplementedTest extends BaseHostJUnit4Test {
-    // Returns the ro.vendor.api_level or 0 if not set.
-    //
-    // Throws NumberFormatException if ill-formatted.
-    //
-    // Throws DeviceNotAvailableException if device is not available.
-    //
-    private int getVendorApiLevel() throws NumberFormatException, DeviceNotAvailableException {
-        String vendorApiLevelString =
-                getDevice().executeShellCommand("getprop ro.vendor.api_level").trim();
-        if (vendorApiLevelString.isEmpty()) {
-            return 0;
-        }
-        return Integer.parseInt(vendorApiLevelString);
-    }
-
-    // As of Android 14 VSR (vendor API level 34), Identity Credential is required at feature
-    // version 202301 or later.
-    @RequiresDevice
-    @Test
-    public void testIdentityCredentialIsImplemented() throws Exception {
-        int vendorApiLevel = getVendorApiLevel();
-        assumeTrue(vendorApiLevel >= 34);
-
-        final String minimumFeatureVersionNeeded = "202301";
-
-        String result = getDevice().executeShellCommand(
-                "pm has-feature android.hardware.identity_credential "
-                + minimumFeatureVersionNeeded);
-        if (!result.trim().equals("true")) {
-            fail("Identity Credential feature version " + minimumFeatureVersionNeeded
-                    + " required but not found");
-        }
-    }
-}
diff --git a/keymaster/4.0/vts/performance/Benchmark.cpp b/keymaster/4.0/vts/performance/Benchmark.cpp
index 96ef5bf..e5fdff2 100644
--- a/keymaster/4.0/vts/performance/Benchmark.cpp
+++ b/keymaster/4.0/vts/performance/Benchmark.cpp
@@ -315,7 +315,7 @@
 
     SecurityLevel getSecurityLevel() { return securityLevel_; }
 
-    const string& GenerateMessage(int size) {
+    const string GenerateMessage(int size) {
         for (const string& message : message_cache_) {
             if (message.size() == size) {
                 return message;
@@ -323,7 +323,7 @@
         }
         string message = string(size, 'x');
         message_cache_.push_back(message);
-        return std::move(message);
+        return message;
     }
 
     optional<BlockMode> getBlockMode(string transform) {
@@ -714,4 +714,4 @@
         return 1;
     }
     ::benchmark::RunSpecifiedBenchmarks();
-}
\ No newline at end of file
+}
diff --git a/media/omx/1.0/vts/functional/store/VtsHalMediaOmxV1_0TargetStoreTest.cpp b/media/omx/1.0/vts/functional/store/VtsHalMediaOmxV1_0TargetStoreTest.cpp
old mode 100755
new mode 100644
index 00e9837..d80e651
--- a/media/omx/1.0/vts/functional/store/VtsHalMediaOmxV1_0TargetStoreTest.cpp
+++ b/media/omx/1.0/vts/functional/store/VtsHalMediaOmxV1_0TargetStoreTest.cpp
@@ -374,21 +374,16 @@
     }
 }
 
-static int getFirstApiLevel() {
-    int boardApiLevel = android::base::GetIntProperty("ro.board.first_api_level", 0);
-    if (boardApiLevel != 0) {
-        return boardApiLevel;
-    }
-
-    return android::base::GetIntProperty("ro.product.first_api_level", __ANDROID_API_T__);
-}
-
 static bool isTV() {
     return testing::deviceSupportsFeature("android.software.leanback");
 }
 
 // list components and roles.
 TEST_P(StoreHidlTest, OmxCodecAllowedTest) {
+    static int sBoardFirstApiLevel = android::base::GetIntProperty("ro.board.first_api_level", 0);
+    if (sBoardFirstApiLevel == 0) {
+        GTEST_SKIP() << "board first API level not detected";
+    }
     hidl_vec<IOmx::ComponentInfo> componentInfos = getComponentInfoList(omx);
     for (IOmx::ComponentInfo info : componentInfos) {
         for (std::string role : info.mRoles) {
@@ -396,27 +391,27 @@
                 role.find("video_encoder") != std::string::npos) {
                 // Codec2 is not mandatory on Android TV devices that launched with Android S
                 if (isTV()) {
-                    ASSERT_LT(getFirstApiLevel(), __ANDROID_API_T__)
+                    ASSERT_LT(sBoardFirstApiLevel, __ANDROID_API_T__)
                             << " Component: " << info.mName.c_str() << " Role: " << role.c_str()
                             << " not allowed for devices launching with Android T and above";
                 } else {
                     std::string codecName = info.mName;
                     bool isAndroidCodec = (codecName.rfind("OMX.google", 0) != std::string::npos);
-                    if (isAndroidCodec && (getFirstApiLevel() <= __ANDROID_API_S__)) {
+                    if (isAndroidCodec && (sBoardFirstApiLevel <= __ANDROID_API_S__)) {
                         // refer b/230582620
                         // S AOSP build did not remove the OMX.google video codecs
                         // so it is infeasible to require no OMX.google.* video codecs
                         // on S launching devices
                     } else {
-                        ASSERT_LT(getFirstApiLevel(), __ANDROID_API_S__)
-                            << " Component: " << info.mName.c_str() << " Role: " << role.c_str()
-                            << " not allowed for devices launching with Android S and above";
+                        ASSERT_LT(sBoardFirstApiLevel, __ANDROID_API_S__)
+                                << " Component: " << info.mName.c_str() << " Role: " << role.c_str()
+                                << " not allowed for devices launching with Android S and above";
                     }
                 }
             }
             if (role.find("audio_decoder") != std::string::npos ||
                 role.find("audio_encoder") != std::string::npos) {
-                ASSERT_LT(getFirstApiLevel(), __ANDROID_API_T__)
+                ASSERT_LT(sBoardFirstApiLevel, __ANDROID_API_T__)
                         << " Component: " << info.mName.c_str() << " Role: " << role.c_str()
                         << " not allowed for devices launching with Android T and above";
             }
diff --git a/neuralnetworks/1.2/utils/src/BurstUtils.cpp b/neuralnetworks/1.2/utils/src/BurstUtils.cpp
index b589c46..c4c096d 100644
--- a/neuralnetworks/1.2/utils/src/BurstUtils.cpp
+++ b/neuralnetworks/1.2/utils/src/BurstUtils.cpp
@@ -190,12 +190,13 @@
     size_t index = 0;
 
     // validate packet information
-    if (data.size() == 0 || data[index].getDiscriminator() != discriminator::packetInformation) {
+    if (index >= data.size() ||
+        data.at(index).getDiscriminator() != discriminator::packetInformation) {
         return NN_ERROR() << "FMQ Request packet ill-formed";
     }
 
     // unpackage packet information
-    const FmqRequestDatum::PacketInformation& packetInfo = data[index].packetInformation();
+    const FmqRequestDatum::PacketInformation& packetInfo = data.at(index).packetInformation();
     index++;
     const uint32_t packetSize = packetInfo.packetSize;
     const uint32_t numberOfInputOperands = packetInfo.numberOfInputOperands;
@@ -212,13 +213,14 @@
     inputs.reserve(numberOfInputOperands);
     for (size_t operand = 0; operand < numberOfInputOperands; ++operand) {
         // validate input operand information
-        if (data[index].getDiscriminator() != discriminator::inputOperandInformation) {
+        if (index >= data.size() ||
+            data.at(index).getDiscriminator() != discriminator::inputOperandInformation) {
             return NN_ERROR() << "FMQ Request packet ill-formed";
         }
 
         // unpackage operand information
         const FmqRequestDatum::OperandInformation& operandInfo =
-                data[index].inputOperandInformation();
+                data.at(index).inputOperandInformation();
         index++;
         const bool hasNoValue = operandInfo.hasNoValue;
         const V1_0::DataLocation location = operandInfo.location;
@@ -229,12 +231,13 @@
         dimensions.reserve(numberOfDimensions);
         for (size_t i = 0; i < numberOfDimensions; ++i) {
             // validate dimension
-            if (data[index].getDiscriminator() != discriminator::inputOperandDimensionValue) {
+            if (index >= data.size() ||
+                data.at(index).getDiscriminator() != discriminator::inputOperandDimensionValue) {
                 return NN_ERROR() << "FMQ Request packet ill-formed";
             }
 
             // unpackage dimension
-            const uint32_t dimension = data[index].inputOperandDimensionValue();
+            const uint32_t dimension = data.at(index).inputOperandDimensionValue();
             index++;
 
             // store result
@@ -251,13 +254,14 @@
     outputs.reserve(numberOfOutputOperands);
     for (size_t operand = 0; operand < numberOfOutputOperands; ++operand) {
         // validate output operand information
-        if (data[index].getDiscriminator() != discriminator::outputOperandInformation) {
+        if (index >= data.size() ||
+            data.at(index).getDiscriminator() != discriminator::outputOperandInformation) {
             return NN_ERROR() << "FMQ Request packet ill-formed";
         }
 
         // unpackage operand information
         const FmqRequestDatum::OperandInformation& operandInfo =
-                data[index].outputOperandInformation();
+                data.at(index).outputOperandInformation();
         index++;
         const bool hasNoValue = operandInfo.hasNoValue;
         const V1_0::DataLocation location = operandInfo.location;
@@ -268,12 +272,13 @@
         dimensions.reserve(numberOfDimensions);
         for (size_t i = 0; i < numberOfDimensions; ++i) {
             // validate dimension
-            if (data[index].getDiscriminator() != discriminator::outputOperandDimensionValue) {
+            if (index >= data.size() ||
+                data.at(index).getDiscriminator() != discriminator::outputOperandDimensionValue) {
                 return NN_ERROR() << "FMQ Request packet ill-formed";
             }
 
             // unpackage dimension
-            const uint32_t dimension = data[index].outputOperandDimensionValue();
+            const uint32_t dimension = data.at(index).outputOperandDimensionValue();
             index++;
 
             // store result
@@ -290,12 +295,13 @@
     slots.reserve(numberOfPools);
     for (size_t pool = 0; pool < numberOfPools; ++pool) {
         // validate input operand information
-        if (data[index].getDiscriminator() != discriminator::poolIdentifier) {
+        if (index >= data.size() ||
+            data.at(index).getDiscriminator() != discriminator::poolIdentifier) {
             return NN_ERROR() << "FMQ Request packet ill-formed";
         }
 
         // unpackage operand information
-        const int32_t poolId = data[index].poolIdentifier();
+        const int32_t poolId = data.at(index).poolIdentifier();
         index++;
 
         // store result
@@ -303,17 +309,17 @@
     }
 
     // validate measureTiming
-    if (data[index].getDiscriminator() != discriminator::measureTiming) {
+    if (index >= data.size() || data.at(index).getDiscriminator() != discriminator::measureTiming) {
         return NN_ERROR() << "FMQ Request packet ill-formed";
     }
 
     // unpackage measureTiming
-    const V1_2::MeasureTiming measure = data[index].measureTiming();
+    const V1_2::MeasureTiming measure = data.at(index).measureTiming();
     index++;
 
     // validate packet information
     if (index != packetSize) {
-        return NN_ERROR() << "FMQ Result packet ill-formed";
+        return NN_ERROR() << "FMQ Request packet ill-formed";
     }
 
     // return request
@@ -328,12 +334,13 @@
     size_t index = 0;
 
     // validate packet information
-    if (data.size() == 0 || data[index].getDiscriminator() != discriminator::packetInformation) {
+    if (index >= data.size() ||
+        data.at(index).getDiscriminator() != discriminator::packetInformation) {
         return NN_ERROR() << "FMQ Result packet ill-formed";
     }
 
     // unpackage packet information
-    const FmqResultDatum::PacketInformation& packetInfo = data[index].packetInformation();
+    const FmqResultDatum::PacketInformation& packetInfo = data.at(index).packetInformation();
     index++;
     const uint32_t packetSize = packetInfo.packetSize;
     const V1_0::ErrorStatus errorStatus = packetInfo.errorStatus;
@@ -349,12 +356,13 @@
     outputShapes.reserve(numberOfOperands);
     for (size_t operand = 0; operand < numberOfOperands; ++operand) {
         // validate operand information
-        if (data[index].getDiscriminator() != discriminator::operandInformation) {
+        if (index >= data.size() ||
+            data.at(index).getDiscriminator() != discriminator::operandInformation) {
             return NN_ERROR() << "FMQ Result packet ill-formed";
         }
 
         // unpackage operand information
-        const FmqResultDatum::OperandInformation& operandInfo = data[index].operandInformation();
+        const FmqResultDatum::OperandInformation& operandInfo = data.at(index).operandInformation();
         index++;
         const bool isSufficient = operandInfo.isSufficient;
         const uint32_t numberOfDimensions = operandInfo.numberOfDimensions;
@@ -364,12 +372,13 @@
         dimensions.reserve(numberOfDimensions);
         for (size_t i = 0; i < numberOfDimensions; ++i) {
             // validate dimension
-            if (data[index].getDiscriminator() != discriminator::operandDimensionValue) {
+            if (index >= data.size() ||
+                data.at(index).getDiscriminator() != discriminator::operandDimensionValue) {
                 return NN_ERROR() << "FMQ Result packet ill-formed";
             }
 
             // unpackage dimension
-            const uint32_t dimension = data[index].operandDimensionValue();
+            const uint32_t dimension = data.at(index).operandDimensionValue();
             index++;
 
             // store result
@@ -381,12 +390,13 @@
     }
 
     // validate execution timing
-    if (data[index].getDiscriminator() != discriminator::executionTiming) {
+    if (index >= data.size() ||
+        data.at(index).getDiscriminator() != discriminator::executionTiming) {
         return NN_ERROR() << "FMQ Result packet ill-formed";
     }
 
     // unpackage execution timing
-    const V1_2::Timing timing = data[index].executionTiming();
+    const V1_2::Timing timing = data.at(index).executionTiming();
     index++;
 
     // validate packet information
diff --git a/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp
index dcf8451..e344458 100644
--- a/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp
+++ b/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp
@@ -736,8 +736,8 @@
                     // If a sync fence is returned, try start another run waiting for the sync
                     // fence.
                     if (testConfig.reusable) {
-                        ret = execution->executeFenced(waitFor, kNoDeadline, kNoDuration,
-                                                       &executionResult);
+                        // Nothing to do because at most one execution may occur on a reusable
+                        // execution object at any given time.
                     } else if (testConfig.useConfig) {
                         ret = preparedModel->executeFencedWithConfig(
                                 request, waitFor,
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 152858f..316c308 100644
--- a/radio/1.5/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.5/vts/functional/radio_hidl_hal_api.cpp
@@ -564,23 +564,23 @@
 TEST_P(RadioHidlTest_v1_5, startNetworkScan) {
     serial = GetRandomSerialNumber();
 
-    ::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands bandP900;
-    bandP900.geranBands() = {GeranBands::BAND_P900};
-    ::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands band850;
-    band850.geranBands() = {GeranBands::BAND_850};
-    ::android::hardware::radio::V1_5::RadioAccessSpecifier specifierP900 = {
-            .radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::GERAN,
-            .bands = bandP900,
+    ::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands band17;
+    band17.eutranBands({::android::hardware::radio::V1_5::EutranBands::BAND_17});
+    ::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands band20;
+    band20.eutranBands({::android::hardware::radio::V1_5::EutranBands::BAND_20});
+    ::android::hardware::radio::V1_5::RadioAccessSpecifier specifier17 = {
+            .radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::EUTRAN,
+            .bands = band17,
             .channels = {1, 2}};
-    ::android::hardware::radio::V1_5::RadioAccessSpecifier specifier850 = {
-            .radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::GERAN,
-            .bands = band850,
+    ::android::hardware::radio::V1_5::RadioAccessSpecifier specifier20 = {
+            .radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::EUTRAN,
+            .bands = band20,
             .channels = {128, 129}};
 
     ::android::hardware::radio::V1_5::NetworkScanRequest request = {
             .type = ScanType::ONE_SHOT,
             .interval = 60,
-            .specifiers = {specifierP900, specifier850},
+            .specifiers = {specifier17, specifier20},
             .maxSearchTime = 60,
             .incrementalResults = false,
             .incrementalResultsPeriodicity = 1};
@@ -595,12 +595,17 @@
     if (cardStatus.base.base.base.cardState == CardState::ABSENT) {
         ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error, {RadioError::SIM_ABSENT}));
     } else if (cardStatus.base.base.base.cardState == CardState::PRESENT) {
-        // OPERATION_NOT_ALLOWED should not be allowed; however, some vendors do
-        // not support the required manual GSM search functionality. This is
-        // tracked in b/112206766. Modems have "GSM" rat scan need to
+        // Modems support 3GPP RAT family need to
         // support scanning requests combined with some parameters.
-        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error,
-                                     {RadioError::NONE, RadioError::OPERATION_NOT_ALLOWED}));
+        if (deviceSupportsFeature(FEATURE_TELEPHONY_GSM)) {
+            ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error,
+                                         {RadioError::NONE, RadioError::OPERATION_NOT_ALLOWED}));
+        } else {
+            ASSERT_TRUE(CheckAnyOfErrors(
+                    radioRsp_v1_5->rspInfo.error,
+                    {RadioError::NONE, RadioError::OPERATION_NOT_ALLOWED,
+                     RadioError::REQUEST_NOT_SUPPORTED, RadioError::INVALID_ARGUMENTS}));
+        }
     }
 
     if (radioRsp_v1_5->rspInfo.error == RadioError::NONE) {
diff --git a/radio/aidl/vts/radio_network_test.cpp b/radio/aidl/vts/radio_network_test.cpp
index c83571e..61b34d7 100644
--- a/radio/aidl/vts/radio_network_test.cpp
+++ b/radio/aidl/vts/radio_network_test.cpp
@@ -829,20 +829,20 @@
 TEST_P(RadioNetworkTest, startNetworkScan) {
     serial = GetRandomSerialNumber();
 
-    RadioAccessSpecifierBands bandP900 =
-            RadioAccessSpecifierBands::make<RadioAccessSpecifierBands::geranBands>(
-                    {GeranBands::BAND_P900});
-    RadioAccessSpecifierBands band850 =
-            RadioAccessSpecifierBands::make<RadioAccessSpecifierBands::geranBands>(
-                    {GeranBands::BAND_850});
-    RadioAccessSpecifier specifierP900 = {
-            .accessNetwork = AccessNetwork::GERAN, .bands = bandP900, .channels = {1, 2}};
-    RadioAccessSpecifier specifier850 = {
-            .accessNetwork = AccessNetwork::GERAN, .bands = band850, .channels = {128, 129}};
+    RadioAccessSpecifierBands band17 =
+            RadioAccessSpecifierBands::make<RadioAccessSpecifierBands::eutranBands>(
+                    {EutranBands::BAND_17});
+    RadioAccessSpecifierBands band20 =
+            RadioAccessSpecifierBands::make<RadioAccessSpecifierBands::eutranBands>(
+                    {EutranBands::BAND_20});
+    RadioAccessSpecifier specifier17 = {
+            .accessNetwork = AccessNetwork::EUTRAN, .bands = band17, .channels = {1, 2}};
+    RadioAccessSpecifier specifier20 = {
+            .accessNetwork = AccessNetwork::EUTRAN, .bands = band20, .channels = {128, 129}};
 
     NetworkScanRequest request = {.type = NetworkScanRequest::SCAN_TYPE_ONE_SHOT,
                                   .interval = 60,
-                                  .specifiers = {specifierP900, specifier850},
+                                  .specifiers = {specifier17, specifier20},
                                   .maxSearchTime = 60,
                                   .incrementalResults = false,
                                   .incrementalResultsPeriodicity = 1};
@@ -858,12 +858,17 @@
     if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
         ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::SIM_ABSENT}));
     } else if (cardStatus.cardState == CardStatus::STATE_PRESENT) {
-        // OPERATION_NOT_ALLOWED should not be allowed; however, some vendors do
-        // not support the required manual GSM search functionality. This is
-        // tracked in b/112206766. Modems have "GSM" rat scan need to
-        // support scanning requests combined with some parameters.
-        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
-                                     {RadioError::NONE, RadioError::OPERATION_NOT_ALLOWED}));
+        if (deviceSupportsFeature(FEATURE_TELEPHONY_GSM)) {
+            // Modems support 3GPP RAT family need to
+            // support scanning requests combined with some parameters.
+            ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                         {RadioError::NONE, RadioError::OPERATION_NOT_ALLOWED}));
+        } else {
+            ASSERT_TRUE(CheckAnyOfErrors(
+                    radioRsp_network->rspInfo.error,
+                    {RadioError::NONE, RadioError::OPERATION_NOT_ALLOWED, RadioError::NONE,
+                     RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED}));
+        }
     }
 
     if (radioRsp_network->rspInfo.error == RadioError::NONE) {
diff --git a/scripts/anapic_hidl2aidl_review.sh b/scripts/anapic_hidl2aidl_review.sh
index 330ae32..ce72160 100755
--- a/scripts/anapic_hidl2aidl_review.sh
+++ b/scripts/anapic_hidl2aidl_review.sh
@@ -1,4 +1,11 @@
 #!/bin/bash
+#
+# Create two CLs for the given HIDL interface to see the diff between the
+# hidl2aidl output and the source at the tip-of-tree.
+# The first CL contains the hidl2aidl output after removing all existing AIDL
+# files.
+# The second CL contains all of the changes on top of the raw hidl2aidl output
+# that can be used for review.
 
 if [[ $# -ne 1 ]]; then
     echo "Usage: $0 INTERFACE_NAME"
@@ -23,5 +30,6 @@
 git commit -am "convert $1" --no-edit
 git revert HEAD --no-edit
 git commit --amend --no-edit
-repo upload . --no-verify
+git diff HEAD~1 --stat
+repo upload . --no-verify --wip --hashtag=anapic_release_review
 popd
diff --git a/scripts/anapic_release_diff.sh b/scripts/anapic_release_diff.sh
new file mode 100755
index 0000000..c22d9e5
--- /dev/null
+++ b/scripts/anapic_release_diff.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+#
+# Create a CL that contains the changes between this branch and a newer branch
+# for a given AIDL interface.
+# Be sure that BRANCH_BASE is the current upstream branch in order to get a CL.
+
+if [[ $# -ne 3 ]]; then
+    echo "Usage: $0 BRANCH_BASE BRANCH_NEW PACKAGE_NAME"
+    echo "- BRANCH_BASE current branch, typically a previous release's dev branch"
+    echo "- BRANCH_NEW end branch, typically goog/master as the latest branch"
+    echo "- PACKAGE_NAME this is the AIDL package name"
+    echo "example of creating the diffs for android.hardware.boot"
+    echo "$ git checkout tm-dev ; repo start review"
+    echo "$ ./anapic_release_diff.sh goog/tm-dev goog/master android.hardware.boot"
+    exit 1
+fi
+
+# for pathmod
+source ${ANDROID_BUILD_TOP}/build/make/envsetup.sh
+
+set -ex
+
+INTERFACE_NAME_NO_VER=${3%@*}
+pushd $(pathmod $INTERFACE_NAME_NO_VER)
+git diff "$1".."$2" android | git apply
+git add -A
+git commit -am "Android $1 to $2: $3" --no-edit
+git diff HEAD~1 --stat
+repo upload . --no-verify --wip --hashtag=anapic_release_review
+popd
diff --git a/secure_element/aidl/android/hardware/secure_element/ISecureElement.aidl b/secure_element/aidl/android/hardware/secure_element/ISecureElement.aidl
index b9ce9d1..800494a 100644
--- a/secure_element/aidl/android/hardware/secure_element/ISecureElement.aidl
+++ b/secure_element/aidl/android/hardware/secure_element/ISecureElement.aidl
@@ -117,12 +117,18 @@
      * closed by this operation.
      * HAL service must send onStateChange() with connected equal to true
      * after resetting and all the re-initialization has been successfully completed.
+     *
+     * @throws ServiceSpecificException on error with the following code:
+     *  - FAILED if the service was unable to reset the secure element.
      */
     void reset();
 
     /**
      * Transmits an APDU command (as per ISO/IEC 7816) to the SE.
      *
+     * @throws ServiceSpecificException with code CHANNEL_NOT_AVAILABLE
+     *  if there was an error in communicating with the secure element.
+     *
      * @param data APDU command to be sent
      * @return response to the command
      */
diff --git a/secure_element/aidl/vts/VtsHalSecureElementTargetTest.cpp b/secure_element/aidl/vts/VtsHalSecureElementTargetTest.cpp
index 37ff1b2..97b4e27 100644
--- a/secure_element/aidl/vts/VtsHalSecureElementTargetTest.cpp
+++ b/secure_element/aidl/vts/VtsHalSecureElementTargetTest.cpp
@@ -83,10 +83,15 @@
 
     void expectCallbackHistory(std::vector<bool>&& want) {
         std::unique_lock<std::mutex> l(m);
-        cv.wait_for(l, 2s, [&]() { return history.size() >= want.size(); });
+        cv.wait_for(l, 5s, [&]() { return history.size() >= want.size(); });
         EXPECT_THAT(history, ElementsAreArray(want));
     }
 
+    void resetCallbackHistory() {
+        std::unique_lock<std::mutex> l(m);
+        history.clear();
+    }
+
   private:
     std::mutex m;  // guards history
     std::condition_variable cv;
@@ -106,10 +111,21 @@
 
         EXPECT_OK(secure_element_->init(secure_element_callback_));
         secure_element_callback_->expectCallbackHistory({true});
+
+        // Check if the basic channel is supported by the bound SE.
+        std::vector<uint8_t> basic_channel_response;
+        auto status =
+                secure_element_->openBasicChannel(kSelectableAid, 0x00, &basic_channel_response);
+        if (status.isOk()) {
+            basic_channel_supported_ = true;
+            secure_element_->closeChannel(0);
+        }
     }
 
     void TearDown() override {
+        secure_element_callback_->resetCallbackHistory();
         EXPECT_OK(secure_element_->reset());
+        secure_element_callback_->expectCallbackHistory({false, true});
         secure_element_ = nullptr;
         secure_element_callback_ = nullptr;
     }
@@ -127,22 +143,32 @@
             apdu[0] |= (channel_number - 4) | 0x40;
         }
 
-        EXPECT_OK(secure_element_->transmit(apdu, &response));
+        // transmit() will return an empty response with the error
+        // code CHANNEL_NOT_AVAILABLE when the SE cannot be
+        // communicated with.
+        auto status = secure_element_->transmit(apdu, &response);
+        if (!status.isOk()) {
+            return 0x6881;
+        }
+
+        // transmit() will return a response containing at least
+        // the APDU response status otherwise.
         EXPECT_GE(response.size(), 2u);
-        uint16_t status =
+        uint16_t apdu_status =
                 (response[response.size() - 2] << 8) | (response[response.size() - 1] << 0);
 
         // When the command is successful the response
         // must contain 256 bytes of data.
-        if (status == 0x9000) {
+        if (apdu_status == 0x9000) {
             EXPECT_EQ(response.size(), 258);
         }
 
-        return status;
+        return apdu_status;
     }
 
     std::shared_ptr<ISecureElement> secure_element_;
     std::shared_ptr<MySecureElementCallback> secure_element_callback_;
+    bool basic_channel_supported_{false};
 };
 
 TEST_P(SecureElementAidl, init) {
@@ -159,14 +185,18 @@
     LogicalChannelResponse logical_channel_response;
 
     // reset called after init shall succeed.
-    EXPECT_OK(secure_element_->openBasicChannel(kSelectableAid, 0x00, &basic_channel_response));
+    if (basic_channel_supported_) {
+        EXPECT_OK(secure_element_->openBasicChannel(kSelectableAid, 0x00, &basic_channel_response));
+    }
     EXPECT_OK(secure_element_->openLogicalChannel(kSelectableAid, 0x00, &logical_channel_response));
 
     EXPECT_OK(secure_element_->reset());
     secure_element_callback_->expectCallbackHistory({true, false, true});
 
     // All opened channels must be closed.
-    EXPECT_NE(transmit(0), 0x9000);
+    if (basic_channel_supported_) {
+        EXPECT_NE(transmit(0), 0x9000);
+    }
     EXPECT_NE(transmit(logical_channel_response.channelNumber), 0x9000);
 }
 
@@ -190,6 +220,10 @@
 TEST_P(SecureElementAidl, openBasicChannel) {
     std::vector<uint8_t> response;
 
+    if (!basic_channel_supported_) {
+        return;
+    }
+
     // openBasicChannel called with an invalid AID shall fail.
     EXPECT_ERR(secure_element_->openBasicChannel(kNonSelectableAid, 0x00, &response));
 
@@ -199,7 +233,7 @@
     EXPECT_OK(secure_element_->openBasicChannel(kSelectableAid, 0x00, &response));
     EXPECT_GE(response.size(), 2u);
 
-    // tramsmit called on the basic channel should succeed.
+    // transmit called on the basic channel should succeed.
     EXPECT_EQ(transmit(0), 0x9000);
 
     // openBasicChannel called a second time shall fail.
@@ -225,7 +259,7 @@
     EXPECT_GE(response.channelNumber, 1u);
     EXPECT_LE(response.channelNumber, 19u);
 
-    // tramsmit called on the logical channel should succeed.
+    // transmit called on the logical channel should succeed.
     EXPECT_EQ(transmit(response.channelNumber), 0x9000);
 }
 
@@ -239,30 +273,39 @@
     EXPECT_ERR(secure_element_->closeChannel(1));
 
     // closeChannel called on basic channel closes the basic channel.
-    EXPECT_OK(secure_element_->openBasicChannel(kSelectableAid, 0x00, &basic_channel_response));
-    EXPECT_OK(secure_element_->closeChannel(0));
+    if (basic_channel_supported_) {
+        EXPECT_OK(secure_element_->openBasicChannel(kSelectableAid, 0x00, &basic_channel_response));
+        EXPECT_OK(secure_element_->closeChannel(0));
 
-    // tramsmit called on the basic channel should fail.
-    EXPECT_NE(transmit(0), 0x9000);
+        // transmit called on the basic channel should fail.
+        EXPECT_NE(transmit(0), 0x9000);
+    }
 
     // closeChannel called on logical channel closes the logical channel.
     EXPECT_OK(secure_element_->openLogicalChannel(kSelectableAid, 0x00, &logical_channel_response));
     EXPECT_OK(secure_element_->closeChannel(logical_channel_response.channelNumber));
 
-    // tramsmit called on the basic channel should fail.
+    // transmit called on the logical channel should fail.
     EXPECT_NE(transmit(logical_channel_response.channelNumber), 0x9000);
 }
 
 TEST_P(SecureElementAidl, transmit) {
     std::vector<uint8_t> response;
+    LogicalChannelResponse logical_channel_response;
 
-    // transmit called after init shall succeed.
-    // Note: no channel is opened for this test and the transmit
-    // response will have the status SW_LOGICAL_CHANNEL_NOT_SUPPORTED.
-    // The transmit response shall be larger than 2 bytes as it includes the
-    // status code.
-    EXPECT_OK(secure_element_->transmit(kDataApdu, &response));
-    EXPECT_GE(response.size(), 2u);
+    // Note: no channel is opened for this test
+    // transmit() will return an empty response with the error
+    // code CHANNEL_NOT_AVAILABLE when the SE cannot be
+    // communicated with.
+    EXPECT_ERR(secure_element_->transmit(kDataApdu, &response));
+
+    EXPECT_OK(secure_element_->openLogicalChannel(kSelectableAid, 0x00, &logical_channel_response));
+    EXPECT_GE(logical_channel_response.selectResponse.size(), 2u);
+    EXPECT_GE(logical_channel_response.channelNumber, 1u);
+    EXPECT_LE(logical_channel_response.channelNumber, 19u);
+
+    // transmit called on the logical channel should succeed.
+    EXPECT_EQ(transmit(logical_channel_response.channelNumber), 0x9000);
 }
 
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SecureElementAidl);
diff --git a/security/dice/aidl/Android.bp b/security/dice/aidl/Android.bp
deleted file mode 100644
index 5625d70..0000000
--- a/security/dice/aidl/Android.bp
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2021, The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "hardware_interfaces_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["hardware_interfaces_license"],
-}
-
-aidl_interface {
-    name: "android.hardware.security.dice",
-    vendor_available: true,
-    srcs: [
-        "android/hardware/security/dice/*.aidl",
-    ],
-    stability: "vintf",
-    backend: {
-        java: {
-            enabled: false,
-            platform_apis: false,
-        },
-        ndk: {
-            apps_enabled: false,
-            apex_available: [
-                "//apex_available:platform",
-                "com.android.compos",
-            ],
-        },
-        rust: {
-            enabled: true,
-            apex_available: [
-                "//apex_available:platform",
-                "com.android.compos",
-            ],
-        },
-    },
-    versions_with_info: [
-        {
-            version: "1",
-            imports: [],
-        },
-    ],
-
-    //     versions: ["1"],
-}
diff --git a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/.hash b/security/dice/aidl/aidl_api/android.hardware.security.dice/1/.hash
deleted file mode 100644
index 3f08fd8..0000000
--- a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/.hash
+++ /dev/null
@@ -1 +0,0 @@
-02994f275fd7b1b40610c10eaeb0573f4312e358
diff --git a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/Bcc.aidl b/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/Bcc.aidl
deleted file mode 100644
index 5af7358..0000000
--- a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/Bcc.aidl
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2021, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-///////////////////////////////////////////////////////////////////////////////
-// 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.security.dice;
-/* @hide */
-@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability
-parcelable Bcc {
-  byte[] data;
-}
diff --git a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/BccHandover.aidl b/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/BccHandover.aidl
deleted file mode 100644
index 8baca94..0000000
--- a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/BccHandover.aidl
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright 2021, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-///////////////////////////////////////////////////////////////////////////////
-// 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.security.dice;
-/* @hide */
-@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability
-parcelable BccHandover {
-  byte[32] cdiAttest;
-  byte[32] cdiSeal;
-  android.hardware.security.dice.Bcc bcc;
-}
diff --git a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/Config.aidl b/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/Config.aidl
deleted file mode 100644
index 78dd2f8..0000000
--- a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/Config.aidl
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2021, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-///////////////////////////////////////////////////////////////////////////////
-// 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.security.dice;
-/* @hide */
-@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability
-parcelable Config {
-  byte[] desc;
-}
diff --git a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/InputValues.aidl b/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/InputValues.aidl
deleted file mode 100644
index e43c429..0000000
--- a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/InputValues.aidl
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright 2021, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-///////////////////////////////////////////////////////////////////////////////
-// 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.security.dice;
-/* @hide */
-@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability
-parcelable InputValues {
-  byte[64] codeHash;
-  android.hardware.security.dice.Config config;
-  byte[64] authorityHash;
-  @nullable byte[] authorityDescriptor;
-  android.hardware.security.dice.Mode mode = android.hardware.security.dice.Mode.NOT_INITIALIZED;
-  byte[64] hidden;
-}
diff --git a/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/Bcc.aidl b/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/Bcc.aidl
deleted file mode 100644
index 5af7358..0000000
--- a/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/Bcc.aidl
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2021, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-///////////////////////////////////////////////////////////////////////////////
-// 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.security.dice;
-/* @hide */
-@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability
-parcelable Bcc {
-  byte[] data;
-}
diff --git a/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/BccHandover.aidl b/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/BccHandover.aidl
deleted file mode 100644
index 8baca94..0000000
--- a/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/BccHandover.aidl
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright 2021, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-///////////////////////////////////////////////////////////////////////////////
-// 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.security.dice;
-/* @hide */
-@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability
-parcelable BccHandover {
-  byte[32] cdiAttest;
-  byte[32] cdiSeal;
-  android.hardware.security.dice.Bcc bcc;
-}
diff --git a/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/Config.aidl b/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/Config.aidl
deleted file mode 100644
index 78dd2f8..0000000
--- a/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/Config.aidl
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2021, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-///////////////////////////////////////////////////////////////////////////////
-// 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.security.dice;
-/* @hide */
-@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability
-parcelable Config {
-  byte[] desc;
-}
diff --git a/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/IDiceDevice.aidl b/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/IDiceDevice.aidl
deleted file mode 100644
index 383f4d1..0000000
--- a/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/IDiceDevice.aidl
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-///////////////////////////////////////////////////////////////////////////////
-// 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.security.dice;
-/* @hide */
-@SensitiveData @VintfStability
-interface IDiceDevice {
-  android.hardware.security.dice.Signature sign(in android.hardware.security.dice.InputValues[] id, in byte[] payload);
-  android.hardware.security.dice.Bcc getAttestationChain(in android.hardware.security.dice.InputValues[] inputValues);
-  android.hardware.security.dice.BccHandover derive(in android.hardware.security.dice.InputValues[] inputValues);
-  void demote(in android.hardware.security.dice.InputValues[] inputValues);
-}
diff --git a/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/InputValues.aidl b/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/InputValues.aidl
deleted file mode 100644
index e43c429..0000000
--- a/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/InputValues.aidl
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright 2021, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-///////////////////////////////////////////////////////////////////////////////
-// 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.security.dice;
-/* @hide */
-@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability
-parcelable InputValues {
-  byte[64] codeHash;
-  android.hardware.security.dice.Config config;
-  byte[64] authorityHash;
-  @nullable byte[] authorityDescriptor;
-  android.hardware.security.dice.Mode mode = android.hardware.security.dice.Mode.NOT_INITIALIZED;
-  byte[64] hidden;
-}
diff --git a/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/Mode.aidl b/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/Mode.aidl
deleted file mode 100644
index 295c32e..0000000
--- a/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/Mode.aidl
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright 2021, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-///////////////////////////////////////////////////////////////////////////////
-// 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.security.dice;
-/* @hide */
-@Backing(type="int") @VintfStability
-enum Mode {
-  NOT_INITIALIZED = 0,
-  NORMAL = 1,
-  DEBUG = 2,
-  RECOVERY = 3,
-}
diff --git a/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/ResponseCode.aidl b/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/ResponseCode.aidl
deleted file mode 100644
index c13afa6..0000000
--- a/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/ResponseCode.aidl
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright 2020, 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.security.dice;
-@Backing(type="int") @VintfStability
-enum ResponseCode {
-  PERMISSION_DENIED = 1,
-  SYSTEM_ERROR = 2,
-  NOT_IMPLEMENTED = 3,
-  DEMOTION_FAILED = 4,
-}
diff --git a/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/Signature.aidl b/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/Signature.aidl
deleted file mode 100644
index 294170d..0000000
--- a/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/Signature.aidl
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2021, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-///////////////////////////////////////////////////////////////////////////////
-// 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.security.dice;
-/* @hide */
-@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability
-parcelable Signature {
-  byte[] data;
-}
diff --git a/security/dice/aidl/android/hardware/security/dice/Bcc.aidl b/security/dice/aidl/android/hardware/security/dice/Bcc.aidl
deleted file mode 100644
index 983915e..0000000
--- a/security/dice/aidl/android/hardware/security/dice/Bcc.aidl
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright 2021, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.security.dice;
-
-/**
- * A DICE certificate chain following the Boot Certificate Chain (BCC) specification.
- * @hide
- */
-@VintfStability
-@RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true)
-parcelable Bcc {
-    /**
-     * The DICE certificate chain CBOR encoded following the BCC specification. The CDDL
-     * specification for BCC can be found here [1].
-     *
-     * @see <a
-     *         href="https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl">
-     *    BCC CDDL specification
-     * </a>
-     */
-    byte[] data;
-}
diff --git a/security/dice/aidl/android/hardware/security/dice/BccHandover.aidl b/security/dice/aidl/android/hardware/security/dice/BccHandover.aidl
deleted file mode 100644
index 6ca862c..0000000
--- a/security/dice/aidl/android/hardware/security/dice/BccHandover.aidl
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2021, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.security.dice;
-
-import android.hardware.security.dice.Bcc;
-
-/**
- * Represents one set of DICE artifacts.
- *
- * @hide
- */
-@VintfStability
-@RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true)
-parcelable BccHandover {
-    /**
-     * CDI_attest. Must be exactly 32 bytes of data.
-     */
-    byte[32] cdiAttest;
-    /**
-     * CDI_seal. Must be exactly 32 bytes of data.
-     */
-    byte[32] cdiSeal;
-    /**
-     * CBOR encoded BCC.
-     *
-     * @see <a
-     *         href="https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl">
-     *    BCC CDDL specification
-     * </a>
-     */
-    Bcc bcc;
-}
diff --git a/security/dice/aidl/android/hardware/security/dice/Config.aidl b/security/dice/aidl/android/hardware/security/dice/Config.aidl
deleted file mode 100644
index 6decfc5..0000000
--- a/security/dice/aidl/android/hardware/security/dice/Config.aidl
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2021, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.security.dice;
-
-/**
- * DICE config descriptor as described in at
- * <a
- * href="https://pigweed.googlesource.com/open-dice/+/refs/heads/main/docs/specification.md#input-values">
- *     input-values
- * </a>
- * @hide
- */
-@VintfStability
-@RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true)
-parcelable Config {
-    /**
-     * A free form descriptor. This should follow the BCC Configuration Descriptor.
-     * @see <a
-     *         href="https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl">
-     *     BccPayload field -4670548
-     * </a>
-     */
-    byte[] desc;
-}
diff --git a/security/dice/aidl/android/hardware/security/dice/IDiceDevice.aidl b/security/dice/aidl/android/hardware/security/dice/IDiceDevice.aidl
deleted file mode 100644
index 709aede..0000000
--- a/security/dice/aidl/android/hardware/security/dice/IDiceDevice.aidl
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.security.dice;
-
-import android.hardware.security.dice.Bcc;
-import android.hardware.security.dice.BccHandover;
-import android.hardware.security.dice.InputValues;
-import android.hardware.security.dice.Signature;
-
-/**
- * IDiceDevice specifies an interface that allows access to the Android instance's DICE artifacts.
- *
- * <h2>Features</h2>
- *
- * The dice device provides access to the component's CDI_SEAL and CDI_ATTEST secrets as well
- * as to its attestation certificate chain. The "component" is the Android instance running this
- * HAL service and the secrets and attestation chain must include all boot stage components,
- * the kernel, and the verified boot information (VBA).
- *
- * Implementations provide the following operations:
- * <li> sign - Signing a payload with a key derived from CDI_ATTEST.
- * <li> getAttestationChain - Retrieve the component's attestation certificate chain.
- * <li> derive - Retrieve the component's DICE artifacts.
- *
- * @see <a
- *         href="https://pigweed.googlesource.com/open-dice/+/refs/heads/main/docs/specification.md">
- *     Open-dice Specification
- * </a>
- * @see <a
- *         href="https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl">
- *     Boot Certificate Chain (BCC) CDDL specification
- * </a>
- * @hide
- */
-@SensitiveData
-@VintfStability
-interface IDiceDevice {
-    /**
-     * Uses the a key derived from the component's, or a child's given by <code>inputValues</code>,
-     * attestation secret to sign the payload using RFC 8032 Pure Ed25519 and returns the
-     * signature. The payload is limited to 1024 bytes.
-     *
-     * @see <a href="https://datatracker.ietf.org/doc/html/rfc8032">RFC 8032</a>
-     */
-    Signature sign(in InputValues[] id, in byte[] payload);
-
-    /**
-     * Returns the attestation chain of the component if <code>inputValues</code> is empty or the
-     * chain to the given child of the component identified by the <code>inputValues</code> vector.
-     *
-     * ## Error as service specific exception:
-     *     ResponseCode::PERMISSION_DENIED if the caller is not sufficiently privileged.
-     */
-    Bcc getAttestationChain(in InputValues[] inputValues);
-
-    /**
-     * This function allows a client to become a resident node. A resident node is a node that
-     * manages its own dice secrets as opposed to using them by proxy, i.e., by calling sign
-     * and getAttestationChain. Called with empty <code>inputValues</code> vectors, an
-     * implementation returns the component's DICE secrets. If the <code>inputValues</code> vector
-     * is given the appropriate derivations are performed starting from the component's level.
-     *
-     * ## Error as service specific exception:
-     *     ResponseCode::PERMISSION_DENIED if the implementation does not allow resident nodes
-     *     at the client's level.
-     */
-    BccHandover derive(in InputValues[] inputValues);
-
-    /**
-     * This demotes the implementation of this interface.
-     * When called, the implementation performs appropriate derivation steps using
-     * <code>inputValues</code>, traversing the vector in ascending order. Then it replaces its
-     * stored DICE artifacts with the newly derived ones.
-     *
-     * IMPORTANT: When the function returns, all remnants of the previous DICE artifacts must
-     * have been purged from memory.
-     *
-     * This operation is not reversible until the next reboot. Further demotion is always
-     * possible.
-     *
-     * ## Error as service specific exception:
-     *     ResponseCode::DEMOTION_FAILED if the implementation failed to demote itself
-     *     or was unable to purge previous DICE artifacts from memory.
-     */
-    void demote(in InputValues[] inputValues);
-}
diff --git a/security/dice/aidl/android/hardware/security/dice/InputValues.aidl b/security/dice/aidl/android/hardware/security/dice/InputValues.aidl
deleted file mode 100644
index 711d523..0000000
--- a/security/dice/aidl/android/hardware/security/dice/InputValues.aidl
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright 2021, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.security.dice;
-
-import android.hardware.security.dice.Config;
-import android.hardware.security.dice.Mode;
-
-/**
- * DICE input values for certificate and CDI generation.
- *
- * @see <a
- *         href="https://pigweed.googlesource.com/open-dice/+/refs/heads/main/docs/specification.md#input-values">
- *     Open-dice input-values
- * </a>
- * @hide
- */
-@RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true)
-@VintfStability
-parcelable InputValues {
-    /**
-     * The target code hash. Must be exactly 64 bytes.
-     */
-    byte[64] codeHash;
-    /**
-     * The configuration data.
-     */
-    Config config;
-    /**
-     * The authority hash. Must be exactly 64 bytes. Must be all zero if unused.
-     */
-    byte[64] authorityHash;
-    /**
-     * Optional free form authorityDescriptor.
-     */
-    @nullable byte[] authorityDescriptor;
-    /**
-     * The mode of operation. Normal, Debug, Maintenance, or not initialized.
-     */
-    Mode mode = Mode.NOT_INITIALIZED;
-    /**
-     * Optional hidden values. Must be exactly 64 bytes. Must be all zero if unused.
-     */
-    byte[64] hidden;
-}
diff --git a/security/dice/aidl/android/hardware/security/dice/Mode.aidl b/security/dice/aidl/android/hardware/security/dice/Mode.aidl
deleted file mode 100644
index 3b3bfdc..0000000
--- a/security/dice/aidl/android/hardware/security/dice/Mode.aidl
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2021, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.security.dice;
-
-/**
- * DICE mode values as defined at
- *
- * @see <a
- *         href="https://pigweed.googlesource.com/open-dice/+/refs/heads/main/docs/specification.md#mode-value-details">
- *     open-dice mode-value-details
- * </a>
- * @hide
- */
-@Backing(type="int")
-@VintfStability
-enum Mode {
-    NOT_INITIALIZED = 0,
-    NORMAL = 1,
-    DEBUG = 2,
-    /**
-     * The recovery mode is also referred to as "maintenance" mode.
-     */
-    RECOVERY = 3,
-}
diff --git a/security/dice/aidl/android/hardware/security/dice/ResponseCode.aidl b/security/dice/aidl/android/hardware/security/dice/ResponseCode.aidl
deleted file mode 100644
index 3e77cf7..0000000
--- a/security/dice/aidl/android/hardware/security/dice/ResponseCode.aidl
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright 2020, 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.security.dice;
-
-@Backing(type="int")
-/**
- * These response codes are used as service specific exception codes by
- * IDiceDevice.
- * @hide
- */
-@VintfStability
-enum ResponseCode {
-    /**
-     * The caller has insufficient privilege to access the DICE API.
-     */
-    PERMISSION_DENIED = 1,
-    /**
-     * An unexpected error occurred, likely with IO or IPC.
-     */
-    SYSTEM_ERROR = 2,
-    /**
-     * Returned if the called function is not implemented.
-     */
-    NOT_IMPLEMENTED = 3,
-    /**
-     * An attempt to demote the implementation failed.
-     */
-    DEMOTION_FAILED = 4,
-}
diff --git a/security/dice/aidl/android/hardware/security/dice/Signature.aidl b/security/dice/aidl/android/hardware/security/dice/Signature.aidl
deleted file mode 100644
index ea3594f..0000000
--- a/security/dice/aidl/android/hardware/security/dice/Signature.aidl
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright 2021, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.security.dice;
-
-/**
- * This parcelable represents a Signature. It is used as return value of IDiceNode::sign.
- *
- * @hide
- */
-@RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true)
-@VintfStability
-parcelable Signature {
-    /**
-     * The RFC 8032 PureEd25519 signature.
-     * @see <a href="https://datatracker.ietf.org/doc/html/rfc8032">RFC 8032</a>
-     */
-    byte[] data;
-}
diff --git a/security/dice/aidl/default/Android.bp b/security/dice/aidl/default/Android.bp
deleted file mode 100644
index b67a44a..0000000
--- a/security/dice/aidl/default/Android.bp
+++ /dev/null
@@ -1,30 +0,0 @@
-package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "hardware_interfaces_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["hardware_interfaces_license"],
-}
-
-rust_binary {
-    name: "android.hardware.security.dice-service.non-secure-software",
-    srcs: ["service.rs"],
-    relative_install_path: "hw",
-    vendor: true,
-    rustlibs: [
-        "android.hardware.security.dice-V1-rust",
-        "libdiced_open_dice_cbor",
-        "libdiced_sample_inputs",
-        "libdiced_vendor",
-        "libandroid_logger",
-        "libanyhow",
-        "libbinder_rs",
-        "liblog_rust",
-        "libserde",
-    ],
-    init_rc: ["android.hardware.security.dice-service.non-secure-software.rc"],
-    vintf_fragments: [
-        "android.hardware.security.dice-service.non-secure-software.xml",
-    ],
-}
diff --git a/security/dice/aidl/default/android.hardware.security.dice-service.non-secure-software.rc b/security/dice/aidl/default/android.hardware.security.dice-service.non-secure-software.rc
deleted file mode 100644
index 28e43c3..0000000
--- a/security/dice/aidl/default/android.hardware.security.dice-service.non-secure-software.rc
+++ /dev/null
@@ -1,9 +0,0 @@
-service vendor.dice /vendor/bin/hw/android.hardware.security.dice-service.non-secure-software
-    class early_hal
-    user nobody
-    # The diced HAL cannot be allowed to restart. When it crashes for any reason.
-    # it loses security critical state. The only remedy is to restart the device.
-    # This may be implementation depended. It is safe to restart the HAL if the
-    # state change during a call to "demote" is is preserved.
-    # see android/hardware/security/dice/IDiceDevice.aidl for details on "demote".
-    oneshot
diff --git a/security/dice/aidl/default/android.hardware.security.dice-service.non-secure-software.xml b/security/dice/aidl/default/android.hardware.security.dice-service.non-secure-software.xml
deleted file mode 100644
index 94ef243..0000000
--- a/security/dice/aidl/default/android.hardware.security.dice-service.non-secure-software.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<manifest version="1.0" type="device">
-    <hal format="aidl">
-        <name>android.hardware.security.dice</name>
-        <fqname>IDiceDevice/default</fqname>
-    </hal>
-</manifest>
\ No newline at end of file
diff --git a/security/dice/aidl/default/service.rs b/security/dice/aidl/default/service.rs
deleted file mode 100644
index eebf333..0000000
--- a/security/dice/aidl/default/service.rs
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright 2021, The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-//! Main entry point for the android.hardware.security.dice service.
-
-use anyhow::Result;
-use diced::{
-    dice,
-    hal_node::{DiceArtifacts, DiceDevice, ResidentHal, UpdatableDiceArtifacts},
-};
-use diced_sample_inputs::make_sample_bcc_and_cdis;
-use serde::{Deserialize, Serialize};
-use std::convert::TryInto;
-use std::panic;
-use std::sync::Arc;
-
-static DICE_HAL_SERVICE_NAME: &str = "android.hardware.security.dice.IDiceDevice/default";
-
-#[derive(Debug, Serialize, Deserialize, Clone)]
-struct InsecureSerializableArtifacts {
-    cdi_attest: [u8; dice::CDI_SIZE],
-    cdi_seal: [u8; dice::CDI_SIZE],
-    bcc: Vec<u8>,
-}
-
-impl DiceArtifacts for InsecureSerializableArtifacts {
-    fn cdi_attest(&self) -> &[u8; dice::CDI_SIZE] {
-        &self.cdi_attest
-    }
-    fn cdi_seal(&self) -> &[u8; dice::CDI_SIZE] {
-        &self.cdi_seal
-    }
-    fn bcc(&self) -> Vec<u8> {
-        self.bcc.clone()
-    }
-}
-
-impl UpdatableDiceArtifacts for InsecureSerializableArtifacts {
-    fn with_artifacts<F, T>(&self, f: F) -> Result<T>
-    where
-        F: FnOnce(&dyn DiceArtifacts) -> Result<T>,
-    {
-        f(self)
-    }
-    fn update(self, new_artifacts: &impl DiceArtifacts) -> Result<Self> {
-        Ok(Self {
-            cdi_attest: *new_artifacts.cdi_attest(),
-            cdi_seal: *new_artifacts.cdi_seal(),
-            bcc: new_artifacts.bcc(),
-        })
-    }
-}
-
-fn main() {
-    android_logger::init_once(
-        android_logger::Config::default()
-            .with_tag("android.hardware.security.dice")
-            .with_min_level(log::Level::Debug),
-    );
-    // Redirect panic messages to logcat.
-    panic::set_hook(Box::new(|panic_info| {
-        log::error!("{}", panic_info);
-    }));
-
-    // Saying hi.
-    log::info!("android.hardware.security.dice is starting.");
-
-    let (cdi_attest, cdi_seal, bcc) =
-        make_sample_bcc_and_cdis().expect("Failed to construct sample dice chain.");
-
-    let hal_impl = Arc::new(
-        unsafe {
-            // Safety: ResidentHal cannot be used in multi threaded processes.
-            // This service does not start a thread pool. The main thread is the only thread
-            // joining the thread pool, thereby keeping the process single threaded.
-            ResidentHal::new(InsecureSerializableArtifacts {
-                cdi_attest: cdi_attest[..]
-                    .try_into()
-                    .expect("Failed to convert cdi_attest to array reference."),
-                cdi_seal: cdi_seal[..]
-                    .try_into()
-                    .expect("Failed to convert cdi_seal to array reference."),
-                bcc,
-            })
-        }
-        .expect("Failed to create ResidentHal implementation."),
-    );
-
-    let hal = DiceDevice::new_as_binder(hal_impl).expect("Failed to construct hal service.");
-
-    binder::add_service(DICE_HAL_SERVICE_NAME, hal.as_binder())
-        .expect("Failed to register IDiceDevice Service");
-
-    log::info!("Joining thread pool now.");
-    binder::ProcessState::join_thread_pool();
-}
diff --git a/security/dice/aidl/vts/functional/Android.bp b/security/dice/aidl/vts/functional/Android.bp
deleted file mode 100644
index f5bc949..0000000
--- a/security/dice/aidl/vts/functional/Android.bp
+++ /dev/null
@@ -1,54 +0,0 @@
-package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "hardware_interfaces_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["hardware_interfaces_license"],
-}
-
-rust_test {
-    name: "VtsAidlDiceTargetTest",
-    srcs: [
-        "dice_test.rs",
-    ],
-    require_root: true,
-    auto_gen_config: true,
-    test_suites: [
-        "general-tests",
-        "vts",
-    ],
-
-    rustlibs: [
-        "android.hardware.security.dice-V1-rust",
-        "libanyhow",
-        "libbinder_rs",
-        "libdiced_open_dice_cbor",
-        "libdiced_sample_inputs",
-        "libdiced_utils",
-        "libkeystore2_vintf_rust",
-    ],
-}
-
-rust_test {
-    name: "VtsAidlDiceDemoteTargetTest",
-    srcs: [
-        "dice_demote_test.rs",
-    ],
-
-    test_config: "VtsAidlDiceDemoteTargetTest.xml",
-    test_suites: [
-        "general-tests",
-        "vts",
-    ],
-
-    rustlibs: [
-        "android.hardware.security.dice-V1-rust",
-        "libanyhow",
-        "libbinder_rs",
-        "libdiced_open_dice_cbor",
-        "libdiced_sample_inputs",
-        "libdiced_utils",
-        "libkeystore2_vintf_rust",
-    ],
-}
diff --git a/security/dice/aidl/vts/functional/VtsAidlDiceDemoteTargetTest.xml b/security/dice/aidl/vts/functional/VtsAidlDiceDemoteTargetTest.xml
deleted file mode 100644
index 2991580..0000000
--- a/security/dice/aidl/vts/functional/VtsAidlDiceDemoteTargetTest.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2019 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="Config to run VtsAidlDiceDemoteTargetTest device tests.">
-
-    <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="VtsAidlDiceDemoteTargetTest->/data/local/tmp/VtsAidlDiceDemoteTargetTest" />
-    </target_preparer>
-
-    <test class="com.android.tradefed.testtype.rust.RustBinaryTest" >
-        <option name="test-device-path" value="/data/local/tmp" />
-        <option name="module-name" value="VtsAidlDiceDemoteTargetTest" />
-    </test>
-    <target_preparer class="com.android.tradefed.targetprep.RebootTargetPreparer" />
-
-</configuration>
\ No newline at end of file
diff --git a/security/dice/aidl/vts/functional/dice_demote_test.rs b/security/dice/aidl/vts/functional/dice_demote_test.rs
deleted file mode 100644
index 1a17ec7..0000000
--- a/security/dice/aidl/vts/functional/dice_demote_test.rs
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2021, The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-use diced_sample_inputs;
-use diced_utils;
-use std::convert::TryInto;
-
-mod utils;
-use utils::with_connection;
-
-// This test calls derive with an empty argument vector, then demotes the HAL using
-// a set of three input values, and then calls derive with empty argument vector again.
-// It then performs the same three derivation steps on the result of the former and compares
-// the result to the result of the latter.
-#[test]
-fn demote_test() {
-    with_connection(|device| {
-        let input_values = diced_sample_inputs::get_input_values_vector();
-        let former = device.derive(&[]).expect("Trying to call derive.");
-        device
-            .demote(&input_values)
-            .expect("Trying to call demote with input values.");
-
-        let latter = device
-            .derive(&[])
-            .expect("Trying to call derive after demote.");
-
-        let artifacts = diced_utils::ResidentArtifacts::new(
-            former.cdiAttest[..].try_into().unwrap(),
-            former.cdiSeal[..].try_into().unwrap(),
-            &former.bcc.data,
-        )
-        .unwrap();
-
-        let artifacts = artifacts.execute_steps(input_values.iter()).unwrap();
-        let (cdi_attest, cdi_seal, bcc) = artifacts.into_tuple();
-        let from_former = diced_utils::make_bcc_handover(
-            cdi_attest[..].try_into().unwrap(),
-            cdi_seal[..].try_into().unwrap(),
-            &bcc,
-        )
-        .unwrap();
-        // TODO b/204938506 when we have a parser/verifier, check equivalence rather
-        // than bit by bit equality.
-        assert_eq!(latter, from_former);
-        Ok(())
-    })
-}
diff --git a/security/dice/aidl/vts/functional/dice_test.rs b/security/dice/aidl/vts/functional/dice_test.rs
deleted file mode 100644
index 190f187..0000000
--- a/security/dice/aidl/vts/functional/dice_test.rs
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2021, The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-use diced_sample_inputs;
-use diced_utils;
-use std::convert::TryInto;
-
-mod utils;
-use utils::with_connection;
-
-static TEST_MESSAGE: &[u8] = &[
-    // "My test message!"
-    0x4d, 0x79, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x21,
-    0x0a,
-];
-
-// This test calls derive with an empty argument vector and with a set of three input values.
-// It then performs the same three derivation steps on the result of the former and compares
-// the result to the result of the latter.
-#[test]
-fn equivalence_test() {
-    with_connection(|device| {
-        let input_values = diced_sample_inputs::get_input_values_vector();
-        let former = device.derive(&[]).expect("Trying to call derive.");
-        let latter = device
-            .derive(&input_values)
-            .expect("Trying to call derive with input values.");
-        let artifacts = diced_utils::ResidentArtifacts::new(
-            former.cdiAttest[..].try_into().unwrap(),
-            former.cdiSeal[..].try_into().unwrap(),
-            &former.bcc.data,
-        )
-        .unwrap();
-
-        let artifacts = artifacts.execute_steps(input_values.iter()).unwrap();
-        let (cdi_attest, cdi_seal, bcc) = artifacts.into_tuple();
-        let from_former = diced_utils::make_bcc_handover(
-            cdi_attest[..].try_into().unwrap(),
-            cdi_seal[..].try_into().unwrap(),
-            &bcc,
-        )
-        .unwrap();
-        // TODO b/204938506 when we have a parser/verifier, check equivalence rather
-        // than bit by bit equality.
-        assert_eq!(latter, from_former);
-        Ok(())
-    })
-}
-
-#[test]
-fn sign_and_verify() {
-    with_connection(|device| {
-        let _signature = device
-            .sign(&[], TEST_MESSAGE)
-            .expect("Trying to call sign.");
-
-        let _bcc = device
-            .getAttestationChain(&[])
-            .expect("Trying to call getAttestationChain.");
-        // TODO b/204938506 check the signature with the bcc when the verifier is available.
-        Ok(())
-    })
-}
diff --git a/security/dice/aidl/vts/functional/utils.rs b/security/dice/aidl/vts/functional/utils.rs
deleted file mode 100644
index 4e6708e..0000000
--- a/security/dice/aidl/vts/functional/utils.rs
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2021, The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-use android_hardware_security_dice::aidl::android::hardware::security::dice::IDiceDevice::IDiceDevice;
-use anyhow::Result;
-use binder::Strong;
-use keystore2_vintf::get_aidl_instances;
-use std::sync::Arc;
-
-static DICE_DEVICE_SERVICE_NAME: &str = &"android.hardware.security.dice";
-static DICE_DEVICE_INTERFACE_NAME: &str = &"IDiceDevice";
-
-/// This function iterates through all announced IDiceDevice services and runs the given test
-/// closure against connections to each of them. It also modifies the panic hook to indicate
-/// on which instance the test failed in case the test closure panics.
-pub fn with_connection<R, F>(test: F)
-where
-    F: Fn(&Strong<dyn IDiceDevice>) -> Result<R>,
-{
-    let instances = get_aidl_instances(DICE_DEVICE_SERVICE_NAME, 1, DICE_DEVICE_INTERFACE_NAME);
-    let panic_hook = Arc::new(std::panic::take_hook());
-    for i in instances.into_iter() {
-        let panic_hook_clone = panic_hook.clone();
-        let instance_clone = i.clone();
-        std::panic::set_hook(Box::new(move |v| {
-            println!("While testing instance: \"{}\"", instance_clone);
-            panic_hook_clone(v)
-        }));
-        let connection: Strong<dyn IDiceDevice> = binder::get_interface(&format!(
-            "{}.{}/{}",
-            DICE_DEVICE_SERVICE_NAME, DICE_DEVICE_INTERFACE_NAME, i
-        ))
-        .unwrap();
-        test(&connection).unwrap();
-        drop(std::panic::take_hook());
-    }
-    // Cannot call unwrap here because the panic hook is not Debug.
-    std::panic::set_hook(match Arc::try_unwrap(panic_hook) {
-        Ok(hook) => hook,
-        _ => panic!("Failed to unwrap and reset previous panic hook."),
-    })
-}
diff --git a/security/keymint/aidl/default/Android.bp b/security/keymint/aidl/default/Android.bp
index 17520b7..953630b 100644
--- a/security/keymint/aidl/default/Android.bp
+++ b/security/keymint/aidl/default/Android.bp
@@ -42,7 +42,6 @@
         "service.cpp",
     ],
     required: [
-        "RemoteProvisioner",
         "android.hardware.hardware_keystore.xml",
     ],
 }
diff --git a/security/keymint/aidl/vts/functional/Android.bp b/security/keymint/aidl/vts/functional/Android.bp
index 26e91bd..ed3ca74 100644
--- a/security/keymint/aidl/vts/functional/Android.bp
+++ b/security/keymint/aidl/vts/functional/Android.bp
@@ -35,9 +35,12 @@
         "libbinder_ndk",
         "libcrypto",
         "libbase",
+        "libgatekeeper",
         "packagemanager_aidl-cpp",
     ],
     static_libs: [
+        "android.hardware.gatekeeper@1.0",
+        "android.hardware.gatekeeper-V1-ndk",
         "android.hardware.security.rkp-V3-ndk",
         "android.hardware.security.secureclock-V1-ndk",
         "libcppbor_external",
@@ -59,6 +62,7 @@
     ],
     srcs: [
         "AttestKeyTest.cpp",
+        "AuthTest.cpp",
         "DeviceUniqueAttestationTest.cpp",
         "KeyBlobUpgradeTest.cpp",
         "KeyMintTest.cpp",
diff --git a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
index e46aeee..8ffc179 100644
--- a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
+++ b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
@@ -106,7 +106,7 @@
         // 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) < 33) {
+        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);
 
@@ -142,11 +142,14 @@
         return false;
     }
 
-    // Check if chipset has received a waiver allowing it to be launched with
-    // Android S (or later) with Keymaster 4.0 in StrongBox
+    // 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;
 
@@ -169,8 +172,9 @@
     //     allowing it to be launched with Android S (or later) with Keymaster 4.0
     //     in StrongBox
     void check_skip_test(void) const {
-        if (is_attest_key_feature_disabled() && is_strongbox_enabled() &&
-            is_chipset_allowed_km4_strongbox()) {
+        // 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";
         }
     }
@@ -1014,6 +1018,14 @@
                     .Authorization(TAG_ATTESTATION_ID_MEID, "mismatching-meid")
                     .Authorization(TAG_ATTESTATION_ID_MANUFACTURER, "malformed-manufacturer")
                     .Authorization(TAG_ATTESTATION_ID_MODEL, "malicious-model");
+
+    // TODO(b/262255219): Remove this condition when StrongBox supports 2nd IMEI attestation.
+    if (SecLevel() != SecurityLevel::STRONGBOX) {
+        if (isSecondImeiIdAttestationRequired()) {
+            attestation_id_tags.Authorization(TAG_ATTESTATION_ID_SECOND_IMEI,
+                                              "invalid-second-imei");
+        }
+    }
     vector<uint8_t> key_blob;
     vector<KeyCharacteristics> key_characteristics;
 
@@ -1042,6 +1054,178 @@
     CheckedDeleteKey(&attest_key.keyBlob);
 }
 
+TEST_P(AttestKeyTest, SecondIMEIAttestationIDSuccess) {
+    if (is_gsi_image()) {
+        // GSI sets up a standard set of device identifiers that may not match
+        // the device identifiers held by the device.
+        GTEST_SKIP() << "Test not applicable under GSI";
+    }
+
+    // TODO(b/262255219): Remove this condition when StrongBox supports 2nd IMEI attestation.
+    if (SecLevel() == SecurityLevel::STRONGBOX) {
+        GTEST_SKIP() << "Test not applicable for SecurityLevel::STRONGBOX";
+    }
+
+    // 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) {
+        GTEST_SKIP() << "Test not applicable as there is no second IMEI";
+    }
+
+    if (!isSecondImeiIdAttestationRequired()) {
+        GTEST_SKIP() << "Test not applicable for KeyMint-Version < 3 or first-api-level < 34";
+    }
+
+    // Create attestation key.
+    AttestationKey attest_key;
+    vector<KeyCharacteristics> attest_key_characteristics;
+    vector<Certificate> attest_key_cert_chain;
+    ASSERT_EQ(ErrorCode::OK,
+              GenerateAttestKey(AuthorizationSetBuilder()
+                                        .EcdsaKey(EcCurve::P_256)
+                                        .AttestKey()
+                                        .SetDefaultValidity(),
+                                {} /* attestation signing key */, &attest_key.keyBlob,
+                                &attest_key_characteristics, &attest_key_cert_chain));
+    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));
+
+    // Use attestation key to sign an ECDSA key, but include an attestation ID field.
+    AuthorizationSetBuilder builder = AuthorizationSetBuilder()
+                                              .EcdsaSigningKey(EcCurve::P_256)
+                                              .Authorization(TAG_NO_AUTH_REQUIRED)
+                                              .AttestationChallenge("challenge")
+                                              .AttestationApplicationId("foo")
+                                              .SetDefaultValidity();
+    // b/264979486 - second imei doesn't depend on first imei.
+    // Add second IMEI as attestation id without adding first IMEI as
+    // attestation id.
+    builder.Authorization(TAG_ATTESTATION_ID_SECOND_IMEI, second_imei.data(), second_imei.size());
+
+    vector<uint8_t> attested_key_blob;
+    vector<KeyCharacteristics> attested_key_characteristics;
+    vector<Certificate> attested_key_cert_chain;
+    auto result = GenerateKey(builder, attest_key, &attested_key_blob,
+                              &attested_key_characteristics, &attested_key_cert_chain);
+
+    if (result == ErrorCode::CANNOT_ATTEST_IDS && !isDeviceIdAttestationRequired()) {
+        GTEST_SKIP()
+                << "Test not applicable as device does not support SECOND-IMEI ID attestation.";
+    }
+
+    ASSERT_EQ(result, ErrorCode::OK);
+
+    device_id_attestation_vsr_check(result);
+
+    CheckedDeleteKey(&attested_key_blob);
+
+    AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
+    AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
+
+    // The attested key characteristics will not contain APPLICATION_ID_* fields (their
+    // spec definitions all have "Must never appear in KeyCharacteristics"), but the
+    // attestation extension should contain them, so make sure the extra tag is added.
+    vector<uint8_t> imei_blob(second_imei.data(), second_imei.data() + second_imei.size());
+    KeyParameter imei_tag = Authorization(TAG_ATTESTATION_ID_SECOND_IMEI, imei_blob);
+    hw_enforced.push_back(imei_tag);
+
+    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) {
+    if (is_gsi_image()) {
+        // GSI sets up a standard set of device identifiers that may not match
+        // the device identifiers held by the device.
+        GTEST_SKIP() << "Test not applicable under GSI";
+    }
+
+    // TODO(b/262255219): Remove this condition when StrongBox supports 2nd IMEI attestation.
+    if (SecLevel() == SecurityLevel::STRONGBOX) {
+        GTEST_SKIP() << "Test not applicable for SecurityLevel::STRONGBOX";
+    }
+
+    // Skip the test if there is no first IMEI exists.
+    string imei = get_imei(0);
+    if (imei.empty() || imei.compare("null") == 0) {
+        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) {
+        GTEST_SKIP() << "Test not applicable as there is no second IMEI";
+    }
+
+    if (!isSecondImeiIdAttestationRequired()) {
+        GTEST_SKIP() << "Test not applicable for KeyMint-Version < 3 or first-api-level < 34";
+    }
+
+    // Create attestation key.
+    AttestationKey attest_key;
+    vector<KeyCharacteristics> attest_key_characteristics;
+    vector<Certificate> attest_key_cert_chain;
+    ASSERT_EQ(ErrorCode::OK,
+              GenerateAttestKey(AuthorizationSetBuilder()
+                                        .EcdsaKey(EcCurve::P_256)
+                                        .AttestKey()
+                                        .SetDefaultValidity(),
+                                {} /* attestation signing key */, &attest_key.keyBlob,
+                                &attest_key_characteristics, &attest_key_cert_chain));
+    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));
+
+    // Use attestation key to sign an ECDSA key, but include both IMEI attestation ID fields.
+    AuthorizationSetBuilder builder = AuthorizationSetBuilder()
+                                              .EcdsaSigningKey(EcCurve::P_256)
+                                              .Authorization(TAG_NO_AUTH_REQUIRED)
+                                              .AttestationChallenge("challenge")
+                                              .AttestationApplicationId("foo")
+                                              .SetDefaultValidity();
+    builder.Authorization(TAG_ATTESTATION_ID_IMEI, imei.data(), imei.size());
+    builder.Authorization(TAG_ATTESTATION_ID_SECOND_IMEI, second_imei.data(), second_imei.size());
+
+    vector<uint8_t> attested_key_blob;
+    vector<KeyCharacteristics> attested_key_characteristics;
+    vector<Certificate> attested_key_cert_chain;
+    auto result = GenerateKey(builder, attest_key, &attested_key_blob,
+                              &attested_key_characteristics, &attested_key_cert_chain);
+
+    if (result == ErrorCode::CANNOT_ATTEST_IDS && !isDeviceIdAttestationRequired()) {
+        GTEST_SKIP() << "Test not applicable as device does not support IMEI ID attestation.";
+    }
+
+    ASSERT_EQ(result, ErrorCode::OK);
+
+    device_id_attestation_vsr_check(result);
+
+    CheckedDeleteKey(&attested_key_blob);
+
+    AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
+    AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
+
+    // The attested key characteristics will not contain APPLICATION_ID_* fields (their
+    // spec definitions all have "Must never appear in KeyCharacteristics"), but the
+    // attestation extension should contain them, so make sure the extra tag is added.
+    vector<uint8_t> imei_blob(imei.data(), imei.data() + imei.size());
+    KeyParameter imei_tag = Authorization(TAG_ATTESTATION_ID_IMEI, imei_blob);
+    hw_enforced.push_back(imei_tag);
+    vector<uint8_t> sec_imei_blob(second_imei.data(), second_imei.data() + second_imei.size());
+    KeyParameter sec_imei_tag = Authorization(TAG_ATTESTATION_ID_SECOND_IMEI, sec_imei_blob);
+    hw_enforced.push_back(sec_imei_tag);
+
+    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);
 
 }  // namespace aidl::android::hardware::security::keymint::test
diff --git a/security/keymint/aidl/vts/functional/AuthTest.cpp b/security/keymint/aidl/vts/functional/AuthTest.cpp
new file mode 100644
index 0000000..78c88f4
--- /dev/null
+++ b/security/keymint/aidl/vts/functional/AuthTest.cpp
@@ -0,0 +1,412 @@
+/*
+ * 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 "keymint_1_test"
+#include <cutils/log.h>
+
+#include <iostream>
+#include <optional>
+
+#include "KeyMintAidlTestBase.h"
+
+#include <aidl/android/hardware/gatekeeper/GatekeeperEnrollResponse.h>
+#include <aidl/android/hardware/gatekeeper/GatekeeperVerifyResponse.h>
+#include <aidl/android/hardware/gatekeeper/IGatekeeper.h>
+#include <aidl/android/hardware/security/secureclock/ISecureClock.h>
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+
+using aidl::android::hardware::gatekeeper::GatekeeperEnrollResponse;
+using aidl::android::hardware::gatekeeper::GatekeeperVerifyResponse;
+using aidl::android::hardware::gatekeeper::IGatekeeper;
+using aidl::android::hardware::security::keymint::HardwareAuthToken;
+using aidl::android::hardware::security::secureclock::ISecureClock;
+
+#include <android/hardware/gatekeeper/1.0/IGatekeeper.h>
+#include <android/hardware/gatekeeper/1.0/types.h>
+#include <gatekeeper/password_handle.h>  // for password_handle_t
+#include <hardware/hw_auth_token.h>
+
+using ::android::sp;
+using IHidlGatekeeper = ::android::hardware::gatekeeper::V1_0::IGatekeeper;
+using HidlGatekeeperResponse = ::android::hardware::gatekeeper::V1_0::GatekeeperResponse;
+using HidlGatekeeperStatusCode = ::android::hardware::gatekeeper::V1_0::GatekeeperStatusCode;
+
+namespace aidl::android::hardware::security::keymint::test {
+
+class AuthTest : public KeyMintAidlTestBase {
+  public:
+    void SetUp() {
+        KeyMintAidlTestBase::SetUp();
+
+        // Find the default Gatekeeper instance.
+        string gk_name = string(IGatekeeper::descriptor) + "/default";
+        if (AServiceManager_isDeclared(gk_name.c_str())) {
+            // Enroll a user with AIDL Gatekeeper.
+            ::ndk::SpAIBinder binder(AServiceManager_waitForService(gk_name.c_str()));
+            gk_ = IGatekeeper::fromBinder(binder);
+        } else {
+            // Prior to Android U, Gatekeeper was HIDL not AIDL and so may not be present.
+            // Try to enroll user with HIDL Gatekeeper instead.
+            string gk_name = "default";
+            hidl_gk_ = IHidlGatekeeper::getService(gk_name.c_str());
+            if (hidl_gk_ == nullptr) {
+                std::cerr << "No HIDL Gatekeeper instance for '" << gk_name << "' found.\n";
+                return;
+            }
+            std::cerr << "No AIDL Gatekeeper instance for '" << gk_name << "' found, using HIDL.\n";
+        }
+
+        // If the device needs timestamps, find the default ISecureClock instance.
+        if (timestamp_token_required_) {
+            string clock_name = string(ISecureClock::descriptor) + "/default";
+            if (AServiceManager_isDeclared(clock_name.c_str())) {
+                ::ndk::SpAIBinder binder(AServiceManager_waitForService(clock_name.c_str()));
+                clock_ = ISecureClock::fromBinder(binder);
+            } else {
+                std::cerr << "No ISecureClock instance for '" << clock_name << "' found.\n";
+            }
+        }
+
+        // Enroll a password for a user.
+        uid_ = 10001;
+        password_ = "correcthorsebatterystaple";
+        std::optional<GatekeeperEnrollResponse> rsp = doEnroll(password_);
+        ASSERT_TRUE(rsp.has_value());
+        sid_ = rsp->secureUserId;
+        handle_ = rsp->data;
+    }
+
+    void TearDown() {
+        if (gk_ == nullptr) return;
+        gk_->deleteUser(uid_);
+    }
+
+    bool GatekeeperAvailable() { return (gk_ != nullptr) || (hidl_gk_ != nullptr); }
+
+    std::optional<GatekeeperEnrollResponse> doEnroll(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);
+                if (!status.isOk() && status.getExceptionCode() == EX_SERVICE_SPECIFIC &&
+                    status.getServiceSpecificError() == IGatekeeper::ERROR_RETRY_TIMEOUT) {
+                    sleep(1);
+                    continue;
+                }
+                if (status.isOk()) {
+                    return std::move(rsp);
+                } else {
+                    GTEST_LOG_(ERROR) << "doEnroll(AIDL) failed: " << status;
+                    return std::nullopt;
+                }
+            }
+        } else if (hidl_gk_ != nullptr) {
+            while (true) {
+                HidlGatekeeperResponse rsp;
+                auto status = hidl_gk_->enroll(
+                        uid_, curHandle, curPwd, newPwd,
+                        [&rsp](const HidlGatekeeperResponse& cbRsp) { rsp = cbRsp; });
+                if (!status.isOk()) {
+                    GTEST_LOG_(ERROR) << "doEnroll(HIDL) failed";
+                    return std::nullopt;
+                }
+                if (rsp.code == HidlGatekeeperStatusCode::ERROR_RETRY_TIMEOUT) {
+                    sleep(1);
+                    continue;
+                }
+                if (rsp.code != HidlGatekeeperStatusCode::STATUS_OK) {
+                    GTEST_LOG_(ERROR) << "doEnroll(HIDL) failed with " << int(rsp.code);
+                    return std::nullopt;
+                }
+                // "Parse" the returned data to get at the secure user ID.
+                if (rsp.data.size() != sizeof(::gatekeeper::password_handle_t)) {
+                    GTEST_LOG_(ERROR)
+                            << "HAL returned password handle of invalid length " << rsp.data.size();
+                    return std::nullopt;
+                }
+                const ::gatekeeper::password_handle_t* handle =
+                        reinterpret_cast<const ::gatekeeper::password_handle_t*>(rsp.data.data());
+
+                // Translate HIDL response to look like an AIDL response.
+                GatekeeperEnrollResponse aidl_rsp;
+                aidl_rsp.statusCode = IGatekeeper::STATUS_OK;
+                aidl_rsp.data = rsp.data;
+                aidl_rsp.secureUserId = handle->user_id;
+                return aidl_rsp;
+            }
+        } else {
+            return std::nullopt;
+        }
+    }
+
+    std::optional<GatekeeperEnrollResponse> doEnroll(const string& newPwd,
+                                                     const std::vector<uint8_t>& curHandle = {},
+                                                     const string& curPwd = {}) {
+        return doEnroll(std::vector<uint8_t>(newPwd.begin(), newPwd.end()), curHandle,
+                        std::vector<uint8_t>(curPwd.begin(), curPwd.end()));
+    }
+
+    std::optional<HardwareAuthToken> doVerify(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);
+                if (!status.isOk() && status.getExceptionCode() == EX_SERVICE_SPECIFIC &&
+                    status.getServiceSpecificError() == IGatekeeper::ERROR_RETRY_TIMEOUT) {
+                    sleep(1);
+                    continue;
+                }
+                if (status.isOk()) {
+                    return rsp.hardwareAuthToken;
+                } else {
+                    GTEST_LOG_(ERROR) << "doVerify(AIDL) failed: " << status;
+                    return std::nullopt;
+                }
+            }
+        } else if (hidl_gk_ != nullptr) {
+            while (true) {
+                HidlGatekeeperResponse rsp;
+                auto status = hidl_gk_->verify(
+                        uid_, challenge, handle, pwd,
+                        [&rsp](const HidlGatekeeperResponse& cbRsp) { rsp = cbRsp; });
+                if (!status.isOk()) {
+                    GTEST_LOG_(ERROR) << "doVerify(HIDL) failed";
+                    return std::nullopt;
+                }
+                if (rsp.code == HidlGatekeeperStatusCode::ERROR_RETRY_TIMEOUT) {
+                    sleep(1);
+                    continue;
+                }
+                if (rsp.code != HidlGatekeeperStatusCode::STATUS_OK) {
+                    GTEST_LOG_(ERROR) << "doVerify(HIDL) failed with " << int(rsp.code);
+                    return std::nullopt;
+                }
+                // "Parse" the returned data to get auth token contents.
+                if (rsp.data.size() != sizeof(hw_auth_token_t)) {
+                    GTEST_LOG_(ERROR) << "Incorrect size of AuthToken payload.";
+                    return std::nullopt;
+                }
+                const hw_auth_token_t* hwAuthToken =
+                        reinterpret_cast<const hw_auth_token_t*>(rsp.data.data());
+                HardwareAuthToken authToken;
+                authToken.timestamp.milliSeconds = betoh64(hwAuthToken->timestamp);
+                authToken.challenge = hwAuthToken->challenge;
+                authToken.userId = hwAuthToken->user_id;
+                authToken.authenticatorId = hwAuthToken->authenticator_id;
+                authToken.authenticatorType = static_cast<HardwareAuthenticatorType>(
+                        betoh32(hwAuthToken->authenticator_type));
+                authToken.mac.assign(&hwAuthToken->hmac[0], &hwAuthToken->hmac[32]);
+                return authToken;
+            }
+        } else {
+            return std::nullopt;
+        }
+    }
+    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()));
+    }
+
+    // Variants of the base class methods but with authentication information included.
+    string ProcessMessage(const vector<uint8_t>& key_blob, KeyPurpose operation,
+                          const string& message, const AuthorizationSet& in_params,
+                          AuthorizationSet* out_params, const HardwareAuthToken& hat) {
+        AuthorizationSet begin_out_params;
+        ErrorCode result = Begin(operation, key_blob, in_params, out_params, hat);
+        EXPECT_EQ(ErrorCode::OK, result);
+        if (result != ErrorCode::OK) {
+            return "";
+        }
+
+        std::optional<secureclock::TimeStampToken> time_token = std::nullopt;
+        if (timestamp_token_required_ && clock_ != nullptr) {
+            // Ask a secure clock instance for a timestamp, including the per-op challenge.
+            secureclock::TimeStampToken token;
+            EXPECT_EQ(ErrorCode::OK,
+                      GetReturnErrorCode(clock_->generateTimeStamp(challenge_, &token)));
+            time_token = token;
+        }
+
+        string output;
+        EXPECT_EQ(ErrorCode::OK, Finish(message, {} /* signature */, &output, hat, time_token));
+        return output;
+    }
+
+    string EncryptMessage(const vector<uint8_t>& key_blob, const string& message,
+                          const AuthorizationSet& in_params, AuthorizationSet* out_params,
+                          const HardwareAuthToken& hat) {
+        SCOPED_TRACE("EncryptMessage");
+        return ProcessMessage(key_blob, KeyPurpose::ENCRYPT, message, in_params, out_params, hat);
+    }
+
+    string DecryptMessage(const vector<uint8_t>& key_blob, const string& ciphertext,
+                          const AuthorizationSet& params, const HardwareAuthToken& hat) {
+        SCOPED_TRACE("DecryptMessage");
+        AuthorizationSet out_params;
+        string plaintext =
+                ProcessMessage(key_blob, KeyPurpose::DECRYPT, ciphertext, params, &out_params, hat);
+        EXPECT_TRUE(out_params.empty());
+        return plaintext;
+    }
+
+  protected:
+    std::shared_ptr<IGatekeeper> gk_;
+    sp<IHidlGatekeeper> hidl_gk_;
+    std::shared_ptr<ISecureClock> clock_;
+    string password_;
+    uint32_t uid_;
+    int64_t sid_;
+    std::vector<uint8_t> handle_;
+};
+
+// Test use of a key that requires user-authentication within recent history.
+TEST_P(AuthTest, TimeoutAuthentication) {
+    if (!GatekeeperAvailable()) {
+        GTEST_SKIP() << "No Gatekeeper available";
+    }
+    if (timestamp_token_required_ && 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));
+
+    // Attempt to use the AES key without authentication.
+    const string message = "Hello World!";
+    AuthorizationSet out_params;
+    auto params = AuthorizationSetBuilder().BlockMode(BlockMode::ECB).Padding(PaddingMode::PKCS7);
+    EXPECT_EQ(ErrorCode::KEY_USER_NOT_AUTHENTICATED,
+              Begin(KeyPurpose::ENCRYPT, keyblob, params, &out_params));
+
+    // 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_);
+
+    // Adding the auth token makes it possible to use the AES key.
+    const string ciphertext = EncryptMessage(keyblob, message, params, &out_params, hat.value());
+    const string plaintext = DecryptMessage(keyblob, ciphertext, params, hat.value());
+    EXPECT_EQ(message, plaintext);
+
+    // Altering a single bit in the MAC means no auth.
+    HardwareAuthToken dodgy_hat = hat.value();
+    ASSERT_GT(dodgy_hat.mac.size(), 0);
+    dodgy_hat.mac[0] ^= 0x01;
+    EXPECT_EQ(ErrorCode::KEY_USER_NOT_AUTHENTICATED,
+              Begin(KeyPurpose::ENCRYPT, keyblob, params, &out_params, dodgy_hat));
+
+    // Wait for long enough that the hardware auth token expires.
+    sleep(timeout_secs + 1);
+    if (!timestamp_token_required_) {
+        // KeyMint implementation has its own clock, and can immediately detect timeout.
+        EXPECT_EQ(ErrorCode::KEY_USER_NOT_AUTHENTICATED,
+                  Begin(KeyPurpose::ENCRYPT, keyblob, params, &out_params, hat));
+    } else {
+        // KeyMint implementation has no clock, so only detects timeout via timestamp token provided
+        // on update()/finish().
+        ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, keyblob, params, &out_params, hat));
+        secureclock::TimeStampToken time_token;
+        EXPECT_EQ(ErrorCode::OK,
+                  GetReturnErrorCode(clock_->generateTimeStamp(challenge_, &time_token)));
+
+        string output;
+        EXPECT_EQ(ErrorCode::KEY_USER_NOT_AUTHENTICATED,
+                  Finish(message, {} /* signature */, &output, hat, time_token));
+    }
+}
+
+// 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) {
+    if (!GatekeeperAvailable()) {
+        GTEST_SKIP() << "No Gatekeeper available";
+    }
+
+    // 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_AUTH_TYPE, HardwareAuthenticatorType::PASSWORD);
+    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));
+
+    // Attempt to use the AES key without authentication fails after begin.
+    const string message = "Hello World!";
+    AuthorizationSet out_params;
+    auto params = AuthorizationSetBuilder().BlockMode(BlockMode::ECB).Padding(PaddingMode::PKCS7);
+    EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, keyblob, params, &out_params));
+    string output;
+    EXPECT_EQ(ErrorCode::KEY_USER_NOT_AUTHENTICATED, Finish(message, {} /* signature */, &output));
+
+    // Verify to get a HAT, but with an arbitrary challenge.
+    const uint64_t unrelated_challenge = 42;
+    const std::optional<HardwareAuthToken> unrelated_hat =
+            doVerify(unrelated_challenge, handle_, password_);
+    ASSERT_TRUE(unrelated_hat.has_value());
+    EXPECT_EQ(unrelated_hat->userId, sid_);
+
+    // Attempt to use the AES key with an unrelated authentication fails after begin.
+    EXPECT_EQ(ErrorCode::OK,
+              Begin(KeyPurpose::ENCRYPT, keyblob, params, &out_params, unrelated_hat.value()));
+    EXPECT_EQ(ErrorCode::KEY_USER_NOT_AUTHENTICATED,
+              Finish(message, {} /* signature */, &output, unrelated_hat.value()));
+
+    // Now get a HAT with the challenge from an in-progress operation.
+    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_);
+    string ciphertext;
+    EXPECT_EQ(ErrorCode::OK, Finish(message, {} /* signature */, &ciphertext, hat.value()));
+
+    // Altering a single bit in the MAC means no auth.
+    EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, keyblob, params, &out_params));
+    std::optional<HardwareAuthToken> dodgy_hat = doVerify(challenge_, handle_, password_);
+    ASSERT_TRUE(dodgy_hat.has_value());
+    EXPECT_EQ(dodgy_hat->userId, sid_);
+    ASSERT_GT(dodgy_hat->mac.size(), 0);
+    dodgy_hat->mac[0] ^= 0x01;
+    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/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index e9cbe10..5e27bd0 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -108,25 +108,13 @@
     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;
+void check_crl_distribution_points_extension_not_present(X509* certificate) {
+    ASN1_OBJECT_Ptr crl_dp_oid(OBJ_txt2obj(kCrlDPOid, 1 /* dotted string format */));
+    ASSERT_TRUE(crl_dp_oid.get());
 
-    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;
+    int location =
+            X509_get_ext_by_OBJ(certificate, crl_dp_oid.get(), -1 /* search from beginning */);
+    ASSERT_EQ(location, -1);
 }
 
 void check_attestation_version(uint32_t attestation_version, int32_t aidl_version) {
@@ -214,7 +202,15 @@
  * which is mandatory for KeyMint version 2 or first_api_level 33 or greater.
  */
 bool KeyMintAidlTestBase::isDeviceIdAttestationRequired() {
-    return AidlVersion() >= 2 || property_get_int32("ro.vendor.api_level", 0) >= 33;
+    return AidlVersion() >= 2 || property_get_int32("ro.vendor.api_level", 0) >= __ANDROID_API_T__;
+}
+
+/**
+ * An API to determine second IMEI ID attestation is required or not,
+ * which is supported for KeyMint version 3 or first_api_level greater than 33.
+ */
+bool KeyMintAidlTestBase::isSecondImeiIdAttestationRequired() {
+    return AidlVersion() >= 3 && property_get_int32("ro.vendor.api_level", 0) > __ANDROID_API_T__;
 }
 
 bool KeyMintAidlTestBase::Curve25519Supported() {
@@ -544,12 +540,13 @@
 
 ErrorCode KeyMintAidlTestBase::Begin(KeyPurpose purpose, const vector<uint8_t>& key_blob,
                                      const AuthorizationSet& in_params,
-                                     AuthorizationSet* out_params) {
+                                     AuthorizationSet* out_params,
+                                     std::optional<HardwareAuthToken> hat) {
     SCOPED_TRACE("Begin");
     Status result;
     BeginResult out;
 
-    result = keymint_->begin(purpose, key_blob, in_params.vector_data(), std::nullopt, &out);
+    result = keymint_->begin(purpose, key_blob, in_params.vector_data(), hat, &out);
 
     if (result.isOk()) {
         *out_params = out.params;
@@ -603,8 +600,9 @@
     return GetReturnErrorCode(result);
 }
 
-ErrorCode KeyMintAidlTestBase::Finish(const string& input, const string& signature,
-                                      string* output) {
+ErrorCode KeyMintAidlTestBase::Finish(const string& input, const string& signature, string* output,
+                                      std::optional<HardwareAuthToken> hat,
+                                      std::optional<secureclock::TimeStampToken> time_token) {
     SCOPED_TRACE("Finish");
     Status result;
 
@@ -613,8 +611,8 @@
 
     vector<uint8_t> oPut;
     result = op_->finish(vector<uint8_t>(input.begin(), input.end()),
-                         vector<uint8_t>(signature.begin(), signature.end()), {} /* authToken */,
-                         {} /* timestampToken */, {} /* confirmationToken */, &oPut);
+                         vector<uint8_t>(signature.begin(), signature.end()), hat, time_token,
+                         {} /* confirmationToken */, &oPut);
 
     if (result.isOk()) output->append(oPut.begin(), oPut.end());
 
@@ -837,7 +835,7 @@
         int vendor_api_level = property_get_int32("ro.vendor.api_level", 0);
         if (SecLevel() == SecurityLevel::STRONGBOX) {
             // This is known to be broken on older vendor implementations.
-            if (vendor_api_level < 33) {
+            if (vendor_api_level < __ANDROID_API_T__) {
                 compare_output = false;
             } else {
                 additional_information = " (b/194134359) ";
@@ -1294,6 +1292,19 @@
 
     return retval;
 }
+
+bool KeyMintAidlTestBase::IsRkpSupportRequired() const {
+    if (get_vsr_api_level() >= __ANDROID_API_T__) {
+        return true;
+    }
+
+    if (get_vsr_api_level() >= __ANDROID_API_S__) {
+        return SecLevel() != SecurityLevel::STRONGBOX;
+    }
+
+    return false;
+}
+
 vector<uint32_t> KeyMintAidlTestBase::ValidKeySizes(Algorithm algorithm) {
     switch (algorithm) {
         case Algorithm::RSA:
@@ -1701,6 +1712,10 @@
     EXPECT_TRUE(!!cert.get());
     if (!cert.get()) return false;
 
+    // Make sure CRL Distribution Points extension is not present in a certificate
+    // containing attestation record.
+    check_crl_distribution_points_extension_not_present(cert.get());
+
     ASN1_OCTET_STRING* attest_rec = get_attestation_record(cert.get());
     EXPECT_TRUE(!!attest_rec);
     if (!attest_rec) return false;
@@ -1743,38 +1758,33 @@
     EXPECT_EQ(security_level, att_keymint_security_level);
     EXPECT_EQ(security_level, att_attestation_security_level);
 
-    // TODO(b/136282179): When running under VTS-on-GSI the TEE-backed
-    // keymint implementation will report YYYYMM dates instead of YYYYMMDD
-    // for the BOOT_PATCH_LEVEL.
-    if (avb_verification_enabled()) {
-        for (int i = 0; i < att_hw_enforced.size(); i++) {
-            if (att_hw_enforced[i].tag == TAG_BOOT_PATCHLEVEL ||
-                att_hw_enforced[i].tag == TAG_VENDOR_PATCHLEVEL) {
-                std::string date =
-                        std::to_string(att_hw_enforced[i].value.get<KeyParameterValue::integer>());
+    for (int i = 0; i < att_hw_enforced.size(); i++) {
+        if (att_hw_enforced[i].tag == TAG_BOOT_PATCHLEVEL ||
+            att_hw_enforced[i].tag == TAG_VENDOR_PATCHLEVEL) {
+            std::string date =
+                    std::to_string(att_hw_enforced[i].value.get<KeyParameterValue::integer>());
 
-                // strptime seems to require delimiters, but the tag value will
-                // be YYYYMMDD
-                if (date.size() != 8) {
-                    ADD_FAILURE() << "Tag " << att_hw_enforced[i].tag
-                                  << " with invalid format (not YYYYMMDD): " << date;
-                    return false;
-                }
-                date.insert(6, "-");
-                date.insert(4, "-");
-                struct tm time;
-                strptime(date.c_str(), "%Y-%m-%d", &time);
-
-                // Day of the month (0-31)
-                EXPECT_GE(time.tm_mday, 0);
-                EXPECT_LT(time.tm_mday, 32);
-                // Months since Jan (0-11)
-                EXPECT_GE(time.tm_mon, 0);
-                EXPECT_LT(time.tm_mon, 12);
-                // Years since 1900
-                EXPECT_GT(time.tm_year, 110);
-                EXPECT_LT(time.tm_year, 200);
+            // strptime seems to require delimiters, but the tag value will
+            // be YYYYMMDD
+            if (date.size() != 8) {
+                ADD_FAILURE() << "Tag " << att_hw_enforced[i].tag
+                              << " with invalid format (not YYYYMMDD): " << date;
+                return false;
             }
+            date.insert(6, "-");
+            date.insert(4, "-");
+            struct tm time;
+            strptime(date.c_str(), "%Y-%m-%d", &time);
+
+            // Day of the month (0-31)
+            EXPECT_GE(time.tm_mday, 0);
+            EXPECT_LT(time.tm_mday, 32);
+            // Months since Jan (0-11)
+            EXPECT_GE(time.tm_mon, 0);
+            EXPECT_LT(time.tm_mon, 12);
+            // Years since 1900
+            EXPECT_GT(time.tm_year, 110);
+            EXPECT_LT(time.tm_year, 200);
         }
     }
 
@@ -1896,6 +1906,27 @@
     return X509_Ptr(d2i_X509(nullptr /* allocate new */, &p, blob.size()));
 }
 
+// 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;
+}
+
 vector<uint8_t> make_name_from_str(const string& name) {
     X509_NAME_Ptr x509_name(X509_NAME_new());
     EXPECT_TRUE(x509_name.get() != nullptr);
@@ -2040,7 +2071,7 @@
 }
 
 void device_id_attestation_vsr_check(const ErrorCode& result) {
-    if (get_vsr_api_level() >= 34) {
+    if (get_vsr_api_level() > __ANDROID_API_T__) {
         ASSERT_FALSE(result == ErrorCode::INVALID_TAG)
                 << "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 "
@@ -2052,9 +2083,10 @@
 // Check whether the given named feature is available.
 bool check_feature(const std::string& name) {
     ::android::sp<::android::IServiceManager> sm(::android::defaultServiceManager());
-    ::android::sp<::android::IBinder> binder(sm->getService(::android::String16("package_native")));
+    ::android::sp<::android::IBinder> binder(
+        sm->waitForService(::android::String16("package_native")));
     if (binder == nullptr) {
-        GTEST_LOG_(ERROR) << "getService package_native failed";
+        GTEST_LOG_(ERROR) << "waitForService package_native failed";
         return false;
     }
     ::android::sp<::android::content::pm::IPackageManagerNative> packageMgr =
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
index fae9459..3245ca9 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
@@ -85,6 +85,7 @@
     uint32_t boot_patch_level(const vector<KeyCharacteristics>& key_characteristics);
     uint32_t boot_patch_level();
     bool isDeviceIdAttestationRequired();
+    bool isSecondImeiIdAttestationRequired();
 
     bool Curve25519Supported();
 
@@ -160,7 +161,8 @@
                     const AuthorizationSet& in_params, AuthorizationSet* out_params,
                     std::shared_ptr<IKeyMintOperation>& op);
     ErrorCode Begin(KeyPurpose purpose, const vector<uint8_t>& key_blob,
-                    const AuthorizationSet& in_params, AuthorizationSet* out_params);
+                    const AuthorizationSet& in_params, AuthorizationSet* out_params,
+                    std::optional<HardwareAuthToken> hat = std::nullopt);
     ErrorCode Begin(KeyPurpose purpose, const AuthorizationSet& in_params,
                     AuthorizationSet* out_params);
     ErrorCode Begin(KeyPurpose purpose, const AuthorizationSet& in_params);
@@ -168,7 +170,9 @@
     ErrorCode UpdateAad(const string& input);
     ErrorCode Update(const string& input, string* output);
 
-    ErrorCode Finish(const string& message, const string& signature, string* output);
+    ErrorCode Finish(const string& message, const string& signature, string* output,
+                     std::optional<HardwareAuthToken> hat = std::nullopt,
+                     std::optional<secureclock::TimeStampToken> time_token = std::nullopt);
     ErrorCode Finish(const string& message, string* output) {
         return Finish(message, {} /* signature */, output);
     }
@@ -305,6 +309,7 @@
     }
     bool IsSecure() const { return securityLevel_ != SecurityLevel::SOFTWARE; }
     SecurityLevel SecLevel() const { return securityLevel_; }
+    bool IsRkpSupportRequired() const;
 
     vector<uint32_t> ValidKeySizes(Algorithm algorithm);
     vector<uint32_t> InvalidKeySizes(Algorithm algorithm);
@@ -352,7 +357,7 @@
     SecurityLevel securityLevel_;
     string name_;
     string author_;
-    long challenge_;
+    int64_t challenge_;
 
   private:
     void CheckEncryptOneByteAtATime(BlockMode block_mode, const int block_size,
@@ -397,6 +402,7 @@
 
 string bin2hex(const vector<uint8_t>& data);
 X509_Ptr parse_cert_blob(const vector<uint8_t>& blob);
+ASN1_OCTET_STRING* get_attestation_record(X509* certificate);
 vector<uint8_t> make_name_from_str(const string& name);
 void check_maced_pubkey(const MacedPublicKey& macedPubKey, bool testMode,
                         vector<uint8_t>* payload_value);
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index 1b9e758..63b2e73 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -26,6 +26,7 @@
 #include <openssl/ec.h>
 #include <openssl/evp.h>
 #include <openssl/mem.h>
+#include <openssl/x509.h>
 #include <openssl/x509v3.h>
 
 #include <cutils/properties.h>
@@ -590,8 +591,7 @@
     return name.substr(pos + 1);
 }
 
-bool matching_rp_instance(const string& km_name,
-                          std::shared_ptr<IRemotelyProvisionedComponent>* rp) {
+std::shared_ptr<IRemotelyProvisionedComponent> matching_rp_instance(const std::string& km_name) {
     string km_suffix = device_suffix(km_name);
 
     vector<string> rp_names =
@@ -601,11 +601,10 @@
         // KeyMint instance, assume they match.
         if (device_suffix(rp_name) == km_suffix && AServiceManager_isDeclared(rp_name.c_str())) {
             ::ndk::SpAIBinder binder(AServiceManager_waitForService(rp_name.c_str()));
-            *rp = IRemotelyProvisionedComponent::fromBinder(binder);
-            return true;
+            return IRemotelyProvisionedComponent::fromBinder(binder);
         }
     }
-    return false;
+    return nullptr;
 }
 
 }  // namespace
@@ -1061,6 +1060,42 @@
 }
 
 /*
+ * NewKeyGenerationTest.RsaWithSpecifiedValidity
+ *
+ * Verifies that KeyMint respects specified NOT_BEFORE and NOT_AFTER certificate dates.
+ */
+TEST_P(NewKeyGenerationTest, RsaWithSpecifiedValidity) {
+    vector<uint8_t> key_blob;
+    vector<KeyCharacteristics> key_characteristics;
+    ASSERT_EQ(ErrorCode::OK,
+              GenerateKey(AuthorizationSetBuilder()
+                                  .RsaSigningKey(2048, 65537)
+                                  .Digest(Digest::NONE)
+                                  .Padding(PaddingMode::NONE)
+                                  .Authorization(TAG_CERTIFICATE_NOT_BEFORE,
+                                                 1183806000000 /* 2007-07-07T11:00:00Z */)
+                                  .Authorization(TAG_CERTIFICATE_NOT_AFTER,
+                                                 1916049600000 /* 2030-09-19T12:00:00Z */),
+                          &key_blob, &key_characteristics));
+    ASSERT_GT(cert_chain_.size(), 0);
+
+    X509_Ptr cert(parse_cert_blob(cert_chain_[0].encodedCertificate));
+    ASSERT_TRUE(!!cert.get());
+
+    const ASN1_TIME* not_before = X509_get0_notBefore(cert.get());
+    ASSERT_NE(not_before, nullptr);
+    time_t not_before_time;
+    ASSERT_EQ(ASN1_TIME_to_time_t(not_before, &not_before_time), 1);
+    EXPECT_EQ(not_before_time, 1183806000);
+
+    const ASN1_TIME* not_after = X509_get0_notAfter(cert.get());
+    ASSERT_NE(not_after, nullptr);
+    time_t not_after_time;
+    ASSERT_EQ(ASN1_TIME_to_time_t(not_after, &not_after_time), 1);
+    EXPECT_EQ(not_after_time, 1916049600);
+}
+
+/*
  * NewKeyGenerationTest.RsaWithAttestation
  *
  * Verifies that keymint can generate all required RSA key sizes with attestation, and that the
@@ -1136,15 +1171,18 @@
  * that has been generated using an associate IRemotelyProvisionedComponent.
  */
 TEST_P(NewKeyGenerationTest, RsaWithRkpAttestation) {
-    if (get_vsr_api_level() < 32 || AidlVersion() < 2) {
-        GTEST_SKIP() << "Only required for VSR 12+ and KeyMint 2+";
+    if (!IsRkpSupportRequired()) {
+        GTEST_SKIP() << "RKP support is not required on this platform";
     }
 
-    // There should be an IRemotelyProvisionedComponent instance associated with the KeyMint
-    // instance.
-    std::shared_ptr<IRemotelyProvisionedComponent> rp;
-    ASSERT_TRUE(matching_rp_instance(GetParam(), &rp))
-            << "No IRemotelyProvisionedComponent found that matches KeyMint device " << GetParam();
+    // Check for an IRemotelyProvisionedComponent instance associated with the
+    // KeyMint instance.
+    std::shared_ptr<IRemotelyProvisionedComponent> rp = matching_rp_instance(GetParam());
+    if (rp == nullptr && SecLevel() == SecurityLevel::STRONGBOX) {
+        GTEST_SKIP() << "Encountered StrongBox implementation that does not support RKP";
+    }
+    ASSERT_NE(rp, nullptr) << "No IRemotelyProvisionedComponent found that matches KeyMint device "
+                           << GetParam();
 
     // Generate a P-256 keypair to use as an attestation key.
     MacedPublicKey macedPubKey;
@@ -1214,15 +1252,18 @@
  * that has been generated using an associate IRemotelyProvisionedComponent.
  */
 TEST_P(NewKeyGenerationTest, EcdsaWithRkpAttestation) {
-    if (get_vsr_api_level() < 32 || AidlVersion() < 2) {
-        GTEST_SKIP() << "Only required for VSR 12+ and KeyMint 2+";
+    if (!IsRkpSupportRequired()) {
+        GTEST_SKIP() << "RKP support is not required on this platform";
     }
 
-    // There should be an IRemotelyProvisionedComponent instance associated with the KeyMint
-    // instance.
-    std::shared_ptr<IRemotelyProvisionedComponent> rp;
-    ASSERT_TRUE(matching_rp_instance(GetParam(), &rp))
-            << "No IRemotelyProvisionedComponent found that matches KeyMint device " << GetParam();
+    // Check for an IRemotelyProvisionedComponent instance associated with the
+    // KeyMint instance.
+    std::shared_ptr<IRemotelyProvisionedComponent> rp = matching_rp_instance(GetParam());
+    if (rp == nullptr && SecLevel() == SecurityLevel::STRONGBOX) {
+        GTEST_SKIP() << "Encountered StrongBox implementation that does not support RKP";
+    }
+    ASSERT_NE(rp, nullptr) << "No IRemotelyProvisionedComponent found that matches KeyMint device "
+                           << GetParam();
 
     // Generate a P-256 keypair to use as an attestation key.
     MacedPublicKey macedPubKey;
@@ -8629,7 +8670,7 @@
 
 TEST_P(VsrRequirementTest, Vsr13Test) {
     int vsr_api_level = get_vsr_api_level();
-    if (vsr_api_level < 33) {
+    if (vsr_api_level < __ANDROID_API_T__) {
         GTEST_SKIP() << "Applies only to VSR API level 33, this device is: " << vsr_api_level;
     }
     EXPECT_GE(AidlVersion(), 2) << "VSR 13+ requires KeyMint version 2";
@@ -8637,7 +8678,7 @@
 
 TEST_P(VsrRequirementTest, Vsr14Test) {
     int vsr_api_level = get_vsr_api_level();
-    if (vsr_api_level < 34) {
+    if (vsr_api_level < __ANDROID_API_U__) {
         GTEST_SKIP() << "Applies only to VSR API level 34, this device is: " << vsr_api_level;
     }
     EXPECT_GE(AidlVersion(), 3) << "VSR 14+ requires KeyMint version 3";
diff --git a/security/keymint/aidl/vts/performance/KeyMintBenchmark.cpp b/security/keymint/aidl/vts/performance/KeyMintBenchmark.cpp
index 0c61c25..49fd0c9 100644
--- a/security/keymint/aidl/vts/performance/KeyMintBenchmark.cpp
+++ b/security/keymint/aidl/vts/performance/KeyMintBenchmark.cpp
@@ -68,7 +68,7 @@
 
     int getError() { return static_cast<int>(error_); }
 
-    const string& GenerateMessage(int size) {
+    const string GenerateMessage(int size) {
         for (const string& message : message_cache_) {
             if (message.size() == size) {
                 return message;
@@ -76,7 +76,7 @@
         }
         string message = string(size, 'x');
         message_cache_.push_back(message);
-        return std::move(message);
+        return message;
     }
 
     optional<BlockMode> getBlockMode(string transform) {
diff --git a/security/keymint/support/attestation_record.cpp b/security/keymint/support/attestation_record.cpp
index 2462228..5a26611 100644
--- a/security/keymint/support/attestation_record.cpp
+++ b/security/keymint/support/attestation_record.cpp
@@ -105,6 +105,7 @@
     ASN1_INTEGER* boot_patchlevel;
     ASN1_NULL* device_unique_attestation;
     ASN1_NULL* identity_credential;
+    ASN1_OCTET_STRING* attestation_id_second_imei;
 } KM_AUTH_LIST;
 
 ASN1_SEQUENCE(KM_AUTH_LIST) = {
@@ -170,6 +171,8 @@
                      TAG_DEVICE_UNIQUE_ATTESTATION.maskedTag()),
         ASN1_EXP_OPT(KM_AUTH_LIST, identity_credential, ASN1_NULL,
                      TAG_IDENTITY_CREDENTIAL_KEY.maskedTag()),
+        ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_second_imei, ASN1_OCTET_STRING,
+                     TAG_ATTESTATION_ID_SECOND_IMEI.maskedTag()),
 } ASN1_SEQUENCE_END(KM_AUTH_LIST);
 IMPLEMENT_ASN1_FUNCTIONS(KM_AUTH_LIST);
 
@@ -323,6 +326,7 @@
     copyAuthTag(record->boot_patchlevel, TAG_BOOT_PATCHLEVEL, auth_list);
     copyAuthTag(record->device_unique_attestation, TAG_DEVICE_UNIQUE_ATTESTATION, auth_list);
     copyAuthTag(record->identity_credential, TAG_IDENTITY_CREDENTIAL_KEY, auth_list);
+    copyAuthTag(record->attestation_id_second_imei, TAG_ATTESTATION_ID_SECOND_IMEI, auth_list);
 
     return ErrorCode::OK;
 }
diff --git a/security/keymint/support/include/keymint_support/attestation_record.h b/security/keymint/support/include/keymint_support/attestation_record.h
index bc76c93..f280f48 100644
--- a/security/keymint/support/include/keymint_support/attestation_record.h
+++ b/security/keymint/support/include/keymint_support/attestation_record.h
@@ -43,6 +43,8 @@
  */
 static const char kAttestionRecordOid[] = "1.3.6.1.4.1.11129.2.1.17";
 
+static const char kCrlDPOid[] = "2.5.29.31";  // Standard CRL Distribution Points extension.
+
 enum class VerifiedBoot : uint8_t {
     VERIFIED = 0,
     SELF_SIGNED = 1,
diff --git a/security/keymint/support/include/keymint_support/keymint_tags.h b/security/keymint/support/include/keymint_support/keymint_tags.h
index 5b2a6f3..823899a 100644
--- a/security/keymint/support/include/keymint_support/keymint_tags.h
+++ b/security/keymint/support/include/keymint_support/keymint_tags.h
@@ -77,6 +77,7 @@
 DECLARE_TYPED_TAG(ATTESTATION_ID_BRAND);
 DECLARE_TYPED_TAG(ATTESTATION_ID_DEVICE);
 DECLARE_TYPED_TAG(ATTESTATION_ID_IMEI);
+DECLARE_TYPED_TAG(ATTESTATION_ID_SECOND_IMEI);
 DECLARE_TYPED_TAG(ATTESTATION_ID_MANUFACTURER);
 DECLARE_TYPED_TAG(ATTESTATION_ID_MEID);
 DECLARE_TYPED_TAG(ATTESTATION_ID_PRODUCT);
diff --git a/security/keymint/support/remote_prov_utils.cpp b/security/keymint/support/remote_prov_utils.cpp
index 9620b6a..ffcaa95 100644
--- a/security/keymint/support/remote_prov_utils.cpp
+++ b/security/keymint/support/remote_prov_utils.cpp
@@ -22,6 +22,7 @@
 #include "aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.h"
 
 #include <aidl/android/hardware/security/keymint/RpcHardwareInfo.h>
+#include <android-base/macros.h>
 #include <android-base/properties.h>
 #include <cppbor.h>
 #include <hwtrust/hwtrust.h>
@@ -43,6 +44,7 @@
 constexpr int32_t kBccPayloadSubjPubKey = -4670552;
 constexpr int32_t kBccPayloadKeyUsage = -4670553;
 constexpr int kP256AffinePointSize = 32;
+constexpr uint32_t kNumTeeDeviceInfoEntries = 14;
 
 using EC_KEY_Ptr = bssl::UniquePtr<EC_KEY>;
 using EVP_PKEY_Ptr = bssl::UniquePtr<EVP_PKEY>;
@@ -290,11 +292,12 @@
     return chain.encode();
 }
 
-ErrMsgOr<std::vector<BccEntryData>> validateBcc(const cppbor::Array* bcc) {
+ErrMsgOr<std::vector<BccEntryData>> validateBcc(const cppbor::Array* bcc,
+                                                hwtrust::DiceChain::Kind kind) {
     auto encodedBcc = bcc->encode();
-    auto chain = hwtrust::DiceChain::verify(encodedBcc);
+    auto chain = hwtrust::DiceChain::Verify(encodedBcc, kind);
     if (!chain.ok()) return chain.error().message();
-    auto keys = chain->cose_public_keys();
+    auto keys = chain->CosePublicKeys();
     if (!keys.ok()) return keys.error().message();
     std::vector<BccEntryData> result;
     for (auto& key : *keys) {
@@ -387,6 +390,11 @@
     return entryName + " has an invalid value.\n";
 }
 
+bool isTeeDeviceInfo(const cppbor::Map& devInfo) {
+    return devInfo.get("security_level") && devInfo.get("security_level")->asTstr() &&
+           devInfo.get("security_level")->asTstr()->value() == "tee";
+}
+
 ErrMsgOr<std::unique_ptr<cppbor::Map>> parseAndValidateDeviceInfo(
         const std::vector<uint8_t>& deviceInfoBytes, IRemotelyProvisionedComponent* provisionable,
         bool isFactory) {
@@ -395,6 +403,21 @@
     const cppbor::Array kValidSecurityLevels = {"tee", "strongbox"};
     const cppbor::Array kValidAttIdStates = {"locked", "open"};
     const cppbor::Array kValidFused = {0, 1};
+    constexpr std::array<std::string_view, kNumTeeDeviceInfoEntries> kDeviceInfoKeys = {
+            "brand",
+            "manufacturer",
+            "product",
+            "model",
+            "device",
+            "vb_state",
+            "bootloader_state",
+            "vbmeta_digest",
+            "os_version",
+            "system_patch_level",
+            "boot_patch_level",
+            "vendor_patch_level",
+            "security_level",
+            "fused"};
 
     struct AttestationIdEntry {
         const char* id;
@@ -438,20 +461,48 @@
     }
 
     std::string error;
+    std::string tmp;
+    std::set<std::string_view> previousKeys;
     switch (info.versionNumber) {
         case 3:
+            if (isTeeDeviceInfo(*parsed) && parsed->size() != kNumTeeDeviceInfoEntries) {
+                error += fmt::format(
+                        "Err: Incorrect number of device info entries. Expected {} but got "
+                        "{}\n",
+                        kNumTeeDeviceInfoEntries, parsed->size());
+            }
+            // TEE IRPC instances require all entries to be present in DeviceInfo. Non-TEE instances
+            // may omit `os_version`
+            if (!isTeeDeviceInfo(*parsed) && (parsed->size() != kNumTeeDeviceInfoEntries &&
+                                              parsed->size() != kNumTeeDeviceInfoEntries - 1)) {
+                error += fmt::format(
+                        "Err: Incorrect number of device info entries. Expected {} or {} but got "
+                        "{}\n",
+                        kNumTeeDeviceInfoEntries - 1, kNumTeeDeviceInfoEntries, parsed->size());
+            }
+            for (auto& [key, _] : *parsed) {
+                const std::string& keyValue = key->asTstr()->value();
+                if (!previousKeys.insert(keyValue).second) {
+                    error += "Err: Duplicate device info entry: <" + keyValue + ">,\n";
+                }
+                if (std::find(kDeviceInfoKeys.begin(), kDeviceInfoKeys.end(), keyValue) ==
+                    kDeviceInfoKeys.end()) {
+                    error += "Err: Unrecognized key entry: <" + key->asTstr()->value() + ">,\n";
+                }
+            }
+            FALLTHROUGH_INTENDED;
         case 2:
             for (const auto& entry : kAttestationIdEntrySet) {
-                error += checkMapEntry(isFactory && !entry.alwaysValidate, *parsed, cppbor::TSTR,
-                                       entry.id);
+                tmp = checkMapEntry(isFactory && !entry.alwaysValidate, *parsed, cppbor::TSTR,
+                                    entry.id);
             }
-            if (!error.empty()) {
-                return error +
-                       "Attestation IDs are missing or malprovisioned. If this test is being\n"
-                       "run against an early proto or EVT build, this error is probably WAI\n"
-                       "and indicates that Device IDs were not provisioned in the factory. If\n"
-                       "this error is returned on a DVT or later build revision, then\n"
-                       "something is likely wrong with the factory provisioning process.";
+            if (!tmp.empty()) {
+                error += tmp +
+                         "Attestation IDs are missing or malprovisioned. If this test is being\n"
+                         "run against an early proto or EVT build, this error is probably WAI\n"
+                         "and indicates that Device IDs were not provisioned in the factory. If\n"
+                         "this error is returned on a DVT or later build revision, then\n"
+                         "something is likely wrong with the factory provisioning process.";
             }
             // TODO: Refactor the KeyMint code that validates these fields and include it here.
             error += checkMapEntry(isFactory, *parsed, cppbor::TSTR, "vb_state", kValidVbStates);
@@ -464,8 +515,7 @@
             error += checkMapEntry(isFactory, *parsed, cppbor::UINT, "fused", kValidFused);
             error += checkMapEntry(isFactory, *parsed, cppbor::TSTR, "security_level",
                                    kValidSecurityLevels);
-            if (parsed->get("security_level") && parsed->get("security_level")->asTstr() &&
-                parsed->get("security_level")->asTstr()->value() == "tee") {
+            if (isTeeDeviceInfo(*parsed)) {
                 error += checkMapEntry(isFactory, *parsed, cppbor::TSTR, "os_version");
             }
             break;
@@ -569,7 +619,7 @@
     }
 
     // BCC is [ pubkey, + BccEntry]
-    auto bccContents = validateBcc(bcc->asArray());
+    auto bccContents = validateBcc(bcc->asArray(), hwtrust::DiceChain::Kind::kVsr13);
     if (!bccContents) {
         return bccContents.message() + "\n" + prettyPrint(bcc.get());
     }
@@ -805,8 +855,8 @@
         return "Challenge must be a Bstr.";
     }
 
-    if (challenge.size() < 32 || challenge.size() > 64) {
-        return "Challenge size must be between 32 and 64 bytes inclusive. "
+    if (challenge.size() < 16 || challenge.size() > 64) {
+        return "Challenge size must be between 16 and 64 bytes inclusive. "
                "However, challenge is " +
                std::to_string(challenge.size()) + " bytes long.";
     }
@@ -859,8 +909,8 @@
         return "AuthenticatedRequest SignedData must be an Array.";
     }
 
-    // DICE chain is [ pubkey, + DiceChainEntry ]. Its format is the same as BCC from RKP v1-2.
-    auto diceContents = validateBcc(diceCertChain);
+    // DICE chain is [ pubkey, + DiceChainEntry ].
+    auto diceContents = validateBcc(diceCertChain, hwtrust::DiceChain::Kind::kVsr14);
     if (!diceContents) {
         return diceContents.message() + "\n" + prettyPrint(diceCertChain);
     }
diff --git a/security/rkp/CHANGELOG.md b/security/rkp/CHANGELOG.md
index 9409a6d..f425284 100644
--- a/security/rkp/CHANGELOG.md
+++ b/security/rkp/CHANGELOG.md
@@ -31,7 +31,7 @@
 * IRemotelyProvisionedComponent
   * The need for an EEK has been removed. There is no longer an encrypted portion of the CSR.
   * Keys for new CSR format must be generated with test mode set to false, effectively removing test
-    mode in the new CSR flow. Old behavior is kept unchanged for backwards compatibility.
+    mode in the new CSR flow.
   * The schema for the CSR itself has been significantly simplified, please see
     IRemotelyProvisionedComponent.aidl for more details. Notably,
     * the chain of signing, MACing, and encryption operations has been replaced with a single
diff --git a/security/rkp/aidl/aidl_api/android.hardware.security.rkp/1/.hash b/security/rkp/aidl/aidl_api/android.hardware.security.rkp/1/.hash
index 404553b..1397c05 100644
--- a/security/rkp/aidl/aidl_api/android.hardware.security.rkp/1/.hash
+++ b/security/rkp/aidl/aidl_api/android.hardware.security.rkp/1/.hash
@@ -1 +1,2 @@
+976674616001f714f4a4df49ee45f548de828524
 d285480d2e0002adc0ace80edf34aa725679512e
diff --git a/security/rkp/aidl/aidl_api/android.hardware.security.rkp/2/.hash b/security/rkp/aidl/aidl_api/android.hardware.security.rkp/2/.hash
index 8700d33..4b3b2a6 100644
--- a/security/rkp/aidl/aidl_api/android.hardware.security.rkp/2/.hash
+++ b/security/rkp/aidl/aidl_api/android.hardware.security.rkp/2/.hash
@@ -1 +1,2 @@
+207c9f218b9b9e4e74ff5232eb16511eca9d7d2e
 c8d34e56ae0807b61f028019622d8b60a37e0a8b
diff --git a/security/rkp/aidl/android/hardware/security/keymint/DeviceInfo.aidl b/security/rkp/aidl/android/hardware/security/keymint/DeviceInfo.aidl
index f0af619..8456148 100644
--- a/security/rkp/aidl/android/hardware/security/keymint/DeviceInfo.aidl
+++ b/security/rkp/aidl/android/hardware/security/keymint/DeviceInfo.aidl
@@ -17,11 +17,11 @@
 package android.hardware.security.keymint;
 
 /**
- * DeviceInfo contains information about the device that's fed in as AAD in the signature of the
- * device private key over the MAC key used for the bundle of public keys. These values are intended
- * to be checked by the server to verify that the certificate signing request crafted by
- * an IRemotelyProvisionedComponent HAL instance is coming from the expected device based
- * on values initially uploaded during device manufacture in the factory.
+ * DeviceInfo contains information about the device that's signed by the
+ * IRemotelyProvisionedComponent HAL. These values are intended to be checked by the server to
+ * verify that the certificate signing request crafted by an IRemotelyProvisionedComponent HAL
+ * instance is coming from the expected device based on values initially uploaded during device
+ * manufacture in the factory.
  * @hide
  */
 @VintfStability
@@ -31,6 +31,11 @@
      * canonicalized according to the specification in RFC 7049. The ordering presented here is
      * non-canonical to group similar entries semantically.
      *
+     * The DeviceInfo has changed across versions 1, 2, and 3 of the HAL. All versions of the
+     * DeviceInfo CDDL are described as follows. Please refer to the CDDL structure version
+     * that corresponds to the HAL version you are working with:
+     *
+     * Version 3, introduced in Android 14:
      *     DeviceInfo = {
      *         "brand" : tstr,
      *         "manufacturer" : tstr,
@@ -43,13 +48,63 @@
      *         ? "os_version" : tstr,                         ; Same as
      *                                                        ; android.os.Build.VERSION.release
      *                                                        ; Not optional for TEE.
-     *         "system_patch_level" : uint,                   ; YYYYMMDD
-     *         "boot_patch_level" : uint,                     ; YYYYMMDD
-     *         "vendor_patch_level" : uint,                   ; YYYYMMDD
+     *         "system_patch_level" : uint,     ; YYYYMM, must match KeyMint OS_PATCHLEVEL
+     *         "boot_patch_level" : uint,       ; YYYYMMDD, must match KeyMint BOOT_PATCHLEVEL
+     *         "vendor_patch_level" : uint,     ; YYYYMMDD, must match KeyMint VENDOR_PATCHLEVEL
      *         "security_level" : "tee" / "strongbox",
      *         "fused": 1 / 0,  ; 1 if secure boot is enforced for the processor that the IRPC
      *                          ; implementation is contained in. 0 otherwise.
      *     }
+     *
+     * ---------------------------------------------------------------------------------------------
+     *
+     * Version 2, introduced in Android 13:
+     *     DeviceInfo = {
+     *         "brand" : tstr,
+     *         "manufacturer" : tstr,
+     *         "product" : tstr,
+     *         "model" : tstr,
+     *         "device" : tstr,
+     *         "vb_state" : "green" / "yellow" / "orange",    ; Taken from the AVB values
+     *         "bootloader_state" : "locked" / "unlocked",    ; Taken from the AVB values
+     *         "vbmeta_digest": bstr,                         ; Taken from the AVB values
+     *         ? "os_version" : tstr,                         ; Same as
+     *                                                        ; android.os.Build.VERSION.release
+     *                                                        ; Not optional for TEE.
+     *         "system_patch_level" : uint,     ; YYYYMM, must match KeyMint OS_PATCHLEVEL
+     *         "boot_patch_level" : uint,       ; YYYYMMDD, must match KeyMint BOOT_PATCHLEVEL
+     *         "vendor_patch_level" : uint,     ; YYYYMMDD, must match KeyMint VENDOR_PATCHLEVEL
+     *         "version" : 2,                                 ; The CDDL schema version.
+     *         "security_level" : "tee" / "strongbox",
+     *         "fused": 1 / 0,  ; 1 if secure boot is enforced for the processor that the IRPC
+     *                          ; implementation is contained in. 0 otherwise.
+     *
+     * ---------------------------------------------------------------------------------------------
+     *
+     * Version 1, introduced in Android 12:
+     *     DeviceInfo = {
+     *         ? "brand" : tstr,
+     *         ? "manufacturer" : tstr,
+     *         ? "product" : tstr,
+     *         ? "model" : tstr,
+     *         ? "board" : tstr,
+     *         ? "vb_state" : "green" / "yellow" / "orange",  ; Taken from the AVB values
+     *         ? "bootloader_state" : "locked" / "unlocked",  ; Taken from the AVB values
+     *         ? "vbmeta_digest": bstr,                       ; Taken from the AVB values
+     *         ? "os_version" : tstr,                         ; Same as
+     *                                                        ; android.os.Build.VERSION.release
+     *         ? "system_patch_level" : uint,     ; YYYYMM, must match KeyMint OS_PATCHLEVEL
+     *         ? "boot_patch_level" : uint,       ; YYYYMMDD, must match KeyMint BOOT_PATCHLEVEL
+     *         ? "vendor_patch_level" : uint,     ; YYYYMMDD, must match KeyMint VENDOR_PATCHLEVEL
+     *         "version" : 1,                                 ; The CDDL schema version.
+     *         "security_level" : "tee" / "strongbox"
+     *         "att_id_state": "locked" / "open",  ; Attestation IDs State. If "locked", this
+     *                                             ; indicates a device's attestable IDs are
+     *                                             ; factory-locked and immutable. If "open",
+     *                                             ; this indicates the device is still in a
+     *                                             ; provisionable state and the attestable IDs
+     *                                             ; are not yet frozen.
+     *     }
      */
     byte[] deviceInfo;
 }
diff --git a/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl b/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
index 5bd2145..7960c7f 100644
--- a/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
+++ b/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
@@ -144,9 +144,9 @@
     byte[] generateEcdsaP256KeyPair(in boolean testMode, out MacedPublicKey macedPublicKey);
 
     /**
-     * This method can be removed in version 3 of the HAL. The header is kept around for
-     * backwards compatibility purposes. From v3, this method is allowed to raise a
-     * ServiceSpecificException with an error code of STATUS_REMOVED.
+     * This method has been deprecated since version 3 of the HAL. The header is kept around for
+     * backwards compatibility purposes. From v3, this method must raise a ServiceSpecificException
+     * with an error code of STATUS_REMOVED.
      *
      * For v1 and v2 implementations:
      * generateCertificateRequest creates a certificate request to be sent to the provisioning
@@ -315,7 +315,7 @@
      *
      * @param in challenge contains a byte string from the provisioning server which will be
      *        included in the signed data of the CSR structure. Different provisioned backends may
-     *        use different semantic data for this field, but the supported sizes must be between 32
+     *        use different semantic data for this field, but the supported sizes must be between 16
      *        and 64 bytes, inclusive.
      *
      * @return the following CBOR Certificate Signing Request (Csr) serialized into a byte array:
diff --git a/security/rkp/aidl/android/hardware/security/keymint/ProtectedData.aidl b/security/rkp/aidl/android/hardware/security/keymint/ProtectedData.aidl
index 57ee8cf..de94264 100644
--- a/security/rkp/aidl/android/hardware/security/keymint/ProtectedData.aidl
+++ b/security/rkp/aidl/android/hardware/security/keymint/ProtectedData.aidl
@@ -70,7 +70,7 @@
      *     ; HKDF. See details on use in ProtectedData comments above. The public key data
      *     ; included in the other field of PartyUInfo / PartyVInfo is encoded as:
      *     ;  - a raw 32-byte public key for X25519
-     *     ;  - uncompressed SEC-1 coordinate data (0x04 || x || y) for P-256
+     *     ;  - raw coordinate data (x || y) for P-256
      *     Context = [
      *         AlgorithmID : 3             ; AES-GCM 256
      *         PartyUInfo : [
diff --git a/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp b/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
index 573f10b..9f68bfa 100644
--- a/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
+++ b/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
@@ -23,6 +23,7 @@
 #include <aidl/android/hardware/security/keymint/SecurityLevel.h>
 #include <android/binder_manager.h>
 #include <binder/IServiceManager.h>
+#include <cppbor.h>
 #include <cppbor_parse.h>
 #include <gmock/gmock.h>
 #include <keymaster/cppcose/cppcose.h>
@@ -407,16 +408,8 @@
         ASSERT_FALSE(HasFatalFailure());
 
         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)) {
-                GTEST_SKIP() << "This test case applies to RKP v3+ only if "
-                             << "generateCertificateRequest() is implemented.";
-            }
+            GTEST_SKIP() << "This test case only applies to RKP v1 and v2. "
+                         << "RKP version discovered: " << rpcHardwareInfo.versionNumber;
         }
     }
 };
@@ -797,6 +790,142 @@
               BnRemotelyProvisionedComponent::STATUS_TEST_KEY_IN_PRODUCTION_REQUEST);
 }
 
+/**
+ * Call generateCertificateRequest(). Make sure it's removed.
+ */
+TEST_P(CertificateRequestV2Test, CertificateRequestV1Removed) {
+    bytevec keysToSignMac;
+    DeviceInfo deviceInfo;
+    ProtectedData protectedData;
+    auto status = provisionable_->generateCertificateRequest(
+            true /* testMode */, {} /* keysToSign */, {} /* EEK chain */, challenge_, &deviceInfo,
+            &protectedData, &keysToSignMac);
+    ASSERT_FALSE(status.isOk()) << status.getMessage();
+    EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_REMOVED);
+}
+
+void parse_root_of_trust(const vector<uint8_t>& attestation_cert,
+                         vector<uint8_t>* verified_boot_key, VerifiedBoot* verified_boot_state,
+                         bool* device_locked, vector<uint8_t>* verified_boot_hash) {
+    X509_Ptr cert(parse_cert_blob(attestation_cert));
+    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, verified_boot_key,
+                                     verified_boot_state, device_locked, verified_boot_hash);
+    ASSERT_EQ(error, ErrorCode::OK);
+}
+
+/**
+ * Generate a CSR and verify DeviceInfo against IDs attested by KeyMint.
+ */
+TEST_P(CertificateRequestV2Test, DeviceInfo) {
+    // See if there is a matching IKeyMintDevice for this IRemotelyProvisionedComponent.
+    std::shared_ptr<IKeyMintDevice> keyMint;
+    if (!matching_keymint_device(GetParam(), &keyMint)) {
+        // No matching IKeyMintDevice.
+        GTEST_SKIP() << "Skipping key use test as no matching KeyMint device found";
+        return;
+    }
+    KeyMintHardwareInfo info;
+    ASSERT_TRUE(keyMint->getHardwareInfo(&info).isOk());
+
+    // Get IDs attested by KeyMint.
+    MacedPublicKey macedPubKey;
+    bytevec privateKeyBlob;
+    auto irpcStatus =
+            provisionable_->generateEcdsaP256KeyPair(false, &macedPubKey, &privateKeyBlob);
+    ASSERT_TRUE(irpcStatus.isOk());
+
+    AttestationKey attestKey;
+    attestKey.keyBlob = std::move(privateKeyBlob);
+    attestKey.issuerSubjectName = make_name_from_str("Android Keystore Key");
+
+    // Generate an ECDSA key that is attested by the generated P256 keypair.
+    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(), attestKey, &creationResult);
+    ASSERT_TRUE(kmStatus.isOk());
+
+    vector<KeyCharacteristics> key_characteristics = std::move(creationResult.keyCharacteristics);
+    vector<Certificate> key_cert_chain = std::move(creationResult.certificateChain);
+    // We didn't provision the attestation key.
+    ASSERT_EQ(key_cert_chain.size(), 1);
+
+    // Parse attested patch levels.
+    auto auths = HwEnforcedAuthorizations(key_characteristics);
+
+    auto attestedSystemPatchLevel = auths.GetTagValue(TAG_OS_PATCHLEVEL);
+    auto attestedVendorPatchLevel = auths.GetTagValue(TAG_VENDOR_PATCHLEVEL);
+    auto attestedBootPatchLevel = auths.GetTagValue(TAG_BOOT_PATCHLEVEL);
+
+    ASSERT_TRUE(attestedSystemPatchLevel.has_value());
+    ASSERT_TRUE(attestedVendorPatchLevel.has_value());
+    ASSERT_TRUE(attestedBootPatchLevel.has_value());
+
+    // Parse attested AVB values.
+    vector<uint8_t> key;
+    VerifiedBoot attestedVbState;
+    bool attestedBootloaderState;
+    vector<uint8_t> attestedVbmetaDigest;
+    parse_root_of_trust(key_cert_chain[0].encodedCertificate, &key, &attestedVbState,
+                        &attestedBootloaderState, &attestedVbmetaDigest);
+
+    // Get IDs from DeviceInfo.
+    bytevec csr;
+    irpcStatus =
+            provisionable_->generateCertificateRequestV2({} /* keysToSign */, challenge_, &csr);
+    ASSERT_TRUE(irpcStatus.isOk()) << irpcStatus.getMessage();
+
+    auto result = verifyProductionCsr(cppbor::Array(), csr, provisionable_.get(), challenge_);
+    ASSERT_TRUE(result) << result.message();
+
+    std::unique_ptr<cppbor::Array> csrPayload = std::move(*result);
+    ASSERT_TRUE(csrPayload);
+
+    auto deviceInfo = csrPayload->get(2)->asMap();
+    ASSERT_TRUE(deviceInfo);
+
+    auto vbState = deviceInfo->get("vb_state")->asTstr();
+    auto bootloaderState = deviceInfo->get("bootloader_state")->asTstr();
+    auto vbmetaDigest = deviceInfo->get("vbmeta_digest")->asBstr();
+    auto systemPatchLevel = deviceInfo->get("system_patch_level")->asUint();
+    auto vendorPatchLevel = deviceInfo->get("vendor_patch_level")->asUint();
+    auto bootPatchLevel = deviceInfo->get("boot_patch_level")->asUint();
+    auto securityLevel = deviceInfo->get("security_level")->asTstr();
+
+    ASSERT_TRUE(vbState);
+    ASSERT_TRUE(bootloaderState);
+    ASSERT_TRUE(vbmetaDigest);
+    ASSERT_TRUE(systemPatchLevel);
+    ASSERT_TRUE(vendorPatchLevel);
+    ASSERT_TRUE(bootPatchLevel);
+    ASSERT_TRUE(securityLevel);
+
+    auto kmDeviceName = device_suffix(GetParam());
+
+    // Compare DeviceInfo against IDs attested by KeyMint.
+    ASSERT_TRUE((securityLevel->value() == "tee" && kmDeviceName == "default") ||
+                (securityLevel->value() == "strongbox" && kmDeviceName == "strongbox"));
+    ASSERT_TRUE((vbState->value() == "green" && attestedVbState == VerifiedBoot::VERIFIED) ||
+                (vbState->value() == "yellow" && attestedVbState == VerifiedBoot::SELF_SIGNED) ||
+                (vbState->value() == "orange" && attestedVbState == VerifiedBoot::UNVERIFIED));
+    ASSERT_TRUE((bootloaderState->value() == "locked" && attestedBootloaderState) ||
+                (bootloaderState->value() == "unlocked" && !attestedBootloaderState));
+    ASSERT_EQ(vbmetaDigest->value(), attestedVbmetaDigest);
+    ASSERT_EQ(systemPatchLevel->value(), attestedSystemPatchLevel.value());
+    ASSERT_EQ(vendorPatchLevel->value(), attestedVendorPatchLevel.value());
+    ASSERT_EQ(bootPatchLevel->value(), attestedBootPatchLevel.value());
+}
+
 INSTANTIATE_REM_PROV_AIDL_TEST(CertificateRequestV2Test);
 
 using VsrRequirementTest = VtsRemotelyProvisionedComponentTests;
diff --git a/sensors/1.0/vts/functional/SensorsHidlEnvironmentV1_0.h b/sensors/1.0/vts/functional/SensorsHidlEnvironmentV1_0.h
index b802e6c..a4e4457 100644
--- a/sensors/1.0/vts/functional/SensorsHidlEnvironmentV1_0.h
+++ b/sensors/1.0/vts/functional/SensorsHidlEnvironmentV1_0.h
@@ -46,8 +46,6 @@
     bool resetHal() override;
     void startPollingThread() override;
     static void pollingThread(SensorsHidlEnvironmentV1_0* env, std::atomic_bool& stop);
-
-    GTEST_DISALLOW_COPY_AND_ASSIGN_(SensorsHidlEnvironmentV1_0);
 };
 
 #endif  // ANDROID_SENSORS_HIDL_ENVIRONMENT_V1_0_H
\ No newline at end of file
diff --git a/sensors/aidl/convert/convert.cpp b/sensors/aidl/convert/convert.cpp
index abd4d55..2dc7a17 100644
--- a/sensors/aidl/convert/convert.cpp
+++ b/sensors/aidl/convert/convert.cpp
@@ -462,7 +462,6 @@
             limitedAxesImuUncal.z = src.limited_axes_imu_uncalibrated.z_uncalib;
             limitedAxesImuUncal.xBias = src.limited_axes_imu_uncalibrated.x_bias;
             limitedAxesImuUncal.yBias = src.limited_axes_imu_uncalibrated.y_bias;
-            limitedAxesImuUncal.yBias = src.limited_axes_imu_uncalibrated.y_bias;
             limitedAxesImuUncal.zBias = src.limited_axes_imu_uncalibrated.z_bias;
             limitedAxesImuUncal.xSupported = src.limited_axes_imu_uncalibrated.x_supported;
             limitedAxesImuUncal.ySupported = src.limited_axes_imu_uncalibrated.y_supported;
diff --git a/sensors/aidl/vts/SensorsAidlEnvironment.h b/sensors/aidl/vts/SensorsAidlEnvironment.h
index 2f5f287..a852e91 100644
--- a/sensors/aidl/vts/SensorsAidlEnvironment.h
+++ b/sensors/aidl/vts/SensorsAidlEnvironment.h
@@ -69,8 +69,6 @@
      */
     void readEvents();
 
-    GTEST_DISALLOW_COPY_AND_ASSIGN_(SensorsAidlEnvironment);
-
     /**
      * Pointer to the Sensors HAL Interface that allows the test to call HAL functions.
      */
diff --git a/sensors/aidl/vts/VtsAidlHalSensorsTargetTest.cpp b/sensors/aidl/vts/VtsAidlHalSensorsTargetTest.cpp
index d536e29..35220a2 100644
--- a/sensors/aidl/vts/VtsAidlHalSensorsTargetTest.cpp
+++ b/sensors/aidl/vts/VtsAidlHalSensorsTargetTest.cpp
@@ -98,6 +98,7 @@
         CHECK_TYPE_STRING_FOR_SENSOR_TYPE(TILT_DETECTOR);
         CHECK_TYPE_STRING_FOR_SENSOR_TYPE(WAKE_GESTURE);
         CHECK_TYPE_STRING_FOR_SENSOR_TYPE(WRIST_TILT_GESTURE);
+        CHECK_TYPE_STRING_FOR_SENSOR_TYPE(HINGE_ANGLE);
         default:
             FAIL() << "Type " << static_cast<int>(type)
                    << " in android defined range is not checked, "
diff --git a/sensors/common/default/2.X/multihal/tests/fake_subhal/Sensor.cpp b/sensors/common/default/2.X/multihal/tests/fake_subhal/Sensor.cpp
index a0bb67a..d8e292a 100644
--- a/sensors/common/default/2.X/multihal/tests/fake_subhal/Sensor.cpp
+++ b/sensors/common/default/2.X/multihal/tests/fake_subhal/Sensor.cpp
@@ -76,6 +76,7 @@
                                   static_cast<int64_t>(mSensorInfo.minDelay) * 1000,
                                   static_cast<int64_t>(mSensorInfo.maxDelay) * 1000);
 
+    std::unique_lock<std::mutex> lock(mRunMutex);
     if (mSamplingPeriodNs != samplingPeriodNs) {
         mSamplingPeriodNs = samplingPeriodNs;
         // Wake up the 'run' thread to check if a new event should be generated now
diff --git a/sensors/common/vts/2_X/SensorsHidlEnvironmentV2_X.h b/sensors/common/vts/2_X/SensorsHidlEnvironmentV2_X.h
index 5fe4d8b..796de2f 100644
--- a/sensors/common/vts/2_X/SensorsHidlEnvironmentV2_X.h
+++ b/sensors/common/vts/2_X/SensorsHidlEnvironmentV2_X.h
@@ -79,8 +79,6 @@
      */
     void readEvents();
 
-    GTEST_DISALLOW_COPY_AND_ASSIGN_(SensorsHidlEnvironmentV2_X);
-
     /**
      * Pointer to the Sensors HAL Interface that allows the test to call HAL functions.
      */
diff --git a/sensors/common/vts/2_X/VtsHalSensorsV2_XTargetTest.h b/sensors/common/vts/2_X/VtsHalSensorsV2_XTargetTest.h
index 7e22b19..aa6e881 100644
--- a/sensors/common/vts/2_X/VtsHalSensorsV2_XTargetTest.h
+++ b/sensors/common/vts/2_X/VtsHalSensorsV2_XTargetTest.h
@@ -559,6 +559,11 @@
 }
 
 TEST_P(SensorsHidlTest, CleanupConnectionsOnInitialize) {
+    if (getSensorsList().size() == 0) {
+        // No sensors
+        return;
+    }
+
     activateAllSensors(true);
 
     // Verify that events are received
diff --git a/sensors/common/vts/utils/include/sensors-vts-utils/SensorsVtsEnvironmentBase.h b/sensors/common/vts/utils/include/sensors-vts-utils/SensorsVtsEnvironmentBase.h
index 17a96ed..e851d40 100644
--- a/sensors/common/vts/utils/include/sensors-vts-utils/SensorsVtsEnvironmentBase.h
+++ b/sensors/common/vts/utils/include/sensors-vts-utils/SensorsVtsEnvironmentBase.h
@@ -115,6 +115,8 @@
         : mCollectionEnabled(false), mCallback(nullptr) {
         mServiceName = service_name;
     }
+    SensorsVtsEnvironmentBase(const SensorsVtsEnvironmentBase&) = delete;
+    SensorsVtsEnvironmentBase& operator=(const SensorsVtsEnvironmentBase&) = delete;
     virtual ~SensorsVtsEnvironmentBase(){};
 
     void addEvent(const Event& ev) {
@@ -139,8 +141,6 @@
     std::mutex mEventsMutex;
 
     IEventCallback<Event>* mCallback;
-
-    GTEST_DISALLOW_COPY_AND_ASSIGN_(SensorsVtsEnvironmentBase<Event>);
 };
 
 #endif  // ANDROID_SENSORS_VTS_ENVIRONMENT_BASE_H
\ No newline at end of file
diff --git a/tests/extension/vibrator/aidl/Android.bp b/tests/extension/vibrator/aidl/Android.bp
index 20df5bb..0306dca 100644
--- a/tests/extension/vibrator/aidl/Android.bp
+++ b/tests/extension/vibrator/aidl/Android.bp
@@ -38,5 +38,11 @@
             enabled: false,
         },
     },
-    versions: ["1"],
+    frozen: true,
+    versions_with_info: [
+        {
+            version: "1",
+            imports: ["android.hardware.vibrator-V2"],
+        },
+    ],
 }
diff --git a/tests/extension/vibrator/aidl/default/Android.bp b/tests/extension/vibrator/aidl/default/Android.bp
index 0f3895f..5e156af 100644
--- a/tests/extension/vibrator/aidl/default/Android.bp
+++ b/tests/extension/vibrator/aidl/default/Android.bp
@@ -29,6 +29,6 @@
         "libbase",
         "libbinder_ndk",
         "android.hardware.vibrator-V2-ndk",
-        "android.hardware.tests.extension.vibrator-V2-ndk",
+        "android.hardware.tests.extension.vibrator-V1-ndk",
     ],
 }
diff --git a/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/CoolingDevice.aidl b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/CoolingDevice.aidl
index dfd8686..dff3c4c 100644
--- a/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/CoolingDevice.aidl
+++ b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/CoolingDevice.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.thermal;
 /* @hide */
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable CoolingDevice {
   android.hardware.thermal.CoolingType type;
   String name;
diff --git a/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/Temperature.aidl b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/Temperature.aidl
index 3bf08bf..ce70ab8 100644
--- a/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/Temperature.aidl
+++ b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/Temperature.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.thermal;
 /* @hide */
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable Temperature {
   android.hardware.thermal.TemperatureType type;
   String name;
diff --git a/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/TemperatureThreshold.aidl b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/TemperatureThreshold.aidl
index c5ca4b9..a384d19 100644
--- a/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/TemperatureThreshold.aidl
+++ b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/TemperatureThreshold.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.thermal;
 /* @hide */
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
 parcelable TemperatureThreshold {
   android.hardware.thermal.TemperatureType type;
   String name;
diff --git a/thermal/aidl/android/hardware/thermal/CoolingDevice.aidl b/thermal/aidl/android/hardware/thermal/CoolingDevice.aidl
index 1f2360d..0c5c17d 100644
--- a/thermal/aidl/android/hardware/thermal/CoolingDevice.aidl
+++ b/thermal/aidl/android/hardware/thermal/CoolingDevice.aidl
@@ -20,6 +20,7 @@
 
 /* @hide */
 @VintfStability
+@JavaDerive(toString=true)
 parcelable CoolingDevice {
     /**
      * This cooling device type, CPU, GPU, BATTERY, and etc.
diff --git a/thermal/aidl/android/hardware/thermal/IThermal.aidl b/thermal/aidl/android/hardware/thermal/IThermal.aidl
index 7c23c17..c94edcd 100644
--- a/thermal/aidl/android/hardware/thermal/IThermal.aidl
+++ b/thermal/aidl/android/hardware/thermal/IThermal.aidl
@@ -36,9 +36,8 @@
      *    exist on boot. The method always returns and never removes from
      *    the list such cooling devices.
      *
-     * @throws ScopedAStatus Status of the operation. If status code is not
-     *    STATUS_OK, getMessage() must be populated with the human-readable
-     *    error message.
+     * @throws EX_ILLEGAL_STATE If the Thermal HAL is not initialized successfully. And the
+     *         getMessage() must be populated with human-readable error message.
      */
     CoolingDevice[] getCoolingDevices();
 
@@ -54,9 +53,8 @@
      *    exist on boot. The method always returns and never removes from
      *    the list such cooling devices.
      *
-     * @throws ScopedAStatus Status of the operation. If status code is not
-     *    STATUS_OK, the getMessage() must be populated with the human-readable
-     *    error message.
+     * @throws EX_ILLEGAL_STATE If the Thermal HAL is not initialized successfully. And the
+     *         getMessage() must be populated with human-readable error message.
      */
     CoolingDevice[] getCoolingDevicesWithType(in CoolingType type);
 
@@ -70,9 +68,8 @@
      *    they go offline, if these devices exist on boot. The method
      *    always returns and never removes such temperatures.
      *
-     * @throws ScopedAStatus Status of the operation. If status code is not
-     *    STATUS_OK, the getMessage() must be populated with the human-readable
-     *    error message.
+     * @throws EX_ILLEGAL_STATE If the Thermal HAL is not initialized successfully. And the
+     *         getMessage() must be populated with human-readable error message.
      */
     Temperature[] getTemperatures();
 
@@ -88,9 +85,8 @@
      *    they go offline, if these devices exist on boot. The method
      *    always returns and never removes such temperatures.
      *
-     * @throws ScopedAStatus Status of the operation. If status code is not
-     *    STATUS_OK, the getMessage() must be populated with the human-readable
-     *    error message.
+     * @throws EX_ILLEGAL_STATE If the Thermal HAL is not initialized successfully. And the
+     *         getMessage() must be populated with human-readable error message.
      */
     Temperature[] getTemperaturesWithType(in TemperatureType type);
 
@@ -110,9 +106,8 @@
      *    throttling status, use getTemperatures or registerThermalChangedCallback
      *    and listen to the callback.
      *
-     * @throws ScopedAStatus Status of the operation. If status code is not
-     *    STATUS_OK, the getMessage() must be populated with the human-readable
-     *    error message.
+     * @throws EX_ILLEGAL_STATE If the Thermal HAL is not initialized successfully. And the
+     *         getMessage() must be populated with human-readable error message.
      */
     TemperatureThreshold[] getTemperatureThresholds();
 
@@ -135,9 +130,8 @@
      *    throttling status, use getTemperatures or registerThermalChangedCallback
      *    and listen to the callback.
      *
-     * @throws ScopedAStatus Status of the operation. If status code is not
-     *    STATUS_OK, the getMessage() must be populated with the human-readable
-     *    error message.
+     * @throws EX_ILLEGAL_STATE If the Thermal HAL is not initialized successfully. And the
+     *         getMessage() must be populated with human-readable error message.
      */
     TemperatureThreshold[] getTemperatureThresholdsWithType(in TemperatureType type);
 
@@ -152,12 +146,10 @@
      *    thermal events. if nullptr callback is given, the status code will be
      *    STATUS_BAD_VALUE and the operation will fail.
      *
-     * @throws ScopedAStatus Status of the operation. If status code is not
-     *    STATUS_OK, the getMessage() must be populated with the human-readable
-     *    error message. If callback is given nullptr, the returned status code
-     *    will be STATUS_BAD_VALUE and the exception will be EX_ILLEGAL_ARGUMENT.
-     *    if callback is already registered, the returned status code will be
-     *    STATUS_INVALID_OPERATION, the exception will be EX_ILLEGAL_ARGUMENT.
+     * @throws EX_ILLEGAL_ARGUMENT If the callback is given nullptr or already registered. And the
+     *         getMessage() must be populated with human-readable error message.
+     * @throws EX_ILLEGAL_STATE If the Thermal HAL is not initialized successfully. And the
+     *         getMessage() must be populated with human-readable error message.
      */
     void registerThermalChangedCallback(in IThermalChangedCallback callback);
 
@@ -174,12 +166,10 @@
      *    STATUS_BAD_VALUE and the operation will fail.
      * @param type the type to be filtered.
      *
-     * @throws ScopedAStatus Status of the operation. If status code is not
-     *    STATUS_OK, the getMessage() must be populated with the human-readable
-     *    error message. If callback is given nullptr, the returned status code
-     *    will be STATUS_BAD_VALUE and the exception will be EX_ILLEGAL_ARGUMENT.
-     *    if callback is already registered, the returned status code will be
-     *    STATUS_INVALID_OPERATION, the exception will be EX_ILLEGAL_ARGUMENT.
+     * @throws EX_ILLEGAL_ARGUMENT If the callback is given nullptr or already registered. And the
+     *         getMessage() must be populated with human-readable error message.
+     * @throws EX_ILLEGAL_STATE If the Thermal HAL is not initialized successfully. And the
+     *         getMessage() must be populated with human-readable error message.
      */
     void registerThermalChangedCallbackWithType(
             in IThermalChangedCallback callback, in TemperatureType type);
@@ -192,12 +182,10 @@
      *    thermal events. if nullptr callback is given, the status code will be
      *    STATUS_BAD_VALUE and the operation will fail.
      *
-     * @throws ScopedAStatus Status of the operation. If status code is not
-     *    STATUS_OK, the getMessage() must be populated with the human-readable
-     *    error message. If callback is given nullptr, the returned status code
-     *    will be STATUS_BAD_VALUE and the exception will be EX_ILLEGAL_ARGUMENT.
-     *    if callback is not registered, the returned status code will be
-     *    STATUS_INVALID_OPERATION, the exception will be EX_ILLEGAL_ARGUMENT.
+     * @throws EX_ILLEGAL_ARGUMENT If the callback is given nullptr or not previously registered.
+     *         And the getMessage() must be populated with human-readable error message.
+     * @throws EX_ILLEGAL_STATE If the Thermal HAL is not initialized successfully. And the
+     *         getMessage() must be populated with human-readable error message.
      */
     void unregisterThermalChangedCallback(in IThermalChangedCallback callback);
 }
diff --git a/thermal/aidl/android/hardware/thermal/Temperature.aidl b/thermal/aidl/android/hardware/thermal/Temperature.aidl
index 281d68d..b3f6700 100644
--- a/thermal/aidl/android/hardware/thermal/Temperature.aidl
+++ b/thermal/aidl/android/hardware/thermal/Temperature.aidl
@@ -21,6 +21,7 @@
 
 /* @hide */
 @VintfStability
+@JavaDerive(toString=true)
 parcelable Temperature {
     /**
      * This temperature's type.
diff --git a/thermal/aidl/android/hardware/thermal/TemperatureThreshold.aidl b/thermal/aidl/android/hardware/thermal/TemperatureThreshold.aidl
index 0714c82..94991ae 100644
--- a/thermal/aidl/android/hardware/thermal/TemperatureThreshold.aidl
+++ b/thermal/aidl/android/hardware/thermal/TemperatureThreshold.aidl
@@ -20,6 +20,7 @@
 
 /* @hide */
 @VintfStability
+@JavaDerive(toString=true)
 parcelable TemperatureThreshold {
     /**
      * This temperature's type.
diff --git a/thermal/aidl/default/Thermal.cpp b/thermal/aidl/default/Thermal.cpp
index 5771e0e..f643d22 100644
--- a/thermal/aidl/default/Thermal.cpp
+++ b/thermal/aidl/default/Thermal.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "thermal_service_example"
+
 #include "Thermal.h"
 
 #include <android-base/logging.h>
@@ -22,6 +24,18 @@
 
 using ndk::ScopedAStatus;
 
+namespace {
+
+bool interfacesEqual(const std::shared_ptr<::ndk::ICInterface>& left,
+                     const std::shared_ptr<::ndk::ICInterface>& right) {
+    if (left == nullptr || right == nullptr || !left->isRemote() || !right->isRemote()) {
+        return left == right;
+    }
+    return left->asBinder() == right->asBinder();
+}
+
+}  // namespace
+
 ScopedAStatus Thermal::getCoolingDevices(std::vector<CoolingDevice>* /* out_devices */) {
     LOG(VERBOSE) << __func__;
     return ScopedAStatus::ok();
@@ -61,12 +75,20 @@
         const std::shared_ptr<IThermalChangedCallback>& in_callback) {
     LOG(VERBOSE) << __func__ << " IThermalChangedCallback: " << in_callback;
     if (in_callback == nullptr) {
-        return ScopedAStatus::fromStatus(STATUS_BAD_VALUE);
+        return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                "Invalid nullptr callback");
     }
-    if (mCallbacks.find(in_callback) != mCallbacks.end()) {
-        return ScopedAStatus::fromStatus(STATUS_INVALID_OPERATION);
+    {
+        std::lock_guard<std::mutex> _lock(thermal_callback_mutex_);
+        if (std::any_of(thermal_callbacks_.begin(), thermal_callbacks_.end(),
+                        [&](const std::shared_ptr<IThermalChangedCallback>& c) {
+                            return interfacesEqual(c, in_callback);
+                        })) {
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "Callback already registered");
+        }
+        thermal_callbacks_.push_back(in_callback);
     }
-    mCallbacks.insert(in_callback);
     return ScopedAStatus::ok();
 }
 
@@ -75,26 +97,48 @@
     LOG(VERBOSE) << __func__ << " IThermalChangedCallback: " << in_callback
                  << ", TemperatureType: " << static_cast<int32_t>(in_type);
     if (in_callback == nullptr) {
-        return ScopedAStatus::fromStatus(STATUS_BAD_VALUE);
+        return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                "Invalid nullptr callback");
     }
-    if (mCallbacks.find(in_callback) != mCallbacks.end()) {
-        return ScopedAStatus::fromStatus(STATUS_INVALID_OPERATION);
+    {
+        std::lock_guard<std::mutex> _lock(thermal_callback_mutex_);
+        if (std::any_of(thermal_callbacks_.begin(), thermal_callbacks_.end(),
+                        [&](const std::shared_ptr<IThermalChangedCallback>& c) {
+                            return interfacesEqual(c, in_callback);
+                        })) {
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "Callback already registered");
+        }
+        thermal_callbacks_.push_back(in_callback);
     }
-    mCallbacks.insert(in_callback);
     return ScopedAStatus::ok();
 }
 
 ScopedAStatus Thermal::unregisterThermalChangedCallback(
         const std::shared_ptr<IThermalChangedCallback>& in_callback) {
     LOG(VERBOSE) << __func__ << " IThermalChangedCallback: " << in_callback;
-    bool found = false;
     if (in_callback == nullptr) {
-        return ScopedAStatus::fromStatus(STATUS_BAD_VALUE);
+        return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                "Invalid nullptr callback");
     }
-    if (mCallbacks.find(in_callback) == mCallbacks.end()) {
-        return ScopedAStatus::fromStatus(STATUS_INVALID_OPERATION);
+    {
+        std::lock_guard<std::mutex> _lock(thermal_callback_mutex_);
+        bool removed = false;
+        thermal_callbacks_.erase(
+                std::remove_if(thermal_callbacks_.begin(), thermal_callbacks_.end(),
+                               [&](const std::shared_ptr<IThermalChangedCallback>& c) {
+                                   if (interfacesEqual(c, in_callback)) {
+                                       removed = true;
+                                       return true;
+                                   }
+                                   return false;
+                               }),
+                thermal_callbacks_.end());
+        if (!removed) {
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "Callback wasn't registered");
+        }
     }
-    mCallbacks.erase(in_callback);
     return ScopedAStatus::ok();
 }
 
diff --git a/thermal/aidl/default/Thermal.h b/thermal/aidl/default/Thermal.h
index 788af4a..8885e63 100644
--- a/thermal/aidl/default/Thermal.h
+++ b/thermal/aidl/default/Thermal.h
@@ -54,7 +54,8 @@
             const std::shared_ptr<IThermalChangedCallback>& in_callback) override;
 
   private:
-    std::set<std::shared_ptr<IThermalChangedCallback>> mCallbacks;
+    std::mutex thermal_callback_mutex_;
+    std::vector<std::shared_ptr<IThermalChangedCallback>> thermal_callbacks_;
 };
 
 }  // namespace example
diff --git a/thermal/aidl/default/main.cpp b/thermal/aidl/default/main.cpp
index 61d8ad0..9f4ddb8 100644
--- a/thermal/aidl/default/main.cpp
+++ b/thermal/aidl/default/main.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "thermal_service_example"
+
 #include "Thermal.h"
 
 #include <android-base/logging.h>
diff --git a/thermal/aidl/vts/VtsHalThermalTargetTest.cpp b/thermal/aidl/vts/VtsHalThermalTargetTest.cpp
index b93250e..73c5dd2 100644
--- a/thermal/aidl/vts/VtsHalThermalTargetTest.cpp
+++ b/thermal/aidl/vts/VtsHalThermalTargetTest.cpp
@@ -95,21 +95,21 @@
 
         mThermalCallback = ndk::SharedRefBase::make<ThermalCallback>();
         ASSERT_NE(mThermalCallback, nullptr);
-        auto ret = mThermal->registerThermalChangedCallback(mThermalCallback);
-        ASSERT_TRUE(ret.isOk());
+        auto status = mThermal->registerThermalChangedCallback(mThermalCallback);
+        ASSERT_TRUE(status.isOk());
         // Expect to fail if register again
-        ret = mThermal->registerThermalChangedCallback(mThermalCallback);
-        ASSERT_FALSE(ret.isOk());
-        ASSERT_TRUE(ret.getStatus() == STATUS_INVALID_OPERATION);
+        status = mThermal->registerThermalChangedCallback(mThermalCallback);
+        ASSERT_FALSE(status.isOk());
+        ASSERT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
     }
 
     void TearDown() override {
-        auto ret = mThermal->unregisterThermalChangedCallback(mThermalCallback);
-        ASSERT_TRUE(ret.isOk());
+        auto status = mThermal->unregisterThermalChangedCallback(mThermalCallback);
+        ASSERT_TRUE(status.isOk());
         // Expect to fail if unregister again
-        ret = mThermal->unregisterThermalChangedCallback(mThermalCallback);
-        ASSERT_FALSE(ret.isOk());
-        ASSERT_TRUE(ret.getStatus() == STATUS_INVALID_OPERATION);
+        status = mThermal->unregisterThermalChangedCallback(mThermalCallback);
+        ASSERT_FALSE(status.isOk());
+        ASSERT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
     }
 
   protected:
diff --git a/tv/README.md b/tv/README.md
new file mode 100644
index 0000000..9a1c381
--- /dev/null
+++ b/tv/README.md
@@ -0,0 +1,8 @@
+# TV-related HIDL and AIDL HALs
+
+This directory bundles TV-related HALs in HIDL (legacy) and AIDL.
+
+- The 'tuner' directory contains the Tuner HIDL and AIDL HALs.
+- The 'input' directory contains the TV Input HIDL and AIDL HALs.
+- The 'cec' directory contains the CEC HIDL HAL.
+- The 'hdmi' directory contains the HDMI-related AIDL HALs, which includes the CEC AIDL HAL.
diff --git a/tv/hdmi/cec/aidl/OWNERS b/tv/hdmi/OWNERS
similarity index 100%
rename from tv/hdmi/cec/aidl/OWNERS
rename to tv/hdmi/OWNERS
diff --git a/tv/hdmi/README.md b/tv/hdmi/README.md
new file mode 100644
index 0000000..183a3d0
--- /dev/null
+++ b/tv/hdmi/README.md
@@ -0,0 +1,11 @@
+# HDMI-related AIDL HALs for Android devices
+
+This directory bundles 3 HDMI-related AIDL HALs: HDMI Connection HAL, CEC HAL and eARC HAL.
+
+The HDMI Connection HAL contains general APIs for the HDMI Connection. These methods are required by
+the CEC and the eARC implementation. Therefore, devices that implement CEC need to support the HDMI
+Connection HAL and the CEC HAL. Devices that implement eARC need to support the HDMI Connection HAL
+and the eARC HAL.
+
+Other Android HALs are related to HDMI as well, but not included in this directory for historical
+reasons, e.g. Display HAL and TV Input HAL.
diff --git a/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/CecDeviceType.aidl b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/CecDeviceType.aidl
index 08dc1ee..4f7e247 100644
--- a/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/CecDeviceType.aidl
+++ b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/CecDeviceType.aidl
@@ -34,7 +34,7 @@
 package android.hardware.tv.hdmi.cec;
 @Backing(type="byte") @VintfStability
 enum CecDeviceType {
-  INACTIVE = -1,
+  INACTIVE = (-1) /* -1 */,
   TV = 0,
   RECORDER = 1,
   TUNER = 3,
diff --git a/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/CecMessageType.aidl b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/CecMessageType.aidl
index 31ca895..20472f0 100644
--- a/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/CecMessageType.aidl
+++ b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/CecMessageType.aidl
@@ -34,78 +34,78 @@
 package android.hardware.tv.hdmi.cec;
 @Backing(type="int") @VintfStability
 enum CecMessageType {
-  FEATURE_ABORT = 0,
-  IMAGE_VIEW_ON = 4,
-  TUNER_STEP_INCREMENT = 5,
-  TUNER_STEP_DECREMENT = 6,
-  TUNER_DEVICE_STATUS = 7,
-  GIVE_TUNER_DEVICE_STATUS = 8,
-  RECORD_ON = 9,
-  RECORD_STATUS = 10,
-  RECORD_OFF = 11,
-  TEXT_VIEW_ON = 13,
-  RECORD_TV_SCREEN = 15,
-  GIVE_DECK_STATUS = 26,
-  DECK_STATUS = 27,
-  SET_MENU_LANGUAGE = 50,
-  CLEAR_ANALOG_TIMER = 51,
-  SET_ANALOG_TIMER = 52,
-  TIMER_STATUS = 53,
-  STANDBY = 54,
-  PLAY = 65,
-  DECK_CONTROL = 66,
-  TIMER_CLEARED_STATUS = 67,
-  USER_CONTROL_PRESSED = 68,
-  USER_CONTROL_RELEASED = 69,
-  GIVE_OSD_NAME = 70,
-  SET_OSD_NAME = 71,
-  SET_OSD_STRING = 100,
-  SET_TIMER_PROGRAM_TITLE = 103,
-  SYSTEM_AUDIO_MODE_REQUEST = 112,
-  GIVE_AUDIO_STATUS = 113,
-  SET_SYSTEM_AUDIO_MODE = 114,
-  REPORT_AUDIO_STATUS = 122,
-  GIVE_SYSTEM_AUDIO_MODE_STATUS = 125,
-  SYSTEM_AUDIO_MODE_STATUS = 126,
-  ROUTING_CHANGE = 128,
-  ROUTING_INFORMATION = 129,
-  ACTIVE_SOURCE = 130,
-  GIVE_PHYSICAL_ADDRESS = 131,
-  REPORT_PHYSICAL_ADDRESS = 132,
-  REQUEST_ACTIVE_SOURCE = 133,
-  SET_STREAM_PATH = 134,
-  DEVICE_VENDOR_ID = 135,
-  VENDOR_COMMAND = 137,
-  VENDOR_REMOTE_BUTTON_DOWN = 138,
-  VENDOR_REMOTE_BUTTON_UP = 139,
-  GIVE_DEVICE_VENDOR_ID = 140,
-  MENU_REQUEST = 141,
-  MENU_STATUS = 142,
-  GIVE_DEVICE_POWER_STATUS = 143,
-  REPORT_POWER_STATUS = 144,
-  GET_MENU_LANGUAGE = 145,
-  SELECT_ANALOG_SERVICE = 146,
-  SELECT_DIGITAL_SERVICE = 147,
-  SET_DIGITAL_TIMER = 151,
-  CLEAR_DIGITAL_TIMER = 153,
-  SET_AUDIO_RATE = 154,
-  INACTIVE_SOURCE = 157,
-  CEC_VERSION = 158,
-  GET_CEC_VERSION = 159,
-  VENDOR_COMMAND_WITH_ID = 160,
-  CLEAR_EXTERNAL_TIMER = 161,
-  SET_EXTERNAL_TIMER = 162,
-  REPORT_SHORT_AUDIO_DESCRIPTOR = 163,
-  REQUEST_SHORT_AUDIO_DESCRIPTOR = 164,
-  INITIATE_ARC = 192,
-  REPORT_ARC_INITIATED = 193,
-  REPORT_ARC_TERMINATED = 194,
-  REQUEST_ARC_INITIATION = 195,
-  REQUEST_ARC_TERMINATION = 196,
-  TERMINATE_ARC = 197,
-  ABORT = 255,
-  GIVE_FEATURES = 165,
-  REPORT_FEATURES = 166,
-  REQUEST_CURRENT_LATENCY = 167,
-  REPORT_CURRENT_LATENCY = 168,
+  FEATURE_ABORT = 0x00,
+  IMAGE_VIEW_ON = 0x04,
+  TUNER_STEP_INCREMENT = 0x05,
+  TUNER_STEP_DECREMENT = 0x06,
+  TUNER_DEVICE_STATUS = 0x07,
+  GIVE_TUNER_DEVICE_STATUS = 0x08,
+  RECORD_ON = 0x09,
+  RECORD_STATUS = 0x0A,
+  RECORD_OFF = 0x0B,
+  TEXT_VIEW_ON = 0x0D,
+  RECORD_TV_SCREEN = 0x0F,
+  GIVE_DECK_STATUS = 0x1A,
+  DECK_STATUS = 0x1B,
+  SET_MENU_LANGUAGE = 0x32,
+  CLEAR_ANALOG_TIMER = 0x33,
+  SET_ANALOG_TIMER = 0x34,
+  TIMER_STATUS = 0x35,
+  STANDBY = 0x36,
+  PLAY = 0x41,
+  DECK_CONTROL = 0x42,
+  TIMER_CLEARED_STATUS = 0x43,
+  USER_CONTROL_PRESSED = 0x44,
+  USER_CONTROL_RELEASED = 0x45,
+  GIVE_OSD_NAME = 0x46,
+  SET_OSD_NAME = 0x47,
+  SET_OSD_STRING = 0x64,
+  SET_TIMER_PROGRAM_TITLE = 0x67,
+  SYSTEM_AUDIO_MODE_REQUEST = 0x70,
+  GIVE_AUDIO_STATUS = 0x71,
+  SET_SYSTEM_AUDIO_MODE = 0x72,
+  REPORT_AUDIO_STATUS = 0x7A,
+  GIVE_SYSTEM_AUDIO_MODE_STATUS = 0x7D,
+  SYSTEM_AUDIO_MODE_STATUS = 0x7E,
+  ROUTING_CHANGE = 0x80,
+  ROUTING_INFORMATION = 0x81,
+  ACTIVE_SOURCE = 0x82,
+  GIVE_PHYSICAL_ADDRESS = 0x83,
+  REPORT_PHYSICAL_ADDRESS = 0x84,
+  REQUEST_ACTIVE_SOURCE = 0x85,
+  SET_STREAM_PATH = 0x86,
+  DEVICE_VENDOR_ID = 0x87,
+  VENDOR_COMMAND = 0x89,
+  VENDOR_REMOTE_BUTTON_DOWN = 0x8A,
+  VENDOR_REMOTE_BUTTON_UP = 0x8B,
+  GIVE_DEVICE_VENDOR_ID = 0x8C,
+  MENU_REQUEST = 0x8D,
+  MENU_STATUS = 0x8E,
+  GIVE_DEVICE_POWER_STATUS = 0x8F,
+  REPORT_POWER_STATUS = 0x90,
+  GET_MENU_LANGUAGE = 0x91,
+  SELECT_ANALOG_SERVICE = 0x92,
+  SELECT_DIGITAL_SERVICE = 0x93,
+  SET_DIGITAL_TIMER = 0x97,
+  CLEAR_DIGITAL_TIMER = 0x99,
+  SET_AUDIO_RATE = 0x9A,
+  INACTIVE_SOURCE = 0x9D,
+  CEC_VERSION = 0x9E,
+  GET_CEC_VERSION = 0x9F,
+  VENDOR_COMMAND_WITH_ID = 0xA0,
+  CLEAR_EXTERNAL_TIMER = 0xA1,
+  SET_EXTERNAL_TIMER = 0xA2,
+  REPORT_SHORT_AUDIO_DESCRIPTOR = 0xA3,
+  REQUEST_SHORT_AUDIO_DESCRIPTOR = 0xA4,
+  INITIATE_ARC = 0xC0,
+  REPORT_ARC_INITIATED = 0xC1,
+  REPORT_ARC_TERMINATED = 0xC2,
+  REQUEST_ARC_INITIATION = 0xC3,
+  REQUEST_ARC_TERMINATION = 0xC4,
+  TERMINATE_ARC = 0xC5,
+  ABORT = 0xFF,
+  GIVE_FEATURES = 0xA5,
+  REPORT_FEATURES = 0xA6,
+  REQUEST_CURRENT_LATENCY = 0xA7,
+  REPORT_CURRENT_LATENCY = 0xA8,
 }
diff --git a/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/IHdmiCec.aidl b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/IHdmiCec.aidl
index 0881489..c6060d1 100644
--- a/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/IHdmiCec.aidl
+++ b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/IHdmiCec.aidl
@@ -41,7 +41,7 @@
   int getPhysicalAddress();
   int getVendorId();
   android.hardware.tv.hdmi.cec.SendMessageResult sendMessage(in android.hardware.tv.hdmi.cec.CecMessage message);
-  void setCallback(in android.hardware.tv.hdmi.cec.IHdmiCecCallback callback);
+  void setCallback(in @nullable android.hardware.tv.hdmi.cec.IHdmiCecCallback callback);
   void setLanguage(in String language);
   void enableWakeupByOtp(in boolean value);
   void enableCec(in boolean value);
diff --git a/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/IHdmiCec.aidl b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/IHdmiCec.aidl
index 577c377..578d924 100644
--- a/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/IHdmiCec.aidl
+++ b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/IHdmiCec.aidl
@@ -77,7 +77,7 @@
      * plugged off and on again. It is advised to call getPhysicalAddress to get
      * the updated address when hot plug event takes place.
      *
-     * @param out addr Physical address of this device.
+     * @return Physical address of this device.
      */
     int getPhysicalAddress();
 
@@ -116,7 +116,7 @@
      *        previously registered callback must be replaced with this one.
      *        setCallback(null) should deregister the callback.
      */
-    void setCallback(in IHdmiCecCallback callback);
+    void setCallback(in @nullable IHdmiCecCallback callback);
 
     /**
      * Passes the updated language information of Android system. Contains
diff --git a/tv/hdmi/connection/aidl/OWNERS b/tv/hdmi/connection/aidl/OWNERS
deleted file mode 100644
index d9c6783..0000000
--- a/tv/hdmi/connection/aidl/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 826094
-include platform/frameworks/base:/core/java/android/hardware/hdmi/OWNERS
\ No newline at end of file
diff --git a/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/IHdmiConnection.aidl b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/IHdmiConnection.aidl
index 98d1452..cf7c4bd 100644
--- a/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/IHdmiConnection.aidl
+++ b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/IHdmiConnection.aidl
@@ -37,6 +37,6 @@
   android.hardware.tv.hdmi.connection.HdmiPortInfo[] getPortInfo();
   boolean isConnected(in int portId);
   void setCallback(in android.hardware.tv.hdmi.connection.IHdmiConnectionCallback callback);
-  void setHpdSignal(android.hardware.tv.hdmi.connection.HpdSignal signal);
-  android.hardware.tv.hdmi.connection.HpdSignal getHpdSignal();
+  void setHpdSignal(android.hardware.tv.hdmi.connection.HpdSignal signal, in int portId);
+  android.hardware.tv.hdmi.connection.HpdSignal getHpdSignal(in int portId);
 }
diff --git a/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/HdmiPortInfo.aidl b/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/HdmiPortInfo.aidl
index 1d2ef4a..6bec7e5 100644
--- a/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/HdmiPortInfo.aidl
+++ b/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/HdmiPortInfo.aidl
@@ -24,10 +24,16 @@
 @VintfStability
 parcelable HdmiPortInfo {
     HdmiPortType type;
-    int portId; // Output ports should start from 1 which corresponds to HDMI "port 1".
+    int portId; // For devices with input ports (e.g. TV Panels), input ports should start from 1
+                // which corresponds to HDMI "port 1".
+
+    // In the following, 'supported' refers to having the necessary hardware and firmware on the
+    // device to support CEC/ARC/eARC on this port.
     boolean cecSupported;
-    boolean arcSupported;
+    boolean arcSupported; // If true, cecSupported has to be true as well. ARC cannot be supported
+                          // without CEC support.
     boolean eArcSupported;
+
     // The physical address of the device connected to this port, valid range is 0x0000 to 0xFFFF
     // (ref Sec 8.7.2 of HDMI 1.4b).
     int physicalAddress;
diff --git a/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/IHdmiConnection.aidl b/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/IHdmiConnection.aidl
index c8759f2..ee6cc89 100644
--- a/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/IHdmiConnection.aidl
+++ b/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/IHdmiConnection.aidl
@@ -55,16 +55,33 @@
      * signaling EDID updates). By default, the HAL will use {@code HDMI_HPD_PHYSICAL} (the physical
      * hotplug signal). When set to {@code HDMI_HPD_STATUS_BIT} the HAL should use the HDP status
      * bit.
+     *
+     * This is only relevant to TV Panel devices that support eARC TX. While eARC TX is connected,
+     * the framework calls this method to set the HPD signal to {@code HDMI_HPD_STATUS_BIT}.
+     *
+     * For all other device types, this method can be stubbed.
+     *
+     * @param signal The HPD signal type to use.
+     * @param portId id of the port on which the HPD signal should be set.
+     *
      * @throws ServiceSpecificException with error code set to
      *         {@code Result::FAILURE_NOT_SUPPORTED} if the signal type is not supported.
      *         {@code Result::FAILURE_INVALID_ARGS} if the signal type is invalid.
      *         {@code Result::FAILURE_UNKNOWN} if the signal type could not be set because of an
      *                                         unknown failure.
      */
-    void setHpdSignal(HpdSignal signal);
+    void setHpdSignal(HpdSignal signal, in int portId);
 
     /**
      * Get the current signal the HAL is using for HPD
+     *
+     * This is only relevant to TV Panel devices that support eARC TX. While eARC TX is connected,
+     * this method returns {@code HDMI_HPD_STATUS_BIT}.
+     *
+     * For all other device types, this method can be stubbed by always returning
+     * {@code HDMI_HPD_PHYSICAL}.
+     *
+     * @param portId id of the port of which the current HPD signal is queried.
      */
-    HpdSignal getHpdSignal();
+    HpdSignal getHpdSignal(in int portId);
 }
diff --git a/tv/hdmi/connection/aidl/default/HdmiConnectionMock.cpp b/tv/hdmi/connection/aidl/default/HdmiConnectionMock.cpp
index db9f4c1..be6247b 100644
--- a/tv/hdmi/connection/aidl/default/HdmiConnectionMock.cpp
+++ b/tv/hdmi/connection/aidl/default/HdmiConnectionMock.cpp
@@ -69,18 +69,23 @@
     return ScopedAStatus::ok();
 }
 
-ScopedAStatus HdmiConnectionMock::setHpdSignal(HpdSignal signal) {
-    if (mHdmiThreadRun) {
-        mHpdSignal = signal;
-        return ScopedAStatus::ok();
-    } else {
+ScopedAStatus HdmiConnectionMock::setHpdSignal(HpdSignal signal, int32_t portId) {
+    if (portId > mTotalPorts || portId < 1) {
+        return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    if (!mHdmiThreadRun) {
         return ScopedAStatus::fromServiceSpecificError(
                 static_cast<int32_t>(Result::FAILURE_INVALID_STATE));
     }
+    mHpdSignal.at(portId - 1) = signal;
+    return ScopedAStatus::ok();
 }
 
-ScopedAStatus HdmiConnectionMock::getHpdSignal(HpdSignal* _aidl_return) {
-    *_aidl_return = mHpdSignal;
+ScopedAStatus HdmiConnectionMock::getHpdSignal(int32_t portId, HpdSignal* _aidl_return) {
+    if (portId > mTotalPorts || portId < 1) {
+        return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    *_aidl_return = mHpdSignal.at(portId - 1);
     return ScopedAStatus::ok();
 }
 
@@ -123,7 +128,7 @@
     bool connected = ((msgBuf[3]) & 0xf) > 0;
     int32_t portId = static_cast<uint32_t>(msgBuf[0] & 0xf);
 
-    if (portId > static_cast<int32_t>(mPortInfos.size())) {
+    if (portId > static_cast<int32_t>(mPortInfos.size()) || portId < 1) {
         ALOGD("[halimp_aidl] ignore hot plug message, id %x does not exist", portId);
         return;
     }
@@ -179,6 +184,7 @@
     mCallback = nullptr;
     mPortInfos.resize(mTotalPorts);
     mPortConnectionStatus.resize(mTotalPorts);
+    mHpdSignal.resize(mTotalPorts);
     mPortInfos[0] = {.type = HdmiPortType::OUTPUT,
                      .portId = static_cast<uint32_t>(1),
                      .cecSupported = true,
@@ -186,6 +192,7 @@
                      .eArcSupported = false,
                      .physicalAddress = mPhysicalAddress};
     mPortConnectionStatus[0] = false;
+    mHpdSignal[0] = HpdSignal::HDMI_HPD_PHYSICAL;
     mDeathRecipient = ndk::ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient_new(serviceDied));
 }
 
diff --git a/tv/hdmi/connection/aidl/default/HdmiConnectionMock.h b/tv/hdmi/connection/aidl/default/HdmiConnectionMock.h
index b879e51..c013fdd 100644
--- a/tv/hdmi/connection/aidl/default/HdmiConnectionMock.h
+++ b/tv/hdmi/connection/aidl/default/HdmiConnectionMock.h
@@ -46,8 +46,8 @@
     ::ndk::ScopedAStatus isConnected(int32_t portId, bool* _aidl_return) override;
     ::ndk::ScopedAStatus setCallback(
             const std::shared_ptr<IHdmiConnectionCallback>& callback) override;
-    ::ndk::ScopedAStatus setHpdSignal(HpdSignal signal) override;
-    ::ndk::ScopedAStatus getHpdSignal(HpdSignal* _aidl_return) override;
+    ::ndk::ScopedAStatus setHpdSignal(HpdSignal signal, int32_t portId) override;
+    ::ndk::ScopedAStatus getHpdSignal(int32_t portId, HpdSignal* _aidl_return) override;
 
     void printEventBuf(const char* msg_buf, int len);
 
@@ -70,7 +70,7 @@
     int mTotalPorts = 1;
 
     // HPD Signal being used
-    HpdSignal mHpdSignal = HpdSignal::HDMI_HPD_PHYSICAL;
+    std::vector<HpdSignal> mHpdSignal;
 
     // Testing variables
     // Input file descriptor
diff --git a/tv/hdmi/connection/aidl/vts/functional/VtsHalTvHdmiConnectionAidlTargetTest.cpp b/tv/hdmi/connection/aidl/vts/functional/VtsHalTvHdmiConnectionAidlTargetTest.cpp
index 69f7ef5..a9b288b 100644
--- a/tv/hdmi/connection/aidl/vts/functional/VtsHalTvHdmiConnectionAidlTargetTest.cpp
+++ b/tv/hdmi/connection/aidl/vts/functional/VtsHalTvHdmiConnectionAidlTargetTest.cpp
@@ -93,8 +93,8 @@
     for (size_t i = 0; i < ports.size(); ++i) {
         EXPECT_TRUE((ports[i].type == HdmiPortType::OUTPUT) ||
                     (ports[i].type == HdmiPortType::INPUT));
-        if (ports[i].portId == 0) {
-            ALOGW("%s: Port id should start from 1", __func__);
+        if (ports[i].type == HdmiPortType::OUTPUT && ports[i].portId <= 0) {
+            ALOGW("%s: Port id for output ports should start from 1", __func__);
         }
         cecSupportedOnDevice = cecSupportedOnDevice | ports[i].cecSupported;
     }
@@ -111,16 +111,21 @@
 }
 
 TEST_P(HdmiConnectionTest, HdpSignal) {
+    std::vector<HdmiPortInfo> ports;
+    ASSERT_TRUE(hdmiConnection->getPortInfo(&ports).isOk());
     HpdSignal originalSignal;
     HpdSignal signal = HpdSignal::HDMI_HPD_STATUS_BIT;
-    HpdSignal readSignal;
-    ASSERT_TRUE(hdmiConnection->getHpdSignal(&originalSignal).isOk());
-    ASSERT_TRUE(hdmiConnection->setHpdSignal(signal).isOk());
-    ASSERT_TRUE(hdmiConnection->getHpdSignal(&readSignal).isOk());
-    EXPECT_EQ(readSignal, signal);
-    signal = HpdSignal::HDMI_HPD_PHYSICAL;
-    ASSERT_TRUE(hdmiConnection->setHpdSignal(signal).isOk());
-    ASSERT_TRUE(hdmiConnection->getHpdSignal(&readSignal).isOk());
-    EXPECT_EQ(readSignal, signal);
-    ASSERT_TRUE(hdmiConnection->setHpdSignal(originalSignal).isOk());
+    for (size_t i = 0; i < ports.size(); ++i) {
+        int32_t portId = ports[i].portId;
+        HpdSignal readSignal;
+        ASSERT_TRUE(hdmiConnection->getHpdSignal(portId, &originalSignal).isOk());
+        ASSERT_TRUE(hdmiConnection->setHpdSignal(signal, portId).isOk());
+        ASSERT_TRUE(hdmiConnection->getHpdSignal(portId, &readSignal).isOk());
+        EXPECT_EQ(readSignal, signal);
+        signal = HpdSignal::HDMI_HPD_PHYSICAL;
+        ASSERT_TRUE(hdmiConnection->setHpdSignal(signal, portId).isOk());
+        ASSERT_TRUE(hdmiConnection->getHpdSignal(portId, &readSignal).isOk());
+        EXPECT_EQ(readSignal, signal);
+        ASSERT_TRUE(hdmiConnection->setHpdSignal(originalSignal, portId).isOk());
+    }
 }
diff --git a/tv/hdmi/earc/aidl/OWNERS b/tv/hdmi/earc/aidl/OWNERS
deleted file mode 100644
index d9c6783..0000000
--- a/tv/hdmi/earc/aidl/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 826094
-include platform/frameworks/base:/core/java/android/hardware/hdmi/OWNERS
\ No newline at end of file
diff --git a/tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/current/android/hardware/tv/hdmi/earc/IEArcStatus.aidl b/tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/current/android/hardware/tv/hdmi/earc/IEArcStatus.aidl
index 29d4ea9..6dcbd8d 100644
--- a/tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/current/android/hardware/tv/hdmi/earc/IEArcStatus.aidl
+++ b/tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/current/android/hardware/tv/hdmi/earc/IEArcStatus.aidl
@@ -34,8 +34,8 @@
 package android.hardware.tv.hdmi.earc;
 @Backing(type="byte") @VintfStability
 enum IEArcStatus {
-  STATUS_IDLE = 0,
-  STATUS_EARC_PENDING = 1,
-  STATUS_ARC_PENDING = 2,
-  STATUS_EARC_CONNECTED = 3,
+  IDLE = 0,
+  EARC_PENDING = 1,
+  ARC_PENDING = 2,
+  EARC_CONNECTED = 3,
 }
diff --git a/tv/hdmi/earc/aidl/android/hardware/tv/hdmi/earc/IEArc.aidl b/tv/hdmi/earc/aidl/android/hardware/tv/hdmi/earc/IEArc.aidl
index a2dde6a..d9fb29c 100644
--- a/tv/hdmi/earc/aidl/android/hardware/tv/hdmi/earc/IEArc.aidl
+++ b/tv/hdmi/earc/aidl/android/hardware/tv/hdmi/earc/IEArc.aidl
@@ -20,7 +20,7 @@
 import android.hardware.tv.hdmi.earc.IEArcStatus;
 
 /**
- * eARC HAL interface definition
+ * eARC HAL interface definition. This is only relevant to TV Panels that implement eARC TX.
  */
 @VintfStability
 interface IEArc {
@@ -64,10 +64,11 @@
     IEArcStatus getState(in int portId);
 
     /**
-     * Getter for the most recent capabilities reported by the device connected to port.
+     * Getter for the most recent audio capabilities reported by the device connected to port.
      *
      * @param portId The port ID on which the device is connected.
-     * @return The raw, unparsed audio capabilities
+     * @return a byte array containing the raw, unparsed audio capabilities (Ref "Section 9.5.3.6 -
+     * eARC RX Capabilities Data Structure" in HDMI 2.1 specification).
      */
     byte[] getLastReportedAudioCapabilities(in int portId);
 }
diff --git a/tv/hdmi/earc/aidl/android/hardware/tv/hdmi/earc/IEArcCallback.aidl b/tv/hdmi/earc/aidl/android/hardware/tv/hdmi/earc/IEArcCallback.aidl
index a11924b..ea77c54 100644
--- a/tv/hdmi/earc/aidl/android/hardware/tv/hdmi/earc/IEArcCallback.aidl
+++ b/tv/hdmi/earc/aidl/android/hardware/tv/hdmi/earc/IEArcCallback.aidl
@@ -34,9 +34,9 @@
     /**
      * The callback function that must be called by the eARC driver and HAL implementation to
      * notify the Android framework of the audio capabilities reported by the connected device. On
-     * every state change to {@code STATUS_EARC_CONNECTED}, the driver shall read the capabilities
-     * reported by the eARC RX. The onStateChange callback shall always be invoked first and the
-     * onCapabilitiesReported callback shall be invoked second.
+     * every state change to {@code IEArcStatus::EARC_CONNECTED}, the driver shall read the
+     * capabilities reported by the eARC RX. The onStateChange callback shall always be invoked
+     * first and the onCapabilitiesReported callback shall be invoked second.
      * @param rawCapabilities The raw unparsed audio capabilities (Ref "Section 9.5.3.6 - eARC RX
      *         Capabilities Data Structure" in HDMI 2.1 specification).
      * @param portId The port ID for which the audio capabilities are being reported
diff --git a/tv/hdmi/earc/aidl/android/hardware/tv/hdmi/earc/IEArcStatus.aidl b/tv/hdmi/earc/aidl/android/hardware/tv/hdmi/earc/IEArcStatus.aidl
index de1aaf1..5407434 100644
--- a/tv/hdmi/earc/aidl/android/hardware/tv/hdmi/earc/IEArcStatus.aidl
+++ b/tv/hdmi/earc/aidl/android/hardware/tv/hdmi/earc/IEArcStatus.aidl
@@ -22,8 +22,8 @@
 @VintfStability
 @Backing(type="byte")
 enum IEArcStatus {
-    STATUS_IDLE = 0,
-    STATUS_EARC_PENDING = 1,
-    STATUS_ARC_PENDING = 2,
-    STATUS_EARC_CONNECTED = 3,
+    IDLE = 0,
+    EARC_PENDING = 1,
+    ARC_PENDING = 2,
+    EARC_CONNECTED = 3,
 }
diff --git a/tv/hdmi/earc/aidl/default/EArcMock.cpp b/tv/hdmi/earc/aidl/default/EArcMock.cpp
index 99a845e..93395fc 100644
--- a/tv/hdmi/earc/aidl/default/EArcMock.cpp
+++ b/tv/hdmi/earc/aidl/default/EArcMock.cpp
@@ -109,7 +109,7 @@
     mCallback = nullptr;
     mCapabilities.resize(mTotalPorts);
     mPortStatus.resize(mTotalPorts);
-    mPortStatus[0] = IEArcStatus::STATUS_IDLE;
+    mPortStatus[0] = IEArcStatus::IDLE;
     mDeathRecipient = ndk::ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient_new(serviceDied));
 }
 
diff --git a/tv/tuner/1.0/default/Dvr.cpp b/tv/tuner/1.0/default/Dvr.cpp
index 40879f2..9d6d86d 100644
--- a/tv/tuner/1.0/default/Dvr.cpp
+++ b/tv/tuner/1.0/default/Dvr.cpp
@@ -164,7 +164,7 @@
         return false;
     }
 
-    mDvrMQ = move(tmpDvrMQ);
+    mDvrMQ = std::move(tmpDvrMQ);
 
     if (EventFlag::createEventFlag(mDvrMQ->getEventFlagWord(), &mDvrEventFlag) != OK) {
         return false;
diff --git a/tv/tuner/1.0/vts/functional/DvrTests.cpp b/tv/tuner/1.0/vts/functional/DvrTests.cpp
index 83f9858..cab5867 100644
--- a/tv/tuner/1.0/vts/functional/DvrTests.cpp
+++ b/tv/tuner/1.0/vts/functional/DvrTests.cpp
@@ -203,7 +203,6 @@
 void DvrCallback::stopRecordThread() {
     mKeepReadingRecordFMQ = false;
     mRecordThreadRunning = false;
-    android::Mutex::Autolock autoLock(mRecordThreadLock);
 }
 
 AssertionResult DvrTests::openDvrInDemux(DvrType type, uint32_t bufferSize) {
diff --git a/tv/tuner/1.1/default/Dvr.cpp b/tv/tuner/1.1/default/Dvr.cpp
index fdb66c1..8262b4d 100644
--- a/tv/tuner/1.1/default/Dvr.cpp
+++ b/tv/tuner/1.1/default/Dvr.cpp
@@ -183,7 +183,7 @@
         return false;
     }
 
-    mDvrMQ = move(tmpDvrMQ);
+    mDvrMQ = std::move(tmpDvrMQ);
 
     if (EventFlag::createEventFlag(mDvrMQ->getEventFlagWord(), &mDvrEventFlag) != OK) {
         return false;
diff --git a/tv/tuner/aidl/default/Dvr.cpp b/tv/tuner/aidl/default/Dvr.cpp
index c591d07..c157bdd 100644
--- a/tv/tuner/aidl/default/Dvr.cpp
+++ b/tv/tuner/aidl/default/Dvr.cpp
@@ -164,7 +164,7 @@
         return false;
     }
 
-    mDvrMQ = move(tmpDvrMQ);
+    mDvrMQ = std::move(tmpDvrMQ);
 
     if (EventFlag::createEventFlag(mDvrMQ->getEventFlagWord(), &mDvrEventFlag) != ::android::OK) {
         return false;
diff --git a/tv/tuner/config/TunerTestingConfigReaderV1_0.h b/tv/tuner/config/TunerTestingConfigReaderV1_0.h
index d049b07..fb76de7 100644
--- a/tv/tuner/config/TunerTestingConfigReaderV1_0.h
+++ b/tv/tuner/config/TunerTestingConfigReaderV1_0.h
@@ -65,6 +65,7 @@
 using android::hardware::tv::tuner::V1_0::LnbVoltage;
 using android::hardware::tv::tuner::V1_0::PlaybackSettings;
 using android::hardware::tv::tuner::V1_0::RecordSettings;
+using android::hardware::tv::tuner::V1_0::FrontendAtscSettings;
 
 const string emptyHardwareId = "";
 
@@ -241,6 +242,7 @@
                         break;
                     case FrontendTypeEnum::ATSC:
                         type = FrontendType::ATSC;
+                        frontendMap[id].settings.atsc(readAtscFrontendSettings(feConfig));
                         break;
                     case FrontendTypeEnum::ATSC3:
                         type = FrontendType::ATSC3;
@@ -627,6 +629,13 @@
         return dvbsSettings;
     }
 
+    static FrontendAtscSettings readAtscFrontendSettings(Frontend feConfig) {
+        FrontendAtscSettings atscSettings{
+            .frequency = (uint32_t)feConfig.getFrequency(),
+        };
+        return atscSettings;
+    }
+
     static bool readFilterTypeAndSettings(Filter filterConfig, DemuxFilterType& type,
                                           DemuxFilterSettings& settings) {
         auto mainType = filterConfig.getMainType();
diff --git a/usb/gadget/1.1/default/lib/MonitorFfs.cpp b/usb/gadget/1.1/default/lib/MonitorFfs.cpp
index 0cdf038..6d09a8a 100644
--- a/usb/gadget/1.1/default/lib/MonitorFfs.cpp
+++ b/usb/gadget/1.1/default/lib/MonitorFfs.cpp
@@ -59,9 +59,9 @@
 
     if (addEpollFd(epollFd, eventFd) == -1) abort();
 
-    mEpollFd = move(epollFd);
-    mInotifyFd = move(inotifyFd);
-    mEventFd = move(eventFd);
+    mEpollFd = std::move(epollFd);
+    mInotifyFd = std::move(inotifyFd);
+    mEventFd = std::move(eventFd);
     gadgetPullup = false;
 }
 
diff --git a/usb/gadget/1.2/default/lib/MonitorFfs.cpp b/usb/gadget/1.2/default/lib/MonitorFfs.cpp
index 0cdf038..6d09a8a 100644
--- a/usb/gadget/1.2/default/lib/MonitorFfs.cpp
+++ b/usb/gadget/1.2/default/lib/MonitorFfs.cpp
@@ -59,9 +59,9 @@
 
     if (addEpollFd(epollFd, eventFd) == -1) abort();
 
-    mEpollFd = move(epollFd);
-    mInotifyFd = move(inotifyFd);
-    mEventFd = move(eventFd);
+    mEpollFd = std::move(epollFd);
+    mInotifyFd = std::move(inotifyFd);
+    mEventFd = std::move(eventFd);
     gadgetPullup = false;
 }
 
diff --git a/usb/gadget/aidl/default/UsbGadget.cpp b/usb/gadget/aidl/default/UsbGadget.cpp
index 72cf681..51f7f5b 100644
--- a/usb/gadget/aidl/default/UsbGadget.cpp
+++ b/usb/gadget/aidl/default/UsbGadget.cpp
@@ -91,6 +91,9 @@
 
 ScopedAStatus UsbGadget::getCurrentUsbFunctions(const shared_ptr<IUsbGadgetCallback>& callback,
                                                 int64_t in_transactionId) {
+    if (callback == nullptr) {
+        return ScopedAStatus::fromExceptionCode(EX_NULL_POINTER);
+    }
     ScopedAStatus ret = callback->getCurrentUsbFunctionsCb(
             mCurrentUsbFunctions,
             mCurrentUsbFunctionsApplied ? Status::FUNCTIONS_APPLIED : Status::FUNCTIONS_NOT_APPLIED,
diff --git a/uwb/aidl/Android.bp b/uwb/aidl/Android.bp
index 7dc2b7f..3e71913 100755
--- a/uwb/aidl/Android.bp
+++ b/uwb/aidl/Android.bp
@@ -18,7 +18,11 @@
     backend: {
         java: {
             sdk_version: "module_Tiramisu",
-            enabled: false,
+            enabled: true,
+            apex_available: [
+                "//apex_available:platform",
+                "com.android.uwb",
+            ],
         },
         ndk: {
             apex_available: [
@@ -72,6 +76,11 @@
             version: "1",
             imports: [],
         },
+        {
+            version: "2",
+            imports: [],
+        },
+
     ],
 
 }
diff --git a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/.hash b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/.hash
new file mode 100644
index 0000000..42772bb
--- /dev/null
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/.hash
@@ -0,0 +1 @@
+590d9f45625a2c353011cf85f18d1d08593b8a0a
diff --git a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/IDiceDevice.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl
similarity index 62%
copy from security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/IDiceDevice.aidl
copy to uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl
index 383f4d1..0cc01c5 100644
--- a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/IDiceDevice.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl
@@ -2,10 +2,10 @@
  * Copyright (C) 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
+ * You may 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
+ *        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,
@@ -31,12 +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.security.dice;
-/* @hide */
-@SensitiveData @VintfStability
-interface IDiceDevice {
-  android.hardware.security.dice.Signature sign(in android.hardware.security.dice.InputValues[] id, in byte[] payload);
-  android.hardware.security.dice.Bcc getAttestationChain(in android.hardware.security.dice.InputValues[] inputValues);
-  android.hardware.security.dice.BccHandover derive(in android.hardware.security.dice.InputValues[] inputValues);
-  void demote(in android.hardware.security.dice.InputValues[] inputValues);
+package android.hardware.uwb.fira_android;
+@Backing(type="int") @VintfStability
+enum UwbVendorCapabilityTlvTypes {
+  SUPPORTED_POWER_STATS_QUERY = 192,
+  CCC_SUPPORTED_CHAPS_PER_SLOT = 160,
+  CCC_SUPPORTED_SYNC_CODES = 161,
+  CCC_SUPPORTED_HOPPING_CONFIG_MODES_AND_SEQUENCES = 162,
+  CCC_SUPPORTED_CHANNELS = 163,
+  CCC_SUPPORTED_VERSIONS = 164,
+  CCC_SUPPORTED_UWB_CONFIGS = 165,
+  CCC_SUPPORTED_PULSE_SHAPE_COMBOS = 166,
+  CCC_SUPPORTED_RAN_MULTIPLIER = 167,
+  CCC_SUPPORTED_MAX_RANGING_SESSION_NUMBER = 168,
+  SUPPORTED_AOA_RESULT_REQ_ANTENNA_INTERLEAVING = 227,
+  SUPPORTED_MIN_RANGING_INTERVAL_MS = 228,
+  SUPPORTED_RANGE_DATA_NTF_CONFIG = 229,
+  SUPPORTED_RSSI_REPORTING = 230,
+  SUPPORTED_DIAGNOSTICS = 231,
+  SUPPORTED_MIN_SLOT_DURATION_RSTU = 232,
+  SUPPORTED_MAX_RANGING_SESSION_NUMBER = 233,
+  SUPPORTED_CHANNELS_AOA = 234,
 }
diff --git a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/IDiceDevice.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvValues.aidl
similarity index 66%
rename from security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/IDiceDevice.aidl
rename to uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvValues.aidl
index 383f4d1..0e33f70 100644
--- a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/IDiceDevice.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvValues.aidl
@@ -2,10 +2,10 @@
  * Copyright (C) 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
+ * You may 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
+ *        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,
@@ -31,12 +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.security.dice;
-/* @hide */
-@SensitiveData @VintfStability
-interface IDiceDevice {
-  android.hardware.security.dice.Signature sign(in android.hardware.security.dice.InputValues[] id, in byte[] payload);
-  android.hardware.security.dice.Bcc getAttestationChain(in android.hardware.security.dice.InputValues[] inputValues);
-  android.hardware.security.dice.BccHandover derive(in android.hardware.security.dice.InputValues[] inputValues);
-  void demote(in android.hardware.security.dice.InputValues[] inputValues);
+package android.hardware.uwb.fira_android;
+@Backing(type="long") @VintfStability
+enum UwbVendorCapabilityTlvValues {
+  UWB_CONFIG_0 = 0,
+  UWB_CONFIG_1 = 1,
+  PULSE_SHAPE_SYMMETRICAL_ROOT_RAISED_COSINE = 0,
+  PULSE_SHAPE_PRECURSOR_FREE = 1,
+  PULSE_SHAPE_PRECURSOR_FREE_SPECIAL = 2,
+  CHAPS_PER_SLOT_3 = 1,
+  CHAPS_PER_SLOT_4 = 2,
+  CHAPS_PER_SLOT_6 = 4,
+  CHAPS_PER_SLOT_8 = 8,
+  CHAPS_PER_SLOT_9 = 16,
+  CHAPS_PER_SLOT_12 = 32,
+  CHAPS_PER_SLOT_24 = 64,
+  HOPPING_SEQUENCE_DEFAULT = 16,
+  HOPPING_SEQUENCE_AES = 8,
+  HOPPING_CONFIG_MODE_NONE = 128,
+  HOPPING_CONFIG_MODE_CONTINUOUS = 64,
+  HOPPING_CONFIG_MODE_ADAPTIVE = 32,
+  CCC_CHANNEL_5 = 1,
+  CCC_CHANNEL_9 = 2,
 }
diff --git a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/Signature.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorGidAndroidOids.aidl
similarity index 79%
copy from security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/Signature.aidl
copy to uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorGidAndroidOids.aidl
index 294170d..fbcfbff 100644
--- a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/Signature.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorGidAndroidOids.aidl
@@ -1,11 +1,11 @@
 /*
- * Copyright 2021, 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.
+ * 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
+ *        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,
@@ -31,9 +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.security.dice;
-/* @hide */
-@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability
-parcelable Signature {
-  byte[] data;
+package android.hardware.uwb.fira_android;
+@Backing(type="byte") @VintfStability
+enum UwbVendorGidAndroidOids {
+  ANDROID_GET_POWER_STATS = 0,
+  ANDROID_SET_COUNTRY_CODE = 1,
+  ANDROID_RANGE_DIAGNOSTICS = 2,
 }
diff --git a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/Mode.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorGids.aidl
similarity index 81%
copy from security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/Mode.aidl
copy to uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorGids.aidl
index 295c32e..5515c67 100644
--- a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/Mode.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorGids.aidl
@@ -1,11 +1,11 @@
 /*
- * Copyright 2021, 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.
+ * 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
+ *        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,
@@ -31,12 +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.security.dice;
-/* @hide */
-@Backing(type="int") @VintfStability
-enum Mode {
-  NOT_INITIALIZED = 0,
-  NORMAL = 1,
-  DEBUG = 2,
-  RECOVERY = 3,
+package android.hardware.uwb.fira_android;
+@Backing(type="byte") @VintfStability
+enum UwbVendorGids {
+  ANDROID = 12,
 }
diff --git a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/Mode.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorReasonCodes.aidl
similarity index 83%
copy from security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/Mode.aidl
copy to uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorReasonCodes.aidl
index 295c32e..dc2252b 100644
--- a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/Mode.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorReasonCodes.aidl
@@ -1,11 +1,11 @@
 /*
- * Copyright 2021, The Android Open Source Project
+ * Copyright (C) 2022 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
+ * 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
+ *        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,
@@ -31,12 +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.security.dice;
-/* @hide */
+package android.hardware.uwb.fira_android;
 @Backing(type="int") @VintfStability
-enum Mode {
-  NOT_INITIALIZED = 0,
-  NORMAL = 1,
-  DEBUG = 2,
-  RECOVERY = 3,
+enum UwbVendorReasonCodes {
+  REASON_ERROR_INVALID_CHANNEL_WITH_AOA = 128,
 }
diff --git a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/ResponseCode.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvTypes.aidl
similarity index 72%
copy from security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/ResponseCode.aidl
copy to uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvTypes.aidl
index c13afa6..8413f06 100644
--- a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/ResponseCode.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvTypes.aidl
@@ -1,11 +1,11 @@
 /*
- * Copyright 2020, 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.
+ * 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
+ *        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,
@@ -31,11 +31,18 @@
 // 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.security.dice;
+package android.hardware.uwb.fira_android;
 @Backing(type="int") @VintfStability
-enum ResponseCode {
-  PERMISSION_DENIED = 1,
-  SYSTEM_ERROR = 2,
-  NOT_IMPLEMENTED = 3,
-  DEMOTION_FAILED = 4,
+enum UwbVendorSessionAppConfigTlvTypes {
+  CCC_HOP_MODE_KEY = 160,
+  CCC_UWB_TIME0 = 161,
+  CCC_RANGING_PROTOCOL_VER = 163,
+  CCC_UWB_CONFIG_ID = 164,
+  CCC_PULSESHAPE_COMBO = 165,
+  CCC_URSK_TTL = 166,
+  NB_OF_RANGE_MEASUREMENTS = 227,
+  NB_OF_AZIMUTH_MEASUREMENTS = 228,
+  NB_OF_ELEVATION_MEASUREMENTS = 229,
+  ENABLE_DIAGNOSTICS = 232,
+  DIAGRAMS_FRAME_REPORTS_FIELDS = 233,
 }
diff --git a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/Mode.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvValues.aidl
similarity index 83%
copy from security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/Mode.aidl
copy to uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvValues.aidl
index 295c32e..a7f487b 100644
--- a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/Mode.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvValues.aidl
@@ -1,11 +1,11 @@
 /*
- * Copyright 2021, 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.
+ * 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
+ *        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,
@@ -31,12 +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.security.dice;
-/* @hide */
+package android.hardware.uwb.fira_android;
 @Backing(type="int") @VintfStability
-enum Mode {
-  NOT_INITIALIZED = 0,
-  NORMAL = 1,
-  DEBUG = 2,
-  RECOVERY = 3,
+enum UwbVendorSessionAppConfigTlvValues {
+  AOA_RESULT_REQ_ANTENNA_INTERLEAVING = 240,
 }
diff --git a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/Mode.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorSessionInitSessionType.aidl
similarity index 83%
copy from security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/Mode.aidl
copy to uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorSessionInitSessionType.aidl
index 295c32e..30a0a1b 100644
--- a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/Mode.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorSessionInitSessionType.aidl
@@ -1,11 +1,11 @@
 /*
- * Copyright 2021, 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.
+ * 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
+ *        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,
@@ -31,12 +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.security.dice;
-/* @hide */
+package android.hardware.uwb.fira_android;
 @Backing(type="int") @VintfStability
-enum Mode {
-  NOT_INITIALIZED = 0,
-  NORMAL = 1,
-  DEBUG = 2,
-  RECOVERY = 3,
+enum UwbVendorSessionInitSessionType {
+  CCC = 160,
 }
diff --git a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/Signature.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorStatusCodes.aidl
similarity index 80%
copy from security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/Signature.aidl
copy to uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorStatusCodes.aidl
index 294170d..2f534df 100644
--- a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/Signature.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorStatusCodes.aidl
@@ -1,11 +1,11 @@
 /*
- * Copyright 2021, The Android Open Source Project
+ * Copyright (C) 2022 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
+ * 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
+ *        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,
@@ -31,9 +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.security.dice;
-/* @hide */
-@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability
-parcelable Signature {
-  byte[] data;
+package android.hardware.uwb.fira_android;
+@Backing(type="byte") @VintfStability
+enum UwbVendorStatusCodes {
+  STATUS_ERROR_CCC_SE_BUSY = 80,
+  STATUS_ERROR_CCC_LIFECYCLE = 81,
 }
diff --git a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl
index b9ac7b9..0cc01c5 100644
--- a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl
@@ -49,6 +49,7 @@
   SUPPORTED_RANGE_DATA_NTF_CONFIG = 229,
   SUPPORTED_RSSI_REPORTING = 230,
   SUPPORTED_DIAGNOSTICS = 231,
-  SUPPORTED_MIN_SLOT_DURATION = 232,
+  SUPPORTED_MIN_SLOT_DURATION_RSTU = 232,
   SUPPORTED_MAX_RANGING_SESSION_NUMBER = 233,
+  SUPPORTED_CHANNELS_AOA = 234,
 }
diff --git a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/ResponseCode.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorReasonCodes.aidl
similarity index 79%
rename from security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/ResponseCode.aidl
rename to uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorReasonCodes.aidl
index c13afa6..a438cbe 100644
--- a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/ResponseCode.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorReasonCodes.aidl
@@ -1,11 +1,11 @@
 /*
- * Copyright 2020, The Android Open Source Project
+ * Copyright (C) 2022 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
+ * 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
+ *        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,
@@ -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.security.dice;
+package android.hardware.uwb.fira_android;
 @Backing(type="int") @VintfStability
-enum ResponseCode {
-  PERMISSION_DENIED = 1,
-  SYSTEM_ERROR = 2,
-  NOT_IMPLEMENTED = 3,
-  DEMOTION_FAILED = 4,
+enum UwbVendorReasonCodes {
+  REASON_ERROR_INVALID_CHANNEL_WITH_AOA = 128,
+  REASON_ERROR_STOPPED_DUE_TO_OTHER_SESSION_CONFLICT = 129,
+  REASON_REGULATION_UWB_OFF = 130,
 }
diff --git a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvTypes.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvTypes.aidl
index 8413f06..c3ac401 100644
--- a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvTypes.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvTypes.aidl
@@ -40,6 +40,7 @@
   CCC_UWB_CONFIG_ID = 164,
   CCC_PULSESHAPE_COMBO = 165,
   CCC_URSK_TTL = 166,
+  CCC_LAST_INDEX_USED = 168,
   NB_OF_RANGE_MEASUREMENTS = 227,
   NB_OF_AZIMUTH_MEASUREMENTS = 228,
   NB_OF_ELEVATION_MEASUREMENTS = 229,
diff --git a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorStatusCodes.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorStatusCodes.aidl
index 2f534df..28cf7fe 100644
--- a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorStatusCodes.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorStatusCodes.aidl
@@ -36,4 +36,6 @@
 enum UwbVendorStatusCodes {
   STATUS_ERROR_CCC_SE_BUSY = 80,
   STATUS_ERROR_CCC_LIFECYCLE = 81,
+  STATUS_ERROR_STOPPED_DUE_TO_OTHER_SESSION_CONFLICT = 82,
+  STATUS_REGULATION_UWB_OFF = 83,
 }
diff --git a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl
index a3bb7a6..891b6f0 100644
--- a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl
+++ b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl
@@ -186,12 +186,26 @@
     SUPPORTED_DIAGNOSTICS = 0xE7,
 
     /**
-     * 4 byte value to indicate supported min slot duration in ms.
+     * 4 byte value to indicate supported min slot duration in rstu.
      */
-    SUPPORTED_MIN_SLOT_DURATION = 0xE8,
+    SUPPORTED_MIN_SLOT_DURATION_RSTU = 0xE8,
 
     /**
      * Int value to indicate supported max number of fira ranging sessions
      */
     SUPPORTED_MAX_RANGING_SESSION_NUMBER = 0xE9,
+
+    /**
+     * 2 byte bitmask to indicate the channels that support AoA.
+     * Each "1" in this bitmap corresponds to a specific UWB channel where:
+     *  0x01 = "Channel 5",
+     *  0x02 = "Channel 6",
+     *  0x04 = "Channel 8",
+     *  0x08 = "Channel 9",
+     *  0x10 = "Channel 10",
+     *  0x20 = "Channel 12",
+     *  0x40 = "Channel 13",
+     *  0x80 = "Channel 14"
+     */
+    SUPPORTED_CHANNELS_AOA = 0xEA,
 }
diff --git a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorReasonCodes.aidl b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorReasonCodes.aidl
new file mode 100644
index 0000000..4cf2496
--- /dev/null
+++ b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorReasonCodes.aidl
@@ -0,0 +1,38 @@
+/*
+ * 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.uwb.fira_android;
+
+/**
+ * Android specific vendor reason codes should be defined here.
+ *
+ */
+@VintfStability
+@Backing(type="int")
+enum UwbVendorReasonCodes {
+    /**
+     * Use values from the vendor specific reason code range: 0x80 – 0xFF defined in Table 16 of
+     * UCI specification.
+     */
+
+    /** Fira specific */
+    /** The channel requested is not available for AoA */
+    REASON_ERROR_INVALID_CHANNEL_WITH_AOA = 0x80,
+    /** UWB stopped caused by other session conflict */
+    REASON_ERROR_STOPPED_DUE_TO_OTHER_SESSION_CONFLICT = 0x81,
+    /** UWB has been disabled (eg: country code change leads to UWB unsupported) */
+    REASON_REGULATION_UWB_OFF = 0x82,
+}
diff --git a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvTypes.aidl b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvTypes.aidl
index f303ed9..65bb1c9 100644
--- a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvTypes.aidl
+++ b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvTypes.aidl
@@ -46,6 +46,8 @@
     CCC_PULSESHAPE_COMBO = 0xA5,
     /** 2 byte data */
     CCC_URSK_TTL = 0xA6,
+    /** 4 byte data */
+    CCC_LAST_INDEX_USED = 0xA8,
 
     /**
      * Range 0xE3 - 0xFF is reserved for proprietary use in the FIRA spec.
diff --git a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorStatusCodes.aidl b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorStatusCodes.aidl
index 8505b8a..f952334 100644
--- a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorStatusCodes.aidl
+++ b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorStatusCodes.aidl
@@ -33,4 +33,8 @@
     STATUS_ERROR_CCC_SE_BUSY = 0x50,
     /** CCC Lifecycle error */
     STATUS_ERROR_CCC_LIFECYCLE = 0x51,
+    /** Other session conflict */
+    STATUS_ERROR_STOPPED_DUE_TO_OTHER_SESSION_CONFLICT = 0x52,
+    /** UWB Regulation Off */
+    STATUS_REGULATION_UWB_OFF = 0x53,
 }
diff --git a/vibrator/OWNERS b/vibrator/OWNERS
index 05e2e73..62a567e 100644
--- a/vibrator/OWNERS
+++ b/vibrator/OWNERS
@@ -2,7 +2,6 @@
 
 include platform/frameworks/base:/services/core/java/com/android/server/vibrator/OWNERS
 
-chasewu@google.com
 chrispaulo@google.com
 michaelwr@google.com
 nathankulczak@google.com
diff --git a/vibrator/aidl/default/example_java_client/Android.bp b/vibrator/aidl/default/example_java_client/Android.bp
new file mode 100644
index 0000000..17a649c
--- /dev/null
+++ b/vibrator/aidl/default/example_java_client/Android.bp
@@ -0,0 +1,54 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_library {
+    name: "libexample_vib_getter",
+    srcs: ["getter.cpp"],
+    product_available: true,
+    vendor_available: true,
+    shared_libs: [
+        "liblog",
+        "libbinder_ndk",
+    ],
+    header_libs: ["jni_headers"],
+    stl: "c++_shared",
+    visibility: [":__subpackages__"],
+}
+
+android_app {
+    name: "ExampleVibratorJavaVendorClient",
+    vendor: true,
+    static_libs: ["android.hardware.vibrator-V1-java"],
+    jni_libs: ["libexample_vib_getter"],
+    use_embedded_native_libs: true,
+    jarjar_rules: "jarjar.txt",
+    stl: "c++_shared",
+    srcs: ["example/vib/MyActivity.java"],
+    sdk_version: "system_current",
+    visibility: [":__subpackages__"],
+}
+
+android_app {
+    name: "ExampleVibratorJavaProductClient",
+    product_specific: true,
+    static_libs: ["android.hardware.vibrator-V1-java"],
+    jni_libs: ["libexample_vib_getter"],
+    use_embedded_native_libs: true,
+    jarjar_rules: "jarjar.txt",
+    stl: "c++_shared",
+    srcs: ["example/vib/MyActivity.java"],
+    sdk_version: "system_current",
+    visibility: [":__subpackages__"],
+    // If PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE is not true, product apps
+    // may use unstable APIs. jni_uses_platform_apis must set to use the
+    // non-SDK jni libs in this case.
+    // This is not required if PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE is
+    // set to true.
+    jni_uses_platform_apis: true,
+}
diff --git a/vibrator/aidl/default/example_vendor_java_client/AndroidManifest.xml b/vibrator/aidl/default/example_java_client/AndroidManifest.xml
similarity index 100%
rename from vibrator/aidl/default/example_vendor_java_client/AndroidManifest.xml
rename to vibrator/aidl/default/example_java_client/AndroidManifest.xml
diff --git a/vibrator/aidl/default/example_vendor_java_client/example/vib/MyActivity.java b/vibrator/aidl/default/example_java_client/example/vib/MyActivity.java
similarity index 100%
rename from vibrator/aidl/default/example_vendor_java_client/example/vib/MyActivity.java
rename to vibrator/aidl/default/example_java_client/example/vib/MyActivity.java
diff --git a/vibrator/aidl/default/example_vendor_java_client/getter.cpp b/vibrator/aidl/default/example_java_client/getter.cpp
similarity index 100%
rename from vibrator/aidl/default/example_vendor_java_client/getter.cpp
rename to vibrator/aidl/default/example_java_client/getter.cpp
diff --git a/vibrator/aidl/default/example_vendor_java_client/jarjar.txt b/vibrator/aidl/default/example_java_client/jarjar.txt
similarity index 100%
rename from vibrator/aidl/default/example_vendor_java_client/jarjar.txt
rename to vibrator/aidl/default/example_java_client/jarjar.txt
diff --git a/vibrator/aidl/default/example_vendor_java_client/Android.bp b/vibrator/aidl/default/example_vendor_java_client/Android.bp
deleted file mode 100644
index f615cb1..0000000
--- a/vibrator/aidl/default/example_vendor_java_client/Android.bp
+++ /dev/null
@@ -1,34 +0,0 @@
-package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "hardware_interfaces_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["hardware_interfaces_license"],
-}
-
-cc_library {
-    name: "libexample_vib_getter",
-    srcs: ["getter.cpp"],
-    vendor: true,
-    shared_libs: [
-        "liblog",
-        "libbinder_ndk",
-    ],
-    header_libs: ["jni_headers"],
-    stl: "c++_shared",
-    visibility: [":__subpackages__"],
-}
-
-android_app {
-    name: "ExampleVibratorJavaVendorClient",
-    privileged: true,
-    vendor: true,
-    static_libs: ["android.hardware.vibrator-V1-java"],
-    jni_libs: ["libexample_vib_getter"],
-    jarjar_rules: "jarjar.txt",
-    stl: "c++_shared",
-    srcs: ["example/vib/MyActivity.java"],
-    sdk_version: "system_current",
-    visibility: [":__subpackages__"],
-}
diff --git a/wifi/1.6/vts/functional/wifi_nan_iface_hidl_test.cpp b/wifi/1.6/vts/functional/wifi_nan_iface_hidl_test.cpp
index 7bcc6d3..37c55e7 100644
--- a/wifi/1.6/vts/functional/wifi_nan_iface_hidl_test.cpp
+++ b/wifi/1.6/vts/functional/wifi_nan_iface_hidl_test.cpp
@@ -68,17 +68,10 @@
 
     virtual void TearDown() override { stopWifi(GetInstanceName()); }
 
-    /* Used as a mechanism to inform the test about data/event callback */
-    inline void notify() {
-        std::unique_lock<std::mutex> lock(mtx_);
-        count_++;
-        cv_.notify_one();
-    }
 
     enum CallbackType {
-        INVALID = -2,
         ANY_CALLBACK = -1,
-
+        INVALID = 0,
         NOTIFY_CAPABILITIES_RESPONSE = 0,
         NOTIFY_ENABLE_RESPONSE,
         NOTIFY_CONFIG_RESPONSE,
@@ -114,8 +107,14 @@
         EVENT_DATA_PATH_CONFIRM_1_6,
     };
 
+    /* Used as a mechanism to inform the test about data/event callback */
+    inline void notify(CallbackType callbackType) {
+        std::unique_lock<std::mutex> lock(mtx_);
+        callbackEventBitMap |= (0x1 << callbackType);
+        cv_.notify_one();
+    }
     /* Test code calls this function to wait for data/event callback */
-    /* Must set callbackType = INVALID before call this function */
+    /* Must set callbackEventBitMap = INVALID before call this function */
     inline std::cv_status wait(CallbackType waitForCallbackType) {
         std::unique_lock<std::mutex> lock(mtx_);
 
@@ -124,15 +123,11 @@
 
         std::cv_status status = std::cv_status::no_timeout;
         auto now = std::chrono::system_clock::now();
-        while (count_ == 0) {
+        while (!(callbackEventBitMap & (0x1 << waitForCallbackType))) {
             status = cv_.wait_until(lock, now + std::chrono::seconds(TIMEOUT_PERIOD));
-            if (status == std::cv_status::timeout) return status;
-            if (waitForCallbackType != ANY_CALLBACK && callbackType != INVALID &&
-                callbackType != waitForCallbackType) {
-                count_--;
-            }
+            if (status == std::cv_status::timeout)
+                return status;
         }
-        count_--;
         return status;
     }
 
@@ -148,340 +143,276 @@
         Return<void> notifyCapabilitiesResponse(
                 uint16_t id, const WifiNanStatus& status,
                 const ::android::hardware::wifi::V1_0::NanCapabilities& capabilities) override {
-            parent_.callbackType = NOTIFY_CAPABILITIES_RESPONSE;
-
             parent_.id = id;
             parent_.status = status;
             parent_.capabilities = capabilities;
 
-            parent_.notify();
+            parent_.notify(NOTIFY_CAPABILITIES_RESPONSE);
             return Void();
         }
 
         Return<void> notifyCapabilitiesResponse_1_5(
                 uint16_t id, const WifiNanStatus& status,
                 const ::android::hardware::wifi::V1_5::NanCapabilities& capabilities) override {
-            parent_.callbackType = NOTIFY_CAPABILITIES_RESPONSE_1_5;
-
             parent_.id = id;
             parent_.status = status;
             parent_.capabilities_1_5 = capabilities;
 
-            parent_.notify();
+            parent_.notify(NOTIFY_CAPABILITIES_RESPONSE_1_5);
             return Void();
         }
 
         Return<void> notifyEnableResponse(uint16_t id, const WifiNanStatus& status) override {
-            parent_.callbackType = NOTIFY_ENABLE_RESPONSE;
-
             parent_.id = id;
             parent_.status = status;
 
-            parent_.notify();
+            parent_.notify(NOTIFY_ENABLE_RESPONSE);
             return Void();
         }
 
         Return<void> notifyConfigResponse(uint16_t id, const WifiNanStatus& status) override {
-            parent_.callbackType = NOTIFY_CONFIG_RESPONSE;
-
             parent_.id = id;
             parent_.status = status;
 
-            parent_.notify();
+            parent_.notify(NOTIFY_CONFIG_RESPONSE);
             return Void();
         }
 
         Return<void> notifyDisableResponse(uint16_t id, const WifiNanStatus& status) override {
-            parent_.callbackType = NOTIFY_DISABLE_RESPONSE;
-
             parent_.id = id;
             parent_.status = status;
 
-            parent_.notify();
+            parent_.notify(NOTIFY_DISABLE_RESPONSE);
             return Void();
         }
 
         Return<void> notifyStartPublishResponse(uint16_t id, const WifiNanStatus& status,
                                                 uint8_t sessionId) override {
-            parent_.callbackType = NOTIFY_START_PUBLISH_RESPONSE;
-
             parent_.id = id;
             parent_.status = status;
             parent_.sessionId = sessionId;
 
-            parent_.notify();
+            parent_.notify(NOTIFY_START_PUBLISH_RESPONSE);
             return Void();
         }
 
         Return<void> notifyStopPublishResponse(uint16_t id, const WifiNanStatus& status) override {
-            parent_.callbackType = NOTIFY_STOP_PUBLISH_RESPONSE;
-
             parent_.id = id;
             parent_.status = status;
 
-            parent_.notify();
+            parent_.notify(NOTIFY_STOP_PUBLISH_RESPONSE);
             return Void();
         }
 
         Return<void> notifyStartSubscribeResponse(uint16_t id, const WifiNanStatus& status,
                                                   uint8_t sessionId) override {
-            parent_.callbackType = NOTIFY_START_SUBSCRIBE_RESPONSE;
-
             parent_.id = id;
             parent_.status = status;
             parent_.sessionId = sessionId;
 
-            parent_.notify();
+            parent_.notify(NOTIFY_START_SUBSCRIBE_RESPONSE);
             return Void();
         }
 
         Return<void> notifyStopSubscribeResponse(uint16_t id,
                                                  const WifiNanStatus& status) override {
-            parent_.callbackType = NOTIFY_STOP_SUBSCRIBE_RESPONSE;
-
             parent_.id = id;
             parent_.status = status;
 
-            parent_.notify();
+            parent_.notify(NOTIFY_STOP_SUBSCRIBE_RESPONSE);
             return Void();
         }
 
         Return<void> notifyTransmitFollowupResponse(uint16_t id,
                                                     const WifiNanStatus& status) override {
-            parent_.callbackType = NOTIFY_TRANSMIT_FOLLOWUP_RESPONSE;
-
             parent_.id = id;
             parent_.status = status;
 
-            parent_.notify();
+            parent_.notify(NOTIFY_TRANSMIT_FOLLOWUP_RESPONSE);
             return Void();
         }
 
         Return<void> notifyCreateDataInterfaceResponse(uint16_t id,
                                                        const WifiNanStatus& status) override {
-            parent_.callbackType = NOTIFY_CREATE_DATA_INTERFACE_RESPONSE;
-
             parent_.id = id;
             parent_.status = status;
 
-            parent_.notify();
+            parent_.notify(NOTIFY_CREATE_DATA_INTERFACE_RESPONSE);
             return Void();
         }
 
         Return<void> notifyDeleteDataInterfaceResponse(uint16_t id,
                                                        const WifiNanStatus& status) override {
-            parent_.callbackType = NOTIFY_DELETE_DATA_INTERFACE_RESPONSE;
-
             parent_.id = id;
             parent_.status = status;
 
-            parent_.notify();
+            parent_.notify(NOTIFY_DELETE_DATA_INTERFACE_RESPONSE);
             return Void();
         }
 
         Return<void> notifyInitiateDataPathResponse(uint16_t id, const WifiNanStatus& status,
                                                     uint32_t ndpInstanceId) override {
-            parent_.callbackType = NOTIFY_INITIATE_DATA_PATH_RESPONSE;
-
             parent_.id = id;
             parent_.status = status;
             parent_.ndpInstanceId = ndpInstanceId;
 
-            parent_.notify();
+            parent_.notify(NOTIFY_INITIATE_DATA_PATH_RESPONSE);
             return Void();
         }
 
         Return<void> notifyRespondToDataPathIndicationResponse(
                 uint16_t id, const WifiNanStatus& status) override {
-            parent_.callbackType = NOTIFY_RESPOND_TO_DATA_PATH_INDICATION_RESPONSE;
-
             parent_.id = id;
             parent_.status = status;
 
-            parent_.notify();
+            parent_.notify(NOTIFY_RESPOND_TO_DATA_PATH_INDICATION_RESPONSE);
             return Void();
         }
 
         Return<void> notifyTerminateDataPathResponse(uint16_t id,
                                                      const WifiNanStatus& status) override {
-            parent_.callbackType = NOTIFY_TERMINATE_DATA_PATH_RESPONSE;
-
             parent_.id = id;
             parent_.status = status;
 
-            parent_.notify();
+            parent_.notify(NOTIFY_TERMINATE_DATA_PATH_RESPONSE);
             return Void();
         }
 
         Return<void> eventClusterEvent(const NanClusterEventInd& event) override {
-            parent_.callbackType = EVENT_CLUSTER_EVENT;
-
             parent_.nanClusterEventInd = event;
 
-            parent_.notify();
+            parent_.notify(EVENT_CLUSTER_EVENT);
             return Void();
         }
 
         Return<void> eventDisabled(const WifiNanStatus& status) override {
-            parent_.callbackType = EVENT_DISABLED;
-
             parent_.status = status;
 
-            parent_.notify();
+            parent_.notify(EVENT_DISABLED);
             return Void();
         }
 
         Return<void> eventPublishTerminated(uint8_t sessionId,
                                             const WifiNanStatus& status) override {
-            parent_.callbackType = EVENT_PUBLISH_TERMINATED;
-
             parent_.sessionId = sessionId;
             parent_.status = status;
 
-            parent_.notify();
+            parent_.notify(EVENT_PUBLISH_TERMINATED);
             return Void();
         }
 
         Return<void> eventSubscribeTerminated(uint8_t sessionId,
                                               const WifiNanStatus& status) override {
-            parent_.callbackType = EVENT_SUBSCRIBE_TERMINATED;
-
             parent_.sessionId = sessionId;
             parent_.status = status;
 
-            parent_.notify();
+            parent_.notify(EVENT_SUBSCRIBE_TERMINATED);
             return Void();
         }
 
         Return<void> eventMatch(
                 const ::android::hardware::wifi::V1_0::NanMatchInd& event) override {
-            parent_.callbackType = EVENT_MATCH;
-
             parent_.nanMatchInd = event;
 
-            parent_.notify();
+            parent_.notify(EVENT_MATCH);
             return Void();
         }
 
         Return<void> eventMatchExpired(uint8_t discoverySessionId, uint32_t peerId) override {
-            parent_.callbackType = EVENT_MATCH_EXPIRED;
-
             parent_.sessionId = discoverySessionId;
             parent_.peerId = peerId;
 
-            parent_.notify();
+            parent_.notify(EVENT_MATCH_EXPIRED);
             return Void();
         }
 
         Return<void> eventFollowupReceived(const NanFollowupReceivedInd& event) override {
-            parent_.callbackType = EVENT_FOLLOWUP_RECEIVED;
-
             parent_.nanFollowupReceivedInd = event;
 
-            parent_.notify();
+            parent_.notify(EVENT_FOLLOWUP_RECEIVED);
             return Void();
         }
 
         Return<void> eventTransmitFollowup(uint16_t id, const WifiNanStatus& status) override {
-            parent_.callbackType = EVENT_TRANSMIT_FOLLOWUP;
-
             parent_.id = id;
             parent_.status = status;
 
-            parent_.notify();
+            parent_.notify(EVENT_TRANSMIT_FOLLOWUP);
             return Void();
         }
 
         Return<void> eventDataPathRequest(const NanDataPathRequestInd& event) override {
-            parent_.callbackType = EVENT_DATA_PATH_REQUEST;
-
             parent_.nanDataPathRequestInd = event;
 
-            parent_.notify();
+            parent_.notify(EVENT_DATA_PATH_REQUEST);
             return Void();
         }
 
         Return<void> eventDataPathConfirm(
                 const ::android::hardware::wifi::V1_0::NanDataPathConfirmInd& event) override {
-            parent_.callbackType = EVENT_DATA_PATH_CONFIRM;
-
             parent_.nanDataPathConfirmInd = event;
 
-            parent_.notify();
+            parent_.notify(EVENT_DATA_PATH_CONFIRM);
             return Void();
         }
 
         Return<void> eventDataPathTerminated(uint32_t ndpInstanceId) override {
-            parent_.callbackType = EVENT_DATA_PATH_TERMINATED;
-
             parent_.ndpInstanceId = ndpInstanceId;
 
-            parent_.notify();
+            parent_.notify(EVENT_DATA_PATH_TERMINATED);
             return Void();
         }
 
         Return<void> eventDataPathConfirm_1_2(
                 const ::android::hardware::wifi::V1_2::NanDataPathConfirmInd& event) override {
-            parent_.callbackType = EVENT_DATA_PATH_CONFIRM_1_2;
-
             parent_.nanDataPathConfirmInd_1_2 = event;
 
-            parent_.notify();
+            parent_.notify(EVENT_DATA_PATH_CONFIRM_1_2);
             return Void();
         }
 
         Return<void> eventDataPathScheduleUpdate(
                 const ::android::hardware::wifi::V1_2::NanDataPathScheduleUpdateInd& event)
                 override {
-            parent_.callbackType = EVENT_DATA_PATH_SCHEDULE_UPDATE;
-
             parent_.nanDataPathScheduleUpdateInd_1_2 = event;
 
-            parent_.notify();
+            parent_.notify(EVENT_DATA_PATH_SCHEDULE_UPDATE);
             return Void();
         }
 
         Return<void> eventMatch_1_6(
                 const ::android::hardware::wifi::V1_6::NanMatchInd& event) override {
-            parent_.callbackType = EVENT_MATCH_1_6;
-
             parent_.nanMatchInd_1_6 = event;
 
-            parent_.notify();
+            parent_.notify(EVENT_MATCH_1_6);
             return Void();
         }
 
         Return<void> notifyCapabilitiesResponse_1_6(
                 uint16_t id, const WifiNanStatus& status,
                 const ::android::hardware::wifi::V1_6::NanCapabilities& capabilities) override {
-            parent_.callbackType = NOTIFY_CAPABILITIES_RESPONSE_1_6;
-
             parent_.id = id;
             parent_.status = status;
             parent_.capabilities_1_6 = capabilities;
 
-            parent_.notify();
+            parent_.notify(NOTIFY_CAPABILITIES_RESPONSE_1_6);
             return Void();
         }
 
         Return<void> eventDataPathScheduleUpdate_1_6(
                 const ::android::hardware::wifi::V1_6::NanDataPathScheduleUpdateInd& event)
                 override {
-            parent_.callbackType = EVENT_DATA_PATH_SCHEDULE_UPDATE_1_6;
-
             parent_.nanDataPathScheduleUpdateInd_1_6 = event;
 
-            parent_.notify();
+            parent_.notify(EVENT_DATA_PATH_SCHEDULE_UPDATE_1_6);
             return Void();
         }
 
         Return<void> eventDataPathConfirm_1_6(
                 const ::android::hardware::wifi::V1_6::NanDataPathConfirmInd& event) override {
-            parent_.callbackType = EVENT_DATA_PATH_CONFIRM_1_6;
-
             parent_.nanDataPathConfirmInd_1_6 = event;
 
-            parent_.notify();
+            parent_.notify(EVENT_DATA_PATH_CONFIRM_1_6);
             return Void();
         }
     };
@@ -490,7 +421,6 @@
     // synchronization objects
     std::mutex mtx_;
     std::condition_variable cv_;
-    int count_ = 0;
 
   protected:
     android::sp<::android::hardware::wifi::V1_6::IWifiNanIface> iwifiNanIface;
@@ -498,7 +428,7 @@
     // Data from IWifiNanIfaceEventCallback callbacks: this is the collection of
     // all arguments to all callbacks. They are set by the callback
     // (notifications or events) and can be retrieved by tests.
-    CallbackType callbackType;
+    uint32_t callbackEventBitMap;
     uint16_t id;
     WifiNanStatus status;
     uint8_t sessionId;
@@ -535,7 +465,7 @@
  */
 TEST_P(WifiNanIfaceHidlTest, enableRequest_1_6InvalidArgs) {
     uint16_t inputCmdId = 10;
-    callbackType = INVALID;
+    callbackEventBitMap = INVALID;
     ::android::hardware::wifi::V1_4::NanEnableRequest nanEnableRequest = {};
     ::android::hardware::wifi::V1_6::NanConfigRequestSupplemental nanConfigRequestSupp = {};
     const auto& halStatus = HIDL_INVOKE(iwifiNanIface, enableRequest_1_6, inputCmdId,
@@ -545,7 +475,7 @@
 
         // wait for a callback
         ASSERT_EQ(std::cv_status::no_timeout, wait(NOTIFY_ENABLE_RESPONSE));
-        ASSERT_EQ(NOTIFY_ENABLE_RESPONSE, callbackType);
+        ASSERT_EQ(0x1 << NOTIFY_ENABLE_RESPONSE, callbackEventBitMap & (0x1 << NOTIFY_ENABLE_RESPONSE));
         ASSERT_EQ(id, inputCmdId);
         ASSERT_EQ(status.status, NanStatusType::INVALID_ARGS);
     }
@@ -572,7 +502,7 @@
  */
 TEST_P(WifiNanIfaceHidlTest, configRequest_1_6InvalidArgs) {
     uint16_t inputCmdId = 10;
-    callbackType = INVALID;
+    callbackEventBitMap = INVALID;
     ::android::hardware::wifi::V1_4::NanConfigRequest nanConfigRequest = {};
     ::android::hardware::wifi::V1_6::NanConfigRequestSupplemental nanConfigRequestSupp = {};
     const auto& halStatus = HIDL_INVOKE(iwifiNanIface, configRequest_1_6, inputCmdId,
@@ -583,7 +513,7 @@
 
         // wait for a callback
         ASSERT_EQ(std::cv_status::no_timeout, wait(NOTIFY_CONFIG_RESPONSE));
-        ASSERT_EQ(NOTIFY_CONFIG_RESPONSE, callbackType);
+        ASSERT_EQ(0x1 << NOTIFY_CONFIG_RESPONSE, callbackEventBitMap & (0x1 << NOTIFY_CONFIG_RESPONSE));
         ASSERT_EQ(id, inputCmdId);
         ASSERT_EQ(status.status, NanStatusType::INVALID_ARGS);
     }
@@ -610,12 +540,12 @@
  */
 TEST_P(WifiNanIfaceHidlTest, notifyCapabilitiesResponse_1_6) {
     uint16_t inputCmdId = 10;
-    callbackType = INVALID;
+    callbackEventBitMap = INVALID;
     const auto& halStatus = HIDL_INVOKE(iwifiNanIface, getCapabilitiesRequest_1_5, inputCmdId).code;
     ASSERT_EQ(WifiStatusCode::SUCCESS, halStatus);
     // wait for a callback
     ASSERT_EQ(std::cv_status::no_timeout, wait(NOTIFY_CAPABILITIES_RESPONSE_1_6));
-    ASSERT_EQ(NOTIFY_CAPABILITIES_RESPONSE_1_6, callbackType);
+    ASSERT_EQ(0x1 << NOTIFY_CAPABILITIES_RESPONSE_1_6, callbackEventBitMap & (0x1 << NOTIFY_CAPABILITIES_RESPONSE_1_6));
     ASSERT_EQ(id, inputCmdId);
     ASSERT_EQ(status.status, NanStatusType::SUCCESS);
 
@@ -711,7 +641,7 @@
     nanConfigRequestSupp.V1_5.V1_2.numberOfSpatialStreamsInDiscovery = 0;
     nanConfigRequestSupp.V1_5.V1_2.enableDiscoveryWindowEarlyTermination = false;
 
-    callbackType = INVALID;
+    callbackEventBitMap = INVALID;
 
     const auto& halStatus =
             HIDL_INVOKE(iwifiNanIface, enableRequest_1_6, inputCmdId, req, nanConfigRequestSupp);
@@ -720,7 +650,7 @@
 
         // wait for a callback
         ASSERT_EQ(std::cv_status::no_timeout, wait(NOTIFY_ENABLE_RESPONSE));
-        ASSERT_EQ(NOTIFY_ENABLE_RESPONSE, callbackType);
+        ASSERT_EQ(0x1 << NOTIFY_ENABLE_RESPONSE, callbackEventBitMap & (0x1 << NOTIFY_ENABLE_RESPONSE));
         ASSERT_EQ(id, inputCmdId);
         ASSERT_EQ(status.status, NanStatusType::SUCCESS);
     }
@@ -749,7 +679,7 @@
 
         // wait for a callback
         ASSERT_EQ(std::cv_status::no_timeout, wait(NOTIFY_START_PUBLISH_RESPONSE));
-        ASSERT_EQ(NOTIFY_START_PUBLISH_RESPONSE, callbackType);
+        ASSERT_EQ(0x1 << NOTIFY_START_PUBLISH_RESPONSE, callbackEventBitMap & (0x1 << NOTIFY_START_PUBLISH_RESPONSE));
         ASSERT_EQ(id, inputCmdId + 1);
         ASSERT_EQ(status.status, NanStatusType::SUCCESS);
     }
@@ -760,7 +690,7 @@
  */
 TEST_P(WifiNanIfaceHidlTest, respondToDataPathIndicationRequest_1_6ShimInvalidArgs) {
     uint16_t inputCmdId = 10;
-    callbackType = INVALID;
+    callbackEventBitMap = INVALID;
     ::android::hardware::wifi::V1_6::NanRespondToDataPathIndicationRequest
             nanRespondToDataPathIndicationRequest = {};
     nanRespondToDataPathIndicationRequest.ifaceName = "AwareinterfaceNameTooLong";
@@ -777,7 +707,7 @@
  */
 TEST_P(WifiNanIfaceHidlTest, initiateDataPathRequest_1_6ShimInvalidArgs) {
     uint16_t inputCmdId = 10;
-    callbackType = INVALID;
+    callbackEventBitMap = INVALID;
     ::android::hardware::wifi::V1_6::NanInitiateDataPathRequest nanInitiateDataPathRequest = {};
     nanInitiateDataPathRequest.ifaceName = "AwareinterfaceNameTooLong";
     const auto& halStatus = HIDL_INVOKE(iwifiNanIface, initiateDataPathRequest_1_6, inputCmdId,