AudioHal: adapt effect_param_t handling with AIDL

Bug: 258124419
Test: atest EffectParamWrapper_tests
Test: Enable AIDL and build, run cts
Test: atest EffectsFactoryHalInterfaceTest

Change-Id: I404122422d4be70f6f24a1b4e40548fed41110b9
diff --git a/media/libaudiohal/impl/EffectConversionHelperAidl.cpp b/media/libaudiohal/impl/EffectConversionHelperAidl.cpp
index 493d1ee..ec8abd7 100644
--- a/media/libaudiohal/impl/EffectConversionHelperAidl.cpp
+++ b/media/libaudiohal/impl/EffectConversionHelperAidl.cpp
@@ -16,12 +16,27 @@
 
 #include <cstdint>
 #include <cstring>
+#include <optional>
 #define LOG_TAG "EffectConversionHelperAidl"
 //#define LOG_NDEBUG 0
 
 #include <error/expected_utils.h>
 #include <media/audiohal/AudioEffectUuid.h>
-#include <system/audio_effects/audio_effects_utils.h>
+#include <system/audio_effects/effect_aec.h>
+#include <system/audio_effects/effect_agc2.h>
+#include <system/audio_effects/effect_bassboost.h>
+#include <system/audio_effects/effect_downmix.h>
+#include <system/audio_effects/effect_dynamicsprocessing.h>
+#include <system/audio_effects/effect_environmentalreverb.h>
+#include <system/audio_effects/effect_equalizer.h>
+#include <system/audio_effects/effect_hapticgenerator.h>
+#include <system/audio_effects/effect_loudnessenhancer.h>
+#include <system/audio_effects/effect_ns.h>
+#include <system/audio_effects/effect_presetreverb.h>
+#include <system/audio_effects/effect_spatializer.h>
+#include <system/audio_effects/effect_virtualizer.h>
+#include <system/audio_effects/effect_visualizer.h>
+
 #include <utils/Log.h>
 
 #include "EffectConversionHelperAidl.h"
@@ -31,10 +46,16 @@
 
 using ::aidl::android::aidl_utils::statusTFromBinderStatus;
 using ::aidl::android::hardware::audio::effect::AcousticEchoCanceler;
+using ::aidl::android::hardware::audio::effect::AutomaticGainControl;
+using ::aidl::android::hardware::audio::effect::BassBoost;
 using ::aidl::android::hardware::audio::effect::CommandId;
+using ::aidl::android::hardware::audio::effect::Descriptor;
+using ::aidl::android::hardware::audio::effect::Downmix;
 using ::aidl::android::hardware::audio::effect::Parameter;
 using ::aidl::android::media::audio::common::AudioDeviceDescription;
 using ::aidl::android::media::audio::common::AudioUuid;
+using android::effect::utils::EffectParamReader;
+using android::effect::utils::EffectParamWriter;
 
 using ::android::status_t;
 
@@ -59,8 +80,26 @@
         EffectConversionHelperAidl::mParameterHandlerMap = {
                 {kAcousticEchoCancelerTypeUUID,
                  {&EffectConversionHelperAidl::setAecParameter,
-                  &EffectConversionHelperAidl::getAecParameter}}};
+                  &EffectConversionHelperAidl::getAecParameter}},
+                {kAutomaticGainControlTypeUUID,
+                 {&EffectConversionHelperAidl::setAgcParameter,
+                  &EffectConversionHelperAidl::getAgcParameter}},
+                {kBassBoostTypeUUID,
+                 {&EffectConversionHelperAidl::setBassBoostParameter,
+                  &EffectConversionHelperAidl::getBassBoostParameter}},
+                {kDownmixTypeUUID,
+                 {&EffectConversionHelperAidl::setDownmixParameter,
+                  &EffectConversionHelperAidl::getDownmixParameter}}};
 
+EffectConversionHelperAidl::EffectConversionHelperAidl(
+        std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> effect,
+        int32_t sessionId, int32_t ioId,
+        const ::aidl::android::hardware::audio::effect::Descriptor& desc)
+    : mSessionId(sessionId), mIoId(ioId), mDesc(desc), mEffect(std::move(effect)) {
+    mCommon.session = sessionId;
+    mCommon.ioHandle = ioId;
+    mCommon.input = mCommon.output = kDefaultAudioConfig;
+}
 
 status_t EffectConversionHelperAidl::handleCommand(uint32_t cmdCode, uint32_t cmdSize,
                                                    void* pCmdData, uint32_t* replySize,
@@ -80,84 +119,87 @@
         return BAD_VALUE;
     }
 
