Merge "Add setDtimMultiplier() and its implementation."
diff --git a/audio/aidl/Android.bp b/audio/aidl/Android.bp
index 691cf34..7e682af 100644
--- a/audio/aidl/Android.bp
+++ b/audio/aidl/Android.bp
@@ -41,6 +41,7 @@
         "android/hardware/audio/common/SinkMetadata.aidl",
         "android/hardware/audio/common/SourceMetadata.aidl",
     ],
+    frozen: true,
     imports: [
         "android.media.audio.common.types-V2",
     ],
diff --git a/audio/aidl/TEST_MAPPING b/audio/aidl/TEST_MAPPING
index 6473d23..484320f 100644
--- a/audio/aidl/TEST_MAPPING
+++ b/audio/aidl/TEST_MAPPING
@@ -2,6 +2,18 @@
   "presubmit": [
     {
       "name": "VtsHalAudioCoreTargetTest"
+    },
+    {
+      "name": "VtsHalAudioEffectFactoryTargetTest"
+    },
+    {
+      "name": "VtsHalAudioEffectTargetTest"
+    },
+    {
+      "name": "VtsHalEqualizerTargetTest"
+    },
+    {
+      "name": "VtsHalLoudnessEnhancerTargetTest"
     }
   ]
 }
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IConfig.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IConfig.aidl
index 163b7a0..9ce45bb 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IConfig.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IConfig.aidl
@@ -35,4 +35,5 @@
 @VintfStability
 interface IConfig {
   android.hardware.audio.core.SurroundSoundConfig getSurroundSoundConfig();
+  android.media.audio.common.AudioHalEngineConfig getEngineConfig();
 }
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 979ebb8..09ad015 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,6 +36,8 @@
 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;
diff --git a/audio/aidl/android/hardware/audio/core/IConfig.aidl b/audio/aidl/android/hardware/audio/core/IConfig.aidl
index c8ba6be..094d233 100644
--- a/audio/aidl/android/hardware/audio/core/IConfig.aidl
+++ b/audio/aidl/android/hardware/audio/core/IConfig.aidl
@@ -17,6 +17,7 @@
 package android.hardware.audio.core;
 
 import android.hardware.audio.core.SurroundSoundConfig;
+import android.media.audio.common.AudioHalEngineConfig;
 
 /**
  * This interface provides system-wide configuration parameters for audio I/O
@@ -34,4 +35,19 @@
      * @return The surround sound configuration
      */
     SurroundSoundConfig getSurroundSoundConfig();
+    /**
+     * Returns the configuration items used to determine the audio policy engine
+     * flavor and initial configuration.
+     *
+     * Engine flavor is determined by presence of capSpecificConfig, which must
+     * only be present if the device uses the Configurable Audio Policy (CAP)
+     * engine. Clients normally use the default audio policy engine. The client
+     * will use the CAP engine only when capSpecificConfig has a non-null value.
+     *
+     * This method is expected to only be called during the initialization of
+     * the audio policy engine, and must always return the same result.
+     *
+     * @return The engine configuration
+     */
+    AudioHalEngineConfig getEngineConfig();
 }
diff --git a/audio/aidl/android/hardware/audio/effect/BassBoost.aidl b/audio/aidl/android/hardware/audio/effect/BassBoost.aidl
index 810c188..9e5d8aa 100644
--- a/audio/aidl/android/hardware/audio/effect/BassBoost.aidl
+++ b/audio/aidl/android/hardware/audio/effect/BassBoost.aidl
@@ -59,6 +59,16 @@
     }
 
     /**
+     * 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
diff --git a/audio/aidl/default/Android.bp b/audio/aidl/default/Android.bp
index 2b9ed5b..f2cebbf 100644
--- a/audio/aidl/default/Android.bp
+++ b/audio/aidl/default/Android.bp
@@ -18,11 +18,14 @@
         "libfmq",
         "libstagefright_foundation",
         "libutils",
+        "libxml2",
         "android.hardware.common-V2-ndk",
         "android.hardware.common.fmq-V1-ndk",
     ],
     header_libs: [
+        "libaudio_system_headers",
         "libaudioaidl_headers",
+        "libxsdc-utils",
     ],
 }
 
@@ -35,12 +38,26 @@
     ],
     export_include_dirs: ["include"],
     srcs: [
+        "AudioPolicyConfigXmlConverter.cpp",
         "Config.cpp",
         "Configuration.cpp",
+        "EngineConfigXmlConverter.cpp",
         "Module.cpp",
         "Stream.cpp",
         "Telephony.cpp",
     ],
+    generated_sources: [
+        "audio_policy_configuration_aidl_default",
+        "audio_policy_engine_configuration_aidl_default",
+    ],
+    generated_headers: [
+        "audio_policy_configuration_aidl_default",
+        "audio_policy_engine_configuration_aidl_default",
+    ],
+    export_generated_headers: [
+        "audio_policy_configuration_aidl_default",
+        "audio_policy_engine_configuration_aidl_default",
+    ],
     visibility: [
         ":__subpackages__",
     ],
diff --git a/audio/aidl/default/AudioPolicyConfigXmlConverter.cpp b/audio/aidl/default/AudioPolicyConfigXmlConverter.cpp
new file mode 100644
index 0000000..6290912
--- /dev/null
+++ b/audio/aidl/default/AudioPolicyConfigXmlConverter.cpp
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <fcntl.h>
+#include <inttypes.h>
+#include <unistd.h>
+
+#include <functional>
+#include <unordered_map>
+
+#include <aidl/android/media/audio/common/AudioHalEngineConfig.h>
+#include <system/audio-base-utils.h>
+
+#include "core-impl/AudioPolicyConfigXmlConverter.h"
+
+using aidl::android::media::audio::common::AudioHalEngineConfig;
+using aidl::android::media::audio::common::AudioHalVolumeCurve;
+using aidl::android::media::audio::common::AudioHalVolumeGroup;
+using aidl::android::media::audio::common::AudioStreamType;
+
+namespace xsd = android::audio::policy::configuration;
+
+namespace aidl::android::hardware::audio::core::internal {
+
+static const int kDefaultVolumeIndexMin = 0;
+static const int kDefaultVolumeIndexMax = 100;
+static const int KVolumeIndexDeferredToAudioService = -1;
+/**
+ * Valid curve points take the form "<index>,<attenuationMb>", where the index
+ * must be in the range [0,100]. kInvalidCurvePointIndex is used to indicate
+ * that a point was formatted incorrectly (e.g. if a vendor accidentally typed a
+ * '.' instead of a ',' in their XML) -- using such a curve point will result in
+ * failed VTS tests.
+ */
+static const int8_t kInvalidCurvePointIndex = -1;
+
+AudioHalVolumeCurve::CurvePoint AudioPolicyConfigXmlConverter::convertCurvePointToAidl(
+        const std::string& xsdcCurvePoint) {
+    AudioHalVolumeCurve::CurvePoint aidlCurvePoint{};
+    if (sscanf(xsdcCurvePoint.c_str(), "%" SCNd8 ",%d", &aidlCurvePoint.index,
+               &aidlCurvePoint.attenuationMb) != 2) {
+        aidlCurvePoint.index = kInvalidCurvePointIndex;
+    }
+    return aidlCurvePoint;
+}
+
+AudioHalVolumeCurve AudioPolicyConfigXmlConverter::convertVolumeCurveToAidl(
+        const xsd::Volume& xsdcVolumeCurve) {
+    AudioHalVolumeCurve aidlVolumeCurve;
+    aidlVolumeCurve.deviceCategory =
+            static_cast<AudioHalVolumeCurve::DeviceCategory>(xsdcVolumeCurve.getDeviceCategory());
+    if (xsdcVolumeCurve.hasRef()) {
+        if (mVolumesReferenceMap.empty()) {
+            mVolumesReferenceMap = generateReferenceMap<xsd::Volumes, xsd::Reference>(
+                    getXsdcConfig()->getVolumes());
+        }
+        aidlVolumeCurve.curvePoints =
+                convertCollectionToAidl<std::string, AudioHalVolumeCurve::CurvePoint>(
+                        mVolumesReferenceMap.at(xsdcVolumeCurve.getRef()).getPoint(),
+                        std::bind(&AudioPolicyConfigXmlConverter::convertCurvePointToAidl, this,
+                                  std::placeholders::_1));
+    } else {
+        aidlVolumeCurve.curvePoints =
+                convertCollectionToAidl<std::string, AudioHalVolumeCurve::CurvePoint>(
+                        xsdcVolumeCurve.getPoint(),
+                        std::bind(&AudioPolicyConfigXmlConverter::convertCurvePointToAidl, this,
+                                  std::placeholders::_1));
+    }
+    return aidlVolumeCurve;
+}
+
+void AudioPolicyConfigXmlConverter::mapStreamToVolumeCurve(const xsd::Volume& xsdcVolumeCurve) {
+    mStreamToVolumeCurvesMap[xsdcVolumeCurve.getStream()].push_back(
+            convertVolumeCurveToAidl(xsdcVolumeCurve));
+}
+
+const AudioHalEngineConfig& AudioPolicyConfigXmlConverter::getAidlEngineConfig() {
+    if (mAidlEngineConfig.volumeGroups.empty() && getXsdcConfig() &&
+        getXsdcConfig()->hasVolumes()) {
+        parseVolumes();
+    }
+    return mAidlEngineConfig;
+}
+
+void AudioPolicyConfigXmlConverter::mapStreamsToVolumeCurves() {
+    if (getXsdcConfig()->hasVolumes()) {
+        for (const xsd::Volumes& xsdcWrapperType : getXsdcConfig()->getVolumes()) {
+            for (const xsd::Volume& xsdcVolume : xsdcWrapperType.getVolume()) {
+                mapStreamToVolumeCurve(xsdcVolume);
+            }
+        }
+    }
+}
+
+void AudioPolicyConfigXmlConverter::addVolumeGroupstoEngineConfig() {
+    for (const auto& [xsdcStream, volumeCurves] : mStreamToVolumeCurvesMap) {
+        AudioHalVolumeGroup volumeGroup;
+        volumeGroup.name = xsd::toString(xsdcStream);
+        if (static_cast<int>(xsdcStream) >= AUDIO_STREAM_PUBLIC_CNT) {
+            volumeGroup.minIndex = kDefaultVolumeIndexMin;
+            volumeGroup.maxIndex = kDefaultVolumeIndexMax;
+        } else {
+            volumeGroup.minIndex = KVolumeIndexDeferredToAudioService;
+            volumeGroup.maxIndex = KVolumeIndexDeferredToAudioService;
+        }
+        volumeGroup.volumeCurves = volumeCurves;
+        mAidlEngineConfig.volumeGroups.push_back(std::move(volumeGroup));
+    }
+}
+
+void AudioPolicyConfigXmlConverter::parseVolumes() {
+    if (mStreamToVolumeCurvesMap.empty() && getXsdcConfig()->hasVolumes()) {
+        mapStreamsToVolumeCurves();
+        addVolumeGroupstoEngineConfig();
+    }
+}
+}  // namespace aidl::android::hardware::audio::core::internal
diff --git a/audio/aidl/default/Config.cpp b/audio/aidl/default/Config.cpp
index 0fdd5b4..87c0ace 100644
--- a/audio/aidl/default/Config.cpp
+++ b/audio/aidl/default/Config.cpp
@@ -13,10 +13,17 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#define LOG_TAG "AHAL_Module"
+
+#define LOG_TAG "AHAL_Config"
 #include <android-base/logging.h>
 
+#include <system/audio_config.h>
+
+#include "core-impl/AudioPolicyConfigXmlConverter.h"
 #include "core-impl/Config.h"
+#include "core-impl/EngineConfigXmlConverter.h"
+
+using aidl::android::media::audio::common::AudioHalEngineConfig;
 
 namespace aidl::android::hardware::audio::core {
 ndk::ScopedAStatus Config::getSurroundSoundConfig(SurroundSoundConfig* _aidl_return) {
@@ -26,4 +33,24 @@
     LOG(DEBUG) << __func__ << ": returning " << _aidl_return->toString();
     return ndk::ScopedAStatus::ok();
 }
+
+ndk::ScopedAStatus Config::getEngineConfig(AudioHalEngineConfig* _aidl_return) {
+    static const AudioHalEngineConfig returnEngCfg = [this]() {
+        AudioHalEngineConfig engConfig;
+        if (mEngConfigConverter.getStatus() == ::android::OK) {
+            engConfig = mEngConfigConverter.getAidlEngineConfig();
+        } else {
+            LOG(INFO) << __func__ << mEngConfigConverter.getError();
+            if (mAudioPolicyConverter.getStatus() == ::android::OK) {
+                engConfig = mAudioPolicyConverter.getAidlEngineConfig();
+            } else {
+                LOG(WARNING) << __func__ << mAudioPolicyConverter.getError();
+            }
+        }
+        return engConfig;
+    }();
+    *_aidl_return = returnEngCfg;
+    LOG(DEBUG) << __func__ << ": returning " << _aidl_return->toString();
+    return ndk::ScopedAStatus::ok();
+}
 }  // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/EffectImpl.cpp b/audio/aidl/default/EffectImpl.cpp
index 2754bb6..0d40cce 100644
--- a/audio/aidl/default/EffectImpl.cpp
+++ b/audio/aidl/default/EffectImpl.cpp
@@ -25,41 +25,33 @@
                                     const std::optional<Parameter::Specific>& specific,
                                     OpenEffectReturn* ret) {
     LOG(DEBUG) << __func__;
-    {
-        std::lock_guard lg(mMutex);
-        RETURN_OK_IF(mState != State::INIT);
-        mContext = createContext(common);
-        RETURN_IF(!mContext, EX_ILLEGAL_ARGUMENT, "createContextFailed");
-        setContext(mContext);
-    }
+    RETURN_OK_IF(mState != State::INIT);
+    auto context = createContext(common);
+    RETURN_IF(!context, EX_NULL_POINTER, "createContextFailed");
 
     RETURN_IF_ASTATUS_NOT_OK(setParameterCommon(common), "setCommParamErr");
     if (specific.has_value()) {
         RETURN_IF_ASTATUS_NOT_OK(setParameterSpecific(specific.value()), "setSpecParamErr");
     }
 
-    RETURN_IF(createThread(LOG_TAG) != RetCode::SUCCESS, EX_UNSUPPORTED_OPERATION,
+    mState = State::IDLE;
+    context->dupeFmq(ret);
+    RETURN_IF(createThread(context, getEffectName()) != RetCode::SUCCESS, EX_UNSUPPORTED_OPERATION,
               "FailedToCreateWorker");
-
-    {
-        std::lock_guard lg(mMutex);
-        mContext->dupeFmq(ret);
-        mState = State::IDLE;
-    }
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus EffectImpl::close() {
-    std::lock_guard lg(mMutex);
     RETURN_OK_IF(mState == State::INIT);
     RETURN_IF(mState == State::PROCESSING, EX_ILLEGAL_STATE, "closeAtProcessing");
 
     // stop the worker thread, ignore the return code
     RETURN_IF(destroyThread() != RetCode::SUCCESS, EX_UNSUPPORTED_OPERATION,
               "FailedToDestroyWorker");
+    mState = State::INIT;
     RETURN_IF(releaseContext() != RetCode::SUCCESS, EX_UNSUPPORTED_OPERATION,
               "FailedToCreateWorker");
-    mState = State::INIT;
+
     LOG(DEBUG) << __func__;
     return ndk::ScopedAStatus::ok();
 }
@@ -113,29 +105,30 @@
 }
 
 ndk::ScopedAStatus EffectImpl::setParameterCommon(const Parameter& param) {
-    std::lock_guard lg(mMutex);
-    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+    auto context = getContext();
+    RETURN_IF(!context, EX_NULL_POINTER, "nullContext");
+
     auto tag = param.getTag();
     switch (tag) {
         case Parameter::common:
-            RETURN_IF(mContext->setCommon(param.get<Parameter::common>()) != RetCode::SUCCESS,
+            RETURN_IF(context->setCommon(param.get<Parameter::common>()) != RetCode::SUCCESS,
                       EX_ILLEGAL_ARGUMENT, "setCommFailed");
             break;
         case Parameter::deviceDescription:
-            RETURN_IF(mContext->setOutputDevice(param.get<Parameter::deviceDescription>()) !=
+            RETURN_IF(context->setOutputDevice(param.get<Parameter::deviceDescription>()) !=
                               RetCode::SUCCESS,
                       EX_ILLEGAL_ARGUMENT, "setDeviceFailed");
             break;
         case Parameter::mode:
-            RETURN_IF(mContext->setAudioMode(param.get<Parameter::mode>()) != RetCode::SUCCESS,
+            RETURN_IF(context->setAudioMode(param.get<Parameter::mode>()) != RetCode::SUCCESS,
                       EX_ILLEGAL_ARGUMENT, "setModeFailed");
             break;
         case Parameter::source:
-            RETURN_IF(mContext->setAudioSource(param.get<Parameter::source>()) != RetCode::SUCCESS,
+            RETURN_IF(context->setAudioSource(param.get<Parameter::source>()) != RetCode::SUCCESS,
                       EX_ILLEGAL_ARGUMENT, "setSourceFailed");
             break;
         case Parameter::volumeStereo:
-            RETURN_IF(mContext->setVolumeStereo(param.get<Parameter::volumeStereo>()) !=
+            RETURN_IF(context->setVolumeStereo(param.get<Parameter::volumeStereo>()) !=
                               RetCode::SUCCESS,
                       EX_ILLEGAL_ARGUMENT, "setVolumeStereoFailed");
             break;
@@ -149,27 +142,28 @@
 }
 
 ndk::ScopedAStatus EffectImpl::getParameterCommon(const Parameter::Tag& tag, Parameter* param) {
-    std::lock_guard lg(mMutex);
-    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+    auto context = getContext();
+    RETURN_IF(!context, EX_NULL_POINTER, "nullContext");
+
     switch (tag) {
         case Parameter::common: {
-            param->set<Parameter::common>(mContext->getCommon());
+            param->set<Parameter::common>(context->getCommon());
             break;
         }
         case Parameter::deviceDescription: {
-            param->set<Parameter::deviceDescription>(mContext->getOutputDevice());
+            param->set<Parameter::deviceDescription>(context->getOutputDevice());
             break;
         }
         case Parameter::mode: {
-            param->set<Parameter::mode>(mContext->getAudioMode());
+            param->set<Parameter::mode>(context->getAudioMode());
             break;
         }
         case Parameter::source: {
-            param->set<Parameter::source>(mContext->getAudioSource());
+            param->set<Parameter::source>(context->getAudioSource());
             break;
         }
         case Parameter::volumeStereo: {
-            param->set<Parameter::volumeStereo>(mContext->getVolumeStereo());
+            param->set<Parameter::volumeStereo>(context->getVolumeStereo());
             break;
         }
         default: {
@@ -182,39 +176,30 @@
 }
 
 ndk::ScopedAStatus EffectImpl::getState(State* state) {
-    std::lock_guard lg(mMutex);
     *state = mState;
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus EffectImpl::command(CommandId command) {
-    std::lock_guard lg(mMutex);
+    RETURN_IF(mState == State::INIT, EX_ILLEGAL_STATE, "CommandStateError");
     LOG(DEBUG) << __func__ << ": receive command: " << toString(command) << " at state "
                << toString(mState);
-    RETURN_IF(mState == State::INIT, EX_ILLEGAL_STATE, "CommandStateError");
-    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
 
     switch (command) {
         case CommandId::START:
             RETURN_IF(mState == State::INIT, EX_ILLEGAL_STATE, "instanceNotOpen");
             RETURN_OK_IF(mState == State::PROCESSING);
-            RETURN_IF_ASTATUS_NOT_OK(commandStart(), "commandStartFailed");
-            mState = State::PROCESSING;
+            RETURN_IF_ASTATUS_NOT_OK(commandImpl(command), "commandImplFailed");
             startThread();
-            return ndk::ScopedAStatus::ok();
+            mState = State::PROCESSING;
+            break;
         case CommandId::STOP:
-            RETURN_OK_IF(mState == State::IDLE);
-            mState = State::IDLE;
-            RETURN_IF_ASTATUS_NOT_OK(commandStop(), "commandStopFailed");
-            stopThread();
-            return ndk::ScopedAStatus::ok();
         case CommandId::RESET:
             RETURN_OK_IF(mState == State::IDLE);
-            mState = State::IDLE;
-            RETURN_IF_ASTATUS_NOT_OK(commandStop(), "commandStopFailed");
             stopThread();
-            mContext->resetBuffer();
-            return ndk::ScopedAStatus::ok();
+            RETURN_IF_ASTATUS_NOT_OK(commandImpl(command), "commandImplFailed");
+            mState = State::IDLE;
+            break;
         default:
             LOG(ERROR) << __func__ << " instance still processing";
             return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
@@ -224,6 +209,15 @@
     return ndk::ScopedAStatus::ok();
 }
 
+ndk::ScopedAStatus EffectImpl::commandImpl(CommandId command) {
+    auto context = getContext();
+    RETURN_IF(!context, EX_NULL_POINTER, "nullContext");
+    if (command == CommandId::RESET) {
+        context->resetBuffer();
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
 void EffectImpl::cleanUp() {
     command(CommandId::STOP);
     close();
@@ -238,19 +232,12 @@
 }
 
 // A placeholder processing implementation to copy samples from input to output
-IEffect::Status EffectImpl::effectProcessImpl(float* in, float* out, int processSamples) {
-    // lock before access context/parameters
-    std::lock_guard lg(mMutex);
-    IEffect::Status status = {EX_NULL_POINTER, 0, 0};
-    RETURN_VALUE_IF(!mContext, status, "nullContext");
-    auto frameSize = mContext->getInputFrameSize();
-    RETURN_VALUE_IF(0 == frameSize, status, "frameSizeIs0");
-    LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << processSamples
-               << " frames " << processSamples * sizeof(float) / frameSize;
-    for (int i = 0; i < processSamples; i++) {
+IEffect::Status EffectImpl::effectProcessImpl(float* in, float* out, int samples) {
+    for (int i = 0; i < samples; i++) {
         *out++ = *in++;
     }
-    LOG(DEBUG) << __func__ << " done processing " << processSamples << " samples";
-    return {STATUS_OK, processSamples, processSamples};
+    LOG(DEBUG) << __func__ << " done processing " << samples << " samples";
+    return {STATUS_OK, samples, samples};
 }
+
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/EffectThread.cpp b/audio/aidl/default/EffectThread.cpp
index 80f120b..2b3513d 100644
--- a/audio/aidl/default/EffectThread.cpp
+++ b/audio/aidl/default/EffectThread.cpp
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <memory>
 #define LOG_TAG "AHAL_EffectThread"
 #include <android-base/logging.h>
 #include <pthread.h>
@@ -32,13 +33,18 @@
     LOG(DEBUG) << __func__ << " done";
 };
 
-RetCode EffectThread::createThread(const std::string& name, const int priority) {
+RetCode EffectThread::createThread(std::shared_ptr<EffectContext> context, const std::string& name,
+                                   const int priority) {
     if (mThread.joinable()) {
         LOG(WARNING) << __func__ << " thread already created, no-op";
         return RetCode::SUCCESS;
     }
     mName = name;
     mPriority = priority;
+    {
+        std::lock_guard lg(mThreadMutex);
+        mThreadContext = std::move(context);
+    }
     mThread = std::thread(&EffectThread::threadLoop, this);
     LOG(DEBUG) << __func__ << " " << name << " priority " << mPriority << " done";
     return RetCode::SUCCESS;
@@ -46,7 +52,7 @@
 
 RetCode EffectThread::destroyThread() {
     {
-        std::lock_guard lg(mMutex);
+        std::lock_guard lg(mThreadMutex);
         mStop = mExit = true;
     }
     mCv.notify_one();
@@ -54,6 +60,11 @@
     if (mThread.joinable()) {
         mThread.join();
     }
+
+    {
+        std::lock_guard lg(mThreadMutex);
+        mThreadContext.reset();
+    }
     LOG(DEBUG) << __func__ << " done";
     return RetCode::SUCCESS;
 }
@@ -65,7 +76,7 @@
     }
 
     {
-        std::lock_guard lg(mMutex);
+        std::lock_guard lg(mThreadMutex);
         if (!mStop) {
             LOG(WARNING) << __func__ << " already start";
             return RetCode::SUCCESS;
@@ -85,7 +96,7 @@
     }
 
     {
-        std::lock_guard lg(mMutex);
+        std::lock_guard lg(mThreadMutex);
         if (mStop) {
             LOG(WARNING) << __func__ << " already stop";
             return RetCode::SUCCESS;
@@ -97,13 +108,13 @@
 }
 
 void EffectThread::threadLoop() {
-    pthread_setname_np(pthread_self(), mName.substr(0, MAX_TASK_COMM_LEN - 1).c_str());
+    pthread_setname_np(pthread_self(), mName.substr(0, kMaxTaskNameLen - 1).c_str());
     setpriority(PRIO_PROCESS, 0, mPriority);
     while (true) {
         bool needExit = false;
         {
-            std::unique_lock l(mMutex);
-            mCv.wait(l, [&]() REQUIRES(mMutex) {
+            std::unique_lock l(mThreadMutex);
+            mCv.wait(l, [&]() REQUIRES(mThreadMutex) {
                 needExit = mExit;
                 return mExit || !mStop;
             });
@@ -112,9 +123,41 @@
             LOG(WARNING) << __func__ << " EXIT!";
             return;
         }
-        // process without lock
+
         process();
     }
 }
 
+void EffectThread::process() {
+    std::shared_ptr<EffectContext> context;
+    {
+        std::lock_guard lg(mThreadMutex);
+        context = mThreadContext;
+        RETURN_VALUE_IF(!context, void(), "nullContext");
+    }
+    std::shared_ptr<EffectContext::StatusMQ> statusMQ = context->getStatusFmq();
+    std::shared_ptr<EffectContext::DataMQ> inputMQ = context->getInputDataFmq();
+    std::shared_ptr<EffectContext::DataMQ> outputMQ = context->getOutputDataFmq();
+    auto buffer = context->getWorkBuffer();
+
+    // Only this worker will read from input data MQ and write to output data MQ.
+    auto readSamples = inputMQ->availableToRead(), writeSamples = outputMQ->availableToWrite();
+    if (readSamples && writeSamples) {
+        auto processSamples = std::min(readSamples, writeSamples);
+        LOG(DEBUG) << __func__ << " available to read " << readSamples << " available to write "
+                   << writeSamples << " process " << processSamples;
+
+        inputMQ->read(buffer, processSamples);
+
+        // call effectProcessImpl without lock
+        IEffect::Status status = effectProcessImpl(buffer, buffer, processSamples);
+        outputMQ->write(buffer, status.fmqProduced);
+        statusMQ->writeBlocking(&status, 1);
+        LOG(DEBUG) << __func__ << " done processing, effect consumed " << status.fmqConsumed
+                   << " produced " << status.fmqProduced;
+    } else {
+        // TODO: maybe add some sleep here to avoid busy waiting
+    }
+}
+
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/EngineConfigXmlConverter.cpp b/audio/aidl/default/EngineConfigXmlConverter.cpp
new file mode 100644
index 0000000..71b4b0e
--- /dev/null
+++ b/audio/aidl/default/EngineConfigXmlConverter.cpp
@@ -0,0 +1,303 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <fcntl.h>
+#include <inttypes.h>
+#include <unistd.h>
+#include <functional>
+#include <unordered_map>
+
+#include <aidl/android/media/audio/common/AudioHalEngineConfig.h>
+
+#include "core-impl/EngineConfigXmlConverter.h"
+
+using aidl::android::media::audio::common::AudioAttributes;
+using aidl::android::media::audio::common::AudioContentType;
+using aidl::android::media::audio::common::AudioFlag;
+using aidl::android::media::audio::common::AudioHalAttributesGroup;
+using aidl::android::media::audio::common::AudioHalCapCriterion;
+using aidl::android::media::audio::common::AudioHalCapCriterionType;
+using aidl::android::media::audio::common::AudioHalEngineConfig;
+using aidl::android::media::audio::common::AudioHalProductStrategy;
+using aidl::android::media::audio::common::AudioHalVolumeCurve;
+using aidl::android::media::audio::common::AudioHalVolumeGroup;
+using aidl::android::media::audio::common::AudioProductStrategyType;
+using aidl::android::media::audio::common::AudioSource;
+using aidl::android::media::audio::common::AudioStreamType;
+using aidl::android::media::audio::common::AudioUsage;
+
+namespace xsd = android::audio::policy::engine::configuration;
+
+namespace aidl::android::hardware::audio::core::internal {
+
+/**
+ * Valid curve points take the form "<index>,<attenuationMb>", where the index
+ * must be in the range [0,100]. kInvalidCurvePointIndex is used to indicate
+ * that a point was formatted incorrectly (e.g. if a vendor accidentally typed a
+ * '.' instead of a ',' in their XML)-- using such a curve point will result in
+ * failed VTS tests.
+ */
+static const int8_t kInvalidCurvePointIndex = -1;
+
+void EngineConfigXmlConverter::initProductStrategyMap() {
+#define STRATEGY_ENTRY(name) {"STRATEGY_" #name, static_cast<int>(AudioProductStrategyType::name)}
+
+    mProductStrategyMap = {STRATEGY_ENTRY(MEDIA),
+                           STRATEGY_ENTRY(PHONE),
+                           STRATEGY_ENTRY(SONIFICATION),
+                           STRATEGY_ENTRY(SONIFICATION_RESPECTFUL),
+                           STRATEGY_ENTRY(DTMF),
+                           STRATEGY_ENTRY(ENFORCED_AUDIBLE),
+                           STRATEGY_ENTRY(TRANSMITTED_THROUGH_SPEAKER),
+                           STRATEGY_ENTRY(ACCESSIBILITY)};
+#undef STRATEGY_ENTRY
+}
+
+int EngineConfigXmlConverter::convertProductStrategyNameToAidl(
+        const std::string& xsdcProductStrategyName) {
+    const auto [it, success] = mProductStrategyMap.insert(
+            std::make_pair(xsdcProductStrategyName, mNextVendorStrategy));
+    if (success) {
+        mNextVendorStrategy++;
+    }
+    return it->second;
+}
+
+bool isDefaultAudioAttributes(const AudioAttributes& attributes) {
+    return ((attributes.contentType == AudioContentType::UNKNOWN) &&
+            (attributes.usage == AudioUsage::UNKNOWN) &&
+            (attributes.source == AudioSource::DEFAULT) && (attributes.flags == 0) &&
+            (attributes.tags.empty()));
+}
+
+AudioAttributes EngineConfigXmlConverter::convertAudioAttributesToAidl(
+        const xsd::AttributesType& xsdcAudioAttributes) {
+    if (xsdcAudioAttributes.hasAttributesRef()) {
+        if (mAttributesReferenceMap.empty()) {
+            mAttributesReferenceMap =
+                    generateReferenceMap<xsd::AttributesRef, xsd::AttributesRefType>(
+                            getXsdcConfig()->getAttributesRef());
+        }
+        return convertAudioAttributesToAidl(
+                *(mAttributesReferenceMap.at(xsdcAudioAttributes.getAttributesRef())
+                          .getFirstAttributes()));
+    }
+    AudioAttributes aidlAudioAttributes;
+    if (xsdcAudioAttributes.hasContentType()) {
+        aidlAudioAttributes.contentType = static_cast<AudioContentType>(
+                xsdcAudioAttributes.getFirstContentType()->getValue());
+    }
+    if (xsdcAudioAttributes.hasUsage()) {
+        aidlAudioAttributes.usage =
+                static_cast<AudioUsage>(xsdcAudioAttributes.getFirstUsage()->getValue());
+    }
+    if (xsdcAudioAttributes.hasSource()) {
+        aidlAudioAttributes.source =
+                static_cast<AudioSource>(xsdcAudioAttributes.getFirstSource()->getValue());
+    }
+    if (xsdcAudioAttributes.hasFlags()) {
+        std::vector<xsd::FlagType> xsdcFlagTypeVec =
+                xsdcAudioAttributes.getFirstFlags()->getValue();
+        for (const xsd::FlagType& xsdcFlagType : xsdcFlagTypeVec) {
+            if (xsdcFlagType != xsd::FlagType::AUDIO_FLAG_NONE) {
+                aidlAudioAttributes.flags |= 1 << (static_cast<int>(xsdcFlagType) - 1);
+            }
+        }
+    }
+    if (xsdcAudioAttributes.hasBundle()) {
+        const xsd::BundleType* xsdcBundle = xsdcAudioAttributes.getFirstBundle();
+        aidlAudioAttributes.tags[0] = xsdcBundle->getKey() + "=" + xsdcBundle->getValue();
+    }
+    if (isDefaultAudioAttributes(aidlAudioAttributes)) {
+        mDefaultProductStrategyId = std::optional<int>{-1};
+    }
+    return aidlAudioAttributes;
+}
+
+AudioHalAttributesGroup EngineConfigXmlConverter::convertAttributesGroupToAidl(
+        const xsd::AttributesGroup& xsdcAttributesGroup) {
+    AudioHalAttributesGroup aidlAttributesGroup;
+    static const int kStreamTypeEnumOffset =
+            static_cast<int>(xsd::Stream::AUDIO_STREAM_VOICE_CALL) -
+            static_cast<int>(AudioStreamType::VOICE_CALL);
+    aidlAttributesGroup.streamType = static_cast<AudioStreamType>(
+            static_cast<int>(xsdcAttributesGroup.getStreamType()) - kStreamTypeEnumOffset);
+    aidlAttributesGroup.volumeGroupName = xsdcAttributesGroup.getVolumeGroup();
+    if (xsdcAttributesGroup.hasAttributes_optional()) {
+        aidlAttributesGroup.attributes =
+                convertCollectionToAidl<xsd::AttributesType, AudioAttributes>(
+                        xsdcAttributesGroup.getAttributes_optional(),
+                        std::bind(&EngineConfigXmlConverter::convertAudioAttributesToAidl, this,
+                                  std::placeholders::_1));
+    } else if (xsdcAttributesGroup.hasContentType_optional() ||
+               xsdcAttributesGroup.hasUsage_optional() ||
+               xsdcAttributesGroup.hasSource_optional() ||
+               xsdcAttributesGroup.hasFlags_optional() ||
+               xsdcAttributesGroup.hasBundle_optional()) {
+        aidlAttributesGroup.attributes.push_back(convertAudioAttributesToAidl(xsd::AttributesType(
+                xsdcAttributesGroup.getContentType_optional(),
+                xsdcAttributesGroup.getUsage_optional(), xsdcAttributesGroup.getSource_optional(),
+                xsdcAttributesGroup.getFlags_optional(), xsdcAttributesGroup.getBundle_optional(),
+                std::nullopt)));
+
+    } else {
+        // do nothing;
+        // TODO: check if this is valid or if we should treat as an error.
+        // Currently, attributes are not mandatory in schema, but an AttributesGroup
+        // without attributes does not make much sense.
+    }
+    return aidlAttributesGroup;
+}
+
+AudioHalProductStrategy EngineConfigXmlConverter::convertProductStrategyToAidl(
+        const xsd::ProductStrategies::ProductStrategy& xsdcProductStrategy) {
+    AudioHalProductStrategy aidlProductStrategy;
+
+    aidlProductStrategy.id = convertProductStrategyNameToAidl(xsdcProductStrategy.getName());
+
+    if (xsdcProductStrategy.hasAttributesGroup()) {
+        aidlProductStrategy.attributesGroups =
+                convertCollectionToAidl<xsd::AttributesGroup, AudioHalAttributesGroup>(
+                        xsdcProductStrategy.getAttributesGroup(),
+                        std::bind(&EngineConfigXmlConverter::convertAttributesGroupToAidl, this,
+                                  std::placeholders::_1));
+    }
+    if ((mDefaultProductStrategyId != std::nullopt) && (mDefaultProductStrategyId.value() == -1)) {
+        mDefaultProductStrategyId = aidlProductStrategy.id;
+    }
+    return aidlProductStrategy;
+}
+
+AudioHalVolumeCurve::CurvePoint EngineConfigXmlConverter::convertCurvePointToAidl(
+        const std::string& xsdcCurvePoint) {
+    AudioHalVolumeCurve::CurvePoint aidlCurvePoint{};
+    if (sscanf(xsdcCurvePoint.c_str(), "%" SCNd8 ",%d", &aidlCurvePoint.index,
+               &aidlCurvePoint.attenuationMb) != 2) {
+        aidlCurvePoint.index = kInvalidCurvePointIndex;
+    }
+    return aidlCurvePoint;
+}
+
+AudioHalVolumeCurve EngineConfigXmlConverter::convertVolumeCurveToAidl(
+        const xsd::Volume& xsdcVolumeCurve) {
+    AudioHalVolumeCurve aidlVolumeCurve;
+    aidlVolumeCurve.deviceCategory =
+            static_cast<AudioHalVolumeCurve::DeviceCategory>(xsdcVolumeCurve.getDeviceCategory());
+    if (xsdcVolumeCurve.hasRef()) {
+        if (mVolumesReferenceMap.empty()) {
+            mVolumesReferenceMap = generateReferenceMap<xsd::VolumesType, xsd::VolumeRef>(
+                    getXsdcConfig()->getVolumes());
+        }
+        aidlVolumeCurve.curvePoints =
+                convertCollectionToAidl<std::string, AudioHalVolumeCurve::CurvePoint>(
+                        mVolumesReferenceMap.at(xsdcVolumeCurve.getRef()).getPoint(),
+                        std::bind(&EngineConfigXmlConverter::convertCurvePointToAidl, this,
+                                  std::placeholders::_1));
+    } else {
+        aidlVolumeCurve.curvePoints =
+                convertCollectionToAidl<std::string, AudioHalVolumeCurve::CurvePoint>(
+                        xsdcVolumeCurve.getPoint(),
+                        std::bind(&EngineConfigXmlConverter::convertCurvePointToAidl, this,
+                                  std::placeholders::_1));
+    }
+    return aidlVolumeCurve;
+}
+
+AudioHalVolumeGroup EngineConfigXmlConverter::convertVolumeGroupToAidl(
+        const xsd::VolumeGroupsType::VolumeGroup& xsdcVolumeGroup) {
+    AudioHalVolumeGroup aidlVolumeGroup;
+    aidlVolumeGroup.name = xsdcVolumeGroup.getName();
+    aidlVolumeGroup.minIndex = xsdcVolumeGroup.getIndexMin();
+    aidlVolumeGroup.maxIndex = xsdcVolumeGroup.getIndexMax();
+    aidlVolumeGroup.volumeCurves = convertCollectionToAidl<xsd::Volume, AudioHalVolumeCurve>(
+            xsdcVolumeGroup.getVolume(),
+            std::bind(&EngineConfigXmlConverter::convertVolumeCurveToAidl, this,
+                      std::placeholders::_1));
+    return aidlVolumeGroup;
+}
+
+AudioHalCapCriterion EngineConfigXmlConverter::convertCapCriterionToAidl(
+        const xsd::CriterionType& xsdcCriterion) {
+    AudioHalCapCriterion aidlCapCriterion;
+    aidlCapCriterion.name = xsdcCriterion.getName();
+    aidlCapCriterion.criterionTypeName = xsdcCriterion.getType();
+    aidlCapCriterion.defaultLiteralValue = xsdcCriterion.get_default();
+    return aidlCapCriterion;
+}
+
+std::string EngineConfigXmlConverter::convertCriterionTypeValueToAidl(
+        const xsd::ValueType& xsdcCriterionTypeValue) {
+    return xsdcCriterionTypeValue.getLiteral();
+}
+
+AudioHalCapCriterionType EngineConfigXmlConverter::convertCapCriterionTypeToAidl(
+        const xsd::CriterionTypeType& xsdcCriterionType) {
+    AudioHalCapCriterionType aidlCapCriterionType;
+    aidlCapCriterionType.name = xsdcCriterionType.getName();
+    aidlCapCriterionType.isInclusive = !(static_cast<bool>(xsdcCriterionType.getType()));
+    aidlCapCriterionType.values =
+            convertWrappedCollectionToAidl<xsd::ValuesType, xsd::ValueType, std::string>(
+                    xsdcCriterionType.getValues(), &xsd::ValuesType::getValue,
+                    std::bind(&EngineConfigXmlConverter::convertCriterionTypeValueToAidl, this,
+                              std::placeholders::_1));
+    return aidlCapCriterionType;
+}
+
+AudioHalEngineConfig& EngineConfigXmlConverter::getAidlEngineConfig() {
+    return mAidlEngineConfig;
+}
+
+void EngineConfigXmlConverter::init() {
+    initProductStrategyMap();
+    if (getXsdcConfig()->hasProductStrategies()) {
+        mAidlEngineConfig.productStrategies =
+                convertWrappedCollectionToAidl<xsd::ProductStrategies,
+                                               xsd::ProductStrategies::ProductStrategy,
+                                               AudioHalProductStrategy>(
+                        getXsdcConfig()->getProductStrategies(),
+                        &xsd::ProductStrategies::getProductStrategy,
+                        std::bind(&EngineConfigXmlConverter::convertProductStrategyToAidl, this,
+                                  std::placeholders::_1));
+        if (mDefaultProductStrategyId) {
+            mAidlEngineConfig.defaultProductStrategyId = mDefaultProductStrategyId.value();
+        }
+    }
+    if (getXsdcConfig()->hasVolumeGroups()) {
+        mAidlEngineConfig.volumeGroups = convertWrappedCollectionToAidl<
+                xsd::VolumeGroupsType, xsd::VolumeGroupsType::VolumeGroup, AudioHalVolumeGroup>(
+                getXsdcConfig()->getVolumeGroups(), &xsd::VolumeGroupsType::getVolumeGroup,
+                std::bind(&EngineConfigXmlConverter::convertVolumeGroupToAidl, this,
+                          std::placeholders::_1));
+    }
+    if (getXsdcConfig()->hasCriteria() && getXsdcConfig()->hasCriterion_types()) {
+        AudioHalEngineConfig::CapSpecificConfig capSpecificConfig;
+        capSpecificConfig.criteria =
+                convertWrappedCollectionToAidl<xsd::CriteriaType, xsd::CriterionType,
+                                               AudioHalCapCriterion>(
+                        getXsdcConfig()->getCriteria(), &xsd::CriteriaType::getCriterion,
+                        std::bind(&EngineConfigXmlConverter::convertCapCriterionToAidl, this,
+                                  std::placeholders::_1));
+        capSpecificConfig.criterionTypes =
+                convertWrappedCollectionToAidl<xsd::CriterionTypesType, xsd::CriterionTypeType,
+                                               AudioHalCapCriterionType>(
+                        getXsdcConfig()->getCriterion_types(),
+                        &xsd::CriterionTypesType::getCriterion_type,
+                        std::bind(&EngineConfigXmlConverter::convertCapCriterionTypeToAidl, this,
+                                  std::placeholders::_1));
+        mAidlEngineConfig.capSpecificConfig = capSpecificConfig;
+    }
+}
+}  // namespace aidl::android::hardware::audio::core::internal
\ No newline at end of file
diff --git a/audio/aidl/default/bassboost/BassBoostSw.cpp b/audio/aidl/default/bassboost/BassBoostSw.cpp
index c52d16f..7971dee 100644
--- a/audio/aidl/default/bassboost/BassBoostSw.cpp
+++ b/audio/aidl/default/bassboost/BassBoostSw.cpp
@@ -14,10 +14,11 @@
  * limitations under the License.
  */
 
+#include <algorithm>
 #include <cstddef>
+#include <memory>
 #define LOG_TAG "AHAL_BassBoostSw"
 #include <Utils.h>
-#include <algorithm>
 #include <unordered_set>
 
 #include <android-base/logging.h>
@@ -73,28 +74,74 @@
 ndk::ScopedAStatus BassBoostSw::setParameterSpecific(const Parameter::Specific& specific) {
     RETURN_IF(Parameter::Specific::bassBoost != specific.getTag(), EX_ILLEGAL_ARGUMENT,
               "EffectNotSupported");
-    std::lock_guard lg(mMutex);
     RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
 
-    mSpecificParam = specific.get<Parameter::Specific::bassBoost>();
-    LOG(DEBUG) << __func__ << " success with: " << specific.toString();
-    return ndk::ScopedAStatus::ok();
+    auto& bbParam = specific.get<Parameter::Specific::bassBoost>();
+    auto tag = bbParam.getTag();
+
+    switch (tag) {
+        case BassBoost::strengthPm: {
+            RETURN_IF(!mStrengthSupported, EX_ILLEGAL_ARGUMENT, "SettingStrengthNotSupported");
+
+            RETURN_IF(mContext->setBbStrengthPm(bbParam.get<BassBoost::strengthPm>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "strengthPmNotSupported");
+            return ndk::ScopedAStatus::ok();
+        }
+        default: {
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "BassBoostTagNotSupported");
+        }
+    }
 }
 
 ndk::ScopedAStatus BassBoostSw::getParameterSpecific(const Parameter::Id& id,
                                                      Parameter::Specific* specific) {
     auto tag = id.getTag();
     RETURN_IF(Parameter::Id::bassBoostTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
-    specific->set<Parameter::Specific::bassBoost>(mSpecificParam);
+    auto bbId = id.get<Parameter::Id::bassBoostTag>();
+    auto bbIdTag = bbId.getTag();
+    switch (bbIdTag) {
+        case BassBoost::Id::commonTag:
+            return getParameterBassBoost(bbId.get<BassBoost::Id::commonTag>(), specific);
+        default:
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "BassBoostTagNotSupported");
+    }
+}
+
+ndk::ScopedAStatus BassBoostSw::getParameterBassBoost(const BassBoost::Tag& tag,
+                                                      Parameter::Specific* specific) {
+    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+    BassBoost bbParam;
+    switch (tag) {
+        case BassBoost::strengthPm: {
+            bbParam.set<BassBoost::strengthPm>(mContext->getBbStrengthPm());
+            break;
+        }
+        default: {
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "BassBoostTagNotSupported");
+        }
+    }
+
+    specific->set<Parameter::Specific::bassBoost>(bbParam);
     return ndk::ScopedAStatus::ok();
 }
 
 std::shared_ptr<EffectContext> BassBoostSw::createContext(const Parameter::Common& common) {
     if (mContext) {
         LOG(DEBUG) << __func__ << " context already exist";
-        return mContext;
+    } else {
+        mContext = std::make_shared<BassBoostSwContext>(1 /* statusFmqDepth */, common);
     }
-    mContext = std::make_shared<BassBoostSwContext>(1 /* statusFmqDepth */, common);
+    return mContext;
+}
+
+std::shared_ptr<EffectContext> BassBoostSw::getContext() {
     return mContext;
 }
 
@@ -106,13 +153,13 @@
 }
 
 // Processing method running in EffectWorker thread.
-IEffect::Status BassBoostSw::effectProcessImpl(float* in, float* out, int process) {
+IEffect::Status BassBoostSw::effectProcessImpl(float* in, float* out, int samples) {
     // TODO: get data buffer and process.
-    LOG(DEBUG) << __func__ << " in " << in << " out " << out << " process " << process;
-    for (int i = 0; i < process; i++) {
+    LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
+    for (int i = 0; i < samples; i++) {
         *out++ = *in++;
     }
-    return {STATUS_OK, process, process};
+    return {STATUS_OK, samples, samples};
 }
 
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/bassboost/BassBoostSw.h b/audio/aidl/default/bassboost/BassBoostSw.h
index 90a8887..24ea652 100644
--- a/audio/aidl/default/bassboost/BassBoostSw.h
+++ b/audio/aidl/default/bassboost/BassBoostSw.h
@@ -32,7 +32,21 @@
         : EffectContext(statusDepth, common) {
         LOG(DEBUG) << __func__;
     }
-    // TODO: add specific context here
+
+    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;
+    }
+    int getBbStrengthPm() const { return mStrength; }
+
+  private:
+    int mStrength;
 };
 
 class BassBoostSw final : public EffectImpl {
@@ -47,14 +61,20 @@
     ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
     ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
                                             Parameter::Specific* specific) override;
-    IEffect::Status effectProcessImpl(float* in, float* out, int process) override;
+
     std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
+    std::shared_ptr<EffectContext> getContext() override;
     RetCode releaseContext() override;
 
+    std::string getEffectName() override { return kEffectName; };
+    IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+
   private:
+    const std::string kEffectName = "BassBoostSw";
     std::shared_ptr<BassBoostSwContext> mContext;
     /* capabilities */
-    const BassBoost::Capability kCapability;
+    const bool mStrengthSupported = true;
+    const BassBoost::Capability kCapability = {.strengthSupported = mStrengthSupported};
     /* Effect descriptor */
     const Descriptor kDescriptor = {
             .common = {.id = {.type = kBassBoostTypeUUID,
@@ -63,11 +83,11 @@
                        .flags = {.type = Flags::Type::INSERT,
                                  .insert = Flags::Insert::FIRST,
                                  .volume = Flags::Volume::CTRL},
-                       .name = "BassBoostSw",
+                       .name = kEffectName,
                        .implementor = "The Android Open Source Project"},
             .capability = Capability::make<Capability::bassBoost>(kCapability)};
 
-    /* parameters */
-    BassBoost mSpecificParam;
+    ndk::ScopedAStatus getParameterBassBoost(const BassBoost::Tag& tag,
+                                             Parameter::Specific* specific);
 };
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/config/audioPolicy/Android.bp b/audio/aidl/default/config/audioPolicy/Android.bp
new file mode 100644
index 0000000..6d8a148
--- /dev/null
+++ b/audio/aidl/default/config/audioPolicy/Android.bp
@@ -0,0 +1,15 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+xsd_config {
+    name: "audio_policy_configuration_aidl_default",
+    srcs: ["audio_policy_configuration.xsd"],
+    package_name: "android.audio.policy.configuration",
+    nullability: true,
+}
diff --git a/audio/aidl/default/config/audioPolicy/api/current.txt b/audio/aidl/default/config/audioPolicy/api/current.txt
new file mode 100644
index 0000000..c0ffe70
--- /dev/null
+++ b/audio/aidl/default/config/audioPolicy/api/current.txt
@@ -0,0 +1,607 @@
+// Signature format: 2.0
+package android.audio.policy.configuration {
+
+  public class AttachedDevices {
+    ctor public AttachedDevices();
+    method @Nullable public java.util.List<java.lang.String> getItem();
+  }
+
+  public enum AudioChannelMask {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_1;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_10;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_11;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_12;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_13;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_14;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_15;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_16;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_17;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_18;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_19;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_2;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_20;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_21;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_22;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_23;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_24;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_3;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_4;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_5;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_6;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_7;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_8;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_9;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_IN_2POINT0POINT2;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_IN_2POINT1POINT2;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_IN_3POINT0POINT2;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_IN_3POINT1POINT2;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_IN_5POINT1;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_IN_6;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_IN_FRONT_BACK;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_IN_MONO;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_IN_STEREO;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_IN_VOICE_CALL_MONO;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_IN_VOICE_DNLINK_MONO;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_IN_VOICE_UPLINK_MONO;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_NONE;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_13POINT_360RA;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_22POINT2;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_2POINT0POINT2;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_2POINT1;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_2POINT1POINT2;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_3POINT0POINT2;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_3POINT1;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_3POINT1POINT2;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_5POINT1;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_5POINT1POINT2;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_5POINT1POINT4;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_5POINT1_BACK;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_5POINT1_SIDE;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_6POINT1;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_7POINT1;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_7POINT1POINT2;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_7POINT1POINT4;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_9POINT1POINT4;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_9POINT1POINT6;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_HAPTIC_AB;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_MONO;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_MONO_HAPTIC_A;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_MONO_HAPTIC_AB;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_PENTA;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_QUAD;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_QUAD_BACK;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_QUAD_SIDE;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_STEREO;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_STEREO_HAPTIC_A;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_STEREO_HAPTIC_AB;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_SURROUND;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_TRI;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_TRI_BACK;
+  }
+
+  public enum AudioContentType {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.configuration.AudioContentType AUDIO_CONTENT_TYPE_MOVIE;
+    enum_constant public static final android.audio.policy.configuration.AudioContentType AUDIO_CONTENT_TYPE_MUSIC;
+    enum_constant public static final android.audio.policy.configuration.AudioContentType AUDIO_CONTENT_TYPE_SONIFICATION;
+    enum_constant public static final android.audio.policy.configuration.AudioContentType AUDIO_CONTENT_TYPE_SPEECH;
+    enum_constant public static final android.audio.policy.configuration.AudioContentType AUDIO_CONTENT_TYPE_ULTRASOUND;
+    enum_constant public static final android.audio.policy.configuration.AudioContentType AUDIO_CONTENT_TYPE_UNKNOWN;
+  }
+
+  public enum AudioDevice {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_AMBIENT;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_AUX_DIGITAL;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_BACK_MIC;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_BLE_HEADSET;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_BLUETOOTH_A2DP;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_BLUETOOTH_BLE;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_BUILTIN_MIC;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_BUS;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_COMMUNICATION;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_DEFAULT;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_ECHO_REFERENCE;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_FM_TUNER;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_HDMI;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_HDMI_ARC;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_HDMI_EARC;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_IP;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_LINE;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_LOOPBACK;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_PROXY;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_REMOTE_SUBMIX;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_SPDIF;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_STUB;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_TELEPHONY_RX;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_TV_TUNER;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_USB_ACCESSORY;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_USB_DEVICE;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_USB_HEADSET;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_VOICE_CALL;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_WIRED_HEADSET;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_NONE;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_AUX_DIGITAL;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_AUX_LINE;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_BLE_BROADCAST;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_BLE_HEADSET;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_BLE_SPEAKER;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_SCO;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_BUS;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_DEFAULT;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_EARPIECE;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_ECHO_CANCELLER;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_FM;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_HDMI;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_HDMI_ARC;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_HDMI_EARC;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_HEARING_AID;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_IP;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_LINE;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_PROXY;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_SPDIF;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_SPEAKER;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_SPEAKER_SAFE;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_STUB;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_TELEPHONY_TX;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_USB_ACCESSORY;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_USB_DEVICE;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_USB_HEADSET;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_WIRED_HEADSET;
+  }
+
+  public enum AudioEncapsulationType {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.configuration.AudioEncapsulationType AUDIO_ENCAPSULATION_TYPE_IEC61937;
+    enum_constant public static final android.audio.policy.configuration.AudioEncapsulationType AUDIO_ENCAPSULATION_TYPE_NONE;
+  }
+
+  public enum AudioFormat {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_ADIF;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_ADTS;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_ADTS_ELD;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_ADTS_ERLC;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_ADTS_HE_V1;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_ADTS_HE_V2;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_ADTS_LC;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_ADTS_LD;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_ADTS_LTP;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_ADTS_MAIN;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_ADTS_SCALABLE;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_ADTS_SSR;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_ADTS_XHE;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_ELD;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_ERLC;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_HE_V1;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_HE_V2;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_LATM;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_LATM_HE_V1;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_LATM_HE_V2;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_LATM_LC;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_LC;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_LD;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_LTP;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_MAIN;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_SCALABLE;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_SSR;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_XHE;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AC3;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AC4;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_ALAC;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AMR_NB;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AMR_WB;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AMR_WB_PLUS;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_APE;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_APTX;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_APTX_ADAPTIVE;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_APTX_ADAPTIVE_QLEA;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_APTX_ADAPTIVE_R4;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_APTX_HD;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_APTX_TWSP;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_CELT;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_DEFAULT;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_DOLBY_TRUEHD;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_DRA;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_DSD;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_DTS;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_DTS_HD;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_DTS_HD_MA;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_DTS_UHD;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_DTS_UHD_P2;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_EVRC;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_EVRCB;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_EVRCNW;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_EVRCWB;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_E_AC3;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_E_AC3_JOC;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_FLAC;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_HE_AAC_V1;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_HE_AAC_V2;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_IEC60958;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_IEC61937;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_LC3;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_LDAC;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_LHDC;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_LHDC_LL;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_MAT;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_MAT_1_0;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_MAT_2_0;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_MAT_2_1;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_MP2;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_MP3;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_MPEGH_BL_L3;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_MPEGH_BL_L4;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_MPEGH_LC_L3;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_MPEGH_LC_L4;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_OPUS;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_PCM_16_BIT;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_PCM_24_BIT_PACKED;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_PCM_32_BIT;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_PCM_8_24_BIT;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_PCM_8_BIT;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_PCM_FLOAT;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_QCELP;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_SBC;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_VORBIS;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_WMA;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_WMA_PRO;
+  }
+
+  public enum AudioGainMode {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.configuration.AudioGainMode AUDIO_GAIN_MODE_CHANNELS;
+    enum_constant public static final android.audio.policy.configuration.AudioGainMode AUDIO_GAIN_MODE_JOINT;
+    enum_constant public static final android.audio.policy.configuration.AudioGainMode AUDIO_GAIN_MODE_RAMP;
+  }
+
+  public enum AudioInOutFlag {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_INPUT_FLAG_DIRECT;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_INPUT_FLAG_FAST;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_INPUT_FLAG_HW_AV_SYNC;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_INPUT_FLAG_HW_HOTWORD;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_INPUT_FLAG_MMAP_NOIRQ;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_INPUT_FLAG_RAW;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_INPUT_FLAG_SYNC;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_INPUT_FLAG_ULTRASOUND;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_INPUT_FLAG_VOIP_TX;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_OUTPUT_FLAG_DIRECT;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_OUTPUT_FLAG_DIRECT_PCM;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_OUTPUT_FLAG_FAST;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_OUTPUT_FLAG_GAPLESS_OFFLOAD;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_OUTPUT_FLAG_HW_AV_SYNC;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_OUTPUT_FLAG_INCALL_MUSIC;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_OUTPUT_FLAG_MMAP_NOIRQ;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_OUTPUT_FLAG_NON_BLOCKING;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_OUTPUT_FLAG_PRIMARY;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_OUTPUT_FLAG_RAW;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_OUTPUT_FLAG_SPATIALIZER;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_OUTPUT_FLAG_SYNC;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_OUTPUT_FLAG_TTS;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_OUTPUT_FLAG_ULTRASOUND;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_OUTPUT_FLAG_VOIP_RX;
+  }
+
+  public class AudioPolicyConfiguration {
+    ctor public AudioPolicyConfiguration();
+    method @Nullable public android.audio.policy.configuration.GlobalConfiguration getGlobalConfiguration();
+    method @Nullable public java.util.List<android.audio.policy.configuration.Modules> getModules();
+    method @Nullable public android.audio.policy.configuration.SurroundSound getSurroundSound();
+    method @Nullable public android.audio.policy.configuration.Version getVersion();
+    method @Nullable public java.util.List<android.audio.policy.configuration.Volumes> getVolumes();
+    method public void setGlobalConfiguration(@Nullable android.audio.policy.configuration.GlobalConfiguration);
+    method public void setSurroundSound(@Nullable android.audio.policy.configuration.SurroundSound);
+    method public void setVersion(@Nullable android.audio.policy.configuration.Version);
+  }
+
+  public enum AudioSource {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.configuration.AudioSource AUDIO_SOURCE_CAMCORDER;
+    enum_constant public static final android.audio.policy.configuration.AudioSource AUDIO_SOURCE_DEFAULT;
+    enum_constant public static final android.audio.policy.configuration.AudioSource AUDIO_SOURCE_ECHO_REFERENCE;
+    enum_constant public static final android.audio.policy.configuration.AudioSource AUDIO_SOURCE_FM_TUNER;
+    enum_constant public static final android.audio.policy.configuration.AudioSource AUDIO_SOURCE_HOTWORD;
+    enum_constant public static final android.audio.policy.configuration.AudioSource AUDIO_SOURCE_MIC;
+    enum_constant public static final android.audio.policy.configuration.AudioSource AUDIO_SOURCE_REMOTE_SUBMIX;
+    enum_constant public static final android.audio.policy.configuration.AudioSource AUDIO_SOURCE_ULTRASOUND;
+    enum_constant public static final android.audio.policy.configuration.AudioSource AUDIO_SOURCE_UNPROCESSED;
+    enum_constant public static final android.audio.policy.configuration.AudioSource AUDIO_SOURCE_VOICE_CALL;
+    enum_constant public static final android.audio.policy.configuration.AudioSource AUDIO_SOURCE_VOICE_COMMUNICATION;
+    enum_constant public static final android.audio.policy.configuration.AudioSource AUDIO_SOURCE_VOICE_DOWNLINK;
+    enum_constant public static final android.audio.policy.configuration.AudioSource AUDIO_SOURCE_VOICE_PERFORMANCE;
+    enum_constant public static final android.audio.policy.configuration.AudioSource AUDIO_SOURCE_VOICE_RECOGNITION;
+    enum_constant public static final android.audio.policy.configuration.AudioSource AUDIO_SOURCE_VOICE_UPLINK;
+  }
+
+  public enum AudioStreamType {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.configuration.AudioStreamType AUDIO_STREAM_ACCESSIBILITY;
+    enum_constant public static final android.audio.policy.configuration.AudioStreamType AUDIO_STREAM_ALARM;
+    enum_constant public static final android.audio.policy.configuration.AudioStreamType AUDIO_STREAM_ASSISTANT;
+    enum_constant public static final android.audio.policy.configuration.AudioStreamType AUDIO_STREAM_BLUETOOTH_SCO;
+    enum_constant public static final android.audio.policy.configuration.AudioStreamType AUDIO_STREAM_CALL_ASSISTANT;
+    enum_constant public static final android.audio.policy.configuration.AudioStreamType AUDIO_STREAM_DTMF;
+    enum_constant public static final android.audio.policy.configuration.AudioStreamType AUDIO_STREAM_ENFORCED_AUDIBLE;
+    enum_constant public static final android.audio.policy.configuration.AudioStreamType AUDIO_STREAM_MUSIC;
+    enum_constant public static final android.audio.policy.configuration.AudioStreamType AUDIO_STREAM_NOTIFICATION;
+    enum_constant public static final android.audio.policy.configuration.AudioStreamType AUDIO_STREAM_PATCH;
+    enum_constant public static final android.audio.policy.configuration.AudioStreamType AUDIO_STREAM_REROUTING;
+    enum_constant public static final android.audio.policy.configuration.AudioStreamType AUDIO_STREAM_RING;
+    enum_constant public static final android.audio.policy.configuration.AudioStreamType AUDIO_STREAM_SYSTEM;
+    enum_constant public static final android.audio.policy.configuration.AudioStreamType AUDIO_STREAM_TTS;
+    enum_constant public static final android.audio.policy.configuration.AudioStreamType AUDIO_STREAM_VOICE_CALL;
+  }
+
+  public enum AudioUsage {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_ALARM;
+    enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_ANNOUNCEMENT;
+    enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY;
+    enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE;
+    enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_ASSISTANCE_SONIFICATION;
+    enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_ASSISTANT;
+    enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_CALL_ASSISTANT;
+    enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_EMERGENCY;
+    enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_GAME;
+    enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_MEDIA;
+    enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_NOTIFICATION;
+    enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_NOTIFICATION_EVENT;
+    enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE;
+    enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_SAFETY;
+    enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_UNKNOWN;
+    enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_VEHICLE_STATUS;
+    enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_VIRTUAL_SOURCE;
+    enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_VOICE_COMMUNICATION;
+    enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING;
+  }
+
+  public enum DeviceCategory {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.configuration.DeviceCategory DEVICE_CATEGORY_EARPIECE;
+    enum_constant public static final android.audio.policy.configuration.DeviceCategory DEVICE_CATEGORY_EXT_MEDIA;
+    enum_constant public static final android.audio.policy.configuration.DeviceCategory DEVICE_CATEGORY_HEADSET;
+    enum_constant public static final android.audio.policy.configuration.DeviceCategory DEVICE_CATEGORY_HEARING_AID;
+    enum_constant public static final android.audio.policy.configuration.DeviceCategory DEVICE_CATEGORY_SPEAKER;
+  }
+
+  public class DevicePorts {
+    ctor public DevicePorts();
+    method @Nullable public java.util.List<android.audio.policy.configuration.DevicePorts.DevicePort> getDevicePort();
+  }
+
+  public static class DevicePorts.DevicePort {
+    ctor public DevicePorts.DevicePort();
+    method @Nullable public String getAddress();
+    method @Nullable public java.util.List<java.lang.String> getEncodedFormats();
+    method @Nullable public android.audio.policy.configuration.Gains getGains();
+    method @Nullable public java.util.List<android.audio.policy.configuration.Profile> getProfile();
+    method @Nullable public android.audio.policy.configuration.Role getRole();
+    method @Nullable public String getTagName();
+    method @Nullable public String getType();
+    method @Nullable public boolean get_default();
+    method public void setAddress(@Nullable String);
+    method public void setEncodedFormats(@Nullable java.util.List<java.lang.String>);
+    method public void setGains(@Nullable android.audio.policy.configuration.Gains);
+    method public void setRole(@Nullable android.audio.policy.configuration.Role);
+    method public void setTagName(@Nullable String);
+    method public void setType(@Nullable String);
+    method public void set_default(@Nullable boolean);
+  }
+
+  public enum EngineSuffix {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.configuration.EngineSuffix _default;
+    enum_constant public static final android.audio.policy.configuration.EngineSuffix configurable;
+  }
+
+  public class Gains {
+    ctor public Gains();
+    method @Nullable public java.util.List<android.audio.policy.configuration.Gains.Gain> getGain();
+  }
+
+  public static class Gains.Gain {
+    ctor public Gains.Gain();
+    method @Nullable public android.audio.policy.configuration.AudioChannelMask getChannel_mask();
+    method @Nullable public int getDefaultValueMB();
+    method @Nullable public int getMaxRampMs();
+    method @Nullable public int getMaxValueMB();
+    method @Nullable public int getMinRampMs();
+    method @Nullable public int getMinValueMB();
+    method @Nullable public java.util.List<android.audio.policy.configuration.AudioGainMode> getMode();
+    method @Nullable public String getName();
+    method @Nullable public int getStepValueMB();
+    method @Nullable public boolean getUseForVolume();
+    method public void setChannel_mask(@Nullable android.audio.policy.configuration.AudioChannelMask);
+    method public void setDefaultValueMB(@Nullable int);
+    method public void setMaxRampMs(@Nullable int);
+    method public void setMaxValueMB(@Nullable int);
+    method public void setMinRampMs(@Nullable int);
+    method public void setMinValueMB(@Nullable int);
+    method public void setMode(@Nullable java.util.List<android.audio.policy.configuration.AudioGainMode>);
+    method public void setName(@Nullable String);
+    method public void setStepValueMB(@Nullable int);
+    method public void setUseForVolume(@Nullable boolean);
+  }
+
+  public class GlobalConfiguration {
+    ctor public GlobalConfiguration();
+    method @Nullable public boolean getCall_screen_mode_supported();
+    method @Nullable public android.audio.policy.configuration.EngineSuffix getEngine_library();
+    method @Nullable public boolean getSpeaker_drc_enabled();
+    method public void setCall_screen_mode_supported(@Nullable boolean);
+    method public void setEngine_library(@Nullable android.audio.policy.configuration.EngineSuffix);
+    method public void setSpeaker_drc_enabled(@Nullable boolean);
+  }
+
+  public enum HalVersion {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.configuration.HalVersion _2_0;
+    enum_constant public static final android.audio.policy.configuration.HalVersion _3_0;
+  }
+
+  public class MixPorts {
+    ctor public MixPorts();
+    method @Nullable public java.util.List<android.audio.policy.configuration.MixPorts.MixPort> getMixPort();
+  }
+
+  public static class MixPorts.MixPort {
+    ctor public MixPorts.MixPort();
+    method @Nullable public java.util.List<android.audio.policy.configuration.AudioInOutFlag> getFlags();
+    method @Nullable public android.audio.policy.configuration.Gains getGains();
+    method @Nullable public long getMaxActiveCount();
+    method @Nullable public long getMaxOpenCount();
+    method @Nullable public String getName();
+    method @Nullable public java.util.List<android.audio.policy.configuration.AudioUsage> getPreferredUsage();
+    method @Nullable public java.util.List<android.audio.policy.configuration.Profile> getProfile();
+    method @Nullable public long getRecommendedMuteDurationMs();
+    method @Nullable public android.audio.policy.configuration.Role getRole();
+    method public void setFlags(@Nullable java.util.List<android.audio.policy.configuration.AudioInOutFlag>);
+    method public void setGains(@Nullable android.audio.policy.configuration.Gains);
+    method public void setMaxActiveCount(@Nullable long);
+    method public void setMaxOpenCount(@Nullable long);
+    method public void setName(@Nullable String);
+    method public void setPreferredUsage(@Nullable java.util.List<android.audio.policy.configuration.AudioUsage>);
+    method public void setRecommendedMuteDurationMs(@Nullable long);
+    method public void setRole(@Nullable android.audio.policy.configuration.Role);
+  }
+
+  public enum MixType {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.configuration.MixType mix;
+    enum_constant public static final android.audio.policy.configuration.MixType mux;
+  }
+
+  public class Modules {
+    ctor public Modules();
+    method @Nullable public java.util.List<android.audio.policy.configuration.Modules.Module> getModule();
+  }
+
+  public static class Modules.Module {
+    ctor public Modules.Module();
+    method @Nullable public android.audio.policy.configuration.AttachedDevices getAttachedDevices();
+    method @Nullable public String getDefaultOutputDevice();
+    method @Nullable public android.audio.policy.configuration.DevicePorts getDevicePorts();
+    method @Nullable public android.audio.policy.configuration.HalVersion getHalVersion();
+    method @Nullable public android.audio.policy.configuration.MixPorts getMixPorts();
+    method @Nullable public String getName();
+    method @Nullable public android.audio.policy.configuration.Routes getRoutes();
+    method public void setAttachedDevices(@Nullable android.audio.policy.configuration.AttachedDevices);
+    method public void setDefaultOutputDevice(@Nullable String);
+    method public void setDevicePorts(@Nullable android.audio.policy.configuration.DevicePorts);
+    method public void setHalVersion(@Nullable android.audio.policy.configuration.HalVersion);
+    method public void setMixPorts(@Nullable android.audio.policy.configuration.MixPorts);
+    method public void setName(@Nullable String);
+    method public void setRoutes(@Nullable android.audio.policy.configuration.Routes);
+  }
+
+  public class Profile {
+    ctor public Profile();
+    method @Nullable public java.util.List<android.audio.policy.configuration.AudioChannelMask> getChannelMasks();
+    method @Nullable public android.audio.policy.configuration.AudioEncapsulationType getEncapsulationType();
+    method @Nullable public String getFormat();
+    method @Nullable public String getName();
+    method @Nullable public java.util.List<java.math.BigInteger> getSamplingRates();
+    method public void setChannelMasks(@Nullable java.util.List<android.audio.policy.configuration.AudioChannelMask>);
+    method public void setEncapsulationType(@Nullable android.audio.policy.configuration.AudioEncapsulationType);
+    method public void setFormat(@Nullable String);
+    method public void setName(@Nullable String);
+    method public void setSamplingRates(@Nullable java.util.List<java.math.BigInteger>);
+  }
+
+  public class Reference {
+    ctor public Reference();
+    method @Nullable public String getName();
+    method @Nullable public java.util.List<java.lang.String> getPoint();
+    method public void setName(@Nullable String);
+  }
+
+  public enum Role {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.configuration.Role sink;
+    enum_constant public static final android.audio.policy.configuration.Role source;
+  }
+
+  public class Routes {
+    ctor public Routes();
+    method @Nullable public java.util.List<android.audio.policy.configuration.Routes.Route> getRoute();
+  }
+
+  public static class Routes.Route {
+    ctor public Routes.Route();
+    method @Nullable public String getSink();
+    method @Nullable public String getSources();
+    method @Nullable public android.audio.policy.configuration.MixType getType();
+    method public void setSink(@Nullable String);
+    method public void setSources(@Nullable String);
+    method public void setType(@Nullable android.audio.policy.configuration.MixType);
+  }
+
+  public class SurroundFormats {
+    ctor public SurroundFormats();
+    method @Nullable public java.util.List<android.audio.policy.configuration.SurroundFormats.Format> getFormat();
+  }
+
+  public static class SurroundFormats.Format {
+    ctor public SurroundFormats.Format();
+    method @Nullable public String getName();
+    method @Nullable public java.util.List<java.lang.String> getSubformats();
+    method public void setName(@Nullable String);
+    method public void setSubformats(@Nullable java.util.List<java.lang.String>);
+  }
+
+  public class SurroundSound {
+    ctor public SurroundSound();
+    method @Nullable public android.audio.policy.configuration.SurroundFormats getFormats();
+    method public void setFormats(@Nullable android.audio.policy.configuration.SurroundFormats);
+  }
+
+  public enum Version {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.configuration.Version _7_0;
+    enum_constant public static final android.audio.policy.configuration.Version _7_1;
+  }
+
+  public class Volume {
+    ctor public Volume();
+    method @Nullable public android.audio.policy.configuration.DeviceCategory getDeviceCategory();
+    method @Nullable public java.util.List<java.lang.String> getPoint();
+    method @Nullable public String getRef();
+    method @Nullable public android.audio.policy.configuration.AudioStreamType getStream();
+    method public void setDeviceCategory(@Nullable android.audio.policy.configuration.DeviceCategory);
+    method public void setRef(@Nullable String);
+    method public void setStream(@Nullable android.audio.policy.configuration.AudioStreamType);
+  }
+
+  public class Volumes {
+    ctor public Volumes();
+    method @Nullable public java.util.List<android.audio.policy.configuration.Reference> getReference();
+    method @Nullable public java.util.List<android.audio.policy.configuration.Volume> getVolume();
+  }
+
+  public class XmlParser {
+    ctor public XmlParser();
+    method @Nullable public static android.audio.policy.configuration.AudioPolicyConfiguration read(@NonNull java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method @Nullable public static String readText(@NonNull org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public static void skip(@NonNull org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+  }
+
+}
+
diff --git a/audio/aidl/default/config/audioPolicy/api/last_current.txt b/audio/aidl/default/config/audioPolicy/api/last_current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/audio/aidl/default/config/audioPolicy/api/last_current.txt
diff --git a/audio/aidl/default/config/audioPolicy/api/last_removed.txt b/audio/aidl/default/config/audioPolicy/api/last_removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/audio/aidl/default/config/audioPolicy/api/last_removed.txt
diff --git a/audio/aidl/default/config/audioPolicy/api/removed.txt b/audio/aidl/default/config/audioPolicy/api/removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/audio/aidl/default/config/audioPolicy/api/removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/audio/aidl/default/config/audio_policy_configuration.xsd b/audio/aidl/default/config/audioPolicy/audio_policy_configuration.xsd
similarity index 100%
rename from audio/aidl/default/config/audio_policy_configuration.xsd
rename to audio/aidl/default/config/audioPolicy/audio_policy_configuration.xsd
diff --git a/audio/aidl/default/config/audioPolicy/engine/Android.bp b/audio/aidl/default/config/audioPolicy/engine/Android.bp
new file mode 100644
index 0000000..b2a7310
--- /dev/null
+++ b/audio/aidl/default/config/audioPolicy/engine/Android.bp
@@ -0,0 +1,15 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+xsd_config {
+    name: "audio_policy_engine_configuration_aidl_default",
+    srcs: ["audio_policy_engine_configuration.xsd"],
+    package_name: "android.audio.policy.engine.configuration",
+    nullability: true,
+}
diff --git a/audio/aidl/default/config/audioPolicy/engine/api/current.txt b/audio/aidl/default/config/audioPolicy/engine/api/current.txt
new file mode 100644
index 0000000..59574f3
--- /dev/null
+++ b/audio/aidl/default/config/audioPolicy/engine/api/current.txt
@@ -0,0 +1,302 @@
+// Signature format: 2.0
+package android.audio.policy.engine.configuration {
+
+  public class AttributesGroup {
+    ctor public AttributesGroup();
+    method @Nullable public java.util.List<android.audio.policy.engine.configuration.AttributesType> getAttributes_optional();
+    method @Nullable public android.audio.policy.engine.configuration.BundleType getBundle_optional();
+    method @Nullable public android.audio.policy.engine.configuration.ContentTypeType getContentType_optional();
+    method @Nullable public android.audio.policy.engine.configuration.FlagsType getFlags_optional();
+    method @Nullable public android.audio.policy.engine.configuration.SourceType getSource_optional();
+    method @Nullable public android.audio.policy.engine.configuration.Stream getStreamType();
+    method @Nullable public android.audio.policy.engine.configuration.UsageType getUsage_optional();
+    method @Nullable public String getVolumeGroup();
+    method public void setBundle_optional(@Nullable android.audio.policy.engine.configuration.BundleType);
+    method public void setContentType_optional(@Nullable android.audio.policy.engine.configuration.ContentTypeType);
+    method public void setFlags_optional(@Nullable android.audio.policy.engine.configuration.FlagsType);
+    method public void setSource_optional(@Nullable android.audio.policy.engine.configuration.SourceType);
+    method public void setStreamType(@Nullable android.audio.policy.engine.configuration.Stream);
+    method public void setUsage_optional(@Nullable android.audio.policy.engine.configuration.UsageType);
+    method public void setVolumeGroup(@Nullable String);
+  }
+
+  public class AttributesRef {
+    ctor public AttributesRef();
+    method @Nullable public java.util.List<android.audio.policy.engine.configuration.AttributesRefType> getReference();
+  }
+
+  public class AttributesRefType {
+    ctor public AttributesRefType();
+    method @Nullable public android.audio.policy.engine.configuration.AttributesType getAttributes();
+    method @Nullable public String getName();
+    method public void setAttributes(@Nullable android.audio.policy.engine.configuration.AttributesType);
+    method public void setName(@Nullable String);
+  }
+
+  public class AttributesType {
+    ctor public AttributesType();
+    method @Nullable public String getAttributesRef();
+    method @Nullable public android.audio.policy.engine.configuration.BundleType getBundle();
+    method @Nullable public android.audio.policy.engine.configuration.ContentTypeType getContentType();
+    method @Nullable public android.audio.policy.engine.configuration.FlagsType getFlags();
+    method @Nullable public android.audio.policy.engine.configuration.SourceType getSource();
+    method @Nullable public android.audio.policy.engine.configuration.UsageType getUsage();
+    method public void setAttributesRef(@Nullable String);
+    method public void setBundle(@Nullable android.audio.policy.engine.configuration.BundleType);
+    method public void setContentType(@Nullable android.audio.policy.engine.configuration.ContentTypeType);
+    method public void setFlags(@Nullable android.audio.policy.engine.configuration.FlagsType);
+    method public void setSource(@Nullable android.audio.policy.engine.configuration.SourceType);
+    method public void setUsage(@Nullable android.audio.policy.engine.configuration.UsageType);
+  }
+
+  public class BundleType {
+    ctor public BundleType();
+    method @Nullable public String getKey();
+    method @Nullable public String getValue();
+    method public void setKey(@Nullable String);
+    method public void setValue(@Nullable String);
+  }
+
+  public class Configuration {
+    ctor public Configuration();
+    method @Nullable public java.util.List<android.audio.policy.engine.configuration.AttributesRef> getAttributesRef();
+    method @Nullable public java.util.List<android.audio.policy.engine.configuration.CriteriaType> getCriteria();
+    method @Nullable public java.util.List<android.audio.policy.engine.configuration.CriterionTypesType> getCriterion_types();
+    method @Nullable public java.util.List<android.audio.policy.engine.configuration.ProductStrategies> getProductStrategies();
+    method @Nullable public android.audio.policy.engine.configuration.Version getVersion();
+    method @Nullable public java.util.List<android.audio.policy.engine.configuration.VolumeGroupsType> getVolumeGroups();
+    method @Nullable public java.util.List<android.audio.policy.engine.configuration.VolumesType> getVolumes();
+    method public void setVersion(@Nullable android.audio.policy.engine.configuration.Version);
+  }
+
+  public enum ContentType {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.engine.configuration.ContentType AUDIO_CONTENT_TYPE_MOVIE;
+    enum_constant public static final android.audio.policy.engine.configuration.ContentType AUDIO_CONTENT_TYPE_MUSIC;
+    enum_constant public static final android.audio.policy.engine.configuration.ContentType AUDIO_CONTENT_TYPE_SONIFICATION;
+    enum_constant public static final android.audio.policy.engine.configuration.ContentType AUDIO_CONTENT_TYPE_SPEECH;
+    enum_constant public static final android.audio.policy.engine.configuration.ContentType AUDIO_CONTENT_TYPE_UNKNOWN;
+  }
+
+  public class ContentTypeType {
+    ctor public ContentTypeType();
+    method @Nullable public android.audio.policy.engine.configuration.ContentType getValue();
+    method public void setValue(@Nullable android.audio.policy.engine.configuration.ContentType);
+  }
+
+  public class CriteriaType {
+    ctor public CriteriaType();
+    method @Nullable public java.util.List<android.audio.policy.engine.configuration.CriterionType> getCriterion();
+  }
+
+  public class CriterionType {
+    ctor public CriterionType();
+    method @Nullable public String getName();
+    method @Nullable public String getType();
+    method @Nullable public String get_default();
+    method public void setName(@Nullable String);
+    method public void setType(@Nullable String);
+    method public void set_default(@Nullable String);
+  }
+
+  public class CriterionTypeType {
+    ctor public CriterionTypeType();
+    method @Nullable public String getName();
+    method @Nullable public android.audio.policy.engine.configuration.PfwCriterionTypeEnum getType();
+    method @Nullable public android.audio.policy.engine.configuration.ValuesType getValues();
+    method public void setName(@Nullable String);
+    method public void setType(@Nullable android.audio.policy.engine.configuration.PfwCriterionTypeEnum);
+    method public void setValues(@Nullable android.audio.policy.engine.configuration.ValuesType);
+  }
+
+  public class CriterionTypesType {
+    ctor public CriterionTypesType();
+    method @Nullable public java.util.List<android.audio.policy.engine.configuration.CriterionTypeType> getCriterion_type();
+  }
+
+  public enum DeviceCategory {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.engine.configuration.DeviceCategory DEVICE_CATEGORY_EARPIECE;
+    enum_constant public static final android.audio.policy.engine.configuration.DeviceCategory DEVICE_CATEGORY_EXT_MEDIA;
+    enum_constant public static final android.audio.policy.engine.configuration.DeviceCategory DEVICE_CATEGORY_HEADSET;
+    enum_constant public static final android.audio.policy.engine.configuration.DeviceCategory DEVICE_CATEGORY_HEARING_AID;
+    enum_constant public static final android.audio.policy.engine.configuration.DeviceCategory DEVICE_CATEGORY_SPEAKER;
+  }
+
+  public enum FlagType {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.engine.configuration.FlagType AUDIO_FLAG_AUDIBILITY_ENFORCED;
+    enum_constant public static final android.audio.policy.engine.configuration.FlagType AUDIO_FLAG_BEACON;
+    enum_constant public static final android.audio.policy.engine.configuration.FlagType AUDIO_FLAG_BYPASS_INTERRUPTION_POLICY;
+    enum_constant public static final android.audio.policy.engine.configuration.FlagType AUDIO_FLAG_BYPASS_MUTE;
+    enum_constant public static final android.audio.policy.engine.configuration.FlagType AUDIO_FLAG_CAPTURE_PRIVATE;
+    enum_constant public static final android.audio.policy.engine.configuration.FlagType AUDIO_FLAG_DEEP_BUFFER;
+    enum_constant public static final android.audio.policy.engine.configuration.FlagType AUDIO_FLAG_HW_AV_SYNC;
+    enum_constant public static final android.audio.policy.engine.configuration.FlagType AUDIO_FLAG_HW_HOTWORD;
+    enum_constant public static final android.audio.policy.engine.configuration.FlagType AUDIO_FLAG_LOW_LATENCY;
+    enum_constant public static final android.audio.policy.engine.configuration.FlagType AUDIO_FLAG_MUTE_HAPTIC;
+    enum_constant public static final android.audio.policy.engine.configuration.FlagType AUDIO_FLAG_NONE;
+    enum_constant public static final android.audio.policy.engine.configuration.FlagType AUDIO_FLAG_NO_MEDIA_PROJECTION;
+    enum_constant public static final android.audio.policy.engine.configuration.FlagType AUDIO_FLAG_NO_SYSTEM_CAPTURE;
+    enum_constant public static final android.audio.policy.engine.configuration.FlagType AUDIO_FLAG_SCO;
+    enum_constant public static final android.audio.policy.engine.configuration.FlagType AUDIO_FLAG_SECURE;
+  }
+
+  public class FlagsType {
+    ctor public FlagsType();
+    method @Nullable public java.util.List<android.audio.policy.engine.configuration.FlagType> getValue();
+    method public void setValue(@Nullable java.util.List<android.audio.policy.engine.configuration.FlagType>);
+  }
+
+  public enum PfwCriterionTypeEnum {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.engine.configuration.PfwCriterionTypeEnum exclusive;
+    enum_constant public static final android.audio.policy.engine.configuration.PfwCriterionTypeEnum inclusive;
+  }
+
+  public class ProductStrategies {
+    ctor public ProductStrategies();
+    method @Nullable public java.util.List<android.audio.policy.engine.configuration.ProductStrategies.ProductStrategy> getProductStrategy();
+  }
+
+  public static class ProductStrategies.ProductStrategy {
+    ctor public ProductStrategies.ProductStrategy();
+    method @Nullable public java.util.List<android.audio.policy.engine.configuration.AttributesGroup> getAttributesGroup();
+    method @Nullable public String getName();
+    method public void setName(@Nullable String);
+  }
+
+  public enum SourceEnumType {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.engine.configuration.SourceEnumType AUDIO_SOURCE_CAMCORDER;
+    enum_constant public static final android.audio.policy.engine.configuration.SourceEnumType AUDIO_SOURCE_DEFAULT;
+    enum_constant public static final android.audio.policy.engine.configuration.SourceEnumType AUDIO_SOURCE_ECHO_REFERENCE;
+    enum_constant public static final android.audio.policy.engine.configuration.SourceEnumType AUDIO_SOURCE_FM_TUNER;
+    enum_constant public static final android.audio.policy.engine.configuration.SourceEnumType AUDIO_SOURCE_MIC;
+    enum_constant public static final android.audio.policy.engine.configuration.SourceEnumType AUDIO_SOURCE_REMOTE_SUBMIX;
+    enum_constant public static final android.audio.policy.engine.configuration.SourceEnumType AUDIO_SOURCE_UNPROCESSED;
+    enum_constant public static final android.audio.policy.engine.configuration.SourceEnumType AUDIO_SOURCE_VOICE_CALL;
+    enum_constant public static final android.audio.policy.engine.configuration.SourceEnumType AUDIO_SOURCE_VOICE_COMMUNICATION;
+    enum_constant public static final android.audio.policy.engine.configuration.SourceEnumType AUDIO_SOURCE_VOICE_DOWNLINK;
+    enum_constant public static final android.audio.policy.engine.configuration.SourceEnumType AUDIO_SOURCE_VOICE_PERFORMANCE;
+    enum_constant public static final android.audio.policy.engine.configuration.SourceEnumType AUDIO_SOURCE_VOICE_RECOGNITION;
+    enum_constant public static final android.audio.policy.engine.configuration.SourceEnumType AUDIO_SOURCE_VOICE_UPLINK;
+  }
+
+  public class SourceType {
+    ctor public SourceType();
+    method @Nullable public android.audio.policy.engine.configuration.SourceEnumType getValue();
+    method public void setValue(@Nullable android.audio.policy.engine.configuration.SourceEnumType);
+  }
+
+  public enum Stream {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.engine.configuration.Stream AUDIO_STREAM_ACCESSIBILITY;
+    enum_constant public static final android.audio.policy.engine.configuration.Stream AUDIO_STREAM_ALARM;
+    enum_constant public static final android.audio.policy.engine.configuration.Stream AUDIO_STREAM_ASSISTANT;
+    enum_constant public static final android.audio.policy.engine.configuration.Stream AUDIO_STREAM_BLUETOOTH_SCO;
+    enum_constant public static final android.audio.policy.engine.configuration.Stream AUDIO_STREAM_DEFAULT;
+    enum_constant public static final android.audio.policy.engine.configuration.Stream AUDIO_STREAM_DTMF;
+    enum_constant public static final android.audio.policy.engine.configuration.Stream AUDIO_STREAM_ENFORCED_AUDIBLE;
+    enum_constant public static final android.audio.policy.engine.configuration.Stream AUDIO_STREAM_MUSIC;
+    enum_constant public static final android.audio.policy.engine.configuration.Stream AUDIO_STREAM_NOTIFICATION;
+    enum_constant public static final android.audio.policy.engine.configuration.Stream AUDIO_STREAM_RING;
+    enum_constant public static final android.audio.policy.engine.configuration.Stream AUDIO_STREAM_SYSTEM;
+    enum_constant public static final android.audio.policy.engine.configuration.Stream AUDIO_STREAM_TTS;
+    enum_constant public static final android.audio.policy.engine.configuration.Stream AUDIO_STREAM_VOICE_CALL;
+  }
+
+  public enum UsageEnumType {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.engine.configuration.UsageEnumType AUDIO_USAGE_ALARM;
+    enum_constant public static final android.audio.policy.engine.configuration.UsageEnumType AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY;
+    enum_constant public static final android.audio.policy.engine.configuration.UsageEnumType AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE;
+    enum_constant public static final android.audio.policy.engine.configuration.UsageEnumType AUDIO_USAGE_ASSISTANCE_SONIFICATION;
+    enum_constant public static final android.audio.policy.engine.configuration.UsageEnumType AUDIO_USAGE_ASSISTANT;
+    enum_constant public static final android.audio.policy.engine.configuration.UsageEnumType AUDIO_USAGE_CALL_ASSISTANT;
+    enum_constant public static final android.audio.policy.engine.configuration.UsageEnumType AUDIO_USAGE_GAME;
+    enum_constant public static final android.audio.policy.engine.configuration.UsageEnumType AUDIO_USAGE_MEDIA;
+    enum_constant public static final android.audio.policy.engine.configuration.UsageEnumType AUDIO_USAGE_NOTIFICATION;
+    enum_constant public static final android.audio.policy.engine.configuration.UsageEnumType AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED;
+    enum_constant public static final android.audio.policy.engine.configuration.UsageEnumType AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT;
+    enum_constant public static final android.audio.policy.engine.configuration.UsageEnumType AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST;
+    enum_constant public static final android.audio.policy.engine.configuration.UsageEnumType AUDIO_USAGE_NOTIFICATION_EVENT;
+    enum_constant public static final android.audio.policy.engine.configuration.UsageEnumType AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE;
+    enum_constant public static final android.audio.policy.engine.configuration.UsageEnumType AUDIO_USAGE_UNKNOWN;
+    enum_constant public static final android.audio.policy.engine.configuration.UsageEnumType AUDIO_USAGE_VIRTUAL_SOURCE;
+    enum_constant public static final android.audio.policy.engine.configuration.UsageEnumType AUDIO_USAGE_VOICE_COMMUNICATION;
+    enum_constant public static final android.audio.policy.engine.configuration.UsageEnumType AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING;
+  }
+
+  public class UsageType {
+    ctor public UsageType();
+    method @Nullable public android.audio.policy.engine.configuration.UsageEnumType getValue();
+    method public void setValue(@Nullable android.audio.policy.engine.configuration.UsageEnumType);
+  }
+
+  public class ValueType {
+    ctor public ValueType();
+    method @Nullable public String getAndroid_type();
+    method @Nullable public String getLiteral();
+    method @Nullable public long getNumerical();
+    method public void setAndroid_type(@Nullable String);
+    method public void setLiteral(@Nullable String);
+    method public void setNumerical(@Nullable long);
+  }
+
+  public class ValuesType {
+    ctor public ValuesType();
+    method @Nullable public java.util.List<android.audio.policy.engine.configuration.ValueType> getValue();
+  }
+
+  public enum Version {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.engine.configuration.Version _1_0;
+  }
+
+  public class Volume {
+    ctor public Volume();
+    method @Nullable public android.audio.policy.engine.configuration.DeviceCategory getDeviceCategory();
+    method @Nullable public java.util.List<java.lang.String> getPoint();
+    method @Nullable public String getRef();
+    method public void setDeviceCategory(@Nullable android.audio.policy.engine.configuration.DeviceCategory);
+    method public void setRef(@Nullable String);
+  }
+
+  public class VolumeGroupsType {
+    ctor public VolumeGroupsType();
+    method @Nullable public java.util.List<android.audio.policy.engine.configuration.VolumeGroupsType.VolumeGroup> getVolumeGroup();
+  }
+
+  public static class VolumeGroupsType.VolumeGroup {
+    ctor public VolumeGroupsType.VolumeGroup();
+    method @Nullable public int getIndexMax();
+    method @Nullable public int getIndexMin();
+    method @Nullable public String getName();
+    method @Nullable public java.util.List<android.audio.policy.engine.configuration.Volume> getVolume();
+    method public void setIndexMax(@Nullable int);
+    method public void setIndexMin(@Nullable int);
+    method public void setName(@Nullable String);
+  }
+
+  public class VolumeRef {
+    ctor public VolumeRef();
+    method @Nullable public String getName();
+    method @Nullable public java.util.List<java.lang.String> getPoint();
+    method public void setName(@Nullable String);
+  }
+
+  public class VolumesType {
+    ctor public VolumesType();
+    method @Nullable public java.util.List<android.audio.policy.engine.configuration.VolumeRef> getReference();
+  }
+
+  public class XmlParser {
+    ctor public XmlParser();
+    method @Nullable public static android.audio.policy.engine.configuration.Configuration read(@NonNull java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method @Nullable public static String readText(@NonNull org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public static void skip(@NonNull org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+  }
+
+}
+
diff --git a/audio/aidl/default/config/audioPolicy/engine/api/last_current.txt b/audio/aidl/default/config/audioPolicy/engine/api/last_current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/audio/aidl/default/config/audioPolicy/engine/api/last_current.txt
diff --git a/audio/aidl/default/config/audioPolicy/engine/api/last_removed.txt b/audio/aidl/default/config/audioPolicy/engine/api/last_removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/audio/aidl/default/config/audioPolicy/engine/api/last_removed.txt
diff --git a/audio/aidl/default/config/audioPolicy/engine/api/removed.txt b/audio/aidl/default/config/audioPolicy/engine/api/removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/audio/aidl/default/config/audioPolicy/engine/api/removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/audio/aidl/default/config/audioPolicy/engine/audio_policy_engine_configuration.xsd b/audio/aidl/default/config/audioPolicy/engine/audio_policy_engine_configuration.xsd
new file mode 100644
index 0000000..b58a6c8
--- /dev/null
+++ b/audio/aidl/default/config/audioPolicy/engine/audio_policy_engine_configuration.xsd
@@ -0,0 +1,418 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+     -->
+
+ <xs:schema version="2.0"
+            elementFormDefault="qualified"
+            attributeFormDefault="unqualified"
+            xmlns:xs="http://www.w3.org/2001/XMLSchema">
+    <!-- List the config versions supported by audio policy engine. -->
+    <xs:simpleType name="version">
+        <xs:restriction base="xs:decimal">
+            <xs:enumeration value="1.0"/>
+        </xs:restriction>
+    </xs:simpleType>
+
+    <xs:element name="configuration">
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element name="ProductStrategies" type="ProductStrategies"  minOccurs="0" maxOccurs="unbounded"/>
+                <xs:element name="criterion_types" type="criterionTypesType"  minOccurs="0" maxOccurs="unbounded"/>
+                <xs:element name="criteria" type="criteriaType"  minOccurs="0" maxOccurs="unbounded"/>
+                <xs:element name="volumeGroups" type="volumeGroupsType"  minOccurs="0" maxOccurs="unbounded"/>
+                <xs:element name="volumes" type="volumesType" minOccurs="0" maxOccurs="unbounded"/>
+                <xs:element name="attributesRef" type="attributesRef"  minOccurs="0" maxOccurs="unbounded"/>
+            </xs:sequence>
+            <xs:attribute name="version" type="version" use="required"/>
+        </xs:complexType>
+
+        <xs:key name="volumeCurveNameKey">
+            <xs:selector xpath="volumes/reference"/>
+            <xs:field xpath="@name"/>
+        </xs:key>
+        <xs:keyref name="volumeCurveRef" refer="volumeCurveNameKey">
+            <xs:selector xpath="volumeGroups/volumeGroup"/>
+            <xs:field xpath="@ref"/>
+        </xs:keyref>
+
+        <xs:key name="attributesRefNameKey">
+            <xs:selector xpath="attributesRef/reference"/>
+            <xs:field xpath="@name"/>
+        </xs:key>
+        <xs:keyref name="volumeGroupAttributesRef" refer="attributesRefNameKey">
+            <xs:selector xpath="volumeGroups/volumeGroup/volume"/>
+            <xs:field xpath="@attributesRef"/>
+        </xs:keyref>
+        <xs:keyref name="ProductStrategyAttributesRef" refer="attributesRefNameKey">
+            <xs:selector xpath="ProductStrategies/ProductStrategy/Attributes"/>
+            <xs:field xpath="@attributesRef"/>
+        </xs:keyref>
+
+        <xs:unique name="productStrategyNameUniqueness">
+            <xs:selector xpath="ProductStrategies/ProductStrategy"/>
+            <xs:field xpath="@name"/>
+        </xs:unique>
+
+        <!-- ensure validity of volume group referred in product strategy-->
+        <xs:key name="volumeGroupKey">
+            <xs:selector xpath="volumeGroups/volumeGroup/name"/>
+            <xs:field xpath="."/>
+        </xs:key>
+        <xs:keyref name="volumeGroupRef" refer="volumeGroupKey">
+            <xs:selector xpath="ProductStrategies/ProductStrategy/AttributesGroup"/>
+            <xs:field xpath="@volumeGroup"/>
+        </xs:keyref>
+
+        <xs:unique name="volumeTargetUniqueness">
+            <xs:selector xpath="volumeGroups/volumeGroup"/>
+            <xs:field xpath="@name"/>
+            <xs:field xpath="@deviceCategory"/>
+        </xs:unique>
+
+        <!-- ensure validity of criterion type referred in criterion-->
+        <xs:key name="criterionTypeKey">
+            <xs:selector xpath="criterion_types/criterion_type"/>
+            <xs:field xpath="@name"/>
+        </xs:key>
+        <xs:keyref name="criterionTypeKeyRef" refer="criterionTypeKey">
+            <xs:selector xpath="criteria/criterion"/>
+            <xs:field xpath="@type"/>
+        </xs:keyref>
+
+    </xs:element>
+
+    <xs:complexType name="ProductStrategies">
+        <xs:annotation>
+            <xs:documentation xml:lang="en">
+            </xs:documentation>
+        </xs:annotation>
+        <xs:sequence>
+            <xs:element name="ProductStrategy" maxOccurs="unbounded">
+                <xs:complexType>
+                    <xs:sequence>
+                        <xs:element name="AttributesGroup" type="AttributesGroup" minOccurs="1" maxOccurs="unbounded"/>
+                    </xs:sequence>
+                    <xs:attribute name="name" type="xs:string" use="required"/>
+                </xs:complexType>
+            </xs:element>
+        </xs:sequence>
+    </xs:complexType>
+
+    <xs:complexType name="AttributesGroup">
+        <xs:sequence>
+            <xs:choice minOccurs="0">
+                <xs:element name="Attributes" type="AttributesType" minOccurs="1" maxOccurs="unbounded"/>
+                <xs:sequence>
+                    <xs:element name="ContentType" type="ContentTypeType" minOccurs="0" maxOccurs="1"/>
+                    <xs:element name="Usage" type="UsageType" minOccurs="1" maxOccurs="1"/>
+                    <xs:element name="Source" type="SourceType" minOccurs="0" maxOccurs="1"/>
+                    <xs:element name="Flags" type="FlagsType" minOccurs="0" maxOccurs="1"/>
+                    <xs:element name="Bundle" type="BundleType" minOccurs="0" maxOccurs="1"/>
+                </xs:sequence>
+            </xs:choice>
+        </xs:sequence>
+        <xs:attribute name="streamType" type="stream" use="optional"/>
+        <xs:attribute name="volumeGroup" type="xs:string" use="optional"/>
+    </xs:complexType>
+
+    <xs:complexType name="volumeGroupsType">
+        <xs:sequence>
+             <xs:element name="volumeGroup" minOccurs="0" maxOccurs="unbounded">
+                <xs:complexType>
+                    <xs:sequence>
+                         <xs:element name="name" type="xs:token"/>
+                         <xs:element name="indexMin" type="xs:int" minOccurs="0" maxOccurs="1"/>
+                         <xs:element name="indexMax" type="xs:int" minOccurs="0" maxOccurs="1"/>
+                         <xs:element name="volume" type="volume" minOccurs="1" maxOccurs="unbounded"/>
+                     </xs:sequence>
+                </xs:complexType>
+                <xs:unique name="volumeAttributesUniqueness">
+                    <xs:selector xpath="volume"/>
+                    <xs:field xpath="deviceCategory"/>
+                </xs:unique>
+             </xs:element>
+        </xs:sequence>
+    </xs:complexType>
+
+    <xs:complexType name="volumesType">
+        <xs:sequence>
+            <xs:element name="reference" type="volumeRef" minOccurs="0" maxOccurs="unbounded"/>
+        </xs:sequence>
+    </xs:complexType>
+
+    <xs:complexType name="attributesRef">
+        <xs:sequence>
+            <xs:element name="reference" type="attributesRefType" minOccurs="0" maxOccurs="unbounded"/>
+        </xs:sequence>
+    </xs:complexType>
+
+    <xs:complexType name="criteriaType">
+        <xs:sequence>
+            <xs:element name="criterion" type="criterionType" maxOccurs="unbounded"/>
+        </xs:sequence>
+    </xs:complexType>
+    <xs:complexType name="criterionType">
+        <xs:attribute name="name" type="xs:string" use="required"/>
+        <xs:attribute name="type" type="xs:string" use="required"/>
+        <xs:attribute name="default" type="xs:string" use="optional"/>
+    </xs:complexType>
+
+    <xs:complexType name="criterionTypesType">
+        <xs:sequence>
+            <xs:element name="criterion_type" type="criterionTypeType" maxOccurs="unbounded"/>
+        </xs:sequence>
+    </xs:complexType>
+    <xs:complexType name="criterionTypeType">
+        <xs:sequence>
+            <xs:element name="values" type="valuesType" minOccurs="0" maxOccurs="1"/>
+        </xs:sequence>
+        <xs:attribute name="name" type="xs:token" use="required"/>
+        <xs:attribute name="type" type="pfwCriterionTypeEnum" use="required"/>
+    </xs:complexType>
+
+    <xs:complexType name="valuesType">
+        <xs:sequence>
+            <xs:element name="value" type="valueType" maxOccurs="unbounded"/>
+        </xs:sequence>
+    </xs:complexType>
+    <xs:complexType name="valueType">
+        <xs:attribute name="literal" type="xs:string" use="required"/>
+        <xs:attribute name="numerical" type="xs:long" use="required"/>
+        <xs:attribute name="android_type" type="longDecimalOrHexType" use="optional"/>
+    </xs:complexType>
+
+    <xs:simpleType name="longDecimalOrHexType">
+      <xs:union memberTypes="xs:long longHexType" />
+    </xs:simpleType>
+
+    <xs:simpleType name="longHexType">
+      <xs:restriction base="xs:string">
+        <xs:pattern value="0x[0-9A-Fa-f]{1,16}"/>
+      </xs:restriction>
+    </xs:simpleType>
+
+    <xs:complexType name="attributesRefType">
+        <xs:sequence>
+            <xs:element name="Attributes" type="AttributesType" minOccurs="1" maxOccurs="1"/>
+        </xs:sequence>
+        <xs:attribute name="name" type="xs:token" use="required"/>
+    </xs:complexType>
+
+    <xs:complexType name="AttributesType">
+        <xs:sequence>
+            <xs:element name="ContentType" type="ContentTypeType" minOccurs="0" maxOccurs="1"/>
+            <xs:element name="Usage" type="UsageType" minOccurs="0" maxOccurs="1"/>
+            <xs:element name="Source" type="SourceType" minOccurs="0" maxOccurs="1"/>
+            <xs:element name="Flags" type="FlagsType" minOccurs="0" maxOccurs="1"/>
+            <xs:element name="Bundle" type="BundleType" minOccurs="0" maxOccurs="1"/>
+        </xs:sequence>
+        <xs:attribute name="attributesRef" type="xs:token" use="optional"/>
+        <!-- with xsd 1.1, it is impossible to make choice on either attributes or element...-->
+    </xs:complexType>
+
+    <xs:complexType name="ContentTypeType">
+        <xs:attribute name="value" type="contentType" use="required"/>
+    </xs:complexType>
+    <xs:complexType name="UsageType">
+        <xs:attribute name="value" type="usageEnumType" use="required"/>
+    </xs:complexType>
+    <xs:complexType name="SourceType">
+        <xs:attribute name="value" type="sourceEnumType" use="required"/>
+    </xs:complexType>
+    <xs:complexType name="FlagsType">
+        <xs:attribute name="value" type="flagsEnumType" use="required"/>
+    </xs:complexType>
+    <xs:complexType name="BundleType">
+        <xs:attribute name="key" type="xs:string" use="required"/>
+        <xs:attribute name="value" type="xs:string" use="required"/>
+    </xs:complexType>
+
+    <xs:complexType name="volume">
+        <xs:annotation>
+            <xs:documentation xml:lang="en">
+                Volume section defines a volume curve for a given use case and device category.
+                It contains a list of points of this curve expressing the attenuation in Millibels
+                for a given volume index from 0 to 100.
+                <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+                    <point>0,-9600</point>
+                    <point>100,0</point>
+                </volume>
+
+                It may also reference a reference/@name to avoid duplicating curves.
+                <volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_MEDIA_VOLUME_CURVE"/>
+                <reference name="DEFAULT_MEDIA_VOLUME_CURVE">
+                    <point>0,-9600</point>
+                    <point>100,0</point>
+                </reference>
+            </xs:documentation>
+        </xs:annotation>
+        <xs:sequence>
+            <xs:element name="point" type="volumePoint" minOccurs="0" maxOccurs="unbounded"/>
+        </xs:sequence>
+        <xs:attribute name="deviceCategory" type="deviceCategory"/>
+        <xs:attribute name="ref" type="xs:token" use="optional"/>
+    </xs:complexType>
+
+    <xs:complexType name="volumeRef">
+        <xs:sequence>
+            <xs:element name="point" type="volumePoint" minOccurs="2" maxOccurs="unbounded"/>
+        </xs:sequence>
+        <xs:attribute name="name" type="xs:token" use="required"/>
+    </xs:complexType>
+
+    <xs:simpleType name="volumePoint">
+        <xs:annotation>
+            <xs:documentation xml:lang="en">
+                Comma separated pair of number.
+                The fist one is the framework level (between 0 and 100).
+                The second one is the volume to send to the HAL.
+                The framework will interpolate volumes not specified.
+                Their MUST be at least 2 points specified.
+            </xs:documentation>
+        </xs:annotation>
+        <xs:restriction base="xs:string">
+            <xs:pattern value="([0-9]{1,2}|100),-?[0-9]+"/>
+        </xs:restriction>
+    </xs:simpleType>
+
+
+    <xs:simpleType name="streamsCsv">
+        <xs:list>
+            <xs:simpleType>
+                <xs:restriction base="stream">
+                </xs:restriction>
+            </xs:simpleType>
+        </xs:list>
+    </xs:simpleType>
+
+    <!-- Enum values of audio_stream_type_t in audio-base.h
+         TODO: avoid manual sync. -->
+    <xs:simpleType name="stream">
+        <xs:restriction base="xs:NMTOKEN">
+            <!--xs:pattern value="\c+(,\c+)*"/-->
+            <xs:enumeration value="AUDIO_STREAM_DEFAULT"/>
+            <xs:enumeration value="AUDIO_STREAM_VOICE_CALL"/>
+            <xs:enumeration value="AUDIO_STREAM_SYSTEM"/>
+            <xs:enumeration value="AUDIO_STREAM_RING"/>
+            <xs:enumeration value="AUDIO_STREAM_MUSIC"/>
+            <xs:enumeration value="AUDIO_STREAM_ALARM"/>
+            <xs:enumeration value="AUDIO_STREAM_NOTIFICATION"/>
+            <xs:enumeration value="AUDIO_STREAM_BLUETOOTH_SCO"/>
+            <xs:enumeration value="AUDIO_STREAM_ENFORCED_AUDIBLE"/>
+            <xs:enumeration value="AUDIO_STREAM_DTMF"/>
+            <xs:enumeration value="AUDIO_STREAM_TTS"/>
+            <xs:enumeration value="AUDIO_STREAM_ACCESSIBILITY"/>
+            <xs:enumeration value="AUDIO_STREAM_ASSISTANT"/>
+        </xs:restriction>
+    </xs:simpleType>
+
+    <xs:simpleType name="deviceCategory">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="DEVICE_CATEGORY_HEADSET"/>
+            <xs:enumeration value="DEVICE_CATEGORY_SPEAKER"/>
+            <xs:enumeration value="DEVICE_CATEGORY_EARPIECE"/>
+            <xs:enumeration value="DEVICE_CATEGORY_EXT_MEDIA"/>
+            <xs:enumeration value="DEVICE_CATEGORY_HEARING_AID"/>
+        </xs:restriction>
+    </xs:simpleType>
+
+    <xs:simpleType name="contentType">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="AUDIO_CONTENT_TYPE_UNKNOWN"/>
+            <xs:enumeration value="AUDIO_CONTENT_TYPE_SPEECH"/>
+            <xs:enumeration value="AUDIO_CONTENT_TYPE_MUSIC"/>
+            <xs:enumeration value="AUDIO_CONTENT_TYPE_MOVIE"/>
+            <xs:enumeration value="AUDIO_CONTENT_TYPE_SONIFICATION"/>
+        </xs:restriction>
+    </xs:simpleType>
+
+    <xs:simpleType name="usageEnumType">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="AUDIO_USAGE_UNKNOWN"/>
+            <xs:enumeration value="AUDIO_USAGE_MEDIA"/>
+            <xs:enumeration value="AUDIO_USAGE_VOICE_COMMUNICATION"/>
+            <xs:enumeration value="AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING"/>
+            <xs:enumeration value="AUDIO_USAGE_ALARM"/>
+            <xs:enumeration value="AUDIO_USAGE_NOTIFICATION"/>
+            <xs:enumeration value="AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE"/>
+            <!-- Note: the following 3 values were deprecated in Android T (13) SDK -->
+            <xs:enumeration value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST"/>
+            <xs:enumeration value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT"/>
+            <xs:enumeration value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED"/>
+            <xs:enumeration value="AUDIO_USAGE_NOTIFICATION_EVENT"/>
+            <xs:enumeration value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY"/>
+            <xs:enumeration value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"/>
+            <xs:enumeration value="AUDIO_USAGE_ASSISTANCE_SONIFICATION"/>
+            <xs:enumeration value="AUDIO_USAGE_GAME"/>
+            <xs:enumeration value="AUDIO_USAGE_VIRTUAL_SOURCE"/>
+            <xs:enumeration value="AUDIO_USAGE_ASSISTANT"/>
+            <xs:enumeration value="AUDIO_USAGE_CALL_ASSISTANT"/>
+        </xs:restriction>
+    </xs:simpleType>
+
+    <xs:simpleType name="flagsEnumType">
+        <xs:list>
+            <xs:simpleType>
+                <xs:restriction base="flagType">
+                </xs:restriction>
+            </xs:simpleType>
+        </xs:list>
+    </xs:simpleType>
+
+    <xs:simpleType name="flagType">
+        <xs:restriction base="xs:NMTOKEN">
+            <xs:enumeration value="AUDIO_FLAG_NONE"/>
+            <xs:enumeration value="AUDIO_FLAG_AUDIBILITY_ENFORCED"/>
+            <xs:enumeration value="AUDIO_FLAG_SECURE"/>
+            <xs:enumeration value="AUDIO_FLAG_SCO"/>
+            <xs:enumeration value="AUDIO_FLAG_BEACON"/>
+            <xs:enumeration value="AUDIO_FLAG_HW_AV_SYNC"/>
+            <xs:enumeration value="AUDIO_FLAG_HW_HOTWORD"/>
+            <xs:enumeration value="AUDIO_FLAG_BYPASS_INTERRUPTION_POLICY"/>
+            <xs:enumeration value="AUDIO_FLAG_BYPASS_MUTE"/>
+            <xs:enumeration value="AUDIO_FLAG_LOW_LATENCY"/>
+            <xs:enumeration value="AUDIO_FLAG_DEEP_BUFFER"/>
+            <xs:enumeration value="AUDIO_FLAG_NO_MEDIA_PROJECTION"/>
+            <xs:enumeration value="AUDIO_FLAG_MUTE_HAPTIC"/>
+            <xs:enumeration value="AUDIO_FLAG_NO_SYSTEM_CAPTURE"/>
+            <xs:enumeration value="AUDIO_FLAG_CAPTURE_PRIVATE"/>
+        </xs:restriction>
+    </xs:simpleType>
+
+    <xs:simpleType name="sourceEnumType">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="AUDIO_SOURCE_DEFAULT"/>
+            <xs:enumeration value="AUDIO_SOURCE_MIC"/>
+            <xs:enumeration value="AUDIO_SOURCE_VOICE_UPLINK"/>
+            <xs:enumeration value="AUDIO_SOURCE_VOICE_DOWNLINK"/>
+            <xs:enumeration value="AUDIO_SOURCE_VOICE_CALL"/>
+            <xs:enumeration value="AUDIO_SOURCE_CAMCORDER"/>
+            <xs:enumeration value="AUDIO_SOURCE_VOICE_RECOGNITION"/>
+            <xs:enumeration value="AUDIO_SOURCE_VOICE_COMMUNICATION"/>
+            <xs:enumeration value="AUDIO_SOURCE_REMOTE_SUBMIX"/>
+            <xs:enumeration value="AUDIO_SOURCE_UNPROCESSED"/>
+            <xs:enumeration value="AUDIO_SOURCE_VOICE_PERFORMANCE"/>
+            <xs:enumeration value="AUDIO_SOURCE_ECHO_REFERENCE"/>
+            <xs:enumeration value="AUDIO_SOURCE_FM_TUNER"/>
+        </xs:restriction>
+    </xs:simpleType>
+
+    <xs:simpleType name="pfwCriterionTypeEnum">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="inclusive"/>
+            <xs:enumeration value="exclusive"/>
+        </xs:restriction>
+    </xs:simpleType>
+</xs:schema>
diff --git a/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.cpp b/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.cpp
index 3920a58..4efd0a5 100644
--- a/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.cpp
+++ b/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.cpp
@@ -73,8 +73,6 @@
 ndk::ScopedAStatus DynamicsProcessingSw::setParameterSpecific(const Parameter::Specific& specific) {
     RETURN_IF(Parameter::Specific::dynamicsProcessing != specific.getTag(), EX_ILLEGAL_ARGUMENT,
               "EffectNotSupported");
-    std::lock_guard lg(mMutex);
-    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
 
     mSpecificParam = specific.get<Parameter::Specific::dynamicsProcessing>();
     LOG(DEBUG) << __func__ << " success with: " << specific.toString();
@@ -93,9 +91,13 @@
         const Parameter::Common& common) {
     if (mContext) {
         LOG(DEBUG) << __func__ << " context already exist";
-        return mContext;
+    } else {
+        mContext = std::make_shared<DynamicsProcessingSwContext>(1 /* statusFmqDepth */, common);
     }
-    mContext = std::make_shared<DynamicsProcessingSwContext>(1 /* statusFmqDepth */, common);
+    return mContext;
+}
+
+std::shared_ptr<EffectContext> DynamicsProcessingSw::getContext() {
     return mContext;
 }
 
@@ -107,13 +109,13 @@
 }
 
 // Processing method running in EffectWorker thread.
-IEffect::Status DynamicsProcessingSw::effectProcessImpl(float* in, float* out, int process) {
+IEffect::Status DynamicsProcessingSw::effectProcessImpl(float* in, float* out, int samples) {
     // TODO: get data buffer and process.
-    LOG(DEBUG) << __func__ << " in " << in << " out " << out << " process " << process;
-    for (int i = 0; i < process; i++) {
+    LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
+    for (int i = 0; i < samples; i++) {
         *out++ = *in++;
     }
-    return {STATUS_OK, process, process};
+    return {STATUS_OK, samples, samples};
 }
 
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.h b/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.h
index 2bc2762..3ad4f77 100644
--- a/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.h
+++ b/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.h
@@ -47,11 +47,16 @@
     ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
     ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
                                             Parameter::Specific* specific) override;
-    IEffect::Status effectProcessImpl(float* in, float* out, int process) override;
+
     std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
+    std::shared_ptr<EffectContext> getContext() override;
     RetCode releaseContext() override;
 
+    IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+    std::string getEffectName() override { return kEffectName; };
+
   private:
+    const std::string kEffectName = "DynamicsProcessingSw";
     std::shared_ptr<DynamicsProcessingSwContext> mContext;
     /* capabilities */
     const DynamicsProcessing::Capability kCapability;
@@ -63,7 +68,7 @@
                        .flags = {.type = Flags::Type::INSERT,
                                  .insert = Flags::Insert::FIRST,
                                  .volume = Flags::Volume::CTRL},
-                       .name = "DynamicsProcessingSw",
+                       .name = kEffectName,
                        .implementor = "The Android Open Source Project"},
             .capability = Capability::make<Capability::dynamicsProcessing>(kCapability)};
 
diff --git a/audio/aidl/default/envReverb/EnvReverbSw.cpp b/audio/aidl/default/envReverb/EnvReverbSw.cpp
index ad447ab..cb09293 100644
--- a/audio/aidl/default/envReverb/EnvReverbSw.cpp
+++ b/audio/aidl/default/envReverb/EnvReverbSw.cpp
@@ -73,8 +73,6 @@
 ndk::ScopedAStatus EnvReverbSw::setParameterSpecific(const Parameter::Specific& specific) {
     RETURN_IF(Parameter::Specific::reverb != specific.getTag(), EX_ILLEGAL_ARGUMENT,
               "EffectNotSupported");
-    std::lock_guard lg(mMutex);
-    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
 
     mSpecificParam = specific.get<Parameter::Specific::reverb>();
     LOG(DEBUG) << __func__ << " success with: " << specific.toString();
@@ -92,9 +90,14 @@
 std::shared_ptr<EffectContext> EnvReverbSw::createContext(const Parameter::Common& common) {
     if (mContext) {
         LOG(DEBUG) << __func__ << " context already exist";
-        return mContext;
+    } else {
+        mContext = std::make_shared<EnvReverbSwContext>(1 /* statusFmqDepth */, common);
     }
-    mContext = std::make_shared<EnvReverbSwContext>(1 /* statusFmqDepth */, common);
+
+    return mContext;
+}
+
+std::shared_ptr<EffectContext> EnvReverbSw::getContext() {
     return mContext;
 }
 
@@ -106,13 +109,13 @@
 }
 
 // Processing method running in EffectWorker thread.
-IEffect::Status EnvReverbSw::effectProcessImpl(float* in, float* out, int process) {
+IEffect::Status EnvReverbSw::effectProcessImpl(float* in, float* out, int samples) {
     // TODO: get data buffer and process.
-    LOG(DEBUG) << __func__ << " in " << in << " out " << out << " process " << process;
-    for (int i = 0; i < process; i++) {
+    LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
+    for (int i = 0; i < samples; i++) {
         *out++ = *in++;
     }
-    return {STATUS_OK, process, process};
+    return {STATUS_OK, samples, samples};
 }
 
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/envReverb/EnvReverbSw.h b/audio/aidl/default/envReverb/EnvReverbSw.h
index 5a9ab27..e8629a2 100644
--- a/audio/aidl/default/envReverb/EnvReverbSw.h
+++ b/audio/aidl/default/envReverb/EnvReverbSw.h
@@ -47,11 +47,16 @@
     ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
     ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
                                             Parameter::Specific* specific) override;
-    IEffect::Status effectProcessImpl(float* in, float* out, int process) override;
+
     std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
+    std::shared_ptr<EffectContext> getContext() override;
     RetCode releaseContext() override;
 
+    IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+    std::string getEffectName() override { return kEffectName; }
+
   private:
+    const std::string kEffectName = "EnvReverbSw";
     std::shared_ptr<EnvReverbSwContext> mContext;
     /* capabilities */
     const Reverb::Capability kCapability;
@@ -63,7 +68,7 @@
                        .flags = {.type = Flags::Type::INSERT,
                                  .insert = Flags::Insert::FIRST,
                                  .volume = Flags::Volume::CTRL},
-                       .name = "EnvReverbSw",
+                       .name = kEffectName,
                        .implementor = "The Android Open Source Project"},
             .capability = Capability::make<Capability::reverb>(kCapability)};
 
diff --git a/audio/aidl/default/equalizer/EqualizerSw.cpp b/audio/aidl/default/equalizer/EqualizerSw.cpp
index d61ef97..243b061 100644
--- a/audio/aidl/default/equalizer/EqualizerSw.cpp
+++ b/audio/aidl/default/equalizer/EqualizerSw.cpp
@@ -70,7 +70,6 @@
 ndk::ScopedAStatus EqualizerSw::setParameterSpecific(const Parameter::Specific& specific) {
     RETURN_IF(Parameter::Specific::equalizer != specific.getTag(), EX_ILLEGAL_ARGUMENT,
               "EffectNotSupported");
-    std::lock_guard lg(mMutex);
     RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
 
     auto& eqParam = specific.get<Parameter::Specific::equalizer>();
@@ -117,7 +116,6 @@
 
 ndk::ScopedAStatus EqualizerSw::getParameterEqualizer(const Equalizer::Tag& tag,
                                                       Parameter::Specific* specific) {
-    std::lock_guard lg(mMutex);
     RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
 
     Equalizer eqParam;
@@ -144,9 +142,14 @@
 std::shared_ptr<EffectContext> EqualizerSw::createContext(const Parameter::Common& common) {
     if (mContext) {
         LOG(DEBUG) << __func__ << " context already exist";
-        return mContext;
+    } else {
+        mContext = std::make_shared<EqualizerSwContext>(1 /* statusFmqDepth */, common);
     }
-    mContext = std::make_shared<EqualizerSwContext>(1 /* statusFmqDepth */, common);
+
+    return mContext;
+}
+
+std::shared_ptr<EffectContext> EqualizerSw::getContext() {
     return mContext;
 }
 
@@ -158,13 +161,13 @@
 }
 
 // Processing method running in EffectWorker thread.
-IEffect::Status EqualizerSw::effectProcessImpl(float* in, float* out, int process) {
+IEffect::Status EqualizerSw::effectProcessImpl(float* in, float* out, int samples) {
     // TODO: get data buffer and process.
-    LOG(DEBUG) << __func__ << " in " << in << " out " << out << " process " << process;
-    for (int i = 0; i < process; i++) {
+    LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
+    for (int i = 0; i < samples; i++) {
         *out++ = *in++;
     }
-    return {STATUS_OK, process, process};
+    return {STATUS_OK, samples, samples};
 }
 
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/equalizer/EqualizerSw.h b/audio/aidl/default/equalizer/EqualizerSw.h
index aa4587a..c104a89 100644
--- a/audio/aidl/default/equalizer/EqualizerSw.h
+++ b/audio/aidl/default/equalizer/EqualizerSw.h
@@ -90,11 +90,16 @@
     ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
     ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
                                             Parameter::Specific* specific) override;
-    IEffect::Status effectProcessImpl(float* in, float* out, int process) override;
+
     std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
+    std::shared_ptr<EffectContext> getContext() override;
     RetCode releaseContext() override;
 
+    IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+    std::string getEffectName() override { return kEffectName; }
+
   private:
+    const std::string kEffectName = "EqualizerSw";
     std::shared_ptr<EqualizerSwContext> mContext;
     /* capabilities */
     const std::vector<Equalizer::BandFrequency> mBandFrequency = {{0, 30000, 120000},
@@ -115,7 +120,7 @@
                                          .flags = {.type = Flags::Type::INSERT,
                                                    .insert = Flags::Insert::FIRST,
                                                    .volume = Flags::Volume::CTRL},
-                                         .name = "EqualizerSw",
+                                         .name = kEffectName,
                                          .implementor = "The Android Open Source Project"},
                               .capability = Capability::make<Capability::equalizer>(kEqCap)};
 
diff --git a/audio/aidl/default/hapticGenerator/HapticGeneratorSw.cpp b/audio/aidl/default/hapticGenerator/HapticGeneratorSw.cpp
index fd5ea34..7e86657 100644
--- a/audio/aidl/default/hapticGenerator/HapticGeneratorSw.cpp
+++ b/audio/aidl/default/hapticGenerator/HapticGeneratorSw.cpp
@@ -73,9 +73,6 @@
 ndk::ScopedAStatus HapticGeneratorSw::setParameterSpecific(const Parameter::Specific& specific) {
     RETURN_IF(Parameter::Specific::hapticGenerator != specific.getTag(), EX_ILLEGAL_ARGUMENT,
               "EffectNotSupported");
-    std::lock_guard lg(mMutex);
-    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
-
     mSpecificParam = specific.get<Parameter::Specific::hapticGenerator>();
     LOG(DEBUG) << __func__ << " success with: " << specific.toString();
     return ndk::ScopedAStatus::ok();
@@ -92,9 +89,14 @@
 std::shared_ptr<EffectContext> HapticGeneratorSw::createContext(const Parameter::Common& common) {
     if (mContext) {
         LOG(DEBUG) << __func__ << " context already exist";
-        return mContext;
+    } else {
+        mContext = std::make_shared<HapticGeneratorSwContext>(1 /* statusFmqDepth */, common);
     }
-    mContext = std::make_shared<HapticGeneratorSwContext>(1 /* statusFmqDepth */, common);
+
+    return mContext;
+}
+
+std::shared_ptr<EffectContext> HapticGeneratorSw::getContext() {
     return mContext;
 }
 
@@ -106,13 +108,13 @@
 }
 
 // Processing method running in EffectWorker thread.
-IEffect::Status HapticGeneratorSw::effectProcessImpl(float* in, float* out, int process) {
+IEffect::Status HapticGeneratorSw::effectProcessImpl(float* in, float* out, int samples) {
     // TODO: get data buffer and process.
-    LOG(DEBUG) << __func__ << " in " << in << " out " << out << " process " << process;
-    for (int i = 0; i < process; i++) {
+    LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
+    for (int i = 0; i < samples; i++) {
         *out++ = *in++;
     }
-    return {STATUS_OK, process, process};
+    return {STATUS_OK, samples, samples};
 }
 
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/hapticGenerator/HapticGeneratorSw.h b/audio/aidl/default/hapticGenerator/HapticGeneratorSw.h
index 518aa87..dbd6c55 100644
--- a/audio/aidl/default/hapticGenerator/HapticGeneratorSw.h
+++ b/audio/aidl/default/hapticGenerator/HapticGeneratorSw.h
@@ -47,11 +47,16 @@
     ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
     ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
                                             Parameter::Specific* specific) override;
-    IEffect::Status effectProcessImpl(float* in, float* out, int process) override;
+
     std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
+    std::shared_ptr<EffectContext> getContext() override;
     RetCode releaseContext() override;
 
+    IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+    std::string getEffectName() override { return kEffectName; }
+
   private:
+    const std::string kEffectName = "HapticGeneratorSw";
     std::shared_ptr<HapticGeneratorSwContext> mContext;
     /* capabilities */
     const HapticGenerator::Capability kCapability;
@@ -63,7 +68,7 @@
                        .flags = {.type = Flags::Type::INSERT,
                                  .insert = Flags::Insert::FIRST,
                                  .volume = Flags::Volume::CTRL},
-                       .name = "HapticGeneratorSw",
+                       .name = kEffectName,
                        .implementor = "The Android Open Source Project"},
             .capability = Capability::make<Capability::hapticGenerator>(kCapability)};
 
diff --git a/audio/aidl/default/include/core-impl/AudioPolicyConfigXmlConverter.h b/audio/aidl/default/include/core-impl/AudioPolicyConfigXmlConverter.h
new file mode 100644
index 0000000..47918f0
--- /dev/null
+++ b/audio/aidl/default/include/core-impl/AudioPolicyConfigXmlConverter.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <string>
+
+#include <aidl/android/media/audio/common/AudioHalEngineConfig.h>
+#include <android_audio_policy_configuration.h>
+#include <android_audio_policy_configuration_enums.h>
+
+#include "core-impl/XmlConverter.h"
+
+namespace aidl::android::hardware::audio::core::internal {
+
+class AudioPolicyConfigXmlConverter {
+  public:
+    explicit AudioPolicyConfigXmlConverter(const std::string& configFilePath)
+        : mConverter(configFilePath, &::android::audio::policy::configuration::read) {}
+
+    std::string getError() const { return mConverter.getError(); }
+    ::android::status_t getStatus() const { return mConverter.getStatus(); }
+
+    const ::aidl::android::media::audio::common::AudioHalEngineConfig& getAidlEngineConfig();
+
+  private:
+    const std::optional<::android::audio::policy::configuration::AudioPolicyConfiguration>&
+    getXsdcConfig() const {
+        return mConverter.getXsdcConfig();
+    }
+    void addVolumeGroupstoEngineConfig();
+    void mapStreamToVolumeCurve(
+            const ::android::audio::policy::configuration::Volume& xsdcVolumeCurve);
+    void mapStreamsToVolumeCurves();
+    void parseVolumes();
+    ::aidl::android::media::audio::common::AudioHalVolumeCurve::CurvePoint convertCurvePointToAidl(
+            const std::string& xsdcCurvePoint);
+
+    ::aidl::android::media::audio::common::AudioHalVolumeCurve convertVolumeCurveToAidl(
+            const ::android::audio::policy::configuration::Volume& xsdcVolumeCurve);
+
+    ::aidl::android::media::audio::common::AudioHalEngineConfig mAidlEngineConfig;
+    XmlConverter<::android::audio::policy::configuration::AudioPolicyConfiguration> mConverter;
+    std::unordered_map<std::string, ::android::audio::policy::configuration::Reference>
+            mVolumesReferenceMap;
+    std::unordered_map<::android::audio::policy::configuration::AudioStreamType,
+                       std::vector<::aidl::android::media::audio::common::AudioHalVolumeCurve>>
+            mStreamToVolumeCurvesMap;
+};
+
+}  // namespace aidl::android::hardware::audio::core::internal
diff --git a/audio/aidl/default/include/core-impl/Config.h b/audio/aidl/default/include/core-impl/Config.h
index 4555efd..96a6cb9 100644
--- a/audio/aidl/default/include/core-impl/Config.h
+++ b/audio/aidl/default/include/core-impl/Config.h
@@ -17,11 +17,22 @@
 #pragma once
 
 #include <aidl/android/hardware/audio/core/BnConfig.h>
+#include <system/audio_config.h>
+
+#include "AudioPolicyConfigXmlConverter.h"
+#include "EngineConfigXmlConverter.h"
 
 namespace aidl::android::hardware::audio::core {
+static const std::string kEngineConfigFileName = "audio_policy_engine_configuration.xml";
 
 class Config : public BnConfig {
     ndk::ScopedAStatus getSurroundSoundConfig(SurroundSoundConfig* _aidl_return) override;
+    ndk::ScopedAStatus getEngineConfig(
+            aidl::android::media::audio::common::AudioHalEngineConfig* _aidl_return) override;
+    internal::AudioPolicyConfigXmlConverter mAudioPolicyConverter{
+            ::android::audio_get_audio_policy_config_file()};
+    internal::EngineConfigXmlConverter mEngConfigConverter{
+            ::android::audio_find_readable_configuration_file(kEngineConfigFileName.c_str())};
 };
 
 }  // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/include/core-impl/EngineConfigXmlConverter.h b/audio/aidl/default/include/core-impl/EngineConfigXmlConverter.h
new file mode 100644
index 0000000..b34441d
--- /dev/null
+++ b/audio/aidl/default/include/core-impl/EngineConfigXmlConverter.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <string>
+#include <unordered_map>
+
+#include <utils/Errors.h>
+
+#include <android_audio_policy_engine_configuration.h>
+#include <android_audio_policy_engine_configuration_enums.h>
+
+#include "core-impl/XmlConverter.h"
+
+namespace aidl::android::hardware::audio::core::internal {
+
+class EngineConfigXmlConverter {
+  public:
+    explicit EngineConfigXmlConverter(const std::string& configFilePath)
+        : mConverter(configFilePath, &::android::audio::policy::engine::configuration::read) {
+        if (mConverter.getXsdcConfig()) {
+            init();
+        }
+    }
+
+    std::string getError() const { return mConverter.getError(); }
+    ::android::status_t getStatus() const { return mConverter.getStatus(); }
+
+    ::aidl::android::media::audio::common::AudioHalEngineConfig& getAidlEngineConfig();
+
+  private:
+    const std::optional<::android::audio::policy::engine::configuration::Configuration>&
+    getXsdcConfig() {
+        return mConverter.getXsdcConfig();
+    }
+    void init();
+    void initProductStrategyMap();
+    ::aidl::android::media::audio::common::AudioAttributes convertAudioAttributesToAidl(
+            const ::android::audio::policy::engine::configuration::AttributesType&
+                    xsdcAudioAttributes);
+    ::aidl::android::media::audio::common::AudioHalAttributesGroup convertAttributesGroupToAidl(
+            const ::android::audio::policy::engine::configuration::AttributesGroup&
+                    xsdcAttributesGroup);
+    ::aidl::android::media::audio::common::AudioHalCapCriterion convertCapCriterionToAidl(
+            const ::android::audio::policy::engine::configuration::CriterionType& xsdcCriterion);
+    ::aidl::android::media::audio::common::AudioHalCapCriterionType convertCapCriterionTypeToAidl(
+            const ::android::audio::policy::engine::configuration::CriterionTypeType&
+                    xsdcCriterionType);
+    std::string convertCriterionTypeValueToAidl(
+            const ::android::audio::policy::engine::configuration::ValueType&
+                    xsdcCriterionTypeValue);
+    ::aidl::android::media::audio::common::AudioHalVolumeCurve::CurvePoint convertCurvePointToAidl(
+            const std::string& xsdcCurvePoint);
+    ::aidl::android::media::audio::common::AudioHalProductStrategy convertProductStrategyToAidl(
+            const ::android::audio::policy::engine::configuration::ProductStrategies::
+                    ProductStrategy& xsdcProductStrategy);
+    int convertProductStrategyNameToAidl(const std::string& xsdcProductStrategyName);
+    ::aidl::android::media::audio::common::AudioHalVolumeCurve convertVolumeCurveToAidl(
+            const ::android::audio::policy::engine::configuration::Volume& xsdcVolumeCurve);
+    ::aidl::android::media::audio::common::AudioHalVolumeGroup convertVolumeGroupToAidl(
+            const ::android::audio::policy::engine::configuration::VolumeGroupsType::VolumeGroup&
+                    xsdcVolumeGroup);
+
+    ::aidl::android::media::audio::common::AudioHalEngineConfig mAidlEngineConfig;
+    XmlConverter<::android::audio::policy::engine::configuration::Configuration> mConverter;
+    std::unordered_map<std::string,
+                       ::android::audio::policy::engine::configuration::AttributesRefType>
+            mAttributesReferenceMap;
+    std::unordered_map<std::string, ::android::audio::policy::engine::configuration::VolumeRef>
+            mVolumesReferenceMap;
+    std::unordered_map<std::string, int> mProductStrategyMap;
+    int mNextVendorStrategy = ::aidl::android::media::audio::common::AudioHalProductStrategy::
+            VENDOR_STRATEGY_ID_START;
+    std::optional<int> mDefaultProductStrategyId;
+};
+
+}  // namespace aidl::android::hardware::audio::core::internal
diff --git a/audio/aidl/default/include/core-impl/XmlConverter.h b/audio/aidl/default/include/core-impl/XmlConverter.h
new file mode 100644
index 0000000..ec23edb
--- /dev/null
+++ b/audio/aidl/default/include/core-impl/XmlConverter.h
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <optional>
+#include <string>
+#include <unordered_map>
+
+#include <system/audio_config.h>
+#include <utils/Errors.h>
+
+namespace aidl::android::hardware::audio::core::internal {
+
+template <typename T>
+class XmlConverter {
+  public:
+    XmlConverter(const std::string& configFilePath,
+                 std::function<std::optional<T>(const char*)> readXmlConfig)
+        : XmlConverter(configFilePath,
+                       ::android::audio_is_readable_configuration_file(configFilePath.c_str()),
+                       readXmlConfig) {}
+
+    const ::android::status_t& getStatus() const { return mStatus; }
+
+    const std::string& getError() const { return mErrorMessage; }
+
+    const std::optional<T>& getXsdcConfig() const { return mXsdcConfig; }
+
+  private:
+    XmlConverter(const std::string& configFilePath, const bool& isReadableConfigFile,
+                 const std::function<std::optional<T>(const char*)>& readXmlConfig)
+        : mXsdcConfig{isReadableConfigFile ? readXmlConfig(configFilePath.c_str()) : std::nullopt},
+          mStatus(mXsdcConfig ? ::android::OK : ::android::NO_INIT),
+          mErrorMessage(generateError(configFilePath, isReadableConfigFile, mStatus)) {}
+
+    static std::string generateError(const std::string& configFilePath,
+                                     const bool& isReadableConfigFile,
+                                     const ::android::status_t& status) {
+        std::string errorMessage;
+        if (status != ::android::OK) {
+            if (!isReadableConfigFile) {
+                errorMessage = "Could not read requested config file:" + configFilePath;
+            } else {
+                errorMessage = "Invalid config file: " + configFilePath;
+            }
+        }
+        return errorMessage;
+    }
+
+    const std::optional<T> mXsdcConfig;
+    const ::android::status_t mStatus;
+    const std::string mErrorMessage;
+};
+
+/**
+ * Converts a vector of an xsd wrapper type to a flat vector of the
+ * corresponding AIDL type.
+ *
+ * Wrapper types are used in order to have well-formed xIncludes. In the
+ * example below, Modules is the wrapper type for Module.
+ *     <Modules>
+ *         <Module> ... </Module>
+ *         <Module> ... </Module>
+ *     </Modules>
+ */
+template <typename W, typename X, typename A>
+static std::vector<A> convertWrappedCollectionToAidl(
+        const std::vector<W>& xsdcWrapperTypeVec,
+        std::function<const std::vector<X>&(const W&)> getInnerTypeVec,
+        std::function<A(const X&)> convertToAidl) {
+    std::vector<A> resultAidlTypeVec;
+    if (!xsdcWrapperTypeVec.empty()) {
+        /*
+         * xsdcWrapperTypeVec likely only contains one element; that is, it's
+         * likely that all the inner types that we need to convert are inside of
+         * xsdcWrapperTypeVec[0].
+         */
+        resultAidlTypeVec.reserve(getInnerTypeVec(xsdcWrapperTypeVec[0]).size());
+        for (const W& xsdcWrapperType : xsdcWrapperTypeVec) {
+            std::transform(getInnerTypeVec(xsdcWrapperType).begin(),
+                           getInnerTypeVec(xsdcWrapperType).end(),
+                           std::back_inserter(resultAidlTypeVec), convertToAidl);
+        }
+    }
+    return resultAidlTypeVec;
+}
+
+template <typename X, typename A>
+static std::vector<A> convertCollectionToAidl(const std::vector<X>& xsdcTypeVec,
+                                              std::function<A(const X&)> convertToAidl) {
+    std::vector<A> resultAidlTypeVec;
+    resultAidlTypeVec.reserve(xsdcTypeVec.size());
+    std::transform(xsdcTypeVec.begin(), xsdcTypeVec.end(), std::back_inserter(resultAidlTypeVec),
+                   convertToAidl);
+    return resultAidlTypeVec;
+}
+
+/**
+ * Generates a map of xsd references, keyed by reference name, given a
+ * vector of wrapper types for the reference.
+ *
+ * Wrapper types are used in order to have well-formed xIncludes. In the
+ * example below, Wrapper is the wrapper type for Reference.
+ *     <Wrapper>
+ *         <Reference> ... </Reference>
+ *         <Reference> ... </Reference>
+ *     </Wrapper>
+ */
+template <typename W, typename R>
+static std::unordered_map<std::string, R> generateReferenceMap(
+        const std::vector<W>& xsdcWrapperTypeVec) {
+    std::unordered_map<std::string, R> resultMap;
+    if (!xsdcWrapperTypeVec.empty()) {
+        /*
+         * xsdcWrapperTypeVec likely only contains one element; that is, it's
+         * likely that all the inner types that we need to convert are inside of
+         * xsdcWrapperTypeVec[0].
+         */
+        resultMap.reserve(xsdcWrapperTypeVec[0].getReference().size());
+        for (const W& xsdcWrapperType : xsdcWrapperTypeVec) {
+            for (const R& xsdcReference : xsdcWrapperType.getReference()) {
+                resultMap.insert({xsdcReference.getName(), xsdcReference});
+            }
+        }
+    }
+    return resultMap;
+}
+}  // namespace aidl::android::hardware::audio::core::internal
diff --git a/audio/aidl/default/include/effect-impl/EffectContext.h b/audio/aidl/default/include/effect-impl/EffectContext.h
index f608e12..95645d5 100644
--- a/audio/aidl/default/include/effect-impl/EffectContext.h
+++ b/audio/aidl/default/include/effect-impl/EffectContext.h
@@ -16,16 +16,13 @@
 
 #pragma once
 #include <Utils.h>
-#include <android-base/logging.h>
-#include <utils/Log.h>
-#include <cstddef>
-#include <cstdint>
 #include <memory>
-#include <utility>
 #include <vector>
 
-#include <aidl/android/hardware/audio/effect/BnEffect.h>
+#include <android-base/logging.h>
 #include <fmq/AidlMessageQueue.h>
+
+#include <aidl/android/hardware/audio/effect/BnEffect.h>
 #include "EffectTypes.h"
 
 namespace aidl::android::hardware::audio::effect {
@@ -74,13 +71,10 @@
     std::shared_ptr<DataMQ> getOutputDataFmq() { return mOutputMQ; }
 
     float* getWorkBuffer() { return static_cast<float*>(mWorkBuffer.data()); }
-    // TODO: update with actual available size
-    size_t availableToRead() { return mWorkBuffer.capacity(); }
-    size_t availableToWrite() { return mWorkBuffer.capacity(); }
 
     // reset buffer status by abandon all data and status in FMQ
     void resetBuffer() {
-        auto buffer = getWorkBuffer();
+        auto buffer = static_cast<float*>(mWorkBuffer.data());
         std::vector<IEffect::Status> status(mStatusMQ->availableToRead());
         mInputMQ->read(buffer, mInputMQ->availableToRead());
         mOutputMQ->read(buffer, mOutputMQ->availableToRead());
@@ -89,9 +83,9 @@
 
     void dupeFmq(IEffect::OpenEffectReturn* effectRet) {
         if (effectRet) {
-            effectRet->statusMQ = getStatusFmq()->dupeDesc();
-            effectRet->inputDataMQ = getInputDataFmq()->dupeDesc();
-            effectRet->outputDataMQ = getOutputDataFmq()->dupeDesc();
+            effectRet->statusMQ = mStatusMQ->dupeDesc();
+            effectRet->inputDataMQ = mInputMQ->dupeDesc();
+            effectRet->outputDataMQ = mOutputMQ->dupeDesc();
         }
     }
     size_t getInputFrameSize() { return mInputFrameSize; }
@@ -138,7 +132,8 @@
   protected:
     // common parameters
     int mSessionId = INVALID_AUDIO_SESSION_ID;
-    size_t mInputFrameSize, mOutputFrameSize;
+    size_t mInputFrameSize;
+    size_t mOutputFrameSize;
     Parameter::Common mCommon;
     aidl::android::media::audio::common::AudioDeviceDescription mOutputDevice;
     aidl::android::media::audio::common::AudioMode mMode;
diff --git a/audio/aidl/default/include/effect-impl/EffectImpl.h b/audio/aidl/default/include/effect-impl/EffectImpl.h
index d9825da..f5e2aec 100644
--- a/audio/aidl/default/include/effect-impl/EffectImpl.h
+++ b/audio/aidl/default/include/effect-impl/EffectImpl.h
@@ -15,45 +15,35 @@
  */
 
 #pragma once
-#include <aidl/android/hardware/audio/effect/BnEffect.h>
-#include <fmq/AidlMessageQueue.h>
 #include <cstdlib>
 #include <memory>
-#include <mutex>
 
+#include <aidl/android/hardware/audio/effect/BnEffect.h>
+#include <fmq/AidlMessageQueue.h>
+
+#include "EffectContext.h"
+#include "EffectThread.h"
 #include "EffectTypes.h"
 #include "effect-impl/EffectContext.h"
+#include "effect-impl/EffectThread.h"
 #include "effect-impl/EffectTypes.h"
-#include "effect-impl/EffectWorker.h"
 
 namespace aidl::android::hardware::audio::effect {
 
-class EffectImpl : public BnEffect, public EffectWorker {
+class EffectImpl : public BnEffect, public EffectThread {
   public:
     EffectImpl() = default;
     virtual ~EffectImpl() = default;
 
-    /**
-     * Each effect implementation CAN override these methods if necessary
-     * If you would like implement IEffect::open completely, override EffectImpl::open(), if you
-     * want to keep most of EffectImpl logic but have a little customize, try override openImpl().
-     * openImpl() will be called at the beginning of EffectImpl::open() without lock protection.
-     *
-     * Same for closeImpl().
-     */
     virtual ndk::ScopedAStatus open(const Parameter::Common& common,
                                     const std::optional<Parameter::Specific>& specific,
                                     OpenEffectReturn* ret) override;
     virtual ndk::ScopedAStatus close() override;
     virtual ndk::ScopedAStatus command(CommandId id) override;
-    virtual ndk::ScopedAStatus commandStart() { return ndk::ScopedAStatus::ok(); }
-    virtual ndk::ScopedAStatus commandStop() { return ndk::ScopedAStatus::ok(); }
-    virtual ndk::ScopedAStatus commandReset() { return ndk::ScopedAStatus::ok(); }
 
     virtual ndk::ScopedAStatus getState(State* state) override;
     virtual ndk::ScopedAStatus setParameter(const Parameter& param) override;
     virtual ndk::ScopedAStatus getParameter(const Parameter::Id& id, Parameter* param) override;
-    virtual IEffect::Status effectProcessImpl(float* in, float* out, int process) override;
 
     virtual ndk::ScopedAStatus setParameterCommon(const Parameter& param);
     virtual ndk::ScopedAStatus getParameterCommon(const Parameter::Tag& tag, Parameter* param);
@@ -63,21 +53,32 @@
     virtual ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) = 0;
     virtual ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
                                                     Parameter::Specific* specific) = 0;
+
+    virtual std::string getEffectName() = 0;
+    virtual IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+
+    /**
+     * Effect context methods must be implemented by each effect.
+     * Each effect can derive from EffectContext and define its own context, but must upcast to
+     * EffectContext for EffectImpl to use.
+     */
     virtual std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) = 0;
+    virtual std::shared_ptr<EffectContext> getContext() = 0;
     virtual RetCode releaseContext() = 0;
 
   protected:
-    /*
-     * Lock is required if effectProcessImpl (which is running in an independent thread) needs to
-     * access state and parameters.
-     */
-    std::mutex mMutex;
-    State mState GUARDED_BY(mMutex) = State::INIT;
+    State mState = State::INIT;
 
     IEffect::Status status(binder_status_t status, size_t consumed, size_t produced);
     void cleanUp();
 
-  private:
-    std::shared_ptr<EffectContext> mContext GUARDED_BY(mMutex);
+    /**
+     * Optional CommandId handling methods for effects to override.
+     * For CommandId::START, EffectImpl call commandImpl before starting the EffectThread
+     * processing.
+     * For CommandId::STOP and CommandId::RESET, EffectImpl call commandImpl after stop the
+     * EffectThread processing.
+     */
+    virtual ndk::ScopedAStatus commandImpl(CommandId id);
 };
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/include/effect-impl/EffectThread.h b/audio/aidl/default/include/effect-impl/EffectThread.h
index 09a0000..4b6cecd 100644
--- a/audio/aidl/default/include/effect-impl/EffectThread.h
+++ b/audio/aidl/default/include/effect-impl/EffectThread.h
@@ -22,6 +22,7 @@
 #include <android-base/thread_annotations.h>
 #include <system/thread_defs.h>
 
+#include "effect-impl/EffectContext.h"
 #include "effect-impl/EffectTypes.h"
 
 namespace aidl::android::hardware::audio::effect {
@@ -33,7 +34,7 @@
     virtual ~EffectThread();
 
     // called by effect implementation.
-    RetCode createThread(const std::string& name,
+    RetCode createThread(std::shared_ptr<EffectContext> context, const std::string& name,
                          const int priority = ANDROID_PRIORITY_URGENT_AUDIO);
     RetCode destroyThread();
     RetCode startThread();
@@ -42,15 +43,43 @@
     // Will call process() in a loop if the thread is running.
     void threadLoop();
 
-    // User of EffectThread must implement the effect processing logic in this method.
-    virtual void process() = 0;
-    const int MAX_TASK_COMM_LEN = 15;
+    /**
+     * @brief effectProcessImpl is running in worker thread which created in EffectThread.
+     *
+     * Effect implementation should think about concurrency in the implementation if necessary.
+     * Parameter setting usually implemented in context (derived from EffectContext), and some
+     * parameter maybe used in the processing, then effect implementation should consider using a
+     * mutex to protect these parameter.
+     *
+     * EffectThread will make sure effectProcessImpl only be called after startThread() successful
+     * and before stopThread() successful.
+     *
+     * @param in address of input float buffer.
+     * @param out address of output float buffer.
+     * @param samples number of samples to process.
+     * @return IEffect::Status
+     */
+    virtual IEffect::Status effectProcessImpl(float* in, float* out, int samples) = 0;
+
+    /**
+     * The default EffectThread::process() implementation doesn't need to lock. It will only
+     * access the FMQ and mWorkBuffer in  EffectContext, since they will only be changed in
+     * EffectImpl IEffect::open() (in this case EffectThread just created and not running yet) and
+     * IEffect::command(CommandId::RESET) (in this case EffectThread already stopped).
+     *
+     * process() call effectProcessImpl for effect processing, and because effectProcessImpl is
+     * implemented by effects, process() must not hold lock before call into effectProcessImpl to
+     * avoid deadlock.
+     */
+    virtual void process();
 
   private:
-    std::mutex mMutex;
+    const int kMaxTaskNameLen = 15;
+    std::mutex mThreadMutex;
     std::condition_variable mCv;
-    bool mExit GUARDED_BY(mMutex) = false;
-    bool mStop GUARDED_BY(mMutex) = true;
+    bool mExit GUARDED_BY(mThreadMutex) = false;
+    bool mStop GUARDED_BY(mThreadMutex) = true;
+    std::shared_ptr<EffectContext> mThreadContext GUARDED_BY(mThreadMutex);
     std::thread mThread;
     int mPriority;
     std::string mName;
diff --git a/audio/aidl/default/include/effect-impl/EffectWorker.h b/audio/aidl/default/include/effect-impl/EffectWorker.h
index 6a78eab..b456817 100644
--- a/audio/aidl/default/include/effect-impl/EffectWorker.h
+++ b/audio/aidl/default/include/effect-impl/EffectWorker.h
@@ -63,7 +63,7 @@
 
     // must implement by each effect implementation
     // TODO: consider if this interface need adjustment to handle in-place processing
-    virtual IEffect::Status effectProcessImpl(float* in, float* out, int processSamples) = 0;
+    virtual IEffect::Status effectProcessImpl(float* in, float* out, int samples) = 0;
 
   private:
     // make sure the context only set once.
diff --git a/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.cpp b/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.cpp
index 9d2b978..4015e61 100644
--- a/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.cpp
+++ b/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.cpp
@@ -73,7 +73,6 @@
 ndk::ScopedAStatus LoudnessEnhancerSw::setParameterSpecific(const Parameter::Specific& specific) {
     RETURN_IF(Parameter::Specific::loudnessEnhancer != specific.getTag(), EX_ILLEGAL_ARGUMENT,
               "EffectNotSupported");
-    std::lock_guard lg(mMutex);
     RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
 
     auto& leParam = specific.get<Parameter::Specific::loudnessEnhancer>();
@@ -113,7 +112,6 @@
 
 ndk::ScopedAStatus LoudnessEnhancerSw::getParameterLoudnessEnhancer(
         const LoudnessEnhancer::Tag& tag, Parameter::Specific* specific) {
-    std::lock_guard lg(mMutex);
     RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
 
     LoudnessEnhancer leParam;
@@ -136,9 +134,14 @@
 std::shared_ptr<EffectContext> LoudnessEnhancerSw::createContext(const Parameter::Common& common) {
     if (mContext) {
         LOG(DEBUG) << __func__ << " context already exist";
-        return mContext;
+    } else {
+        mContext = std::make_shared<LoudnessEnhancerSwContext>(1 /* statusFmqDepth */, common);
     }
-    mContext = std::make_shared<LoudnessEnhancerSwContext>(1 /* statusFmqDepth */, common);
+
+    return mContext;
+}
+
+std::shared_ptr<EffectContext> LoudnessEnhancerSw::getContext() {
     return mContext;
 }
 
@@ -150,13 +153,13 @@
 }
 
 // Processing method running in EffectWorker thread.
-IEffect::Status LoudnessEnhancerSw::effectProcessImpl(float* in, float* out, int process) {
+IEffect::Status LoudnessEnhancerSw::effectProcessImpl(float* in, float* out, int samples) {
     // TODO: get data buffer and process.
-    LOG(DEBUG) << __func__ << " in " << in << " out " << out << " process " << process;
-    for (int i = 0; i < process; i++) {
+    LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
+    for (int i = 0; i < samples; i++) {
         *out++ = *in++;
     }
-    return {STATUS_OK, process, process};
+    return {STATUS_OK, samples, samples};
 }
 
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.h b/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.h
index 856bf0b..2aa4953 100644
--- a/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.h
+++ b/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.h
@@ -56,11 +56,16 @@
     ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
     ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
                                             Parameter::Specific* specific) override;
-    IEffect::Status effectProcessImpl(float* in, float* out, int process) override;
+
     std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
+    std::shared_ptr<EffectContext> getContext() override;
     RetCode releaseContext() override;
 
+    IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+    std::string getEffectName() override { return kEffectName; }
+
   private:
+    const std::string kEffectName = "LoudnessEnhancerSw";
     std::shared_ptr<LoudnessEnhancerSwContext> mContext;
     /* capabilities */
     const LoudnessEnhancer::Capability kCapability;
@@ -72,7 +77,7 @@
                        .flags = {.type = Flags::Type::INSERT,
                                  .insert = Flags::Insert::FIRST,
                                  .volume = Flags::Volume::CTRL},
-                       .name = "LoudnessEnhancerSw",
+                       .name = kEffectName,
                        .implementor = "The Android Open Source Project"},
             .capability = Capability::make<Capability::loudnessEnhancer>(kCapability)};
 
diff --git a/audio/aidl/default/main.cpp b/audio/aidl/default/main.cpp
index 7786cc6..48067a2 100644
--- a/audio/aidl/default/main.cpp
+++ b/audio/aidl/default/main.cpp
@@ -17,14 +17,14 @@
 #include <cstdlib>
 #include <ctime>
 
-#include "core-impl/Config.h"
-#include "core-impl/Module.h"
-
 #include <android-base/logging.h>
 #include <android/binder_ibinder_platform.h>
 #include <android/binder_manager.h>
 #include <android/binder_process.h>
 
+#include "core-impl/Config.h"
+#include "core-impl/Module.h"
+
 using aidl::android::hardware::audio::core::Config;
 using aidl::android::hardware::audio::core::Module;
 
diff --git a/audio/aidl/default/presetReverb/PresetReverbSw.cpp b/audio/aidl/default/presetReverb/PresetReverbSw.cpp
index 069d0ff..e1f505e 100644
--- a/audio/aidl/default/presetReverb/PresetReverbSw.cpp
+++ b/audio/aidl/default/presetReverb/PresetReverbSw.cpp
@@ -73,8 +73,6 @@
 ndk::ScopedAStatus PresetReverbSw::setParameterSpecific(const Parameter::Specific& specific) {
     RETURN_IF(Parameter::Specific::reverb != specific.getTag(), EX_ILLEGAL_ARGUMENT,
               "EffectNotSupported");
-    std::lock_guard lg(mMutex);
-    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
 
     mSpecificParam = specific.get<Parameter::Specific::reverb>();
     LOG(DEBUG) << __func__ << " success with: " << specific.toString();
@@ -92,9 +90,14 @@
 std::shared_ptr<EffectContext> PresetReverbSw::createContext(const Parameter::Common& common) {
     if (mContext) {
         LOG(DEBUG) << __func__ << " context already exist";
-        return mContext;
+    } else {
+        mContext = std::make_shared<PresetReverbSwContext>(1 /* statusFmqDepth */, common);
     }
-    mContext = std::make_shared<PresetReverbSwContext>(1 /* statusFmqDepth */, common);
+
+    return mContext;
+}
+
+std::shared_ptr<EffectContext> PresetReverbSw::getContext() {
     return mContext;
 }
 
@@ -106,13 +109,13 @@
 }
 
 // Processing method running in EffectWorker thread.
-IEffect::Status PresetReverbSw::effectProcessImpl(float* in, float* out, int process) {
+IEffect::Status PresetReverbSw::effectProcessImpl(float* in, float* out, int samples) {
     // TODO: get data buffer and process.
-    LOG(DEBUG) << __func__ << " in " << in << " out " << out << " process " << process;
-    for (int i = 0; i < process; i++) {
+    LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
+    for (int i = 0; i < samples; i++) {
         *out++ = *in++;
     }
-    return {STATUS_OK, process, process};
+    return {STATUS_OK, samples, samples};
 }
 
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/presetReverb/PresetReverbSw.h b/audio/aidl/default/presetReverb/PresetReverbSw.h
index 75a5a94..6fd3a9e 100644
--- a/audio/aidl/default/presetReverb/PresetReverbSw.h
+++ b/audio/aidl/default/presetReverb/PresetReverbSw.h
@@ -47,11 +47,16 @@
     ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
     ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
                                             Parameter::Specific* specific) override;
-    IEffect::Status effectProcessImpl(float* in, float* out, int process) override;
+
     std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
+    std::shared_ptr<EffectContext> getContext() override;
     RetCode releaseContext() override;
 
+    IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+    std::string getEffectName() override { return kEffectName; }
+
   private:
+    const std::string kEffectName = "PresetReverbSw";
     std::shared_ptr<PresetReverbSwContext> mContext;
     /* capabilities */
     const Reverb::Capability kCapability;
@@ -63,7 +68,7 @@
                        .flags = {.type = Flags::Type::INSERT,
                                  .insert = Flags::Insert::FIRST,
                                  .volume = Flags::Volume::CTRL},
-                       .name = "PresetReverbSw",
+                       .name = kEffectName,
                        .implementor = "The Android Open Source Project"},
             .capability = Capability::make<Capability::reverb>(kCapability)};
 
diff --git a/audio/aidl/default/virtualizer/VirtualizerSw.cpp b/audio/aidl/default/virtualizer/VirtualizerSw.cpp
index 9688fc8..125fbee 100644
--- a/audio/aidl/default/virtualizer/VirtualizerSw.cpp
+++ b/audio/aidl/default/virtualizer/VirtualizerSw.cpp
@@ -73,8 +73,6 @@
 ndk::ScopedAStatus VirtualizerSw::setParameterSpecific(const Parameter::Specific& specific) {
     RETURN_IF(Parameter::Specific::virtualizer != specific.getTag(), EX_ILLEGAL_ARGUMENT,
               "EffectNotSupported");
-    std::lock_guard lg(mMutex);
-    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
 
     mSpecificParam = specific.get<Parameter::Specific::virtualizer>();
     LOG(DEBUG) << __func__ << " success with: " << specific.toString();
@@ -92,9 +90,14 @@
 std::shared_ptr<EffectContext> VirtualizerSw::createContext(const Parameter::Common& common) {
     if (mContext) {
         LOG(DEBUG) << __func__ << " context already exist";
-        return mContext;
+    } else {
+        mContext = std::make_shared<VirtualizerSwContext>(1 /* statusFmqDepth */, common);
     }
-    mContext = std::make_shared<VirtualizerSwContext>(1 /* statusFmqDepth */, common);
+
+    return mContext;
+}
+
+std::shared_ptr<EffectContext> VirtualizerSw::getContext() {
     return mContext;
 }
 
@@ -106,13 +109,13 @@
 }
 
 // Processing method running in EffectWorker thread.
-IEffect::Status VirtualizerSw::effectProcessImpl(float* in, float* out, int process) {
+IEffect::Status VirtualizerSw::effectProcessImpl(float* in, float* out, int samples) {
     // TODO: get data buffer and process.
-    LOG(DEBUG) << __func__ << " in " << in << " out " << out << " process " << process;
-    for (int i = 0; i < process; i++) {
+    LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
+    for (int i = 0; i < samples; i++) {
         *out++ = *in++;
     }
-    return {STATUS_OK, process, process};
+    return {STATUS_OK, samples, samples};
 }
 
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/virtualizer/VirtualizerSw.h b/audio/aidl/default/virtualizer/VirtualizerSw.h
index e4de8b3..e77adef 100644
--- a/audio/aidl/default/virtualizer/VirtualizerSw.h
+++ b/audio/aidl/default/virtualizer/VirtualizerSw.h
@@ -47,11 +47,16 @@
     ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
     ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
                                             Parameter::Specific* specific) override;
-    IEffect::Status effectProcessImpl(float* in, float* out, int process) override;
+
     std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
+    std::shared_ptr<EffectContext> getContext() override;
     RetCode releaseContext() override;
 
+    IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+    std::string getEffectName() override { return kEffectName; }
+
   private:
+    const std::string kEffectName = "VirtualizerSw";
     std::shared_ptr<VirtualizerSwContext> mContext;
     /* capabilities */
     const Virtualizer::Capability kCapability;
@@ -63,7 +68,7 @@
                        .flags = {.type = Flags::Type::INSERT,
                                  .insert = Flags::Insert::FIRST,
                                  .volume = Flags::Volume::CTRL},
-                       .name = "VirtualizerSw",
+                       .name = kEffectName,
                        .implementor = "The Android Open Source Project"},
             .capability = Capability::make<Capability::virtualizer>(kCapability)};
 
diff --git a/audio/aidl/default/visualizer/VisualizerSw.cpp b/audio/aidl/default/visualizer/VisualizerSw.cpp
index 24a7bef..ffdf325 100644
--- a/audio/aidl/default/visualizer/VisualizerSw.cpp
+++ b/audio/aidl/default/visualizer/VisualizerSw.cpp
@@ -73,8 +73,6 @@
 ndk::ScopedAStatus VisualizerSw::setParameterSpecific(const Parameter::Specific& specific) {
     RETURN_IF(Parameter::Specific::visualizer != specific.getTag(), EX_ILLEGAL_ARGUMENT,
               "EffectNotSupported");
-    std::lock_guard lg(mMutex);
-    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
 
     mSpecificParam = specific.get<Parameter::Specific::visualizer>();
     LOG(DEBUG) << __func__ << " success with: " << specific.toString();
@@ -92,9 +90,14 @@
 std::shared_ptr<EffectContext> VisualizerSw::createContext(const Parameter::Common& common) {
     if (mContext) {
         LOG(DEBUG) << __func__ << " context already exist";
-        return mContext;
+    } else {
+        mContext = std::make_shared<VisualizerSwContext>(1 /* statusFmqDepth */, common);
     }
-    mContext = std::make_shared<VisualizerSwContext>(1 /* statusFmqDepth */, common);
+
+    return mContext;
+}
+
+std::shared_ptr<EffectContext> VisualizerSw::getContext() {
     return mContext;
 }
 
@@ -106,13 +109,13 @@
 }
 
 // Processing method running in EffectWorker thread.
-IEffect::Status VisualizerSw::effectProcessImpl(float* in, float* out, int process) {
+IEffect::Status VisualizerSw::effectProcessImpl(float* in, float* out, int samples) {
     // TODO: get data buffer and process.
-    LOG(DEBUG) << __func__ << " in " << in << " out " << out << " process " << process;
-    for (int i = 0; i < process; i++) {
+    LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
+    for (int i = 0; i < samples; i++) {
         *out++ = *in++;
     }
-    return {STATUS_OK, process, process};
+    return {STATUS_OK, samples, samples};
 }
 
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/visualizer/VisualizerSw.h b/audio/aidl/default/visualizer/VisualizerSw.h
index bccd6e9..18bb10c 100644
--- a/audio/aidl/default/visualizer/VisualizerSw.h
+++ b/audio/aidl/default/visualizer/VisualizerSw.h
@@ -47,11 +47,16 @@
     ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
     ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
                                             Parameter::Specific* specific) override;
-    IEffect::Status effectProcessImpl(float* in, float* out, int process) override;
+
     std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
+    std::shared_ptr<EffectContext> getContext() override;
     RetCode releaseContext() override;
 
+    IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+    std::string getEffectName() override { return kEffectName; }
+
   private:
+    const std::string kEffectName = "VisualizerSw";
     std::shared_ptr<VisualizerSwContext> mContext;
     /* capabilities */
     const Visualizer::Capability kCapability;
@@ -63,7 +68,7 @@
                        .flags = {.type = Flags::Type::INSERT,
                                  .insert = Flags::Insert::FIRST,
                                  .volume = Flags::Volume::CTRL},
-                       .name = "VisualizerSw",
+                       .name = kEffectName,
                        .implementor = "The Android Open Source Project"},
             .capability = Capability::make<Capability::visualizer>(kCapability)};
 
diff --git a/audio/aidl/default/volume/VolumeSw.cpp b/audio/aidl/default/volume/VolumeSw.cpp
index b8af921..4cc4f08 100644
--- a/audio/aidl/default/volume/VolumeSw.cpp
+++ b/audio/aidl/default/volume/VolumeSw.cpp
@@ -73,8 +73,6 @@
 ndk::ScopedAStatus VolumeSw::setParameterSpecific(const Parameter::Specific& specific) {
     RETURN_IF(Parameter::Specific::volume != specific.getTag(), EX_ILLEGAL_ARGUMENT,
               "EffectNotSupported");
-    std::lock_guard lg(mMutex);
-    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
 
     mSpecificParam = specific.get<Parameter::Specific::volume>();
     LOG(DEBUG) << __func__ << " success with: " << specific.toString();
@@ -92,9 +90,14 @@
 std::shared_ptr<EffectContext> VolumeSw::createContext(const Parameter::Common& common) {
     if (mContext) {
         LOG(DEBUG) << __func__ << " context already exist";
-        return mContext;
+    } else {
+        mContext = std::make_shared<VolumeSwContext>(1 /* statusFmqDepth */, common);
     }
-    mContext = std::make_shared<VolumeSwContext>(1 /* statusFmqDepth */, common);
+
+    return mContext;
+}
+
+std::shared_ptr<EffectContext> VolumeSw::getContext() {
     return mContext;
 }
 
@@ -106,13 +109,13 @@
 }
 
 // Processing method running in EffectWorker thread.
-IEffect::Status VolumeSw::effectProcessImpl(float* in, float* out, int process) {
+IEffect::Status VolumeSw::effectProcessImpl(float* in, float* out, int samples) {
     // TODO: get data buffer and process.
-    LOG(DEBUG) << __func__ << " in " << in << " out " << out << " process " << process;
-    for (int i = 0; i < process; i++) {
+    LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
+    for (int i = 0; i < samples; i++) {
         *out++ = *in++;
     }
-    return {STATUS_OK, process, process};
+    return {STATUS_OK, samples, samples};
 }
 
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/volume/VolumeSw.h b/audio/aidl/default/volume/VolumeSw.h
index 86e01c1..b9e554b 100644
--- a/audio/aidl/default/volume/VolumeSw.h
+++ b/audio/aidl/default/volume/VolumeSw.h
@@ -47,11 +47,16 @@
     ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
     ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
                                             Parameter::Specific* specific) override;
-    IEffect::Status effectProcessImpl(float* in, float* out, int process) override;
+
     std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
+    std::shared_ptr<EffectContext> getContext() override;
     RetCode releaseContext() override;
 
+    IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+    std::string getEffectName() override { return kEffectName; }
+
   private:
+    const std::string kEffectName = "VolumeSw";
     std::shared_ptr<VolumeSwContext> mContext;
     /* capabilities */
     const Volume::Capability kCapability;
@@ -63,7 +68,7 @@
                        .flags = {.type = Flags::Type::INSERT,
                                  .insert = Flags::Insert::FIRST,
                                  .volume = Flags::Volume::CTRL},
-                       .name = "VolumeSw",
+                       .name = kEffectName,
                        .implementor = "The Android Open Source Project"},
             .capability = Capability::make<Capability::volume>(kCapability)};
 
diff --git a/audio/aidl/vts/Android.bp b/audio/aidl/vts/Android.bp
index 03e9fca..068742d 100644
--- a/audio/aidl/vts/Android.bp
+++ b/audio/aidl/vts/Android.bp
@@ -49,7 +49,8 @@
     ],
     srcs: [
         "ModuleConfig.cpp",
-        "VtsHalAudioCoreTargetTest.cpp",
+        "VtsHalAudioCoreConfigTargetTest.cpp",
+        "VtsHalAudioCoreModuleTargetTest.cpp",
     ],
 }
 
@@ -66,6 +67,12 @@
 }
 
 cc_test {
+    name: "VtsHalBassBoostTargetTest",
+    defaults: ["VtsHalAudioTargetTestDefaults"],
+    srcs: ["VtsHalBassBoostTargetTest.cpp"],
+}
+
+cc_test {
     name: "VtsHalEqualizerTargetTest",
     defaults: ["VtsHalAudioTargetTestDefaults"],
     srcs: ["VtsHalEqualizerTargetTest.cpp"],
diff --git a/audio/aidl/vts/VtsHalAudioCoreConfigTargetTest.cpp b/audio/aidl/vts/VtsHalAudioCoreConfigTargetTest.cpp
new file mode 100644
index 0000000..bf73648
--- /dev/null
+++ b/audio/aidl/vts/VtsHalAudioCoreConfigTargetTest.cpp
@@ -0,0 +1,333 @@
+#include <set>
+#include <string>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+
+#define LOG_TAG "VtsHalAudioCore.Config"
+
+#include <Utils.h>
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/audio/core/IConfig.h>
+
+#include "AudioHalBinderServiceUtil.h"
+#include "TestUtils.h"
+
+using namespace android;
+using aidl::android::hardware::audio::core::IConfig;
+using aidl::android::media::audio::common::AudioAttributes;
+using aidl::android::media::audio::common::AudioFlag;
+using aidl::android::media::audio::common::AudioHalAttributesGroup;
+using aidl::android::media::audio::common::AudioHalCapCriterion;
+using aidl::android::media::audio::common::AudioHalCapCriterionType;
+using aidl::android::media::audio::common::AudioHalEngineConfig;
+using aidl::android::media::audio::common::AudioHalProductStrategy;
+using aidl::android::media::audio::common::AudioHalVolumeCurve;
+using aidl::android::media::audio::common::AudioHalVolumeGroup;
+using aidl::android::media::audio::common::AudioProductStrategyType;
+using aidl::android::media::audio::common::AudioSource;
+using aidl::android::media::audio::common::AudioStreamType;
+using aidl::android::media::audio::common::AudioUsage;
+
+class AudioCoreConfig : public testing::TestWithParam<std::string> {
+  public:
+    void SetUp() override { ASSERT_NO_FATAL_FAILURE(ConnectToService()); }
+    void ConnectToService() {
+        mConfig = IConfig::fromBinder(mBinderUtil.connectToService(GetParam()));
+        ASSERT_NE(mConfig, nullptr);
+    }
+
+    void RestartService() {
+        ASSERT_NE(mConfig, nullptr);
+        mEngineConfig.reset();
+        mConfig = IConfig::fromBinder(mBinderUtil.restartService());
+        ASSERT_NE(mConfig, nullptr);
+    }
+
+    void SetUpEngineConfig() {
+        if (mEngineConfig == nullptr) {
+            auto tempConfig = std::make_unique<AudioHalEngineConfig>();
+            ASSERT_IS_OK(mConfig->getEngineConfig(tempConfig.get()));
+            mEngineConfig = std::move(tempConfig);
+        }
+    }
+
+    static bool IsProductStrategyTypeReservedForSystemUse(const AudioProductStrategyType& pst) {
+        switch (pst) {
+            case AudioProductStrategyType::SYS_RESERVED_NONE:
+            case AudioProductStrategyType::SYS_RESERVED_REROUTING:
+            case AudioProductStrategyType::SYS_RESERVED_CALL_ASSISTANT:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    static bool IsStreamTypeReservedForSystemUse(const AudioStreamType& streamType) {
+        switch (streamType) {
+            case AudioStreamType::SYS_RESERVED_DEFAULT:
+            case AudioStreamType::SYS_RESERVED_REROUTING:
+            case AudioStreamType::SYS_RESERVED_PATCH:
+            case AudioStreamType::CALL_ASSISTANT:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    static bool IsAudioUsageValid(const AudioUsage& usage) {
+        switch (usage) {
+            case AudioUsage::INVALID:
+            case AudioUsage::SYS_RESERVED_NOTIFICATION_COMMUNICATION_REQUEST:
+            case AudioUsage::SYS_RESERVED_NOTIFICATION_COMMUNICATION_INSTANT:
+            case AudioUsage::SYS_RESERVED_NOTIFICATION_COMMUNICATION_DELAYED:
+                return false;
+            default:
+                return true;
+        }
+    }
+
+    static bool IsAudioSourceValid(const AudioSource& source) {
+        return (source != AudioSource::SYS_RESERVED_INVALID);
+    }
+
+    static const std::unordered_set<int>& GetSupportedAudioProductStrategyTypes() {
+        static const std::unordered_set<int> supportedAudioProductStrategyTypes = []() {
+            std::unordered_set<int> supportedStrategyTypes;
+            for (const auto& audioProductStrategyType :
+                 ndk::enum_range<AudioProductStrategyType>()) {
+                if (!IsProductStrategyTypeReservedForSystemUse(audioProductStrategyType)) {
+                    supportedStrategyTypes.insert(static_cast<int>(audioProductStrategyType));
+                }
+            }
+            return supportedStrategyTypes;
+        }();
+        return supportedAudioProductStrategyTypes;
+    }
+
+    static int GetSupportedAudioFlagsMask() {
+        static const int supportedAudioFlagsMask = []() {
+            int mask = 0;
+            for (const auto& audioFlag : ndk::enum_range<AudioFlag>()) {
+                mask |= static_cast<int>(audioFlag);
+            }
+            return mask;
+        }();
+        return supportedAudioFlagsMask;
+    }
+
+    /**
+     * Verify streamType is not INVALID if using default engine.
+     * Verify that streamType is a valid AudioStreamType if the associated
+     * volumeGroup minIndex/maxIndex is INDEX_DEFERRED_TO_AUDIO_SERVICE.
+     */
+    void ValidateAudioStreamType(const AudioStreamType& streamType,
+                                 const AudioHalVolumeGroup& associatedVolumeGroup) {
+        EXPECT_FALSE(IsStreamTypeReservedForSystemUse(streamType));
+        if (!mEngineConfig->capSpecificConfig ||
+            associatedVolumeGroup.minIndex ==
+                    AudioHalVolumeGroup::INDEX_DEFERRED_TO_AUDIO_SERVICE) {
+            EXPECT_NE(streamType, AudioStreamType::INVALID);
+        }
+    }
+
+    /**
+     * Verify contained enum types are valid.
+     */
+    void ValidateAudioAttributes(const AudioAttributes& attributes) {
+        // No need to check contentType; there are no INVALID or SYS_RESERVED values
+        EXPECT_TRUE(IsAudioUsageValid(attributes.usage));
+        EXPECT_TRUE(IsAudioSourceValid(attributes.source));
+        EXPECT_EQ(attributes.flags & ~GetSupportedAudioFlagsMask(), 0);
+    }
+
+    /**
+     * Verify volumeGroupName corresponds to an AudioHalVolumeGroup.
+     * Validate contained types.
+     */
+    void ValidateAudioHalAttributesGroup(
+            const AudioHalAttributesGroup& attributesGroup,
+            std::unordered_map<std::string, const AudioHalVolumeGroup&>& volumeGroupMap,
+            std::unordered_set<std::string>& volumeGroupsUsedInStrategies) {
+        bool isVolumeGroupNameValid = volumeGroupMap.count(attributesGroup.volumeGroupName);
+        EXPECT_TRUE(isVolumeGroupNameValid);
+        EXPECT_NO_FATAL_FAILURE(ValidateAudioStreamType(
+                attributesGroup.streamType, volumeGroupMap.at(attributesGroup.volumeGroupName)));
+        if (isVolumeGroupNameValid) {
+            volumeGroupsUsedInStrategies.insert(attributesGroup.volumeGroupName);
+        }
+        for (const AudioAttributes& attr : attributesGroup.attributes) {
+            EXPECT_NO_FATAL_FAILURE(ValidateAudioAttributes(attr));
+        }
+    }
+
+    /**
+     * Default engine: verify productStrategy.id is valid AudioProductStrategyType.
+     * CAP engine: verify productStrategy.id is either valid AudioProductStrategyType
+     * or is >= VENDOR_STRATEGY_ID_START.
+     * Validate contained types.
+     */
+    void ValidateAudioHalProductStrategy(
+            const AudioHalProductStrategy& strategy,
+            std::unordered_map<std::string, const AudioHalVolumeGroup&>& volumeGroupMap,
+            std::unordered_set<std::string>& volumeGroupsUsedInStrategies) {
+        if (!mEngineConfig->capSpecificConfig ||
+            (strategy.id < AudioHalProductStrategy::VENDOR_STRATEGY_ID_START)) {
+            EXPECT_NE(GetSupportedAudioProductStrategyTypes().find(strategy.id),
+                      GetSupportedAudioProductStrategyTypes().end());
+        }
+        for (const AudioHalAttributesGroup& attributesGroup : strategy.attributesGroups) {
+            EXPECT_NO_FATAL_FAILURE(ValidateAudioHalAttributesGroup(attributesGroup, volumeGroupMap,
+                                                                    volumeGroupsUsedInStrategies));
+        }
+    }
+
+    /**
+     * Verify curve point index is in [CurvePoint::MIN_INDEX, CurvePoint::MAX_INDEX].
+     */
+    void ValidateAudioHalVolumeCurve(const AudioHalVolumeCurve& volumeCurve) {
+        for (const AudioHalVolumeCurve::CurvePoint& curvePoint : volumeCurve.curvePoints) {
+            EXPECT_TRUE(curvePoint.index >= AudioHalVolumeCurve::CurvePoint::MIN_INDEX);
+            EXPECT_TRUE(curvePoint.index <= AudioHalVolumeCurve::CurvePoint::MAX_INDEX);
+        }
+    }
+
+    /**
+     * Verify minIndex, maxIndex are non-negative.
+     * Verify minIndex <= maxIndex.
+     * Verify no two volume curves use the same device category.
+     * Validate contained types.
+     */
+    void ValidateAudioHalVolumeGroup(const AudioHalVolumeGroup& volumeGroup) {
+        /**
+         * Legacy volume curves in audio_policy_configuration.xsd don't use
+         * minIndex or maxIndex. Use of audio_policy_configuration.xml still
+         * allows, and in some cases, relies on, AudioService to provide the min
+         * and max indices for a volumeGroup. From the VTS perspective, there is
+         * no way to differentiate between use of audio_policy_configuration.xml
+         * or audio_policy_engine_configuration.xml, as either one can be used
+         * for the default audio policy engine.
+         */
+        if (volumeGroup.minIndex != AudioHalVolumeGroup::INDEX_DEFERRED_TO_AUDIO_SERVICE ||
+            volumeGroup.maxIndex != AudioHalVolumeGroup::INDEX_DEFERRED_TO_AUDIO_SERVICE) {
+            EXPECT_TRUE(volumeGroup.minIndex >= 0);
+            EXPECT_TRUE(volumeGroup.maxIndex >= 0);
+        }
+        EXPECT_TRUE(volumeGroup.minIndex <= volumeGroup.maxIndex);
+        std::unordered_set<AudioHalVolumeCurve::DeviceCategory> deviceCategorySet;
+        for (const AudioHalVolumeCurve& volumeCurve : volumeGroup.volumeCurves) {
+            EXPECT_TRUE(deviceCategorySet.insert(volumeCurve.deviceCategory).second);
+            EXPECT_NO_FATAL_FAILURE(ValidateAudioHalVolumeCurve(volumeCurve));
+        }
+    }
+
+    /**
+     * Verify defaultLiteralValue is empty for inclusive criterion.
+     */
+    void ValidateAudioHalCapCriterion(const AudioHalCapCriterion& criterion,
+                                      const AudioHalCapCriterionType& criterionType) {
+        if (criterionType.isInclusive) {
+            EXPECT_TRUE(criterion.defaultLiteralValue.empty());
+        }
+    }
+
+    /**
+     * Verify values only contain alphanumeric characters.
+     */
+    void ValidateAudioHalCapCriterionType(const AudioHalCapCriterionType& criterionType) {
+        auto isNotAlnum = [](const char& c) { return !isalnum(c); };
+        for (const std::string& value : criterionType.values) {
+            EXPECT_EQ(find_if(value.begin(), value.end(), isNotAlnum), value.end());
+        }
+    }
+
+    /**
+     * Verify each criterionType has a unique name.
+     * Verify each criterion has a unique name.
+     * Verify each criterion maps to a criterionType.
+     * Verify each criterionType is used in a criterion.
+     * Validate contained types.
+     */
+    void ValidateCapSpecificConfig(const AudioHalEngineConfig::CapSpecificConfig& capCfg) {
+        EXPECT_FALSE(capCfg.criteria.empty());
+        EXPECT_FALSE(capCfg.criterionTypes.empty());
+        std::unordered_map<std::string, AudioHalCapCriterionType> criterionTypeMap;
+        for (const AudioHalCapCriterionType& criterionType : capCfg.criterionTypes) {
+            EXPECT_NO_FATAL_FAILURE(ValidateAudioHalCapCriterionType(criterionType));
+            EXPECT_TRUE(criterionTypeMap.insert({criterionType.name, criterionType}).second);
+        }
+        std::unordered_set<std::string> criterionNameSet;
+        for (const AudioHalCapCriterion& criterion : capCfg.criteria) {
+            EXPECT_TRUE(criterionNameSet.insert(criterion.name).second);
+            EXPECT_EQ(criterionTypeMap.count(criterion.criterionTypeName), 1UL);
+            EXPECT_NO_FATAL_FAILURE(ValidateAudioHalCapCriterion(
+                    criterion, criterionTypeMap.at(criterion.criterionTypeName)));
+        }
+        EXPECT_EQ(criterionTypeMap.size(), criterionNameSet.size());
+    }
+
+    /**
+     * Verify VolumeGroups are non-empty.
+     * Verify defaultProductStrategyId matches one of the provided productStrategies.
+     * Otherwise, must be left uninitialized.
+     * Verify each volumeGroup has a unique name.
+     * Verify each productStrategy has a unique id.
+     * Verify each volumeGroup is used in a product strategy.
+     * CAP engine: verify productStrategies are non-empty.
+     * Validate contained types.
+     */
+    void ValidateAudioHalEngineConfig() {
+        EXPECT_NE(mEngineConfig->volumeGroups.size(), 0UL);
+        std::unordered_map<std::string, const AudioHalVolumeGroup&> volumeGroupMap;
+        for (const AudioHalVolumeGroup& volumeGroup : mEngineConfig->volumeGroups) {
+            EXPECT_TRUE(volumeGroupMap.insert({volumeGroup.name, volumeGroup}).second);
+            EXPECT_NO_FATAL_FAILURE(ValidateAudioHalVolumeGroup(volumeGroup));
+        }
+        if (!mEngineConfig->productStrategies.empty()) {
+            std::unordered_set<int> productStrategyIdSet;
+            std::unordered_set<std::string> volumeGroupsUsedInStrategies;
+            for (const AudioHalProductStrategy& strategy : mEngineConfig->productStrategies) {
+                EXPECT_TRUE(productStrategyIdSet.insert(strategy.id).second);
+                EXPECT_NO_FATAL_FAILURE(ValidateAudioHalProductStrategy(
+                        strategy, volumeGroupMap, volumeGroupsUsedInStrategies));
+            }
+            EXPECT_TRUE(productStrategyIdSet.count(mEngineConfig->defaultProductStrategyId))
+                    << "defaultProductStrategyId doesn't match any of the provided "
+                       "productStrategies";
+            EXPECT_EQ(volumeGroupMap.size(), volumeGroupsUsedInStrategies.size());
+        } else {
+            EXPECT_EQ(mEngineConfig->defaultProductStrategyId,
+                      static_cast<int>(AudioProductStrategyType::SYS_RESERVED_NONE))
+                    << "defaultProductStrategyId defined, but no productStrategies were provided";
+        }
+        if (mEngineConfig->capSpecificConfig) {
+            EXPECT_NO_FATAL_FAILURE(
+                    ValidateCapSpecificConfig(mEngineConfig->capSpecificConfig.value()));
+            EXPECT_FALSE(mEngineConfig->productStrategies.empty());
+        }
+    }
+
+  private:
+    std::shared_ptr<IConfig> mConfig;
+    std::unique_ptr<AudioHalEngineConfig> mEngineConfig;
+    AudioHalBinderServiceUtil mBinderUtil;
+};
+
+TEST_P(AudioCoreConfig, Published) {
+    // SetUp must complete with no failures.
+}
+
+TEST_P(AudioCoreConfig, CanBeRestarted) {
+    ASSERT_NO_FATAL_FAILURE(RestartService());
+}
+
+TEST_P(AudioCoreConfig, GetEngineConfigIsValid) {
+    ASSERT_NO_FATAL_FAILURE(SetUpEngineConfig());
+    EXPECT_NO_FATAL_FAILURE(ValidateAudioHalEngineConfig());
+}
+
+INSTANTIATE_TEST_SUITE_P(AudioCoreConfigTest, AudioCoreConfig,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(IConfig::descriptor)),
+                         android::PrintInstanceNameToString);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioCoreConfig);
diff --git a/audio/aidl/vts/VtsHalAudioCoreTargetTest.cpp b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
similarity index 98%
rename from audio/aidl/vts/VtsHalAudioCoreTargetTest.cpp
rename to audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
index c0c04f4..eb7a3e4 100644
--- a/audio/aidl/vts/VtsHalAudioCoreTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
@@ -27,7 +27,7 @@
 #include <variant>
 #include <vector>
 
-#define LOG_TAG "VtsHalAudioCore"
+#define LOG_TAG "VtsHalAudioCore.Module"
 #include <android-base/logging.h>
 
 #include <StreamWorker.h>
@@ -490,16 +490,16 @@
   private:
     StreamDescriptor::State getState() const { return mSteps[mCurrentStep].second; }
     bool isBurstBifurcation() {
-        return getTrigger() == TransitionTrigger{kBurstCommand}&& getState() ==
-               StreamDescriptor::State::TRANSFERRING;
+        return getTrigger() == TransitionTrigger{kBurstCommand} &&
+               getState() == StreamDescriptor::State::TRANSFERRING;
     }
     bool isPauseBifurcation() {
-        return getTrigger() == TransitionTrigger{kPauseCommand}&& getState() ==
-               StreamDescriptor::State::TRANSFER_PAUSED;
+        return getTrigger() == TransitionTrigger{kPauseCommand} &&
+               getState() == StreamDescriptor::State::TRANSFER_PAUSED;
     }
     bool isStartBifurcation() {
-        return getTrigger() == TransitionTrigger{kStartCommand}&& getState() ==
-               StreamDescriptor::State::TRANSFERRING;
+        return getTrigger() == TransitionTrigger{kStartCommand} &&
+               getState() == StreamDescriptor::State::TRANSFERRING;
     }
     const std::vector<StateTransition> mSteps;
     size_t mCurrentStep = 0;
@@ -1902,9 +1902,13 @@
 using AudioStreamIn = AudioStream<IStreamIn>;
 using AudioStreamOut = AudioStream<IStreamOut>;
 
-#define TEST_IN_AND_OUT_STREAM(method_name)                                        \
-    TEST_P(AudioStreamIn, method_name) { ASSERT_NO_FATAL_FAILURE(method_name()); } \
-    TEST_P(AudioStreamOut, method_name) { ASSERT_NO_FATAL_FAILURE(method_name()); }
+#define TEST_IN_AND_OUT_STREAM(method_name)     \
+    TEST_P(AudioStreamIn, method_name) {        \
+        ASSERT_NO_FATAL_FAILURE(method_name()); \
+    }                                           \
+    TEST_P(AudioStreamOut, method_name) {       \
+        ASSERT_NO_FATAL_FAILURE(method_name()); \
+    }
 
 TEST_IN_AND_OUT_STREAM(CloseTwice);
 TEST_IN_AND_OUT_STREAM(OpenAllConfigs);
@@ -2280,9 +2284,13 @@
 using AudioStreamIoIn = AudioStreamIo<IStreamIn>;
 using AudioStreamIoOut = AudioStreamIo<IStreamOut>;
 
-#define TEST_IN_AND_OUT_STREAM_IO(method_name)                                       \
-    TEST_P(AudioStreamIoIn, method_name) { ASSERT_NO_FATAL_FAILURE(method_name()); } \
-    TEST_P(AudioStreamIoOut, method_name) { ASSERT_NO_FATAL_FAILURE(method_name()); }
+#define TEST_IN_AND_OUT_STREAM_IO(method_name)  \
+    TEST_P(AudioStreamIoIn, method_name) {      \
+        ASSERT_NO_FATAL_FAILURE(method_name()); \
+    }                                           \
+    TEST_P(AudioStreamIoOut, method_name) {     \
+        ASSERT_NO_FATAL_FAILURE(method_name()); \
+    }
 
 TEST_IN_AND_OUT_STREAM_IO(Run);
 
@@ -2435,9 +2443,13 @@
 
 // Not all tests require both directions, so parametrization would require
 // more abstractions.
-#define TEST_PATCH_BOTH_DIRECTIONS(method_name)                                                  \
-    TEST_P(AudioModulePatch, method_name##Input) { ASSERT_NO_FATAL_FAILURE(method_name(true)); } \
-    TEST_P(AudioModulePatch, method_name##Output) { ASSERT_NO_FATAL_FAILURE(method_name(false)); }
+#define TEST_PATCH_BOTH_DIRECTIONS(method_name)      \
+    TEST_P(AudioModulePatch, method_name##Input) {   \
+        ASSERT_NO_FATAL_FAILURE(method_name(true));  \
+    }                                                \
+    TEST_P(AudioModulePatch, method_name##Output) {  \
+        ASSERT_NO_FATAL_FAILURE(method_name(false)); \
+    }
 
 TEST_PATCH_BOTH_DIRECTIONS(ResetPortConfigUsedByPatch);
 TEST_PATCH_BOTH_DIRECTIONS(SetInvalidPatch);
diff --git a/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp b/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
index 8212149..4f14bf0 100644
--- a/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
@@ -752,16 +752,9 @@
         ::testing::Combine(testing::ValuesIn(
                 EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor))),
         [](const testing::TestParamInfo<AudioEffectTest::ParamType>& info) {
-            auto msSinceEpoch = std::chrono::duration_cast<std::chrono::nanoseconds>(
-                                        std::chrono::system_clock::now().time_since_epoch())
-                                        .count();
             auto instance = std::get<PARAM_INSTANCE_NAME>(info.param);
-            std::ostringstream address;
-            address << msSinceEpoch << "_factory_" << instance.first.get();
-            std::string name = address.str() + "_UUID_timeLow_" +
-                               ::android::internal::ToString(instance.second.uuid.timeLow) +
-                               "_timeMid_" +
-                               ::android::internal::ToString(instance.second.uuid.timeMid);
+            std::string name = "TYPE_" + instance.second.type.toString() + "_UUID_" +
+                               instance.second.uuid.toString();
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
diff --git a/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp b/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp
new file mode 100644
index 0000000..7adf63c
--- /dev/null
+++ b/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp
@@ -0,0 +1,185 @@
+/*
+ * 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 "VtsHalBassBoostTest"
+
+#include <Utils.h>
+#include <aidl/Vintf.h>
+#include <limits.h>
+
+#include "EffectHelper.h"
+
+using namespace android;
+
+using aidl::android::hardware::audio::effect::BassBoost;
+using aidl::android::hardware::audio::effect::Capability;
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::IFactory;
+using aidl::android::hardware::audio::effect::kBassBoostTypeUUID;
+using aidl::android::hardware::audio::effect::Parameter;
+
+/**
+ * Here we focus on specific parameter checking, general IEffect interfaces testing performed in
+ * VtsAudioEffectTargetTest.
+ */
+enum ParamName { PARAM_INSTANCE_NAME, PARAM_STRENGTH };
+using BassBoostParamTestParam =
+        std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor::Identity>, int>;
+
+/*
+ * Testing parameter range, assuming the parameter supported by effect is in this range.
+ * Parameter should be within the valid range defined in the documentation,
+ * for any supported value test expects EX_NONE from IEffect.setParameter(),
+ * 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:
+    BassBoostParamTest() : mParamStrength(std::get<PARAM_STRENGTH>(GetParam())) {
+        std::tie(mFactory, mIdentity) = std::get<PARAM_INSTANCE_NAME>(GetParam());
+    }
+
+    void SetUp() override {
+        ASSERT_NE(nullptr, mFactory);
+        ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mIdentity));
+
+        Parameter::Specific specific = getDefaultParamSpecific();
+        Parameter::Common common = EffectHelper::createParamCommon(
+                0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
+                kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
+        IEffect::OpenEffectReturn ret;
+        ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &ret, EX_NONE));
+        ASSERT_NE(nullptr, mEffect);
+    }
+
+    void TearDown() override {
+        ASSERT_NO_FATAL_FAILURE(close(mEffect));
+        ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+    }
+
+    Parameter::Specific getDefaultParamSpecific() {
+        BassBoost bb = BassBoost::make<BassBoost::strengthPm>(BassBoost::MIN_PER_MILLE_STRENGTH);
+        Parameter::Specific specific =
+                Parameter::Specific::make<Parameter::Specific::bassBoost>(bb);
+        return specific;
+    }
+
+    static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
+    std::shared_ptr<IFactory> mFactory;
+    std::shared_ptr<IEffect> mEffect;
+    Descriptor::Identity mIdentity;
+    int mParamStrength = BassBoost::MIN_PER_MILLE_STRENGTH;
+
+    void SetAndGetBassBoostParameters() {
+        for (auto& it : mTags) {
+            auto& tag = it.first;
+            auto& bb = 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::bassBoost>(bb);
+            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;
+                BassBoost::Id bbId;
+                bbId.set<BassBoost::Id::commonTag>(tag);
+                id.set<Parameter::Id::bassBoostTag>(bbId);
+                // if set success, then get should match
+                EXPECT_STATUS(expected, mEffect->getParameter(id, &getParam));
+                EXPECT_EQ(expectParam, getParam);
+            }
+        }
+    }
+
+    void addStrengthParam(int strength) {
+        BassBoost bb;
+        bb.set<BassBoost::strengthPm>(strength);
+        mTags.push_back({BassBoost::strengthPm, bb});
+    }
+
+    bool isTagInRange(const BassBoost::Tag& tag, const BassBoost& bb,
+                      const Descriptor& desc) const {
+        const BassBoost::Capability& bbCap = desc.capability.get<Capability::bassBoost>();
+        switch (tag) {
+            case BassBoost::strengthPm: {
+                int strength = bb.get<BassBoost::strengthPm>();
+                return isStrengthInRange(bbCap, strength);
+            }
+            default:
+                return false;
+        }
+        return false;
+    }
+
+    bool isStrengthInRange(const BassBoost::Capability& cap, int strength) const {
+        return cap.strengthSupported && strength >= BassBoost::MIN_PER_MILLE_STRENGTH &&
+               strength <= BassBoost::MAX_PER_MILLE_STRENGTH;
+    }
+
+  private:
+    std::vector<std::pair<BassBoost::Tag, BassBoost>> mTags;
+    void CleanUp() { mTags.clear(); }
+};
+
+TEST_P(BassBoostParamTest, SetAndGetStrength) {
+    EXPECT_NO_FATAL_FAILURE(addStrengthParam(mParamStrength));
+    SetAndGetBassBoostParameters();
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        BassBoostTest, BassBoostParamTest,
+        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+                                   IFactory::descriptor, kBassBoostTypeUUID)),
+                           testing::ValuesIn(kStrengthValues)),
+        [](const testing::TestParamInfo<BassBoostParamTest::ParamType>& info) {
+            auto instance = std::get<PARAM_INSTANCE_NAME>(info.param);
+            std::string strength = std::to_string(std::get<PARAM_STRENGTH>(info.param));
+            std::string name = instance.second.uuid.toString() + "_strength_" + strength;
+            std::replace_if(
+                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+            return name;
+        });
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BassBoostParamTest);
+
+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/VtsHalEqualizerTargetTest.cpp b/audio/aidl/vts/VtsHalEqualizerTargetTest.cpp
index f19dff6..1b147a6 100644
--- a/audio/aidl/vts/VtsHalEqualizerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalEqualizerTargetTest.cpp
@@ -327,18 +327,9 @@
                                    IFactory::descriptor, kEqualizerTypeUUID)),
                            testing::ValuesIn(kBandLevels)),
         [](const testing::TestParamInfo<EqualizerTest::ParamType>& info) {
-            auto msSinceEpoch = std::chrono::duration_cast<std::chrono::nanoseconds>(
-                                        std::chrono::system_clock::now().time_since_epoch())
-                                        .count();
             auto instance = std::get<PARAM_INSTANCE_NAME>(info.param);
             std::string bandLevel = std::to_string(std::get<PARAM_BAND_LEVEL>(info.param));
-            std::ostringstream address;
-            address << msSinceEpoch << "_factory_" << instance.first.get();
-            std::string name = address.str() + "_UUID_timeLow_" +
-                               ::android::internal::ToString(instance.second.uuid.timeLow) +
-                               "_timeMid_" +
-                               ::android::internal::ToString(instance.second.uuid.timeMid) +
-                               "_bandLevel_" + bandLevel;
+            std::string name = instance.second.uuid.toString() + "_bandLevel_" + bandLevel;
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
diff --git a/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp b/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
index 1485657..3fd2812 100644
--- a/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
@@ -15,6 +15,7 @@
  */
 
 #include <aidl/Vintf.h>
+#include <string>
 
 #define LOG_TAG "VtsHalLoudnessEnhancerTest"
 
@@ -129,19 +130,9 @@
                                    IFactory::descriptor, kLoudnessEnhancerTypeUUID)),
                            testing::ValuesIn(kGainMbValues)),
         [](const testing::TestParamInfo<LoudnessEnhancerParamTest::ParamType>& info) {
-            auto msSinceEpoch = std::chrono::duration_cast<std::chrono::nanoseconds>(
-                                        std::chrono::system_clock::now().time_since_epoch())
-                                        .count();
             auto instance = std::get<PARAM_INSTANCE_NAME>(info.param);
             std::string gainMb = std::to_string(std::get<PARAM_GAIN_MB>(info.param));
-
-            std::ostringstream address;
-            address << msSinceEpoch << "_factory_" << instance.first.get();
-            std::string name = address.str() + "_UUID_timeLow_" +
-                               ::android::internal::ToString(instance.second.uuid.timeLow) +
-                               "_timeMid_" +
-                               ::android::internal::ToString(instance.second.uuid.timeMid) +
-                               "_gainMb" + gainMb;
+            std::string name = instance.second.uuid.toString() + "_gainMb_" + gainMb;
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
diff --git a/automotive/vehicle/aidl/Android.bp b/automotive/vehicle/aidl/Android.bp
index 9aeb4d2..18a5046 100644
--- a/automotive/vehicle/aidl/Android.bp
+++ b/automotive/vehicle/aidl/Android.bp
@@ -27,6 +27,7 @@
     srcs: [
         "android/hardware/automotive/vehicle/**/*.aidl",
     ],
+    frozen: false,
     stability: "vintf",
     backend: {
         cpp: {
diff --git a/biometrics/common/aidl/Android.bp b/biometrics/common/aidl/Android.bp
index 3cd76fd..88edf04 100644
--- a/biometrics/common/aidl/Android.bp
+++ b/biometrics/common/aidl/Android.bp
@@ -13,6 +13,7 @@
     srcs: [
         "android/hardware/biometrics/common/*.aidl",
     ],
+    frozen: false,
     stability: "vintf",
     backend: {
         java: {
diff --git a/camera/common/aidl/Android.bp b/camera/common/aidl/Android.bp
index e1c9cc5..4ffcfd9 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 2e5b667..bf5bf63 100644
--- a/camera/device/aidl/Android.bp
+++ b/camera/device/aidl/Android.bp
@@ -11,6 +11,7 @@
     name: "android.hardware.camera.device",
     vendor_available: true,
     srcs: ["android/hardware/camera/device/*.aidl"],
+    frozen: false,
     stability: "vintf",
     imports: [
         "android.hardware.common-V2",
diff --git a/camera/metadata/aidl/Android.bp b/camera/metadata/aidl/Android.bp
index 0113a4b..7bec61d 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: false,
     stability: "vintf",
     backend: {
         cpp: {
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index 9f43219..b87b1a6 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -577,6 +577,7 @@
     </hal>
     <hal format="aidl" optional="true">
         <name>android.hardware.sensors</name>
+        <version>2</version>
         <interface>
             <name>ISensors</name>
             <instance>default</instance>
@@ -707,14 +708,6 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.wifi</name>
-        <version>1.3-6</version>
-        <interface>
-            <name>IWifi</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
     <hal format="aidl" optional="true">
         <name>android.hardware.uwb</name>
         <version>1</version>
diff --git a/graphics/composer/2.2/utils/vts/ComposerVts.cpp b/graphics/composer/2.2/utils/vts/ComposerVts.cpp
index b706596..a6dfcaf 100644
--- a/graphics/composer/2.2/utils/vts/ComposerVts.cpp
+++ b/graphics/composer/2.2/utils/vts/ComposerVts.cpp
@@ -126,15 +126,23 @@
     ASSERT_EQ(Error::NONE, error) << "failed to setReadbackBuffer";
 }
 
-void ComposerClient::getReadbackBufferAttributes(Display display, PixelFormat* outPixelFormat,
-                                                 Dataspace* outDataspace) {
+void ComposerClient::getRequiredReadbackBufferAttributes(Display display,
+                                                         PixelFormat* outPixelFormat,
+                                                         Dataspace* outDataspace) {
+    ASSERT_EQ(Error::NONE, getReadbackBufferAttributes(display, outPixelFormat, outDataspace));
+}
+
+Error ComposerClient::getReadbackBufferAttributes(Display display, PixelFormat* outPixelFormat,
+                                                  Dataspace* outDataspace) {
+    Error error;
     mClient->getReadbackBufferAttributes(
-        display,
-        [&](const auto& tmpError, const auto& tmpOutPixelFormat, const auto& tmpOutDataspace) {
-            ASSERT_EQ(Error::NONE, tmpError) << "failed to get readback buffer attributes";
-            *outPixelFormat = tmpOutPixelFormat;
-            *outDataspace = tmpOutDataspace;
-        });
+            display, [&](const Error& tmpError, const PixelFormat& tmpPixelFormat,
+                         const Dataspace& tmpDataspace) {
+                error = tmpError;
+                *outPixelFormat = tmpPixelFormat;
+                *outDataspace = tmpDataspace;
+            });
+    return error;
 }
 
 void ComposerClient::getReadbackBufferFence(Display display, int32_t* outFence) {
diff --git a/graphics/composer/2.2/utils/vts/ReadbackVts.cpp b/graphics/composer/2.2/utils/vts/ReadbackVts.cpp
index a1794af..5dd68df 100644
--- a/graphics/composer/2.2/utils/vts/ReadbackVts.cpp
+++ b/graphics/composer/2.2/utils/vts/ReadbackVts.cpp
@@ -19,6 +19,8 @@
 #include "renderengine/ExternalTexture.h"
 #include "renderengine/impl/ExternalTexture.h"
 
+using ::android::status_t;
+
 namespace android {
 namespace hardware {
 namespace graphics {
@@ -107,6 +109,40 @@
     }
 }
 
+void ReadbackHelper::fillBufferAndGetFence(const sp<GraphicBuffer>& graphicBuffer,
+                                           IComposerClient::Color desiredColor, int* fillFence) {
+    ASSERT_NE(nullptr, fillFence);
+    std::vector<IComposerClient::Color> desiredColors(
+            static_cast<size_t>(graphicBuffer->getWidth() * graphicBuffer->getHeight()));
+    ::android::Rect bounds = graphicBuffer->getBounds();
+    fillColorsArea(desiredColors, static_cast<int32_t>(graphicBuffer->getWidth()),
+                   {bounds.left, bounds.top, bounds.right, bounds.bottom}, desiredColor);
+    ASSERT_NO_FATAL_FAILURE(fillBufferAndGetFence(graphicBuffer, desiredColors, fillFence));
+}
+
+void ReadbackHelper::fillBufferAndGetFence(const sp<GraphicBuffer>& graphicBuffer,
+                                           const std::vector<IComposerClient::Color>& desiredColors,
+                                           int* fillFence) {
+    ASSERT_TRUE(graphicBuffer->getPixelFormat() == ::android::PIXEL_FORMAT_RGB_888 ||
+                graphicBuffer->getPixelFormat() == ::android::PIXEL_FORMAT_RGBA_8888);
+    void* bufData;
+    int32_t bytesPerPixel = -1;
+    int32_t bytesPerStride = -1;
+    status_t status =
+            graphicBuffer->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
+                                &bufData, &bytesPerPixel, &bytesPerStride);
+    ASSERT_EQ(::android::OK, status);
+
+    const uint32_t stride = (bytesPerPixel > 0 && bytesPerStride > 0)
+                                    ? static_cast<uint32_t>(bytesPerStride / bytesPerPixel)
+                                    : graphicBuffer->getStride();
+    ReadbackHelper::fillBuffer(graphicBuffer->getWidth(), graphicBuffer->getHeight(), stride,
+                               bufData, static_cast<PixelFormat>(graphicBuffer->getPixelFormat()),
+                               desiredColors);
+    status = graphicBuffer->unlockAsync(fillFence);
+    ASSERT_EQ(::android::OK, status);
+}
+
 void ReadbackHelper::fillBuffer(int32_t width, int32_t height, uint32_t stride, void* bufferData,
                                 PixelFormat pixelFormat,
                                 std::vector<IComposerClient::Color> desiredPixelColors) {
@@ -116,16 +152,16 @@
     for (int row = 0; row < height; row++) {
         for (int col = 0; col < width; col++) {
             int pixel = row * width + col;
-            IComposerClient::Color srcColor = desiredPixelColors[pixel];
+            IComposerClient::Color desiredColor = desiredPixelColors[pixel];
 
             int offset = (row * stride + col) * bytesPerPixel;
             uint8_t* pixelColor = (uint8_t*)bufferData + offset;
-            pixelColor[0] = srcColor.r;
-            pixelColor[1] = srcColor.g;
-            pixelColor[2] = srcColor.b;
+            pixelColor[0] = desiredColor.r;
+            pixelColor[1] = desiredColor.g;
+            pixelColor[2] = desiredColor.b;
 
             if (bytesPerPixel == 4) {
-                pixelColor[3] = srcColor.a;
+                pixelColor[3] = desiredColor.a;
             }
         }
     }
@@ -152,12 +188,14 @@
     }
 }
 
-bool ReadbackHelper::readbackSupported(const PixelFormat& pixelFormat, const Dataspace& dataspace,
-                                       const Error error) {
+bool ReadbackHelper::readbackSupported(PixelFormat pixelFormat, Dataspace dataspace, Error error) {
     if (error != Error::NONE) {
         return false;
     }
-    // TODO: add support for RGBA_1010102
+    return readbackSupported(pixelFormat, dataspace);
+}
+
+bool ReadbackHelper::readbackSupported(PixelFormat pixelFormat, Dataspace dataspace) {
     if (pixelFormat != PixelFormat::RGB_888 && pixelFormat != PixelFormat::RGBA_8888) {
         return false;
     }
@@ -167,71 +205,94 @@
     return true;
 }
 
-void ReadbackHelper::compareColorBuffers(std::vector<IComposerClient::Color>& expectedColors,
-                                         void* bufferData, const uint32_t stride,
-                                         const uint32_t width, const uint32_t height,
-                                         const PixelFormat pixelFormat) {
-    const int32_t bytesPerPixel = ReadbackHelper::GetBytesPerPixel(pixelFormat);
-    ASSERT_NE(-1, bytesPerPixel);
-    for (int row = 0; row < height; row++) {
-        for (int col = 0; col < width; col++) {
-            int pixel = row * width + col;
-            int offset = (row * stride + col) * bytesPerPixel;
-            uint8_t* pixelColor = (uint8_t*)bufferData + offset;
+void ReadbackHelper::createReadbackBuffer(uint32_t width, uint32_t height, PixelFormat pixelFormat,
+                                          Dataspace dataspace, sp<GraphicBuffer>* graphicBuffer) {
+    ASSERT_NE(nullptr, graphicBuffer);
+    if (!readbackSupported(pixelFormat, dataspace)) {
+        *graphicBuffer = nullptr;
+    }
+    android::PixelFormat bufferFormat = static_cast<android::PixelFormat>(pixelFormat);
+    uint32_t layerCount = 1;
+    uint64_t usage = static_cast<uint64_t>(static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN) |
+                                           static_cast<uint64_t>(BufferUsage::GPU_TEXTURE));
+    *graphicBuffer = sp<GraphicBuffer>::make(width, height, bufferFormat, layerCount, usage,
+                                             "ReadbackBuffer");
+    ASSERT_NE(nullptr, *graphicBuffer);
+    ASSERT_EQ(::android::OK, (*graphicBuffer)->initCheck());
+}
 
-            ASSERT_EQ(expectedColors[pixel].r, pixelColor[0]);
-            ASSERT_EQ(expectedColors[pixel].g, pixelColor[1]);
-            ASSERT_EQ(expectedColors[pixel].b, pixelColor[2]);
+void ReadbackHelper::compareColorToBuffer(IComposerClient::Color expectedColor,
+                                          const sp<GraphicBuffer>& graphicBuffer, int32_t fence) {
+    std::vector<IComposerClient::Color> expectedColors(
+            static_cast<size_t>(graphicBuffer->getWidth() * graphicBuffer->getHeight()));
+    ::android::Rect bounds = graphicBuffer->getBounds();
+    fillColorsArea(expectedColors, static_cast<int32_t>(graphicBuffer->getWidth()),
+                   {bounds.left, bounds.top, bounds.right, bounds.bottom}, expectedColor);
+    compareColorsToBuffer(expectedColors, graphicBuffer, fence);
+}
+
+void ReadbackHelper::compareColorsToBuffer(std::vector<IComposerClient::Color>& expectedColors,
+                                           const sp<GraphicBuffer>& graphicBuffer, int32_t fence) {
+    ASSERT_TRUE(graphicBuffer->getPixelFormat() == ::android::PIXEL_FORMAT_RGB_888 ||
+                graphicBuffer->getPixelFormat() == ::android::PIXEL_FORMAT_RGBA_8888);
+
+    int bytesPerPixel = -1;
+    int bytesPerStride = -1;
+    void* bufData = nullptr;
+    status_t status = graphicBuffer->lockAsync(GRALLOC_USAGE_SW_READ_OFTEN, &bufData, fence,
+                                               &bytesPerPixel, &bytesPerStride);
+    ASSERT_EQ(::android::OK, status);
+
+    const uint32_t stride = (bytesPerPixel > 0 && bytesPerStride > 0)
+                                    ? static_cast<uint32_t>(bytesPerStride / bytesPerPixel)
+                                    : graphicBuffer->getStride();
+
+    if (bytesPerPixel == -1) {
+        PixelFormat pixelFormat = static_cast<PixelFormat>(graphicBuffer->getPixelFormat());
+        bytesPerPixel = ReadbackHelper::GetBytesPerPixel(pixelFormat);
+    }
+    ASSERT_NE(-1, bytesPerPixel);
+    for (int row = 0; row < graphicBuffer->getHeight(); row++) {
+        for (int col = 0; col < graphicBuffer->getWidth(); col++) {
+            int pixel = row * static_cast<int32_t>(graphicBuffer->getWidth()) + col;
+            int offset = (row * static_cast<int32_t>(stride) + col) * bytesPerPixel;
+            uint8_t* pixelColor = (uint8_t*)bufData + offset;
+            const IComposerClient::Color expectedColor = expectedColors[static_cast<size_t>(pixel)];
+            ASSERT_EQ(std::round(255.0f * expectedColor.r), pixelColor[0]);
+            ASSERT_EQ(std::round(255.0f * expectedColor.g), pixelColor[1]);
+            ASSERT_EQ(std::round(255.0f * expectedColor.b), pixelColor[2]);
         }
     }
+
+    status = graphicBuffer->unlock();
+    ASSERT_EQ(::android::OK, status);
 }
 
 ReadbackBuffer::ReadbackBuffer(Display display, const std::shared_ptr<ComposerClient>& client,
-                               const std::shared_ptr<Gralloc>& gralloc, uint32_t width,
-                               uint32_t height, PixelFormat pixelFormat, Dataspace dataspace) {
+                               uint32_t width, uint32_t height, PixelFormat pixelFormat) {
     mDisplay = display;
-
     mComposerClient = client;
-    mGralloc = gralloc;
-
-    mPixelFormat = pixelFormat;
-    mDataspace = dataspace;
-
     mWidth = width;
     mHeight = height;
+    mPixelFormat = pixelFormat;
     mLayerCount = 1;
-    mFormat = mPixelFormat;
     mUsage = static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN | BufferUsage::GPU_TEXTURE);
-
-    mAccessRegion.top = 0;
-    mAccessRegion.left = 0;
-    mAccessRegion.width = width;
-    mAccessRegion.height = height;
 }
 
 void ReadbackBuffer::setReadbackBuffer() {
-    mBufferHandle.reset(new Gralloc::NativeHandleWrapper(
-            mGralloc->allocate(mWidth, mHeight, mLayerCount, mFormat, mUsage,
-                               /*import*/ true, &mStride)));
-    ASSERT_NE(false, mGralloc->validateBufferSize(mBufferHandle->get(), mWidth, mHeight,
-                                                  mLayerCount, mFormat, mUsage, mStride));
-    ASSERT_NO_FATAL_FAILURE(mComposerClient->setReadbackBuffer(mDisplay, mBufferHandle->get(), -1));
+    mGraphicBuffer = sp<GraphicBuffer>::make(mWidth, mHeight,
+                                             static_cast<::android::PixelFormat>(mPixelFormat),
+                                             mLayerCount, mUsage, "ReadbackBuffer");
+    ASSERT_NE(nullptr, mGraphicBuffer);
+    ASSERT_EQ(::android::OK, mGraphicBuffer->initCheck());
+    mComposerClient->setReadbackBuffer(mDisplay, mGraphicBuffer->handle, -1 /* fence */);
 }
 
 void ReadbackBuffer::checkReadbackBuffer(std::vector<IComposerClient::Color> expectedColors) {
     // lock buffer for reading
     int32_t fenceHandle;
     ASSERT_NO_FATAL_FAILURE(mComposerClient->getReadbackBufferFence(mDisplay, &fenceHandle));
-
-    void* bufData = mGralloc->lock(mBufferHandle->get(), mUsage, mAccessRegion, fenceHandle);
-    ASSERT_TRUE(mPixelFormat == PixelFormat::RGB_888 || mPixelFormat == PixelFormat::RGBA_8888);
-    ReadbackHelper::compareColorBuffers(expectedColors, bufData, mStride, mWidth, mHeight,
-                                        mPixelFormat);
-    int32_t unlockFence = mGralloc->unlock(mBufferHandle->get());
-    if (unlockFence != -1) {
-        sync_wait(unlockFence, -1);
-        close(unlockFence);
-    }
+    ReadbackHelper::compareColorsToBuffer(expectedColors, mGraphicBuffer, fenceHandle);
 }
 
 void TestColorLayer::write(const std::shared_ptr<CommandWriterBase>& writer) {
diff --git a/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp b/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp
index 1700b2a..254ff3b 100644
--- a/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp
+++ b/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp
@@ -83,9 +83,7 @@
 void TestRenderEngine::checkColorBuffer(std::vector<V2_2::IComposerClient::Color>& expectedColors) {
     void* bufferData;
     ASSERT_EQ(0, mGraphicBuffer->lock(mGraphicBuffer->getUsage(), &bufferData));
-    ReadbackHelper::compareColorBuffers(expectedColors, bufferData, mGraphicBuffer->getStride(),
-                                        mGraphicBuffer->getWidth(), mGraphicBuffer->getHeight(),
-                                        mFormat);
+    ReadbackHelper::compareColorsToBuffer(expectedColors, mGraphicBuffer, -1 /* fence */);
     ASSERT_EQ(0, mGraphicBuffer->unlock());
 }
 
diff --git a/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ComposerVts.h b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ComposerVts.h
index 02d7bdb..bbf8ef3 100644
--- a/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ComposerVts.h
+++ b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ComposerVts.h
@@ -78,8 +78,10 @@
                                     PixelFormat format, Dataspace dataspace);
     void setPowerMode_2_2(Display display, IComposerClient::PowerMode mode);
     void setReadbackBuffer(Display display, const native_handle_t* buffer, int32_t releaseFence);
-    void getReadbackBufferAttributes(Display display, PixelFormat* outPixelFormat,
-                                     Dataspace* outDataspace);
+    void getRequiredReadbackBufferAttributes(Display display, PixelFormat* outPixelFormat,
+                                             Dataspace* outDataspace);
+    Error getReadbackBufferAttributes(Display display, PixelFormat* outPixelFormat,
+                                      Dataspace* outDataspace);
     void getReadbackBufferFence(Display display, int32_t* outFence);
 
     std::vector<ColorMode> getColorModes(Display display);
diff --git a/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ReadbackVts.h b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ReadbackVts.h
index 58efde9..7100297 100644
--- a/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ReadbackVts.h
+++ b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ReadbackVts.h
@@ -34,6 +34,8 @@
 namespace V2_2 {
 namespace vts {
 
+using android::GraphicBuffer;
+using android::sp;
 using android::hardware::hidl_handle;
 using common::V1_1::BufferUsage;
 using common::V1_1::Dataspace;
@@ -156,6 +158,13 @@
 
     static int32_t GetBytesPerPixel(PixelFormat pixelFormat);
 
+    static void fillBufferAndGetFence(const sp<GraphicBuffer>& graphicBuffer,
+                                      IComposerClient::Color desiredColor, int* fillFence);
+
+    static void fillBufferAndGetFence(const sp<GraphicBuffer>& graphicBuffer,
+                                      const std::vector<IComposerClient::Color>& desiredColors,
+                                      int* fillFence);
+
     static void fillBuffer(int32_t width, int32_t height, uint32_t stride, void* bufferData,
                            PixelFormat pixelFormat,
                            std::vector<IComposerClient::Color> desiredPixelColors);
@@ -166,40 +175,39 @@
     static void fillColorsArea(std::vector<IComposerClient::Color>& expectedColors, int32_t stride,
                                IComposerClient::Rect area, IComposerClient::Color color);
 
-    static bool readbackSupported(const PixelFormat& pixelFormat, const Dataspace& dataspace,
-                                  const Error error);
-
     static const std::vector<ColorMode> colorModes;
     static const std::vector<Dataspace> dataspaces;
 
-    static void compareColorBuffers(std::vector<IComposerClient::Color>& expectedColors,
-                                    void* bufferData, const uint32_t stride, const uint32_t width,
-                                    const uint32_t height, const PixelFormat pixelFormat);
+    static bool readbackSupported(PixelFormat pixelFormat, Dataspace dataspace, Error error);
+    static bool readbackSupported(PixelFormat pixelFormat, Dataspace dataspace);
+
+    static void createReadbackBuffer(uint32_t width, uint32_t height, PixelFormat pixelFormat,
+                                     Dataspace dataspace, sp<GraphicBuffer>* graphicBuffer);
+
+    static void compareColorToBuffer(IComposerClient::Color expectedColors,
+                                     const sp<GraphicBuffer>& graphicBuffer, int32_t fence);
+
+    static void compareColorsToBuffer(std::vector<IComposerClient::Color>& expectedColors,
+                                      const sp<GraphicBuffer>& graphicBuffer, int32_t fence);
 };
 
 class ReadbackBuffer {
   public:
-    ReadbackBuffer(Display display, const std::shared_ptr<ComposerClient>& client,
-                   const std::shared_ptr<Gralloc>& gralloc, uint32_t width, uint32_t height,
-                   PixelFormat pixelFormat, Dataspace dataspace);
+    ReadbackBuffer(Display display, const std::shared_ptr<ComposerClient>& client, uint32_t width,
+                   uint32_t height, PixelFormat pixelFormat);
 
     void setReadbackBuffer();
 
     void checkReadbackBuffer(std::vector<IComposerClient::Color> expectedColors);
 
   protected:
+    sp<GraphicBuffer> mGraphicBuffer;
     uint32_t mWidth;
     uint32_t mHeight;
-    uint32_t mLayerCount;
-    PixelFormat mFormat;
-    uint64_t mUsage;
-    AccessRegion mAccessRegion;
-    uint32_t mStride;
-    std::unique_ptr<Gralloc::NativeHandleWrapper> mBufferHandle = nullptr;
     PixelFormat mPixelFormat;
-    Dataspace mDataspace;
+    uint32_t mLayerCount;
+    uint64_t mUsage;
     Display mDisplay;
-    std::shared_ptr<Gralloc> mGralloc;
     std::shared_ptr<ComposerClient> mComposerClient;
 };
 
diff --git a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp
index e2a0f4d..5b8ce3f 100644
--- a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp
+++ b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp
@@ -40,7 +40,6 @@
 namespace {
 
 using android::Rect;
-using common::V1_1::BufferUsage;
 using common::V1_1::Dataspace;
 using common::V1_1::PixelFormat;
 using V2_1::Config;
@@ -100,8 +99,8 @@
 
         mTestRenderEngine->initGraphicBuffer(
                 static_cast<uint32_t>(mDisplayWidth), static_cast<uint32_t>(mDisplayHeight), 1,
-                static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
-                                      BufferUsage::GPU_RENDER_TARGET));
+                GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_SW_READ_OFTEN |
+                        GRALLOC_USAGE_HW_RENDER);
         mTestRenderEngine->setDisplaySettings(clientCompositionDisplay);
     }
 
@@ -116,6 +115,22 @@
         }
     }
 
+    sp<GraphicBuffer> allocateBuffer(uint32_t width, uint32_t height, uint32_t usage) {
+        const auto& graphicBuffer = sp<GraphicBuffer>::make(
+                width, height, android::PIXEL_FORMAT_RGBA_8888,
+                /*layerCount*/ 1u, usage, "VtsHalGraphicsComposer2_2_ReadbackTest");
+
+        if (graphicBuffer && android::OK == graphicBuffer->initCheck()) {
+            return nullptr;
+        }
+        return graphicBuffer;
+    }
+
+    sp<GraphicBuffer> allocateBuffer(uint32_t usage) {
+        return allocateBuffer(static_cast<uint32_t>(mDisplayWidth),
+                              static_cast<uint32_t>(mDisplayHeight), usage);
+    }
+
     void clearCommandReaderState() {
         mReader->mCompositionChanges.clear();
         mReader->mErrors.clear();
@@ -193,15 +208,9 @@
         ASSERT_NO_FATAL_FAILURE(
                 mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
 
-        mComposerClient->getRaw()->getReadbackBufferAttributes(
-                mPrimaryDisplay,
-                [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) {
-                    mHasReadbackBuffer = ReadbackHelper::readbackSupported(tmpPixelFormat,
-                                                                           tmpDataspace, tmpError);
-                    mPixelFormat = tmpPixelFormat;
-                    mDataspace = tmpDataspace;
-                });
-
+        Error error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay, &mPixelFormat,
+                                                                   &mDataspace);
+        mHasReadbackBuffer = ReadbackHelper::readbackSupported(mPixelFormat, mDataspace, error);
         if (!mHasReadbackBuffer) {
             std::cout << "Readback not supported or unsupported pixelFormat/dataspace" << std::endl;
             GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
@@ -220,8 +229,8 @@
         std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
         ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, coloredSquare, BLUE);
 
-        ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
-                                      mDisplayHeight, mPixelFormat, mDataspace);
+        ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mDisplayWidth,
+                                      mDisplayHeight, mPixelFormat);
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
         writeLayers(layers);
@@ -255,15 +264,9 @@
         ASSERT_NO_FATAL_FAILURE(
                 mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
 
-        mComposerClient->getRaw()->getReadbackBufferAttributes(
-                mPrimaryDisplay,
-                [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) {
-                    mHasReadbackBuffer = ReadbackHelper::readbackSupported(tmpPixelFormat,
-                                                                           tmpDataspace, tmpError);
-                    mPixelFormat = tmpPixelFormat;
-                    mDataspace = tmpDataspace;
-                });
-
+        Error error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay, &mPixelFormat,
+                                                                   &mDataspace);
+        mHasReadbackBuffer = ReadbackHelper::readbackSupported(mPixelFormat, mDataspace, error);
         if (!mHasReadbackBuffer) {
             std::cout << "Readback not supported or unsupported pixelFormat/dataspace" << std::endl;
             GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
@@ -272,8 +275,8 @@
 
         mWriter->selectDisplay(mPrimaryDisplay);
 
-        ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
-                                      mDisplayHeight, mPixelFormat, mDataspace);
+        ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mDisplayWidth,
+                                      mDisplayHeight, mPixelFormat);
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
         std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
         ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
@@ -319,6 +322,155 @@
     }
 }
 
+TEST_P(GraphicsCompositionTest, SetLayerBufferWithSlotsToClear) {
+    Error error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay, &mPixelFormat,
+                                                               &mDataspace);
+    if (error == Error::UNSUPPORTED) {
+        GTEST_SUCCEED() << "Readback is unsupported";
+        return;
+    }
+    ASSERT_EQ(Error::NONE, error);
+
+    sp<GraphicBuffer> readbackBuffer;
+    ASSERT_NO_FATAL_FAILURE(ReadbackHelper::createReadbackBuffer(
+            mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace, &readbackBuffer));
+    if (readbackBuffer == nullptr) {
+        GTEST_SUCCEED() << "Unsupported readback buffer attributes";
+        return;
+    }
+    // no fence needed for the readback buffer
+    int noFence = -1;
+
+    sp<GraphicBuffer> clearSlotBuffer = allocateBuffer(1u, 1u, GRALLOC_USAGE_HW_COMPOSER);
+    ASSERT_NE(nullptr, clearSlotBuffer);
+
+    // red buffer
+    uint32_t usage = GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_SW_READ_OFTEN;
+    sp<GraphicBuffer> redBuffer = allocateBuffer(usage);
+    ASSERT_NE(nullptr, redBuffer);
+    int redFence;
+    ASSERT_NO_FATAL_FAILURE(ReadbackHelper::fillBufferAndGetFence(redBuffer, RED, &redFence));
+
+    // blue buffer
+    sp<GraphicBuffer> blueBuffer = allocateBuffer(usage);
+    ASSERT_NE(nullptr, blueBuffer);
+    int blueFence;
+    ASSERT_NO_FATAL_FAILURE(ReadbackHelper::fillBufferAndGetFence(blueBuffer, BLUE, &blueFence));
+
+    // layer defaults
+    IComposerClient::Rect rectFullDisplay = {0, 0, mDisplayWidth, mDisplayHeight};
+    Layer layer = mComposerClient->createLayer(mPrimaryDisplay, 3);
+    mWriter->selectDisplay(mPrimaryDisplay);
+    mWriter->selectLayer(layer);
+    mWriter->setLayerDisplayFrame(rectFullDisplay);
+    mWriter->setLayerCompositionType(IComposerClient::Composition::DEVICE);
+
+    // set the layer to the blue buffer
+    // should be blue
+    {
+        ASSERT_NO_FATAL_FAILURE(mComposerClient->setReadbackBuffer(
+                mPrimaryDisplay, readbackBuffer->handle, noFence));
+        mWriter->selectDisplay(mPrimaryDisplay);
+        mWriter->selectLayer(layer);
+        mWriter->setLayerBuffer(/*slot*/ 0, blueBuffer->handle, blueFence);
+        mWriter->validateDisplay();
+        execute();
+        ASSERT_TRUE(mReader->mCompositionChanges.empty());
+        ASSERT_TRUE(mReader->mErrors.size());
+        mWriter->selectDisplay(mPrimaryDisplay);
+        mWriter->presentDisplay();
+        execute();
+        int32_t fence;
+        ASSERT_NO_FATAL_FAILURE(mComposerClient->getReadbackBufferFence(mPrimaryDisplay, &fence));
+        ASSERT_NO_FATAL_FAILURE(ReadbackHelper::compareColorToBuffer(BLUE, readbackBuffer, fence));
+    }
+
+    // change the layer to the red buffer
+    // should be red
+    {
+        ASSERT_NO_FATAL_FAILURE(mComposerClient->setReadbackBuffer(
+                mPrimaryDisplay, readbackBuffer->handle, noFence));
+        mWriter->selectDisplay(mPrimaryDisplay);
+        mWriter->selectLayer(layer);
+        mWriter->setLayerBuffer(/*slot*/ 1, redBuffer->handle, redFence);
+        mWriter->validateDisplay();
+        execute();
+        ASSERT_TRUE(mReader->mCompositionChanges.empty());
+        ASSERT_TRUE(mReader->mErrors.size());
+        mWriter->selectDisplay(mPrimaryDisplay);
+        mWriter->presentDisplay();
+        execute();
+        int32_t fence;
+        ASSERT_NO_FATAL_FAILURE(mComposerClient->getReadbackBufferFence(mPrimaryDisplay, &fence));
+        ReadbackHelper::compareColorToBuffer(RED, readbackBuffer, fence);
+    }
+
+    // clear the slot for the blue buffer
+    // should still be red
+    {
+        ASSERT_NO_FATAL_FAILURE(mComposerClient->setReadbackBuffer(
+                mPrimaryDisplay, readbackBuffer->handle, noFence));
+        mWriter->selectDisplay(mPrimaryDisplay);
+        mWriter->selectLayer(layer);
+        mWriter->setLayerBuffer(/*slot*/ 0, clearSlotBuffer->handle, /*fence*/ -1);
+        mWriter->validateDisplay();
+        execute();
+        ASSERT_TRUE(mReader->mCompositionChanges.empty());
+        ASSERT_TRUE(mReader->mErrors.size());
+        mWriter->selectDisplay(mPrimaryDisplay);
+        mWriter->presentDisplay();
+        execute();
+        int32_t fence;
+        ASSERT_NO_FATAL_FAILURE(mComposerClient->getReadbackBufferFence(mPrimaryDisplay, &fence));
+        ReadbackHelper::compareColorToBuffer(RED, readbackBuffer, fence);
+    }
+
+    // clear the slot for the red buffer, and set the buffer with the same slot to the blue buffer
+    // should be blue
+    {
+        ASSERT_NO_FATAL_FAILURE(mComposerClient->setReadbackBuffer(
+                mPrimaryDisplay, readbackBuffer->handle, noFence));
+        mWriter->selectDisplay(mPrimaryDisplay);
+        mWriter->selectLayer(layer);
+        mWriter->setLayerBuffer(/*slot*/ 1, clearSlotBuffer->handle, /*fence*/ -1);
+        mWriter->selectDisplay(mPrimaryDisplay);
+        mWriter->selectLayer(layer);
+        mWriter->setLayerBuffer(/*slot*/ 1, blueBuffer->handle, blueFence);
+        mWriter->validateDisplay();
+        execute();
+        ASSERT_TRUE(mReader->mCompositionChanges.empty());
+        ASSERT_TRUE(mReader->mErrors.size());
+        mWriter->selectDisplay(mPrimaryDisplay);
+        mWriter->presentDisplay();
+        execute();
+        int32_t fence;
+        ASSERT_NO_FATAL_FAILURE(mComposerClient->getReadbackBufferFence(mPrimaryDisplay, &fence));
+        ReadbackHelper::compareColorToBuffer(BLUE, readbackBuffer, fence);
+    }
+
+    // clear the slot for the now-blue buffer
+    // should be black (no buffer)
+    // TODO(b/262037933) Ensure we never clear the active buffer's slot with the placeholder buffer
+    // by setting the layer to the color black
+    {
+        ASSERT_NO_FATAL_FAILURE(mComposerClient->setReadbackBuffer(
+                mPrimaryDisplay, readbackBuffer->handle, noFence));
+        mWriter->selectDisplay(mPrimaryDisplay);
+        mWriter->selectLayer(layer);
+        mWriter->setLayerBuffer(/*slot*/ 1, clearSlotBuffer->handle, /*fence*/ -1);
+        mWriter->validateDisplay();
+        execute();
+        ASSERT_TRUE(mReader->mCompositionChanges.empty());
+        ASSERT_TRUE(mReader->mErrors.size());
+        mWriter->selectDisplay(mPrimaryDisplay);
+        mWriter->presentDisplay();
+        execute();
+        int32_t fence;
+        ASSERT_NO_FATAL_FAILURE(mComposerClient->getReadbackBufferFence(mPrimaryDisplay, &fence));
+        ReadbackHelper::compareColorToBuffer(BLACK, readbackBuffer, fence);
+    }
+}
+
 TEST_P(GraphicsCompositionTest, SetLayerBufferNoEffect) {
     for (ColorMode mode : mTestColorModes) {
         std::cout << "---Testing Color Mode " << ReadbackHelper::getColorModeString(mode) << "---"
@@ -327,15 +479,9 @@
         ASSERT_NO_FATAL_FAILURE(
                 mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
 
-        mComposerClient->getRaw()->getReadbackBufferAttributes(
-                mPrimaryDisplay,
-                [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) {
-                    mHasReadbackBuffer = ReadbackHelper::readbackSupported(tmpPixelFormat,
-                                                                           tmpDataspace, tmpError);
-                    mPixelFormat = tmpPixelFormat;
-                    mDataspace = tmpDataspace;
-                });
-
+        Error error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay, &mPixelFormat,
+                                                                   &mDataspace);
+        mHasReadbackBuffer = ReadbackHelper::readbackSupported(mPixelFormat, mDataspace, error);
         if (!mHasReadbackBuffer) {
             std::cout << "Readback not supported or unsupported pixelFormat/dataspace" << std::endl;
             GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
@@ -350,8 +496,7 @@
         layer->write(mWriter);
 
         // This following buffer call should have no effect
-        uint64_t usage =
-                static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN);
+        uint32_t usage = GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_SW_READ_OFTEN;
         NativeHandleWrapper bufferHandle =
                 mGralloc->allocate(mDisplayWidth, mDisplayHeight, 1, PixelFormat::RGBA_8888, usage);
         mWriter->setLayerBuffer(0, bufferHandle.get(), -1);
@@ -360,8 +505,8 @@
         std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
         ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, coloredSquare, BLUE);
 
-        ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
-                                      mDisplayHeight, mPixelFormat, mDataspace);
+        ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mDisplayWidth,
+                                      mDisplayHeight, mPixelFormat);
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
         mWriter->validateDisplay();
@@ -392,15 +537,11 @@
         ASSERT_NO_FATAL_FAILURE(
                 mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
 
-        mComposerClient->getRaw()->getReadbackBufferAttributes(
-                mPrimaryDisplay,
-                [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) {
-                    mHasReadbackBuffer = ReadbackHelper::readbackSupported(tmpPixelFormat,
-                                                                           tmpDataspace, tmpError);
-                    mPixelFormat = tmpPixelFormat;
-                    mDataspace = tmpDataspace;
-                });
-
+        PixelFormat pixelFormat;
+        Dataspace dataspace;
+        Error error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay, &pixelFormat,
+                                                                   &dataspace);
+        mHasReadbackBuffer = ReadbackHelper::readbackSupported(pixelFormat, dataspace, error);
         if (!mHasReadbackBuffer) {
             std::cout << "Readback not supported or unsupported pixelFormat/dataspace" << std::endl;
             GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
@@ -428,8 +569,8 @@
 
         std::vector<std::shared_ptr<TestLayer>> layers = {layer};
 
-        ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
-                                      mDisplayHeight, mPixelFormat, mDataspace);
+        ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mDisplayWidth,
+                                      mDisplayHeight, mPixelFormat);
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
         writeLayers(layers);
         ASSERT_EQ(0, mReader->mErrors.size());
@@ -441,9 +582,8 @@
             ASSERT_EQ(1, mReader->mCompositionChanges[0].second);
 
             PixelFormat clientFormat = PixelFormat::RGBA_8888;
-            uint64_t clientUsage = static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN |
-                                                         BufferUsage::CPU_WRITE_OFTEN |
-                                                         BufferUsage::COMPOSER_CLIENT_TARGET);
+            uint32_t clientUsage = GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_SW_READ_OFTEN |
+                                   GRALLOC_USAGE_HW_FB;
             Dataspace clientDataspace = ReadbackHelper::getDataspaceForColorMode(mode);
             IComposerClient::Rect damage{0, 0, mDisplayWidth, mDisplayHeight};
 
@@ -510,15 +650,9 @@
         ASSERT_NO_FATAL_FAILURE(
                 mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
 
-        mComposerClient->getRaw()->getReadbackBufferAttributes(
-                mPrimaryDisplay,
-                [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) {
-                    mHasReadbackBuffer = ReadbackHelper::readbackSupported(tmpPixelFormat,
-                                                                           tmpDataspace, tmpError);
-                    mPixelFormat = tmpPixelFormat;
-                    mDataspace = tmpDataspace;
-                });
-
+        Error error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay, &mPixelFormat,
+                                                                   &mDataspace);
+        mHasReadbackBuffer = ReadbackHelper::readbackSupported(mPixelFormat, mDataspace, error);
         if (!mHasReadbackBuffer) {
             std::cout << "Readback not supported or unsupported pixelFormat/dataspace" << std::endl;
             GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
@@ -531,8 +665,8 @@
         ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
                                        {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight}, RED);
 
-        ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
-                                      mDisplayHeight, mPixelFormat, mDataspace);
+        ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mDisplayWidth,
+                                      mDisplayHeight, mPixelFormat);
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
         auto deviceLayer = std::make_shared<TestBufferLayer>(
@@ -552,9 +686,8 @@
         deviceLayer->write(mWriter);
 
         PixelFormat clientFormat = PixelFormat::RGBA_8888;
-        uint64_t clientUsage =
-                static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
-                                      BufferUsage::COMPOSER_CLIENT_TARGET);
+        uint32_t clientUsage =
+                GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_HW_FB;
         Dataspace clientDataspace = ReadbackHelper::getDataspaceForColorMode(mode);
         int32_t clientWidth = mDisplayWidth;
         int32_t clientHeight = mDisplayHeight / 2;
@@ -633,15 +766,9 @@
         ASSERT_NO_FATAL_FAILURE(
                 mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
 
-        mComposerClient->getRaw()->getReadbackBufferAttributes(
-                mPrimaryDisplay,
-                [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) {
-                    mHasReadbackBuffer = ReadbackHelper::readbackSupported(tmpPixelFormat,
-                                                                           tmpDataspace, tmpError);
-                    mPixelFormat = tmpPixelFormat;
-                    mDataspace = tmpDataspace;
-                });
-
+        Error error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay, &mPixelFormat,
+                                                                   &mDataspace);
+        mHasReadbackBuffer = ReadbackHelper::readbackSupported(mPixelFormat, mDataspace, error);
         if (!mHasReadbackBuffer) {
             std::cout << "Readback not supported or unsupported pixelFormat/dataspace" << std::endl;
             GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
@@ -665,8 +792,8 @@
 
         std::vector<std::shared_ptr<TestLayer>> layers = {layer};
 
-        ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
-                                      mDisplayHeight, mPixelFormat, mDataspace);
+        ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mDisplayWidth,
+                                      mDisplayHeight, mPixelFormat);
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
         writeLayers(layers);
@@ -718,15 +845,9 @@
         ASSERT_NO_FATAL_FAILURE(
                 mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
 
-        mComposerClient->getRaw()->getReadbackBufferAttributes(
-                mPrimaryDisplay,
-                [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) {
-                    mHasReadbackBuffer = ReadbackHelper::readbackSupported(tmpPixelFormat,
-                                                                           tmpDataspace, tmpError);
-                    mPixelFormat = tmpPixelFormat;
-                    mDataspace = tmpDataspace;
-                });
-
+        Error error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay, &mPixelFormat,
+                                                                   &mDataspace);
+        mHasReadbackBuffer = ReadbackHelper::readbackSupported(mPixelFormat, mDataspace, error);
         if (!mHasReadbackBuffer) {
             std::cout << "Readback not supported or unsupported pixelFormat/dataspace" << std::endl;
             GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
@@ -742,8 +863,8 @@
 
         std::vector<std::shared_ptr<TestLayer>> layers = {layer};
 
-        ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
-                                      mDisplayHeight, mPixelFormat, mDataspace);
+        ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mDisplayWidth,
+                                      mDisplayHeight, mPixelFormat);
 
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
@@ -779,15 +900,9 @@
         ASSERT_NO_FATAL_FAILURE(
                 mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
 
-        mComposerClient->getRaw()->getReadbackBufferAttributes(
-                mPrimaryDisplay,
-                [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) {
-                    mHasReadbackBuffer = ReadbackHelper::readbackSupported(tmpPixelFormat,
-                                                                           tmpDataspace, tmpError);
-                    mPixelFormat = tmpPixelFormat;
-                    mDataspace = tmpDataspace;
-                });
-
+        Error error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay, &mPixelFormat,
+                                                                   &mDataspace);
+        mHasReadbackBuffer = ReadbackHelper::readbackSupported(mPixelFormat, mDataspace, error);
         if (!mHasReadbackBuffer) {
             std::cout << "Readback not supported or unsupported pixelFormat/dataspace" << std::endl;
             GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
@@ -819,8 +934,8 @@
         // update expected colors to match crop
         ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
                                        {0, 0, mDisplayWidth, mDisplayHeight}, BLUE);
-        ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
-                                      mDisplayHeight, mPixelFormat, mDataspace);
+        ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mDisplayWidth,
+                                      mDisplayHeight, mPixelFormat);
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
         writeLayers(layers);
         ASSERT_EQ(0, mReader->mErrors.size());
@@ -850,15 +965,9 @@
         ASSERT_NO_FATAL_FAILURE(
                 mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
 
-        mComposerClient->getRaw()->getReadbackBufferAttributes(
-                mPrimaryDisplay,
-                [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) {
-                    mHasReadbackBuffer = ReadbackHelper::readbackSupported(tmpPixelFormat,
-                                                                           tmpDataspace, tmpError);
-                    mPixelFormat = tmpPixelFormat;
-                    mDataspace = tmpDataspace;
-                });
-
+        Error error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay, &mPixelFormat,
+                                                                   &mDataspace);
+        mHasReadbackBuffer = ReadbackHelper::readbackSupported(mPixelFormat, mDataspace, error);
         if (!mHasReadbackBuffer) {
             std::cout << "Readback not supported or unsupported pixelFormat/dataspace" << std::endl;
             GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
@@ -886,8 +995,8 @@
         ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, blueRect, BLUE);
         ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, redRect, RED);
 
-        ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
-                                      mDisplayHeight, mPixelFormat, mDataspace);
+        ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mDisplayWidth,
+                                      mDisplayHeight, mPixelFormat);
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
         writeLayers(layers);
@@ -1019,15 +1128,9 @@
         ASSERT_NO_FATAL_FAILURE(
                 mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
 
-        mComposerClient->getRaw()->getReadbackBufferAttributes(
-                mPrimaryDisplay,
-                [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) {
-                    mHasReadbackBuffer = ReadbackHelper::readbackSupported(tmpPixelFormat,
-                                                                           tmpDataspace, tmpError);
-                    mPixelFormat = tmpPixelFormat;
-                    mDataspace = tmpDataspace;
-                });
-
+        Error error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay, &mPixelFormat,
+                                                                   &mDataspace);
+        mHasReadbackBuffer = ReadbackHelper::readbackSupported(mPixelFormat, mDataspace, error);
         if (!mHasReadbackBuffer) {
             std::cout << "Readback not supported or unsupported pixelFormat/dataspace" << std::endl;
             GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
@@ -1043,8 +1146,8 @@
         setUpLayers(IComposerClient::BlendMode::NONE);
         setExpectedColors(expectedColors);
 
-        ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
-                                      mDisplayHeight, mPixelFormat, mDataspace);
+        ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mDisplayWidth,
+                                      mDisplayHeight, mPixelFormat);
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
         writeLayers(mLayers);
         ASSERT_EQ(0, mReader->mErrors.size());
@@ -1077,15 +1180,9 @@
         ASSERT_NO_FATAL_FAILURE(
                 mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
 
-        mComposerClient->getRaw()->getReadbackBufferAttributes(
-                mPrimaryDisplay,
-                [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) {
-                    mHasReadbackBuffer = ReadbackHelper::readbackSupported(tmpPixelFormat,
-                                                                           tmpDataspace, tmpError);
-                    mPixelFormat = tmpPixelFormat;
-                    mDataspace = tmpDataspace;
-                });
-
+        Error error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay, &mPixelFormat,
+                                                                   &mDataspace);
+        mHasReadbackBuffer = ReadbackHelper::readbackSupported(mPixelFormat, mDataspace, error);
         if (!mHasReadbackBuffer) {
             std::cout << "Readback not supported or unsupported pixelFormat/dataspace" << std::endl;
             GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
@@ -1102,8 +1199,8 @@
         setUpLayers(IComposerClient::BlendMode::COVERAGE);
         setExpectedColors(expectedColors);
 
-        ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
-                                      mDisplayHeight, mPixelFormat, mDataspace);
+        ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mDisplayWidth,
+                                      mDisplayHeight, mPixelFormat);
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
         writeLayers(mLayers);
         ASSERT_EQ(0, mReader->mErrors.size());
@@ -1130,15 +1227,9 @@
         ASSERT_NO_FATAL_FAILURE(
                 mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
 
-        mComposerClient->getRaw()->getReadbackBufferAttributes(
-                mPrimaryDisplay,
-                [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) {
-                    mHasReadbackBuffer = ReadbackHelper::readbackSupported(tmpPixelFormat,
-                                                                           tmpDataspace, tmpError);
-                    mPixelFormat = tmpPixelFormat;
-                    mDataspace = tmpDataspace;
-                });
-
+        Error error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay, &mPixelFormat,
+                                                                   &mDataspace);
+        mHasReadbackBuffer = ReadbackHelper::readbackSupported(mPixelFormat, mDataspace, error);
         if (!mHasReadbackBuffer) {
             std::cout << "Readback not supported or unsupported pixelFormat/dataspace" << std::endl;
             GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
@@ -1153,8 +1244,8 @@
         setUpLayers(IComposerClient::BlendMode::PREMULTIPLIED);
         setExpectedColors(expectedColors);
 
-        ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
-                                      mDisplayHeight, mPixelFormat, mDataspace);
+        ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mDisplayWidth,
+                                      mDisplayHeight, mPixelFormat);
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
         writeLayers(mLayers);
         ASSERT_EQ(0, mReader->mErrors.size());
@@ -1222,22 +1313,16 @@
         ASSERT_NO_FATAL_FAILURE(
                 mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
 
-        mComposerClient->getRaw()->getReadbackBufferAttributes(
-                mPrimaryDisplay,
-                [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) {
-                    mHasReadbackBuffer = ReadbackHelper::readbackSupported(tmpPixelFormat,
-                                                                           tmpDataspace, tmpError);
-                    mPixelFormat = tmpPixelFormat;
-                    mDataspace = tmpDataspace;
-                });
-
+        Error error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay, &mPixelFormat,
+                                                                   &mDataspace);
+        mHasReadbackBuffer = ReadbackHelper::readbackSupported(mPixelFormat, mDataspace, error);
         if (!mHasReadbackBuffer) {
             std::cout << "Readback not supported or unsupported pixelFormat/dataspace" << std::endl;
             GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
             return;
         }
-        ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
-                                      mDisplayHeight, mPixelFormat, mDataspace);
+        ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mDisplayWidth,
+                                      mDisplayHeight, mPixelFormat);
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
         mLayer->setTransform(Transform::FLIP_H);
         mLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter);
@@ -1277,22 +1362,16 @@
         ASSERT_NO_FATAL_FAILURE(
                 mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
 
-        mComposerClient->getRaw()->getReadbackBufferAttributes(
-                mPrimaryDisplay,
-                [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) {
-                    mHasReadbackBuffer = ReadbackHelper::readbackSupported(tmpPixelFormat,
-                                                                           tmpDataspace, tmpError);
-                    mPixelFormat = tmpPixelFormat;
-                    mDataspace = tmpDataspace;
-                });
-
+        Error error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay, &mPixelFormat,
+                                                                   &mDataspace);
+        mHasReadbackBuffer = ReadbackHelper::readbackSupported(mPixelFormat, mDataspace, error);
         if (!mHasReadbackBuffer) {
             std::cout << "Readback not supported or unsupported pixelFormat/dataspace" << std::endl;
             GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
             return;
         }
-        ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
-                                      mDisplayHeight, mPixelFormat, mDataspace);
+        ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mDisplayWidth,
+                                      mDisplayHeight, mPixelFormat);
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
         mLayer->setTransform(Transform::FLIP_V);
@@ -1332,22 +1411,16 @@
         ASSERT_NO_FATAL_FAILURE(
                 mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
 
-        mComposerClient->getRaw()->getReadbackBufferAttributes(
-                mPrimaryDisplay,
-                [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) {
-                    mHasReadbackBuffer = ReadbackHelper::readbackSupported(tmpPixelFormat,
-                                                                           tmpDataspace, tmpError);
-                    mPixelFormat = tmpPixelFormat;
-                    mDataspace = tmpDataspace;
-                });
-
+        Error error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay, &mPixelFormat,
+                                                                   &mDataspace);
+        mHasReadbackBuffer = ReadbackHelper::readbackSupported(mPixelFormat, mDataspace, error);
         if (!mHasReadbackBuffer) {
             std::cout << "Readback not supported or unsupported pixelFormat/dataspace" << std::endl;
             GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
             return;
         }
-        ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
-                                      mDisplayHeight, mPixelFormat, mDataspace);
+        ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mDisplayWidth,
+                                      mDisplayHeight, mPixelFormat);
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
         mLayer->setTransform(Transform::ROT_180);
diff --git a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp
index 7e25a2e..f8fbb04 100644
--- a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp
+++ b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp
@@ -23,6 +23,7 @@
 #include <composer-vts/2.1/TestCommandReader.h>
 #include <composer-vts/2.2/ComposerVts.h>
 #include <gtest/gtest.h>
+#include <hardware/gralloc.h>
 #include <hidl/GtestPrinter.h>
 #include <hidl/ServiceManagement.h>
 #include <mapper-vts/2.0/MapperVts.h>
@@ -35,7 +36,6 @@
 namespace vts {
 namespace {
 
-using common::V1_0::BufferUsage;
 using common::V1_1::ColorMode;
 using common::V1_1::Dataspace;
 using common::V1_1::PixelFormat;
@@ -65,17 +65,13 @@
         mComposerClient->setVsyncEnabled(mPrimaryDisplay, false);
         mComposerCallback->setVsyncAllowed(false);
 
-        mComposerClient->getRaw()->getReadbackBufferAttributes(
-            mPrimaryDisplay,
-            [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) {
-                mHasReadbackBuffer = tmpError == Error::NONE;
-                if (mHasReadbackBuffer) {
-                    mReadbackPixelFormat = tmpPixelFormat;
-                    mReadbackDataspace = tmpDataspace;
-                    ASSERT_LT(static_cast<PixelFormat>(0), mReadbackPixelFormat);
-                    ASSERT_NE(Dataspace::UNKNOWN, mReadbackDataspace);
-                }
-            });
+        Error error = mComposerClient->getReadbackBufferAttributes(
+                mPrimaryDisplay, &mReadbackPixelFormat, &mReadbackDataspace);
+        mHasReadbackBuffer = error == Error::NONE;
+        if (mHasReadbackBuffer) {
+            ASSERT_LT(static_cast<PixelFormat>(0), mReadbackPixelFormat);
+            ASSERT_NE(Dataspace::UNKNOWN, mReadbackDataspace);
+        }
 
         mInvalidDisplayId = GetInvalidDisplayId();
     }
@@ -153,10 +149,9 @@
     }
 
     NativeHandleWrapper allocate() {
-        uint64_t usage =
-                static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN);
         return mGralloc->allocate(/*width*/ 64, /*height*/ 64, /*layerCount*/ 1,
-                                  PixelFormat::RGBA_8888, usage);
+                                  PixelFormat::RGBA_8888,
+                                  GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_SW_READ_OFTEN);
     }
 
     void execute() { mComposerClient->execute(mReader.get(), mWriter.get()); }
@@ -434,9 +429,7 @@
     }
 
     // BufferUsage::COMPOSER_OUTPUT is missing
-    uint64_t usage =
-            static_cast<uint64_t>(BufferUsage::COMPOSER_OVERLAY | BufferUsage::CPU_READ_OFTEN);
-
+    uint64_t usage = GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_SW_READ_OFTEN;
     std::unique_ptr<Gralloc> gralloc;
     std::unique_ptr<NativeHandleWrapper> buffer;
     ASSERT_NO_FATAL_FAILURE(gralloc = std::make_unique<Gralloc>());
@@ -457,9 +450,7 @@
         return;
     }
 
-    uint64_t usage =
-            static_cast<uint64_t>(BufferUsage::COMPOSER_OVERLAY | BufferUsage::CPU_READ_OFTEN);
-
+    uint64_t usage = GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_SW_READ_OFTEN;
     std::unique_ptr<Gralloc> gralloc;
     std::unique_ptr<NativeHandleWrapper> buffer;
     ASSERT_NO_FATAL_FAILURE(gralloc = std::make_unique<Gralloc>());
diff --git a/graphics/composer/aidl/vts/ReadbackVts.cpp b/graphics/composer/aidl/vts/ReadbackVts.cpp
index abb58e2..b59793f 100644
--- a/graphics/composer/aidl/vts/ReadbackVts.cpp
+++ b/graphics/composer/aidl/vts/ReadbackVts.cpp
@@ -20,6 +20,8 @@
 #include "renderengine/ExternalTexture.h"
 #include "renderengine/impl/ExternalTexture.h"
 
+using ::android::status_t;
+
 namespace aidl::android::hardware::graphics::composer3::vts {
 
 const std::vector<ColorMode> ReadbackHelper::colorModes = {ColorMode::SRGB, ColorMode::DISPLAY_P3};
@@ -27,6 +29,9 @@
                                                            common::Dataspace::DISPLAY_P3};
 
 void TestLayer::write(ComposerClientWriter& writer) {
+    ::android::status_t status = ::android::OK;
+    ASSERT_EQ(::android::OK, status);
+
     writer.setLayerDisplayFrame(mDisplay, mLayer, mDisplayFrame);
     writer.setLayerSourceCrop(mDisplay, mLayer, mSourceCrop);
     writer.setLayerZOrder(mDisplay, mLayer, mZOrder);
@@ -37,6 +42,40 @@
     writer.setLayerBrightness(mDisplay, mLayer, mBrightness);
 }
 
+bool ReadbackHelper::readbackSupported(const common::PixelFormat& pixelFormat,
+                                       const common::Dataspace& dataspace) {
+    // TODO: add support for RGBA_1010102
+    if (pixelFormat != common::PixelFormat::RGB_888 &&
+        pixelFormat != common::PixelFormat::RGBA_8888) {
+        return false;
+    }
+    if (std::find(dataspaces.begin(), dataspaces.end(), dataspace) == dataspaces.end()) {
+        return false;
+    }
+    return true;
+}
+
+void ReadbackHelper::createReadbackBuffer(ReadbackBufferAttributes readbackBufferAttributes,
+                                          const VtsDisplay& display,
+                                          sp<GraphicBuffer>* graphicBuffer) {
+    ASSERT_NE(nullptr, graphicBuffer);
+    if (!readbackSupported(readbackBufferAttributes.format, readbackBufferAttributes.dataspace)) {
+        *graphicBuffer = nullptr;
+    }
+    uint64_t usage =
+            static_cast<uint64_t>(static_cast<uint64_t>(common::BufferUsage::CPU_READ_OFTEN) |
+                                  static_cast<uint64_t>(common::BufferUsage::GPU_TEXTURE));
+
+    uint32_t layerCount = 1;
+    *graphicBuffer = sp<GraphicBuffer>::make(
+            static_cast<uint32_t>(display.getDisplayWidth()),
+            static_cast<uint32_t>(display.getDisplayHeight()),
+            static_cast<::android::PixelFormat>(readbackBufferAttributes.format), layerCount, usage,
+            "ReadbackBuffer");
+    ASSERT_NE(nullptr, *graphicBuffer);
+    ASSERT_EQ(::android::OK, (*graphicBuffer)->initCheck());
+}
+
 std::string ReadbackHelper::getColorModeString(ColorMode mode) {
     switch (mode) {
         case ColorMode::SRGB:
@@ -103,11 +142,11 @@
     return layerSettings;
 }
 
-int32_t ReadbackHelper::GetBytesPerPixel(common::PixelFormat pixelFormat) {
+int32_t ReadbackHelper::GetBytesPerPixel(PixelFormat pixelFormat) {
     switch (pixelFormat) {
-        case common::PixelFormat::RGBA_8888:
+        case PixelFormat::RGBA_8888:
             return 4;
-        case common::PixelFormat::RGB_888:
+        case PixelFormat::RGB_888:
             return 3;
         default:
             return -1;
@@ -116,136 +155,161 @@
 
 void ReadbackHelper::fillBuffer(uint32_t width, uint32_t height, uint32_t stride, void* bufferData,
                                 common::PixelFormat pixelFormat,
-                                std::vector<Color> desiredPixelColors) {
+                                const std::vector<Color>& desiredColors) {
     ASSERT_TRUE(pixelFormat == common::PixelFormat::RGB_888 ||
                 pixelFormat == common::PixelFormat::RGBA_8888);
     int32_t bytesPerPixel = GetBytesPerPixel(pixelFormat);
     ASSERT_NE(-1, bytesPerPixel);
     for (int row = 0; row < height; row++) {
         for (int col = 0; col < width; col++) {
-            auto pixel = row * static_cast<int32_t>(width) + col;
-            Color srcColor = desiredPixelColors[static_cast<size_t>(pixel)];
+            int pixel = row * static_cast<int32_t>(width) + col;
+            Color desiredColor = desiredColors[static_cast<size_t>(pixel)];
 
             int offset = (row * static_cast<int32_t>(stride) + col) * bytesPerPixel;
             uint8_t* pixelColor = (uint8_t*)bufferData + offset;
-            pixelColor[0] = static_cast<uint8_t>(std::round(255.0f * srcColor.r));
-            pixelColor[1] = static_cast<uint8_t>(std::round(255.0f * srcColor.g));
-            pixelColor[2] = static_cast<uint8_t>(std::round(255.0f * srcColor.b));
+            pixelColor[0] = static_cast<uint8_t>(std::round(255.0f * desiredColor.r));
+            pixelColor[1] = static_cast<uint8_t>(std::round(255.0f * desiredColor.g));
+            pixelColor[2] = static_cast<uint8_t>(std::round(255.0f * desiredColor.b));
 
             if (bytesPerPixel == 4) {
-                pixelColor[3] = static_cast<uint8_t>(std::round(255.0f * srcColor.a));
+                pixelColor[3] = static_cast<uint8_t>(std::round(255.0f * desiredColor.a));
             }
         }
     }
 }
 
-void ReadbackHelper::clearColors(std::vector<Color>& expectedColors, int32_t width, int32_t height,
+void ReadbackHelper::clearColors(std::vector<Color>& colors, int32_t width, int32_t height,
                                  int32_t displayWidth) {
     for (int row = 0; row < height; row++) {
         for (int col = 0; col < width; col++) {
             int pixel = row * displayWidth + col;
-            expectedColors[static_cast<size_t>(pixel)] = BLACK;
+            colors[static_cast<size_t>(pixel)] = BLACK;
         }
     }
 }
 
-void ReadbackHelper::fillColorsArea(std::vector<Color>& expectedColors, int32_t stride, Rect area,
-                                    Color color) {
+void ReadbackHelper::fillColorsArea(std::vector<Color>& colors, int32_t stride, Rect area,
+                                    Color desiredColor) {
     for (int row = area.top; row < area.bottom; row++) {
         for (int col = area.left; col < area.right; col++) {
             int pixel = row * stride + col;
-            expectedColors[static_cast<size_t>(pixel)] = color;
+            colors[static_cast<size_t>(pixel)] = desiredColor;
         }
     }
 }
 
-bool ReadbackHelper::readbackSupported(const common::PixelFormat& pixelFormat,
-                                       const common::Dataspace& dataspace) {
-    if (pixelFormat != common::PixelFormat::RGB_888 &&
-        pixelFormat != common::PixelFormat::RGBA_8888) {
-        return false;
-    }
-    if (std::find(dataspaces.begin(), dataspaces.end(), dataspace) == dataspaces.end()) {
-        return false;
-    }
-    return true;
+void ReadbackHelper::fillBufferAndGetFence(const sp<GraphicBuffer>& graphicBuffer,
+                                           Color desiredColor, int* fillFence) {
+    ASSERT_NE(nullptr, fillFence);
+    std::vector<Color> desiredColors(
+            static_cast<size_t>(graphicBuffer->getWidth() * graphicBuffer->getHeight()));
+    ::android::Rect bounds = graphicBuffer->getBounds();
+    fillColorsArea(desiredColors, static_cast<int32_t>(graphicBuffer->getWidth()),
+                   {bounds.left, bounds.top, bounds.right, bounds.bottom}, desiredColor);
+    ASSERT_NO_FATAL_FAILURE(fillBufferAndGetFence(graphicBuffer, desiredColors, fillFence));
 }
 
-void ReadbackHelper::compareColorBuffers(const std::vector<Color>& expectedColors, void* bufferData,
-                                         const uint32_t stride, const uint32_t width,
-                                         const uint32_t height, common::PixelFormat pixelFormat) {
-    const int32_t bytesPerPixel = ReadbackHelper::GetBytesPerPixel(pixelFormat);
+void ReadbackHelper::fillBufferAndGetFence(const sp<GraphicBuffer>& graphicBuffer,
+                                           const std::vector<Color>& desiredColors,
+                                           int* fillFence) {
+    ASSERT_TRUE(graphicBuffer->getPixelFormat() == ::android::PIXEL_FORMAT_RGB_888 ||
+                graphicBuffer->getPixelFormat() == ::android::PIXEL_FORMAT_RGBA_8888);
+    void* bufData;
+    int32_t bytesPerPixel = -1;
+    int32_t bytesPerStride = -1;
+    status_t status =
+            graphicBuffer->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
+                                &bufData, &bytesPerPixel, &bytesPerStride);
+    ASSERT_EQ(::android::OK, status);
+
+    const uint32_t stride = (bytesPerPixel > 0 && bytesPerStride > 0)
+                                    ? static_cast<uint32_t>(bytesPerStride / bytesPerPixel)
+                                    : graphicBuffer->getStride();
+    ReadbackHelper::fillBuffer(
+            graphicBuffer->getWidth(), graphicBuffer->getHeight(), stride, bufData,
+            static_cast<common::PixelFormat>(graphicBuffer->getPixelFormat()), desiredColors);
+    status = graphicBuffer->unlockAsync(fillFence);
+    ASSERT_EQ(::android::OK, status);
+}
+
+void ReadbackHelper::compareColorToBuffer(Color expectedColor,
+                                          const sp<GraphicBuffer>& graphicBuffer,
+                                          const ndk::ScopedFileDescriptor& fence) {
+    std::vector<Color> expectedColors(
+            static_cast<size_t>(graphicBuffer->getWidth() * graphicBuffer->getHeight()));
+    ::android::Rect bounds = graphicBuffer->getBounds();
+    fillColorsArea(expectedColors, static_cast<int32_t>(graphicBuffer->getWidth()),
+                   {bounds.left, bounds.top, bounds.right, bounds.bottom}, expectedColor);
+    compareColorsToBuffer(expectedColors, graphicBuffer, fence);
+}
+
+void ReadbackHelper::compareColorsToBuffer(const std::vector<Color>& expectedColors,
+                                           const sp<GraphicBuffer>& graphicBuffer,
+                                           const ndk::ScopedFileDescriptor& fence) {
+    ASSERT_TRUE(graphicBuffer->getPixelFormat() == ::android::PIXEL_FORMAT_RGB_888 ||
+                graphicBuffer->getPixelFormat() == ::android::PIXEL_FORMAT_RGBA_8888);
+
+    int bytesPerPixel = -1;
+    int bytesPerStride = -1;
+    void* bufData = nullptr;
+    status_t status = graphicBuffer->lockAsync(GRALLOC_USAGE_SW_READ_OFTEN, &bufData,
+                                               dup(fence.get()), &bytesPerPixel, &bytesPerStride);
+    ASSERT_EQ(::android::OK, status);
+
+    const uint32_t stride = (bytesPerPixel > 0 && bytesPerStride > 0)
+                                    ? static_cast<uint32_t>(bytesPerStride / bytesPerPixel)
+                                    : graphicBuffer->getStride();
+
+    if (bytesPerPixel == -1) {
+        bytesPerPixel = ReadbackHelper::GetBytesPerPixel(
+                static_cast<PixelFormat>(graphicBuffer->getPixelFormat()));
+    }
     ASSERT_NE(-1, bytesPerPixel);
-    for (int row = 0; row < height; row++) {
-        for (int col = 0; col < width; col++) {
-            auto pixel = row * static_cast<int32_t>(width) + col;
+    for (int row = 0; row < graphicBuffer->getHeight(); row++) {
+        for (int col = 0; col < graphicBuffer->getWidth(); col++) {
+            int pixel = row * static_cast<int32_t>(graphicBuffer->getWidth()) + col;
             int offset = (row * static_cast<int32_t>(stride) + col) * bytesPerPixel;
-            uint8_t* pixelColor = (uint8_t*)bufferData + offset;
+            uint8_t* pixelColor = (uint8_t*)bufData + offset;
             const Color expectedColor = expectedColors[static_cast<size_t>(pixel)];
             ASSERT_EQ(std::round(255.0f * expectedColor.r), pixelColor[0]);
             ASSERT_EQ(std::round(255.0f * expectedColor.g), pixelColor[1]);
             ASSERT_EQ(std::round(255.0f * expectedColor.b), pixelColor[2]);
         }
     }
+
+    status = graphicBuffer->unlock();
+    ASSERT_EQ(::android::OK, status);
 }
 
 ReadbackBuffer::ReadbackBuffer(int64_t display, const std::shared_ptr<VtsComposerClient>& client,
-                               int32_t width, int32_t height, common::PixelFormat pixelFormat,
-                               common::Dataspace dataspace)
+                               int32_t width, int32_t height, common::PixelFormat pixelFormat)
     : mComposerClient(client) {
     mDisplay = display;
-
-    mPixelFormat = pixelFormat;
-    mDataspace = dataspace;
-
     mWidth = static_cast<uint32_t>(width);
     mHeight = static_cast<uint32_t>(height);
+    mPixelFormat = pixelFormat;
     mLayerCount = 1;
     mUsage = static_cast<uint64_t>(static_cast<uint64_t>(common::BufferUsage::CPU_READ_OFTEN) |
                                    static_cast<uint64_t>(common::BufferUsage::GPU_TEXTURE));
-
-    mAccessRegion.top = 0;
-    mAccessRegion.left = 0;
-    mAccessRegion.right = static_cast<int32_t>(width);
-    mAccessRegion.bottom = static_cast<int32_t>(height);
-}
-
-::android::sp<::android::GraphicBuffer> ReadbackBuffer::allocateBuffer() {
-    return ::android::sp<::android::GraphicBuffer>::make(
-            mWidth, mHeight, static_cast<::android::PixelFormat>(mPixelFormat), mLayerCount, mUsage,
-            "ReadbackBuffer");
 }
 
 void ReadbackBuffer::setReadbackBuffer() {
-    mGraphicBuffer = allocateBuffer();
+    mGraphicBuffer = sp<GraphicBuffer>::make(mWidth, mHeight,
+                                             static_cast<::android::PixelFormat>(mPixelFormat),
+                                             mLayerCount, mUsage, "ReadbackBuffer");
     ASSERT_NE(nullptr, mGraphicBuffer);
     ASSERT_EQ(::android::OK, mGraphicBuffer->initCheck());
-    const auto& bufferHandle = mGraphicBuffer->handle;
-    ::ndk::ScopedFileDescriptor fence = ::ndk::ScopedFileDescriptor(-1);
-    EXPECT_TRUE(mComposerClient->setReadbackBuffer(mDisplay, bufferHandle, fence).isOk());
+    ::ndk::ScopedFileDescriptor noFence = ::ndk::ScopedFileDescriptor(-1);
+    const auto& status =
+            mComposerClient->setReadbackBuffer(mDisplay, mGraphicBuffer->handle, noFence);
+    ASSERT_TRUE(status.isOk());
 }
 
 void ReadbackBuffer::checkReadbackBuffer(const std::vector<Color>& expectedColors) {
-    ASSERT_NE(nullptr, mGraphicBuffer);
     // lock buffer for reading
     const auto& [fenceStatus, bufferFence] = mComposerClient->getReadbackBufferFence(mDisplay);
-    EXPECT_TRUE(fenceStatus.isOk());
-
-    int bytesPerPixel = -1;
-    int bytesPerStride = -1;
-    void* bufData = nullptr;
-
-    auto status = mGraphicBuffer->lockAsync(mUsage, mAccessRegion, &bufData, dup(bufferFence.get()),
-                                            &bytesPerPixel, &bytesPerStride);
-    EXPECT_EQ(::android::OK, status);
-    ASSERT_TRUE(mPixelFormat == PixelFormat::RGB_888 || mPixelFormat == PixelFormat::RGBA_8888);
-    const uint32_t stride = (bytesPerPixel > 0 && bytesPerStride > 0)
-                                    ? static_cast<uint32_t>(bytesPerStride / bytesPerPixel)
-                                    : mGraphicBuffer->getStride();
-    ReadbackHelper::compareColorBuffers(expectedColors, bufData, stride, mWidth, mHeight,
-                                        mPixelFormat);
-    status = mGraphicBuffer->unlock();
-    EXPECT_EQ(::android::OK, status);
+    ASSERT_TRUE(fenceStatus.isOk());
+    ReadbackHelper::compareColorsToBuffer(expectedColors, mGraphicBuffer, bufferFence);
 }
 
 void TestColorLayer::write(ComposerClientWriter& writer) {
@@ -323,9 +387,8 @@
     const uint32_t stride = (bytesPerPixel > 0 && bytesPerStride > 0)
                                     ? static_cast<uint32_t>(bytesPerStride / bytesPerPixel)
                                     : mGraphicBuffer->getStride();
-    EXPECT_EQ(::android::OK, status);
-    ASSERT_NO_FATAL_FAILURE(ReadbackHelper::fillBuffer(mWidth, mHeight, stride, bufData,
-                                                       mPixelFormat, expectedColors));
+    ASSERT_EQ(::android::OK, status);
+    ReadbackHelper::fillBuffer(mWidth, mHeight, stride, bufData, mPixelFormat, expectedColors);
 
     const auto unlockStatus = mGraphicBuffer->unlockAsync(&mFillFence);
     ASSERT_EQ(::android::OK, unlockStatus);
@@ -335,13 +398,13 @@
     mGraphicBuffer = allocateBuffer();
     ASSERT_NE(nullptr, mGraphicBuffer);
     ASSERT_EQ(::android::OK, mGraphicBuffer->initCheck());
-    ASSERT_NO_FATAL_FAILURE(fillBuffer(colors));
+    fillBuffer(colors);
 }
 
-::android::sp<::android::GraphicBuffer> TestBufferLayer::allocateBuffer() {
-    return ::android::sp<::android::GraphicBuffer>::make(
-            mWidth, mHeight, static_cast<::android::PixelFormat>(mPixelFormat), mLayerCount, mUsage,
-            "TestBufferLayer");
+sp<GraphicBuffer> TestBufferLayer::allocateBuffer() {
+    return sp<GraphicBuffer>::make(mWidth, mHeight,
+                                   static_cast<::android::PixelFormat>(mPixelFormat), mLayerCount,
+                                   mUsage, "TestBufferLayer");
 }
 
 void TestBufferLayer::setDataspace(common::Dataspace dataspace, ComposerClientWriter& writer) {
diff --git a/graphics/composer/aidl/vts/ReadbackVts.h b/graphics/composer/aidl/vts/ReadbackVts.h
index ee9f0d5..ecf0d52 100644
--- a/graphics/composer/aidl/vts/ReadbackVts.h
+++ b/graphics/composer/aidl/vts/ReadbackVts.h
@@ -33,6 +33,8 @@
 using common::Dataspace;
 using common::PixelFormat;
 using IMapper2_1 = ::android::hardware::graphics::mapper::V2_1::IMapper;
+using ::android::GraphicBuffer;
+using ::android::sp;
 
 static const Color BLACK = {0.0f, 0.0f, 0.0f, 1.0f};
 static const Color RED = {1.0f, 0.0f, 0.0f, 1.0f};
@@ -146,7 +148,7 @@
 
   protected:
     Composition mComposition;
-    ::android::sp<::android::GraphicBuffer> mGraphicBuffer;
+    sp<GraphicBuffer> mGraphicBuffer;
     TestRenderEngine& mRenderEngine;
     int32_t mFillFence;
     uint32_t mWidth;
@@ -162,6 +164,11 @@
 
 class ReadbackHelper {
   public:
+    static bool readbackSupported(const PixelFormat& pixelFormat, const Dataspace& dataspace);
+
+    static void createReadbackBuffer(ReadbackBufferAttributes readbackBufferAttributes,
+                                     const VtsDisplay& display, sp<GraphicBuffer>* graphicBuffer);
+
     static std::string getColorModeString(ColorMode mode);
 
     static std::string getDataspaceString(Dataspace dataspace);
@@ -171,28 +178,36 @@
     static int32_t GetBytesPerPixel(PixelFormat pixelFormat);
 
     static void fillBuffer(uint32_t width, uint32_t height, uint32_t stride, void* bufferData,
-                           PixelFormat pixelFormat, std::vector<Color> desiredPixelColors);
+                           PixelFormat pixelFormat, const std::vector<Color>& desriedColors);
 
-    static void clearColors(std::vector<Color>& expectedColors, int32_t width, int32_t height,
+    static void clearColors(std::vector<Color>& colors, int32_t width, int32_t height,
                             int32_t displayWidth);
 
-    static void fillColorsArea(std::vector<Color>& expectedColors, int32_t stride, Rect area,
-                               Color color);
+    static void fillColorsArea(std::vector<Color>& colors, int32_t stride, Rect area,
+                               Color desiredColor);
 
-    static bool readbackSupported(const PixelFormat& pixelFormat, const Dataspace& dataspace);
+    static void fillBufferAndGetFence(const sp<GraphicBuffer>& buffer, Color desiredColor,
+                                      int* fillFence);
+
+    static void fillBufferAndGetFence(const sp<GraphicBuffer>& buffer,
+                                      const std::vector<Color>& desiredColors, int* fillFence);
+
+    static void compareColorToBuffer(
+            Color expectedColor, const sp<GraphicBuffer>& graphicBuffer,
+            const ndk::ScopedFileDescriptor& fence = ::ndk::ScopedFileDescriptor(-1));
+
+    static void compareColorsToBuffer(
+            const std::vector<Color>& expectedColors, const sp<GraphicBuffer>& graphicBuffer,
+            const ndk::ScopedFileDescriptor& fence = ::ndk::ScopedFileDescriptor(-1));
 
     static const std::vector<ColorMode> colorModes;
     static const std::vector<Dataspace> dataspaces;
-
-    static void compareColorBuffers(const std::vector<Color>& expectedColors, void* bufferData,
-                                    const uint32_t stride, const uint32_t width,
-                                    const uint32_t height, PixelFormat pixelFormat);
 };
 
 class ReadbackBuffer {
   public:
     ReadbackBuffer(int64_t display, const std::shared_ptr<VtsComposerClient>& client, int32_t width,
-                   int32_t height, common::PixelFormat pixelFormat, common::Dataspace dataspace);
+                   int32_t height, common::PixelFormat pixelFormat);
 
     void setReadbackBuffer();
 
@@ -201,18 +216,12 @@
   protected:
     uint32_t mWidth;
     uint32_t mHeight;
+    PixelFormat mPixelFormat;
     uint32_t mLayerCount;
     uint32_t mUsage;
-    PixelFormat mPixelFormat;
-    Dataspace mDataspace;
     int64_t mDisplay;
-    ::android::sp<::android::GraphicBuffer> mGraphicBuffer;
+    sp<GraphicBuffer> mGraphicBuffer;
     std::shared_ptr<VtsComposerClient> mComposerClient;
-    ::android::Rect mAccessRegion;
-    native_handle_t mBufferHandle;
-
-  private:
-    ::android::sp<::android::GraphicBuffer> allocateBuffer();
 };
 
 }  // namespace aidl::android::hardware::graphics::composer3::vts
diff --git a/graphics/composer/aidl/vts/RenderEngineVts.cpp b/graphics/composer/aidl/vts/RenderEngineVts.cpp
index 66779c8..b84d0d0 100644
--- a/graphics/composer/aidl/vts/RenderEngineVts.cpp
+++ b/graphics/composer/aidl/vts/RenderEngineVts.cpp
@@ -76,18 +76,7 @@
 }
 
 void TestRenderEngine::checkColorBuffer(const std::vector<Color>& expectedColors) {
-    void* bufferData;
-    int32_t bytesPerPixel = -1;
-    int32_t bytesPerStride = -1;
-    ASSERT_EQ(0, mGraphicBuffer->lock(static_cast<uint32_t>(mGraphicBuffer->getUsage()),
-                                      &bufferData, &bytesPerPixel, &bytesPerStride));
-    const uint32_t stride = (bytesPerPixel > 0 && bytesPerStride > 0)
-                                    ? static_cast<uint32_t>(bytesPerStride / bytesPerPixel)
-                                    : mGraphicBuffer->getStride();
-    ReadbackHelper::compareColorBuffers(expectedColors, bufferData, stride,
-                                        mGraphicBuffer->getWidth(), mGraphicBuffer->getHeight(),
-                                        mFormat);
-    ASSERT_EQ(::android::OK, mGraphicBuffer->unlock());
+    ReadbackHelper::compareColorsToBuffer(expectedColors, mGraphicBuffer);
 }
 
 }  // namespace aidl::android::hardware::graphics::composer3::vts
diff --git a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp
index 6fa3392..93d9693 100644
--- a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp
+++ b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp
@@ -18,7 +18,6 @@
 
 #include <aidl/Gtest.h>
 #include <aidl/Vintf.h>
-#include <aidl/android/hardware/graphics/common/BufferUsage.h>
 #include <aidl/android/hardware/graphics/composer3/IComposer.h>
 #include <gtest/gtest.h>
 #include <ui/DisplayId.h>
@@ -81,13 +80,11 @@
         clientCompositionDisplay.physicalDisplay = Rect(getDisplayWidth(), getDisplayHeight());
         clientCompositionDisplay.clip = clientCompositionDisplay.physicalDisplay;
 
-        mTestRenderEngine->initGraphicBuffer(
-                static_cast<uint32_t>(getDisplayWidth()), static_cast<uint32_t>(getDisplayHeight()),
-                /*layerCount*/ 1U,
-                static_cast<uint64_t>(
-                        static_cast<uint64_t>(common::BufferUsage::CPU_READ_OFTEN) |
-                        static_cast<uint64_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
-                        static_cast<uint64_t>(common::BufferUsage::GPU_RENDER_TARGET)));
+        mTestRenderEngine->initGraphicBuffer(static_cast<uint32_t>(getDisplayWidth()),
+                                             static_cast<uint32_t>(getDisplayHeight()),
+                                             /*layerCount*/ 1U,
+                                             GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_SW_READ_OFTEN |
+                                                     GRALLOC_USAGE_SW_WRITE_OFTEN);
         mTestRenderEngine->setDisplaySettings(clientCompositionDisplay);
     }
 
@@ -115,18 +112,21 @@
         ASSERT_EQ(status.getServiceSpecificError(), serviceSpecificError);
     }
 
-    std::pair<bool, ::android::sp<::android::GraphicBuffer>> allocateBuffer(uint32_t usage) {
-        const auto width = static_cast<uint32_t>(getDisplayWidth());
-        const auto height = static_cast<uint32_t>(getDisplayHeight());
-
-        const auto& graphicBuffer = ::android::sp<::android::GraphicBuffer>::make(
-                width, height, ::android::PIXEL_FORMAT_RGBA_8888,
-                /*layerCount*/ 1u, usage, "VtsHalGraphicsComposer3_ReadbackTest");
+    sp<GraphicBuffer> allocateBuffer(uint32_t width, uint32_t height, uint64_t usage) {
+        sp<GraphicBuffer> graphicBuffer =
+                sp<GraphicBuffer>::make(width, height, ::android::PIXEL_FORMAT_RGBA_8888,
+                                        /*layerCount*/ 1u, static_cast<uint32_t>(usage),
+                                        "VtsHalGraphicsComposer3_ReadbackTest");
 
         if (graphicBuffer && ::android::OK == graphicBuffer->initCheck()) {
-            return {true, graphicBuffer};
+            return graphicBuffer;
         }
-        return {false, graphicBuffer};
+        return nullptr;
+    }
+
+    sp<GraphicBuffer> allocateBuffer(uint64_t usage) {
+        return allocateBuffer(static_cast<uint32_t>(getDisplayWidth()),
+                              static_cast<uint32_t>(getDisplayHeight()), usage);
     }
 
     uint64_t getStableDisplayId(int64_t display) {
@@ -293,7 +293,7 @@
         ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(), coloredSquare, BLUE);
 
         ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
-                                      getDisplayHeight(), mPixelFormat, mDataspace);
+                                      getDisplayHeight(), mPixelFormat);
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
         writeLayers(layers);
@@ -332,7 +332,7 @@
         }
 
         ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
-                                      getDisplayHeight(), mPixelFormat, mDataspace);
+                                      getDisplayHeight(), mPixelFormat);
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
         std::vector<Color> expectedColors(
                 static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
@@ -378,6 +378,143 @@
     }
 }
 
+TEST_P(GraphicsCompositionTest, SetLayerBufferWithSlotsToClear) {
+    const auto& [status, readbackBufferAttributes] =
+            mComposerClient->getReadbackBufferAttributes(getPrimaryDisplayId());
+    if (!status.isOk()) {
+        GTEST_SUCCEED() << "Readback not supported";
+        return;
+    }
+
+    sp<GraphicBuffer> readbackBuffer;
+    ASSERT_NO_FATAL_FAILURE(ReadbackHelper::createReadbackBuffer(
+            readbackBufferAttributes, getPrimaryDisplay(), &readbackBuffer));
+    if (readbackBuffer == nullptr) {
+        GTEST_SUCCEED() << "Unsupported readback buffer attributes";
+        return;
+    }
+    // no fence needed for the readback buffer
+    ScopedFileDescriptor noFence(-1);
+
+    sp<GraphicBuffer> clearSlotBuffer = allocateBuffer(1u, 1u, GRALLOC_USAGE_HW_COMPOSER);
+    ASSERT_NE(nullptr, clearSlotBuffer);
+
+    // red buffer
+    uint64_t usage = GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_SW_READ_OFTEN;
+    sp<GraphicBuffer> redBuffer = allocateBuffer(usage);
+    ASSERT_NE(nullptr, redBuffer);
+    int redFence;
+    ASSERT_NO_FATAL_FAILURE(ReadbackHelper::fillBufferAndGetFence(redBuffer, RED, &redFence));
+
+    // blue buffer
+    sp<GraphicBuffer> blueBuffer = allocateBuffer(usage);
+    ASSERT_NE(nullptr, blueBuffer);
+    int blueFence;
+    ASSERT_NO_FATAL_FAILURE(ReadbackHelper::fillBufferAndGetFence(blueBuffer, BLUE, &blueFence));
+
+    // layer defaults
+    common::Rect rectFullDisplay = {0, 0, getDisplayWidth(), getDisplayHeight()};
+    int64_t display = getPrimaryDisplayId();
+    auto [layerStatus, layer] = mComposerClient->createLayer(getPrimaryDisplayId(), 3);
+    ASSERT_TRUE(layerStatus.isOk());
+    mWriter->setLayerDisplayFrame(display, layer, rectFullDisplay);
+    mWriter->setLayerCompositionType(display, layer, Composition::DEVICE);
+
+    // set the layer to the blue buffer
+    // should be blue
+    {
+        auto status = mComposerClient->setReadbackBuffer(display, readbackBuffer->handle, noFence);
+        ASSERT_TRUE(status.isOk());
+        mWriter->setLayerBuffer(display, layer, /*slot*/ 0, blueBuffer->handle, blueFence);
+        mWriter->validateDisplay(display, ComposerClientWriter::kNoTimestamp);
+        execute();
+        ASSERT_TRUE(mReader.takeChangedCompositionTypes(display).empty());
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter->presentDisplay(display);
+        execute();
+        auto [fenceStatus, fence] = mComposerClient->getReadbackBufferFence(display);
+        ASSERT_TRUE(fenceStatus.isOk());
+        ReadbackHelper::compareColorToBuffer(BLUE, readbackBuffer, fence);
+    }
+
+    // change the layer to the red buffer
+    // should be red
+    {
+        auto status = mComposerClient->setReadbackBuffer(display, readbackBuffer->handle, noFence);
+        ASSERT_TRUE(status.isOk());
+        mWriter->setLayerBuffer(display, layer, /*slot*/ 1, redBuffer->handle, redFence);
+        mWriter->validateDisplay(display, ComposerClientWriter::kNoTimestamp);
+        execute();
+        ASSERT_TRUE(mReader.takeChangedCompositionTypes(display).empty());
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter->presentDisplay(display);
+        execute();
+        auto [fenceStatus, fence] = mComposerClient->getReadbackBufferFence(display);
+        ASSERT_TRUE(fenceStatus.isOk());
+        ReadbackHelper::compareColorToBuffer(RED, readbackBuffer, fence);
+    }
+
+    // clear the slot for the blue buffer
+    // should still be red
+    {
+        auto status = mComposerClient->setReadbackBuffer(display, readbackBuffer->handle, noFence);
+        ASSERT_TRUE(status.isOk());
+        mWriter->setLayerBufferWithNewCommand(display, layer, /*slot*/ 0, clearSlotBuffer->handle,
+                                              /*fence*/ -1);
+        mWriter->validateDisplay(display, ComposerClientWriter::kNoTimestamp);
+        execute();
+        ASSERT_TRUE(mReader.takeChangedCompositionTypes(display).empty());
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter->presentDisplay(display);
+        execute();
+        auto [fenceStatus, fence] = mComposerClient->getReadbackBufferFence(display);
+        ASSERT_TRUE(fenceStatus.isOk());
+        ReadbackHelper::compareColorToBuffer(RED, readbackBuffer, fence);
+    }
+
+    // clear the slot for the red buffer, and set the buffer with the same slot to the blue buffer
+    // should be blue
+    {
+        auto status = mComposerClient->setReadbackBuffer(display, readbackBuffer->handle, noFence);
+        ASSERT_TRUE(status.isOk());
+        mWriter->setLayerBufferWithNewCommand(display, layer, /*slot*/ 1, clearSlotBuffer->handle,
+                                              /*fence*/ -1);
+        mWriter->setLayerBuffer(display, layer, /*slot*/ 1, blueBuffer->handle, blueFence);
+        mWriter->validateDisplay(display, ComposerClientWriter::kNoTimestamp);
+        execute();
+        ASSERT_TRUE(mReader.takeChangedCompositionTypes(display).empty());
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter->presentDisplay(display);
+        execute();
+        auto [fenceStatus, fence] = mComposerClient->getReadbackBufferFence(display);
+        ASSERT_TRUE(fenceStatus.isOk());
+        ReadbackHelper::compareColorToBuffer(BLUE, readbackBuffer, fence);
+    }
+
+    // clear the slot for the now-blue buffer
+    // should be black (no buffer)
+    // TODO(b/262037933) Ensure we never clear the active buffer's slot with the placeholder buffer
+    // by setting the layer to the color black
+    {
+        auto status = mComposerClient->setReadbackBuffer(display, readbackBuffer->handle, noFence);
+        ASSERT_TRUE(status.isOk());
+        mWriter->setLayerBufferWithNewCommand(display, layer, /*slot*/ 1, clearSlotBuffer->handle,
+                                              /*fence*/ -1);
+        mWriter->validateDisplay(display, ComposerClientWriter::kNoTimestamp);
+        execute();
+        if (!mReader.takeChangedCompositionTypes(display).empty()) {
+            GTEST_SUCCEED();
+            return;
+        }
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter->presentDisplay(display);
+        execute();
+        auto [fenceStatus, fence] = mComposerClient->getReadbackBufferFence(display);
+        ASSERT_TRUE(fenceStatus.isOk());
+        ReadbackHelper::compareColorToBuffer(BLACK, readbackBuffer, fence);
+    }
+}
+
 TEST_P(GraphicsCompositionTest, SetLayerBufferNoEffect) {
     for (ColorMode mode : mTestColorModes) {
         EXPECT_TRUE(mComposerClient
@@ -399,10 +536,9 @@
         layer->write(*mWriter);
 
         // This following buffer call should have no effect
-        const auto usage = static_cast<uint32_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
-                           static_cast<uint32_t>(common::BufferUsage::CPU_READ_OFTEN);
-        const auto& [graphicBufferStatus, graphicBuffer] = allocateBuffer(usage);
-        ASSERT_TRUE(graphicBufferStatus);
+        uint64_t usage = GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_SW_READ_OFTEN;
+        sp<GraphicBuffer> graphicBuffer = allocateBuffer(usage);
+        ASSERT_NE(nullptr, graphicBuffer);
         const auto& buffer = graphicBuffer->handle;
         mWriter->setLayerBuffer(getPrimaryDisplayId(), layer->getLayer(), /*slot*/ 0, buffer,
                                 /*acquireFence*/ -1);
@@ -413,7 +549,7 @@
         ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(), coloredSquare, BLUE);
 
         ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
-                                      getDisplayHeight(), mPixelFormat, mDataspace);
+                                      getDisplayHeight(), mPixelFormat);
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
         mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
@@ -441,7 +577,7 @@
     }
 
     ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
-                                  getDisplayHeight(), mPixelFormat, mDataspace);
+                                  getDisplayHeight(), mPixelFormat);
 
     ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 }
@@ -454,10 +590,9 @@
         return;
     }
 
-    const auto usage = static_cast<uint32_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
-                       static_cast<uint32_t>(common::BufferUsage::CPU_READ_OFTEN);
-    const auto& [graphicBufferStatus, graphicBuffer] = allocateBuffer(usage);
-    ASSERT_TRUE(graphicBufferStatus);
+    uint64_t usage = GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_SW_READ_OFTEN;
+    sp<GraphicBuffer> graphicBuffer = allocateBuffer(usage);
+    ASSERT_NE(nullptr, graphicBuffer);
     const auto& bufferHandle = graphicBuffer->handle;
     ::ndk::ScopedFileDescriptor fence = ::ndk::ScopedFileDescriptor(-1);
 
@@ -539,7 +674,7 @@
         std::vector<std::shared_ptr<TestLayer>> layers = {layer};
 
         ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
-                                      getDisplayHeight(), mPixelFormat, mDataspace);
+                                      getDisplayHeight(), mPixelFormat);
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
         writeLayers(layers);
         ASSERT_TRUE(mReader.takeErrors().empty());
@@ -552,16 +687,14 @@
             ASSERT_EQ(Composition::CLIENT, changedCompositionTypes[0].composition);
 
             PixelFormat clientFormat = PixelFormat::RGBA_8888;
-            auto clientUsage = static_cast<uint32_t>(
-                    static_cast<uint32_t>(common::BufferUsage::CPU_READ_OFTEN) |
-                    static_cast<uint32_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
-                    static_cast<uint32_t>(common::BufferUsage::COMPOSER_CLIENT_TARGET));
+            auto clientUsage = GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_SW_READ_OFTEN |
+                               GRALLOC_USAGE_SW_WRITE_OFTEN;
             Dataspace clientDataspace = ReadbackHelper::getDataspaceForColorMode(mode);
             common::Rect damage{0, 0, getDisplayWidth(), getDisplayHeight()};
 
             // create client target buffer
-            const auto& [graphicBufferStatus, graphicBuffer] = allocateBuffer(clientUsage);
-            ASSERT_TRUE(graphicBufferStatus);
+            sp<GraphicBuffer> graphicBuffer = allocateBuffer(clientUsage);
+            ASSERT_NE(nullptr, graphicBuffer);
             const auto& buffer = graphicBuffer->handle;
             void* clientBufData;
             const auto stride = static_cast<uint32_t>(graphicBuffer->stride);
@@ -618,7 +751,7 @@
                 {0, getDisplayHeight() / 2, getDisplayWidth(), getDisplayHeight()}, RED);
 
         ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
-                                      getDisplayHeight(), mPixelFormat, mDataspace);
+                                      getDisplayHeight(), mPixelFormat);
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
         auto deviceLayer = std::make_shared<TestBufferLayer>(
@@ -637,10 +770,8 @@
         deviceLayer->write(*mWriter);
 
         PixelFormat clientFormat = PixelFormat::RGBA_8888;
-        auto clientUsage = static_cast<uint32_t>(
-                static_cast<uint64_t>(common::BufferUsage::CPU_READ_OFTEN) |
-                static_cast<uint32_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
-                static_cast<uint32_t>(common::BufferUsage::COMPOSER_CLIENT_TARGET));
+        auto clientUsage =
+                GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN;
         Dataspace clientDataspace = ReadbackHelper::getDataspaceForColorMode(mode);
         int32_t clientWidth = getDisplayWidth();
         int32_t clientHeight = getDisplayHeight() / 2;
@@ -662,8 +793,8 @@
         }
         // create client target buffer
         ASSERT_EQ(Composition::CLIENT, changedCompositionTypes[0].composition);
-        const auto& [graphicBufferStatus, graphicBuffer] = allocateBuffer(clientUsage);
-        ASSERT_TRUE(graphicBufferStatus);
+        sp<GraphicBuffer> graphicBuffer = allocateBuffer(clientUsage);
+        ASSERT_NE(nullptr, graphicBuffer);
         const auto& buffer = graphicBuffer->handle;
 
         void* clientBufData;
@@ -725,7 +856,7 @@
         std::vector<std::shared_ptr<TestLayer>> layers = {layer};
 
         ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
-                                      getDisplayHeight(), mPixelFormat, mDataspace);
+                                      getDisplayHeight(), mPixelFormat);
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
         writeLayers(layers);
@@ -793,7 +924,7 @@
         std::vector<std::shared_ptr<TestLayer>> layers = {layer};
 
         ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
-                                      getDisplayHeight(), mPixelFormat, mDataspace);
+                                      getDisplayHeight(), mPixelFormat);
 
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
@@ -859,7 +990,7 @@
         ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(),
                                        {0, 0, getDisplayWidth(), getDisplayHeight()}, BLUE);
         ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
-                                      getDisplayHeight(), mPixelFormat, mDataspace);
+                                      getDisplayHeight(), mPixelFormat);
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
         writeLayers(layers);
         ASSERT_TRUE(mReader.takeErrors().empty());
@@ -916,7 +1047,7 @@
         ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(), redRect, RED);
 
         ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
-                                      getDisplayHeight(), mPixelFormat, mDataspace);
+                                      getDisplayHeight(), mPixelFormat);
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
         writeLayers(layers);
@@ -1026,7 +1157,7 @@
         ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(), dimmerRedRect, DIM_RED);
 
         ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
-                                      getDisplayHeight(), mPixelFormat, mDataspace);
+                                      getDisplayHeight(), mPixelFormat);
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
         writeLayers(layers);
@@ -1162,7 +1293,7 @@
         setExpectedColors(expectedColors);
 
         ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
-                                      getDisplayHeight(), mPixelFormat, mDataspace);
+                                      getDisplayHeight(), mPixelFormat);
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
         writeLayers(mLayers);
         ASSERT_TRUE(mReader.takeErrors().empty());
@@ -1207,7 +1338,7 @@
         setExpectedColors(expectedColors);
 
         ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
-                                      getDisplayHeight(), mPixelFormat, mDataspace);
+                                      getDisplayHeight(), mPixelFormat);
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
         writeLayers(mLayers);
         ASSERT_TRUE(mReader.takeErrors().empty());
@@ -1247,7 +1378,7 @@
         setExpectedColors(expectedColors);
 
         ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
-                                      getDisplayHeight(), mPixelFormat, mDataspace);
+                                      getDisplayHeight(), mPixelFormat);
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
         writeLayers(mLayers);
         ASSERT_TRUE(mReader.takeErrors().empty());
@@ -1321,7 +1452,7 @@
             return;
         }
         ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
-                                      getDisplayHeight(), mPixelFormat, mDataspace);
+                                      getDisplayHeight(), mPixelFormat);
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
         mLayer->setTransform(Transform::FLIP_H);
         mLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), *mWriter);
@@ -1366,7 +1497,7 @@
             return;
         }
         ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
-                                      getDisplayHeight(), mPixelFormat, mDataspace);
+                                      getDisplayHeight(), mPixelFormat);
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
         mLayer->setTransform(Transform::FLIP_V);
@@ -1411,7 +1542,7 @@
             return;
         }
         ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
-                                      getDisplayHeight(), mPixelFormat, mDataspace);
+                                      getDisplayHeight(), mPixelFormat);
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
         mLayer->setTransform(Transform::ROT_180);
diff --git a/identity/aidl/Android.bp b/identity/aidl/Android.bp
index 2090473..6a25e62 100644
--- a/identity/aidl/Android.bp
+++ b/identity/aidl/Android.bp
@@ -18,7 +18,7 @@
         "android.hardware.security.rkp-V3",
     ],
     stability: "vintf",
-    frozen: true,
+    frozen: false,
     backend: {
         java: {
             platform_apis: true,
@@ -67,20 +67,20 @@
 cc_defaults {
     name: "identity_use_latest_hal_aidl_ndk_static",
     static_libs: [
-        "android.hardware.identity-V4-ndk",
+        "android.hardware.identity-V5-ndk",
     ],
 }
 
 cc_defaults {
     name: "identity_use_latest_hal_aidl_ndk_shared",
     shared_libs: [
-        "android.hardware.identity-V4-ndk",
+        "android.hardware.identity-V5-ndk",
     ],
 }
 
 cc_defaults {
     name: "identity_use_latest_hal_aidl_cpp_static",
     static_libs: [
-        "android.hardware.identity-V4-cpp",
+        "android.hardware.identity-V5-cpp",
     ],
 }
diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredential.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredential.aidl
index 5065641..4f2fe0b 100644
--- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredential.aidl
+++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredential.aidl
@@ -51,4 +51,5 @@
   byte[] deleteCredentialWithChallenge(in byte[] challenge);
   byte[] proveOwnership(in byte[] challenge);
   android.hardware.identity.IWritableIdentityCredential updateCredential();
+  @SuppressWarnings(value={"out-array"}) void finishRetrievalWithSignature(out byte[] mac, out byte[] deviceNameSpaces, out byte[] ecdsaSignature);
 }
diff --git a/identity/aidl/android/hardware/identity/IIdentityCredential.aidl b/identity/aidl/android/hardware/identity/IIdentityCredential.aidl
index 82b0a83..abdb00b 100644
--- a/identity/aidl/android/hardware/identity/IIdentityCredential.aidl
+++ b/identity/aidl/android/hardware/identity/IIdentityCredential.aidl
@@ -194,7 +194,8 @@
      * is permissible for this to be empty in which case the readerSignature parameter
      * must also be empty. If this is not the case, the call fails with STATUS_FAILED.
      *
-     * If the SessionTranscript CBOR is not empty, the X and Y coordinates of the public
+     * If mdoc session encryption is used (e.g. createEphemeralKeyPair() has been called)
+     * and the SessionTranscript CBOR is not empty, the X and Y coordinates of the public
      * part of the key-pair previously generated by createEphemeralKeyPair() must appear
      * somewhere in the bytes of the CBOR. Each of these coordinates must appear encoded
      * with the most significant bits first and use the exact amount of bits indicated by
@@ -239,8 +240,8 @@
      *   and remove the corresponding requests from the counts.
      */
     void startRetrieval(in SecureAccessControlProfile[] accessControlProfiles,
-        in HardwareAuthToken authToken, in byte[] itemsRequest, in byte[] signingKeyBlob,
-        in byte[] sessionTranscript, in byte[] readerSignature, in int[] requestCounts);
+            in HardwareAuthToken authToken, in byte[] itemsRequest, in byte[] signingKeyBlob,
+            in byte[] sessionTranscript, in byte[] readerSignature, in int[] requestCounts);
 
     /**
      * Starts retrieving an entry, subject to access control requirements.  Entries must be
@@ -271,8 +272,8 @@
      *     is given and this profile wasn't passed to startRetrieval() this call fails
      *     with STATUS_INVALID_DATA.
      */
-    void startRetrieveEntryValue(in @utf8InCpp String nameSpace, in @utf8InCpp String name,
-                                 in int entrySize, in int[] accessControlProfileIds);
+    void startRetrieveEntryValue(in @utf8InCpp String nameSpace,
+            in @utf8InCpp String name, in int entrySize, in int[] accessControlProfileIds);
 
     /**
      * Retrieves an entry value, or part of one, if the entry value is larger than gcmChunkSize.
@@ -293,11 +294,13 @@
      * returned data.
      *
      * If signingKeyBlob or the sessionTranscript parameter passed to startRetrieval() is
-     * empty then the returned MAC will be empty.
+     * empty or if mdoc session encryption is not being used (e.g. if createEphemeralKeyPair()
+     * was not called) then the returned MAC will be empty.
      *
-     * @param out mac is empty if signingKeyBlob or the sessionTranscript passed to
-     *    startRetrieval() is empty. Otherwise it is a COSE_Mac0 with empty payload
-     *    and the detached content is set to DeviceAuthenticationBytes as defined below.
+     * @param out mac is empty if signingKeyBlob, or the sessionTranscript passed to
+     *    startRetrieval() is empty, or if mdoc session encryption is not being used (e.g. if
+     *    createEphemeralKeyPair() was not called). Otherwise it is a COSE_Mac0 with empty
+     *    payload and the detached content is set to DeviceAuthenticationBytes as defined below.
      *    This code is produced by using the key agreement and key derivation function
      *    from the ciphersuite with the authentication private key and the reader
      *    ephemeral public key to compute a shared message authentication code (MAC)
@@ -407,13 +410,13 @@
      */
     void setRequestedNamespaces(in RequestNamespace[] requestNamespaces);
 
-   /**
-    * Sets the VerificationToken. This method must be called before startRetrieval() is
-    * called. This token uses the same challenge as returned by createAuthChallenge().
-    *
-    * @param verificationToken
-    *   The verification token. This token is only valid if the timestamp field is non-zero.
-    */
+    /**
+     * Sets the VerificationToken. This method must be called before startRetrieval() is
+     * called. This token uses the same challenge as returned by createAuthChallenge().
+     *
+     * @param verificationToken
+     *   The verification token. This token is only valid if the timestamp field is non-zero.
+     */
     void setVerificationToken(in VerificationToken verificationToken);
 
     /**
@@ -485,4 +488,20 @@
      * @return an IWritableIdentityCredential
      */
     IWritableIdentityCredential updateCredential();
+
+    /**
+     * Like finishRetrieval() but also returns an ECDSA signature in addition to the MAC.
+     *
+     * See section 9.1.3.6 of ISO/IEC 18013-5:2021 for details of how the signature is calculated.
+     *
+     * Unlike MACing, an ECDSA signature will be returned even if mdoc session encryption isn't
+     * being used.
+     *
+     * This method was introduced in API version 5.
+     *
+     * @param ecdsaSignature a COSE_Sign1 signature described above.
+     */
+    @SuppressWarnings(value={"out-array"})
+    void finishRetrievalWithSignature(
+            out byte[] mac, out byte[] deviceNameSpaces, out byte[] ecdsaSignature);
 }
diff --git a/identity/aidl/android/hardware/identity/IPresentationSession.aidl b/identity/aidl/android/hardware/identity/IPresentationSession.aidl
index b0449f0..0a06740 100644
--- a/identity/aidl/android/hardware/identity/IPresentationSession.aidl
+++ b/identity/aidl/android/hardware/identity/IPresentationSession.aidl
@@ -70,6 +70,17 @@
      *
      * This can be empty but if it's non-empty it must be valid CBOR.
      *
+     * If mdoc session encryption is used (e.g. getEphemeralKeyPair() has been called)
+     * and the SessionTranscript CBOR is not empty, the X and Y coordinates of the public
+     * part of the key-pair previously generated by createEphemeralKeyPair() must appear
+     * somewhere in the bytes of the CBOR. Each of these coordinates must appear encoded
+     * with the most significant bits first and use the exact amount of bits indicated by
+     * the key size of the ephemeral keys. For example, if the ephemeral key is using the
+     * P-256 curve then the 32 bytes for the X coordinate encoded with the most significant
+     * bits first must appear somewhere in the CBOR and ditto for the 32 bytes for the Y
+     * coordinate. If this is not satisfied, the call fails with
+     * STATUS_EPHEMERAL_PUBLIC_KEY_NOT_FOUND.
+     *
      * This method may only be called once per instance. If called more than once, STATUS_FAILED
      * must be returned.
      *
diff --git a/identity/aidl/default/FakeSecureHardwareProxy.cpp b/identity/aidl/default/FakeSecureHardwareProxy.cpp
index 9b9a749..8551ab7 100644
--- a/identity/aidl/default/FakeSecureHardwareProxy.cpp
+++ b/identity/aidl/default/FakeSecureHardwareProxy.cpp
@@ -596,10 +596,10 @@
     return eicPresentationStartRetrieveEntries(&ctx_);
 }
 
-bool FakeSecureHardwarePresentationProxy::calcMacKey(
+bool FakeSecureHardwarePresentationProxy::prepareDeviceAuthentication(
         const vector<uint8_t>& sessionTranscript, const vector<uint8_t>& readerEphemeralPublicKey,
         const vector<uint8_t>& signingKeyBlob, const string& docType,
-        unsigned int numNamespacesWithValues, size_t expectedProofOfProvisioningSize) {
+        unsigned int numNamespacesWithValues, size_t expectedDeviceNamespacesSize) {
     if (!validateId(__func__)) {
         return false;
     }
@@ -608,10 +608,10 @@
         eicDebug("Unexpected size %zd of signingKeyBlob, expected 60", signingKeyBlob.size());
         return false;
     }
-    return eicPresentationCalcMacKey(&ctx_, sessionTranscript.data(), sessionTranscript.size(),
-                                     readerEphemeralPublicKey.data(), signingKeyBlob.data(),
-                                     docType.c_str(), docType.size(), numNamespacesWithValues,
-                                     expectedProofOfProvisioningSize);
+    return eicPresentationPrepareDeviceAuthentication(
+            &ctx_, sessionTranscript.data(), sessionTranscript.size(),
+            readerEphemeralPublicKey.data(), readerEphemeralPublicKey.size(), signingKeyBlob.data(),
+            docType.c_str(), docType.size(), numNamespacesWithValues, expectedDeviceNamespacesSize);
 }
 
 AccessCheckResult FakeSecureHardwarePresentationProxy::startRetrieveEntryValue(
@@ -673,6 +673,25 @@
     return content;
 }
 
+optional<pair<vector<uint8_t>, vector<uint8_t>>>
+FakeSecureHardwarePresentationProxy::finishRetrievalWithSignature() {
+    if (!validateId(__func__)) {
+        return std::nullopt;
+    }
+
+    vector<uint8_t> mac(32);
+    size_t macSize = 32;
+    vector<uint8_t> ecdsaSignature(EIC_ECDSA_P256_SIGNATURE_SIZE);
+    size_t ecdsaSignatureSize = EIC_ECDSA_P256_SIGNATURE_SIZE;
+    if (!eicPresentationFinishRetrievalWithSignature(&ctx_, mac.data(), &macSize,
+                                                     ecdsaSignature.data(), &ecdsaSignatureSize)) {
+        return std::nullopt;
+    }
+    mac.resize(macSize);
+    ecdsaSignature.resize(ecdsaSignatureSize);
+    return std::make_pair(mac, ecdsaSignature);
+}
+
 optional<vector<uint8_t>> FakeSecureHardwarePresentationProxy::finishRetrieval() {
     if (!validateId(__func__)) {
         return std::nullopt;
diff --git a/identity/aidl/default/FakeSecureHardwareProxy.h b/identity/aidl/default/FakeSecureHardwareProxy.h
index 2512074..b56ab93 100644
--- a/identity/aidl/default/FakeSecureHardwareProxy.h
+++ b/identity/aidl/default/FakeSecureHardwareProxy.h
@@ -175,11 +175,11 @@
                                 const vector<uint8_t>& requestMessage, int coseSignAlg,
                                 const vector<uint8_t>& readerSignatureOfToBeSigned) override;
 
-    bool calcMacKey(const vector<uint8_t>& sessionTranscript,
-                    const vector<uint8_t>& readerEphemeralPublicKey,
-                    const vector<uint8_t>& signingKeyBlob, const string& docType,
-                    unsigned int numNamespacesWithValues,
-                    size_t expectedProofOfProvisioningSize) override;
+    bool prepareDeviceAuthentication(const vector<uint8_t>& sessionTranscript,
+                                     const vector<uint8_t>& readerEphemeralPublicKey,
+                                     const vector<uint8_t>& signingKeyBlob, const string& docType,
+                                     unsigned int numNamespacesWithValues,
+                                     size_t expectedDeviceNamespacesSize) override;
 
     AccessCheckResult startRetrieveEntryValue(
             const string& nameSpace, const string& name, unsigned int newNamespaceNumEntries,
@@ -191,6 +191,8 @@
 
     optional<vector<uint8_t>> finishRetrieval() override;
 
+    optional<pair<vector<uint8_t>, vector<uint8_t>>> finishRetrievalWithSignature() override;
+
     optional<vector<uint8_t>> deleteCredential(const string& docType,
                                                const vector<uint8_t>& challenge,
                                                bool includeChallenge,
diff --git a/identity/aidl/default/common/IdentityCredential.cpp b/identity/aidl/default/common/IdentityCredential.cpp
index ff80752..4c3b7b2 100644
--- a/identity/aidl/default/common/IdentityCredential.cpp
+++ b/identity/aidl/default/common/IdentityCredential.cpp
@@ -457,17 +457,16 @@
     }
 
     if (session_) {
-        // If presenting in a session, the TA has already done this check.
-
+        // If presenting in a session, the TA has already done the check for (X, Y) as done
+        // below, see eicSessionSetSessionTranscript().
     } else {
-        // To prevent replay-attacks, we check that the public part of the ephemeral
-        // key we previously created, is present in the DeviceEngagement part of
-        // SessionTranscript as a COSE_Key, in uncompressed form.
+        // If mdoc session encryption is in use, check that the
+        // public part of the ephemeral key we previously created, is
+        // present in the DeviceEngagement part of SessionTranscript
+        // as a COSE_Key, in uncompressed form.
         //
         // We do this by just searching for the X and Y coordinates.
-        //
-        // Would be nice to move this check to the TA.
-        if (sessionTranscript.size() > 0) {
+        if (sessionTranscript.size() > 0 && ephemeralPublicKey_.size() > 0) {
             auto [getXYSuccess, ePubX, ePubY] = support::ecPublicKeyGetXandY(ephemeralPublicKey_);
             if (!getXYSuccess) {
                 return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
@@ -608,33 +607,36 @@
     // Finally, pass info so the HMAC key can be derived and the TA can start
     // creating the DeviceNameSpaces CBOR...
     if (!session_) {
-        if (sessionTranscript_.size() > 0 && readerPublicKey_.size() > 0 &&
-            signingKeyBlob.size() > 0) {
-            // We expect the reader ephemeral public key to be same size and curve
-            // as the ephemeral key we generated (e.g. P-256 key), otherwise ECDH
-            // won't work. So its length should be 65 bytes and it should be
-            // starting with 0x04.
-            if (readerPublicKey_.size() != 65 || readerPublicKey_[0] != 0x04) {
-                return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
-                        IIdentityCredentialStore::STATUS_FAILED,
-                        "Reader public key is not in expected format"));
+        if (sessionTranscript_.size() > 0 && signingKeyBlob.size() > 0) {
+            vector<uint8_t> eReaderKeyP256;
+            if (readerPublicKey_.size() > 0) {
+                // If set, we expect the reader ephemeral public key to be same size and curve
+                // as the ephemeral key we generated (e.g. P-256 key), otherwise ECDH won't
+                // work. So its length should be 65 bytes and it should be starting with 0x04.
+                if (readerPublicKey_.size() != 65 || readerPublicKey_[0] != 0x04) {
+                    return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                            IIdentityCredentialStore::STATUS_FAILED,
+                            "Reader public key is not in expected format"));
+                }
+                eReaderKeyP256 =
+                        vector<uint8_t>(readerPublicKey_.begin() + 1, readerPublicKey_.end());
             }
-            vector<uint8_t> pubKeyP256(readerPublicKey_.begin() + 1, readerPublicKey_.end());
-            if (!hwProxy_->calcMacKey(sessionTranscript_, pubKeyP256, signingKeyBlob, docType_,
-                                      numNamespacesWithValues, expectedDeviceNameSpacesSize_)) {
+            if (!hwProxy_->prepareDeviceAuthentication(
+                        sessionTranscript_, eReaderKeyP256, signingKeyBlob, docType_,
+                        numNamespacesWithValues, expectedDeviceNameSpacesSize_)) {
                 return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
                         IIdentityCredentialStore::STATUS_FAILED,
                         "Error starting retrieving entries"));
             }
         }
     } else {
-        if (session_->getSessionTranscript().size() > 0 &&
-            session_->getReaderEphemeralPublicKey().size() > 0 && signingKeyBlob.size() > 0) {
+        if (session_->getSessionTranscript().size() > 0 && signingKeyBlob.size() > 0) {
             // Don't actually pass the reader ephemeral public key in, the TA will get
             // it from the session object.
             //
-            if (!hwProxy_->calcMacKey(sessionTranscript_, {}, signingKeyBlob, docType_,
-                                      numNamespacesWithValues, expectedDeviceNameSpacesSize_)) {
+            if (!hwProxy_->prepareDeviceAuthentication(sessionTranscript_, {}, signingKeyBlob,
+                                                       docType_, numNamespacesWithValues,
+                                                       expectedDeviceNameSpacesSize_)) {
                 return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
                         IIdentityCredentialStore::STATUS_FAILED,
                         "Error starting retrieving entries"));
@@ -924,8 +926,9 @@
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus IdentityCredential::finishRetrieval(vector<uint8_t>* outMac,
-                                                       vector<uint8_t>* outDeviceNameSpaces) {
+ndk::ScopedAStatus IdentityCredential::finishRetrievalWithSignature(
+        vector<uint8_t>* outMac, vector<uint8_t>* outDeviceNameSpaces,
+        vector<uint8_t>* outEcdsaSignature) {
     ndk::ScopedAStatus status = ensureHwProxy();
     if (!status.isOk()) {
         return status;
@@ -948,17 +951,34 @@
                         .c_str()));
     }
 
+    optional<vector<uint8_t>> digestToBeMaced;
+    optional<vector<uint8_t>> signatureToBeSigned;
+
+    // This relies on the fact that binder calls never pass a nullptr
+    // for out parameters. Hence if it's null here we know this was
+    // called from finishRetrieval() below.
+    if (outEcdsaSignature == nullptr) {
+        digestToBeMaced = hwProxy_->finishRetrieval();
+        if (!digestToBeMaced) {
+            return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                    IIdentityCredentialStore::STATUS_INVALID_DATA,
+                    "Error generating digestToBeMaced"));
+        }
+    } else {
+        auto macAndSignature = hwProxy_->finishRetrievalWithSignature();
+        if (!macAndSignature) {
+            return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                    IIdentityCredentialStore::STATUS_INVALID_DATA,
+                    "Error generating digestToBeMaced and signatureToBeSigned"));
+        }
+        digestToBeMaced = macAndSignature->first;
+        signatureToBeSigned = macAndSignature->second;
+    }
+
     // If the TA calculated a MAC (it might not have), format it as a COSE_Mac0
     //
-    optional<vector<uint8_t>> mac;
-    optional<vector<uint8_t>> digestToBeMaced = hwProxy_->finishRetrieval();
-
-    // The MAC not being set means an error occurred.
-    if (!digestToBeMaced) {
-        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
-                IIdentityCredentialStore::STATUS_INVALID_DATA, "Error generating digestToBeMaced"));
-    }
     // Size 0 means that the MAC isn't set. If it's set, it has to be 32 bytes.
+    optional<vector<uint8_t>> mac;
     if (digestToBeMaced.value().size() != 0) {
         if (digestToBeMaced.value().size() != 32) {
             return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
@@ -967,12 +987,27 @@
         }
         mac = support::coseMacWithDigest(digestToBeMaced.value(), {} /* data */);
     }
-
     *outMac = mac.value_or(vector<uint8_t>({}));
+
+    optional<vector<uint8_t>> signature;
+    if (signatureToBeSigned && signatureToBeSigned.value().size() != 0) {
+        signature = support::coseSignEcDsaWithSignature(signatureToBeSigned.value(), {},  // data
+                                                        {});  // certificateChain
+    }
+    if (outEcdsaSignature != nullptr) {
+        *outEcdsaSignature = signature.value_or(vector<uint8_t>({}));
+    }
+
     *outDeviceNameSpaces = encodedDeviceNameSpaces;
+
     return ndk::ScopedAStatus::ok();
 }
 
+ndk::ScopedAStatus IdentityCredential::finishRetrieval(vector<uint8_t>* outMac,
+                                                       vector<uint8_t>* outDeviceNameSpaces) {
+    return finishRetrievalWithSignature(outMac, outDeviceNameSpaces, nullptr);
+}
+
 ndk::ScopedAStatus IdentityCredential::generateSigningKeyPair(
         vector<uint8_t>* outSigningKeyBlob, Certificate* outSigningKeyCertificate) {
     if (session_) {
diff --git a/identity/aidl/default/common/IdentityCredential.h b/identity/aidl/default/common/IdentityCredential.h
index 5929829..1e0cd64 100644
--- a/identity/aidl/default/common/IdentityCredential.h
+++ b/identity/aidl/default/common/IdentityCredential.h
@@ -92,6 +92,10 @@
     ndk::ScopedAStatus updateCredential(
             shared_ptr<IWritableIdentityCredential>* outWritableCredential) override;
 
+    ndk::ScopedAStatus finishRetrievalWithSignature(vector<uint8_t>* outMac,
+                                                    vector<uint8_t>* outDeviceNameSpaces,
+                                                    vector<uint8_t>* outEcdsaSignature) override;
+
   private:
     ndk::ScopedAStatus deleteCredentialCommon(const vector<uint8_t>& challenge,
                                               bool includeChallenge,
diff --git a/identity/aidl/default/common/PresentationSession.cpp b/identity/aidl/default/common/PresentationSession.cpp
index 2eb7f2e..cf5b066 100644
--- a/identity/aidl/default/common/PresentationSession.cpp
+++ b/identity/aidl/default/common/PresentationSession.cpp
@@ -54,19 +54,6 @@
     }
     id_ = id.value();
 
-    optional<vector<uint8_t>> ephemeralKeyPriv = hwProxy_->getEphemeralKeyPair();
-    if (!ephemeralKeyPriv) {
-        LOG(ERROR) << "Error getting ephemeral private key for session";
-        return IIdentityCredentialStore::STATUS_FAILED;
-    }
-    optional<vector<uint8_t>> ephemeralKeyPair =
-            support::ecPrivateKeyToKeyPair(ephemeralKeyPriv.value());
-    if (!ephemeralKeyPair) {
-        LOG(ERROR) << "Error creating ephemeral key-pair";
-        return IIdentityCredentialStore::STATUS_FAILED;
-    }
-    ephemeralKeyPair_ = ephemeralKeyPair.value();
-
     optional<uint64_t> authChallenge = hwProxy_->getAuthChallenge();
     if (!authChallenge) {
         LOG(ERROR) << "Error getting authChallenge for session";
@@ -78,6 +65,23 @@
 }
 
 ndk::ScopedAStatus PresentationSession::getEphemeralKeyPair(vector<uint8_t>* outKeyPair) {
+    if (ephemeralKeyPair_.size() == 0) {
+        optional<vector<uint8_t>> ephemeralKeyPriv = hwProxy_->getEphemeralKeyPair();
+        if (!ephemeralKeyPriv) {
+            LOG(ERROR) << "Error getting ephemeral private key for session";
+            return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                    IIdentityCredentialStore::STATUS_FAILED,
+                    "Error getting ephemeral private key for session"));
+        }
+        optional<vector<uint8_t>> ephemeralKeyPair =
+                support::ecPrivateKeyToKeyPair(ephemeralKeyPriv.value());
+        if (!ephemeralKeyPair) {
+            LOG(ERROR) << "Error creating ephemeral key-pair";
+            return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                    IIdentityCredentialStore::STATUS_FAILED, "Error creating ephemeral key-pair"));
+        }
+        ephemeralKeyPair_ = ephemeralKeyPair.value();
+    }
     *outKeyPair = ephemeralKeyPair_;
     return ndk::ScopedAStatus::ok();
 }
diff --git a/identity/aidl/default/common/PresentationSession.h b/identity/aidl/default/common/PresentationSession.h
index 4cb174a..b3d46f9 100644
--- a/identity/aidl/default/common/PresentationSession.h
+++ b/identity/aidl/default/common/PresentationSession.h
@@ -72,9 +72,11 @@
 
     // Set by initialize()
     uint64_t id_;
-    vector<uint8_t> ephemeralKeyPair_;
     uint64_t authChallenge_;
 
+    // Set by getEphemeralKeyPair()
+    vector<uint8_t> ephemeralKeyPair_;
+
     // Set by setReaderEphemeralPublicKey()
     vector<uint8_t> readerPublicKey_;
 
diff --git a/identity/aidl/default/common/SecureHardwareProxy.h b/identity/aidl/default/common/SecureHardwareProxy.h
index 9f63ad8..6463318 100644
--- a/identity/aidl/default/common/SecureHardwareProxy.h
+++ b/identity/aidl/default/common/SecureHardwareProxy.h
@@ -194,11 +194,12 @@
                                         const vector<uint8_t>& requestMessage, int coseSignAlg,
                                         const vector<uint8_t>& readerSignatureOfToBeSigned) = 0;
 
-    virtual bool calcMacKey(const vector<uint8_t>& sessionTranscript,
-                            const vector<uint8_t>& readerEphemeralPublicKey,
-                            const vector<uint8_t>& signingKeyBlob, const string& docType,
-                            unsigned int numNamespacesWithValues,
-                            size_t expectedProofOfProvisioningSize) = 0;
+    virtual bool prepareDeviceAuthentication(const vector<uint8_t>& sessionTranscript,
+                                             const vector<uint8_t>& readerEphemeralPublicKey,
+                                             const vector<uint8_t>& signingKeyBlob,
+                                             const string& docType,
+                                             unsigned int numNamespacesWithValues,
+                                             size_t expectedDeviceNamespacesSize) = 0;
 
     virtual AccessCheckResult startRetrieveEntryValue(
             const string& nameSpace, const string& name, unsigned int newNamespaceNumEntries,
@@ -209,6 +210,7 @@
             const vector<int32_t>& accessControlProfileIds) = 0;
 
     virtual optional<vector<uint8_t>> finishRetrieval();
+    virtual optional<pair<vector<uint8_t>, vector<uint8_t>>> finishRetrievalWithSignature();
 
     virtual optional<vector<uint8_t>> deleteCredential(const string& docType,
                                                        const vector<uint8_t>& challenge,
diff --git a/identity/aidl/default/identity-default.xml b/identity/aidl/default/identity-default.xml
index cc0ddc7..d0d43af 100644
--- a/identity/aidl/default/identity-default.xml
+++ b/identity/aidl/default/identity-default.xml
@@ -1,7 +1,7 @@
 <manifest version="1.0" type="device">
     <hal format="aidl">
         <name>android.hardware.identity</name>
-        <version>4</version>
+        <version>5</version>
         <interface>
             <name>IIdentityCredentialStore</name>
             <instance>default</instance>
diff --git a/identity/aidl/default/libeic/EicPresentation.c b/identity/aidl/default/libeic/EicPresentation.c
index 104a559..23fd0b3 100644
--- a/identity/aidl/default/libeic/EicPresentation.c
+++ b/identity/aidl/default/libeic/EicPresentation.c
@@ -557,87 +557,11 @@
     return true;
 }
 
-bool eicPresentationCalcMacKey(EicPresentation* ctx, const uint8_t* sessionTranscript,
-                               size_t sessionTranscriptSize,
-                               const uint8_t readerEphemeralPublicKey[EIC_P256_PUB_KEY_SIZE],
-                               const uint8_t signingKeyBlob[60], const char* docType,
-                               size_t docTypeLength, unsigned int numNamespacesWithValues,
-                               size_t expectedDeviceNamespacesSize) {
-    if (ctx->sessionId != 0) {
-        EicSession* session = eicSessionGetForId(ctx->sessionId);
-        if (session == NULL) {
-            eicDebug("Error looking up session for sessionId %" PRIu32, ctx->sessionId);
-            return false;
-        }
-        EicSha256Ctx sha256;
-        uint8_t sessionTranscriptSha256[EIC_SHA256_DIGEST_SIZE];
-        eicOpsSha256Init(&sha256);
-        eicOpsSha256Update(&sha256, sessionTranscript, sessionTranscriptSize);
-        eicOpsSha256Final(&sha256, sessionTranscriptSha256);
-        if (eicCryptoMemCmp(sessionTranscriptSha256, session->sessionTranscriptSha256,
-                            EIC_SHA256_DIGEST_SIZE) != 0) {
-            eicDebug("SessionTranscript mismatch");
-            return false;
-        }
-        readerEphemeralPublicKey = session->readerEphemeralPublicKey;
-    }
-
-    uint8_t signingKeyPriv[EIC_P256_PRIV_KEY_SIZE];
-    if (!eicOpsDecryptAes128Gcm(ctx->storageKey, signingKeyBlob, 60, (const uint8_t*)docType,
-                                docTypeLength, signingKeyPriv)) {
-        eicDebug("Error decrypting signingKeyBlob");
-        return false;
-    }
-
-    uint8_t sharedSecret[EIC_P256_COORDINATE_SIZE];
-    if (!eicOpsEcdh(readerEphemeralPublicKey, signingKeyPriv, sharedSecret)) {
-        eicDebug("ECDH failed");
-        return false;
-    }
-
-    EicCbor cbor;
-    eicCborInit(&cbor, NULL, 0);
-    eicCborAppendSemantic(&cbor, EIC_CBOR_SEMANTIC_TAG_ENCODED_CBOR);
-    eicCborAppendByteString(&cbor, sessionTranscript, sessionTranscriptSize);
-    uint8_t salt[EIC_SHA256_DIGEST_SIZE];
-    eicCborFinal(&cbor, salt);
-
-    const uint8_t info[7] = {'E', 'M', 'a', 'c', 'K', 'e', 'y'};
-    uint8_t derivedKey[32];
-    if (!eicOpsHkdf(sharedSecret, EIC_P256_COORDINATE_SIZE, salt, sizeof(salt), info, sizeof(info),
-                    derivedKey, sizeof(derivedKey))) {
-        eicDebug("HKDF failed");
-        return false;
-    }
-
-    eicCborInitHmacSha256(&ctx->cbor, NULL, 0, derivedKey, sizeof(derivedKey));
-    ctx->buildCbor = true;
-
-    // What we're going to calculate the HMAC-SHA256 is the COSE ToBeMaced
-    // structure which looks like the following:
-    //
-    // MAC_structure = [
-    //   context : "MAC" / "MAC0",
-    //   protected : empty_or_serialized_map,
-    //   external_aad : bstr,
-    //   payload : bstr
-    // ]
-    //
-    eicCborAppendArray(&ctx->cbor, 4);
-    eicCborAppendStringZ(&ctx->cbor, "MAC0");
-
-    // The COSE Encoded protected headers is just a single field with
-    // COSE_LABEL_ALG (1) -> COSE_ALG_HMAC_256_256 (5). For simplicitly we just
-    // hard-code the CBOR encoding:
-    static const uint8_t coseEncodedProtectedHeaders[] = {0xa1, 0x01, 0x05};
-    eicCborAppendByteString(&ctx->cbor, coseEncodedProtectedHeaders,
-                            sizeof(coseEncodedProtectedHeaders));
-
-    // We currently don't support Externally Supplied Data (RFC 8152 section 4.3)
-    // so external_aad is the empty bstr
-    static const uint8_t externalAad[0] = {};
-    eicCborAppendByteString(&ctx->cbor, externalAad, sizeof(externalAad));
-
+// Helper used to append the DeviceAuthencation prelude, used for both MACing and ECDSA signing.
+static size_t appendDeviceAuthentication(EicCbor* cbor, const uint8_t* sessionTranscript,
+                                         size_t sessionTranscriptSize, const char* docType,
+                                         size_t docTypeLength,
+                                         size_t expectedDeviceNamespacesSize) {
     // For the payload, the _encoded_ form follows here. We handle this by simply
     // opening a bstr, and then writing the CBOR. This requires us to know the
     // size of said bstr, ahead of time... the CBOR to be written is
@@ -674,26 +598,148 @@
     dabCalculatedSize += calculatedSize;
 
     // Begin the bytestring for DeviceAuthenticationBytes;
-    eicCborBegin(&ctx->cbor, EIC_CBOR_MAJOR_TYPE_BYTE_STRING, dabCalculatedSize);
+    eicCborBegin(cbor, EIC_CBOR_MAJOR_TYPE_BYTE_STRING, dabCalculatedSize);
 
-    eicCborAppendSemantic(&ctx->cbor, EIC_CBOR_SEMANTIC_TAG_ENCODED_CBOR);
+    eicCborAppendSemantic(cbor, EIC_CBOR_SEMANTIC_TAG_ENCODED_CBOR);
 
     // Begins the bytestring for DeviceAuthentication;
-    eicCborBegin(&ctx->cbor, EIC_CBOR_MAJOR_TYPE_BYTE_STRING, calculatedSize);
+    eicCborBegin(cbor, EIC_CBOR_MAJOR_TYPE_BYTE_STRING, calculatedSize);
 
-    eicCborAppendArray(&ctx->cbor, 4);
-    eicCborAppendStringZ(&ctx->cbor, "DeviceAuthentication");
-    eicCborAppend(&ctx->cbor, sessionTranscript, sessionTranscriptSize);
-    eicCborAppendString(&ctx->cbor, docType, docTypeLength);
+    eicCborAppendArray(cbor, 4);
+    eicCborAppendStringZ(cbor, "DeviceAuthentication");
+    eicCborAppend(cbor, sessionTranscript, sessionTranscriptSize);
+    eicCborAppendString(cbor, docType, docTypeLength);
 
     // For the payload, the _encoded_ form follows here. We handle this by simply
     // opening a bstr, and then writing the CBOR. This requires us to know the
     // size of said bstr, ahead of time.
-    eicCborAppendSemantic(&ctx->cbor, EIC_CBOR_SEMANTIC_TAG_ENCODED_CBOR);
-    eicCborBegin(&ctx->cbor, EIC_CBOR_MAJOR_TYPE_BYTE_STRING, expectedDeviceNamespacesSize);
-    ctx->expectedCborSizeAtEnd = expectedDeviceNamespacesSize + ctx->cbor.size;
+    eicCborAppendSemantic(cbor, EIC_CBOR_SEMANTIC_TAG_ENCODED_CBOR);
+    eicCborBegin(cbor, EIC_CBOR_MAJOR_TYPE_BYTE_STRING, expectedDeviceNamespacesSize);
+    size_t expectedCborSizeAtEnd = expectedDeviceNamespacesSize + cbor->size;
 
-    eicCborAppendMap(&ctx->cbor, numNamespacesWithValues);
+    return expectedCborSizeAtEnd;
+}
+
+bool eicPresentationPrepareDeviceAuthentication(
+        EicPresentation* ctx, const uint8_t* sessionTranscript, size_t sessionTranscriptSize,
+        const uint8_t* readerEphemeralPublicKey, size_t readerEphemeralPublicKeySize,
+        const uint8_t signingKeyBlob[60], const char* docType, size_t docTypeLength,
+        unsigned int numNamespacesWithValues, size_t expectedDeviceNamespacesSize) {
+    if (ctx->sessionId != 0) {
+        if (readerEphemeralPublicKeySize != 0) {
+            eicDebug("In a session but readerEphemeralPublicKeySize is non-zero");
+            return false;
+        }
+        EicSession* session = eicSessionGetForId(ctx->sessionId);
+        if (session == NULL) {
+            eicDebug("Error looking up session for sessionId %" PRIu32, ctx->sessionId);
+            return false;
+        }
+        EicSha256Ctx sha256;
+        uint8_t sessionTranscriptSha256[EIC_SHA256_DIGEST_SIZE];
+        eicOpsSha256Init(&sha256);
+        eicOpsSha256Update(&sha256, sessionTranscript, sessionTranscriptSize);
+        eicOpsSha256Final(&sha256, sessionTranscriptSha256);
+        if (eicCryptoMemCmp(sessionTranscriptSha256, session->sessionTranscriptSha256,
+                            EIC_SHA256_DIGEST_SIZE) != 0) {
+            eicDebug("SessionTranscript mismatch");
+            return false;
+        }
+        readerEphemeralPublicKey = session->readerEphemeralPublicKey;
+        readerEphemeralPublicKeySize = session->readerEphemeralPublicKeySize;
+    }
+
+    // Stash the decrypted DeviceKey in context since we'll need it later in
+    // eicPresentationFinishRetrievalWithSignature()
+    if (!eicOpsDecryptAes128Gcm(ctx->storageKey, signingKeyBlob, 60, (const uint8_t*)docType,
+                                docTypeLength, ctx->deviceKeyPriv)) {
+        eicDebug("Error decrypting signingKeyBlob");
+        return false;
+    }
+
+    // We can only do MACing if EReaderKey has been set... it might not have been set if for
+    // example mdoc session encryption isn't in use. In that case we can still do ECDSA
+    if (readerEphemeralPublicKeySize > 0) {
+        if (readerEphemeralPublicKeySize != EIC_P256_PUB_KEY_SIZE) {
+            eicDebug("Unexpected size %zd for readerEphemeralPublicKeySize",
+                     readerEphemeralPublicKeySize);
+            return false;
+        }
+
+        uint8_t sharedSecret[EIC_P256_COORDINATE_SIZE];
+        if (!eicOpsEcdh(readerEphemeralPublicKey, ctx->deviceKeyPriv, sharedSecret)) {
+            eicDebug("ECDH failed");
+            return false;
+        }
+
+        EicCbor cbor;
+        eicCborInit(&cbor, NULL, 0);
+        eicCborAppendSemantic(&cbor, EIC_CBOR_SEMANTIC_TAG_ENCODED_CBOR);
+        eicCborAppendByteString(&cbor, sessionTranscript, sessionTranscriptSize);
+        uint8_t salt[EIC_SHA256_DIGEST_SIZE];
+        eicCborFinal(&cbor, salt);
+
+        const uint8_t info[7] = {'E', 'M', 'a', 'c', 'K', 'e', 'y'};
+        uint8_t derivedKey[32];
+        if (!eicOpsHkdf(sharedSecret, EIC_P256_COORDINATE_SIZE, salt, sizeof(salt), info,
+                        sizeof(info), derivedKey, sizeof(derivedKey))) {
+            eicDebug("HKDF failed");
+            return false;
+        }
+
+        eicCborInitHmacSha256(&ctx->cbor, NULL, 0, derivedKey, sizeof(derivedKey));
+
+        // What we're going to calculate the HMAC-SHA256 is the COSE ToBeMaced
+        // structure which looks like the following:
+        //
+        // MAC_structure = [
+        //   context : "MAC" / "MAC0",
+        //   protected : empty_or_serialized_map,
+        //   external_aad : bstr,
+        //   payload : bstr
+        // ]
+        //
+        eicCborAppendArray(&ctx->cbor, 4);
+        eicCborAppendStringZ(&ctx->cbor, "MAC0");
+
+        // The COSE Encoded protected headers is just a single field with
+        // COSE_LABEL_ALG (1) -> COSE_ALG_HMAC_256_256 (5). For simplicitly we just
+        // hard-code the CBOR encoding:
+        static const uint8_t coseEncodedProtectedHeaders[] = {0xa1, 0x01, 0x05};
+        eicCborAppendByteString(&ctx->cbor, coseEncodedProtectedHeaders,
+                                sizeof(coseEncodedProtectedHeaders));
+
+        // We currently don't support Externally Supplied Data (RFC 8152 section 4.3)
+        // so external_aad is the empty bstr
+        static const uint8_t externalAad[0] = {};
+        eicCborAppendByteString(&ctx->cbor, externalAad, sizeof(externalAad));
+
+        // Append DeviceAuthentication prelude and open the DeviceSigned map...
+        ctx->expectedCborSizeAtEnd =
+                appendDeviceAuthentication(&ctx->cbor, sessionTranscript, sessionTranscriptSize,
+                                           docType, docTypeLength, expectedDeviceNamespacesSize);
+        eicCborAppendMap(&ctx->cbor, numNamespacesWithValues);
+        ctx->buildCbor = true;
+    }
+
+    // Now do the same for ECDSA signatures...
+    //
+    eicCborInit(&ctx->cborEcdsa, NULL, 0);
+    eicCborAppendArray(&ctx->cborEcdsa, 4);
+    eicCborAppendStringZ(&ctx->cborEcdsa, "Signature1");
+    static const uint8_t coseEncodedProtectedHeadersEcdsa[] = {0xa1, 0x01, 0x26};
+    eicCborAppendByteString(&ctx->cborEcdsa, coseEncodedProtectedHeadersEcdsa,
+                            sizeof(coseEncodedProtectedHeadersEcdsa));
+    static const uint8_t externalAadEcdsa[0] = {};
+    eicCborAppendByteString(&ctx->cborEcdsa, externalAadEcdsa, sizeof(externalAadEcdsa));
+
+    // Append DeviceAuthentication prelude and open the DeviceSigned map...
+    ctx->expectedCborEcdsaSizeAtEnd =
+            appendDeviceAuthentication(&ctx->cborEcdsa, sessionTranscript, sessionTranscriptSize,
+                                       docType, docTypeLength, expectedDeviceNamespacesSize);
+    eicCborAppendMap(&ctx->cborEcdsa, numNamespacesWithValues);
+    ctx->buildCborEcdsa = true;
+
     return true;
 }
 
@@ -702,6 +748,7 @@
     // state objects here.
     ctx->requestMessageValidated = false;
     ctx->buildCbor = false;
+    ctx->buildCborEcdsa = false;
     ctx->accessControlProfileMaskValidated = 0;
     ctx->accessControlProfileMaskUsesReaderAuth = 0;
     ctx->accessControlProfileMaskFailedReaderAuth = 0;
@@ -724,6 +771,9 @@
     if (newNamespaceNumEntries > 0) {
         eicCborAppendString(&ctx->cbor, nameSpace, nameSpaceLength);
         eicCborAppendMap(&ctx->cbor, newNamespaceNumEntries);
+
+        eicCborAppendString(&ctx->cborEcdsa, nameSpace, nameSpaceLength);
+        eicCborAppendMap(&ctx->cborEcdsa, newNamespaceNumEntries);
     }
 
     // We'll need to calc and store a digest of additionalData to check that it's the same
@@ -778,6 +828,7 @@
 
     if (result == EIC_ACCESS_CHECK_RESULT_OK) {
         eicCborAppendString(&ctx->cbor, name, nameLength);
+        eicCborAppendString(&ctx->cborEcdsa, name, nameLength);
         ctx->accessCheckOk = true;
     }
     return result;
@@ -821,6 +872,7 @@
     }
 
     eicCborAppend(&ctx->cbor, content, encryptedContentSize - 28);
+    eicCborAppend(&ctx->cborEcdsa, content, encryptedContentSize - 28);
 
     return true;
 }
@@ -842,6 +894,40 @@
         return false;
     }
     eicCborFinal(&ctx->cbor, digestToBeMaced);
+
+    return true;
+}
+
+bool eicPresentationFinishRetrievalWithSignature(EicPresentation* ctx, uint8_t* digestToBeMaced,
+                                                 size_t* digestToBeMacedSize,
+                                                 uint8_t* signatureOfToBeSigned,
+                                                 size_t* signatureOfToBeSignedSize) {
+    if (!eicPresentationFinishRetrieval(ctx, digestToBeMaced, digestToBeMacedSize)) {
+        return false;
+    }
+
+    if (!ctx->buildCborEcdsa) {
+        *signatureOfToBeSignedSize = 0;
+        return true;
+    }
+    if (*signatureOfToBeSignedSize != EIC_ECDSA_P256_SIGNATURE_SIZE) {
+        return false;
+    }
+
+    // This verifies that the correct expectedDeviceNamespacesSize value was
+    // passed in at eicPresentationCalcMacKey() time.
+    if (ctx->cborEcdsa.size != ctx->expectedCborEcdsaSizeAtEnd) {
+        eicDebug("CBOR ECDSA size is %zd, was expecting %zd", ctx->cborEcdsa.size,
+                 ctx->expectedCborEcdsaSizeAtEnd);
+        return false;
+    }
+    uint8_t cborSha256[EIC_SHA256_DIGEST_SIZE];
+    eicCborFinal(&ctx->cborEcdsa, cborSha256);
+    if (!eicOpsEcDsa(ctx->deviceKeyPriv, cborSha256, signatureOfToBeSigned)) {
+        eicDebug("Error signing DeviceAuthentication");
+        return false;
+    }
+    eicDebug("set the signature");
     return true;
 }
 
diff --git a/identity/aidl/default/libeic/EicPresentation.h b/identity/aidl/default/libeic/EicPresentation.h
index a031890..cd3162a 100644
--- a/identity/aidl/default/libeic/EicPresentation.h
+++ b/identity/aidl/default/libeic/EicPresentation.h
@@ -76,6 +76,7 @@
     // aren't.
     bool requestMessageValidated;
     bool buildCbor;
+    bool buildCborEcdsa;
 
     // Set to true initialized as a test credential.
     bool testCredential;
@@ -101,6 +102,12 @@
 
     size_t expectedCborSizeAtEnd;
     EicCbor cbor;
+
+    // The selected DeviceKey / AuthKey
+    uint8_t deviceKeyPriv[EIC_P256_PRIV_KEY_SIZE];
+
+    EicCbor cborEcdsa;
+    size_t expectedCborEcdsaSizeAtEnd;
 } EicPresentation;
 
 // If sessionId is zero (EIC_PRESENTATION_ID_UNSET), the presentation object is not associated
@@ -214,14 +221,13 @@
     EIC_ACCESS_CHECK_RESULT_READER_AUTHENTICATION_FAILED,
 } EicAccessCheckResult;
 
-// Passes enough information to calculate the MACing key
+// Passes enough information to calculate the MACing key and/or prepare ECDSA signing
 //
-bool eicPresentationCalcMacKey(EicPresentation* ctx, const uint8_t* sessionTranscript,
-                               size_t sessionTranscriptSize,
-                               const uint8_t readerEphemeralPublicKey[EIC_P256_PUB_KEY_SIZE],
-                               const uint8_t signingKeyBlob[60], const char* docType,
-                               size_t docTypeLength, unsigned int numNamespacesWithValues,
-                               size_t expectedDeviceNamespacesSize);
+bool eicPresentationPrepareDeviceAuthentication(
+        EicPresentation* ctx, const uint8_t* sessionTranscript, size_t sessionTranscriptSize,
+        const uint8_t* readerEphemeralPublicKey, size_t readerEphemeralPublicKeySize,
+        const uint8_t signingKeyBlob[60], const char* docType, size_t docTypeLength,
+        unsigned int numNamespacesWithValues, size_t expectedDeviceNamespacesSize);
 
 // The scratchSpace should be set to a buffer at least 512 bytes (ideally 1024
 // bytes, the bigger the better). It's done this way to avoid allocating stack
@@ -253,6 +259,13 @@
 bool eicPresentationFinishRetrieval(EicPresentation* ctx, uint8_t* digestToBeMaced,
                                     size_t* digestToBeMacedSize);
 
+// Like eicPresentationFinishRetrieval() but also returns an ECDSA signature.
+//
+bool eicPresentationFinishRetrievalWithSignature(EicPresentation* ctx, uint8_t* digestToBeMaced,
+                                                 size_t* digestToBeMacedSize,
+                                                 uint8_t* signatureOfToBeSigned,
+                                                 size_t* signatureOfToBeSignedSize);
+
 // The data returned in |signatureOfToBeSigned| contains the ECDSA signature of
 // the ToBeSigned CBOR from RFC 8051 "4.4. Signing and Verification Process"
 // where content is set to the ProofOfDeletion CBOR.
diff --git a/identity/aidl/default/libeic/EicSession.c b/identity/aidl/default/libeic/EicSession.c
index d0c7a0d..e44fa68 100644
--- a/identity/aidl/default/libeic/EicSession.c
+++ b/identity/aidl/default/libeic/EicSession.c
@@ -84,30 +84,35 @@
 bool eicSessionGetEphemeralKeyPair(EicSession* ctx,
                                    uint8_t ephemeralPrivateKey[EIC_P256_PRIV_KEY_SIZE]) {
     eicMemCpy(ephemeralPrivateKey, ctx->ephemeralPrivateKey, EIC_P256_PRIV_KEY_SIZE);
+    ctx->getEphemeralKeyPairCalled = true;
     return true;
 }
 
 bool eicSessionSetReaderEphemeralPublicKey(
         EicSession* ctx, const uint8_t readerEphemeralPublicKey[EIC_P256_PUB_KEY_SIZE]) {
     eicMemCpy(ctx->readerEphemeralPublicKey, readerEphemeralPublicKey, EIC_P256_PUB_KEY_SIZE);
+    ctx->readerEphemeralPublicKeySize = EIC_P256_PUB_KEY_SIZE;
     return true;
 }
 
 bool eicSessionSetSessionTranscript(EicSession* ctx, const uint8_t* sessionTranscript,
                                     size_t sessionTranscriptSize) {
-    // Only accept the SessionTranscript if X and Y from the ephemeral key
-    // we created is somewhere in SessionTranscript...
+    // If mdoc session encryption is in use, only accept the
+    // SessionTranscript if X and Y from the ephemeral key we created
+    // is somewhere in SessionTranscript...
     //
-    if (eicMemMem(sessionTranscript, sessionTranscriptSize, ctx->ephemeralPublicKey,
-                  EIC_P256_PUB_KEY_SIZE / 2) == NULL) {
-        eicDebug("Error finding X from ephemeralPublicKey in sessionTranscript");
-        return false;
-    }
-    if (eicMemMem(sessionTranscript, sessionTranscriptSize,
-                  ctx->ephemeralPublicKey + EIC_P256_PUB_KEY_SIZE / 2,
-                  EIC_P256_PUB_KEY_SIZE / 2) == NULL) {
-        eicDebug("Error finding Y from ephemeralPublicKey in sessionTranscript");
-        return false;
+    if (ctx->getEphemeralKeyPairCalled) {
+        if (eicMemMem(sessionTranscript, sessionTranscriptSize, ctx->ephemeralPublicKey,
+                      EIC_P256_PUB_KEY_SIZE / 2) == NULL) {
+            eicDebug("Error finding X from ephemeralPublicKey in sessionTranscript");
+            return false;
+        }
+        if (eicMemMem(sessionTranscript, sessionTranscriptSize,
+                      ctx->ephemeralPublicKey + EIC_P256_PUB_KEY_SIZE / 2,
+                      EIC_P256_PUB_KEY_SIZE / 2) == NULL) {
+            eicDebug("Error finding Y from ephemeralPublicKey in sessionTranscript");
+            return false;
+        }
     }
 
     // To save space we only store the SHA-256 of SessionTranscript
diff --git a/identity/aidl/default/libeic/EicSession.h b/identity/aidl/default/libeic/EicSession.h
index 0303dae..ae9babf 100644
--- a/identity/aidl/default/libeic/EicSession.h
+++ b/identity/aidl/default/libeic/EicSession.h
@@ -31,6 +31,9 @@
     // A non-zero number unique for this EicSession instance
     uint32_t id;
 
+    // Set to true iff eicSessionGetEphemeralKeyPair() has been called.
+    bool getEphemeralKeyPairCalled;
+
     // The challenge generated at construction time by eicSessionInit().
     uint64_t authChallenge;
 
@@ -41,6 +44,7 @@
 
     uint8_t sessionTranscriptSha256[EIC_SHA256_DIGEST_SIZE];
 
+    size_t readerEphemeralPublicKeySize;
 } EicSession;
 
 bool eicSessionInit(EicSession* ctx);
diff --git a/identity/aidl/vts/EndToEndTests.cpp b/identity/aidl/vts/EndToEndTests.cpp
index 67db915..ae9035b 100644
--- a/identity/aidl/vts/EndToEndTests.cpp
+++ b/identity/aidl/vts/EndToEndTests.cpp
@@ -441,8 +441,18 @@
     }
 
     vector<uint8_t> mac;
+    vector<uint8_t> ecdsaSignature;
     vector<uint8_t> deviceNameSpacesEncoded;
-    ASSERT_TRUE(credential->finishRetrieval(&mac, &deviceNameSpacesEncoded).isOk());
+    // API version 5 (feature version 202301) returns both MAC and ECDSA signature.
+    if (halApiVersion_ >= 5) {
+        ASSERT_TRUE(credential
+                            ->finishRetrievalWithSignature(&mac, &deviceNameSpacesEncoded,
+                                                           &ecdsaSignature)
+                            .isOk());
+        ASSERT_GT(ecdsaSignature.size(), 0);
+    } else {
+        ASSERT_TRUE(credential->finishRetrieval(&mac, &deviceNameSpacesEncoded).isOk());
+    }
     cborPretty = cppbor::prettyPrint(deviceNameSpacesEncoded, 32, {});
     ASSERT_EQ(
             "{\n"
@@ -475,6 +485,21 @@
     ASSERT_TRUE(calculatedMac);
     EXPECT_EQ(mac, calculatedMac);
 
+    if (ecdsaSignature.size() > 0) {
+        vector<uint8_t> encodedDeviceAuthentication =
+                cppbor::Array()
+                        .add("DeviceAuthentication")
+                        .add(sessionTranscript.clone())
+                        .add(docType)
+                        .add(cppbor::SemanticTag(24, deviceNameSpacesEncoded))
+                        .encode();
+        vector<uint8_t> deviceAuthenticationBytes =
+                cppbor::SemanticTag(24, encodedDeviceAuthentication).encode();
+        EXPECT_TRUE(support::coseCheckEcDsaSignature(ecdsaSignature,
+                                                     deviceAuthenticationBytes,  // Detached content
+                                                     signingPubKey.value()));
+    }
+
     // Also perform an additional empty request. This is what mDL applications
     // are envisioned to do - one call to get the data elements, another to get
     // an empty DeviceSignedItems and corresponding MAC.
@@ -486,7 +511,16 @@
                                 signingKeyBlob, sessionTranscriptEncoded, {},  // readerSignature,
                                 testEntriesEntryCounts)
                         .isOk());
-    ASSERT_TRUE(credential->finishRetrieval(&mac, &deviceNameSpacesEncoded).isOk());
+    // API version 5 (feature version 202301) returns both MAC and ECDSA signature.
+    if (halApiVersion_ >= 5) {
+        ASSERT_TRUE(credential
+                            ->finishRetrievalWithSignature(&mac, &deviceNameSpacesEncoded,
+                                                           &ecdsaSignature)
+                            .isOk());
+        ASSERT_GT(ecdsaSignature.size(), 0);
+    } else {
+        ASSERT_TRUE(credential->finishRetrieval(&mac, &deviceNameSpacesEncoded).isOk());
+    }
     cborPretty = cppbor::prettyPrint(deviceNameSpacesEncoded, 32, {});
     ASSERT_EQ("{}", cborPretty);
     // Calculate DeviceAuthentication and MAC (MACing key hasn't changed)
@@ -497,6 +531,21 @@
     ASSERT_TRUE(calculatedMac);
     EXPECT_EQ(mac, calculatedMac);
 
+    if (ecdsaSignature.size() > 0) {
+        vector<uint8_t> encodedDeviceAuthentication =
+                cppbor::Array()
+                        .add("DeviceAuthentication")
+                        .add(sessionTranscript.clone())
+                        .add(docType)
+                        .add(cppbor::SemanticTag(24, deviceNameSpacesEncoded))
+                        .encode();
+        vector<uint8_t> deviceAuthenticationBytes =
+                cppbor::SemanticTag(24, encodedDeviceAuthentication).encode();
+        EXPECT_TRUE(support::coseCheckEcDsaSignature(ecdsaSignature,
+                                                     deviceAuthenticationBytes,  // Detached content
+                                                     signingPubKey.value()));
+    }
+
     // Some mDL apps might send a request but with a single empty
     // namespace. Check that too.
     RequestNamespace emptyRequestNS;
@@ -508,7 +557,16 @@
                                 signingKeyBlob, sessionTranscriptEncoded, {},  // readerSignature,
                                 testEntriesEntryCounts)
                         .isOk());
-    ASSERT_TRUE(credential->finishRetrieval(&mac, &deviceNameSpacesEncoded).isOk());
+    // API version 5 (feature version 202301) returns both MAC and ECDSA signature.
+    if (halApiVersion_ >= 5) {
+        ASSERT_TRUE(credential
+                            ->finishRetrievalWithSignature(&mac, &deviceNameSpacesEncoded,
+                                                           &ecdsaSignature)
+                            .isOk());
+        ASSERT_GT(ecdsaSignature.size(), 0);
+    } else {
+        ASSERT_TRUE(credential->finishRetrieval(&mac, &deviceNameSpacesEncoded).isOk());
+    }
     cborPretty = cppbor::prettyPrint(deviceNameSpacesEncoded, 32, {});
     ASSERT_EQ("{}", cborPretty);
     // Calculate DeviceAuthentication and MAC (MACing key hasn't changed)
@@ -518,6 +576,248 @@
                                      eMacKey.value());            // EMacKey
     ASSERT_TRUE(calculatedMac);
     EXPECT_EQ(mac, calculatedMac);
+
+    if (ecdsaSignature.size() > 0) {
+        vector<uint8_t> encodedDeviceAuthentication =
+                cppbor::Array()
+                        .add("DeviceAuthentication")
+                        .add(sessionTranscript.clone())
+                        .add(docType)
+                        .add(cppbor::SemanticTag(24, deviceNameSpacesEncoded))
+                        .encode();
+        vector<uint8_t> deviceAuthenticationBytes =
+                cppbor::SemanticTag(24, encodedDeviceAuthentication).encode();
+        EXPECT_TRUE(support::coseCheckEcDsaSignature(ecdsaSignature,
+                                                     deviceAuthenticationBytes,  // Detached content
+                                                     signingPubKey.value()));
+    }
+}
+
+TEST_P(EndToEndTests, noSessionEncryption) {
+    if (halApiVersion_ < 5) {
+        GTEST_SKIP() << "Need HAL API version 5, have " << halApiVersion_;
+    }
+
+    const vector<test_utils::TestProfile> testProfiles = {// Profile 0 (no authentication)
+                                                          {0, {}, false, 0}};
+
+    HardwareAuthToken authToken;
+    VerificationToken verificationToken;
+    authToken.challenge = 0;
+    authToken.userId = 0;
+    authToken.authenticatorId = 0;
+    authToken.authenticatorType = ::android::hardware::keymaster::HardwareAuthenticatorType::NONE;
+    authToken.timestamp.milliSeconds = 0;
+    authToken.mac.clear();
+    verificationToken.challenge = 0;
+    verificationToken.timestamp.milliSeconds = 0;
+    verificationToken.securityLevel = ::android::hardware::keymaster::SecurityLevel::SOFTWARE;
+    verificationToken.mac.clear();
+
+    // Here's the actual test data:
+    const vector<test_utils::TestEntryData> testEntries = {
+            {"PersonalData", "Last name", string("Turing"), vector<int32_t>{0}},
+            {"PersonalData", "Birth date", string("19120623"), vector<int32_t>{0}},
+            {"PersonalData", "First name", string("Alan"), vector<int32_t>{0}},
+    };
+    const vector<int32_t> testEntriesEntryCounts = {3};
+    HardwareInformation hwInfo;
+    ASSERT_TRUE(credentialStore_->getHardwareInformation(&hwInfo).isOk());
+
+    string cborPretty;
+    sp<IWritableIdentityCredential> writableCredential;
+    ASSERT_TRUE(test_utils::setupWritableCredential(writableCredential, credentialStore_,
+                                                    true /* testCredential */));
+
+    string challenge = "attestationChallenge";
+    test_utils::AttestationData attData(writableCredential, challenge,
+                                        {1} /* atteestationApplicationId */);
+    ASSERT_TRUE(attData.result.isOk())
+            << attData.result.exceptionCode() << "; " << attData.result.exceptionMessage() << endl;
+
+    // This is kinda of a hack but we need to give the size of
+    // ProofOfProvisioning that we'll expect to receive.
+    const int32_t expectedProofOfProvisioningSize = 230;
+    // OK to fail, not available in v1 HAL
+    writableCredential->setExpectedProofOfProvisioningSize(expectedProofOfProvisioningSize);
+    ASSERT_TRUE(
+            writableCredential->startPersonalization(testProfiles.size(), testEntriesEntryCounts)
+                    .isOk());
+
+    optional<vector<SecureAccessControlProfile>> secureProfiles =
+            test_utils::addAccessControlProfiles(writableCredential, testProfiles);
+    ASSERT_TRUE(secureProfiles);
+
+    // Uses TestEntryData* pointer as key and values are the encrypted blobs. This
+    // is a little hacky but it works well enough.
+    map<const test_utils::TestEntryData*, vector<vector<uint8_t>>> encryptedBlobs;
+
+    for (const auto& entry : testEntries) {
+        ASSERT_TRUE(test_utils::addEntry(writableCredential, entry, hwInfo.dataChunkSize,
+                                         encryptedBlobs, true));
+    }
+
+    vector<uint8_t> credentialData;
+    vector<uint8_t> proofOfProvisioningSignature;
+    ASSERT_TRUE(
+            writableCredential->finishAddingEntries(&credentialData, &proofOfProvisioningSignature)
+                    .isOk());
+
+    // Validate the proofOfProvisioning which was returned
+    optional<vector<uint8_t>> proofOfProvisioning =
+            support::coseSignGetPayload(proofOfProvisioningSignature);
+    ASSERT_TRUE(proofOfProvisioning);
+    cborPretty = cppbor::prettyPrint(proofOfProvisioning.value(), 32, {"readerCertificate"});
+    EXPECT_EQ(
+            "[\n"
+            "  'ProofOfProvisioning',\n"
+            "  'org.iso.18013-5.2019.mdl',\n"
+            "  [\n"
+            "    {\n"
+            "      'id' : 0,\n"
+            "    },\n"
+            "  ],\n"
+            "  {\n"
+            "    'PersonalData' : [\n"
+            "      {\n"
+            "        'name' : 'Last name',\n"
+            "        'value' : 'Turing',\n"
+            "        'accessControlProfiles' : [0, ],\n"
+            "      },\n"
+            "      {\n"
+            "        'name' : 'Birth date',\n"
+            "        'value' : '19120623',\n"
+            "        'accessControlProfiles' : [0, ],\n"
+            "      },\n"
+            "      {\n"
+            "        'name' : 'First name',\n"
+            "        'value' : 'Alan',\n"
+            "        'accessControlProfiles' : [0, ],\n"
+            "      },\n"
+            "    ],\n"
+            "  },\n"
+            "  true,\n"
+            "]",
+            cborPretty);
+
+    optional<vector<uint8_t>> credentialPubKey = support::certificateChainGetTopMostKey(
+            attData.attestationCertificate[0].encodedCertificate);
+    ASSERT_TRUE(credentialPubKey);
+    EXPECT_TRUE(support::coseCheckEcDsaSignature(proofOfProvisioningSignature,
+                                                 {},  // Additional data
+                                                 credentialPubKey.value()));
+    writableCredential = nullptr;
+
+    // Extract doctype, storage key, and credentialPrivKey from credentialData... this works
+    // only because we asked for a test-credential meaning that the HBK is all zeroes.
+    auto [exSuccess, exDocType, exStorageKey, exCredentialPrivKey, exSha256Pop] =
+            extractFromTestCredentialData(credentialData);
+
+    ASSERT_TRUE(exSuccess);
+    ASSERT_EQ(exDocType, "org.iso.18013-5.2019.mdl");
+    // ... check that the public key derived from the private key matches what was
+    // in the certificate.
+    optional<vector<uint8_t>> exCredentialKeyPair =
+            support::ecPrivateKeyToKeyPair(exCredentialPrivKey);
+    ASSERT_TRUE(exCredentialKeyPair);
+    optional<vector<uint8_t>> exCredentialPubKey =
+            support::ecKeyPairGetPublicKey(exCredentialKeyPair.value());
+    ASSERT_TRUE(exCredentialPubKey);
+    ASSERT_EQ(exCredentialPubKey.value(), credentialPubKey.value());
+
+    sp<IIdentityCredential> credential;
+    ASSERT_TRUE(credentialStore_
+                        ->getCredential(
+                                CipherSuite::CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256,
+                                credentialData, &credential)
+                        .isOk());
+    ASSERT_NE(credential, nullptr);
+
+    // Calculate sessionTranscript, make something that resembles what you'd use for
+    // an over-the-Internet presentation not using mdoc session encryption.
+    cppbor::Array sessionTranscript =
+            cppbor::Array()
+                    .add(cppbor::Null())  // DeviceEngagementBytes isn't used.
+                    .add(cppbor::Null())  // EReaderKeyBytes isn't used.
+                    .add(cppbor::Array()  // Proprietary handover structure follows.
+                                 .add(cppbor::Tstr("TestHandover"))
+                                 .add(cppbor::Bstr(vector<uint8_t>{1, 2, 3}))
+                                 .add(cppbor::Bstr(vector<uint8_t>{9, 8, 7, 6})));
+    vector<uint8_t> sessionTranscriptEncoded = sessionTranscript.encode();
+
+    // Generate the key that will be used to sign AuthenticatedData.
+    vector<uint8_t> signingKeyBlob;
+    Certificate signingKeyCertificate;
+    ASSERT_TRUE(credential->generateSigningKeyPair(&signingKeyBlob, &signingKeyCertificate).isOk());
+    optional<vector<uint8_t>> signingPubKey =
+            support::certificateChainGetTopMostKey(signingKeyCertificate.encodedCertificate);
+    EXPECT_TRUE(signingPubKey);
+    test_utils::verifyAuthKeyCertificate(signingKeyCertificate.encodedCertificate);
+
+    vector<RequestNamespace> requestedNamespaces = test_utils::buildRequestNamespaces(testEntries);
+    ASSERT_TRUE(credential->setRequestedNamespaces(requestedNamespaces).isOk());
+    ASSERT_TRUE(credential->setVerificationToken(verificationToken).isOk());
+    Status status = credential->startRetrieval(
+            secureProfiles.value(), authToken, {} /* itemsRequestBytes*/, signingKeyBlob,
+            sessionTranscriptEncoded, {} /* readerSignature */, testEntriesEntryCounts);
+    ASSERT_TRUE(status.isOk()) << status.exceptionCode() << ": " << status.exceptionMessage();
+
+    for (const auto& entry : testEntries) {
+        ASSERT_TRUE(credential
+                            ->startRetrieveEntryValue(entry.nameSpace, entry.name,
+                                                      entry.valueCbor.size(), entry.profileIds)
+                            .isOk());
+
+        auto it = encryptedBlobs.find(&entry);
+        ASSERT_NE(it, encryptedBlobs.end());
+        const vector<vector<uint8_t>>& encryptedChunks = it->second;
+
+        vector<uint8_t> content;
+        for (const auto& encryptedChunk : encryptedChunks) {
+            vector<uint8_t> chunk;
+            ASSERT_TRUE(credential->retrieveEntryValue(encryptedChunk, &chunk).isOk());
+            content.insert(content.end(), chunk.begin(), chunk.end());
+        }
+        EXPECT_EQ(content, entry.valueCbor);
+    }
+
+    vector<uint8_t> mac;
+    vector<uint8_t> ecdsaSignature;
+    vector<uint8_t> deviceNameSpacesEncoded;
+    status = credential->finishRetrievalWithSignature(&mac, &deviceNameSpacesEncoded,
+                                                      &ecdsaSignature);
+    ASSERT_TRUE(status.isOk()) << status.exceptionCode() << ": " << status.exceptionMessage();
+    // MACing should NOT work since we're not using session encryption
+    ASSERT_EQ(0, mac.size());
+
+    // ECDSA signatures should work, however. Check this.
+    ASSERT_GT(ecdsaSignature.size(), 0);
+
+    cborPretty = cppbor::prettyPrint(deviceNameSpacesEncoded, 32, {});
+    ASSERT_EQ(
+            "{\n"
+            "  'PersonalData' : {\n"
+            "    'Last name' : 'Turing',\n"
+            "    'Birth date' : '19120623',\n"
+            "    'First name' : 'Alan',\n"
+            "  },\n"
+            "}",
+            cborPretty);
+
+    string docType = "org.iso.18013-5.2019.mdl";
+
+    vector<uint8_t> encodedDeviceAuthentication =
+            cppbor::Array()
+                    .add("DeviceAuthentication")
+                    .add(sessionTranscript.clone())
+                    .add(docType)
+                    .add(cppbor::SemanticTag(24, deviceNameSpacesEncoded))
+                    .encode();
+    vector<uint8_t> deviceAuthenticationBytes =
+            cppbor::SemanticTag(24, encodedDeviceAuthentication).encode();
+    EXPECT_TRUE(support::coseCheckEcDsaSignature(ecdsaSignature,
+                                                 deviceAuthenticationBytes,  // Detached content
+                                                 signingPubKey.value()));
 }
 
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EndToEndTests);
diff --git a/radio/aidl/Android.bp b/radio/aidl/Android.bp
index 9dbe09a..930b6d4 100644
--- a/radio/aidl/Android.bp
+++ b/radio/aidl/Android.bp
@@ -12,6 +12,7 @@
     vendor_available: true,
     host_supported: true,
     srcs: ["android/hardware/radio/*.aidl"],
+    frozen: false,
     stability: "vintf",
     backend: {
         cpp: {
@@ -35,6 +36,7 @@
     vendor_available: true,
     host_supported: true,
     srcs: ["android/hardware/radio/config/*.aidl"],
+    frozen: false,
     stability: "vintf",
     imports: ["android.hardware.radio-V2"],
     backend: {
diff --git a/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/ISensors.aidl b/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/ISensors.aidl
index f60f5bb..b26040b 100644
--- a/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/ISensors.aidl
+++ b/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/ISensors.aidl
@@ -58,6 +58,8 @@
   const int DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_DATA = 24;
   const int DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_RESERVED = 88;
   const int DIRECT_REPORT_SENSOR_EVENT_TOTAL_LENGTH = 104;
+  const int RUNTIME_SENSORS_HANDLE_BASE = 1593835520;
+  const int RUNTIME_SENSORS_HANDLE_END = 1610612735;
   @Backing(type="int") @VintfStability
   enum RateLevel {
     STOP = 0,
diff --git a/sensors/aidl/android/hardware/sensors/ISensors.aidl b/sensors/aidl/android/hardware/sensors/ISensors.aidl
index 2c68489..5e276dd 100644
--- a/sensors/aidl/android/hardware/sensors/ISensors.aidl
+++ b/sensors/aidl/android/hardware/sensors/ISensors.aidl
@@ -371,4 +371,13 @@
     const int DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_DATA = 0x18;
     const int DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_RESERVED = 0x58;
     const int DIRECT_REPORT_SENSOR_EVENT_TOTAL_LENGTH = 104;
+
+    /**
+     * Constants related to reserved sensor handle ranges.
+     *
+     * The following range (inclusive) is reserved for usage by the system for
+     * runtime sensors.
+     */
+    const int RUNTIME_SENSORS_HANDLE_BASE = 0x5F000000;
+    const int RUNTIME_SENSORS_HANDLE_END = 0x5FFFFFFF;
 }
diff --git a/sensors/aidl/convert/Android.bp b/sensors/aidl/convert/Android.bp
index 0b31597..53060b9 100644
--- a/sensors/aidl/convert/Android.bp
+++ b/sensors/aidl/convert/Android.bp
@@ -35,7 +35,7 @@
         "libhardware",
         "libbase",
         "libutils",
-        "android.hardware.sensors-V1-ndk",
+        "android.hardware.sensors-V2-ndk",
     ],
     whole_static_libs: [
         "sensors_common_convert",
diff --git a/sensors/aidl/default/Android.bp b/sensors/aidl/default/Android.bp
index 3c66744..16b4d35 100644
--- a/sensors/aidl/default/Android.bp
+++ b/sensors/aidl/default/Android.bp
@@ -41,7 +41,7 @@
         "libfmq",
         "libpower",
         "libbinder_ndk",
-        "android.hardware.sensors-V1-ndk",
+        "android.hardware.sensors-V2-ndk",
     ],
     export_include_dirs: ["include"],
     srcs: [
@@ -68,7 +68,7 @@
         "libcutils",
         "liblog",
         "libutils",
-        "android.hardware.sensors-V1-ndk",
+        "android.hardware.sensors-V2-ndk",
     ],
     static_libs: [
         "libsensorsexampleimpl",
diff --git a/sensors/aidl/default/multihal/Android.bp b/sensors/aidl/default/multihal/Android.bp
index eee1062..a20d6d7 100644
--- a/sensors/aidl/default/multihal/Android.bp
+++ b/sensors/aidl/default/multihal/Android.bp
@@ -38,7 +38,7 @@
         "android.hardware.sensors@1.0",
         "android.hardware.sensors@2.0",
         "android.hardware.sensors@2.1",
-        "android.hardware.sensors-V1-ndk",
+        "android.hardware.sensors-V2-ndk",
     ],
     export_include_dirs: ["include"],
     srcs: [
diff --git a/sensors/aidl/default/sensors-default.xml b/sensors/aidl/default/sensors-default.xml
index 7898a6b..36b28ed 100644
--- a/sensors/aidl/default/sensors-default.xml
+++ b/sensors/aidl/default/sensors-default.xml
@@ -1,7 +1,7 @@
 <manifest version="1.0" type="device">
     <hal format="aidl">
         <name>android.hardware.sensors</name>
-        <version>1</version>
+        <version>2</version>
         <fqname>ISensors/default</fqname>
     </hal>
 </manifest>
diff --git a/sensors/aidl/multihal/Android.bp b/sensors/aidl/multihal/Android.bp
index 6d35daf..522d305 100644
--- a/sensors/aidl/multihal/Android.bp
+++ b/sensors/aidl/multihal/Android.bp
@@ -40,7 +40,7 @@
         "android.hardware.sensors@2.0-ScopedWakelock",
         "android.hardware.sensors@2.0",
         "android.hardware.sensors@2.1",
-        "android.hardware.sensors-V1-ndk",
+        "android.hardware.sensors-V2-ndk",
         "libbase",
         "libcutils",
         "libfmq",
diff --git a/sensors/aidl/multihal/android.hardware.sensors-multihal.xml b/sensors/aidl/multihal/android.hardware.sensors-multihal.xml
index d78edff..5da4fbd 100644
--- a/sensors/aidl/multihal/android.hardware.sensors-multihal.xml
+++ b/sensors/aidl/multihal/android.hardware.sensors-multihal.xml
@@ -17,7 +17,7 @@
 <manifest version="1.0" type="device">
     <hal format="aidl">
         <name>android.hardware.sensors</name>
-        <version>1</version>
+        <version>2</version>
         <fqname>ISensors/default</fqname>
     </hal>
 </manifest>
diff --git a/sensors/aidl/vts/Android.bp b/sensors/aidl/vts/Android.bp
index f3972ec..c17a558 100644
--- a/sensors/aidl/vts/Android.bp
+++ b/sensors/aidl/vts/Android.bp
@@ -41,7 +41,7 @@
         "android.hardware.common.fmq-V1-ndk",
     ],
     static_libs: [
-        "android.hardware.sensors-V1-ndk",
+        "android.hardware.sensors-V2-ndk",
         "VtsHalSensorsTargetTestUtils",
         "libaidlcommonsupport",
     ],
diff --git a/sensors/aidl/vts/VtsAidlHalSensorsTargetTest.cpp b/sensors/aidl/vts/VtsAidlHalSensorsTargetTest.cpp
index d536e29..ad58e21 100644
--- a/sensors/aidl/vts/VtsAidlHalSensorsTargetTest.cpp
+++ b/sensors/aidl/vts/VtsAidlHalSensorsTargetTest.cpp
@@ -560,10 +560,15 @@
             EXPECT_NO_FATAL_FAILURE(assertTypeMatchStringType(info.type, info.typeAsString));
         }
 
-        // Test if all sensor has name and vendor
+        // Test if all sensors have name and vendor
         EXPECT_FALSE(info.name.empty());
         EXPECT_FALSE(info.vendor.empty());
 
+        // Make sure that the sensor handle is not within the reserved range for runtime
+        // sensors.
+        EXPECT_FALSE(ISensors::RUNTIME_SENSORS_HANDLE_BASE <= info.sensorHandle &&
+                     info.sensorHandle <= ISensors::RUNTIME_SENSORS_HANDLE_END);
+
         // Make sure that sensors of the same type have a unique name.
         std::vector<std::string>& v = sensorTypeNameMap[static_cast<int32_t>(info.type)];
         bool isUniqueName = std::find(v.begin(), v.end(), info.name) == v.end();
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiChip.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiChip.aidl
index 647891f..f800e8f 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiChip.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiChip.aidl
@@ -59,6 +59,7 @@
   @PropagateAllowBlocking android.hardware.wifi.IWifiStaIface getStaIface(in String ifname);
   String[] getStaIfaceNames();
   android.hardware.wifi.WifiRadioCombinationMatrix getSupportedRadioCombinationsMatrix();
+  android.hardware.wifi.WifiChipCapabilities getWifiChipCapabilities();
   android.hardware.wifi.WifiUsableChannel[] getUsableChannels(in android.hardware.wifi.WifiBand band, in android.hardware.wifi.WifiIfaceMode ifaceModeMask, in android.hardware.wifi.IWifiChip.UsableChannelFilter filterMask);
   void registerEventCallback(in android.hardware.wifi.IWifiChipEventCallback callback);
   void removeApIface(in String ifname);
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiChipCapabilities.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiChipCapabilities.aidl
new file mode 100644
index 0000000..48dc8e0
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiChipCapabilities.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.wifi;
+@VintfStability
+parcelable WifiChipCapabilities {
+  int maxMloLinkCount;
+  int maxConcurrentTdlsSessionCount;
+}
diff --git a/wifi/aidl/android/hardware/wifi/IWifiChip.aidl b/wifi/aidl/android/hardware/wifi/IWifiChip.aidl
index fe9a6f3..64692af 100644
--- a/wifi/aidl/android/hardware/wifi/IWifiChip.aidl
+++ b/wifi/aidl/android/hardware/wifi/IWifiChip.aidl
@@ -25,6 +25,7 @@
 import android.hardware.wifi.IfaceConcurrencyType;
 import android.hardware.wifi.IfaceType;
 import android.hardware.wifi.WifiBand;
+import android.hardware.wifi.WifiChipCapabilities;
 import android.hardware.wifi.WifiDebugHostWakeReasonStats;
 import android.hardware.wifi.WifiDebugRingBufferStatus;
 import android.hardware.wifi.WifiDebugRingBufferVerboseLevel;
@@ -785,6 +786,18 @@
     WifiRadioCombinationMatrix getSupportedRadioCombinationsMatrix();
 
     /**
+     * Get capabilities supported by this chip.
+     *
+     * @return Chip capabilities represented by |WifiChipCapabilities|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.FAILURE_UNKNOWN|
+     *
+     */
+    WifiChipCapabilities getWifiChipCapabilities();
+
+    /**
      * Retrieve a list of usable Wifi channels for the specified band &
      * operational modes.
      *
diff --git a/wifi/aidl/android/hardware/wifi/WifiChipCapabilities.aidl b/wifi/aidl/android/hardware/wifi/WifiChipCapabilities.aidl
new file mode 100644
index 0000000..f65d49a
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiChipCapabilities.aidl
@@ -0,0 +1,37 @@
+/*
+ * 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.wifi;
+
+/**
+ * WifiChipCapabilities captures various Wifi chip capability params.
+ */
+@VintfStability
+parcelable WifiChipCapabilities {
+    /**
+     * Maximum number of links used in Multi-Link Operation. The maximum
+     * number of links used for MLO can be different from the number of
+     * radios supported by the chip.
+     *
+     * This is a static configuration of the chip.
+     */
+    int maxMloLinkCount;
+    /**
+     * Maximum number of concurrent TDLS sessions that can be enabled
+     * by framework via ISupplicantStaIface#initiateTdlsSetup().
+     */
+    int maxConcurrentTdlsSessionCount;
+}
diff --git a/wifi/aidl/default/aidl_struct_util.cpp b/wifi/aidl/default/aidl_struct_util.cpp
index 07612b6..ec8b396 100644
--- a/wifi/aidl/default/aidl_struct_util.cpp
+++ b/wifi/aidl/default/aidl_struct_util.cpp
@@ -2768,6 +2768,15 @@
     return true;
 }
 
+bool convertLegacyWifiChipCapabilitiesToAidl(
+        const legacy_hal::wifi_chip_capabilities& legacy_chip_capabilities,
+        WifiChipCapabilities& aidl_chip_capabilities) {
+    aidl_chip_capabilities.maxMloLinkCount = legacy_chip_capabilities.max_mlo_link_count;
+    aidl_chip_capabilities.maxConcurrentTdlsSessionCount =
+            legacy_chip_capabilities.max_concurrent_tdls_session_count;
+    return true;
+}
+
 }  // namespace aidl_struct_util
 }  // namespace wifi
 }  // namespace hardware
diff --git a/wifi/aidl/default/aidl_struct_util.h b/wifi/aidl/default/aidl_struct_util.h
index 4ebfc10..d8e1fd4 100644
--- a/wifi/aidl/default/aidl_struct_util.h
+++ b/wifi/aidl/default/aidl_struct_util.h
@@ -171,6 +171,9 @@
                                       StaPeerInfo* aidl_peer_info_stats);
 bool convertLegacyWifiRateInfoToAidl(const legacy_hal::wifi_rate& legacy_rate,
                                      WifiRateInfo* aidl_rate);
+bool convertLegacyWifiChipCapabilitiesToAidl(
+        const legacy_hal::wifi_chip_capabilities& legacy_chip_capabilities,
+        WifiChipCapabilities& aidl_chip_capabilities);
 }  // namespace aidl_struct_util
 }  // namespace wifi
 }  // namespace hardware
diff --git a/wifi/aidl/default/wifi_chip.cpp b/wifi/aidl/default/wifi_chip.cpp
index 076f351..4061699 100644
--- a/wifi/aidl/default/wifi_chip.cpp
+++ b/wifi/aidl/default/wifi_chip.cpp
@@ -680,6 +680,11 @@
                            &WifiChip::getSupportedRadioCombinationsMatrixInternal, _aidl_return);
 }
 
+ndk::ScopedAStatus WifiChip::getWifiChipCapabilities(WifiChipCapabilities* _aidl_return) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::getWifiChipCapabilitiesInternal, _aidl_return);
+}
+
 void WifiChip::invalidateAndRemoveAllIfaces() {
     invalidateAndClearBridgedApAll();
     invalidateAndClearAll(ap_ifaces_);
@@ -1403,6 +1408,26 @@
     return {aidl_matrix, ndk::ScopedAStatus::ok()};
 }
 
+std::pair<WifiChipCapabilities, ndk::ScopedAStatus> WifiChip::getWifiChipCapabilitiesInternal() {
+    legacy_hal::wifi_error legacy_status;
+    legacy_hal::wifi_chip_capabilities legacy_chip_capabilities;
+    std::tie(legacy_status, legacy_chip_capabilities) =
+            legacy_hal_.lock()->getWifiChipCapabilities();
+    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+        LOG(ERROR) << "Failed to get chip capabilities from legacy HAL: "
+                   << legacyErrorToString(legacy_status);
+        return {WifiChipCapabilities(), createWifiStatusFromLegacyError(legacy_status)};
+    }
+    WifiChipCapabilities aidl_chip_capabilities;
+    if (!aidl_struct_util::convertLegacyWifiChipCapabilitiesToAidl(legacy_chip_capabilities,
+                                                                   aidl_chip_capabilities)) {
+        LOG(ERROR) << "Failed convertLegacyWifiChipCapabilitiesToAidl() ";
+        return {WifiChipCapabilities(), createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS)};
+    }
+
+    return {aidl_chip_capabilities, ndk::ScopedAStatus::ok()};
+}
+
 ndk::ScopedAStatus WifiChip::triggerSubsystemRestartInternal() {
     auto legacy_status = legacy_hal_.lock()->triggerSubsystemRestart();
     return createWifiStatusFromLegacyError(legacy_status);
diff --git a/wifi/aidl/default/wifi_chip.h b/wifi/aidl/default/wifi_chip.h
index 59eaa4a..7b04e85 100644
--- a/wifi/aidl/default/wifi_chip.h
+++ b/wifi/aidl/default/wifi_chip.h
@@ -144,6 +144,7 @@
     ndk::ScopedAStatus triggerSubsystemRestart() override;
     ndk::ScopedAStatus getSupportedRadioCombinationsMatrix(
             WifiRadioCombinationMatrix* _aidl_return) override;
+    ndk::ScopedAStatus getWifiChipCapabilities(WifiChipCapabilities* _aidl_return) override;
     binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
 
   private:
@@ -250,6 +251,7 @@
     ndk::ScopedAStatus triggerSubsystemRestartInternal();
     std::pair<WifiRadioCombinationMatrix, ndk::ScopedAStatus>
     getSupportedRadioCombinationsMatrixInternal();
+    std::pair<WifiChipCapabilities, ndk::ScopedAStatus> getWifiChipCapabilitiesInternal();
     void setWeakPtr(std::weak_ptr<WifiChip> ptr);
 
     int32_t chip_id_;
diff --git a/wifi/aidl/default/wifi_legacy_hal.cpp b/wifi/aidl/default/wifi_legacy_hal.cpp
index 43e73ca..e4883d1 100644
--- a/wifi/aidl/default/wifi_legacy_hal.cpp
+++ b/wifi/aidl/default/wifi_legacy_hal.cpp
@@ -1609,6 +1609,13 @@
     return status;
 }
 
+std::pair<wifi_error, wifi_chip_capabilities> WifiLegacyHal::getWifiChipCapabilities() {
+    wifi_chip_capabilities chip_capabilities;
+    wifi_error status =
+            global_func_table_.wifi_get_chip_capabilities(global_handle_, &chip_capabilities);
+    return {status, chip_capabilities};
+}
+
 void WifiLegacyHal::invalidate() {
     global_handle_ = nullptr;
     iface_name_to_handle_.clear();
diff --git a/wifi/aidl/default/wifi_legacy_hal.h b/wifi/aidl/default/wifi_legacy_hal.h
index cd8c0b1..33ed359 100644
--- a/wifi/aidl/default/wifi_legacy_hal.h
+++ b/wifi/aidl/default/wifi_legacy_hal.h
@@ -232,6 +232,7 @@
 using ::wifi_channel_info;
 using ::wifi_channel_stat;
 using ::wifi_channel_width;
+using ::wifi_chip_capabilities;
 using ::wifi_coex_restriction;
 using ::wifi_coex_unsafe_channel;
 using ::WIFI_DUAL_STA_NON_TRANSIENT_UNBIASED;
@@ -693,6 +694,7 @@
     wifi_error enableWifiTxPowerLimits(const std::string& iface_name, bool enable);
     wifi_error getWifiCachedScanResults(const std::string& iface_name,
                                         const CachedScanResultsCallbackHandlers& handler);
+    std::pair<wifi_error, wifi_chip_capabilities> getWifiChipCapabilities();
 
   private:
     // Retrieve interface handles for all the available interfaces.
diff --git a/wifi/aidl/default/wifi_legacy_hal_stubs.cpp b/wifi/aidl/default/wifi_legacy_hal_stubs.cpp
index cff7f69..7777894 100644
--- a/wifi/aidl/default/wifi_legacy_hal_stubs.cpp
+++ b/wifi/aidl/default/wifi_legacy_hal_stubs.cpp
@@ -167,6 +167,7 @@
     populateStubFor(&hal_fn->wifi_chre_register_handler);
     populateStubFor(&hal_fn->wifi_enable_tx_power_limits);
     populateStubFor(&hal_fn->wifi_get_cached_scan_results);
+    populateStubFor(&hal_fn->wifi_get_chip_capabilities);
     return true;
 }
 
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl
index 6276a35..f9a078b 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl
@@ -39,4 +39,5 @@
   oneway void onNetworkEapSimUmtsAuthRequest(in android.hardware.wifi.supplicant.NetworkRequestEapSimUmtsAuthParams params);
   oneway void onTransitionDisable(in android.hardware.wifi.supplicant.TransitionDisableIndication ind);
   oneway void onServerCertificateAvailable(in int depth, in byte[] subject, in byte[] certHash, in byte[] certBlob);
+  oneway void onPermanentIdReqDenied();
 }
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl
index de7b675..4f892be 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl
@@ -71,4 +71,11 @@
      */
     void onServerCertificateAvailable(
             in int depth, in byte[] subject, in byte[] certHash, in byte[] certBlob);
+
+    /**
+     * Used to notify the AT_PERMANENT_ID_REQ denied event.
+     *
+     * In strict conservative mode, AT_PERMANENT_ID_REQ is denied from eap_peer side.
+     */
+    void onPermanentIdReqDenied();
 }
diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_sta_network_aidl_test.cpp b/wifi/supplicant/aidl/vts/functional/supplicant_sta_network_aidl_test.cpp
index 6ff64a5..0aebe6d 100644
--- a/wifi/supplicant/aidl/vts/functional/supplicant_sta_network_aidl_test.cpp
+++ b/wifi/supplicant/aidl/vts/functional/supplicant_sta_network_aidl_test.cpp
@@ -100,6 +100,7 @@
             const std::vector<uint8_t>& /* certBlob */) override {
         return ndk::ScopedAStatus::ok();
     }
+    ::ndk::ScopedAStatus onPermanentIdReqDenied() override { return ndk::ScopedAStatus::ok(); }
 };
 
 class SupplicantStaNetworkAidlTest