Merge "audio: Implement ITelephony core interface for telecom"
diff --git a/audio/OWNERS b/audio/OWNERS
index ede448c..3671685 100644
--- a/audio/OWNERS
+++ b/audio/OWNERS
@@ -1 +1,4 @@
-per-file README.md = elaurent@google.com,mnaganov@google.com
+# Bug component: 48436
+
+elaurent@google.com
+mnaganov@google.com
diff --git a/audio/aidl/Android.bp b/audio/aidl/Android.bp
index 42a4ac1..ef51361 100644
--- a/audio/aidl/Android.bp
+++ b/audio/aidl/Android.bp
@@ -114,11 +114,11 @@
         "android/hardware/audio/core/AudioRoute.aidl",
         "android/hardware/audio/core/IConfig.aidl",
         "android/hardware/audio/core/IModule.aidl",
-        "android/hardware/audio/core/ISoundDose.aidl",
         "android/hardware/audio/core/IStreamCallback.aidl",
         "android/hardware/audio/core/IStreamCommon.aidl",
         "android/hardware/audio/core/IStreamIn.aidl",
         "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",
@@ -132,6 +132,7 @@
         "android.hardware.common-V2",
         "android.hardware.common.fmq-V1",
         "android.hardware.audio.common-V1",
+        "android.hardware.audio.core.sounddose-V1",
         "android.hardware.audio.effect-V1",
         "android.media.audio.common.types-V2",
     ],