-    return *(status_t*)pReplyData = OK;
+    return *(status_t*)pReplyData =
+                   statusTFromBinderStatus(mEffect->open(mCommon, std::nullopt, &mOpenReturn));
 }
 
 status_t EffectConversionHelperAidl::handleSetParameter(uint32_t cmdSize, const void* pCmdData,
                                                         uint32_t* replySize, void* pReplyData) {
-    if (cmdSize < kEffectParamSize || !pCmdData || !replySize || *replySize < sizeof(int) ||
-        !pReplyData) {
+    if (cmdSize < sizeof(effect_param_t) || !pCmdData || !replySize ||
+        *replySize < sizeof(int) || !pReplyData) {
         return BAD_VALUE;
     }
 
-    const effect_param_t* param = (effect_param_t*)pCmdData;
-    if (!validateCommandSize(*param, cmdSize)) {
-        ALOGE("%s illegal param %s size %u", __func__, utils::toString(*param).c_str(), cmdSize);
+    auto reader = EffectParamReader(*(effect_param_t*)pCmdData);
+    if (!reader.validateCmdSize(cmdSize)) {
+        ALOGE("%s illegal param %s size %u", __func__, reader.toString().c_str(), cmdSize);
         return BAD_VALUE;
     }
 
-    const auto& handler = mParameterHandlerMap.find(mTypeUuid);
+    const auto& handler = mParameterHandlerMap.find(mDesc.common.id.type);
     if (handler == mParameterHandlerMap.end() || !handler->second.first) {
-        ALOGE("%s handler for uuid %s not found", __func__, mTypeUuid.toString().c_str());
+        ALOGE("%s handler for uuid %s not found", __func__,
+              mDesc.common.id.type.toString().c_str());
         return BAD_VALUE;
     }
     const SetParameter& functor = handler->second.first;
-    return *(status_t*)pReplyData = (this->*functor)(*(const effect_param_t*)param);
+    return *(status_t*)pReplyData = (this->*functor)(reader);
 }
 
 status_t EffectConversionHelperAidl::handleGetParameter(uint32_t cmdSize, const void* pCmdData,
                                                         uint32_t* replySize, void* pReplyData) {
-    if (cmdSize < kEffectParamSize || !pCmdData || !replySize || !pReplyData) {
+    if (cmdSize < sizeof(effect_param_t) || !pCmdData || !replySize || !pReplyData) {
         return BAD_VALUE;
     }
 
-    const effect_param_t* param = (effect_param_t*)pCmdData;
-    if (!validateCommandSize(*param, *replySize)) {
-        ALOGE("%s illegal param %s, replysize %u", __func__, utils::toString(*param).c_str(),
+    const auto reader = EffectParamReader(*(effect_param_t*)pCmdData);
+    if (!reader.validateCmdSize(cmdSize)) {
+        ALOGE("%s illegal param %s, replysize %u", __func__, reader.toString().c_str(),
               *replySize);
         return BAD_VALUE;
     }
 
-    const auto& handler = mParameterHandlerMap.find(mTypeUuid);
+    const auto& handler = mParameterHandlerMap.find(mDesc.common.id.type);
     if (handler == mParameterHandlerMap.end() || !handler->second.second) {
-        ALOGE("%s handler for uuid %s not found", __func__, mTypeUuid.toString().c_str());
+        ALOGE("%s handler for uuid %s not found", __func__,
+              mDesc.common.id.type.toString().c_str());
         return BAD_VALUE;
     }
     const GetParameter& functor = handler->second.second;
-    memcpy(pReplyData, pCmdData, sizeof(effect_param_t) + param->psize);
-    effect_param_t* reply = (effect_param_t *)pReplyData;
-    (this->*functor)(*reply);
-    *replySize = kEffectParamSize + padding(reply->psize) + reply->vsize;
-    return reply->status;
+    memcpy(pReplyData, pCmdData, sizeof(effect_param_t) + reader.getParameterSize());
+    auto writer = EffectParamWriter(*(effect_param_t *)pReplyData);
+    (this->*functor)(writer);
+    *replySize = writer.getTotalSize();
+    return writer.getStatus();
 }
 
 status_t EffectConversionHelperAidl::handleSetConfig(uint32_t cmdSize, const void* pCmdData,
                                                      uint32_t* replySize, void* pReplyData) {
-    if (!replySize || *replySize != sizeof(int) || !pReplyData || cmdSize != kEffectConfigSize) {
+    if (!replySize || *replySize != sizeof(int) || !pReplyData ||
+        cmdSize != sizeof(effect_config_t)) {
         return BAD_VALUE;
     }
 
     const auto& legacyConfig = static_cast<const effect_config_t*>(pCmdData);
     // already open, apply latest settings
-    Parameter::Common common;
-    common.input.base =
+    mCommon.input.base =
             VALUE_OR_RETURN_STATUS(::aidl::android::legacy2aidl_buffer_config_t_AudioConfigBase(
                     legacyConfig->inputCfg, true /* isInput */));
-    common.output.base =
+    mCommon.output.base =
             VALUE_OR_RETURN_STATUS(::aidl::android::legacy2aidl_buffer_config_t_AudioConfigBase(
                     legacyConfig->outputCfg, false /* isInput */));
-    common.session = mSessionId;
-    common.ioHandle = mIoId;
+    mCommon.session = mSessionId;
+    mCommon.ioHandle = mIoId;
     // TODO: add access mode support
     RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
-            mEffect->setParameter(Parameter::make<Parameter::common>(common))));
+            mEffect->setParameter(Parameter::make<Parameter::common>(mCommon))));
     return *static_cast<int32_t*>(pReplyData) = OK;
 }
 
 status_t EffectConversionHelperAidl::handleGetConfig(uint32_t cmdSize __unused,
                                                      const void* pCmdData __unused,
                                                      uint32_t* replySize, void* pReplyData) {
-    if (!replySize || *replySize != kEffectConfigSize || !pReplyData) {
+    if (!replySize || *replySize != sizeof(effect_config_t) || !pReplyData) {
         ALOGE("%s parameter invalid %p %p", __func__, replySize, pReplyData);
         return BAD_VALUE;
     }
@@ -179,43 +221,40 @@
 status_t EffectConversionHelperAidl::handleReset(uint32_t cmdSize __unused,
                                                  const void* pCmdData __unused, uint32_t* replySize,
                                                  void* pReplyData) {
-    if (!replySize || *replySize != kEffectConfigSize || !pReplyData) {
+    if (!replySize || *replySize != sizeof(effect_config_t) || !pReplyData) {
         ALOGE("%s parameter invalid %p %p", __func__, replySize, pReplyData);
         return BAD_VALUE;
     }
 
-    RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->command(CommandId::RESET)));
-    return OK;
+    return statusTFromBinderStatus(mEffect->command(CommandId::RESET));
 }
 
 status_t EffectConversionHelperAidl::handleEnable(uint32_t cmdSize __unused,
                                                  const void* pCmdData __unused, uint32_t* replySize,
                                                  void* pReplyData) {
-    if (!replySize || *replySize != kEffectConfigSize || !pReplyData) {
+    if (!replySize || *replySize != sizeof(effect_config_t) || !pReplyData) {
         ALOGE("%s parameter invalid %p %p", __func__, replySize, pReplyData);
         return BAD_VALUE;
     }
 
-    RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->command(CommandId::START)));
-    return OK;
+    return statusTFromBinderStatus(mEffect->command(CommandId::START));
 }
 
 status_t EffectConversionHelperAidl::handleDisable(uint32_t cmdSize __unused,
                                                    const void* pCmdData __unused,
                                                    uint32_t* replySize, void* pReplyData) {
-    if (!replySize || *replySize != kEffectConfigSize || !pReplyData) {
+    if (!replySize || *replySize != sizeof(effect_config_t) || !pReplyData) {
         ALOGE("%s parameter invalid %p %p", __func__, replySize, pReplyData);
         return BAD_VALUE;
     }
 
-    RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->command(CommandId::STOP)));
-    return OK;
+    return statusTFromBinderStatus(mEffect->command(CommandId::STOP));
 }
 
 status_t EffectConversionHelperAidl::handleSetDevice(uint32_t cmdSize, const void* pCmdData,
                                                      uint32_t* replySize, void* pReplyData) {
-    if (cmdSize != sizeof(uint32_t) || !pCmdData || !replySize || *replySize != kEffectConfigSize ||
-        !pReplyData) {
+    if (cmdSize != sizeof(uint32_t) || !pCmdData || !replySize ||
+        *replySize != sizeof(effect_config_t) || !pReplyData) {
         ALOGE("%s parameter invalid %u %p %p %p", __func__, cmdSize, pCmdData, replySize,
               pReplyData);
         return BAD_VALUE;
@@ -231,7 +270,7 @@
 status_t EffectConversionHelperAidl::handleSetVolume(uint32_t cmdSize, const void* pCmdData,
                                                      uint32_t* replySize, void* pReplyData) {
     if (cmdSize != 2 * sizeof(uint32_t) || !pCmdData || !replySize ||
-        *replySize != kEffectConfigSize || !pReplyData) {
+        *replySize != sizeof(effect_config_t) || !pReplyData) {
         ALOGE("%s parameter invalid %u %p %p %p", __func__, cmdSize, pCmdData, replySize,
               pReplyData);
         return BAD_VALUE;
@@ -246,7 +285,7 @@
 status_t EffectConversionHelperAidl::handleSetOffload(uint32_t cmdSize, const void* pCmdData,
                                                       uint32_t* replySize, void* pReplyData) {
     if (cmdSize < sizeof(effect_offload_param_t) || !pCmdData || !replySize ||
-        *replySize != kEffectConfigSize || !pReplyData) {
+        *replySize != sizeof(effect_config_t) || !pReplyData) {
         ALOGE("%s parameter invalid %u %p %p %p", __func__, cmdSize, pCmdData, replySize,
               pReplyData);
         return BAD_VALUE;
@@ -258,87 +297,270 @@
 status_t EffectConversionHelperAidl::handleFirstPriority(uint32_t cmdSize __unused,
                                                          const void* pCmdData __unused,
                                                          uint32_t* replySize, void* pReplyData) {
-    if (!replySize || *replySize != kEffectConfigSize || !pReplyData) {
+    if (!replySize || *replySize != sizeof(effect_config_t) || !pReplyData) {
         ALOGE("%s parameter invalid %p %p", __func__, replySize, pReplyData);
         return BAD_VALUE;
     }
 
-    // TODO
+    // TODO to be implemented
     return OK;
 }
 
-status_t EffectConversionHelperAidl::setAecParameter(const effect_param_t& param) {
-    const auto psize = sizeof(uint32_t);
-    const auto vsize = sizeof(uint32_t);
-    if (!validatePVsize(param, psize, vsize)) {
+status_t EffectConversionHelperAidl::setAecParameter(EffectParamReader& param) {
+    uint32_t type, value = 0;
+    if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint32_t)) ||
+        OK != param.readFromParameter(&type) ||
+        OK != param.readFromValue(&value)) {
+        ALOGW("%s invalid param %s", __func__, param.toString().c_str());
         return BAD_VALUE;
     }
 
-    const auto& type = *(uint32_t*)param.data;
-    const auto& value = *(uint32_t*)(param.data + psize);
     Parameter aidlParam;
     switch (type) {
         case AEC_PARAM_ECHO_DELAY:
             FALLTHROUGH_INTENDED;
         case AEC_PARAM_PROPERTIES: {
             aidlParam = VALUE_OR_RETURN_STATUS(
-                    aidl::android::legacy2aidl_uint32_echoDelay_Parameter(value));
+                    aidl::android::legacy2aidl_uint32_echoDelay_Parameter_aec(value));
             break;
         }
         case AEC_PARAM_MOBILE_MODE: {
             aidlParam = VALUE_OR_RETURN_STATUS(
-                    aidl::android::legacy2aidl_uint32_mobileMode_Parameter(value));
+                    aidl::android::legacy2aidl_uint32_mobileMode_Parameter_aec(value));
             break;
         }
         default: {
-            ALOGW("%s unknown param %08x value %08x", __func__, type, value);
+            ALOGW("%s unknown param %s", __func__, param.toString().c_str());
             return BAD_VALUE;
         }
     }
 
-    return mEffect->setParameter(aidlParam).getStatus();
+    return statusTFromBinderStatus(mEffect->setParameter(aidlParam));
 }
 
-status_t EffectConversionHelperAidl::getAecParameter(effect_param_t& param) {
-    const auto psize = sizeof(uint32_t);
-    const auto vsize = sizeof(uint32_t);
-    if (!validatePVsize(param, psize, vsize)) {
-        return param.status = BAD_VALUE;
+status_t EffectConversionHelperAidl::getAecParameter(EffectParamWriter& param) {
+    uint32_t type = 0, value = 0;
+    if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint32_t)) ||
+        OK != param.readFromParameter(&type) || OK != param.readFromValue(&value)) {
+        param.setStatus(BAD_VALUE);
+        ALOGW("%s invalid param %s", __func__, param.toString().c_str());
+        return BAD_VALUE;
     }
-
-    uint32_t value = 0;
-    status_t status = BAD_VALUE;
-    const auto& type = *(uint32_t*)param.data;
+    Parameter aidlParam;
     switch (type) {
         case AEC_PARAM_ECHO_DELAY:
             FALLTHROUGH_INTENDED;
         case AEC_PARAM_PROPERTIES: {
-            Parameter aidlParam;
-            Parameter::Id id = Parameter::Id::make<Parameter::Id::acousticEchoCancelerTag>(
-                    AcousticEchoCanceler::Id::make<AcousticEchoCanceler::Id::commonTag>(
-                            AcousticEchoCanceler::echoDelayUs));
+            Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(AcousticEchoCanceler,
+                                                          acousticEchoCancelerTag, echoDelayUs);
             RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
             value = VALUE_OR_RETURN_STATUS(
-                    aidl::android::aidl2legacy_Parameter_uint32_echoDelay(aidlParam));
+                    aidl::android::aidl2legacy_Parameter_aec_uint32_echoDelay(aidlParam));
             break;
         }
         case AEC_PARAM_MOBILE_MODE: {
-            Parameter aidlParam;
-            Parameter::Id id = Parameter::Id::make<Parameter::Id::acousticEchoCancelerTag>(
-                    AcousticEchoCanceler::Id::make<AcousticEchoCanceler::Id::commonTag>(
-                            AcousticEchoCanceler::mobileMode));
+            Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(AcousticEchoCanceler,
+                                                          acousticEchoCancelerTag, mobileMode);
             RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
             value = VALUE_OR_RETURN_STATUS(
-                    aidl::android::aidl2legacy_Parameter_uint32_mobileMode(aidlParam));
+                    aidl::android::aidl2legacy_Parameter_aec_uint32_mobileMode(aidlParam));
             break;
         }
         default:
-            ALOGW("%s unknown param %08x", __func__, type);
+            ALOGW("%s unknown param %s", __func__, param.toString().c_str());
+            return BAD_VALUE;
+    }
+    param.writeToValue(&value);
+    return OK;
+}
+
+status_t EffectConversionHelperAidl::setAgcParameter(EffectParamReader& param) {
+    uint32_t type = 0, value = 0;
+    if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint32_t)) ||
+        OK != param.readFromParameter(&type) || OK != param.readFromValue(&value)) {
+        ALOGW("%s invalid param %s", __func__, param.toString().c_str());
+        return BAD_VALUE;
+    }
+    Parameter aidlParam;
+    switch (type) {
+        case AGC2_PARAM_FIXED_DIGITAL_GAIN: {
+            aidlParam = VALUE_OR_RETURN_STATUS(
+                    aidl::android::legacy2aidl_uint32_fixedDigitalGain_Parameter_agc(value));
             break;
+        }
+        case AGC2_PARAM_ADAPT_DIGI_LEVEL_ESTIMATOR: {
+            aidlParam = VALUE_OR_RETURN_STATUS(
+                    aidl::android::legacy2aidl_uint32_levelEstimator_Parameter_agc(value));
+            break;
+        }
+        case AGC2_PARAM_ADAPT_DIGI_EXTRA_SATURATION_MARGIN: {
+            aidlParam = VALUE_OR_RETURN_STATUS(
+                    aidl::android::legacy2aidl_uint32_saturationMargin_Parameter_agc(value));
+            break;
+        }
+        default: {
+            ALOGW("%s unknown param %s", __func__, param.toString().c_str());
+            return BAD_VALUE;
+        }
     }
 
-    *(uint32_t*)(param.data + psize) = value;
-    return param.status = status;
+    return statusTFromBinderStatus(mEffect->setParameter(aidlParam));
+}
+
+status_t EffectConversionHelperAidl::getAgcParameter(EffectParamWriter& param) {
+    uint32_t type = 0, value = 0;
+    if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint32_t)) ||
+        OK != param.readFromParameter(&type) || OK != param.readFromValue(&value)) {
+        ALOGW("%s invalid param %s", __func__, param.toString().c_str());
+        return BAD_VALUE;
+    }
+    Parameter aidlParam;
+    switch (type) {
+        case AGC2_PARAM_FIXED_DIGITAL_GAIN: {
+            Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(
+                    AutomaticGainControl, automaticGainControlTag, fixedDigitalGainMb);
+            RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
+            value = VALUE_OR_RETURN_STATUS(
+                    aidl::android::aidl2legacy_Parameter_agc_uint32_fixedDigitalGain(aidlParam));
+            break;
+        }
+        case AGC2_PARAM_ADAPT_DIGI_LEVEL_ESTIMATOR: {
+            Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(AutomaticGainControl,
+                                                          automaticGainControlTag, levelEstimator);
+            RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
+            value = VALUE_OR_RETURN_STATUS(
+                    aidl::android::aidl2legacy_Parameter_agc_uint32_levelEstimator(aidlParam));
+            break;
+        }
+        case AGC2_PARAM_ADAPT_DIGI_EXTRA_SATURATION_MARGIN: {
+            Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(
+                    AutomaticGainControl, automaticGainControlTag, saturationMarginMb);
+            RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
+            value = VALUE_OR_RETURN_STATUS(
+                    aidl::android::aidl2legacy_Parameter_agc_uint32_saturationMargin(aidlParam));
+            break;
+        }
+        default: {
+            ALOGW("%s unknown param %s", __func__, param.toString().c_str());
+            return BAD_VALUE;
+        }
+    }
+
+    param.writeToValue(&value);
+    return OK;
+}
+
+status_t EffectConversionHelperAidl::setBassBoostParameter(EffectParamReader& param) {
+    uint32_t type = 0;
+    uint16_t value = 0;
+    if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint16_t)) ||
+        OK != param.readFromParameter(&type) || OK != param.readFromValue(&value)) {
+        ALOGW("%s invalid param %s", __func__, param.toString().c_str());
+        return BAD_VALUE;
+    }
+    Parameter aidlParam;
+    switch (type) {
+        case BASSBOOST_PARAM_STRENGTH: {
+            aidlParam = VALUE_OR_RETURN_STATUS(
+                    aidl::android::legacy2aidl_uint16_strengthPm_Parameter_BassBoost(value));
+            break;
+        }
+        case BASSBOOST_PARAM_STRENGTH_SUPPORTED: {
+            ALOGW("%s set BASSBOOST_PARAM_STRENGTH_SUPPORTED not supported", __func__);
+            return BAD_VALUE;
+        }
+        default: {
+            ALOGW("%s unknown param %s", __func__, param.toString().c_str());
+            return BAD_VALUE;
+        }
+    }
+
+    return statusTFromBinderStatus(mEffect->setParameter(aidlParam));
+}
+
+status_t EffectConversionHelperAidl::getBassBoostParameter(EffectParamWriter& param) {
+    uint32_t type = 0, value = 0;
+    if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint32_t)) ||
+        OK != param.readFromParameter(&type) || OK != param.readFromValue(&value)) {
+        ALOGW("%s invalid param %s", __func__, param.toString().c_str());
+        param.setStatus(BAD_VALUE);
+        return BAD_VALUE;
+    }
+    Parameter aidlParam;
+    switch (type) {
+        case BASSBOOST_PARAM_STRENGTH: {
+            Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(BassBoost, bassBoostTag, strengthPm);
+            RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
+            value = VALUE_OR_RETURN_STATUS(
+                    aidl::android::aidl2legacy_Parameter_BassBoost_uint16_strengthPm(aidlParam));
+            break;
+        }
+        case BASSBOOST_PARAM_STRENGTH_SUPPORTED: {
+            const auto& cap =
+                    VALUE_OR_RETURN_STATUS(aidl::android::UNION_GET(mDesc.capability, bassBoost));
+            value = VALUE_OR_RETURN_STATUS(
+                    aidl::android::convertIntegral<uint32_t>(cap.strengthSupported));
+            break;
+        }
+        default: {
+            ALOGW("%s unknown param %s", __func__, param.toString().c_str());
+            return BAD_VALUE;
+        }
+    }
+
+    param.writeToValue(&value);
+    return OK;
+}
+
+status_t EffectConversionHelperAidl::setDownmixParameter(EffectParamReader& param) {
+    uint32_t type = 0;
+    int16_t value = 0;
+    if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(int16_t)) ||
+        OK != param.readFromParameter(&type) || OK != param.readFromValue(&value)) {
+        ALOGW("%s invalid param %s", __func__, param.toString().c_str());
+        return BAD_VALUE;
+    }
+    Parameter aidlParam;
+    switch (type) {
+        case DOWNMIX_PARAM_TYPE: {
+            aidlParam = VALUE_OR_RETURN_STATUS(
+                    aidl::android::legacy2aidl_int16_type_Parameter_Downmix(value));
+            break;
+        }
+        default: {
+            ALOGW("%s unknown param %s", __func__, param.toString().c_str());
+            return BAD_VALUE;
+        }
+    }
+
+    return statusTFromBinderStatus(mEffect->setParameter(aidlParam));
+}
+
+status_t EffectConversionHelperAidl::getDownmixParameter(EffectParamWriter& param) {
+    int16_t value = 0;
+    uint32_t type = 0;
+    if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint16_t)) ||
+        OK != param.readFromParameter(&type) || OK != param.readFromValue(&value)) {
+        param.setStatus(BAD_VALUE);
+        return BAD_VALUE;
+    }
+    Parameter aidlParam;
+    switch (type) {
+        case DOWNMIX_PARAM_TYPE: {
+            Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(Downmix, downmixTag, type);
+            RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
+            value = VALUE_OR_RETURN_STATUS(
+                    aidl::android::aidl2legacy_Parameter_Downmix_int16_type(aidlParam));
+            break;
+        }
+        default: {
+            ALOGW("%s unknown param %s", __func__, param.toString().c_str());
+            return BAD_VALUE;
+        }
+    }
+
+    param.writeToValue(&value);
+    return OK;
 }
 
 } // namespace effect
diff --git a/media/libaudiohal/impl/EffectConversionHelperAidl.h b/media/libaudiohal/impl/EffectConversionHelperAidl.h
index 5d7c1d6..35249f5 100644
--- a/media/libaudiohal/impl/EffectConversionHelperAidl.h
+++ b/media/libaudiohal/impl/EffectConversionHelperAidl.h
@@ -25,28 +25,17 @@
 
 #include <media/AidlConversionNdk.h>
 #include <system/audio_effect.h>
-#include <system/audio_effects/effect_aec.h>
-#include <system/audio_effects/effect_downmix.h>
-#include <system/audio_effects/effect_dynamicsprocessing.h>
-#include <system/audio_effects/effect_hapticgenerator.h>
-#include <system/audio_effects/effect_ns.h>
-#include <system/audio_effects/effect_visualizer.h>
+#include <system/audio_effects/audio_effects_utils.h>
 
 namespace android {
 namespace effect {
 
-static const size_t kEffectParamSize = sizeof(effect_param_t);
-static const size_t kEffectConfigSize = sizeof(effect_config_t);
-
 class EffectConversionHelperAidl {
   protected:
     EffectConversionHelperAidl(
             std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> effect,
-            int32_t sessionId, int32_t ioId, ::aidl::android::media::audio::common::AudioUuid uuid)
-        : mSessionId(sessionId),
-          mIoId(ioId),
-          mTypeUuid(std::move(uuid)),
-          mEffect(std::move(effect)) {}
+            int32_t sessionId, int32_t ioId,
+            const ::aidl::android::hardware::audio::effect::Descriptor& desc);
 
     status_t handleCommand(uint32_t cmdCode, uint32_t cmdSize, void* pCmdData, uint32_t* replySize,
                            void* pReplyData);
@@ -54,9 +43,25 @@
   private:
     const int32_t mSessionId;
     const int32_t mIoId;
+    const ::aidl::android::hardware::audio::effect::Descriptor mDesc;
     ::aidl::android::media::audio::common::AudioUuid mTypeUuid;
     const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> mEffect;
+    ::aidl::android::hardware::audio::effect::IEffect::OpenEffectReturn mOpenReturn;
+    ::aidl::android::hardware::audio::effect::Parameter::Common mCommon;
 
+    const aidl::android::media::audio::common::AudioFormatDescription kDefaultFormatDescription = {
+            .type = aidl::android::media::audio::common::AudioFormatType::PCM,
+            .pcm = aidl::android::media::audio::common::PcmType::FLOAT_32_BIT};
+
+    static constexpr int kDefaultframeCount = 0x100;
+
+    using AudioChannelLayout = aidl::android::media::audio::common::AudioChannelLayout;
+    const aidl::android::media::audio::common::AudioConfig kDefaultAudioConfig = {
+            .base = {.sampleRate = 44100,
+                     .channelMask = AudioChannelLayout::make<AudioChannelLayout::layoutMask>(
+                             AudioChannelLayout::LAYOUT_STEREO),
+                     .format = kDefaultFormatDescription},
+            .frameCount = kDefaultframeCount};
     // command handler map
     typedef status_t (EffectConversionHelperAidl::*CommandHandler)(uint32_t /* cmdSize */,
                                                                    const void* /* pCmdData */,
@@ -65,23 +70,14 @@
     static const std::map<uint32_t /* effect_command_e */, CommandHandler> mCommandHandlerMap;
 
     // parameter set/get handler map
-    typedef status_t (EffectConversionHelperAidl::*SetParameter)(const effect_param_t& param);
-    typedef status_t (EffectConversionHelperAidl::*GetParameter)(effect_param_t& param);
+    typedef status_t (EffectConversionHelperAidl::*SetParameter)(
+            android::effect::utils::EffectParamReader& param);
+    typedef status_t (EffectConversionHelperAidl::*GetParameter)(
+            android::effect::utils::EffectParamWriter& param);
     static const std::map<::aidl::android::media::audio::common::AudioUuid /* TypeUUID */,
                           std::pair<SetParameter, GetParameter>>
             mParameterHandlerMap;
 
-    // align to 32 bit boundary
-    static constexpr size_t padding(size_t size) {
-        return ((size - 1) / sizeof(int) + 1) * sizeof(int);
-    }
-    static constexpr bool validatePVsize(const effect_param_t& param, size_t p, size_t v) {
-        return padding(param.psize) == p && param.vsize == v;
-    }
-    static constexpr bool validateCommandSize(const effect_param_t& param, size_t size) {
-        return padding(param.psize) + param.vsize + kEffectParamSize <= size;
-    }
-
     status_t handleInit(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
                         void* pReplyData);
     status_t handleSetParameter(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
@@ -107,9 +103,15 @@
     status_t handleFirstPriority(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
                                  void* pReplyData);
 
-    // AEC parameter handler
-    status_t setAecParameter(const effect_param_t& param);
-    status_t getAecParameter(effect_param_t& param);
+    // set/get parameter handler
+    status_t setAecParameter(android::effect::utils::EffectParamReader& param);
+    status_t getAecParameter(android::effect::utils::EffectParamWriter& param);
+    status_t setAgcParameter(android::effect::utils::EffectParamReader& param);
+    status_t getAgcParameter(android::effect::utils::EffectParamWriter& param);
+    status_t setBassBoostParameter(android::effect::utils::EffectParamReader& param);
+    status_t getBassBoostParameter(android::effect::utils::EffectParamWriter& param);
+    status_t setDownmixParameter(android::effect::utils::EffectParamReader& param);
+    status_t getDownmixParameter(android::effect::utils::EffectParamWriter& param);
 };
 
 }  // namespace effect
diff --git a/media/libaudiohal/impl/EffectHalAidl.cpp b/media/libaudiohal/impl/EffectHalAidl.cpp
index 3346459..0c37552 100644
--- a/media/libaudiohal/impl/EffectHalAidl.cpp
+++ b/media/libaudiohal/impl/EffectHalAidl.cpp
@@ -42,21 +42,30 @@
 using ::aidl::android::hardware::audio::effect::CommandId;
 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::Parameter;
 
 namespace android {
 namespace effect {
 
-EffectHalAidl::EffectHalAidl(const std::shared_ptr<IEffect>& effect, uint64_t effectId,
-                             int32_t sessionId, int32_t ioId, const Descriptor& desc)
-    : EffectConversionHelperAidl(effect, sessionId, ioId, desc.common.id.type),
+EffectHalAidl::EffectHalAidl(
+        const std::shared_ptr<::aidl::android::hardware::audio::effect::IFactory>& factory,
+        const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>& effect,
+        uint64_t effectId, int32_t sessionId, int32_t ioId,
+        const ::aidl::android::hardware::audio::effect::Descriptor& desc)
+    : EffectConversionHelperAidl(effect, sessionId, ioId, desc),
+      mFactory(factory),
+      mEffect(effect),
       mEffectId(effectId),
       mSessionId(sessionId),
       mIoId(ioId),
-      mEffect(effect),
       mDesc(desc) {}
 
-EffectHalAidl::~EffectHalAidl() {}
+EffectHalAidl::~EffectHalAidl() {
+    if (mFactory) {
+        mFactory->destroyEffect(mEffect);
+    }
+}
 
 status_t EffectHalAidl::setInBuffer(const sp<EffectBufferHalInterface>& buffer) {
     if (buffer == nullptr) {
@@ -105,8 +114,7 @@
 }
 
 status_t EffectHalAidl::close() {
-    RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->close()));
-    return OK;
+    return statusTFromBinderStatus(mEffect->close());
 }
 
 status_t EffectHalAidl::dump(int fd) {
diff --git a/media/libaudiohal/impl/EffectHalAidl.h b/media/libaudiohal/impl/EffectHalAidl.h
index 1ba262c..6a1ec1c 100644
--- a/media/libaudiohal/impl/EffectHalAidl.h
+++ b/media/libaudiohal/impl/EffectHalAidl.h
@@ -17,6 +17,7 @@
 #pragma once
 
 #include <aidl/android/hardware/audio/effect/IEffect.h>
+#include <aidl/android/hardware/audio/effect/IFactory.h>
 #include <media/audiohal/EffectHalInterface.h>
 #include <system/audio_effect.h>
 
@@ -64,19 +65,22 @@
   private:
     friend class sp<EffectHalAidl>;
 
+    const std::shared_ptr<::aidl::android::hardware::audio::effect::IFactory> mFactory;
+    const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> mEffect;
     const uint64_t mEffectId;
     const int32_t mSessionId;
     const int32_t mIoId;
-    const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> mEffect;
     const ::aidl::android::hardware::audio::effect::Descriptor mDesc;
 
     sp<EffectBufferHalInterface> mInBuffer, mOutBuffer;
     effect_config_t mConfig;
 
     // Can not be constructed directly by clients.
-    EffectHalAidl(const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>& effect,
-                  uint64_t effectId, int32_t sessionId, int32_t ioId,
-                  const ::aidl::android::hardware::audio::effect::Descriptor& desc);
+    EffectHalAidl(
+            const std::shared_ptr<::aidl::android::hardware::audio::effect::IFactory>& factory,
+            const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>& effect,
+            uint64_t effectId, int32_t sessionId, int32_t ioId,
+            const ::aidl::android::hardware::audio::effect::Descriptor& desc);
     bool setEffectReverse(bool reverse);
 
     // The destructor automatically releases the effect.
diff --git a/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp b/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
index 96ea861..878c19e 100644
--- a/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
+++ b/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
@@ -134,7 +134,7 @@
         effectId = ++mEffectIdCounter;
     }
 
-    *effect = sp<EffectHalAidl>::make(aidlEffect, effectId, sessionId, ioId, desc);
+    *effect = sp<EffectHalAidl>::make(mFactory, aidlEffect, effectId, sessionId, ioId, desc);
     return OK;
 }