@@ -177,7 +178,7 @@
         "android.hardware.audio_defaults",
     ],
     srcs: [
-        "android/hardware/audio/core/ISoundDose.aidl",
+        "android/hardware/audio/core/sounddose/ISoundDose.aidl",
     ],
     imports: [
         "android.media.audio.common.types-V2",
diff --git a/audio/aidl/OWNERS b/audio/aidl/OWNERS
deleted file mode 100644
index f9a2d6b..0000000
--- a/audio/aidl/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-# Bug component: 48436
-elaurent@google.com
-mnaganov@google.com
diff --git a/audio/aidl/TEST_MAPPING b/audio/aidl/TEST_MAPPING
index 2e84d95..a166e61 100644
--- a/audio/aidl/TEST_MAPPING
+++ b/audio/aidl/TEST_MAPPING
@@ -13,6 +13,9 @@
       "name": "VtsHalDownmixTargetTest"
     },
     {
+      "name": "VtsHalEnvironmentalReverbTargetTest"
+    },
+    {
       "name": "VtsHalEqualizerTargetTest"
     },
     {
@@ -22,6 +25,9 @@
       "name": "VtsHalLoudnessEnhancerTargetTest"
     },
     {
+      "name": "VtsHalPresetReverbTargetTest"
+    },
+    {
       "name": "VtsHalVirtualizerTargetTest"
     },
     {
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core.sounddose/current/android/hardware/audio/core/ISoundDose.aidl b/audio/aidl/aidl_api/android.hardware.audio.core.sounddose/current/android/hardware/audio/core/sounddose/ISoundDose.aidl
similarity index 88%
rename from audio/aidl/aidl_api/android.hardware.audio.core.sounddose/current/android/hardware/audio/core/ISoundDose.aidl
rename to audio/aidl/aidl_api/android.hardware.audio.core.sounddose/current/android/hardware/audio/core/sounddose/ISoundDose.aidl
index bc010ca..3b5d2d0 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.core.sounddose/current/android/hardware/audio/core/ISoundDose.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.core.sounddose/current/android/hardware/audio/core/sounddose/ISoundDose.aidl
@@ -31,18 +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.audio.core;
+package android.hardware.audio.core.sounddose;
 @VintfStability
 interface ISoundDose {
   void setOutputRs2(float rs2ValueDbA);
   float getOutputRs2();
-  void registerSoundDoseCallback(in android.hardware.audio.core.ISoundDose.IHalSoundDoseCallback callback);
+  void registerSoundDoseCallback(in android.hardware.audio.core.sounddose.ISoundDose.IHalSoundDoseCallback callback);
   const int DEFAULT_MAX_RS2 = 100;
   const int MIN_RS2 = 80;
   @VintfStability
   interface IHalSoundDoseCallback {
     oneway void onMomentaryExposureWarning(float currentDbA, in android.media.audio.common.AudioDevice audioDevice);
-    oneway void onNewMelValues(in android.hardware.audio.core.ISoundDose.IHalSoundDoseCallback.MelRecord melRecord, in android.media.audio.common.AudioDevice audioDevice);
+    oneway void onNewMelValues(in android.hardware.audio.core.sounddose.ISoundDose.IHalSoundDoseCallback.MelRecord melRecord, in android.media.audio.common.AudioDevice audioDevice);
     @VintfStability
     parcelable MelRecord {
       float[] melValues;
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 dd2279d..a029d43 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
@@ -46,6 +46,7 @@
   android.hardware.audio.core.AudioRoute[] getAudioRoutesForAudioPort(int portId);
   android.hardware.audio.core.IModule.OpenInputStreamReturn openInputStream(in android.hardware.audio.core.IModule.OpenInputStreamArguments args);
   android.hardware.audio.core.IModule.OpenOutputStreamReturn openOutputStream(in android.hardware.audio.core.IModule.OpenOutputStreamArguments args);
+  android.hardware.audio.core.IModule.SupportedPlaybackRateFactors getSupportedPlaybackRateFactors();
   android.hardware.audio.core.AudioPatch setAudioPatch(in android.hardware.audio.core.AudioPatch requested);
   boolean setAudioPortConfig(in android.media.audio.common.AudioPortConfig requested, out android.media.audio.common.AudioPortConfig suggested);
   void resetAudioPatch(int patchId);
@@ -60,7 +61,7 @@
   void updateAudioMode(android.hardware.audio.core.AudioMode mode);
   void updateScreenRotation(android.hardware.audio.core.IModule.ScreenRotation rotation);
   void updateScreenState(boolean isTurnedOn);
-  @nullable android.hardware.audio.core.ISoundDose getSoundDose();
+  @nullable android.hardware.audio.core.sounddose.ISoundDose getSoundDose();
   int generateHwAvSyncId();
   android.hardware.audio.core.VendorParameter[] getVendorParameters(in @utf8InCpp String[] ids);
   void setVendorParameters(in android.hardware.audio.core.VendorParameter[] parameters, boolean async);
@@ -84,12 +85,20 @@
     @nullable android.media.audio.common.AudioOffloadInfo offloadInfo;
     long bufferSizeFrames;
     @nullable android.hardware.audio.core.IStreamCallback callback;
+    @nullable android.hardware.audio.core.IStreamOutEventCallback eventCallback;
   }
   @VintfStability
   parcelable OpenOutputStreamReturn {
     android.hardware.audio.core.IStreamOut stream;
     android.hardware.audio.core.StreamDescriptor desc;
   }
+  @VintfStability
+  parcelable SupportedPlaybackRateFactors {
+    float minSpeed;
+    float maxSpeed;
+    float minPitch;
+    float maxPitch;
+  }
   @Backing(type="int") @VintfStability
   enum ScreenRotation {
     DEG_0 = 0,
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/ISoundDose.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/ISoundDose.aidl
deleted file mode 100644
index bc010ca..0000000
--- a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/ISoundDose.aidl
+++ /dev/null
@@ -1,52 +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;
-@VintfStability
-interface ISoundDose {
-  void setOutputRs2(float rs2ValueDbA);
-  float getOutputRs2();
-  void registerSoundDoseCallback(in android.hardware.audio.core.ISoundDose.IHalSoundDoseCallback callback);
-  const int DEFAULT_MAX_RS2 = 100;
-  const int MIN_RS2 = 80;
-  @VintfStability
-  interface IHalSoundDoseCallback {
-    oneway void onMomentaryExposureWarning(float currentDbA, in android.media.audio.common.AudioDevice audioDevice);
-    oneway void onNewMelValues(in android.hardware.audio.core.ISoundDose.IHalSoundDoseCallback.MelRecord melRecord, in android.media.audio.common.AudioDevice audioDevice);
-    @VintfStability
-    parcelable MelRecord {
-      float[] melValues;
-      long timestamp;
-    }
-  }
-}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IStreamOut.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IStreamOut.aidl
index 092b801..46acc11 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
@@ -38,6 +38,16 @@
   void updateMetadata(in android.hardware.audio.common.SourceMetadata sourceMetadata);
   float[] getHwVolume();
   void setHwVolume(in float[] channelVolumes);
+  float getAudioDescriptionMixLevel();
+  void setAudioDescriptionMixLevel(float leveldB);
+  android.media.audio.common.AudioDualMonoMode getDualMonoMode();
+  void setDualMonoMode(android.media.audio.common.AudioDualMonoMode mode);
+  android.media.audio.common.AudioLatencyMode[] getRecommendedLatencyModes();
+  void setLatencyMode(android.media.audio.common.AudioLatencyMode mode);
+  android.media.audio.common.AudioPlaybackRate getPlaybackRateParameters();
+  void setPlaybackRateParameters(in android.media.audio.common.AudioPlaybackRate playbackRate);
+  void selectPresentation(int presentationId, int programId);
   const int HW_VOLUME_MIN = 0;
   const int HW_VOLUME_MAX = 1;
+  const int AUDIO_DESCRIPTION_MIX_LEVEL_MAX = 48;
 }
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core.sounddose/current/android/hardware/audio/core/ISoundDose.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IStreamOutEventCallback.aidl
similarity index 71%
copy from audio/aidl/aidl_api/android.hardware.audio.core.sounddose/current/android/hardware/audio/core/ISoundDose.aidl
copy to audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IStreamOutEventCallback.aidl
index bc010ca..31cf0b7 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.core.sounddose/current/android/hardware/audio/core/ISoundDose.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IStreamOutEventCallback.aidl
@@ -33,20 +33,7 @@
 
 package android.hardware.audio.core;
 @VintfStability
-interface ISoundDose {
-  void setOutputRs2(float rs2ValueDbA);
-  float getOutputRs2();
-  void registerSoundDoseCallback(in android.hardware.audio.core.ISoundDose.IHalSoundDoseCallback callback);
-  const int DEFAULT_MAX_RS2 = 100;
-  const int MIN_RS2 = 80;
-  @VintfStability
-  interface IHalSoundDoseCallback {
-    oneway void onMomentaryExposureWarning(float currentDbA, in android.media.audio.common.AudioDevice audioDevice);
-    oneway void onNewMelValues(in android.hardware.audio.core.ISoundDose.IHalSoundDoseCallback.MelRecord melRecord, in android.media.audio.common.AudioDevice audioDevice);
-    @VintfStability
-    parcelable MelRecord {
-      float[] melValues;
-      long timestamp;
-    }
-  }
+interface IStreamOutEventCallback {
+  oneway void onCodecFormatChanged(in byte[] audioMetadata);
+  oneway void onRecommendedLatencyModeChanged(in android.media.audio.common.AudioLatencyMode[] modes);
 }
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 09ad015..f8baa2a 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
@@ -36,8 +36,6 @@
 union BassBoost {
   android.hardware.audio.effect.VendorExtension vendor;
   int strengthPm;
-  const int MIN_PER_MILLE_STRENGTH = 0;
-  const int MAX_PER_MILLE_STRENGTH = 1000;
   @VintfStability
   union Id {
     int vendorExtensionTag;
@@ -46,6 +44,7 @@
   @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/EnvironmentalReverb.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/EnvironmentalReverb.aidl
index fcf08c3..0e61932 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
@@ -44,6 +44,22 @@
   int diffusionPm;
   int densityPm;
   boolean bypass;
+  const int MIN_ROOM_LEVEL_MB = -6000;
+  const int MAX_ROOM_LEVEL_MB = 0;
+  const int MIN_ROOM_HF_LEVEL_MB = -4000;
+  const int MAX_ROOM_HF_LEVEL_MB = 0;
+  const int MIN_DECAY_TIME_MS = 100;
+  const int MAX_DECAY_TIME_MS = 20000;
+  const int MIN_DECAY_HF_RATIO_PM = 100;
+  const int MAX_DECAY_HF_RATIO_PM = 1000;
+  const int MIN_LEVEL_MB = -6000;
+  const int MAX_LEVEL_MB = 0;
+  const int MIN_DELAY_MS = 0;
+  const int MAX_DELAY_MS = 65;
+  const int MIN_DIFFUSION_PM = 0;
+  const int MAX_DIFFUSION_PM = 1000;
+  const int MIN_DENSITY_PM = 0;
+  const int MAX_DENSITY_PM = 1000;
   @VintfStability
   union Id {
     int vendorExtensionTag;
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 deaff90..9fdd692 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,8 +36,6 @@
 union Virtualizer {
   android.hardware.audio.effect.VendorExtension vendor;
   int strengthPm;
-  const int MIN_PER_MILLE_STRENGTH = 0;
-  const int MAX_PER_MILLE_STRENGTH = 1000;
   @VintfStability
   union Id {
     int vendorExtensionTag;
@@ -46,6 +44,7 @@
   @VintfStability
   parcelable Capability {
     android.hardware.audio.effect.VendorExtension extension;
+    int maxStrengthPm;
     boolean strengthSupported;
   }
 }
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 ccd32e8..6259cfb 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
@@ -37,9 +37,6 @@
   android.hardware.audio.effect.VendorExtension vendor;
   int levelDb;
   boolean mute;
-  // TODO(b/263416041) Move to Capability
-  const int MIN_LEVEL_DB = -9600;
-  const int MAX_LEVEL_DB = 0;
   @VintfStability
   union Id {
     int vendorExtensionTag;
@@ -48,6 +45,7 @@
   @VintfStability
   parcelable Capability {
     android.hardware.audio.effect.VendorExtension extension;
-    int maxLevel;
+    int minLevelDb;
+    int maxLevelDb;
   }
 }
diff --git a/audio/aidl/android/hardware/audio/core/IModule.aidl b/audio/aidl/android/hardware/audio/core/IModule.aidl
index b278ac4..4779f1f 100644
--- a/audio/aidl/android/hardware/audio/core/IModule.aidl
+++ b/audio/aidl/android/hardware/audio/core/IModule.aidl
@@ -21,19 +21,21 @@
 import android.hardware.audio.core.AudioMode;
 import android.hardware.audio.core.AudioPatch;
 import android.hardware.audio.core.AudioRoute;
-import android.hardware.audio.core.ISoundDose;
 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;
+import android.hardware.audio.core.sounddose.ISoundDose;
 import android.hardware.audio.effect.IEffect;
 import android.media.audio.common.AudioOffloadInfo;
 import android.media.audio.common.AudioPort;
 import android.media.audio.common.AudioPortConfig;
+import android.media.audio.common.Float;
 
 /**
  * Each instance of IModule corresponds to a separate audio module. The system
@@ -389,6 +391,8 @@
         long bufferSizeFrames;
         /** Client callback interface for the non-blocking output mode. */
         @nullable IStreamCallback callback;
+        /** Optional callback to notify client about stream events. */
+        @nullable IStreamOutEventCallback eventCallback;
     }
     @VintfStability
     parcelable OpenOutputStreamReturn {
@@ -398,6 +402,33 @@
     OpenOutputStreamReturn openOutputStream(in OpenOutputStreamArguments args);
 
     /**
+     * Get supported ranges of playback rate factors.
+     *
+     * See 'PlaybackRate' for the information on the playback rate parameters.
+     * This method provides supported ranges (inclusive) for the speed factor
+     * and the pitch factor.
+     *
+     * If the HAL module supports setting the playback rate, it is recommended
+     * to support speed and pitch factor values at least in the range from 0.5f
+     * to 2.0f.
+     *
+     * @throws EX_UNSUPPORTED_OPERATION If setting of playback rate parameters
+     *                                  is not supported by the module.
+     */
+    @VintfStability
+    parcelable SupportedPlaybackRateFactors {
+        /** The minimum allowed speed factor. */
+        float minSpeed;
+        /** The maximum allowed speed factor. */
+        float maxSpeed;
+        /** The minimum allowed pitch factor. */
+        float minPitch;
+        /** The maximum allowed pitch factor. */
+        float maxPitch;
+    }
+    SupportedPlaybackRateFactors getSupportedPlaybackRateFactors();
+
+    /**
      * Set an audio patch.
      *
      * This method creates new or updates an existing audio patch. If the
diff --git a/audio/aidl/android/hardware/audio/core/IStreamOut.aidl b/audio/aidl/android/hardware/audio/core/IStreamOut.aidl
index 85da00d..b60b0fd 100644
--- a/audio/aidl/android/hardware/audio/core/IStreamOut.aidl
+++ b/audio/aidl/android/hardware/audio/core/IStreamOut.aidl
@@ -18,6 +18,9 @@
 
 import android.hardware.audio.common.SourceMetadata;
 import android.hardware.audio.core.IStreamCommon;
+import android.media.audio.common.AudioDualMonoMode;
+import android.media.audio.common.AudioLatencyMode;
+import android.media.audio.common.AudioPlaybackRate;
 
 /**
  * This interface provides means for sending audio data to output devices.
@@ -86,4 +89,140 @@
      * @throws EX_UNSUPPORTED_OPERATION If hardware volume control is not supported.
      */
     void setHwVolume(in float[] channelVolumes);
+
+    // aidl: Constant of type float is not supported (b/251286924).
+    // const float AUDIO_DESCRIPTION_MIX_LEVEL_MIN = -Inf;
+    const int AUDIO_DESCRIPTION_MIX_LEVEL_MAX = 48;
+    /**
+     * Returns the Audio Description Mix level in dB.
+     *
+     * The level is applied to streams incorporating a secondary Audio
+     * Description stream. It specifies the relative level of mixing for
+     * the Audio Description with a reference to the Main Audio.
+     *
+     * The value of the relative level is in the range from negative infinity
+     * to +48, see AUDIO_DESCRIPTION_MIX_LEVEL_* constants.
+     *
+     * @return The current Audio Description Mix Level in dB.
+     * @throws EX_ILLEGAL_STATE If the stream is closed.
+     * @throws EX_UNSUPPORTED_OPERATION If the information is unavailable.
+     */
+    float getAudioDescriptionMixLevel();
+    /**
+     * Sets the Audio Description Mix level in dB.
+     *
+     * For streams incorporating a secondary Audio Description stream the
+     * relative level of mixing of the Audio Description to the Main Audio is
+     * controlled by this method.
+     *
+     * The value of the relative level must be in the range from negative
+     * infinity to +48, see AUDIO_DESCRIPTION_MIX_LEVEL_* constants.
+     *
+     * @param leveldB Audio Description Mix Level in dB.
+     * @throws EX_ILLEGAL_ARGUMENT If the provided value is out of range.
+     * @throws EX_ILLEGAL_STATE If the stream is closed.
+     * @throws EX_UNSUPPORTED_OPERATION If setting of this parameter is not supported.
+     */
+    void setAudioDescriptionMixLevel(float leveldB);
+
+    /**
+     * Returns the Dual Mono mode presentation setting.
+     *
+     * @return The current setting of Dual Mono mode.
+     * @throws EX_ILLEGAL_STATE If the stream is closed.
+     * @throws EX_UNSUPPORTED_OPERATION If the information is unavailable.
+     */
+    AudioDualMonoMode getDualMonoMode();
+    /**
+     * Sets the Dual Mono mode presentation on the output device.
+     *
+     * The Dual Mono mode is generally applied to stereo audio streams
+     * where the left and right channels come from separate sources.
+     *
+     * @param mode Selected Dual Mono mode.
+     * @throws EX_ILLEGAL_STATE If the stream is closed.
+     * @throws EX_UNSUPPORTED_OPERATION If setting of this parameter is not supported.
+     */
+    void setDualMonoMode(AudioDualMonoMode mode);
+
+    /**
+     * Retrieve supported latency modes.
+     *
+     * Indicates which latency modes are currently supported on this output
+     * stream. If the transport protocol (for example, Bluetooth A2DP) used by
+     * this output stream to reach the output device supports variable latency
+     * modes, the HAL indicates which modes are currently supported. The client
+     * can then call setLatencyMode() with one of the supported modes to select
+     * the desired operation mode.
+     *
+     * Implementation for this method is mandatory only on specific spatial
+     * audio streams indicated by AUDIO_OUTPUT_FLAG_SPATIALIZER flag if they can
+     * be routed to a BT classic sink.
+     *
+     * @return Currently supported latency modes.
+     * @throws EX_ILLEGAL_STATE If the stream is closed.
+     * @throws EX_UNSUPPORTED_OPERATION If the information is unavailable.
+     */
+    AudioLatencyMode[] getRecommendedLatencyModes();
+    /**
+     * Sets the latency mode.
+     *
+     * The requested mode must be one of the modes returned by the
+     * 'getRecommendedLatencyModes()' method.
+     *
+     * Implementation for this method is mandatory only on specific spatial
+     * audio streams indicated by AUDIO_OUTPUT_FLAG_SPATIALIZER flag if they can
+     * be routed to a BT classic sink.
+     *
+     * @throws EX_ILLEGAL_ARGUMENT If the specified mode is not supported.
+     * @throws EX_ILLEGAL_STATE If the stream is closed.
+     * @throws EX_UNSUPPORTED_OPERATION If setting of this parameter is not supported.
+     */
+    void setLatencyMode(AudioLatencyMode mode);
+
+    /**
+     * Retrieve current playback rate parameters.
+     *
+     * @return Current playback parameters.
+     * @throws EX_ILLEGAL_STATE If the stream is closed.
+     * @throws EX_UNSUPPORTED_OPERATION If the information is unavailable.
+     */
+    AudioPlaybackRate getPlaybackRateParameters();
+    /**
+     * Set playback rate parameters.
+     *
+     * Sets the playback rate parameters that control playback behavior. This
+     * is normally used when playing encoded content and decoding is performed
+     * in hardware. Otherwise, the client can apply necessary transformations
+     * itself.
+     *
+     * The range of supported values for speed and pitch factors is provided by
+     * the 'IModule.getSupportedPlaybackRateFactors' method. Out of range speed
+     * and pitch values must not be rejected if the fallback mode is 'MUTE'.
+     *
+     * @param playbackRate Playback parameters to set.
+     * @throws EX_ILLEGAL_ARGUMENT If provided parameters are out of acceptable range.
+     * @throws EX_ILLEGAL_STATE If the stream is closed.
+     * @throws EX_UNSUPPORTED_OPERATION If setting playback rate parameters
+     *                                  is not supported.
+     */
+    void setPlaybackRateParameters(in AudioPlaybackRate playbackRate);
+
+    /**
+     * Select presentation and program from for decoding.
+     *
+     * Selects a presentation for decoding from a next generation media stream
+     * (as defined per ETSI TS 103 190-2) and a program within the presentation.
+     * The client must obtain valid presentation and program IDs from the media
+     * stream on its own.
+     *
+     * @param presentationId Selected audio presentation.
+     * @param programId Refinement for the presentation.
+     * @throws EX_ILLEGAL_ARGUMENT If the HAL module is unable to locate
+     *                             the specified presentation or program in
+     *                             the media stream.
+     * @throws EX_ILLEGAL_STATE If the stream is closed.
+     * @throws EX_UNSUPPORTED_OPERATION If presentation selection is not supported.
+     */
+    void selectPresentation(int presentationId, int programId);
 }
diff --git a/audio/aidl/android/hardware/audio/core/IStreamOutEventCallback.aidl b/audio/aidl/android/hardware/audio/core/IStreamOutEventCallback.aidl
new file mode 100644
index 0000000..75d7385
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/core/IStreamOutEventCallback.aidl
@@ -0,0 +1,168 @@
+/*
+ * 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.AudioLatencyMode;
+
+/**
+ * This interface provides means for asynchronous notification of the client
+ * by an output stream.
+ */
+@VintfStability
+oneway interface IStreamOutEventCallback {
+    /**
+     * Codec format changed notification.
+     *
+     * onCodecFormatChanged returns an AudioMetadata object in read-only
+     * ByteString format.  It represents the most recent codec format decoded by
+     * a HW audio decoder.
+     *
+     * Codec format is an optional message from HW audio decoders. It serves to
+     * notify the application about the codec format and audio objects contained
+     * within the compressed audio stream for control, informational,
+     * and display purposes.
+     *
+     * audioMetadata ByteString is convertible to an AudioMetadata object
+     * through both a C++ and a C API present in Metadata.h [1], or through a
+     * Java API present in AudioMetadata.java [2].
+     *
+     * The ByteString format is a stable format used for parcelling
+     * (marshalling) across JNI, AIDL, and HIDL interfaces.  The test for R
+     * compatibility for native marshalling is TEST(metadata_tests,
+     * compatibility_R) [3]. The test for R compatibility for JNI marshalling
+     * is android.media.cts.AudioMetadataTest#testCompatibilityR [4].
+     *
+     * Android R defined keys are as follows [2]:
+     * "bitrate", int32
+     * "channel-mask", int32
+     * "mime", string
+     * "sample-rate", int32
+     * "bit-width", int32
+     * "has-atmos", int32
+     * "audio-encoding", int32
+     *
+     * Android S in addition adds the following keys:
+     * "presentation-id", int32
+     * "program-id", int32
+     * "presentation-content-classifier", int32
+     *    presentation-content-classifier key values can be referenced from
+     *    frameworks/base/media/java/android/media/AudioPresentation.java
+     *    i.e. AudioPresentation.ContentClassifier
+     *    It can contain any of the below values
+     *    CONTENT_UNKNOWN   = -1,
+     *    CONTENT_MAIN      =  0,
+     *    CONTENT_MUSIC_AND_EFFECTS = 1,
+     *    CONTENT_VISUALLY_IMPAIRED = 2,
+     *    CONTENT_HEARING_IMPAIRED  = 3,
+     *    CONTENT_DIALOG = 4,
+     *    CONTENT_COMMENTARY = 5,
+     *    CONTENT_EMERGENCY = 6,
+     *    CONTENT_VOICEOVER = 7
+     * "presentation-language", string  // represents ISO 639-2 (three letter code)
+     *
+     * Parceling Format:
+     * All values are native endian order. [1]
+     *
+     * using type_size_t = uint32_t;
+     * using index_size_t = uint32_t;
+     * using datum_size_t = uint32_t;
+     *
+     * Permitted type indexes are
+     * TYPE_NONE = 0, // Reserved
+     * TYPE_INT32 = 1,
+     * TYPE_INT64 = 2,
+     * TYPE_FLOAT = 3,
+     * TYPE_DOUBLE = 4,
+     * TYPE_STRING = 5,
+     * TYPE_DATA = 6,  // A data table of <String, Datum>
+     *
+     * Datum = {
+     *           (type_size_t)  Type (the type index from type_as_value<T>.)
+     *           (datum_size_t) Size (size of the Payload)
+     *           (byte string)  Payload<Type>
+     *         }
+     *
+     * The data is specified in native endian order. Since the size of the
+     * Payload is always present, unknown types may be skipped.
+     *
+     * Payload<Fixed-size Primitive_Value>
+     * [ sizeof(Primitive_Value) in raw bytes ]
+     *
+     * Example of Payload<Int32> of 123:
+     * Payload<Int32>
+     * [ value of 123                   ] =  0x7b 0x00 0x00 0x00       123
+     *
+     * Payload<String>
+     * [ (index_size_t) length, not including zero terminator.]
+     * [ (length) raw bytes ]
+     *
+     * Example of Payload<String> of std::string("hi"):
+     * [ (index_size_t) length          ] = 0x02 0x00 0x00 0x00        2 strlen("hi")
+     * [ raw bytes "hi"                 ] = 0x68 0x69                  "hi"
+     *
+     * Payload<Data>
+     * [ (index_size_t) entries ]
+     * [ raw bytes   (entry 1) Key   (Payload<String>)
+     *                         Value (Datum)
+     *                ...  (until #entries) ]
+     *
+     * Example of Payload<Data> of {{"hello", "world"},
+     *                              {"value", (int32_t)1000}};
+     * [ (index_size_t) #entries        ] = 0x02 0x00 0x00 0x00        2 entries
+     *    Key (Payload<String>)
+     *    [ index_size_t length         ] = 0x05 0x00 0x00 0x00        5 strlen("hello")
+     *    [ raw bytes "hello"           ] = 0x68 0x65 0x6c 0x6c 0x6f   "hello"
+     *    Value (Datum)
+     *    [ (type_size_t) type          ] = 0x05 0x00 0x00 0x00        5 (TYPE_STRING)
+     *    [ (datum_size_t) size         ] = 0x09 0x00 0x00 0x00        sizeof(index_size_t) +
+     *                                                                 strlen("world")
+     *       Payload<String>
+     *       [ (index_size_t) length    ] = 0x05 0x00 0x00 0x00        5 strlen("world")
+     *       [ raw bytes "world"        ] = 0x77 0x6f 0x72 0x6c 0x64   "world"
+     *    Key (Payload<String>)
+     *    [ index_size_t length         ] = 0x05 0x00 0x00 0x00        5 strlen("value")
+     *    [ raw bytes "value"           ] = 0x76 0x61 0x6c 0x75 0x65   "value"
+     *    Value (Datum)
+     *    [ (type_size_t) type          ] = 0x01 0x00 0x00 0x00        1 (TYPE_INT32)
+     *    [ (datum_size_t) size         ] = 0x04 0x00 0x00 0x00        4 sizeof(int32_t)
+     *        Payload<Int32>
+     *        [ raw bytes 1000          ] = 0xe8 0x03 0x00 0x00        1000
+     *
+     * The contents of audioMetadata is a Payload<Data>.
+     * An implementation dependent detail is that the Keys are always
+     * stored sorted, so the byte string representation generated is unique.
+     *
+     * Vendor keys are allowed for informational and debugging purposes.
+     * Vendor keys should consist of the vendor company name followed
+     * by a dot; for example, "vendorCompany.someVolume" [2].
+     *
+     * [1] system/media/audio_utils/include/audio_utils/Metadata.h
+     * [2] frameworks/base/media/java/android/media/AudioMetadata.java
+     * [3] system/media/audio_utils/tests/metadata_tests.cpp
+     * [4] cts/tests/tests/media/src/android/media/cts/AudioMetadataTest.java
+     *
+     * @param audioMetadata A buffer containing decoded format changes
+     *     reported by codec. The buffer contains data that can be transformed
+     *     to audio metadata, which is a C++ object based map.
+     */
+    void onCodecFormatChanged(in byte[] audioMetadata);
+
+    /**
+     * Called with the new list of supported latency modes when a change occurs.
+     */
+    void onRecommendedLatencyModeChanged(in AudioLatencyMode[] modes);
+}
diff --git a/audio/aidl/android/hardware/audio/core/ISoundDose.aidl b/audio/aidl/android/hardware/audio/core/sounddose/ISoundDose.aidl
similarity index 98%
rename from audio/aidl/android/hardware/audio/core/ISoundDose.aidl
rename to audio/aidl/android/hardware/audio/core/sounddose/ISoundDose.aidl
index 89fd69b..953ab62 100644
--- a/audio/aidl/android/hardware/audio/core/ISoundDose.aidl
+++ b/audio/aidl/android/hardware/audio/core/sounddose/ISoundDose.aidl
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.hardware.audio.core;
+package android.hardware.audio.core.sounddose;
 
 import android.media.audio.common.AudioDevice;
 
diff --git a/audio/aidl/android/hardware/audio/effect/BassBoost.aidl b/audio/aidl/android/hardware/audio/effect/BassBoost.aidl
index 9e5d8aa..6a94242 100644
--- a/audio/aidl/android/hardware/audio/effect/BassBoost.aidl
+++ b/audio/aidl/android/hardware/audio/effect/BassBoost.aidl
@@ -52,6 +52,10 @@
          */
         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.
          */
@@ -59,23 +63,14 @@
     }
 
     /**
-     * Minimal possible per mille strength.
-     */
-    const int MIN_PER_MILLE_STRENGTH = 0;
-
-    /**
-     * Maximum possible per mille strength.
-     */
-    const int MAX_PER_MILLE_STRENGTH = 1000;
-
-    /**
      * 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 valid range for strength is [0, 1000].
+     * 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/EnvironmentalReverb.aidl b/audio/aidl/android/hardware/audio/effect/EnvironmentalReverb.aidl
index 3df0d27..81c0dde 100644
--- a/audio/aidl/android/hardware/audio/effect/EnvironmentalReverb.aidl
+++ b/audio/aidl/android/hardware/audio/effect/EnvironmentalReverb.aidl
@@ -56,37 +56,109 @@
     }
 
     /**
+     * Minimal possible room level in millibels.
+     */
+    const int MIN_ROOM_LEVEL_MB = -6000;
+    /**
+     * Maximum possible room level in millibels.
+     */
+    const int MAX_ROOM_LEVEL_MB = 0;
+    /**
      * Room level apply to the reverb effect in millibels.
      */
     int roomLevelMb;
+
+    /**
+     * Minimal possible room hf level in millibels.
+     */
+    const int MIN_ROOM_HF_LEVEL_MB = -4000;
+    /**
+     * Maximum possible room hf level in millibels.
+     */
+    const int MAX_ROOM_HF_LEVEL_MB = 0;
     /**
      * Room HF level apply to the reverb effect in millibels.
      */
     int roomHfLevelMb;
+
+    /**
+     * Minimal possible decay time in milliseconds.
+     */
+    const int MIN_DECAY_TIME_MS = 100;
+    /**
+     * Maximum possible decay time in milliseconds.
+     */
+    const int MAX_DECAY_TIME_MS = 20000;
     /**
      * Delay time apply to the reverb effect in milliseconds.
      */
     int decayTimeMs;
+
+    /**
+     * Minimal possible per mille decay hf ratio.
+     */
+    const int MIN_DECAY_HF_RATIO_PM = 100;
+    /**
+     * Maximum possible per mille decay hf ratio.
+     */
+    const int MAX_DECAY_HF_RATIO_PM = 1000;
     /**
      * HF decay ratio in permilles.
      */
     int decayHfRatioPm;
+
+    /**
+     * Minimal possible room level in millibels.
+     */
+    const int MIN_LEVEL_MB = -6000;
+    /**
+     * Maximum possible room level in millibels.
+     */
+    const int MAX_LEVEL_MB = 0;
     /**
      * Reverb level in millibels.
      */
     int levelMb;
+
+    /**
+     * Minimal possible delay time in milliseconds.
+     */
+    const int MIN_DELAY_MS = 0;
+    /**
+     * Maximum possible delay time in milliseconds.
+     */
+    const int MAX_DELAY_MS = 65;
     /**
      * Reverb delay in milliseconds.
      */
     int delayMs;
+
+    /**
+     * Minimal possible per mille diffusion.
+     */
+    const int MIN_DIFFUSION_PM = 0;
+    /**
+     * Maximum possible per mille diffusion.
+     */
+    const int MAX_DIFFUSION_PM = 1000;
     /**
      * Diffusion in permilles.
      */
     int diffusionPm;
+
+    /**
+     * Minimal possible per mille density.
+     */
+    const int MIN_DENSITY_PM = 0;
+    /**
+     * Maximum possible per mille density.
+     */
+    const int MAX_DENSITY_PM = 1000;
     /**
      * Density in permilles.
      */
     int densityPm;
+
     /**
      * Bypass reverb and copy input to output if set to true.
      */
diff --git a/audio/aidl/android/hardware/audio/effect/Virtualizer.aidl b/audio/aidl/android/hardware/audio/effect/Virtualizer.aidl
index 90ec6f8..5f385a6 100644
--- a/audio/aidl/android/hardware/audio/effect/Virtualizer.aidl
+++ b/audio/aidl/android/hardware/audio/effect/Virtualizer.aidl
@@ -53,6 +53,10 @@
          */
         VendorExtension 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 always return EX_ILLEGAL_ARGUMENT.
          */
@@ -60,23 +64,14 @@
     }
 
     /**
-     * Minimal possible per mille strength.
-     */
-    const int MIN_PER_MILLE_STRENGTH = 0;
-
-    /**
-     * Maximum possible per mille strength.
-     */
-    const int MAX_PER_MILLE_STRENGTH = 1000;
-
-    /**
      * The per mille strength of the virtualizer 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 valid range for strength is [0, 1000].
+     * 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/Volume.aidl b/audio/aidl/android/hardware/audio/effect/Volume.aidl
index a9f8371..5033881 100644
--- a/audio/aidl/android/hardware/audio/effect/Volume.aidl
+++ b/audio/aidl/android/hardware/audio/effect/Volume.aidl
@@ -52,25 +52,18 @@
         VendorExtension extension;
 
         /**
-         * Volume strength supported in dB.
+         * Minimum Volume level supported in dB.
          */
-        int maxLevel;
+        int minLevelDb;
+
+        /**
+         * Maximum Volume level supported in dB.
+         */
+        int maxLevelDb;
     }
 
-    // TODO(b/263416041) Move to Capability
     /**
-     * Minimal level in dB.
-     */
-    const int MIN_LEVEL_DB = -9600;
-
-    /**
-     * Maximum level in dB.
-     */
-    const int MAX_LEVEL_DB = 0;
-
-    /**
-    /**
-     * Current level in dB.
+     * Current level in dB with supported minimum and maximum level specified in capability.
      */
     int levelDb;
     /**
diff --git a/audio/aidl/default/Android.bp b/audio/aidl/default/Android.bp
index 8f0b4bd..8cd56c0 100644
--- a/audio/aidl/default/Android.bp
+++ b/audio/aidl/default/Android.bp
@@ -95,6 +95,7 @@
     defaults: [
         "aidlaudioservice_defaults",
         "latest_android_media_audio_common_types_ndk_shared",
+        "latest_android_hardware_audio_core_sounddose_ndk_shared",
         "latest_android_hardware_audio_core_ndk_shared",
     ],
     static_libs: [
@@ -149,6 +150,8 @@
     vintf_fragments: ["android.hardware.audio.effect.service-aidl.xml"],
     defaults: ["aidlaudioeffectservice_defaults"],
     shared_libs: [
+        "libaecsw",
+        "libagcsw",
         "libbassboostsw",
         "libbundleaidl",
         "libdownmixaidl",
@@ -157,6 +160,7 @@
         "libequalizersw",
         "libhapticgeneratoraidl",
         "libloudnessenhanceraidl",
+        "libnssw",
         "libpresetreverbsw",
         "libtinyxml2",
         "libvirtualizersw",
diff --git a/audio/aidl/default/Module.cpp b/audio/aidl/default/Module.cpp
index 4a424bd..b58c562 100644
--- a/audio/aidl/default/Module.cpp
+++ b/audio/aidl/default/Module.cpp
@@ -32,6 +32,7 @@
 
 using aidl::android::hardware::audio::common::SinkMetadata;
 using aidl::android::hardware::audio::common::SourceMetadata;
+using aidl::android::hardware::audio::core::sounddose::ISoundDose;
 using aidl::android::media::audio::common::AudioChannelLayout;
 using aidl::android::media::audio::common::AudioDevice;
 using aidl::android::media::audio::common::AudioFormatDescription;
@@ -603,6 +604,13 @@
     return ndk::ScopedAStatus::ok();
 }
 
+ndk::ScopedAStatus Module::getSupportedPlaybackRateFactors(
+        SupportedPlaybackRateFactors* _aidl_return) {
+    LOG(DEBUG) << __func__;
+    (void)_aidl_return;
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
 ndk::ScopedAStatus Module::setAudioPatch(const AudioPatch& in_requested, AudioPatch* _aidl_return) {
     LOG(DEBUG) << __func__ << ": requested patch " << in_requested.toString();
     if (in_requested.sourcePortConfigIds.empty()) {
@@ -939,7 +947,7 @@
 
 ndk::ScopedAStatus Module::getSoundDose(std::shared_ptr<ISoundDose>* _aidl_return) {
     if (mSoundDose == nullptr) {
-        mSoundDose = ndk::SharedRefBase::make<SoundDose>();
+        mSoundDose = ndk::SharedRefBase::make<sounddose::SoundDose>();
         mSoundDoseBinder = mSoundDose->asBinder();
         AIBinder_setMinSchedulerPolicy(mSoundDoseBinder.get(), SCHED_NORMAL,
                                        ANDROID_PRIORITY_AUDIO);
diff --git a/audio/aidl/default/SoundDose.cpp b/audio/aidl/default/SoundDose.cpp
index 3d222a8..be9f93a 100644
--- a/audio/aidl/default/SoundDose.cpp
+++ b/audio/aidl/default/SoundDose.cpp
@@ -20,7 +20,7 @@
 
 #include <android-base/logging.h>
 
-namespace aidl::android::hardware::audio::core {
+namespace aidl::android::hardware::audio::core::sounddose {
 
 ndk::ScopedAStatus SoundDose::setOutputRs2(float in_rs2ValueDbA) {
     if (in_rs2ValueDbA < MIN_RS2 || in_rs2ValueDbA > DEFAULT_MAX_RS2) {
@@ -54,4 +54,4 @@
     return ndk::ScopedAStatus::ok();
 }
 
-}  // namespace aidl::android::hardware::audio::core
+}  // namespace aidl::android::hardware::audio::core::sounddose
diff --git a/audio/aidl/default/Stream.cpp b/audio/aidl/default/Stream.cpp
index bb123a2..a490a2a 100644
--- a/audio/aidl/default/Stream.cpp
+++ b/audio/aidl/default/Stream.cpp
@@ -27,7 +27,10 @@
 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::AudioDualMonoMode;
+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;
 
@@ -724,4 +727,55 @@
     return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
 }
 
+ndk::ScopedAStatus StreamOut::getAudioDescriptionMixLevel(float* _aidl_return) {
+    LOG(DEBUG) << __func__;
+    (void)_aidl_return;
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ndk::ScopedAStatus StreamOut::setAudioDescriptionMixLevel(float in_leveldB) {
+    LOG(DEBUG) << __func__ << ": description mix level " << in_leveldB;
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ndk::ScopedAStatus StreamOut::getDualMonoMode(AudioDualMonoMode* _aidl_return) {
+    LOG(DEBUG) << __func__;
+    (void)_aidl_return;
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ndk::ScopedAStatus StreamOut::setDualMonoMode(AudioDualMonoMode in_mode) {
+    LOG(DEBUG) << __func__ << ": dual mono mode " << toString(in_mode);
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ndk::ScopedAStatus StreamOut::getRecommendedLatencyModes(
+        std::vector<AudioLatencyMode>* _aidl_return) {
+    LOG(DEBUG) << __func__;
+    (void)_aidl_return;
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ndk::ScopedAStatus StreamOut::setLatencyMode(AudioLatencyMode in_mode) {
+    LOG(DEBUG) << __func__ << ": latency mode " << toString(in_mode);
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ndk::ScopedAStatus StreamOut::getPlaybackRateParameters(AudioPlaybackRate* _aidl_return) {
+    LOG(DEBUG) << __func__;
+    (void)_aidl_return;
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ndk::ScopedAStatus StreamOut::setPlaybackRateParameters(const AudioPlaybackRate& in_playbackRate) {
+    LOG(DEBUG) << __func__ << ": " << in_playbackRate.toString();
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ndk::ScopedAStatus StreamOut::selectPresentation(int32_t in_presentationId, int32_t in_programId) {
+    LOG(DEBUG) << __func__ << ": presentationId " << in_presentationId << ", programId "
+               << in_programId;
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
 }  // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/acousticEchoCanceler/AcousticEchoCancelerSw.h b/audio/aidl/default/acousticEchoCanceler/AcousticEchoCancelerSw.h
index 809812a..5f1bc46 100644
--- a/audio/aidl/default/acousticEchoCanceler/AcousticEchoCancelerSw.h
+++ b/audio/aidl/default/acousticEchoCanceler/AcousticEchoCancelerSw.h
@@ -37,7 +37,7 @@
     int getEchoDelay() const { return mEchoDelayUs; }
 
   private:
-    int mEchoDelayUs;
+    int mEchoDelayUs = 0;
 };
 
 class AcousticEchoCancelerSw final : public EffectImpl {
diff --git a/audio/aidl/default/automaticGainControl/AutomaticGainControlSw.h b/audio/aidl/default/automaticGainControl/AutomaticGainControlSw.h
index e23fec0..2724835 100644
--- a/audio/aidl/default/automaticGainControl/AutomaticGainControlSw.h
+++ b/audio/aidl/default/automaticGainControl/AutomaticGainControlSw.h
@@ -41,9 +41,10 @@
     int getSaturationMargin();
 
   private:
-    int mDigitalGain;
-    AutomaticGainControl::LevelEstimator mLevelEstimator;
-    int mSaturationMargin;
+    int mDigitalGain = 0;
+    AutomaticGainControl::LevelEstimator mLevelEstimator =
+            AutomaticGainControl::LevelEstimator::RMS;
+    int mSaturationMargin = 0;
 };
 
 class AutomaticGainControlSw final : public EffectImpl {
diff --git a/audio/aidl/default/bassboost/BassBoostSw.cpp b/audio/aidl/default/bassboost/BassBoostSw.cpp
index 8e4779d..0c7ebe1 100644
--- a/audio/aidl/default/bassboost/BassBoostSw.cpp
+++ b/audio/aidl/default/bassboost/BassBoostSw.cpp
@@ -62,7 +62,8 @@
 
 const std::string BassBoostSw::kEffectName = "BassBoostSw";
 const bool BassBoostSw::kStrengthSupported = true;
-const BassBoost::Capability BassBoostSw::kCapability = {.strengthSupported = kStrengthSupported};
+const BassBoost::Capability BassBoostSw::kCapability = {.maxStrengthPm = 1000,
+                                                        .strengthSupported = kStrengthSupported};
 const Descriptor BassBoostSw::kDescriptor = {
         .common = {.id = {.type = kBassBoostTypeUUID,
                           .uuid = kBassBoostSwImplUUID,
@@ -171,4 +172,14 @@
     return {STATUS_OK, samples, samples};
 }
 
+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;
+}
+
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/bassboost/BassBoostSw.h b/audio/aidl/default/bassboost/BassBoostSw.h
index 411b9c9..65c01c8 100644
--- a/audio/aidl/default/bassboost/BassBoostSw.h
+++ b/audio/aidl/default/bassboost/BassBoostSw.h
@@ -33,20 +33,11 @@
         LOG(DEBUG) << __func__;
     }
 
-    RetCode setBbStrengthPm(int strength) {
-        if (strength < BassBoost::MIN_PER_MILLE_STRENGTH ||
-            strength > BassBoost::MAX_PER_MILLE_STRENGTH) {
-            LOG(ERROR) << __func__ << " invalid strength: " << strength;
-            return RetCode::ERROR_ILLEGAL_PARAMETER;
-        }
-        // TODO : Add implementation to apply new strength
-        mStrength = strength;
-        return RetCode::SUCCESS;
-    }
+    RetCode setBbStrengthPm(int strength);
     int getBbStrengthPm() const { return mStrength; }
 
   private:
-    int mStrength;
+    int mStrength = 0;
 };
 
 class BassBoostSw final : public EffectImpl {
diff --git a/audio/aidl/default/envReverb/EnvReverbSw.cpp b/audio/aidl/default/envReverb/EnvReverbSw.cpp
index a107064..9d7159a 100644
--- a/audio/aidl/default/envReverb/EnvReverbSw.cpp
+++ b/audio/aidl/default/envReverb/EnvReverbSw.cpp
@@ -60,7 +60,8 @@
 namespace aidl::android::hardware::audio::effect {
 
 const std::string EnvReverbSw::kEffectName = "EnvReverbSw";
-const EnvironmentalReverb::Capability EnvReverbSw::kCapability;
+const EnvironmentalReverb::Capability EnvReverbSw::kCapability = {
+        .maxDecayTimeMs = EnvironmentalReverb::MAX_DECAY_TIME_MS};
 const Descriptor EnvReverbSw::kDescriptor = {
         .common = {.id = {.type = kEnvReverbTypeUUID,
                           .uuid = kEnvReverbSwImplUUID,
@@ -82,16 +83,140 @@
     RETURN_IF(Parameter::Specific::environmentalReverb != specific.getTag(), EX_ILLEGAL_ARGUMENT,
               "EffectNotSupported");
 
-    mSpecificParam = specific.get<Parameter::Specific::environmentalReverb>();
-    LOG(DEBUG) << __func__ << " success with: " << specific.toString();
-    return ndk::ScopedAStatus::ok();
+    auto& erParam = specific.get<Parameter::Specific::environmentalReverb>();
+    auto tag = erParam.getTag();
+
+    switch (tag) {
+        case EnvironmentalReverb::roomLevelMb: {
+            RETURN_IF(mContext->setErRoomLevel(erParam.get<EnvironmentalReverb::roomLevelMb>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setRoomLevelFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        case EnvironmentalReverb::roomHfLevelMb: {
+            RETURN_IF(
+                    mContext->setErRoomHfLevel(erParam.get<EnvironmentalReverb::roomHfLevelMb>()) !=
+                            RetCode::SUCCESS,
+                    EX_ILLEGAL_ARGUMENT, "setRoomHfLevelFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        case EnvironmentalReverb::decayTimeMs: {
+            RETURN_IF(mContext->setErDecayTime(erParam.get<EnvironmentalReverb::decayTimeMs>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setDecayTimeFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        case EnvironmentalReverb::decayHfRatioPm: {
+            RETURN_IF(
+                    mContext->setErDecayHfRatio(
+                            erParam.get<EnvironmentalReverb::decayHfRatioPm>()) != RetCode::SUCCESS,
+                    EX_ILLEGAL_ARGUMENT, "setDecayHfRatioFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        case EnvironmentalReverb::levelMb: {
+            RETURN_IF(mContext->setErLevel(erParam.get<EnvironmentalReverb::levelMb>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setLevelFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        case EnvironmentalReverb::delayMs: {
+            RETURN_IF(mContext->setErDelay(erParam.get<EnvironmentalReverb::delayMs>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setDelayFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        case EnvironmentalReverb::diffusionPm: {
+            RETURN_IF(mContext->setErDiffusion(erParam.get<EnvironmentalReverb::diffusionPm>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setDiffusionFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        case EnvironmentalReverb::densityPm: {
+            RETURN_IF(mContext->setErDensity(erParam.get<EnvironmentalReverb::densityPm>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setDensityFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        case EnvironmentalReverb::bypass: {
+            RETURN_IF(mContext->setErBypass(erParam.get<EnvironmentalReverb::bypass>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setBypassFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        default: {
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+                    EX_ILLEGAL_ARGUMENT, "EnvironmentalReverbTagNotSupported");
+        }
+    }
 }
 
 ndk::ScopedAStatus EnvReverbSw::getParameterSpecific(const Parameter::Id& id,
                                                      Parameter::Specific* specific) {
     auto tag = id.getTag();
     RETURN_IF(Parameter::Id::environmentalReverbTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
-    specific->set<Parameter::Specific::environmentalReverb>(mSpecificParam);
+    auto erId = id.get<Parameter::Id::environmentalReverbTag>();
+    auto erIdTag = erId.getTag();
+    switch (erIdTag) {
+        case EnvironmentalReverb::Id::commonTag:
+            return getParameterEnvironmentalReverb(erId.get<EnvironmentalReverb::Id::commonTag>(),
+                                                   specific);
+        default:
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(erIdTag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+                    EX_ILLEGAL_ARGUMENT, "EnvironmentalReverbTagNotSupported");
+    }
+}
+
+ndk::ScopedAStatus EnvReverbSw::getParameterEnvironmentalReverb(const EnvironmentalReverb::Tag& tag,
+                                                                Parameter::Specific* specific) {
+    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+    EnvironmentalReverb erParam;
+    switch (tag) {
+        case EnvironmentalReverb::roomLevelMb: {
+            erParam.set<EnvironmentalReverb::roomLevelMb>(mContext->getErRoomLevel());
+            break;
+        }
+        case EnvironmentalReverb::roomHfLevelMb: {
+            erParam.set<EnvironmentalReverb::roomHfLevelMb>(mContext->getErRoomHfLevel());
+            break;
+        }
+        case EnvironmentalReverb::decayTimeMs: {
+            erParam.set<EnvironmentalReverb::decayTimeMs>(mContext->getErDecayTime());
+            break;
+        }
+        case EnvironmentalReverb::decayHfRatioPm: {
+            erParam.set<EnvironmentalReverb::decayHfRatioPm>(mContext->getErDecayHfRatio());
+            break;
+        }
+        case EnvironmentalReverb::levelMb: {
+            erParam.set<EnvironmentalReverb::levelMb>(mContext->getErLevel());
+            break;
+        }
+        case EnvironmentalReverb::delayMs: {
+            erParam.set<EnvironmentalReverb::delayMs>(mContext->getErDelay());
+            break;
+        }
+        case EnvironmentalReverb::diffusionPm: {
+            erParam.set<EnvironmentalReverb::diffusionPm>(mContext->getErDiffusion());
+            break;
+        }
+        case EnvironmentalReverb::densityPm: {
+            erParam.set<EnvironmentalReverb::densityPm>(mContext->getErDensity());
+            break;
+        }
+        case EnvironmentalReverb::bypass: {
+            erParam.set<EnvironmentalReverb::bypass>(mContext->getErBypass());
+            break;
+        }
+        default: {
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+                    EX_ILLEGAL_ARGUMENT, "EnvironmentalReverbTagNotSupported");
+        }
+    }
+
+    specific->set<Parameter::Specific::environmentalReverb>(erParam);
     return ndk::ScopedAStatus::ok();
 }
 
diff --git a/audio/aidl/default/envReverb/EnvReverbSw.h b/audio/aidl/default/envReverb/EnvReverbSw.h
index b8761a6..f521215 100644
--- a/audio/aidl/default/envReverb/EnvReverbSw.h
+++ b/audio/aidl/default/envReverb/EnvReverbSw.h
@@ -32,7 +32,120 @@
         : EffectContext(statusDepth, common) {
         LOG(DEBUG) << __func__;
     }
-    // TODO: add specific context here
+
+    RetCode setErRoomLevel(int roomLevel) {
+        if (roomLevel < EnvironmentalReverb::MIN_ROOM_LEVEL_MB ||
+            roomLevel > EnvironmentalReverb::MAX_ROOM_LEVEL_MB) {
+            LOG(ERROR) << __func__ << " invalid roomLevel: " << roomLevel;
+            return RetCode::ERROR_ILLEGAL_PARAMETER;
+        }
+        // TODO : Add implementation to apply new room level
+        mRoomLevel = roomLevel;
+        return RetCode::SUCCESS;
+    }
+    int getErRoomLevel() const { return mRoomLevel; }
+
+    RetCode setErRoomHfLevel(int roomHfLevel) {
+        if (roomHfLevel < EnvironmentalReverb::MIN_ROOM_HF_LEVEL_MB ||
+            roomHfLevel > EnvironmentalReverb::MAX_ROOM_HF_LEVEL_MB) {
+            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;
+    }
+    int getErRoomHfLevel() const { return mRoomHfLevel; }
+
+    RetCode setErDecayTime(int decayTime) {
+        if (decayTime < EnvironmentalReverb::MIN_DECAY_TIME_MS ||
+            decayTime > EnvironmentalReverb::MAX_DECAY_TIME_MS) {
+            LOG(ERROR) << __func__ << " invalid decayTime: " << decayTime;
+            return RetCode::ERROR_ILLEGAL_PARAMETER;
+        }
+        // TODO : Add implementation to apply new decay time
+        mDecayTime = decayTime;
+        return RetCode::SUCCESS;
+    }
+    int getErDecayTime() const { return mDecayTime; }
+
+    RetCode setErDecayHfRatio(int decayHfRatio) {
+        if (decayHfRatio < EnvironmentalReverb::MIN_DECAY_HF_RATIO_PM ||
+            decayHfRatio > EnvironmentalReverb::MAX_DECAY_HF_RATIO_PM) {
+            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;
+    }
+    int getErDecayHfRatio() const { return mDecayHfRatio; }
+
+    RetCode setErLevel(int level) {
+        if (level < EnvironmentalReverb::MIN_LEVEL_MB ||
+            level > EnvironmentalReverb::MAX_LEVEL_MB) {
+            LOG(ERROR) << __func__ << " invalid level: " << level;
+            return RetCode::ERROR_ILLEGAL_PARAMETER;
+        }
+        // TODO : Add implementation to apply new level
+        mLevel = level;
+        return RetCode::SUCCESS;
+    }
+    int getErLevel() const { return mLevel; }
+
+    RetCode setErDelay(int delay) {
+        if (delay < EnvironmentalReverb::MIN_DELAY_MS ||
+            delay > EnvironmentalReverb::MAX_DELAY_MS) {
+            LOG(ERROR) << __func__ << " invalid delay: " << delay;
+            return RetCode::ERROR_ILLEGAL_PARAMETER;
+        }
+        // TODO : Add implementation to apply new delay
+        mDelay = delay;
+        return RetCode::SUCCESS;
+    }
+    int getErDelay() const { return mDelay; }
+
+    RetCode setErDiffusion(int diffusion) {
+        if (diffusion < EnvironmentalReverb::MIN_DIFFUSION_PM ||
+            diffusion > EnvironmentalReverb::MAX_DIFFUSION_PM) {
+            LOG(ERROR) << __func__ << " invalid diffusion: " << diffusion;
+            return RetCode::ERROR_ILLEGAL_PARAMETER;
+        }
+        // TODO : Add implementation to apply new diffusion
+        mDiffusion = diffusion;
+        return RetCode::SUCCESS;
+    }
+    int getErDiffusion() const { return mDiffusion; }
+
+    RetCode setErDensity(int density) {
+        if (density < EnvironmentalReverb::MIN_DENSITY_PM ||
+            density > EnvironmentalReverb::MAX_DENSITY_PM) {
+            LOG(ERROR) << __func__ << " invalid density: " << density;
+            return RetCode::ERROR_ILLEGAL_PARAMETER;
+        }
+        // TODO : Add implementation to apply new density
+        mDensity = density;
+        return RetCode::SUCCESS;
+    }
+    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; }
+
+  private:
+    int mRoomLevel = EnvironmentalReverb::MIN_ROOM_LEVEL_MB;       // Default room level
+    int mRoomHfLevel = EnvironmentalReverb::MAX_ROOM_HF_LEVEL_MB;  // Default room hf level
+    int mDecayTime = 1000;                                         // Default decay time
+    int mDecayHfRatio = 500;                                       // Default decay hf ratio
+    int mLevel = EnvironmentalReverb::MIN_LEVEL_MB;                // Default level
+    int mDelay = 40;                                               // Default delay
+    int mDiffusion = EnvironmentalReverb::MAX_DIFFUSION_PM;        // Default diffusion
+    int mDensity = EnvironmentalReverb::MAX_DENSITY_PM;            // Default density
+    bool mBypass = false;                                          // Default bypass
 };
 
 class EnvReverbSw final : public EffectImpl {
@@ -60,7 +173,7 @@
 
   private:
     std::shared_ptr<EnvReverbSwContext> mContext;
-    /* parameters */
-    EnvironmentalReverb mSpecificParam;
+    ndk::ScopedAStatus getParameterEnvironmentalReverb(const EnvironmentalReverb::Tag& tag,
+                                                       Parameter::Specific* specific);
 };
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/include/core-impl/Module.h b/audio/aidl/default/include/core-impl/Module.h
index aa05d2a..faca61e 100644
--- a/audio/aidl/default/include/core-impl/Module.h
+++ b/audio/aidl/default/include/core-impl/Module.h
@@ -66,6 +66,8 @@
                     in_args,
             ::aidl::android::hardware::audio::core::IModule::OpenOutputStreamReturn* _aidl_return)
             override;
+    ndk::ScopedAStatus getSupportedPlaybackRateFactors(
+            SupportedPlaybackRateFactors* _aidl_return) override;
     ndk::ScopedAStatus setAudioPatch(const AudioPatch& in_requested,
                                      AudioPatch* _aidl_return) override;
     ndk::ScopedAStatus setAudioPortConfig(
@@ -86,7 +88,7 @@
     ndk::ScopedAStatus updateScreenRotation(
             ::aidl::android::hardware::audio::core::IModule::ScreenRotation in_rotation) override;
     ndk::ScopedAStatus updateScreenState(bool in_isTurnedOn) override;
-    ndk::ScopedAStatus getSoundDose(std::shared_ptr<ISoundDose>* _aidl_return) override;
+    ndk::ScopedAStatus getSoundDose(std::shared_ptr<sounddose::ISoundDose>* _aidl_return) override;
     ndk::ScopedAStatus generateHwAvSyncId(int32_t* _aidl_return) override;
     ndk::ScopedAStatus getVendorParameters(const std::vector<std::string>& in_ids,
                                            std::vector<VendorParameter>* _aidl_return) override;
@@ -138,7 +140,7 @@
     bool mMasterMute = false;
     float mMasterVolume = 1.0f;
     bool mMicMute = false;
-    std::shared_ptr<ISoundDose> mSoundDose;
+    std::shared_ptr<sounddose::ISoundDose> mSoundDose;
     ndk::SpAIBinder mSoundDoseBinder;
 };
 
diff --git a/audio/aidl/default/include/core-impl/SoundDose.h b/audio/aidl/default/include/core-impl/SoundDose.h
index 54a6cbf..306aa04 100644
--- a/audio/aidl/default/include/core-impl/SoundDose.h
+++ b/audio/aidl/default/include/core-impl/SoundDose.h
@@ -18,12 +18,12 @@
 
 #include <mutex>
 
-#include <aidl/android/hardware/audio/core/BnSoundDose.h>
+#include <aidl/android/hardware/audio/core/sounddose/BnSoundDose.h>
 #include <aidl/android/media/audio/common/AudioDevice.h>
 
 using aidl::android::media::audio::common::AudioDevice;
 
-namespace aidl::android::hardware::audio::core {
+namespace aidl::android::hardware::audio::core::sounddose {
 
 class SoundDose : public BnSoundDose {
   public:
@@ -39,4 +39,4 @@
     float mRs2Value;
 };
 
-}  // namespace aidl::android::hardware::audio::core
+}  // namespace aidl::android::hardware::audio::core::sounddose
diff --git a/audio/aidl/default/include/core-impl/Stream.h b/audio/aidl/default/include/core-impl/Stream.h
index a5d240f..5abd4de 100644
--- a/audio/aidl/default/include/core-impl/Stream.h
+++ b/audio/aidl/default/include/core-impl/Stream.h
@@ -367,6 +367,23 @@
     }
     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;
+    ndk::ScopedAStatus setAudioDescriptionMixLevel(float in_leveldB) override;
+    ndk::ScopedAStatus getDualMonoMode(
+            ::aidl::android::media::audio::common::AudioDualMonoMode* _aidl_return) override;
+    ndk::ScopedAStatus setDualMonoMode(
+            ::aidl::android::media::audio::common::AudioDualMonoMode in_mode) override;
+    ndk::ScopedAStatus getRecommendedLatencyModes(
+            std::vector<::aidl::android::media::audio::common::AudioLatencyMode>* _aidl_return)
+            override;
+    ndk::ScopedAStatus setLatencyMode(
+            ::aidl::android::media::audio::common::AudioLatencyMode in_mode) override;
+    ndk::ScopedAStatus getPlaybackRateParameters(
+            ::aidl::android::media::audio::common::AudioPlaybackRate* _aidl_return) override;
+    ndk::ScopedAStatus setPlaybackRateParameters(
+            const ::aidl::android::media::audio::common::AudioPlaybackRate& in_playbackRate)
+            override;
+    ndk::ScopedAStatus selectPresentation(int32_t in_presentationId, int32_t in_programId) override;
 
   public:
     static ndk::ScopedAStatus createInstance(
diff --git a/audio/aidl/default/noiseSuppression/NoiseSuppressionSw.h b/audio/aidl/default/noiseSuppression/NoiseSuppressionSw.h
index 0c03038..f39d8e5 100644
--- a/audio/aidl/default/noiseSuppression/NoiseSuppressionSw.h
+++ b/audio/aidl/default/noiseSuppression/NoiseSuppressionSw.h
@@ -37,7 +37,7 @@
     NoiseSuppression::Level getLevel();
 
   private:
-    NoiseSuppression::Level mLevel;
+    NoiseSuppression::Level mLevel = NoiseSuppression::Level::LOW;
 };
 
 class NoiseSuppressionSw final : public EffectImpl {
diff --git a/audio/aidl/default/presetReverb/PresetReverbSw.cpp b/audio/aidl/default/presetReverb/PresetReverbSw.cpp
index 1b9d614..d038596 100644
--- a/audio/aidl/default/presetReverb/PresetReverbSw.cpp
+++ b/audio/aidl/default/presetReverb/PresetReverbSw.cpp
@@ -21,6 +21,7 @@
 #include <unordered_set>
 
 #include <android-base/logging.h>
+#include <android/binder_enums.h>
 #include <fmq/AidlMessageQueue.h>
 
 #include "PresetReverbSw.h"
@@ -60,7 +61,13 @@
 namespace aidl::android::hardware::audio::effect {
 
 const std::string PresetReverbSw::kEffectName = "PresetReverbSw";
-const PresetReverb::Capability PresetReverbSw::kCapability;
+
+const std::vector<PresetReverb::Presets> kSupportedPresets{
+        ndk::enum_range<PresetReverb::Presets>().begin(),
+        ndk::enum_range<PresetReverb::Presets>().end()};
+
+const PresetReverb::Capability PresetReverbSw::kCapability = {.supportedPresets =
+                                                                      kSupportedPresets};
 const Descriptor PresetReverbSw::kDescriptor = {
         .common = {.id = {.type = kPresetReverbTypeUUID,
                           .uuid = kPresetReverbSwImplUUID,
@@ -82,16 +89,59 @@
     RETURN_IF(Parameter::Specific::presetReverb != specific.getTag(), EX_ILLEGAL_ARGUMENT,
               "EffectNotSupported");
 
-    mSpecificParam = specific.get<Parameter::Specific::presetReverb>();
-    LOG(DEBUG) << __func__ << " success with: " << specific.toString();
-    return ndk::ScopedAStatus::ok();
+    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+
+    auto& prParam = specific.get<Parameter::Specific::presetReverb>();
+    auto tag = prParam.getTag();
+
+    switch (tag) {
+        case PresetReverb::preset: {
+            RETURN_IF(
+                    mContext->setPRPreset(prParam.get<PresetReverb::preset>()) != RetCode::SUCCESS,
+                    EX_ILLEGAL_ARGUMENT, "setPresetFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        default: {
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "PresetReverbTagNotSupported");
+        }
+    }
 }
 
 ndk::ScopedAStatus PresetReverbSw::getParameterSpecific(const Parameter::Id& id,
                                                         Parameter::Specific* specific) {
     auto tag = id.getTag();
     RETURN_IF(Parameter::Id::presetReverbTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
-    specific->set<Parameter::Specific::presetReverb>(mSpecificParam);
+    auto prId = id.get<Parameter::Id::presetReverbTag>();
+    auto prIdTag = prId.getTag();
+    switch (prIdTag) {
+        case PresetReverb::Id::commonTag:
+            return getParameterPresetReverb(prId.get<PresetReverb::Id::commonTag>(), specific);
+        default:
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "PresetReverbTagNotSupported");
+    }
+}
+
+ndk::ScopedAStatus PresetReverbSw::getParameterPresetReverb(const PresetReverb::Tag& tag,
+                                                            Parameter::Specific* specific) {
+    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+    PresetReverb prParam;
+    switch (tag) {
+        case PresetReverb::preset: {
+            prParam.set<PresetReverb::preset>(mContext->getPRPreset());
+            break;
+        }
+        default: {
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "PresetReverbTagNotSupported");
+        }
+    }
+
+    specific->set<Parameter::Specific::presetReverb>(prParam);
     return ndk::ScopedAStatus::ok();
 }
 
diff --git a/audio/aidl/default/presetReverb/PresetReverbSw.h b/audio/aidl/default/presetReverb/PresetReverbSw.h
index 43ed36e..eb1d80a 100644
--- a/audio/aidl/default/presetReverb/PresetReverbSw.h
+++ b/audio/aidl/default/presetReverb/PresetReverbSw.h
@@ -32,7 +32,15 @@
         : EffectContext(statusDepth, common) {
         LOG(DEBUG) << __func__;
     }
-    // TODO: add specific context here
+    RetCode setPRPreset(PresetReverb::Presets preset) {
+        // TODO : Add implementation to modify Presets
+        mPreset = preset;
+        return RetCode::SUCCESS;
+    }
+    PresetReverb::Presets getPRPreset() const { return mPreset; }
+
+  private:
+    PresetReverb::Presets mPreset = PresetReverb::Presets::NONE;
 };
 
 class PresetReverbSw final : public EffectImpl {
@@ -60,7 +68,8 @@
 
   private:
     std::shared_ptr<PresetReverbSwContext> mContext;
-    /* parameters */
-    PresetReverb mSpecificParam;
+
+    ndk::ScopedAStatus getParameterPresetReverb(const PresetReverb::Tag& tag,
+                                                Parameter::Specific* specific);
 };
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/virtualizer/VirtualizerSw.cpp b/audio/aidl/default/virtualizer/VirtualizerSw.cpp
index f4aa67c..cc51937 100644
--- a/audio/aidl/default/virtualizer/VirtualizerSw.cpp
+++ b/audio/aidl/default/virtualizer/VirtualizerSw.cpp
@@ -61,8 +61,8 @@
 
 const std::string VirtualizerSw::kEffectName = "VirtualizerSw";
 const bool VirtualizerSw::kStrengthSupported = true;
-const Virtualizer::Capability VirtualizerSw::kCapability = {.strengthSupported =
-                                                                    kStrengthSupported};
+const Virtualizer::Capability VirtualizerSw::kCapability = {
+        .maxStrengthPm = 1000, .strengthSupported = kStrengthSupported};
 const Descriptor VirtualizerSw::kDescriptor = {
         .common = {.id = {.type = kVirtualizerTypeUUID,
                           .uuid = kVirtualizerSwImplUUID,
@@ -172,4 +172,14 @@
     return {STATUS_OK, samples, samples};
 }
 
+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;
+}
+
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/virtualizer/VirtualizerSw.h b/audio/aidl/default/virtualizer/VirtualizerSw.h
index 05974a8..0f294cd 100644
--- a/audio/aidl/default/virtualizer/VirtualizerSw.h
+++ b/audio/aidl/default/virtualizer/VirtualizerSw.h
@@ -32,20 +32,11 @@
         : EffectContext(statusDepth, common) {
         LOG(DEBUG) << __func__;
     }
-    RetCode setVrStrength(int strength) {
-        if (strength < Virtualizer::MIN_PER_MILLE_STRENGTH ||
-            strength > Virtualizer::MAX_PER_MILLE_STRENGTH) {
-            LOG(ERROR) << __func__ << " invalid strength " << strength;
-            return RetCode::ERROR_ILLEGAL_PARAMETER;
-        }
-        // TODO : Add implementation to apply new strength
-        mStrength = strength;
-        return RetCode::SUCCESS;
-    }
+    RetCode setVrStrength(int strength);
     int getVrStrength() const { return mStrength; }
 
   private:
-    int mStrength;
+    int mStrength = 0;
 };
 
 class VirtualizerSw final : public EffectImpl {
diff --git a/audio/aidl/default/visualizer/VisualizerSw.cpp b/audio/aidl/default/visualizer/VisualizerSw.cpp
index 735180e..614988c 100644
--- a/audio/aidl/default/visualizer/VisualizerSw.cpp
+++ b/audio/aidl/default/visualizer/VisualizerSw.cpp
@@ -241,4 +241,37 @@
     return {STATUS_OK, samples, samples};
 }
 
+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;
+}
+
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/visualizer/VisualizerSw.h b/audio/aidl/default/visualizer/VisualizerSw.h
index edaf123..e9d46d7 100644
--- a/audio/aidl/default/visualizer/VisualizerSw.h
+++ b/audio/aidl/default/visualizer/VisualizerSw.h
@@ -38,40 +38,16 @@
         fill(mCaptureSampleBuffer.begin(), mCaptureSampleBuffer.end(), 0x80);
     }
 
-    RetCode setVsCaptureSize(int captureSize) {
-        if (captureSize < kMinCaptureSize || captureSize > kMaxCaptureSize) {
-            LOG(ERROR) << __func__ << " invalid captureSize " << captureSize;
-            return RetCode::ERROR_ILLEGAL_PARAMETER;
-        }
-        // TODO : Add implementation to apply new captureSize
-        mCaptureSize = captureSize;
-        return RetCode::SUCCESS;
-    }
+    RetCode setVsCaptureSize(int captureSize);
     int getVsCaptureSize() const { return mCaptureSize; }
 
-    RetCode setVsScalingMode(Visualizer::ScalingMode scalingMode) {
-        // TODO : Add implementation to apply new scalingMode
-        mScalingMode = scalingMode;
-        return RetCode::SUCCESS;
-    }
+    RetCode setVsScalingMode(Visualizer::ScalingMode scalingMode);
     Visualizer::ScalingMode getVsScalingMode() const { return mScalingMode; }
 
-    RetCode setVsMeasurementMode(Visualizer::MeasurementMode measurementMode) {
-        // TODO : Add implementation to apply new measurementMode
-        mMeasurementMode = measurementMode;
-        return RetCode::SUCCESS;
-    }
+    RetCode setVsMeasurementMode(Visualizer::MeasurementMode measurementMode);
     Visualizer::MeasurementMode getVsMeasurementMode() const { return mMeasurementMode; }
 
-    RetCode setVsLatency(int latency) {
-        if (latency < 0 || latency > kMaxLatencyMs) {
-            LOG(ERROR) << __func__ << " invalid latency " << latency;
-            return RetCode::ERROR_ILLEGAL_PARAMETER;
-        }
-        // TODO : Add implementation to modify latency
-        mLatency = latency;
-        return RetCode::SUCCESS;
-    }
+    RetCode setVsLatency(int latency);
 
     Visualizer::GetOnlyParameters::Measurement getVsMeasurement() const { return mMeasurement; }
     std::vector<uint8_t> getVsCaptureSampleBuffer() const { return mCaptureSampleBuffer; }
@@ -80,7 +56,7 @@
     int mCaptureSize = kMaxCaptureSize;
     Visualizer::ScalingMode mScalingMode = Visualizer::ScalingMode::NORMALIZED;
     Visualizer::MeasurementMode mMeasurementMode = Visualizer::MeasurementMode::NONE;
-    int mLatency;
+    int mLatency = 0;
     const Visualizer::GetOnlyParameters::Measurement mMeasurement = {0, 0};
     std::vector<uint8_t> mCaptureSampleBuffer;
 };
diff --git a/audio/aidl/default/volume/VolumeSw.cpp b/audio/aidl/default/volume/VolumeSw.cpp
index 24e1e1d..64301dc 100644
--- a/audio/aidl/default/volume/VolumeSw.cpp
+++ b/audio/aidl/default/volume/VolumeSw.cpp
@@ -60,7 +60,7 @@
 namespace aidl::android::hardware::audio::effect {
 
 const std::string VolumeSw::kEffectName = "VolumeSw";
-const Volume::Capability VolumeSw::kCapability = {.maxLevel = Volume::MAX_LEVEL_DB};
+const Volume::Capability VolumeSw::kCapability = {.minLevelDb = -9600, .maxLevelDb = 0};
 const Descriptor VolumeSw::kDescriptor = {
         .common = {.id = {.type = kVolumeTypeUUID,
                           .uuid = kVolumeSwImplUUID,
@@ -176,4 +176,20 @@
     return {STATUS_OK, samples, samples};
 }
 
+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;
+}
+
+RetCode VolumeSwContext::setVolMute(bool mute) {
+    // TODO : Add implementation to modify mute
+    mMute = mute;
+    return RetCode::SUCCESS;
+}
+
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/volume/VolumeSw.h b/audio/aidl/default/volume/VolumeSw.h
index a101c59..b6f6077 100644
--- a/audio/aidl/default/volume/VolumeSw.h
+++ b/audio/aidl/default/volume/VolumeSw.h
@@ -33,23 +33,11 @@
         LOG(DEBUG) << __func__;
     }
 
-    RetCode setVolLevel(int level) {
-        if (level < Volume::MIN_LEVEL_DB || level > Volume::MAX_LEVEL_DB) {
-            LOG(ERROR) << __func__ << " invalid level " << level;
-            return RetCode::ERROR_ILLEGAL_PARAMETER;
-        }
-        // TODO : Add implementation to apply new level
-        mLevel = level;
-        return RetCode::SUCCESS;
-    }
+    RetCode setVolLevel(int level);
 
     int getVolLevel() const { return mLevel; }
 
-    RetCode setVolMute(bool mute) {
-        // TODO : Add implementation to modify mute
-        mMute = mute;
-        return RetCode::SUCCESS;
-    }
+    RetCode setVolMute(bool mute);
 
     bool getVolMute() const { return mMute; }
 
diff --git a/audio/aidl/sounddose/aidl_api/android.hardware.audio.sounddose/current/android/hardware/audio/sounddose/ISoundDoseFactory.aidl b/audio/aidl/sounddose/aidl_api/android.hardware.audio.sounddose/current/android/hardware/audio/sounddose/ISoundDoseFactory.aidl
index 7dda011..148720c 100644
--- a/audio/aidl/sounddose/aidl_api/android.hardware.audio.sounddose/current/android/hardware/audio/sounddose/ISoundDoseFactory.aidl
+++ b/audio/aidl/sounddose/aidl_api/android.hardware.audio.sounddose/current/android/hardware/audio/sounddose/ISoundDoseFactory.aidl
@@ -34,5 +34,5 @@
 package android.hardware.audio.sounddose;
 @VintfStability
 interface ISoundDoseFactory {
-  @nullable android.hardware.audio.core.ISoundDose getSoundDose(in @utf8InCpp String module);
+  @nullable android.hardware.audio.core.sounddose.ISoundDose getSoundDose(in @utf8InCpp String module);
 }
diff --git a/audio/aidl/sounddose/android/hardware/audio/sounddose/ISoundDoseFactory.aidl b/audio/aidl/sounddose/android/hardware/audio/sounddose/ISoundDoseFactory.aidl
index 3487237..4079fe8 100644
--- a/audio/aidl/sounddose/android/hardware/audio/sounddose/ISoundDoseFactory.aidl
+++ b/audio/aidl/sounddose/android/hardware/audio/sounddose/ISoundDoseFactory.aidl
@@ -16,7 +16,7 @@
 
 package android.hardware.audio.sounddose;
 
-import android.hardware.audio.core.ISoundDose;
+import android.hardware.audio.core.sounddose.ISoundDose;
 
 /**
  * This interface is used to provide an easy way to implement the ISoundDose interface
diff --git a/audio/aidl/sounddose/default/SoundDoseFactory.cpp b/audio/aidl/sounddose/default/SoundDoseFactory.cpp
index 50796d0..83a592b 100644
--- a/audio/aidl/sounddose/default/SoundDoseFactory.cpp
+++ b/audio/aidl/sounddose/default/SoundDoseFactory.cpp
@@ -23,7 +23,7 @@
 
 namespace aidl::android::hardware::audio::sounddose {
 
-using ::aidl::android::hardware::audio::core::SoundDose;
+using ::aidl::android::hardware::audio::core::sounddose::SoundDose;
 
 ndk::ScopedAStatus SoundDoseFactory::getSoundDose(const std::string& in_module,
                                                   std::shared_ptr<ISoundDose>* _aidl_return) {
diff --git a/audio/aidl/sounddose/default/include/SoundDoseFactory.h b/audio/aidl/sounddose/default/include/SoundDoseFactory.h
index 4cf3277..ced4291 100644
--- a/audio/aidl/sounddose/default/include/SoundDoseFactory.h
+++ b/audio/aidl/sounddose/default/include/SoundDoseFactory.h
@@ -16,7 +16,7 @@
 
 #pragma once
 
-#include <aidl/android/hardware/audio/core/ISoundDose.h>
+#include <aidl/android/hardware/audio/core/sounddose/ISoundDose.h>
 #include <aidl/android/hardware/audio/sounddose/BnSoundDoseFactory.h>
 #include <android/binder_interface_utils.h>
 
@@ -24,7 +24,7 @@
 
 namespace aidl::android::hardware::audio::sounddose {
 
-using ::aidl::android::hardware::audio::core::ISoundDose;
+using ::aidl::android::hardware::audio::core::sounddose::ISoundDose;
 
 class SoundDoseFactory : public BnSoundDoseFactory {
   public:
diff --git a/audio/aidl/sounddose/vts/VtsHalSoundDoseFactoryTargetTest.cpp b/audio/aidl/sounddose/vts/VtsHalSoundDoseFactoryTargetTest.cpp
index 7448c1f..df35bae 100644
--- a/audio/aidl/sounddose/vts/VtsHalSoundDoseFactoryTargetTest.cpp
+++ b/audio/aidl/sounddose/vts/VtsHalSoundDoseFactoryTargetTest.cpp
@@ -47,7 +47,7 @@
 
 using namespace android;
 
-using aidl::android::hardware::audio::core::ISoundDose;
+using aidl::android::hardware::audio::core::sounddose::ISoundDose;
 using aidl::android::hardware::audio::sounddose::ISoundDoseFactory;
 
 class SoundDoseFactory : public testing::TestWithParam<std::string> {
diff --git a/audio/aidl/vts/Android.bp b/audio/aidl/vts/Android.bp
index 2b4692e..becdf1b 100644
--- a/audio/aidl/vts/Android.bp
+++ b/audio/aidl/vts/Android.bp
@@ -44,6 +44,7 @@
     defaults: [
         "VtsHalAudioTargetTestDefaults",
         "latest_android_hardware_audio_core_ndk_static",
+        "latest_android_hardware_audio_core_sounddose_ndk_static",
     ],
     shared_libs: [
         "libcutils",
@@ -80,6 +81,12 @@
 }
 
 cc_test {
+    name: "VtsHalEnvironmentalReverbTargetTest",
+    defaults: ["VtsHalAudioTargetTestDefaults"],
+    srcs: ["VtsHalEnvironmentalReverbTargetTest.cpp"],
+}
+
+cc_test {
     name: "VtsHalEqualizerTargetTest",
     defaults: ["VtsHalAudioTargetTestDefaults"],
     srcs: ["VtsHalEqualizerTargetTest.cpp"],
@@ -98,6 +105,12 @@
 }
 
 cc_test {
+    name: "VtsHalPresetReverbTargetTest",
+    defaults: ["VtsHalAudioTargetTestDefaults"],
+    srcs: ["VtsHalPresetReverbTargetTest.cpp"],
+}
+
+cc_test {
     name: "VtsHalVirtualizerTargetTest",
     defaults: ["VtsHalAudioTargetTestDefaults"],
     srcs: ["VtsHalVirtualizerTargetTest.cpp"],
diff --git a/audio/aidl/vts/VtsHalAECTargetTest.cpp b/audio/aidl/vts/VtsHalAECTargetTest.cpp
index eb92ef8..c3427c8 100644
--- a/audio/aidl/vts/VtsHalAECTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAECTargetTest.cpp
@@ -17,6 +17,7 @@
 #include <Utils.h>
 #include <aidl/Vintf.h>
 #include <algorithm>
+#include <string>
 #include <unordered_set>
 
 #define LOG_TAG "VtsHalAECParamTest"
@@ -70,10 +71,6 @@
         return specific;
     }
 
-    static const std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kFactoryDescList;
-    static const std::unordered_set<int> kEchoDelayValues;
-    static const std::unordered_set<bool> kMobileModeValues;
-
     static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
     std::shared_ptr<IFactory> mFactory;
     std::shared_ptr<IEffect> mEffect;
@@ -157,8 +154,10 @@
     }
 
     static std::unordered_set<int> getEchoDelayTestValues() {
+        auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
+                                                                     kAcousticEchoCancelerTypeUUID);
         const auto max = std::max_element(
-                kFactoryDescList.begin(), kFactoryDescList.end(),
+                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>()
@@ -166,26 +165,20 @@
                            b.second.capability.get<Capability::acousticEchoCanceler>()
                                    .maxEchoDelayUs;
                 });
-        if (max == kFactoryDescList.end()) {
+        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:
     std::vector<std::pair<AcousticEchoCanceler::Tag, AcousticEchoCanceler>> mTags;
     void CleanUp() { mTags.clear(); }
 };
 
-const std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> AECParamTest::kFactoryDescList =
-        EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
-                                                     kAcousticEchoCancelerTypeUUID);
-const std::unordered_set<int> AECParamTest::kEchoDelayValues =
-        AECParamTest::getEchoDelayTestValues();
-const std::unordered_set<bool> AECParamTest::kMobileModeValues = {true, false};
-
 TEST_P(AECParamTest, SetAndGetEchoDelay) {
     EXPECT_NO_FATAL_FAILURE(addEchoDelayParam(mEchoDelay));
     SetAndGetParameters();
@@ -196,20 +189,24 @@
     SetAndGetParameters();
 }
 
-INSTANTIATE_TEST_SUITE_P(AECParamTest, AECParamTest,
-                         ::testing::Combine(testing::ValuesIn(AECParamTest::kFactoryDescList),
-                                            testing::ValuesIn(AECParamTest::kEchoDelayValues),
-                                            testing::ValuesIn(AECParamTest::kMobileModeValues)),
-                         [](const testing::TestParamInfo<AECParamTest::ParamType>& info) {
-                             auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
-                             std::string name = "Implementor_" + descriptor.common.implementor +
-                                                "_name_" + descriptor.common.name + "_UUID_" +
-                                                descriptor.common.id.uuid.toString();
-                             std::replace_if(
-                                     name.begin(), name.end(),
-                                     [](const char c) { return !std::isalnum(c); }, '_');
-                             return name;
-                         });
+INSTANTIATE_TEST_SUITE_P(
+        AECParamTest, AECParamTest,
+        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+                                   IFactory::descriptor, kAcousticEchoCancelerTypeUUID)),
+                           testing::ValuesIn(AECParamTest::getEchoDelayTestValues()),
+                           testing::ValuesIn(AECParamTest::getMobileModeValues())),
+        [](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));
+            std::string mobileMode = std::get<PARAM_MOBILE_MODE>(info.param) ? "true" : "false";
+            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+                               descriptor.common.name + "_UUID_" +
+                               descriptor.common.id.uuid.toString() + "_EchoDelay_" + echoDelay +
+                               "_MobileMode_" + mobileMode;
+            std::replace_if(
+                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+            return name;
+        });
 
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AECParamTest);
 
diff --git a/audio/aidl/vts/VtsHalAGCTargetTest.cpp b/audio/aidl/vts/VtsHalAGCTargetTest.cpp
index 484cc84..3448ae2 100644
--- a/audio/aidl/vts/VtsHalAGCTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAGCTargetTest.cpp
@@ -79,11 +79,6 @@
     }
 
     static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
-    static const std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kFactoryDescList;
-    static const std::unordered_set<int> kDigitalGainValues;
-    static const std::unordered_set<int> kSaturationMarginValues;
-    static const std::unordered_set<AutomaticGainControl::LevelEstimator> kLevelEstimatorValues;
-
     std::shared_ptr<IFactory> mFactory;
     std::shared_ptr<IEffect> mEffect;
     Descriptor mDescriptor;
@@ -161,8 +156,10 @@
         }
     }
     static std::unordered_set<int> getDigitalGainValues() {
+        auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
+                                                                     kAutomaticGainControlTypeUUID);
         const auto max = std::max_element(
-                kFactoryDescList.begin(), kFactoryDescList.end(),
+                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>()
@@ -170,7 +167,7 @@
                            b.second.capability.get<Capability::automaticGainControl>()
                                    .maxFixedDigitalGainMb;
                 });
-        if (max == kFactoryDescList.end()) {
+        if (max == descList.end()) {
             return {0};
         }
         int maxGain = max->second.capability.get<Capability::automaticGainControl>()
@@ -178,8 +175,10 @@
         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(
-                kFactoryDescList.begin(), kFactoryDescList.end(),
+                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>()
@@ -187,30 +186,23 @@
                            b.second.capability.get<Capability::automaticGainControl>()
                                    .maxSaturationMarginMb;
                 });
-        if (max == kFactoryDescList.end()) {
+        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(); }
 };
 
-const std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> AGCParamTest::kFactoryDescList =
-        EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
-                                                     kAutomaticGainControlTypeUUID);
-const std::unordered_set<int> AGCParamTest::kDigitalGainValues =
-        AGCParamTest::getDigitalGainValues();
-const std::unordered_set<int> AGCParamTest::kSaturationMarginValues =
-        AGCParamTest::getSaturationMarginValues();
-const std::unordered_set<AutomaticGainControl::LevelEstimator> AGCParamTest::kLevelEstimatorValues =
-        {ndk::enum_range<AutomaticGainControl::LevelEstimator>().begin(),
-         ndk::enum_range<AutomaticGainControl::LevelEstimator>().end()};
-
 TEST_P(AGCParamTest, SetAndGetDigitalGainParam) {
     EXPECT_NO_FATAL_FAILURE(addDigitalGainParam(mGain));
     SetAndGetParameters();
@@ -230,9 +222,9 @@
         AGCParamTest, AGCParamTest,
         ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
                                    IFactory::descriptor, kAutomaticGainControlTypeUUID)),
-                           testing::ValuesIn(AGCParamTest::kDigitalGainValues),
-                           testing::ValuesIn(AGCParamTest::kSaturationMarginValues),
-                           testing::ValuesIn(AGCParamTest::kLevelEstimatorValues)),
+                           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));
diff --git a/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
index 7e1e2b5..0451c0b 100644
--- a/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
@@ -36,8 +36,8 @@
 #include <aidl/Vintf.h>
 #include <aidl/android/hardware/audio/core/BnStreamCallback.h>
 #include <aidl/android/hardware/audio/core/IModule.h>
-#include <aidl/android/hardware/audio/core/ISoundDose.h>
 #include <aidl/android/hardware/audio/core/ITelephony.h>
+#include <aidl/android/hardware/audio/core/sounddose/ISoundDose.h>
 #include <aidl/android/media/audio/common/AudioIoFlags.h>
 #include <aidl/android/media/audio/common/AudioOutputFlags.h>
 #include <android-base/chrono_utils.h>
@@ -57,7 +57,6 @@
 using aidl::android::hardware::audio::core::AudioPatch;
 using aidl::android::hardware::audio::core::AudioRoute;
 using aidl::android::hardware::audio::core::IModule;
-using aidl::android::hardware::audio::core::ISoundDose;
 using aidl::android::hardware::audio::core::IStreamCommon;
 using aidl::android::hardware::audio::core::IStreamIn;
 using aidl::android::hardware::audio::core::IStreamOut;
@@ -67,14 +66,18 @@
 using aidl::android::hardware::audio::core::ModuleDebug;
 using aidl::android::hardware::audio::core::StreamDescriptor;
 using aidl::android::hardware::audio::core::VendorParameter;
+using aidl::android::hardware::audio::core::sounddose::ISoundDose;
 using aidl::android::hardware::common::fmq::SynchronizedReadWrite;
 using aidl::android::media::audio::common::AudioContentType;
 using aidl::android::media::audio::common::AudioDevice;
 using aidl::android::media::audio::common::AudioDeviceAddress;
 using aidl::android::media::audio::common::AudioDeviceType;
+using aidl::android::media::audio::common::AudioDualMonoMode;
 using aidl::android::media::audio::common::AudioFormatType;
 using aidl::android::media::audio::common::AudioIoFlags;
+using aidl::android::media::audio::common::AudioLatencyMode;
 using aidl::android::media::audio::common::AudioOutputFlags;
+using aidl::android::media::audio::common::AudioPlaybackRate;
 using aidl::android::media::audio::common::AudioPort;
 using aidl::android::media::audio::common::AudioPortConfig;
 using aidl::android::media::audio::common::AudioPortDeviceExt;
@@ -1753,13 +1756,12 @@
 TEST_P(AudioCoreModule, AddRemoveEffectInvalidArguments) {
     ndk::ScopedAStatus addEffectStatus = module->addDeviceEffect(-1, nullptr);
     ndk::ScopedAStatus removeEffectStatus = module->removeDeviceEffect(-1, nullptr);
-    const bool isSupported = addEffectStatus.getExceptionCode() != EX_UNSUPPORTED_OPERATION;
-    if (isSupported) {
+    if (addEffectStatus.getExceptionCode() != EX_UNSUPPORTED_OPERATION) {
         EXPECT_EQ(EX_ILLEGAL_ARGUMENT, addEffectStatus.getExceptionCode());
         EXPECT_EQ(EX_ILLEGAL_ARGUMENT, removeEffectStatus.getExceptionCode());
-    } else if (EX_UNSUPPORTED_OPERATION != removeEffectStatus.getExceptionCode()) {
-        GTEST_FAIL() << "addEffect and removeEffect must be either supported or not supported "
-                     << "together";
+    } else if (removeEffectStatus.getExceptionCode() != EX_UNSUPPORTED_OPERATION) {
+        GTEST_FAIL() << "addDeviceEffect and removeDeviceEffect must be either supported or "
+                     << "not supported together";
     } else {
         GTEST_SKIP() << "Offloaded effects not supported";
     }
@@ -2166,15 +2168,13 @@
             ASSERT_NE(nullptr, streamCommon);
             ndk::ScopedAStatus addEffectStatus = streamCommon->addEffect(nullptr);
             ndk::ScopedAStatus removeEffectStatus = streamCommon->removeEffect(nullptr);
-            const bool isSupported = addEffectStatus.getExceptionCode() != EX_UNSUPPORTED_OPERATION;
-            if (isSupported) {
+            if (addEffectStatus.getExceptionCode() != EX_UNSUPPORTED_OPERATION) {
                 EXPECT_EQ(EX_ILLEGAL_ARGUMENT, addEffectStatus.getExceptionCode());
                 EXPECT_EQ(EX_ILLEGAL_ARGUMENT, removeEffectStatus.getExceptionCode());
                 atLeastOneSupports = true;
-            } else if (EX_UNSUPPORTED_OPERATION != removeEffectStatus.getExceptionCode()) {
-                ADD_FAILURE()
-                        << "addEffect and removeEffect must be either supported or not supported "
-                        << "together";
+            } else if (removeEffectStatus.getExceptionCode() != EX_UNSUPPORTED_OPERATION) {
+                ADD_FAILURE() << "addEffect and removeEffect must be either supported or "
+                              << "not supported together";
                 atLeastOneSupports = true;
             }
         }
@@ -2433,6 +2433,191 @@
             << "when no async callback is provided for a non-blocking mix port";
 }
 
+TEST_P(AudioStreamOut, AudioDescriptionMixLevel) {
+    const auto ports = moduleConfig->getOutputMixPorts(false /*attachedOnly*/);
+    if (ports.empty()) {
+        GTEST_SKIP() << "No output mix ports";
+    }
+    bool atLeastOneSupports = false;
+    for (const auto& port : ports) {
+        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));
+        bool isSupported = false;
+        EXPECT_NO_FATAL_FAILURE(
+                TestAccessors<float>(stream.get(), &IStreamOut::getAudioDescriptionMixLevel,
+                                     &IStreamOut::setAudioDescriptionMixLevel,
+                                     {IStreamOut::AUDIO_DESCRIPTION_MIX_LEVEL_MAX,
+                                      IStreamOut::AUDIO_DESCRIPTION_MIX_LEVEL_MAX - 1, 0,
+                                      -INFINITY /*IStreamOut::AUDIO_DESCRIPTION_MIX_LEVEL_MIN*/},
+                                     {IStreamOut::AUDIO_DESCRIPTION_MIX_LEVEL_MAX * 2,
+                                      IStreamOut::AUDIO_DESCRIPTION_MIX_LEVEL_MAX * 1.1f},
+                                     &isSupported));
+        if (isSupported) atLeastOneSupports = true;
+    }
+    if (!atLeastOneSupports) {
+        GTEST_SKIP() << "Audio description mix level is not supported";
+    }
+}
+
+TEST_P(AudioStreamOut, DualMonoMode) {
+    const auto ports = moduleConfig->getOutputMixPorts(false /*attachedOnly*/);
+    if (ports.empty()) {
+        GTEST_SKIP() << "No output mix ports";
+    }
+    bool atLeastOneSupports = false;
+    for (const auto& port : ports) {
+        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));
+        bool isSupported = false;
+        EXPECT_NO_FATAL_FAILURE(TestAccessors<AudioDualMonoMode>(
+                stream.get(), &IStreamOut::getDualMonoMode, &IStreamOut::setDualMonoMode,
+                std::vector<AudioDualMonoMode>(enum_range<AudioDualMonoMode>().begin(),
+                                               enum_range<AudioDualMonoMode>().end()),
+                {}, &isSupported));
+        if (isSupported) atLeastOneSupports = true;
+    }
+    if (!atLeastOneSupports) {
+        GTEST_SKIP() << "Audio dual mono mode is not supported";
+    }
+}
+
+TEST_P(AudioStreamOut, LatencyMode) {
+    const auto ports = moduleConfig->getOutputMixPorts(false /*attachedOnly*/);
+    if (ports.empty()) {
+        GTEST_SKIP() << "No output mix ports";
+    }
+    bool atLeastOneSupports = false;
+    for (const auto& port : ports) {
+        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));
+        std::vector<AudioLatencyMode> supportedModes;
+        ndk::ScopedAStatus status = stream.get()->getRecommendedLatencyModes(&supportedModes);
+        if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) continue;
+        atLeastOneSupports = true;
+        if (!status.isOk()) {
+            ADD_FAILURE() << "When latency modes are supported, getRecommendedLatencyModes "
+                          << "must succeed on a non-closed stream, but it failed with " << status;
+            continue;
+        }
+        std::set<AudioLatencyMode> unsupportedModes(enum_range<AudioLatencyMode>().begin(),
+                                                    enum_range<AudioLatencyMode>().end());
+        for (const auto mode : supportedModes) {
+            unsupportedModes.erase(mode);
+            ndk::ScopedAStatus status = stream.get()->setLatencyMode(mode);
+            if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
+                ADD_FAILURE() << "When latency modes are supported, both getRecommendedLatencyModes"
+                              << " and setLatencyMode must be supported";
+            }
+            EXPECT_IS_OK(status) << "Setting of supported latency mode must succeed";
+        }
+        for (const auto mode : unsupportedModes) {
+            EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, stream.get()->setLatencyMode(mode));
+        }
+    }
+    if (!atLeastOneSupports) {
+        GTEST_SKIP() << "Audio latency modes are not supported";
+    }
+}
+
+TEST_P(AudioStreamOut, PlaybackRate) {
+    static const auto kStatuses = {EX_NONE, EX_UNSUPPORTED_OPERATION};
+    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";
+    }
+    ndk::ScopedAStatus status;
+    IModule::SupportedPlaybackRateFactors factors;
+    EXPECT_STATUS(kStatuses, status = module.get()->getSupportedPlaybackRateFactors(&factors));
+    if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
+        GTEST_SKIP() << "Audio playback rate configuration is not supported";
+    }
+    EXPECT_LE(factors.minSpeed, factors.maxSpeed);
+    EXPECT_LE(factors.minPitch, factors.maxPitch);
+    EXPECT_LE(factors.minSpeed, 1.0f);
+    EXPECT_GE(factors.maxSpeed, 1.0f);
+    EXPECT_LE(factors.minPitch, 1.0f);
+    EXPECT_GE(factors.maxPitch, 1.0f);
+    constexpr auto tsDefault = AudioPlaybackRate::TimestretchMode::DEFAULT;
+    constexpr auto tsVoice = AudioPlaybackRate::TimestretchMode::VOICE;
+    constexpr auto fbFail = AudioPlaybackRate::TimestretchFallbackMode::FAIL;
+    constexpr auto fbMute = AudioPlaybackRate::TimestretchFallbackMode::MUTE;
+    const std::vector<AudioPlaybackRate> validValues = {
+            AudioPlaybackRate{1.0f, 1.0f, tsDefault, fbFail},
+            AudioPlaybackRate{1.0f, 1.0f, tsDefault, fbMute},
+            AudioPlaybackRate{factors.maxSpeed, factors.maxPitch, tsDefault, fbMute},
+            AudioPlaybackRate{factors.minSpeed, factors.minPitch, tsDefault, fbMute},
+            AudioPlaybackRate{1.0f, 1.0f, tsVoice, fbMute},
+            AudioPlaybackRate{1.0f, 1.0f, tsVoice, fbFail},
+            AudioPlaybackRate{factors.maxSpeed, factors.maxPitch, tsVoice, fbMute},
+            AudioPlaybackRate{factors.minSpeed, factors.minPitch, tsVoice, fbMute},
+            // Out of range speed / pitch values must not be rejected if the fallback mode is "mute"
+            AudioPlaybackRate{factors.maxSpeed * 2, factors.maxPitch * 2, tsDefault, fbMute},
+            AudioPlaybackRate{factors.minSpeed / 2, factors.minPitch / 2, tsDefault, fbMute},
+            AudioPlaybackRate{factors.maxSpeed * 2, factors.maxPitch * 2, tsVoice, fbMute},
+            AudioPlaybackRate{factors.minSpeed / 2, factors.minPitch / 2, tsVoice, fbMute},
+    };
+    const std::vector<AudioPlaybackRate> invalidValues = {
+            AudioPlaybackRate{factors.maxSpeed, factors.maxPitch * 2, tsDefault, fbFail},
+            AudioPlaybackRate{factors.maxSpeed * 2, factors.maxPitch, tsDefault, fbFail},
+            AudioPlaybackRate{factors.minSpeed, factors.minPitch / 2, tsDefault, fbFail},
+            AudioPlaybackRate{factors.minSpeed / 2, factors.minPitch, tsDefault, fbFail},
+            AudioPlaybackRate{factors.maxSpeed, factors.maxPitch * 2, tsVoice, fbFail},
+            AudioPlaybackRate{factors.maxSpeed * 2, factors.maxPitch, tsVoice, fbFail},
+            AudioPlaybackRate{factors.minSpeed, factors.minPitch / 2, tsVoice, fbFail},
+            AudioPlaybackRate{factors.minSpeed / 2, factors.minPitch, tsVoice, fbFail},
+            AudioPlaybackRate{1.0f, 1.0f, tsDefault,
+                              AudioPlaybackRate::TimestretchFallbackMode::SYS_RESERVED_CUT_REPEAT},
+            AudioPlaybackRate{1.0f, 1.0f, tsDefault,
+                              AudioPlaybackRate::TimestretchFallbackMode::SYS_RESERVED_DEFAULT},
+    };
+    bool atLeastOneSupports = false;
+    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(), kDefaultBufferSizeFrames));
+        bool isSupported = false;
+        EXPECT_NO_FATAL_FAILURE(TestAccessors<AudioPlaybackRate>(
+                stream.get(), &IStreamOut::getPlaybackRateParameters,
+                &IStreamOut::setPlaybackRateParameters, validValues, invalidValues, &isSupported));
+        if (isSupported) atLeastOneSupports = true;
+    }
+    if (!atLeastOneSupports) {
+        GTEST_SKIP() << "Audio playback rate configuration is not supported";
+    }
+}
+
+TEST_P(AudioStreamOut, SelectPresentation) {
+    static const auto kStatuses = {EX_ILLEGAL_ARGUMENT, EX_UNSUPPORTED_OPERATION};
+    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";
+    }
+    bool atLeastOneSupports = false;
+    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(), kDefaultBufferSizeFrames));
+        ndk::ScopedAStatus status;
+        EXPECT_STATUS(kStatuses, status = stream.get()->selectPresentation(0, 0));
+        if (status.getExceptionCode() != EX_UNSUPPORTED_OPERATION) atLeastOneSupports = true;
+    }
+    if (!atLeastOneSupports) {
+        GTEST_SKIP() << "Presentation selection is not supported";
+    }
+}
+
 class StreamLogicDefaultDriver : public StreamLogicDriver {
   public:
     explicit StreamLogicDefaultDriver(std::shared_ptr<StateSequence> commands)
diff --git a/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp b/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp
index 724a9c3..d49a865 100644
--- a/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp
@@ -46,15 +46,6 @@
  * otherwise expect EX_ILLEGAL_ARGUMENT.
  */
 
-const std::vector<int> kStrengthValues = {
-        std::numeric_limits<int>::min(),
-        BassBoost::MIN_PER_MILLE_STRENGTH - 1,
-        BassBoost::MIN_PER_MILLE_STRENGTH,
-        (BassBoost::MIN_PER_MILLE_STRENGTH + BassBoost::MAX_PER_MILLE_STRENGTH) >> 1,
-        BassBoost::MAX_PER_MILLE_STRENGTH,
-        BassBoost::MAX_PER_MILLE_STRENGTH + 2,
-        std::numeric_limits<int>::max()};
-
 class BassBoostParamTest : public ::testing::TestWithParam<BassBoostParamTestParam>,
                            public EffectHelper {
   public:
@@ -81,7 +72,7 @@
     }
 
     Parameter::Specific getDefaultParamSpecific() {
-        BassBoost bb = BassBoost::make<BassBoost::strengthPm>(BassBoost::MIN_PER_MILLE_STRENGTH);
+        BassBoost bb = BassBoost::make<BassBoost::strengthPm>(0);
         Parameter::Specific specific =
                 Parameter::Specific::make<Parameter::Specific::bassBoost>(bb);
         return specific;
@@ -91,7 +82,7 @@
     std::shared_ptr<IFactory> mFactory;
     std::shared_ptr<IEffect> mEffect;
     Descriptor mDescriptor;
-    int mParamStrength = BassBoost::MIN_PER_MILLE_STRENGTH;
+    int mParamStrength = 0;
 
     void SetAndGetBassBoostParameters() {
         for (auto& it : mTags) {
@@ -146,8 +137,29 @@
     }
 
     bool isStrengthInRange(const BassBoost::Capability& cap, int strength) const {
-        return cap.strengthSupported && strength >= BassBoost::MIN_PER_MILLE_STRENGTH &&
-               strength <= BassBoost::MAX_PER_MILLE_STRENGTH;
+        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:
@@ -162,9 +174,12 @@
 
 INSTANTIATE_TEST_SUITE_P(
         BassBoostTest, BassBoostParamTest,
-        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
-                                   IFactory::descriptor, kBassBoostTypeUUID)),
-                           testing::ValuesIn(kStrengthValues)),
+        ::testing::Combine(
+                testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
+                                                                               kBassBoostTypeUUID)),
+                testing::ValuesIn(BassBoostParamTest::getStrengthTestValues(
+                        EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
+                                                                     kBassBoostTypeUUID)))),
         [](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/VtsHalEnvironmentalReverbTargetTest.cpp b/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp
new file mode 100644
index 0000000..e99c4a4
--- /dev/null
+++ b/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp
@@ -0,0 +1,629 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "VtsHalEnvironmentalReverbTest"
+
+#include <Utils.h>
+#include <aidl/Vintf.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::IEffect;
+using aidl::android::hardware::audio::effect::IFactory;
+using aidl::android::hardware::audio::effect::kEnvReverbTypeUUID;
+using aidl::android::hardware::audio::effect::Parameter;
+
+/**
+ * Here we focus on specific parameter checking, general IEffect interfaces testing performed in
+ * VtsAudioEffectTargetTest.
+ * Testing parameter range, assuming the parameter supported by effect is in this range.
+ * This range is verified with IEffect.getDescriptor() and range defined in the documentation, for
+ * any index supported value test expects EX_NONE from IEffect.setParameter(), otherwise expects
+ * EX_ILLEGAL_ARGUMENT.
+ */
+const std::vector<int> kRoomLevelValues = {
+        EnvironmentalReverb::MIN_ROOM_LEVEL_MB - 1, EnvironmentalReverb::MIN_ROOM_LEVEL_MB,
+        EnvironmentalReverb::MAX_ROOM_LEVEL_MB, EnvironmentalReverb::MAX_ROOM_LEVEL_MB + 1};
+const std::vector<int> kRoomHfLevelValues = {
+        EnvironmentalReverb::MIN_ROOM_HF_LEVEL_MB - 1, EnvironmentalReverb::MIN_ROOM_HF_LEVEL_MB,
+        EnvironmentalReverb::MAX_ROOM_HF_LEVEL_MB, EnvironmentalReverb::MAX_ROOM_HF_LEVEL_MB + 1};
+const std::vector<int> kDecayTimeValues = {
+        EnvironmentalReverb::MIN_DECAY_TIME_MS - 1, EnvironmentalReverb::MIN_DECAY_TIME_MS,
+        EnvironmentalReverb::MAX_DECAY_TIME_MS, EnvironmentalReverb::MAX_DECAY_TIME_MS + 1};
+const std::vector<int> kDecayHfRatioValues = {
+        EnvironmentalReverb::MIN_DECAY_HF_RATIO_PM - 1, EnvironmentalReverb::MIN_DECAY_HF_RATIO_PM,
+        EnvironmentalReverb::MAX_DECAY_HF_RATIO_PM, EnvironmentalReverb::MAX_DECAY_HF_RATIO_PM + 1};
+const std::vector<int> kLevelValues = {
+        EnvironmentalReverb::MIN_LEVEL_MB - 1, EnvironmentalReverb::MIN_LEVEL_MB,
+        EnvironmentalReverb::MAX_LEVEL_MB, EnvironmentalReverb::MAX_LEVEL_MB + 1};
+const std::vector<int> kDelayValues = {
+        EnvironmentalReverb::MIN_DELAY_MS - 1, EnvironmentalReverb::MIN_DELAY_MS,
+        EnvironmentalReverb::MAX_DELAY_MS, EnvironmentalReverb::MAX_DELAY_MS + 1};
+const std::vector<int> kDiffusionValues = {
+        EnvironmentalReverb::MIN_DIFFUSION_PM - 1, EnvironmentalReverb::MIN_DIFFUSION_PM,
+        EnvironmentalReverb::MAX_DIFFUSION_PM, EnvironmentalReverb::MAX_DIFFUSION_PM + 1};
+const std::vector<int> kDensityValues = {
+        EnvironmentalReverb::MIN_DENSITY_PM - 1, EnvironmentalReverb::MIN_DENSITY_PM,
+        EnvironmentalReverb::MAX_DENSITY_PM, EnvironmentalReverb::MAX_DENSITY_PM + 1};
+
+class EnvironmentalReverbHelper : public EffectHelper {
+  public:
+    EnvironmentalReverbHelper(std::pair<std::shared_ptr<IFactory>, Descriptor> pair) {
+        std::tie(mFactory, mDescriptor) = pair;
+    }
+
+    void SetUpReverb() {
+        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 TearDownReverb() {
+        ASSERT_NO_FATAL_FAILURE(close(mEffect));
+        ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+    }
+
+    Parameter::Specific getDefaultParamSpecific() {
+        EnvironmentalReverb er = EnvironmentalReverb::make<EnvironmentalReverb::roomLevelMb>(
+                EnvironmentalReverb::MIN_ROOM_LEVEL_MB);
+        Parameter::Specific specific =
+                Parameter::Specific::make<Parameter::Specific::environmentalReverb>(er);
+        return specific;
+    }
+
+    static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
+    std::shared_ptr<IFactory> mFactory;
+    std::shared_ptr<IEffect> mEffect;
+    Descriptor mDescriptor;
+    int mRoomLevel = EnvironmentalReverb::MIN_ROOM_LEVEL_MB;
+    int mRoomHfLevel = EnvironmentalReverb::MAX_ROOM_HF_LEVEL_MB;
+    int mDecayTime = 1000;
+    int mDecayHfRatio = 500;
+    int mLevel = EnvironmentalReverb::MIN_LEVEL_MB;
+    int mDelay = 40;
+    int mDiffusion = EnvironmentalReverb::MAX_DIFFUSION_PM;
+    int mDensity = EnvironmentalReverb::MAX_DENSITY_PM;
+    bool mBypass = false;
+
+    void SetAndGetReverbParameters() {
+        for (auto& it : mTags) {
+            auto& tag = it.first;
+            auto& er = it.second;
+
+            // validate parameter
+            Descriptor desc;
+            ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
+            const bool valid = isTagInRange(it.first, it.second, desc);
+            const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
+
+            // set
+            Parameter expectParam;
+            Parameter::Specific specific;
+            specific.set<Parameter::Specific::environmentalReverb>(er);
+            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;
+                EnvironmentalReverb::Id erId;
+                erId.set<EnvironmentalReverb::Id::commonTag>(tag);
+                id.set<Parameter::Id::environmentalReverbTag>(erId);
+                // if set success, then get should match
+                EXPECT_STATUS(expected, mEffect->getParameter(id, &getParam));
+                EXPECT_EQ(expectParam, getParam);
+            }
+        }
+    }
+
+    void addRoomLevelParam() {
+        EnvironmentalReverb er;
+        er.set<EnvironmentalReverb::roomLevelMb>(mRoomLevel);
+        mTags.push_back({EnvironmentalReverb::roomLevelMb, er});
+    }
+
+    void addRoomHfLevelParam(int roomHfLevel) {
+        EnvironmentalReverb er;
+        er.set<EnvironmentalReverb::roomHfLevelMb>(roomHfLevel);
+        mTags.push_back({EnvironmentalReverb::roomHfLevelMb, er});
+    }
+
+    void addDecayTimeParam(int decayTime) {
+        EnvironmentalReverb er;
+        er.set<EnvironmentalReverb::decayTimeMs>(decayTime);
+        mTags.push_back({EnvironmentalReverb::decayTimeMs, er});
+    }
+
+    void addDecayHfRatioParam(int decayHfRatio) {
+        EnvironmentalReverb er;
+        er.set<EnvironmentalReverb::decayHfRatioPm>(decayHfRatio);
+        mTags.push_back({EnvironmentalReverb::decayHfRatioPm, er});
+    }
+
+    void addLevelParam(int level) {
+        EnvironmentalReverb er;
+        er.set<EnvironmentalReverb::levelMb>(level);
+        mTags.push_back({EnvironmentalReverb::levelMb, er});
+    }
+
+    void addDelayParam(int delay) {
+        EnvironmentalReverb er;
+        er.set<EnvironmentalReverb::delayMs>(delay);
+        mTags.push_back({EnvironmentalReverb::delayMs, er});
+    }
+
+    void addDiffusionParam(int diffusion) {
+        EnvironmentalReverb er;
+        er.set<EnvironmentalReverb::diffusionPm>(diffusion);
+        mTags.push_back({EnvironmentalReverb::diffusionPm, er});
+    }
+
+    void addDensityParam(int density) {
+        EnvironmentalReverb er;
+        er.set<EnvironmentalReverb::densityPm>(density);
+        mTags.push_back({EnvironmentalReverb::densityPm, er});
+    }
+
+    void addBypassParam(bool bypass) {
+        EnvironmentalReverb er;
+        er.set<EnvironmentalReverb::bypass>(bypass);
+        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(roomLevel);
+            }
+            case EnvironmentalReverb::roomHfLevelMb: {
+                int roomHfLevel = er.get<EnvironmentalReverb::roomHfLevelMb>();
+                return isRoomHfLevelInRange(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(decayHfRatio);
+            }
+            case EnvironmentalReverb::levelMb: {
+                int level = er.get<EnvironmentalReverb::levelMb>();
+                return isLevelInRange(level);
+            }
+            case EnvironmentalReverb::delayMs: {
+                int delay = er.get<EnvironmentalReverb::delayMs>();
+                return isDelayInRange(delay);
+            }
+            case EnvironmentalReverb::diffusionPm: {
+                int diffusion = er.get<EnvironmentalReverb::diffusionPm>();
+                return isDiffusionInRange(diffusion);
+            }
+            case EnvironmentalReverb::densityPm: {
+                int density = er.get<EnvironmentalReverb::densityPm>();
+                return isDensityInRange(density);
+            }
+            case EnvironmentalReverb::bypass: {
+                return true;
+            }
+            default:
+                return false;
+        }
+        return false;
+    }
+
+    bool isRoomLevelInRange(int roomLevel) const {
+        return roomLevel >= EnvironmentalReverb::MIN_ROOM_LEVEL_MB &&
+               roomLevel <= EnvironmentalReverb::MAX_ROOM_LEVEL_MB;
+    }
+
+    bool isRoomHfLevelInRange(int roomHfLevel) const {
+        return roomHfLevel >= EnvironmentalReverb::MIN_ROOM_HF_LEVEL_MB &&
+               roomHfLevel <= EnvironmentalReverb::MAX_ROOM_HF_LEVEL_MB;
+    }
+
+    bool isDecayTimeInRange(const EnvironmentalReverb::Capability& cap, int decayTime) const {
+        return decayTime >= EnvironmentalReverb::MIN_DECAY_TIME_MS &&
+               decayTime <= EnvironmentalReverb::MAX_DECAY_TIME_MS &&
+               decayTime <= cap.maxDecayTimeMs;
+    }
+
+    bool isDecayHfRatioInRange(int decayHfRatio) const {
+        return decayHfRatio >= EnvironmentalReverb::MIN_DECAY_HF_RATIO_PM &&
+               decayHfRatio <= EnvironmentalReverb::MAX_DECAY_HF_RATIO_PM;
+    }
+
+    bool isLevelInRange(int level) const {
+        return level >= EnvironmentalReverb::MIN_LEVEL_MB &&
+               level <= EnvironmentalReverb::MAX_LEVEL_MB;
+    }
+
+    bool isDelayInRange(int delay) const {
+        return delay >= EnvironmentalReverb::MIN_DELAY_MS &&
+               delay <= EnvironmentalReverb::MAX_DELAY_MS;
+    }
+
+    bool isDiffusionInRange(int diffusion) const {
+        return diffusion >= EnvironmentalReverb::MIN_DIFFUSION_PM &&
+               diffusion <= EnvironmentalReverb::MAX_DIFFUSION_PM;
+    }
+
+    bool isDensityInRange(int density) const {
+        return density >= EnvironmentalReverb::MIN_DENSITY_PM &&
+               density <= EnvironmentalReverb::MAX_DENSITY_PM;
+    }
+
+  private:
+    std::vector<std::pair<EnvironmentalReverb::Tag, EnvironmentalReverb>> mTags;
+    void CleanUp() { mTags.clear(); }
+};
+
+class EnvironmentalReverbRoomLevelTest
+    : public ::testing::TestWithParam<
+              std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int>>,
+      public EnvironmentalReverbHelper {
+  public:
+    EnvironmentalReverbRoomLevelTest() : EnvironmentalReverbHelper(std::get<0>(GetParam())) {
+        mRoomLevel = std::get<1>(GetParam());
+    }
+
+    void SetUp() override { SetUpReverb(); }
+
+    void TearDown() override { TearDownReverb(); }
+};
+
+TEST_P(EnvironmentalReverbRoomLevelTest, SetAndGetRoomLevel) {
+    EXPECT_NO_FATAL_FAILURE(addRoomLevelParam());
+    SetAndGetReverbParameters();
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        EnvironmentalReverbTest, EnvironmentalReverbRoomLevelTest,
+        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+                                   IFactory::descriptor, kEnvReverbTypeUUID)),
+                           testing::ValuesIn(kRoomLevelValues)),
+        [](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));
+
+            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+                               descriptor.common.name + "_UUID_" +
+                               descriptor.common.id.uuid.toString() + "_roomLevel" + roomLevel;
+            std::replace_if(
+                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+            return name;
+        });
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbRoomLevelTest);
+
+class EnvironmentalReverbRoomHfLevelTest
+    : public ::testing::TestWithParam<
+              std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int>>,
+      public EnvironmentalReverbHelper {
+  public:
+    EnvironmentalReverbRoomHfLevelTest() : EnvironmentalReverbHelper(std::get<0>(GetParam())) {
+        mRoomHfLevel = std::get<1>(GetParam());
+    }
+
+    void SetUp() override { SetUpReverb(); }
+
+    void TearDown() override { TearDownReverb(); }
+};
+
+TEST_P(EnvironmentalReverbRoomHfLevelTest, SetAndGetRoomHfLevel) {
+    EXPECT_NO_FATAL_FAILURE(addRoomHfLevelParam(mRoomHfLevel));
+    SetAndGetReverbParameters();
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        EnvironmentalReverbTest, EnvironmentalReverbRoomHfLevelTest,
+        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+                                   IFactory::descriptor, kEnvReverbTypeUUID)),
+                           testing::ValuesIn(kRoomHfLevelValues)),
+        [](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));
+
+            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+                               descriptor.common.name + "_UUID_" +
+                               descriptor.common.id.uuid.toString() + "_roomHfLevel" + roomHfLevel;
+            std::replace_if(
+                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+            return name;
+        });
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbRoomHfLevelTest);
+
+class EnvironmentalReverbDecayTimeTest
+    : public ::testing::TestWithParam<
+              std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int>>,
+      public EnvironmentalReverbHelper {
+  public:
+    EnvironmentalReverbDecayTimeTest() : EnvironmentalReverbHelper(std::get<0>(GetParam())) {
+        mDecayTime = std::get<1>(GetParam());
+    }
+
+    void SetUp() override { SetUpReverb(); }
+
+    void TearDown() override { TearDownReverb(); }
+};
+
+TEST_P(EnvironmentalReverbDecayTimeTest, SetAndGetDecayTime) {
+    EXPECT_NO_FATAL_FAILURE(addDecayTimeParam(mDecayTime));
+    SetAndGetReverbParameters();
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        EnvironmentalReverbTest, EnvironmentalReverbDecayTimeTest,
+        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+                                   IFactory::descriptor, kEnvReverbTypeUUID)),
+                           testing::ValuesIn(kDecayTimeValues)),
+        [](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));
+
+            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+                               descriptor.common.name + "_UUID_" +
+                               descriptor.common.id.uuid.toString() + "_decayTime" + decayTime;
+            std::replace_if(
+                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+            return name;
+        });
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbDecayTimeTest);
+
+class EnvironmentalReverbDecayHfRatioTest
+    : public ::testing::TestWithParam<
+              std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int>>,
+      public EnvironmentalReverbHelper {
+  public:
+    EnvironmentalReverbDecayHfRatioTest() : EnvironmentalReverbHelper(std::get<0>(GetParam())) {
+        mDecayHfRatio = std::get<1>(GetParam());
+    }
+
+    void SetUp() override { SetUpReverb(); }
+
+    void TearDown() override { TearDownReverb(); }
+};
+
+TEST_P(EnvironmentalReverbDecayHfRatioTest, SetAndGetDecayHfRatio) {
+    EXPECT_NO_FATAL_FAILURE(addDecayHfRatioParam(mDecayHfRatio));
+    SetAndGetReverbParameters();
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        EnvironmentalReverbTest, EnvironmentalReverbDecayHfRatioTest,
+        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+                                   IFactory::descriptor, kEnvReverbTypeUUID)),
+                           testing::ValuesIn(kDecayHfRatioValues)),
+        [](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));
+
+            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+                               descriptor.common.name + "_UUID_" +
+                               descriptor.common.id.uuid.toString() + "_decayHfRatio" +
+                               decayHfRatio;
+            std::replace_if(
+                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+            return name;
+        });
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbDecayHfRatioTest);
+
+class EnvironmentalReverbLevelTest
+    : public ::testing::TestWithParam<
+              std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int>>,
+      public EnvironmentalReverbHelper {
+  public:
+    EnvironmentalReverbLevelTest() : EnvironmentalReverbHelper(std::get<0>(GetParam())) {
+        mLevel = std::get<1>(GetParam());
+    }
+
+    void SetUp() override { SetUpReverb(); }
+
+    void TearDown() override { TearDownReverb(); }
+};
+
+TEST_P(EnvironmentalReverbLevelTest, SetAndGetLevel) {
+    EXPECT_NO_FATAL_FAILURE(addLevelParam(mLevel));
+    SetAndGetReverbParameters();
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        EnvironmentalReverbTest, EnvironmentalReverbLevelTest,
+        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+                                   IFactory::descriptor, kEnvReverbTypeUUID)),
+                           testing::ValuesIn(kLevelValues)),
+        [](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));
+
+            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+                               descriptor.common.name + "_UUID_" +
+                               descriptor.common.id.uuid.toString() + "_level" + level;
+            std::replace_if(
+                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+            return name;
+        });
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbLevelTest);
+
+class EnvironmentalReverbDelayTest
+    : public ::testing::TestWithParam<
+              std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int>>,
+      public EnvironmentalReverbHelper {
+  public:
+    EnvironmentalReverbDelayTest() : EnvironmentalReverbHelper(std::get<0>(GetParam())) {
+        mDelay = std::get<1>(GetParam());
+    }
+
+    void SetUp() override { SetUpReverb(); }
+
+    void TearDown() override { TearDownReverb(); }
+};
+
+TEST_P(EnvironmentalReverbDelayTest, SetAndGetDelay) {
+    EXPECT_NO_FATAL_FAILURE(addDelayParam(mDelay));
+    SetAndGetReverbParameters();
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        EnvironmentalReverbTest, EnvironmentalReverbDelayTest,
+        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+                                   IFactory::descriptor, kEnvReverbTypeUUID)),
+                           testing::ValuesIn(kDelayValues)),
+        [](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));
+
+            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+                               descriptor.common.name + "_UUID_" +
+                               descriptor.common.id.uuid.toString() + "_delay" + delay;
+            std::replace_if(
+                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+            return name;
+        });
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbDelayTest);
+
+class EnvironmentalReverbDiffusionTest
+    : public ::testing::TestWithParam<
+              std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int>>,
+      public EnvironmentalReverbHelper {
+  public:
+    EnvironmentalReverbDiffusionTest() : EnvironmentalReverbHelper(std::get<0>(GetParam())) {
+        mDiffusion = std::get<1>(GetParam());
+    }
+
+    void SetUp() override { SetUpReverb(); }
+
+    void TearDown() override { TearDownReverb(); }
+};
+
+TEST_P(EnvironmentalReverbDiffusionTest, SetAndGetDiffusion) {
+    EXPECT_NO_FATAL_FAILURE(addDiffusionParam(mDiffusion));
+    SetAndGetReverbParameters();
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        EnvironmentalReverbTest, EnvironmentalReverbDiffusionTest,
+        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+                                   IFactory::descriptor, kEnvReverbTypeUUID)),
+                           testing::ValuesIn(kDiffusionValues)),
+        [](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));
+
+            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+                               descriptor.common.name + "_UUID_" +
+                               descriptor.common.id.uuid.toString() + "_diffusion" + diffusion;
+            std::replace_if(
+                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+            return name;
+        });
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbDiffusionTest);
+
+class EnvironmentalReverbDensityTest
+    : public ::testing::TestWithParam<
+              std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int>>,
+      public EnvironmentalReverbHelper {
+  public:
+    EnvironmentalReverbDensityTest() : EnvironmentalReverbHelper(std::get<0>(GetParam())) {
+        mDensity = std::get<1>(GetParam());
+    }
+
+    void SetUp() override { SetUpReverb(); }
+
+    void TearDown() override { TearDownReverb(); }
+};
+
+TEST_P(EnvironmentalReverbDensityTest, SetAndGetDensity) {
+    EXPECT_NO_FATAL_FAILURE(addDensityParam(mDensity));
+    SetAndGetReverbParameters();
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        EnvironmentalReverbTest, EnvironmentalReverbDensityTest,
+        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+                                   IFactory::descriptor, kEnvReverbTypeUUID)),
+                           testing::ValuesIn(kDensityValues)),
+        [](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));
+
+            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+                               descriptor.common.name + "_UUID_" +
+                               descriptor.common.id.uuid.toString() + "_density" + density;
+            std::replace_if(
+                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+            return name;
+        });
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbDensityTest);
+
+class EnvironmentalReverbBypassTest
+    : public ::testing::TestWithParam<
+              std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, bool>>,
+      public EnvironmentalReverbHelper {
+  public:
+    EnvironmentalReverbBypassTest() : EnvironmentalReverbHelper(std::get<0>(GetParam())) {
+        mBypass = std::get<1>(GetParam());
+    }
+
+    void SetUp() override { SetUpReverb(); }
+
+    void TearDown() override { TearDownReverb(); }
+};
+
+TEST_P(EnvironmentalReverbBypassTest, SetAndGetBypass) {
+    EXPECT_NO_FATAL_FAILURE(addBypassParam(mBypass));
+    SetAndGetReverbParameters();
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        EnvironmentalReverbTest, EnvironmentalReverbBypassTest,
+        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+                                   IFactory::descriptor, kEnvReverbTypeUUID)),
+                           testing::Bool()),
+        [](const testing::TestParamInfo<EnvironmentalReverbBypassTest::ParamType>& info) {
+            auto descriptor = std::get<0>(info.param).second;
+            std::string bypass = std::to_string(std::get<1>(info.param));
+
+            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+                               descriptor.common.name + "_UUID_" +
+                               descriptor.common.id.uuid.toString() + "_bypass" + bypass;
+            std::replace_if(
+                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+            return name;
+        });
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbBypassTest);
+
+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/VtsHalNSTargetTest.cpp b/audio/aidl/vts/VtsHalNSTargetTest.cpp
index 2845225..93ad86d 100644
--- a/audio/aidl/vts/VtsHalNSTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalNSTargetTest.cpp
@@ -14,12 +14,14 @@
  * limitations under the License.
  */
 
+#include <Utils.h>
 #include <aidl/Vintf.h>
+#include <android/binder_enums.h>
+#include <unordered_set>
 
 #define LOG_TAG "VtsHalNSParamTest"
 
-#include <Utils.h>
-#include <unordered_set>
+#include <aidl/android/hardware/audio/effect/NoiseSuppression.h>
 #include "EffectHelper.h"
 
 using namespace android;
@@ -69,9 +71,6 @@
     }
 
     static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
-    static const std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kFactoryDescList;
-    static const std::unordered_set<NoiseSuppression::Level> kLevelValues;
-
     std::shared_ptr<IFactory> mFactory;
     std::shared_ptr<IEffect> mEffect;
     Descriptor mDescriptor;
@@ -114,19 +113,16 @@
         ns.set<NoiseSuppression::level>(level);
         mTags.push_back({NoiseSuppression::level, ns});
     }
+    static std::unordered_set<NoiseSuppression::Level> getLevelValues() {
+        return {ndk::enum_range<NoiseSuppression::Level>().begin(),
+                ndk::enum_range<NoiseSuppression::Level>().end()};
+    }
 
   private:
     std::vector<std::pair<NoiseSuppression::Tag, NoiseSuppression>> mTags;
     void CleanUp() { mTags.clear(); }
 };
 
-const std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kFactoryDescList =
-        EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
-                                                     kNoiseSuppressionTypeUUID);
-const std::unordered_set<NoiseSuppression::Level> NSParamTest::kLevelValues = {
-        ndk::enum_range<NoiseSuppression::Level>().begin(),
-        ndk::enum_range<NoiseSuppression::Level>().end()};
-
 TEST_P(NSParamTest, SetAndGetLevel) {
     EXPECT_NO_FATAL_FAILURE(addLevelParam(mLevel));
     SetAndGetParameters();
@@ -136,7 +132,7 @@
         NSParamTest, NSParamTest,
         ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
                                    IFactory::descriptor, kNoiseSuppressionTypeUUID)),
-                           testing::ValuesIn(NSParamTest::kLevelValues)),
+                           testing::ValuesIn(NSParamTest::getLevelValues())),
         [](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(
diff --git a/audio/aidl/vts/VtsHalPresetReverbTargetTest.cpp b/audio/aidl/vts/VtsHalPresetReverbTargetTest.cpp
new file mode 100644
index 0000000..19d5747
--- /dev/null
+++ b/audio/aidl/vts/VtsHalPresetReverbTargetTest.cpp
@@ -0,0 +1,178 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "VtsHalPresetReverbTargetTest"
+
+#include <Utils.h>
+#include <aidl/Vintf.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::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;
+
+/**
+ * Here we focus on specific parameter checking, general IEffect interfaces testing performed in
+ * VtsAudioEffectTargetTest.
+ */
+enum ParamName { PARAM_INSTANCE_NAME, PARAM_PRESETS };
+using PresetReverbParamTestParam =
+        std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, PresetReverb::Presets>;
+
+// Testing for enum values
+const std::vector<PresetReverb::Presets> kPresetsValues{
+        ndk::enum_range<PresetReverb::Presets>().begin(),
+        ndk::enum_range<PresetReverb::Presets>().end()};
+
+class PresetReverbParamTest : public ::testing::TestWithParam<PresetReverbParamTestParam>,
+                              public EffectHelper {
+  public:
+    PresetReverbParamTest() : mParamPresets(std::get<PARAM_PRESETS>(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));
+    }
+
+    static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
+    std::shared_ptr<IFactory> mFactory;
+    std::shared_ptr<IEffect> mEffect;
+    Descriptor mDescriptor;
+    PresetReverb::Presets mParamPresets = PresetReverb::Presets::NONE;
+
+    void SetAndGetPresetReverbParameters() {
+        for (auto& it : mTags) {
+            auto& tag = it.first;
+            auto& pr = it.second;
+
+            // validate parameter
+            Descriptor desc;
+            ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
+            const bool valid = isTagInRange(it.first, it.second, desc);
+            const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
+
+            // set parameter
+            Parameter expectParam;
+            Parameter::Specific specific;
+            specific.set<Parameter::Specific::presetReverb>(pr);
+            expectParam.set<Parameter::specific>(specific);
+            // All values are valid, set parameter should succeed
+            EXPECT_STATUS(expected, mEffect->setParameter(expectParam)) << expectParam.toString();
+
+            // get parameter
+            Parameter getParam;
+            Parameter::Id id;
+            PresetReverb::Id prId;
+            prId.set<PresetReverb::Id::commonTag>(tag);
+            id.set<Parameter::Id::presetReverbTag>(prId);
+            EXPECT_STATUS(expected, mEffect->getParameter(id, &getParam));
+
+            EXPECT_EQ(expectParam, getParam);
+        }
+    }
+
+    void addPresetsParam(PresetReverb::Presets preset) {
+        PresetReverb pr;
+        pr.set<PresetReverb::preset>(preset);
+        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 =
+                Parameter::Specific::make<Parameter::Specific::presetReverb>(pr);
+        return specific;
+    }
+
+  private:
+    std::vector<std::pair<PresetReverb::Tag, PresetReverb>> mTags;
+    void CleanUp() { mTags.clear(); }
+};
+
+TEST_P(PresetReverbParamTest, SetAndGetPresets) {
+    EXPECT_NO_FATAL_FAILURE(addPresetsParam(mParamPresets));
+    SetAndGetPresetReverbParameters();
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        PresetReverbTest, PresetReverbParamTest,
+        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+                                   IFactory::descriptor, kPresetReverbTypeUUID)),
+                           testing::ValuesIn(kPresetsValues)),
+        [](const testing::TestParamInfo<PresetReverbParamTest::ParamType>& info) {
+            auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
+            std::string preset =
+                    std::to_string(static_cast<int>(std::get<PARAM_PRESETS>(info.param)));
+            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+                               descriptor.common.name + "_UUID_" +
+                               descriptor.common.id.uuid.toString() + "_preset" + preset;
+            std::replace_if(
+                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+            return name;
+        });
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(PresetReverbParamTest);
+
+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/VtsHalVirtualizerTargetTest.cpp b/audio/aidl/vts/VtsHalVirtualizerTargetTest.cpp
index 61776b2..090de17 100644
--- a/audio/aidl/vts/VtsHalVirtualizerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalVirtualizerTargetTest.cpp
@@ -44,11 +44,6 @@
  * otherwise expect EX_ILLEGAL_ARGUMENT.
  */
 
-const std::vector<int> kStrengthValues = {
-        std::numeric_limits<int>::min(),         Virtualizer::MIN_PER_MILLE_STRENGTH - 1,
-        Virtualizer::MIN_PER_MILLE_STRENGTH,     Virtualizer::MAX_PER_MILLE_STRENGTH,
-        Virtualizer::MAX_PER_MILLE_STRENGTH + 1, std::numeric_limits<int>::max()};
-
 class VirtualizerParamTest : public ::testing::TestWithParam<VirtualizerParamTestParam>,
                              public EffectHelper {
   public:
@@ -75,8 +70,7 @@
     }
 
     Parameter::Specific getDefaultParamSpecific() {
-        Virtualizer vr =
-                Virtualizer::make<Virtualizer::strengthPm>(Virtualizer::MIN_PER_MILLE_STRENGTH);
+        Virtualizer vr = Virtualizer::make<Virtualizer::strengthPm>(0);
         Parameter::Specific specific =
                 Parameter::Specific::make<Parameter::Specific::virtualizer>(vr);
         return specific;
@@ -86,7 +80,7 @@
     std::shared_ptr<IFactory> mFactory;
     std::shared_ptr<IEffect> mEffect;
     Descriptor mDescriptor;
-    int mParamStrength = Virtualizer::MIN_PER_MILLE_STRENGTH;
+    int mParamStrength = 0;
 
     void SetAndGetVirtualizerParameters() {
         for (auto& it : mTags) {
@@ -141,8 +135,29 @@
     }
 
     bool isStrengthInRange(const Virtualizer::Capability& cap, int strength) const {
-        return cap.strengthSupported && strength >= Virtualizer::MIN_PER_MILLE_STRENGTH &&
-               strength <= Virtualizer::MAX_PER_MILLE_STRENGTH;
+        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:
@@ -159,7 +174,9 @@
         VirtualizerTest, VirtualizerParamTest,
         ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
                                    IFactory::descriptor, kVirtualizerTypeUUID)),
-                           testing::ValuesIn(kStrengthValues)),
+                           testing::ValuesIn(VirtualizerParamTest::getStrengthTestValues(
+                                   EffectFactoryHelper::getAllEffectDescriptors(
+                                           IFactory::descriptor, kVirtualizerTypeUUID)))),
         [](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 47d6755..242be3f 100644
--- a/audio/aidl/vts/VtsHalVisualizerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalVisualizerTargetTest.cpp
@@ -85,12 +85,6 @@
         return specific;
     }
 
-    static const std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kFactoryDescList;
-    static const std::unordered_set<Visualizer::ScalingMode> kScalingModeValues;
-    static const std::unordered_set<Visualizer::MeasurementMode> kMeasurementModeValues;
-    static const std::unordered_set<int> kLatencyValues;
-    static const std::unordered_set<int> kCaptureSizeValues;
-
     static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
     std::shared_ptr<IFactory> mFactory;
     std::shared_ptr<IEffect> mEffect;
@@ -141,7 +135,7 @@
             // validate parameter
             Descriptor desc;
             ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
-            const bool valid = isSetOnlyParamTagInRange(tag, vs, desc);
+            const bool valid = isSetOnlyParamTagInRange(vs, desc);
             const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
 
             // set parameter
@@ -219,18 +213,26 @@
         switch (tag) {
             case Visualizer::captureSamples: {
                 int captureSize = vs.get<Visualizer::captureSamples>();
-                return isCaptureSizeInRange(vsCap, captureSize);
+                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(Visualizer::SetOnlyParameters::Tag, const Visualizer& vs,
-                                  const Descriptor& desc) const {
+    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>();
@@ -239,19 +241,16 @@
         return isLatencyInRange(vsCap, latency);
     }
 
-    bool isCaptureSizeInRange(const Visualizer::Capability& cap, int captureSize) const {
-        return (captureSize >= cap.captureSampleRange.min &&
-                captureSize <= cap.captureSampleRange.max);
-    }
-
     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 : kFactoryDescList) {
+        for (const auto& it : descList) {
             maxCaptureSize = std::max(
                     it.second.capability.get<Capability::visualizer>().captureSampleRange.max,
                     maxCaptureSize);
@@ -265,19 +264,29 @@
     }
 
     static std::unordered_set<int> getLatencyValues() {
+        auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
+                                                                     kVisualizerTypeUUID);
         const auto max = std::max_element(
-                kFactoryDescList.begin(), kFactoryDescList.end(),
+                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 == kFactoryDescList.end()) {
+        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()};
+    }
 
   private:
     std::vector<std::pair<Visualizer::Tag, Visualizer>> mCommonTags;
@@ -290,20 +299,6 @@
     }
 };
 
-const std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>>
-        VisualizerParamTest::kFactoryDescList = EffectFactoryHelper::getAllEffectDescriptors(
-                IFactory::descriptor, kVisualizerTypeUUID);
-const std::unordered_set<int> VisualizerParamTest::kCaptureSizeValues =
-        VisualizerParamTest::getCaptureSizeValues();
-const std::unordered_set<Visualizer::MeasurementMode> VisualizerParamTest::kMeasurementModeValues(
-        ndk::enum_range<Visualizer::MeasurementMode>().begin(),
-        ndk::enum_range<Visualizer::MeasurementMode>().end());
-const std::unordered_set<Visualizer::ScalingMode> VisualizerParamTest::kScalingModeValues(
-        ndk::enum_range<Visualizer::ScalingMode>().begin(),
-        ndk::enum_range<Visualizer::ScalingMode>().end());
-const std::unordered_set<int> VisualizerParamTest::kLatencyValues =
-        VisualizerParamTest::getLatencyValues();
-
 TEST_P(VisualizerParamTest, SetAndGetCaptureSize) {
     EXPECT_NO_FATAL_FAILURE(addCaptureSizeParam(mCaptureSize));
     SetAndGetCommonParameters();
@@ -338,17 +333,17 @@
         VisualizerParamTest, VisualizerParamTest,
         ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
                                    IFactory::descriptor, kVisualizerTypeUUID)),
-                           testing::ValuesIn(VisualizerParamTest::kCaptureSizeValues),
-                           testing::ValuesIn(VisualizerParamTest::kScalingModeValues),
-                           testing::ValuesIn(VisualizerParamTest::kMeasurementModeValues),
-                           testing::ValuesIn(VisualizerParamTest::kLatencyValues)),
+                           testing::ValuesIn(VisualizerParamTest::getCaptureSizeValues()),
+                           testing::ValuesIn(VisualizerParamTest::getScalingModeValues()),
+                           testing::ValuesIn(VisualizerParamTest::getMeasurementModeValues()),
+                           testing::ValuesIn(VisualizerParamTest::getLatencyValues())),
         [](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));
-            std::string scalingMode =
-                    std::to_string(static_cast<int>(std::get<PARAM_SCALING_MODE>(info.param)));
-            std::string measurementMode =
-                    std::to_string(static_cast<int>(std::get<PARAM_MEASUREMENT_MODE>(info.param)));
+            std::string scalingMode = aidl::android::hardware::audio::effect::toString(
+                    std::get<PARAM_SCALING_MODE>(info.param));
+            std::string measurementMode = aidl::android::hardware::audio::effect::toString(
+                    std::get<PARAM_MEASUREMENT_MODE>(info.param));
             std::string latency = std::to_string(std::get<PARAM_LATENCY>(info.param));
 
             std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
diff --git a/audio/aidl/vts/VtsHalVolumeTargetTest.cpp b/audio/aidl/vts/VtsHalVolumeTargetTest.cpp
index 3e82854..34625e7 100644
--- a/audio/aidl/vts/VtsHalVolumeTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalVolumeTargetTest.cpp
@@ -34,17 +34,14 @@
  * Here we focus on specific parameter checking, general IEffect interfaces testing performed in
  * VtsAudioEffectTargetTest.
  */
-enum ParamName { PARAM_INSTANCE_NAME, PARAM_LEVEL_DB, PARAM_MUTE };
+enum ParamName { PARAM_INSTANCE_NAME, PARAM_LEVEL, PARAM_MUTE };
 using VolumeParamTestParam =
         std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int, bool>;
 
-const std::vector<int> kLevelValues = {Volume::MIN_LEVEL_DB - 1, Volume::MIN_LEVEL_DB, -100,
-                                       Volume::MAX_LEVEL_DB, Volume::MAX_LEVEL_DB + 1};
-
 class VolumeParamTest : public ::testing::TestWithParam<VolumeParamTestParam>, public EffectHelper {
   public:
     VolumeParamTest()
-        : mParamLevel(std::get<PARAM_LEVEL_DB>(GetParam())),
+        : mParamLevel(std::get<PARAM_LEVEL>(GetParam())),
           mParamMute(std::get<PARAM_MUTE>(GetParam())) {
         std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
     }
@@ -67,7 +64,7 @@
     }
 
     Parameter::Specific getDefaultParamSpecific() {
-        Volume vol = Volume::make<Volume::levelDb>(Volume::MIN_LEVEL_DB);
+        Volume vol = Volume::make<Volume::levelDb>(-9600);
         Parameter::Specific specific = Parameter::Specific::make<Parameter::Specific::volume>(vol);
         return specific;
     }
@@ -87,6 +84,8 @@
             // 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 binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
 
@@ -97,7 +96,7 @@
             expectParam.set<Parameter::specific>(specific);
             EXPECT_STATUS(expected, mEffect->setParameter(expectParam)) << expectParam.toString();
 
-            // only get if parameter in range and set success
+            // only get if parameter is in range and set success
             if (expected == EX_NONE) {
                 Parameter getParam;
                 Parameter::Id id;
@@ -124,6 +123,11 @@
         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) {
@@ -138,9 +142,21 @@
         }
     }
 
-    bool isLevelInRange(const Volume::Capability& cap, int level) const {
-        return level >= Volume::MIN_LEVEL_DB && level <= Volume::MAX_LEVEL_DB &&
-               level <= cap.maxLevel;
+    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:
@@ -160,12 +176,16 @@
 
 INSTANTIATE_TEST_SUITE_P(
         VolumeTest, VolumeParamTest,
-        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
-                                   IFactory::descriptor, kVolumeTypeUUID)),
-                           testing::ValuesIn(kLevelValues), testing::Bool()),
+        ::testing::Combine(
+                testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
+                                                                               kVolumeTypeUUID)),
+                testing::ValuesIn(VolumeParamTest::getLevelTestValues(
+                        EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
+                                                                     kVolumeTypeUUID))),
+                testing::Bool() /* mute */),
         [](const testing::TestParamInfo<VolumeParamTest::ParamType>& info) {
             auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
-            std::string level = std::to_string(std::get<PARAM_LEVEL_DB>(info.param));
+            std::string level = std::to_string(std::get<PARAM_LEVEL>(info.param));
             std::string mute = std::to_string(std::get<PARAM_MUTE>(info.param));
             std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
                                descriptor.common.name + "_UUID_" +
diff --git a/audio/common/7.0/enums/OWNERS b/audio/common/7.0/enums/OWNERS
deleted file mode 100644
index 24071af..0000000
--- a/audio/common/7.0/enums/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-elaurent@google.com
-mnaganov@google.com
diff --git a/audio/common/7.0/example/OWNERS b/audio/common/7.0/example/OWNERS
deleted file mode 100644
index 24071af..0000000
--- a/audio/common/7.0/example/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-elaurent@google.com
-mnaganov@google.com
diff --git a/audio/common/7.1/enums/OWNERS b/audio/common/7.1/enums/OWNERS
deleted file mode 100644
index 24071af..0000000
--- a/audio/common/7.1/enums/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-elaurent@google.com
-mnaganov@google.com
diff --git a/audio/common/all-versions/OWNERS b/audio/common/all-versions/OWNERS
deleted file mode 100644
index 24071af..0000000
--- a/audio/common/all-versions/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-elaurent@google.com
-mnaganov@google.com
diff --git a/audio/common/all-versions/default/OWNERS b/audio/common/all-versions/default/OWNERS
deleted file mode 100644
index 24071af..0000000
--- a/audio/common/all-versions/default/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-elaurent@google.com
-mnaganov@google.com
diff --git a/audio/common/all-versions/default/service/android.hardware.audio.service.rc b/audio/common/all-versions/default/service/android.hardware.audio.service.rc
index 45fef9a..f859f21 100644
--- a/audio/common/all-versions/default/service/android.hardware.audio.service.rc
+++ b/audio/common/all-versions/default/service/android.hardware.audio.service.rc
@@ -4,6 +4,8 @@
     # media gid needed for /dev/fm (radio) and for /data/misc/media (tee)
     group audio camera drmrpc inet media mediadrm net_bt net_bt_admin net_bw_acct wakelock context_hub
     capabilities BLOCK_SUSPEND
+    # setting RLIMIT_RTPRIO allows binder RT priority inheritance
+    rlimit rtprio 10 10
     ioprio rt 4
     task_profiles ProcessCapacityHigh HighPerformance
     onrestart restart audioserver
diff --git a/audio/core/all-versions/OWNERS b/audio/core/all-versions/OWNERS
deleted file mode 100644
index f9a2d6b..0000000
--- a/audio/core/all-versions/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-# Bug component: 48436
-elaurent@google.com
-mnaganov@google.com
diff --git a/audio/core/all-versions/default/Device.cpp b/audio/core/all-versions/default/Device.cpp
index b954fcd..d03118a 100644
--- a/audio/core/all-versions/default/Device.cpp
+++ b/audio/core/all-versions/default/Device.cpp
@@ -30,6 +30,7 @@
 #include <algorithm>
 
 #include <android/log.h>
+#include <hidl/HidlTransportSupport.h>
 #include <mediautils/MemoryLeakTrackUtil.h>
 #include <memunreachable/memunreachable.h>
 
@@ -183,6 +184,7 @@
     if (status == OK) {
         streamOut = new StreamOut(this, halStream);
         ++mOpenedStreamsCount;
+        android::hardware::setMinSchedulerPolicy(streamOut, SCHED_NORMAL, ANDROID_PRIORITY_AUDIO);
     }
     status_t convertStatus =
             HidlUtils::audioConfigFromHal(halConfig, false /*isInput*/, suggestedConfig);
@@ -220,6 +222,7 @@
     if (status == OK) {
         streamIn = new StreamIn(this, halStream);
         ++mOpenedStreamsCount;
+        android::hardware::setMinSchedulerPolicy(streamIn, SCHED_NORMAL, ANDROID_PRIORITY_AUDIO);
     }
     status_t convertStatus =
             HidlUtils::audioConfigFromHal(halConfig, true /*isInput*/, suggestedConfig);
diff --git a/audio/core/all-versions/default/DevicesFactory.cpp b/audio/core/all-versions/default/DevicesFactory.cpp
index f44daf0..011f9ac 100644
--- a/audio/core/all-versions/default/DevicesFactory.cpp
+++ b/audio/core/all-versions/default/DevicesFactory.cpp
@@ -23,6 +23,8 @@
 #include <string.h>
 
 #include <android/log.h>
+#include <hidl/HidlTransportSupport.h>
+#include <system/thread_defs.h>
 
 namespace android {
 namespace hardware {
@@ -103,6 +105,7 @@
     int halStatus = loadAudioInterface(moduleName, &halDevice);
     if (halStatus == OK) {
         result = new DeviceShim(halDevice);
+        android::hardware::setMinSchedulerPolicy(result, SCHED_NORMAL, ANDROID_PRIORITY_AUDIO);
         retval = Result::OK;
     } else if (halStatus == -EINVAL) {
         retval = Result::NOT_INITIALIZED;
diff --git a/audio/core/all-versions/vts/functional/OWNERS b/audio/core/all-versions/vts/functional/OWNERS
deleted file mode 100644
index 448d9fe..0000000
--- a/audio/core/all-versions/vts/functional/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 48436
-mnaganov@google.com
diff --git a/audio/effect/all-versions/OWNERS b/audio/effect/all-versions/OWNERS
deleted file mode 100644
index f9a2d6b..0000000
--- a/audio/effect/all-versions/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-# Bug component: 48436
-elaurent@google.com
-mnaganov@google.com
diff --git a/audio/effect/all-versions/default/Effect.cpp b/audio/effect/all-versions/default/Effect.cpp
index b57dc63..5dc42dc 100644
--- a/audio/effect/all-versions/default/Effect.cpp
+++ b/audio/effect/all-versions/default/Effect.cpp
@@ -700,8 +700,21 @@
 
     void* dataPtr = halDataSize > 0 ? &halData[0] : NULL;
     void* resultPtr = halResultSize > 0 ? &halResult[0] : NULL;
-    status_t status =
-        (*mHandle)->command(mHandle, commandId, halDataSize, dataPtr, &halResultSize, resultPtr);
+    status_t status = BAD_VALUE;
+    switch (commandId) {
+        case 'gtid':  // retrieve the tid, used for spatializer priority boost
+            if (halDataSize == 0 && resultMaxSize == sizeof(int32_t)) {
+                auto ptid = (int32_t*)resultPtr;
+                ptid[0] = mProcessThread ? mProcessThread->getTid() : -1;
+                status = OK;
+                break;  // we have handled 'gtid' here.
+            }
+            [[fallthrough]];  // allow 'gtid' overload (checked halDataSize and resultMaxSize).
+        default:
+            status = (*mHandle)->command(mHandle, commandId, halDataSize, dataPtr, &halResultSize,
+                                         resultPtr);
+            break;
+    }
     hidl_vec<uint8_t> result;
     if (status == OK && resultPtr != NULL) {
         result.setToExternal(&halResult[0], halResultSize);
diff --git a/audio/effect/all-versions/default/EffectsFactory.cpp b/audio/effect/all-versions/default/EffectsFactory.cpp
index e93ad89..9bf309c 100644
--- a/audio/effect/all-versions/default/EffectsFactory.cpp
+++ b/audio/effect/all-versions/default/EffectsFactory.cpp
@@ -32,6 +32,7 @@
 
 #include <UuidUtils.h>
 #include <android/log.h>
+#include <hidl/HidlTransportSupport.h>
 #include <media/EffectsFactoryApi.h>
 #include <system/audio_effects/effect_aec.h>
 #include <system/audio_effects/effect_agc.h>
@@ -44,6 +45,7 @@
 #include <system/audio_effects/effect_presetreverb.h>
 #include <system/audio_effects/effect_virtualizer.h>
 #include <system/audio_effects/effect_visualizer.h>
+#include <system/thread_defs.h>
 #include <util/EffectUtils.h>
 
 namespace android {
@@ -189,6 +191,7 @@
         status = (*handle)->get_descriptor(handle, &halDescriptor);
         if (status == OK) {
             effect = dispatchEffectInstanceCreation(halDescriptor, handle);
+            android::hardware::setMinSchedulerPolicy(effect, SCHED_NORMAL, ANDROID_PRIORITY_AUDIO);
             effectId = EffectMap::getInstance().add(handle);
         } else {
             ALOGE("Error querying effect descriptor for %s: %s",
diff --git a/audio/effect/all-versions/vts/functional/OWNERS b/audio/effect/all-versions/vts/functional/OWNERS
deleted file mode 100644
index 448d9fe..0000000
--- a/audio/effect/all-versions/vts/functional/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 48436
-mnaganov@google.com
diff --git a/audio/policy/1.0/vts/OWNERS b/audio/policy/1.0/vts/OWNERS
deleted file mode 100644
index 24071af..0000000
--- a/audio/policy/1.0/vts/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-elaurent@google.com
-mnaganov@google.com
diff --git a/audio/policy/1.0/vts/functional/OWNERS b/audio/policy/1.0/vts/functional/OWNERS
deleted file mode 100644
index 448d9fe..0000000
--- a/audio/policy/1.0/vts/functional/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 48436
-mnaganov@google.com
diff --git a/biometrics/face/aidl/Android.bp b/biometrics/face/aidl/Android.bp
index 0bec0c5..78f113d 100644
--- a/biometrics/face/aidl/Android.bp
+++ b/biometrics/face/aidl/Android.bp
@@ -14,7 +14,7 @@
         "android/hardware/biometrics/face/**/*.aidl",
     ],
     imports: [
-        "android.hardware.biometrics.common",
+        "android.hardware.biometrics.common-V2",
         "android.hardware.common-V2",
         "android.hardware.keymaster-V3",
     ],
diff --git a/biometrics/fingerprint/aidl/Android.bp b/biometrics/fingerprint/aidl/Android.bp
index 0bd6422..620e270 100644
--- a/biometrics/fingerprint/aidl/Android.bp
+++ b/biometrics/fingerprint/aidl/Android.bp
@@ -14,7 +14,7 @@
         "android/hardware/biometrics/fingerprint/**/*.aidl",
     ],
     imports: [
-        "android.hardware.biometrics.common",
+        "android.hardware.biometrics.common-V2",
         "android.hardware.keymaster-V3",
     ],
     stability: "vintf",
diff --git a/bluetooth/audio/aidl/Android.bp b/bluetooth/audio/aidl/Android.bp
index 4aea83f..618141f 100644
--- a/bluetooth/audio/aidl/Android.bp
+++ b/bluetooth/audio/aidl/Android.bp
@@ -29,7 +29,7 @@
     imports: [
         "android.hardware.common-V2",
         "android.hardware.common.fmq-V1",
-        "android.hardware.audio.common",
+        "android.hardware.audio.common-V1",
     ],
     backend: {
         cpp: {
diff --git a/camera/common/aidl/Android.bp b/camera/common/aidl/Android.bp
index d21ae58..fa74392 100644
--- a/camera/common/aidl/Android.bp
+++ b/camera/common/aidl/Android.bp
@@ -11,6 +11,7 @@
     name: "android.hardware.camera.common",
     vendor_available: true,
     srcs: ["android/hardware/camera/common/*.aidl"],
+    frozen: true,
     stability: "vintf",
     backend: {
         cpp: {
diff --git a/camera/device/aidl/Android.bp b/camera/device/aidl/Android.bp
index 6115d53..461e89d 100644
--- a/camera/device/aidl/Android.bp
+++ b/camera/device/aidl/Android.bp
@@ -11,13 +11,14 @@
     name: "android.hardware.camera.device",
     vendor_available: true,
     srcs: ["android/hardware/camera/device/*.aidl"],
+    frozen: true,
     stability: "vintf",
     imports: [
         "android.hardware.common-V2",
         "android.hardware.common.fmq-V1",
-        "android.hardware.camera.common",
-        "android.hardware.camera.metadata",
-        "android.hardware.graphics.common",
+        "android.hardware.camera.common-V1",
+        "android.hardware.camera.metadata-V1",
+        "android.hardware.graphics.common-V4",
     ],
     backend: {
         cpp: {
diff --git a/camera/metadata/aidl/Android.bp b/camera/metadata/aidl/Android.bp
index 301a943..8c13ce5 100644
--- a/camera/metadata/aidl/Android.bp
+++ b/camera/metadata/aidl/Android.bp
@@ -11,6 +11,7 @@
     name: "android.hardware.camera.metadata",
     vendor_available: true,
     srcs: ["android/hardware/camera/metadata/*.aidl"],
+    frozen: true,
     stability: "vintf",
     backend: {
         cpp: {
diff --git a/camera/provider/aidl/Android.bp b/camera/provider/aidl/Android.bp
index 87a94b2..e2c2bea 100644
--- a/camera/provider/aidl/Android.bp
+++ b/camera/provider/aidl/Android.bp
@@ -14,8 +14,8 @@
         "android/hardware/camera/provider/*.aidl",
     ],
     imports: [
-        "android.hardware.camera.device",
-        "android.hardware.camera.common",
+        "android.hardware.camera.device-V1",
+        "android.hardware.camera.common-V1",
     ],
     stability: "vintf",
     backend: {
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index 5e1589b..267c762 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -829,4 +829,12 @@
             <instance>default</instance>
         </interface>
     </hal>
+    <hal format="native">
+        <name>mapper</name>
+        <version>1.0</version>
+        <interface>
+            <name>I</name>
+            <regex-instance>.*</regex-instance>
+        </interface>
+    </hal>
 </compatibility-matrix>
diff --git a/compatibility_matrices/exclude/fcm_exclude.cpp b/compatibility_matrices/exclude/fcm_exclude.cpp
index cf1e138..3c0c5f1 100644
--- a/compatibility_matrices/exclude/fcm_exclude.cpp
+++ b/compatibility_matrices/exclude/fcm_exclude.cpp
@@ -52,6 +52,7 @@
             "android.hardware.radio.config@1.2",
             // AIDL
             "android.hardware.audio.common",
+            "android.hardware.audio.core.sounddose",
             "android.hardware.biometrics.common",
             "android.hardware.camera.metadata",
             "android.hardware.camera.device",
diff --git a/input/processor/aidl/Android.bp b/input/processor/aidl/Android.bp
index 773bb49..f1a73d2 100644
--- a/input/processor/aidl/Android.bp
+++ b/input/processor/aidl/Android.bp
@@ -13,7 +13,7 @@
     vendor_available: true,
     srcs: ["android/hardware/input/processor/*.aidl"],
     imports: [
-        "android.hardware.input.common",
+        "android.hardware.input.common-V1",
     ],
     stability: "vintf",
     backend: {
diff --git a/radio/aidl/Android.bp b/radio/aidl/Android.bp
index 0088264..80ad14a 100644
--- a/radio/aidl/Android.bp
+++ b/radio/aidl/Android.bp
@@ -38,7 +38,7 @@
     srcs: ["android/hardware/radio/config/*.aidl"],
     frozen: true,
     stability: "vintf",
-    imports: ["android.hardware.radio"],
+    imports: ["android.hardware.radio-V1"],
     backend: {
         cpp: {
             enabled: false,
@@ -62,7 +62,7 @@
     host_supported: true,
     srcs: ["android/hardware/radio/data/*.aidl"],
     stability: "vintf",
-    imports: ["android.hardware.radio"],
+    imports: ["android.hardware.radio-V1"],
     backend: {
         cpp: {
             enabled: false,
@@ -86,7 +86,7 @@
     host_supported: true,
     srcs: ["android/hardware/radio/messaging/*.aidl"],
     stability: "vintf",
-    imports: ["android.hardware.radio"],
+    imports: ["android.hardware.radio-V1"],
     backend: {
         cpp: {
             enabled: false,
@@ -110,7 +110,7 @@
     host_supported: true,
     srcs: ["android/hardware/radio/modem/*.aidl"],
     stability: "vintf",
-    imports: ["android.hardware.radio"],
+    imports: ["android.hardware.radio-V1"],
     backend: {
         cpp: {
             enabled: false,
@@ -134,7 +134,7 @@
     host_supported: true,
     srcs: ["android/hardware/radio/network/*.aidl"],
     stability: "vintf",
-    imports: ["android.hardware.radio"],
+    imports: ["android.hardware.radio-V1"],
     backend: {
         cpp: {
             enabled: false,
@@ -159,8 +159,8 @@
     srcs: ["android/hardware/radio/sim/*.aidl"],
     stability: "vintf",
     imports: [
-        "android.hardware.radio",
-        "android.hardware.radio.config",
+        "android.hardware.radio-V1",
+        "android.hardware.radio.config-V1",
     ],
     backend: {
         cpp: {
@@ -188,7 +188,7 @@
     host_supported: true,
     srcs: ["android/hardware/radio/voice/*.aidl"],
     stability: "vintf",
-    imports: ["android.hardware.radio"],
+    imports: ["android.hardware.radio-V1"],
     backend: {
         cpp: {
             enabled: false,
diff --git a/security/keymint/aidl/vts/functional/Android.bp b/security/keymint/aidl/vts/functional/Android.bp
index e7f5a0f..88badc7 100644
--- a/security/keymint/aidl/vts/functional/Android.bp
+++ b/security/keymint/aidl/vts/functional/Android.bp
@@ -57,6 +57,7 @@
     srcs: [
         "AttestKeyTest.cpp",
         "DeviceUniqueAttestationTest.cpp",
+        "KeyBlobUpgradeTest.cpp",
         "KeyMintTest.cpp",
         "SecureElementProvisioningTest.cpp",
     ],
diff --git a/security/keymint/aidl/vts/functional/KeyBlobUpgradeTest.cpp b/security/keymint/aidl/vts/functional/KeyBlobUpgradeTest.cpp
new file mode 100644
index 0000000..c952012
--- /dev/null
+++ b/security/keymint/aidl/vts/functional/KeyBlobUpgradeTest.cpp
@@ -0,0 +1,609 @@
+/*
+ * 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.
+ */
+
+// The tests in this file are intended to be run manually, to allow testing of whether
+// keyblob upgrade works correctly.  The manual procedure is roughly:
+//
+// 1) Run the "*Before*" subset of these tests with the `--keyblob_dir <dir>` command-line argument
+//    so that keyblobs are saved to a directory on the device:
+//
+//      VtsAidlKeyMintTargetTest --gtest_filter="*KeyBlobUpgradeTest*Before*" \
+//                               --keyblob_dir /data/local/tmp/keymint-blobs
+//
+//    All tests should pass, and the `UpgradeKeyBlobs` test should indicate that no keyblob
+//    upgrades were needed.
+//
+// 2) Copy the generated keyblobs off the device into a safe place.
+//
+//      adb pull /data/local/tmp/keymint-blobs
+//
+// 3) Upgrade the device to a new version.
+//
+// 4) Push the saved keyblobs back onto the upgraded device.
+//
+//      adb push keymint-blobs /data/local/tmp/keymint-blobs
+//
+// 5) Run the "*After*" subset of these tests with the `--keyblob_dir <dir>` command-line argument
+//    pointing to the directory with the keyblobs:
+//
+//      VtsAidlKeyMintTargetTest --gtest_filter="*KeyBlobUpgradeTest*After*" \
+//                               --keyblob_dir /data/local/tmp/keymint-blobs
+//
+//    (Note that this skips the `CreateKeyBlobs` test, which would otherwise replace the saved
+//    keyblobs with freshly generated ones.).
+//
+//    All tests should pass, and the `UpgradeKeyBlobs` test should have output that matches whether
+//    upgrade was expected or not.
+
+#define LOG_TAG "keymint_1_test"
+#include <cutils/log.h>
+
+#include <algorithm>
+#include <fstream>
+#include <iostream>
+
+#include <unistd.h>
+
+#include <openssl/curve25519.h>
+#include <openssl/ec.h>
+#include <openssl/evp.h>
+#include <openssl/mem.h>
+#include <openssl/x509v3.h>
+
+#include "KeyMintAidlTestBase.h"
+
+using aidl::android::hardware::security::keymint::KeyCharacteristics;
+
+namespace aidl::android::hardware::security::keymint::test {
+
+namespace {
+
+std::vector<std::string> keyblob_names_tee = {
+        "aes-key",        "aes-key-rr",      "des-key",           "hmac-key",
+        "rsa-key",        "p256-key",        "ed25519-key",       "x25519-key",
+        "rsa-attest-key", "p256-attest-key", "ed25519-attest-key"};
+
+std::vector<std::string> keyblob_names_sb = {"aes-key",        "aes-key-rr",     "des-key",
+                                             "hmac-key",       "rsa-key",        "p256-key",
+                                             "rsa-attest-key", "p256-attest-key"};
+
+const std::vector<std::string>& keyblob_names(SecurityLevel sec_level) {
+    if (sec_level == SecurityLevel::STRONGBOX) {
+        return keyblob_names_sb;
+    } else {
+        return keyblob_names_tee;
+    }
+}
+
+bool requires_rr(const std::string& name) {
+    return name.find("-rr") != std::string::npos;
+}
+
+bool is_asymmetric(const std::string& name) {
+    return (name.find("rsa") != std::string::npos || name.find("25519") != std::string::npos ||
+            name.find("p256") != std::string::npos);
+}
+
+std::string keyblob_subdir(const std::string& keyblob_dir, const std::string& full_name,
+                           bool create) {
+    if (keyblob_dir.empty()) {
+        return "";
+    }
+
+    // Use a subdirectory for the specific instance, so two different KeyMint instances won't
+    // clash with each other.
+    size_t found = full_name.find_last_of('/');
+    std::string subdir = keyblob_dir + "/" + full_name.substr(found + 1);
+
+    if (create) {
+        mkdir(keyblob_dir.c_str(), 0777);
+        mkdir(subdir.c_str(), 0777);
+    }
+    return subdir;
+}
+
+void save_keyblob(const std::string& subdir, const std::string& name,
+                  const vector<uint8_t>& keyblob,
+                  const std::vector<KeyCharacteristics>& key_characteristics) {
+    // Write the keyblob out to a file.
+    std::string blobname(subdir + "/" + name + ".keyblob");
+    std::ofstream blobfile(blobname, std::ios::out | std::ios::trunc | std::ios::binary);
+    blobfile.write(reinterpret_cast<const char*>(keyblob.data()), keyblob.size());
+    blobfile.close();
+
+    // Dump the characteristics too.
+    std::string charsname(subdir + "/" + name + ".chars");
+    std::ofstream charsfile(charsname, std::ios::out | std::ios::trunc);
+    charsfile << "{\n";
+    for (const auto& characteristic : key_characteristics) {
+        charsfile << "  " << characteristic.toString() << "\n";
+    }
+    charsfile << "}\n";
+    charsfile.close();
+
+    // Also write out a hexdump of the keyblob for convenience.
+    std::string hexname(subdir + "/" + name + ".hex");
+    std::ofstream hexfile(hexname, std::ios::out | std::ios::trunc);
+    hexfile << bin2hex(keyblob) << "\n";
+    hexfile.close();
+}
+
+void save_keyblob_and_cert(const std::string& subdir, const std::string& name,
+                           const vector<uint8_t>& keyblob,
+                           const std::vector<KeyCharacteristics>& key_characteristics,
+                           const std::vector<Certificate>& cert_chain) {
+    save_keyblob(subdir, name, keyblob, key_characteristics);
+
+    if (is_asymmetric(name)) {
+        // Dump the leaf certificate as DER.
+        if (cert_chain.empty()) {
+            FAIL() << "No cert available for " << name;
+        } else {
+            const vector<uint8_t>& certdata = cert_chain[0].encodedCertificate;
+            std::string certname(subdir + "/" + name + ".cert");
+            std::ofstream certfile(certname, std::ios::out | std::ios::trunc | std::ios::binary);
+            certfile.write(reinterpret_cast<const char*>(certdata.data()), certdata.size());
+            certfile.close();
+        }
+    }
+}
+
+void delete_keyblob(const std::string& subdir, const std::string& name) {
+    std::string blobname(subdir + "/" + name + ".keyblob");
+    unlink(blobname.c_str());
+    std::string charsname(subdir + "/" + name + ".chars");
+    unlink(charsname.c_str());
+    std::string hexname(subdir + "/" + name + ".hex");
+    unlink(hexname.c_str());
+    std::string certname(subdir + "/" + name + ".cert");
+    unlink(certname.c_str());
+}
+
+std::vector<uint8_t> load_file(const std::string& subdir, const std::string& name,
+                               const std::string& suffix) {
+    std::string blobname(subdir + "/" + name + suffix);
+    std::ifstream blobfile(blobname, std::ios::in | std::ios::binary);
+
+    std::vector<uint8_t> data((std::istreambuf_iterator<char>(blobfile)),
+                              std::istreambuf_iterator<char>());
+    return data;
+}
+
+std::vector<uint8_t> load_keyblob(const std::string& subdir, const std::string& name) {
+    return load_file(subdir, name, ".keyblob");
+}
+
+std::vector<uint8_t> load_cert(const std::string& subdir, const std::string& name) {
+    return load_file(subdir, name, ".cert");
+}
+
+}  // namespace
+
+class KeyBlobUpgradeTest : public KeyMintAidlTestBase {
+  protected:
+    void UpgradeKeyBlobs(bool expectUpgrade) {
+        std::string subdir = keyblob_subdir(keyblob_dir, GetParam(), /* create? */ false);
+        if (subdir.empty()) {
+            GTEST_SKIP() << "No keyblob directory provided";
+        }
+
+        for (std::string name : keyblob_names(SecLevel())) {
+            for (bool with_hidden : {false, true}) {
+                std::string app_id;
+                std::string app_data;
+                auto builder = AuthorizationSetBuilder();
+                if (with_hidden) {
+                    // Build a variant keyblob that requires app_id/app_data
+                    app_id = "appid";
+                    app_data = "appdata";
+                    builder.Authorization(TAG_APPLICATION_ID, "appid")
+                            .Authorization(TAG_APPLICATION_DATA, "appdata");
+                    name += "-hidden";
+                }
+                SCOPED_TRACE(testing::Message() << name);
+
+                // Load the old format keyblob.
+                std::vector<uint8_t> keyblob = load_keyblob(subdir, name);
+                if (keyblob.empty()) {
+                    if (requires_rr(name)) {
+                        std::cerr << "Skipping missing keyblob file '" << name
+                                  << "', assuming rollback resistance unavailable\n";
+                    } else {
+                        FAIL() << "Missing keyblob file '" << name << "'";
+                    }
+                    continue;
+                }
+
+                // An upgrade will either produce a new keyblob or no data (if upgrade isn't
+                // needed).
+                std::vector<uint8_t> upgraded_keyblob;
+                Status result =
+                        keymint_->upgradeKey(keyblob, builder.vector_data(), &upgraded_keyblob);
+                ASSERT_EQ(ErrorCode::OK, GetReturnErrorCode(result));
+
+                if (upgraded_keyblob.empty()) {
+                    std::cerr << "Keyblob '" << name << "' did not require upgrade\n";
+                    EXPECT_TRUE(!expectUpgrade) << "Keyblob '" << name << "' unexpectedly upgraded";
+                } else {
+                    // Ensure the old format keyblob is deleted (so any secure deletion data is
+                    // cleaned up).
+                    EXPECT_EQ(ErrorCode::OK, DeleteKey(&keyblob));
+
+                    std::vector<uint8_t> app_id_v(app_id.begin(), app_id.end());
+                    std::vector<uint8_t> app_data_v(app_data.begin(), app_data.end());
+                    std::vector<KeyCharacteristics> key_characteristics;
+                    result = keymint_->getKeyCharacteristics(upgraded_keyblob, app_id_v, app_data_v,
+                                                             &key_characteristics);
+                    ASSERT_EQ(ErrorCode::OK, GetReturnErrorCode(result))
+                            << "Failed getKeyCharacteristics() after upgrade";
+
+                    save_keyblob(subdir, name, upgraded_keyblob, key_characteristics);
+                    // Cert file is left unchanged.
+                    std::cerr << "Keyblob '" << name << "' upgraded\n";
+                    EXPECT_TRUE(expectUpgrade)
+                            << "Keyblob '" << name << "' unexpectedly left as-is";
+                }
+            }
+        }
+    }
+};
+
+// To save off keyblobs before upgrade, use:
+//
+//    VtsAidlKeyMintTargetTest --gtest_filter="*KeyBlobUpgradeTest.CreateKeyBlobs*" \
+//                             --keyblob_dir /data/local/tmp/keymint-blobs
+//
+// Then copy the contents of the /data/local/tmp/keymint-blobs/ directory somewhere safe:
+//
+//    adb pull /data/local/tmp/keymint-blobs/
+TEST_P(KeyBlobUpgradeTest, CreateKeyBlobsBefore) {
+    std::string subdir = keyblob_subdir(keyblob_dir, GetParam(), /* create? */ true);
+
+    std::map<const std::string, AuthorizationSetBuilder> keys_info = {
+            {"aes-key", AuthorizationSetBuilder()
+                                .AesEncryptionKey(256)
+                                .BlockMode(BlockMode::ECB)
+                                .Padding(PaddingMode::PKCS7)
+                                .Authorization(TAG_NO_AUTH_REQUIRED)},
+            {"aes-key-rr", AuthorizationSetBuilder()
+                                   .AesEncryptionKey(256)
+                                   .BlockMode(BlockMode::ECB)
+                                   .Padding(PaddingMode::PKCS7)
+                                   .Authorization(TAG_ROLLBACK_RESISTANCE)
+                                   .Authorization(TAG_NO_AUTH_REQUIRED)},
+            {"des-key", AuthorizationSetBuilder()
+                                .TripleDesEncryptionKey(168)
+                                .BlockMode(BlockMode::ECB)
+                                .Padding(PaddingMode::PKCS7)
+                                .Authorization(TAG_NO_AUTH_REQUIRED)},
+            {"hmac-key", AuthorizationSetBuilder()
+                                 .HmacKey(128)
+                                 .Digest(Digest::SHA1)
+                                 .Authorization(TAG_MIN_MAC_LENGTH, 128)
+                                 .Authorization(TAG_NO_AUTH_REQUIRED)},
+            {"rsa-key", AuthorizationSetBuilder()
+                                .RsaEncryptionKey(2048, 65537)
+                                .Authorization(TAG_PURPOSE, KeyPurpose::SIGN)
+                                .Digest(Digest::NONE)
+                                .Digest(Digest::SHA1)
+                                .Padding(PaddingMode::NONE)
+                                .Authorization(TAG_NO_AUTH_REQUIRED)
+                                .SetDefaultValidity()},
+            {
+                    "p256-key",
+                    AuthorizationSetBuilder()
+                            .EcdsaSigningKey(EcCurve::P_256)
+                            .Authorization(TAG_PURPOSE, KeyPurpose::AGREE_KEY)
+                            .Digest(Digest::NONE)
+                            .Digest(Digest::SHA1)
+                            .Authorization(TAG_NO_AUTH_REQUIRED)
+                            .SetDefaultValidity(),
+            },
+            {
+                    "ed25519-key",
+                    AuthorizationSetBuilder()
+                            .EcdsaSigningKey(EcCurve::CURVE_25519)
+                            .Digest(Digest::NONE)
+                            .Authorization(TAG_NO_AUTH_REQUIRED)
+                            .SetDefaultValidity(),
+            },
+            {"x25519-key", AuthorizationSetBuilder()
+                                   .Authorization(TAG_EC_CURVE, EcCurve::CURVE_25519)
+                                   .Authorization(TAG_PURPOSE, KeyPurpose::AGREE_KEY)
+                                   .Authorization(TAG_ALGORITHM, Algorithm::EC)
+                                   .Authorization(TAG_NO_AUTH_REQUIRED)
+                                   .SetDefaultValidity()},
+            {"rsa-attest-key", AuthorizationSetBuilder()
+                                       .RsaKey(2048, 65537)
+                                       .AttestKey()
+                                       .Authorization(TAG_NO_AUTH_REQUIRED)
+                                       .SetDefaultValidity()},
+            {
+                    "p256-attest-key",
+                    AuthorizationSetBuilder()
+                            .EcdsaKey(EcCurve::P_256)
+                            .AttestKey()
+                            .Authorization(TAG_NO_AUTH_REQUIRED)
+                            .SetDefaultValidity(),
+            },
+            {
+                    "ed25519-attest-key",
+                    AuthorizationSetBuilder()
+                            .EcdsaKey(EcCurve::CURVE_25519)
+                            .AttestKey()
+                            .Authorization(TAG_NO_AUTH_REQUIRED)
+                            .SetDefaultValidity(),
+            }};
+
+    for (std::string name : keyblob_names(SecLevel())) {
+        auto entry = keys_info.find(name);
+        ASSERT_NE(entry, keys_info.end()) << "no builder for " << name;
+        auto builder = entry->second;
+        for (bool with_hidden : {false, true}) {
+            if (with_hidden) {
+                // Build a variant keyblob that requires app_id/app_data
+                builder.Authorization(TAG_APPLICATION_ID, "appid")
+                        .Authorization(TAG_APPLICATION_DATA, "appdata");
+                name += "-hidden";
+            }
+            SCOPED_TRACE(testing::Message() << name);
+
+            vector<uint8_t> keyblob;
+            vector<KeyCharacteristics> key_characteristics;
+            vector<Certificate> cert_chain;
+            auto result =
+                    GenerateKey(builder, std::nullopt, &keyblob, &key_characteristics, &cert_chain);
+
+            if (requires_rr(name) && result == ErrorCode::ROLLBACK_RESISTANCE_UNAVAILABLE) {
+                // Rollback resistance support is optional.
+                std::cerr << "Skipping '" << name << "' key as rollback resistance unavailable\n";
+                continue;
+            }
+            ASSERT_EQ(ErrorCode::OK, result) << " failed for " << name;
+
+            if (!subdir.empty()) {
+                save_keyblob_and_cert(subdir, name, keyblob, key_characteristics, cert_chain);
+            }
+        }
+    }
+
+    if (!subdir.empty()) {
+        std::cerr << "Save generated keyblobs with:\n\n    adb pull " << keyblob_dir << "\n\n";
+    }
+}
+
+TEST_P(KeyBlobUpgradeTest, UpgradeKeyBlobsBefore) {
+    // Check that attempting to upgrade valid keyblobs does nothing.
+    UpgradeKeyBlobs(/* expectUpgrade= */ false);
+}
+
+// To run this test:
+//
+// - save off some keyblobs before upgrade as per the CreateKeyBlobs test above.
+// - upgrade the device to a version that should trigger keyblob upgrade (e.g. different patchlevel)
+// - put the saved keyblobs back onto the upgraded device:
+//
+//     adb push keymint-blobs /data/local/tmp/keymint-blobs
+//
+// - run the test with:
+//
+//     VtsAidlKeyMintTargetTest --gtest_filter="*KeyBlobUpgradeTest.UpgradeKeyBlobsAfter*" \
+//                              --keyblob_dir /data/local/tmp/keymint-blobs
+//
+// - this replaces the keyblob contents in that directory; if needed, save the upgraded keyblobs
+//   with:
+//      adb pull /data/local/tmp/keymint-blobs/
+TEST_P(KeyBlobUpgradeTest, UpgradeKeyBlobsAfter) {
+    UpgradeKeyBlobs(/* expectUpgrade= */ true);
+}
+
+// To run this test:
+//
+// - save off some keyblobs before upgrade as per the CreateKeyBlobs test above
+// - if needed, upgrade the saved keyblobs as per the UpgradeKeyBlobs test above
+// - run the test with:
+//
+//     VtsAidlKeyMintTargetTest --gtest_filter="*KeyBlobUpgradeTest.UseKeyBlobs*" \
+//                              --keyblob_dir /data/local/tmp/keymint-blobs
+TEST_P(KeyBlobUpgradeTest, UseKeyBlobsBeforeOrAfter) {
+    std::string subdir = keyblob_subdir(keyblob_dir, GetParam(), /* create? */ false);
+    if (subdir.empty()) {
+        GTEST_SKIP() << "No keyblob directory provided with (e.g.) --keyblob_dir "
+                        "/data/local/tmp/keymint-blobs";
+    }
+
+    for (std::string name : keyblob_names(SecLevel())) {
+        for (bool with_hidden : {false, true}) {
+            auto builder = AuthorizationSetBuilder();
+            if (with_hidden) {
+                // Build a variant keyblob that requires app_id/app_data
+                builder.Authorization(TAG_APPLICATION_ID, "appid")
+                        .Authorization(TAG_APPLICATION_DATA, "appdata");
+                name += "-hidden";
+            }
+            SCOPED_TRACE(testing::Message() << name);
+            std::vector<uint8_t> keyblob = load_keyblob(subdir, name);
+            if (keyblob.empty()) {
+                if (requires_rr(name)) {
+                    std::cerr << "Skipping missing keyblob file '" << name
+                              << "', assuming rollback resistance unavailable\n";
+                } else {
+                    FAIL() << "Missing keyblob file '" << name << "'";
+                }
+                continue;
+            }
+
+            std::vector<uint8_t> cert;
+            if (is_asymmetric(name)) {
+                cert = load_cert(subdir, name);
+            }
+
+            // Perform an algorithm-specific operation with the keyblob.
+            string message = "Hello World!";
+            AuthorizationSet out_params;
+            if (name.find("aes-key") != std::string::npos) {
+                builder.BlockMode(BlockMode::ECB).Padding(PaddingMode::PKCS7);
+                string ciphertext = EncryptMessage(keyblob, message, builder, &out_params);
+                string plaintext = DecryptMessage(keyblob, ciphertext, builder);
+                EXPECT_EQ(message, plaintext);
+            } else if (name.find("des-key") != std::string::npos) {
+                builder.BlockMode(BlockMode::ECB).Padding(PaddingMode::PKCS7);
+                string ciphertext = EncryptMessage(keyblob, message, builder, &out_params);
+                string plaintext = DecryptMessage(keyblob, ciphertext, builder);
+                EXPECT_EQ(message, plaintext);
+            } else if (name.find("hmac-key") != std::string::npos) {
+                builder.Digest(Digest::SHA1);
+                auto sign_builder = builder;
+                sign_builder.Authorization(TAG_MAC_LENGTH, 128);
+                string tag = SignMessage(keyblob, message, sign_builder);
+                VerifyMessage(keyblob, message, tag, builder);
+            } else if (name.find("rsa-key") != std::string::npos) {
+                builder.Digest(Digest::NONE).Padding(PaddingMode::NONE);
+                string signature = SignMessage(keyblob, message, builder);
+                LocalVerifyMessage(cert, message, signature, builder);
+            } else if (name.find("p256-key") != std::string::npos) {
+                builder.Digest(Digest::SHA1);
+                string signature = SignMessage(keyblob, message, builder);
+                LocalVerifyMessage(cert, message, signature, builder);
+            } else if (name.find("ed25519-key") != std::string::npos) {
+                builder.Digest(Digest::NONE);
+                string signature = SignMessage(keyblob, message, builder);
+                LocalVerifyMessage(cert, message, signature, builder);
+            } else if (name.find("x25519-key") != std::string::npos) {
+                // Generate EC key on same curve locally (with access to private key material).
+                uint8_t localPrivKeyData[32];
+                uint8_t localPubKeyData[32];
+                X25519_keypair(localPubKeyData, localPrivKeyData);
+                EVP_PKEY_Ptr localPrivKey(EVP_PKEY_new_raw_private_key(
+                        EVP_PKEY_X25519, nullptr, localPrivKeyData, sizeof(localPrivKeyData)));
+                // Get encoded form of the public part of the locally generated key.
+                unsigned char* p = nullptr;
+                int localPublicKeySize = i2d_PUBKEY(localPrivKey.get(), &p);
+                ASSERT_GT(localPublicKeySize, 0);
+                vector<uint8_t> localPublicKey(
+                        reinterpret_cast<const uint8_t*>(p),
+                        reinterpret_cast<const uint8_t*>(p + localPublicKeySize));
+                OPENSSL_free(p);
+
+                // Agree on a key between local and KeyMint.
+                string data;
+                ASSERT_EQ(ErrorCode::OK,
+                          Begin(KeyPurpose::AGREE_KEY, keyblob, builder, &out_params));
+                ASSERT_EQ(ErrorCode::OK,
+                          Finish(string(localPublicKey.begin(), localPublicKey.end()), &data));
+                vector<uint8_t> keymint_data(data.begin(), data.end());
+
+                // Extract the public key for the KeyMint key from the cert.
+                X509_Ptr kmKeyCert(parse_cert_blob(cert));
+                ASSERT_NE(kmKeyCert, nullptr);
+                EVP_PKEY_Ptr kmPubKey = EVP_PKEY_Ptr(X509_get_pubkey(kmKeyCert.get()));
+                ASSERT_NE(kmPubKey.get(), nullptr);
+
+                size_t kmPubKeySize = 32;
+                uint8_t kmPubKeyData[32];
+                ASSERT_EQ(1,
+                          EVP_PKEY_get_raw_public_key(kmPubKey.get(), kmPubKeyData, &kmPubKeySize));
+                ASSERT_EQ(kmPubKeySize, 32);
+
+                // Agree on a key between KeyMint and local.
+                uint8_t sharedKey[32];
+                ASSERT_EQ(1, X25519(sharedKey, localPrivKeyData, kmPubKeyData));
+                vector<uint8_t> local_data(sharedKey, sharedKey + 32);
+
+                // Both ways round should agree.
+                EXPECT_EQ(keymint_data, local_data);
+            } else if (name.find("-attest-key") != std::string::npos) {
+                // Covers rsa-attest-key, p256-attest-key, ed25519-attest-key.
+
+                // Use attestation key to sign RSA signing key
+                AttestationKey attest_key;
+                attest_key.keyBlob = keyblob;
+                attest_key.attestKeyParams = builder.vector_data();
+                attest_key.issuerSubjectName = make_name_from_str("Android Keystore Key");
+                vector<uint8_t> attested_key_blob;
+                vector<KeyCharacteristics> attested_key_characteristics;
+                vector<Certificate> attested_key_cert_chain;
+                EXPECT_EQ(ErrorCode::OK,
+                          GenerateKey(AuthorizationSetBuilder()
+                                              .RsaSigningKey(2048, 65537)
+                                              .Authorization(TAG_NO_AUTH_REQUIRED)
+                                              .AttestationChallenge("challenge")
+                                              .AttestationApplicationId("app-id")
+                                              .SetDefaultValidity(),
+                                      attest_key, &attested_key_blob, &attested_key_characteristics,
+                                      &attested_key_cert_chain));
+                CheckedDeleteKey(&attested_key_blob);
+            } else {
+                FAIL() << "Unexpected name: " << name;
+            }
+        }
+    }
+}
+
+// This test target deletes any keys from the keyblob subdirectory that have rollback resistance
+// enabled.
+TEST_P(KeyBlobUpgradeTest, DeleteRRKeyBlobsAfter) {
+    std::string subdir = keyblob_subdir(keyblob_dir, GetParam(), /* create? */ false);
+    if (subdir.empty()) {
+        GTEST_SKIP() << "No keyblob directory provided with (e.g.) --keyblob_dir "
+                        "/data/local/tmp/keymint-blobs";
+    }
+
+    for (std::string name : keyblob_names(SecLevel())) {
+        for (bool with_hidden : {false, true}) {
+            auto builder = AuthorizationSetBuilder();
+            if (with_hidden) {
+                // Build a variant keyblob that requires app_id/app_data
+                builder.Authorization(TAG_APPLICATION_ID, "appid")
+                        .Authorization(TAG_APPLICATION_DATA, "appdata");
+                name += "-hidden";
+            }
+            if (!requires_rr(name)) {
+                std::cerr << "Skipping keyblob file '" << name
+                          << "' which does not use rollback resistance\n";
+                continue;
+            }
+            SCOPED_TRACE(testing::Message() << name);
+            std::vector<uint8_t> keyblob = load_keyblob(subdir, name);
+            if (keyblob.empty()) {
+                std::cerr << "Skipping missing keyblob file '" << name
+                          << "', assuming rollback resistance unavailable\n";
+                continue;
+            }
+
+            // Delete the key
+            ASSERT_EQ(ErrorCode::OK, DeleteKey(&keyblob));
+
+            // Remove all files relating to the deleted key.
+            std::cerr << "Deleting files for deleted key '" << name << ";";
+            delete_keyblob(subdir, name);
+
+            // Attempting to use the keyblob after deletion should fail.
+            AuthorizationSet out_params;
+            if (name.find("aes-key") != std::string::npos) {
+                builder.BlockMode(BlockMode::ECB).Padding(PaddingMode::PKCS7);
+                EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB,
+                          Begin(KeyPurpose::ENCRYPT, keyblob, builder, &out_params));
+            } else {
+                FAIL() << "Unexpected name: " << name;
+            }
+        }
+    }
+}
+
+INSTANTIATE_KEYMINT_AIDL_TEST(KeyBlobUpgradeTest);
+
+}  // 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 43ad30a..6c012fa 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -184,6 +184,7 @@
 
 bool KeyMintAidlTestBase::arm_deleteAllKeys = false;
 bool KeyMintAidlTestBase::dump_Attestations = false;
+std::string KeyMintAidlTestBase::keyblob_dir;
 
 uint32_t KeyMintAidlTestBase::boot_patch_level(
         const vector<KeyCharacteristics>& key_characteristics) {
@@ -946,9 +947,15 @@
                                              const AuthorizationSet& params) {
     SCOPED_TRACE("LocalVerifyMessage");
 
-    // Retrieve the public key from the leaf certificate.
     ASSERT_GT(cert_chain_.size(), 0);
-    X509_Ptr key_cert(parse_cert_blob(cert_chain_[0].encodedCertificate));
+    LocalVerifyMessage(cert_chain_[0].encodedCertificate, message, signature, params);
+}
+
+void KeyMintAidlTestBase::LocalVerifyMessage(const vector<uint8_t>& der_cert, const string& message,
+                                             const string& signature,
+                                             const AuthorizationSet& params) {
+    // Retrieve the public key from the leaf certificate.
+    X509_Ptr key_cert(parse_cert_blob(der_cert));
     ASSERT_TRUE(key_cert.get());
     EVP_PKEY_Ptr pub_key(X509_get_pubkey(key_cert.get()));
     ASSERT_TRUE(pub_key.get());
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
index 5b09ca5..908eeab 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
@@ -64,6 +64,10 @@
     static bool arm_deleteAllKeys;
     static bool dump_Attestations;
 
+    // Directory to store/retrieve keyblobs, using subdirectories named for the
+    // KeyMint instance in question (e.g. "./default/", "./strongbox/").
+    static std::string keyblob_dir;
+
     void SetUp() override;
     void TearDown() override {
         if (key_blob_.size()) {
@@ -206,6 +210,8 @@
                        const string& signature, const AuthorizationSet& params);
     void VerifyMessage(const string& message, const string& signature,
                        const AuthorizationSet& params);
+    void LocalVerifyMessage(const vector<uint8_t>& der_cert, const string& message,
+                            const string& signature, const AuthorizationSet& params);
     void LocalVerifyMessage(const string& message, const string& signature,
                             const AuthorizationSet& params);
 
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index ca18082..342b926 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -8649,6 +8649,15 @@
                 // interactions.
                 aidl::android::hardware::security::keymint::test::check_boot_pl = false;
             }
+            if (std::string(argv[i]) == "--keyblob_dir") {
+                if (i + 1 >= argc) {
+                    std::cerr << "Missing argument for --keyblob_dir\n";
+                    return 1;
+                }
+                aidl::android::hardware::security::keymint::test::KeyMintAidlTestBase::keyblob_dir =
+                        std::string(argv[i + 1]);
+                ++i;
+            }
         }
     }
     return RUN_ALL_TESTS();