diff --git a/audio/aidl/vts/EffectFactoryHelper.h b/audio/aidl/vts/EffectFactoryHelper.h
index d58fcf2..dc766dd 100644
--- a/audio/aidl/vts/EffectFactoryHelper.h
+++ b/audio/aidl/vts/EffectFactoryHelper.h
@@ -29,10 +29,7 @@
 using namespace android;
 
 using aidl::android::hardware::audio::effect::Descriptor;
-using aidl::android::hardware::audio::effect::EffectNullUuid;
-using aidl::android::hardware::audio::effect::IEffect;
 using aidl::android::hardware::audio::effect::IFactory;
-using aidl::android::hardware::audio::effect::Processing;
 using aidl::android::media::audio::common::AudioUuid;
 
 class EffectFactoryHelper {
@@ -48,122 +45,36 @@
         ASSERT_NE(mEffectFactory, nullptr);
         mEffectFactory = IFactory::fromBinder(binderUtil.restartService());
         ASSERT_NE(mEffectFactory, nullptr);
-        ClearEffectMap();
     }
 
-    void QueryEffects(const std::optional<AudioUuid>& in_type,
-                      const std::optional<AudioUuid>& in_instance,
-                      const std::optional<AudioUuid>& in_proxy,
-                      std::vector<Descriptor::Identity>* _aidl_return) {
-        ASSERT_NE(mEffectFactory, nullptr);
-        EXPECT_IS_OK(mEffectFactory->queryEffects(in_type, in_instance, in_proxy, _aidl_return));
-        mIds = *_aidl_return;
-    }
+    std::shared_ptr<IFactory> GetFactory() const { return mEffectFactory; }
 
-    void QueryProcessing(const std::optional<Processing::Type>& in_type,
-                         std::vector<Processing>* _aidl_return) {
-        ASSERT_NE(mEffectFactory, nullptr);
-        EXPECT_IS_OK(mEffectFactory->queryProcessing(in_type, _aidl_return));
-        // only update the whole list if no filter applied
-        if (!in_type.has_value()) {
-            mProcesses = *_aidl_return;
-        }
-    }
+    static std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor::Identity>>
+    getAllEffectDescriptors(std::string serviceName, std::optional<AudioUuid> type = std::nullopt) {
+        AudioHalBinderServiceUtil util;
+        auto names = android::getAidlHalInstanceNames(serviceName);
+        std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor::Identity>> result;
 
-    void CreateEffects() {
-        for (const auto& id : mIds) {
-            std::shared_ptr<IEffect> effect;
-            EXPECT_IS_OK(mEffectFactory->createEffect(id.uuid, &effect));
-            EXPECT_NE(effect, nullptr) << id.toString();
-            if (effect) {
-                mEffectIdMap[effect] = id;
+        for (const auto& name : names) {
+            auto factory = IFactory::fromBinder(util.connectToService(name));
+            if (factory) {
+                if (std::vector<Descriptor::Identity> ids;
+                    factory->queryEffects(std::nullopt, std::nullopt, std::nullopt, &ids).isOk()) {
+                    for (const auto& id : ids) {
+                        if (type.has_value() && id.type != type.value()) {
+                            continue;
+                        }
+                        result.emplace_back(factory, id);
+                    }
+                }
             }
         }
-    }
 
-    void QueryAndCreateEffects(const AudioUuid& type = EffectNullUuid) {
-        std::vector<Descriptor::Identity> ids;
-        ASSERT_NE(mEffectFactory, nullptr);
-
-        if (type == EffectNullUuid) {
-            EXPECT_IS_OK(
-                    mEffectFactory->queryEffects(std::nullopt, std::nullopt, std::nullopt, &ids));
-        } else {
-            EXPECT_IS_OK(mEffectFactory->queryEffects(type, std::nullopt, std::nullopt, &ids));
-        }
-        for (const auto& id : ids) {
-            ASSERT_EQ(id.type, type);
-            std::shared_ptr<IEffect> effect;
-            EXPECT_IS_OK(mEffectFactory->createEffect(id.uuid, &effect));
-            EXPECT_NE(effect, nullptr) << id.toString();
-            if (effect) {
-                mEffectIdMap[effect] = id;
-            }
-        }
+        return result;
     }
 
-    void CreateEffectsAndExpect(
-            const std::vector<std::pair<Descriptor::Identity, binder_exception_t>>& uuid_status) {
-        ASSERT_NE(mEffectFactory, nullptr);
-        for (const auto& it : uuid_status) {
-            std::shared_ptr<IEffect> effect;
-            auto status = mEffectFactory->createEffect(it.first.uuid, &effect);
-            EXPECT_STATUS(it.second, status);
-            if (effect) {
-                mEffectIdMap[effect] = it.first;
-            }
-        }
-    }
-
-    void DestroyEffectAndExpect(std::shared_ptr<IEffect>& instance, binder_exception_t exception) {
-        ASSERT_NE(mEffectFactory, nullptr);
-        auto status = mEffectFactory->destroyEffect(instance);
-        EXPECT_STATUS(exception, status);
-    }
-
-    void QueryAndCreateAllEffects() {
-        ASSERT_NE(mEffectFactory, nullptr);
-        EXPECT_IS_OK(mEffectFactory->queryEffects(std::nullopt, std::nullopt, std::nullopt,
-                                                  &mCompleteIds));
-        for (const auto& id : mCompleteIds) {
-            std::shared_ptr<IEffect> effect;
-            EXPECT_IS_OK(mEffectFactory->createEffect(id.uuid, &effect));
-            EXPECT_NE(effect, nullptr) << id.toString();
-            mEffectIdMap[effect] = id;
-        }
-    }
-
-    void DestroyEffects(const binder_exception_t expected = EX_NONE, const int remaining = 0) {
-        ASSERT_NE(mEffectFactory, nullptr);
-
-        for (auto it = mEffectIdMap.begin(); it != mEffectIdMap.end();) {
-            auto erased = it++;
-            auto status = mEffectFactory->destroyEffect(erased->first);
-            EXPECT_STATUS(expected, status);
-            if (status.isOk()) {
-                mEffectIdMap.erase(erased);
-            }
-        }
-        EXPECT_EQ((unsigned int)remaining, mEffectIdMap.size());
-    }
-
-    std::shared_ptr<IFactory> GetFactory() { return mEffectFactory; }
-    const std::vector<Descriptor::Identity>& GetEffectIds() { return mIds; }
-    const std::vector<Descriptor::Identity>& GetCompleteEffectIdList() const {
-        return mCompleteIds;
-    }
-    const std::map<std::shared_ptr<IEffect>, Descriptor::Identity>& GetEffectMap() const {
-        return mEffectIdMap;
-    }
-    void ClearEffectMap() { mEffectIdMap.clear(); }
-
   private:
     std::shared_ptr<IFactory> mEffectFactory;
     std::string mServiceName;
     AudioHalBinderServiceUtil binderUtil;
-    std::vector<Descriptor::Identity> mIds;
-    std::vector<Descriptor::Identity> mCompleteIds;
-    std::vector<Processing> mProcesses;
-
-    std::map<std::shared_ptr<IEffect>, Descriptor::Identity> mEffectIdMap;
 };
diff --git a/audio/aidl/vts/EffectHelper.h b/audio/aidl/vts/EffectHelper.h
index 623ac37..73a1f49 100644
--- a/audio/aidl/vts/EffectHelper.h
+++ b/audio/aidl/vts/EffectHelper.h
@@ -16,6 +16,7 @@
 
 #pragma once
 
+#include <algorithm>
 #include <memory>
 #include <string>
 #include <unordered_map>
@@ -24,7 +25,6 @@
 #include <aidl/android/hardware/audio/effect/IEffect.h>
 #include <aidl/android/hardware/audio/effect/IFactory.h>
 #include <aidl/android/media/audio/common/AudioChannelLayout.h>
-#include <aidl/android/media/audio/common/AudioDeviceType.h>
 #include <android/binder_auto_utils.h>
 #include <fmq/AidlMessageQueue.h>
 
@@ -35,275 +35,139 @@
 using namespace android;
 using aidl::android::hardware::audio::effect::CommandId;
 using aidl::android::hardware::audio::effect::Descriptor;
-using aidl::android::hardware::audio::effect::EffectNullUuid;
-using aidl::android::hardware::audio::effect::EffectZeroUuid;
 using aidl::android::hardware::audio::effect::IEffect;
 using aidl::android::hardware::audio::effect::Parameter;
 using aidl::android::hardware::audio::effect::State;
 using aidl::android::hardware::common::fmq::SynchronizedReadWrite;
 using aidl::android::media::audio::common::AudioChannelLayout;
-using aidl::android::media::audio::common::AudioDeviceType;
 using aidl::android::media::audio::common::AudioFormatDescription;
 using aidl::android::media::audio::common::AudioFormatType;
 using aidl::android::media::audio::common::AudioUuid;
 using aidl::android::media::audio::common::PcmType;
 
-const AudioFormatDescription DefaultFormat = {
+const AudioFormatDescription kDefaultFormatDescription = {
         .type = AudioFormatType::PCM, .pcm = PcmType::FLOAT_32_BIT, .encoding = ""};
 
+typedef ::android::AidlMessageQueue<IEffect::Status,
+                                    ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>
+        StatusMQ;
+typedef ::android::AidlMessageQueue<float,
+                                    ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>
+        DataMQ;
+
 class EffectHelper {
   public:
-    explicit EffectHelper(const std::string& name) : mFactoryHelper(EffectFactoryHelper(name)) {
-        mFactoryHelper.ConnectToFactoryService();
+    static void create(std::shared_ptr<IFactory> factory, std::shared_ptr<IEffect>& effect,
+                       Descriptor::Identity id, binder_status_t status = EX_NONE) {
+        ASSERT_NE(factory, nullptr);
+        EXPECT_STATUS(status, factory->createEffect(id.uuid, &effect));
+        if (status == EX_NONE) {
+            ASSERT_NE(effect, nullptr) << id.uuid.toString();
+        }
     }
 
-    void OpenEffects(const AudioUuid& type = EffectNullUuid) {
-        auto open = [&](const std::shared_ptr<IEffect>& effect) {
-            ASSERT_NE(effect, nullptr);
-            IEffect::OpenEffectReturn ret;
-            EXPECT_IS_OK(effect->open(mCommon, mSpecific, &ret));
-            EffectParam params;
-            params.statusMQ = std::make_unique<StatusMQ>(ret.statusMQ);
-            params.inputMQ = std::make_unique<DataMQ>(ret.inputDataMQ);
-            params.outputMQ = std::make_unique<DataMQ>(ret.outputDataMQ);
-            mEffectParams.push_back(std::move(params));
-        };
-        EXPECT_NO_FATAL_FAILURE(ForEachEffect(open, type));
+    static void destroy(std::shared_ptr<IFactory> factory, std::shared_ptr<IEffect> effect,
+                        binder_status_t status = EX_NONE) {
+        ASSERT_NE(factory, nullptr);
+        ASSERT_NE(effect, nullptr);
+        EXPECT_STATUS(status, factory->destroyEffect(effect));
     }
 
-    void CloseEffects(const binder_status_t status = EX_NONE) {
-        auto close = [&](const std::shared_ptr<IEffect>& effect) {
-            ASSERT_NE(effect, nullptr);
+    static void open(std::shared_ptr<IEffect> effect, const Parameter::Common& common,
+                     const std::optional<Parameter::Specific>& specific,
+                     IEffect::OpenEffectReturn* ret, binder_status_t status = EX_NONE) {
+        ASSERT_NE(effect, nullptr);
+        EXPECT_STATUS(status, effect->open(common, specific, ret));
+    }
+
+    static void open(std::shared_ptr<IEffect> effect, int session = 0,
+                     binder_status_t status = EX_NONE) {
+        ASSERT_NE(effect, nullptr);
+        Parameter::Common common = EffectHelper::createParamCommon(session);
+        IEffect::OpenEffectReturn ret;
+        open(effect, common, std::nullopt /* specific */, &ret, status);
+    }
+
+    static void close(std::shared_ptr<IEffect> effect, binder_status_t status = EX_NONE) {
+        if (effect) {
             EXPECT_STATUS(status, effect->close());
-        };
-
-        EXPECT_NO_FATAL_FAILURE(ForEachEffect(close));
-    }
-
-    void CreateEffects(const int n = 1) {
-        for (int i = 0; i < n; i++) {
-            ASSERT_NO_FATAL_FAILURE(mFactoryHelper.QueryAndCreateAllEffects());
         }
     }
-
-    void CreateEffectsWithUUID(const AudioUuid& type = EffectNullUuid) {
-        ASSERT_NO_FATAL_FAILURE(mFactoryHelper.QueryAndCreateEffects(type));
+    static void getDescriptor(std::shared_ptr<IEffect> effect, Descriptor& desc,
+                              binder_status_t status = EX_NONE) {
+        ASSERT_NE(effect, nullptr);
+        EXPECT_STATUS(status, effect->getDescriptor(&desc));
     }
-
-    void QueryEffects() { ASSERT_NO_FATAL_FAILURE(mFactoryHelper.QueryAndCreateAllEffects()); }
-
-    void DestroyEffects(const binder_status_t status = EX_NONE, const int remaining = 0) {
-        ASSERT_NO_FATAL_FAILURE(mFactoryHelper.DestroyEffects(status, remaining));
-        mEffectDescriptors.clear();
+    static void expectState(std::shared_ptr<IEffect> effect, State expectState,
+                            binder_status_t status = EX_NONE) {
+        ASSERT_NE(effect, nullptr);
+        State state;
+        EXPECT_STATUS(status, effect->getState(&state));
+        EXPECT_EQ(expectState, state);
     }
-
-    void GetEffectDescriptors() {
-        auto get = [&](const std::shared_ptr<IEffect>& effect) {
-            ASSERT_NE(effect, nullptr);
-            Descriptor desc;
-            EXPECT_IS_OK(effect->getDescriptor(&desc));
-            mEffectDescriptors.push_back(std::move(desc));
-        };
-        EXPECT_NO_FATAL_FAILURE(ForEachEffect(get));
+    static void command(std::shared_ptr<IEffect> effect, CommandId command,
+                        binder_status_t status = EX_NONE) {
+        ASSERT_NE(effect, nullptr);
+        EXPECT_STATUS(status, effect->command(command));
     }
-
-    void CommandEffects(CommandId command) {
-        auto close = [&](const std::shared_ptr<IEffect>& effect) {
-            ASSERT_NE(effect, nullptr);
-            EXPECT_IS_OK(effect->command(command));
-        };
-        EXPECT_NO_FATAL_FAILURE(ForEachEffect(close));
+    static void allocateInputData(const Parameter::Common common, std::unique_ptr<DataMQ>& mq,
+                                  std::vector<float>& buffer) {
+        ASSERT_NE(mq, nullptr);
+        auto frameSize = android::hardware::audio::common::getFrameSizeInBytes(
+                common.input.base.format, common.input.base.channelMask);
+        const size_t floatsToWrite = mq->availableToWrite();
+        EXPECT_NE(0UL, floatsToWrite);
+        EXPECT_EQ(frameSize * common.input.frameCount, floatsToWrite * sizeof(float));
+        buffer.resize(floatsToWrite);
+        std::fill(buffer.begin(), buffer.end(), 0x5a);
     }
-
-    void CommandEffectsExpectStatus(CommandId command, const binder_status_t status) {
-        auto func = [&](const std::shared_ptr<IEffect>& effect) {
-            ASSERT_NE(effect, nullptr);
-            EXPECT_STATUS(status, effect->command(command));
-        };
-        EXPECT_NO_FATAL_FAILURE(ForEachEffect(func));
+    static void writeToFmq(std::unique_ptr<DataMQ>& mq, const std::vector<float>& buffer) {
+        const size_t available = mq->availableToWrite();
+        EXPECT_NE(0Ul, available);
+        auto bufferFloats = buffer.size();
+        auto floatsToWrite = std::min(available, bufferFloats);
+        EXPECT_TRUE(mq->write(buffer.data(), floatsToWrite));
     }
-
-    void ExpectState(State expected) {
-        auto get = [&](const std::shared_ptr<IEffect>& effect) {
-            ASSERT_NE(effect, nullptr);
-            State state = State::INIT;
-            EXPECT_IS_OK(effect->getState(&state));
-            EXPECT_EQ(expected, state);
-        };
-        EXPECT_NO_FATAL_FAILURE(ForEachEffect(get));
-    }
-
-    void SetParameter() {
-        auto func = [&](const std::shared_ptr<IEffect>& effect) {
-            ASSERT_NE(effect, nullptr);
-            Parameter param;
-            param.set<Parameter::common>(mCommon);
-            EXPECT_IS_OK(effect->setParameter(param));
-        };
-        EXPECT_NO_FATAL_FAILURE(ForEachEffect(func));
-    }
-
-    void VerifyParameters() {
-        auto func = [&](const std::shared_ptr<IEffect>& effect) {
-            ASSERT_NE(effect, nullptr);
-            Parameter paramCommonGet = Parameter(), paramCommonExpect = Parameter();
-            Parameter::Id id;
-            id.set<Parameter::Id::commonTag>(Parameter::common);
-            paramCommonExpect.set<Parameter::common>(mCommon);
-            EXPECT_IS_OK(effect->getParameter(id, &paramCommonGet));
-            EXPECT_EQ(paramCommonExpect, paramCommonGet)
-                    << paramCommonExpect.toString() << " vs " << paramCommonGet.toString();
-        };
-        EXPECT_NO_FATAL_FAILURE(ForEachEffect(func));
-    }
-
-    void QueryEffects(const std::optional<AudioUuid>& in_type,
-                      const std::optional<AudioUuid>& in_instance,
-                      const std::optional<AudioUuid>& in_proxy,
-                      std::vector<Descriptor::Identity>* _aidl_return) {
-        mFactoryHelper.QueryEffects(in_type, in_instance, in_proxy, _aidl_return);
-    }
-
-    template <typename Functor>
-    void ForEachEffect(Functor functor, const std::optional<AudioUuid>& type = EffectNullUuid) {
-        auto effectMap = mFactoryHelper.GetEffectMap();
-        for (const auto& it : effectMap) {
-            SCOPED_TRACE(it.second.toString());
-            if (type != EffectNullUuid && it.second.type != type) continue;
-            functor(it.first);
+    static void readFromFmq(std::unique_ptr<StatusMQ>& statusMq, size_t statusNum,
+                            std::unique_ptr<DataMQ>& dataMq, size_t expectFloats,
+                            std::vector<float>& buffer) {
+        IEffect::Status status{};
+        EXPECT_TRUE(statusMq->readBlocking(&status, statusNum));
+        EXPECT_EQ(STATUS_OK, status.status);
+        if (statusNum != 0) {
+            EXPECT_EQ(expectFloats, (unsigned)status.fmqProduced);
+            EXPECT_EQ(expectFloats, dataMq->availableToRead());
+            if (expectFloats != 0) {
+                EXPECT_TRUE(dataMq->read(buffer.data(), expectFloats));
+            }
         }
     }
+    static Parameter::Common createParamCommon(
+            int session = 0, int ioHandle = -1, int iSampleRate = 48000, int oSampleRate = 48000,
+            long iFrameCount = 0x100, long oFrameCount = 0x100,
+            AudioChannelLayout inputChannelLayout =
+                    AudioChannelLayout::make<AudioChannelLayout::layoutMask>(
+                            AudioChannelLayout::LAYOUT_STEREO),
+            AudioChannelLayout outputChannelLayout =
+                    AudioChannelLayout::make<AudioChannelLayout::layoutMask>(
+                            AudioChannelLayout::LAYOUT_STEREO)) {
+        Parameter::Common common;
+        common.session = session;
+        common.ioHandle = ioHandle;
 
-    template <typename Functor>
-    void ForEachDescriptor(Functor functor) {
-        for (size_t i = 0; i < mEffectDescriptors.size(); i++) {
-            SCOPED_TRACE(mEffectDescriptors[i].toString());
-            functor(i, mEffectDescriptors[i]);
-        }
-    }
-
-    static const size_t mWriteMQBytes = 0x400;
-
-    enum class IO : char { INPUT = 0, OUTPUT = 1, INOUT = 2 };
-
-    void initParamCommonFormat(IO io = IO::INOUT,
-                               const AudioFormatDescription& format = DefaultFormat) {
-        if (io == IO::INPUT || io == IO::INOUT) {
-            mCommon.input.base.format = format;
-        }
-        if (io == IO::OUTPUT || io == IO::INOUT) {
-            mCommon.output.base.format = format;
-        }
-    }
-
-    void initParamCommonSampleRate(IO io = IO::INOUT, const int& sampleRate = 48000) {
-        if (io == IO::INPUT || io == IO::INOUT) {
-            mCommon.input.base.sampleRate = sampleRate;
-        }
-        if (io == IO::OUTPUT || io == IO::INOUT) {
-            mCommon.output.base.sampleRate = sampleRate;
-        }
-    }
-
-    void initParamCommonFrameCount(IO io = IO::INOUT, const long& frameCount = 48000) {
-        if (io == IO::INPUT || io == IO::INOUT) {
-            mCommon.input.frameCount = frameCount;
-        }
-        if (io == IO::OUTPUT || io == IO::INOUT) {
-            mCommon.output.frameCount = frameCount;
-        }
-    }
-    void initParamCommon(int session = 0, int ioHandle = -1, int iSampleRate = 48000,
-                         int oSampleRate = 48000, long iFrameCount = 0x100,
-                         long oFrameCount = 0x100) {
-        mCommon.session = session;
-        mCommon.ioHandle = ioHandle;
-
-        auto& input = mCommon.input;
-        auto& output = mCommon.output;
+        auto& input = common.input;
+        auto& output = common.output;
         input.base.sampleRate = iSampleRate;
-        input.base.channelMask = mInputChannelLayout;
+        input.base.channelMask = inputChannelLayout;
+        input.base.format = kDefaultFormatDescription;
         input.frameCount = iFrameCount;
-        input.base.format = DefaultFormat;
         output.base.sampleRate = oSampleRate;
-        output.base.channelMask = mOutputChannelLayout;
-        output.base.format = DefaultFormat;
+        output.base.channelMask = outputChannelLayout;
+        output.base.format = kDefaultFormatDescription;
         output.frameCount = oFrameCount;
-        output.base.format = DefaultFormat;
-        inputFrameSize = android::hardware::audio::common::getFrameSizeInBytes(
-                input.base.format, input.base.channelMask);
-        outputFrameSize = android::hardware::audio::common::getFrameSizeInBytes(
-                output.base.format, output.base.channelMask);
+        return common;
     }
 
-    void setSpecific(Parameter::Specific& specific) { mSpecific = specific; }
-
-    // usually this function only call once.
-    void PrepareInputData(size_t bytes = mWriteMQBytes) {
-        size_t maxInputBytes = mWriteMQBytes;
-        for (auto& it : mEffectParams) {
-            auto& mq = it.inputMQ;
-            EXPECT_NE(nullptr, mq);
-            EXPECT_TRUE(mq->isValid());
-            const size_t bytesToWrite = mq->availableToWrite() * sizeof(float);
-            EXPECT_EQ(inputFrameSize * mCommon.input.frameCount, bytesToWrite);
-            EXPECT_NE(0UL, bytesToWrite);
-            EXPECT_TRUE(bytes <= bytesToWrite);
-            maxInputBytes = std::max(maxInputBytes, bytesToWrite);
-        }
-        mInputBuffer.resize(maxInputBytes / sizeof(float));
-        std::fill(mInputBuffer.begin(), mInputBuffer.end(), 0x5a);
-    }
-
-    void writeToFmq(size_t bytes = mWriteMQBytes) {
-        for (auto& it : mEffectParams) {
-            auto& mq = it.inputMQ;
-            EXPECT_NE(nullptr, mq);
-            const size_t bytesToWrite = mq->availableToWrite() * sizeof(float);
-            EXPECT_NE(0Ul, bytesToWrite);
-            EXPECT_TRUE(bytes <= bytesToWrite);
-            EXPECT_TRUE(mq->write(mInputBuffer.data(), bytes / sizeof(float)));
-        }
-    }
-
-    void readFromFmq(size_t expectBytes = mWriteMQBytes) {
-        for (auto& it : mEffectParams) {
-            IEffect::Status status{};
-            auto& statusMq = it.statusMQ;
-            EXPECT_NE(nullptr, statusMq);
-            EXPECT_TRUE(statusMq->readBlocking(&status, 1));
-            EXPECT_EQ(STATUS_OK, status.status);
-            EXPECT_EQ(expectBytes, (unsigned)status.fmqProduced * sizeof(float));
-
-            auto& outputMq = it.outputMQ;
-            EXPECT_NE(nullptr, outputMq);
-            EXPECT_EQ(expectBytes, outputMq->availableToRead() * sizeof(float));
-        }
-    }
-
-    void setInputChannelLayout(AudioChannelLayout input) { mInputChannelLayout = input; }
-    void setOutputChannelLayout(AudioChannelLayout output) { mOutputChannelLayout = output; }
-    const std::vector<Descriptor::Identity>& GetCompleteEffectIdList() const {
-        return mFactoryHelper.GetCompleteEffectIdList();
-    }
-    const std::vector<Descriptor>& getDescriptorVec() const { return mEffectDescriptors; }
-
-  private:
-    EffectFactoryHelper mFactoryHelper;
-
-    AudioChannelLayout mInputChannelLayout =
-            AudioChannelLayout::make<AudioChannelLayout::layoutMask>(
-                    AudioChannelLayout::LAYOUT_STEREO);
-    AudioChannelLayout mOutputChannelLayout =
-            AudioChannelLayout::make<AudioChannelLayout::layoutMask>(
-                    AudioChannelLayout::LAYOUT_STEREO);
-
-    Parameter::Common mCommon;
-    std::optional<Parameter::Specific> mSpecific = std::nullopt;
-
-    size_t inputFrameSize, outputFrameSize;
-    std::vector<float> mInputBuffer;  // reuse same buffer for all effects testing
-
     typedef ::android::AidlMessageQueue<
             IEffect::Status, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>
             StatusMQ;
@@ -317,6 +181,4 @@
         std::unique_ptr<DataMQ> inputMQ;
         std::unique_ptr<DataMQ> outputMQ;
     };
-    std::vector<EffectParam> mEffectParams;
-    std::vector<Descriptor> mEffectDescriptors;
 };
diff --git a/audio/aidl/vts/VtsHalAudioEffectFactoryTargetTest.cpp b/audio/aidl/vts/VtsHalAudioEffectFactoryTargetTest.cpp
index d30dff4..8ae963e 100644
--- a/audio/aidl/vts/VtsHalAudioEffectFactoryTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioEffectFactoryTargetTest.cpp
@@ -15,6 +15,7 @@
  */
 
 #include <memory>
+#include <set>
 #include <string>
 #include <vector>
 
@@ -37,23 +38,81 @@
 using namespace android;
 
 using aidl::android::hardware::audio::effect::Descriptor;
-using aidl::android::hardware::audio::effect::EffectNullUuid;
-using aidl::android::hardware::audio::effect::EffectZeroUuid;
+using aidl::android::hardware::audio::effect::IEffect;
 using aidl::android::hardware::audio::effect::IFactory;
+using aidl::android::hardware::audio::effect::kEffectNullUuid;
+using aidl::android::hardware::audio::effect::kEffectZeroUuid;
 using aidl::android::hardware::audio::effect::Processing;
+using aidl::android::media::audio::common::AudioSource;
+using aidl::android::media::audio::common::AudioStreamType;
 using aidl::android::media::audio::common::AudioUuid;
 
 /// Effect factory testing.
 class EffectFactoryTest : public testing::TestWithParam<std::string> {
   public:
-    void SetUp() override { ASSERT_NO_FATAL_FAILURE(mFactory.ConnectToFactoryService()); }
+    void SetUp() override {
+        mFactoryHelper = std::make_unique<EffectFactoryHelper>(GetParam());
+        connectAndGetFactory();
+    }
 
-    void TearDown() override { mFactory.DestroyEffects(); }
+    void TearDown() override {
+        for (auto& effect : mEffects) {
+            const auto status = mEffectFactory->destroyEffect(effect);
+            EXPECT_STATUS(EX_NONE, status);
+        }
+    }
 
-    EffectFactoryHelper mFactory = EffectFactoryHelper(GetParam());
+    std::unique_ptr<EffectFactoryHelper> mFactoryHelper;
+    std::shared_ptr<IFactory> mEffectFactory;
+    std::vector<std::shared_ptr<IEffect>> mEffects;
+    const Descriptor::Identity kNullDesc = {.uuid = kEffectNullUuid};
+    const Descriptor::Identity kZeroDesc = {.uuid = kEffectZeroUuid};
 
-    const Descriptor::Identity nullDesc = {.uuid = EffectNullUuid};
-    const Descriptor::Identity zeroDesc = {.uuid = EffectZeroUuid};
+    template <typename Functor>
+    void ForEachId(const std::vector<Descriptor::Identity> ids, Functor functor) {
+        for (const auto& id : ids) {
+            SCOPED_TRACE(id.toString());
+            functor(id);
+        }
+    }
+    template <typename Functor>
+    void ForEachEffect(std::vector<std::shared_ptr<IEffect>> effects, Functor functor) {
+        for (auto& effect : effects) {
+            functor(effect);
+        }
+    }
+
+    std::vector<std::shared_ptr<IEffect>> createWithIds(
+            const std::vector<Descriptor::Identity> ids,
+            const binder_status_t expectStatus = EX_NONE) {
+        std::vector<std::shared_ptr<IEffect>> effects;
+        for (const auto& id : ids) {
+            std::shared_ptr<IEffect> effect;
+            EXPECT_STATUS(expectStatus, mEffectFactory->createEffect(id.uuid, &effect));
+            if (expectStatus == EX_NONE) {
+                EXPECT_NE(effect, nullptr) << " null effect with uuid: " << id.uuid.toString();
+                effects.push_back(std::move(effect));
+            }
+        }
+        return effects;
+    }
+    void destroyEffects(std::vector<std::shared_ptr<IEffect>> effects,
+                        const binder_status_t expectStatus = EX_NONE) {
+        for (const auto& effect : effects) {
+            EXPECT_STATUS(expectStatus, mEffectFactory->destroyEffect(effect));
+        }
+    }
+    void creatAndDestroyIds(const std::vector<Descriptor::Identity> ids) {
+        for (const auto& id : ids) {
+            auto effects = createWithIds({id});
+            ASSERT_NO_FATAL_FAILURE(destroyEffects(effects));
+        }
+    }
+    void connectAndGetFactory() {
+        ASSERT_NO_FATAL_FAILURE(mFactoryHelper->ConnectToFactoryService());
+        mEffectFactory = mFactoryHelper->GetFactory();
+        ASSERT_NE(mEffectFactory, nullptr);
+    }
 };
 
 TEST_P(EffectFactoryTest, SetupAndTearDown) {
@@ -61,165 +120,160 @@
 }
 
 TEST_P(EffectFactoryTest, CanBeRestarted) {
-    ASSERT_NO_FATAL_FAILURE(mFactory.RestartFactoryService());
+    ASSERT_NO_FATAL_FAILURE(mFactoryHelper->RestartFactoryService());
 }
 
-TEST_P(EffectFactoryTest, QueriedDescriptorList) {
-    std::vector<Descriptor::Identity> descriptors;
-    mFactory.QueryEffects(std::nullopt, std::nullopt, std::nullopt, &descriptors);
-    EXPECT_NE(descriptors.size(), 0UL);
-}
+/**
+ * @brief Check at least support list of effect must be supported by aosp:
+ * https://developer.android.com/reference/android/media/audiofx/AudioEffect
+ */
+TEST_P(EffectFactoryTest, ExpectAllAospEffectTypes) {
+    std::vector<Descriptor::Identity> ids;
+    std::set<AudioUuid> typeUuidSet(
+            {aidl::android::hardware::audio::effect::kBassBoostTypeUUID,
+             aidl::android::hardware::audio::effect::kEqualizerTypeUUID,
+             aidl::android::hardware::audio::effect::kEnvReverbTypeUUID,
+             aidl::android::hardware::audio::effect::kPresetReverbTypeUUID,
+             aidl::android::hardware::audio::effect::kDynamicsProcessingTypeUUID,
+             aidl::android::hardware::audio::effect::kHapticGeneratorTypeUUID,
+             aidl::android::hardware::audio::effect::kVirtualizerTypeUUID});
 
-TEST_P(EffectFactoryTest, DescriptorUUIDNotNull) {
-    std::vector<Descriptor::Identity> descriptors;
-    mFactory.QueryEffects(std::nullopt, std::nullopt, std::nullopt, &descriptors);
-    // TODO: Factory eventually need to return the full list of MUST supported AOSP effects.
-    for (auto& desc : descriptors) {
-        EXPECT_NE(desc.type, EffectNullUuid);
-        EXPECT_NE(desc.uuid, EffectNullUuid);
+    EXPECT_IS_OK(mEffectFactory->queryEffects(std::nullopt, std::nullopt, std::nullopt, &ids));
+    EXPECT_TRUE(ids.size() >= typeUuidSet.size());
+    for (const auto& id : ids) {
+        typeUuidSet.erase(id.type);
     }
+    std::string msg = " missing type UUID:\n";
+    for (const auto& uuid : typeUuidSet) {
+        msg += (uuid.toString() + "\n");
+    }
+    SCOPED_TRACE(msg);
+    EXPECT_EQ(0UL, typeUuidSet.size());
 }
 
-TEST_P(EffectFactoryTest, QueriedDescriptorNotExistType) {
-    std::vector<Descriptor::Identity> descriptors;
-    mFactory.QueryEffects(EffectNullUuid, std::nullopt, std::nullopt, &descriptors);
-    EXPECT_EQ(descriptors.size(), 0UL);
+TEST_P(EffectFactoryTest, QueryNullTypeUuid) {
+    std::vector<Descriptor::Identity> ids;
+    EXPECT_IS_OK(mEffectFactory->queryEffects(kEffectNullUuid, std::nullopt, std::nullopt, &ids));
+    EXPECT_EQ(ids.size(), 0UL);
 }
 
-TEST_P(EffectFactoryTest, QueriedDescriptorNotExistInstance) {
-    std::vector<Descriptor::Identity> descriptors;
-    mFactory.QueryEffects(std::nullopt, EffectNullUuid, std::nullopt, &descriptors);
-    EXPECT_EQ(descriptors.size(), 0UL);
+TEST_P(EffectFactoryTest, QueriedNullImplUuid) {
+    std::vector<Descriptor::Identity> ids;
+    EXPECT_IS_OK(mEffectFactory->queryEffects(std::nullopt, kEffectNullUuid, std::nullopt, &ids));
+    EXPECT_EQ(ids.size(), 0UL);
 }
 
-TEST_P(EffectFactoryTest, CreateAndDestroyOnce) {
-    std::vector<Descriptor::Identity> descriptors;
-    mFactory.QueryEffects(std::nullopt, std::nullopt, std::nullopt, &descriptors);
-    auto numIds = mFactory.GetEffectIds().size();
-    EXPECT_NE(numIds, 0UL);
-
-    auto& effectMap = mFactory.GetEffectMap();
-    EXPECT_EQ(effectMap.size(), 0UL);
-    mFactory.CreateEffects();
-    EXPECT_EQ(effectMap.size(), numIds);
-    mFactory.DestroyEffects();
-    EXPECT_EQ(effectMap.size(), 0UL);
+TEST_P(EffectFactoryTest, QueriedNullProxyUuid) {
+    std::vector<Descriptor::Identity> ids;
+    EXPECT_IS_OK(mEffectFactory->queryEffects(std::nullopt, std::nullopt, kEffectNullUuid, &ids));
+    EXPECT_EQ(ids.size(), 0UL);
 }
 
-TEST_P(EffectFactoryTest, CreateAndDestroyRepeat) {
-    std::vector<Descriptor::Identity> descriptors;
-    mFactory.QueryEffects(std::nullopt, std::nullopt, std::nullopt, &descriptors);
-    auto numIds = mFactory.GetEffectIds().size();
-    EXPECT_NE(numIds, 0UL);
+// create all effects, and then destroy them all together
+TEST_P(EffectFactoryTest, CreateAndDestroyEffects) {
+    std::vector<Descriptor::Identity> ids;
+    EXPECT_IS_OK(mEffectFactory->queryEffects(std::nullopt, std::nullopt, std::nullopt, &ids));
+    EXPECT_NE(ids.size(), 0UL);
 
-    auto& effectMap = mFactory.GetEffectMap();
-    EXPECT_EQ(effectMap.size(), 0UL);
-    mFactory.CreateEffects();
-    EXPECT_EQ(effectMap.size(), numIds);
-    mFactory.DestroyEffects();
-    EXPECT_EQ(effectMap.size(), 0UL);
-
-    // Create and destroy again
-    mFactory.CreateEffects();
-    EXPECT_EQ(effectMap.size(), numIds);
-    mFactory.DestroyEffects();
-    EXPECT_EQ(effectMap.size(), 0UL);
+    std::vector<std::shared_ptr<IEffect>> effects;
+    effects = createWithIds(ids);
+    EXPECT_EQ(ids.size(), effects.size());
+    destroyEffects(effects);
 }
 
 TEST_P(EffectFactoryTest, CreateMultipleInstanceOfSameEffect) {
-    std::vector<Descriptor::Identity> descriptors;
-    mFactory.QueryEffects(std::nullopt, std::nullopt, std::nullopt, &descriptors);
-    auto numIds = mFactory.GetEffectIds().size();
-    EXPECT_NE(numIds, 0UL);
+    std::vector<Descriptor::Identity> ids;
+    EXPECT_IS_OK(mEffectFactory->queryEffects(std::nullopt, std::nullopt, std::nullopt, &ids));
+    EXPECT_NE(ids.size(), 0UL);
 
-    auto& effectMap = mFactory.GetEffectMap();
-    EXPECT_EQ(effectMap.size(), 0UL);
-    mFactory.CreateEffects();
-    EXPECT_EQ(effectMap.size(), numIds);
-    // Create effect instances of same implementation
-    mFactory.CreateEffects();
-    EXPECT_EQ(effectMap.size(), 2 * numIds);
+    std::vector<std::shared_ptr<IEffect>> effects = createWithIds(ids);
+    EXPECT_EQ(ids.size(), effects.size());
+    std::vector<std::shared_ptr<IEffect>> effects2 = createWithIds(ids);
+    EXPECT_EQ(ids.size(), effects2.size());
+    std::vector<std::shared_ptr<IEffect>> effects3 = createWithIds(ids);
+    EXPECT_EQ(ids.size(), effects3.size());
 
-    mFactory.CreateEffects();
-    EXPECT_EQ(effectMap.size(), 3 * numIds);
+    destroyEffects(effects);
+    destroyEffects(effects2);
+    destroyEffects(effects3);
+}
 
-    mFactory.DestroyEffects();
-    EXPECT_EQ(effectMap.size(), 0UL);
+// create and destroy each effect one by one
+TEST_P(EffectFactoryTest, CreateAndDestroyEffectsOneByOne) {
+    std::vector<Descriptor::Identity> ids;
+    EXPECT_IS_OK(mEffectFactory->queryEffects(std::nullopt, std::nullopt, std::nullopt, &ids));
+    EXPECT_NE(ids.size(), 0UL);
+
+    creatAndDestroyIds(ids);
+}
+
+// for each effect: repeat 3 times create and destroy
+TEST_P(EffectFactoryTest, CreateAndDestroyRepeat) {
+    std::vector<Descriptor::Identity> ids;
+    EXPECT_IS_OK(mEffectFactory->queryEffects(std::nullopt, std::nullopt, std::nullopt, &ids));
+    EXPECT_NE(ids.size(), 0UL);
+
+    creatAndDestroyIds(ids);
+    creatAndDestroyIds(ids);
+    creatAndDestroyIds(ids);
 }
 
 // Expect EX_ILLEGAL_ARGUMENT when create with invalid UUID.
 TEST_P(EffectFactoryTest, CreateWithInvalidUuid) {
-    std::vector<std::pair<Descriptor::Identity, binder_status_t>> descriptors;
-    descriptors.push_back(std::make_pair(nullDesc, EX_ILLEGAL_ARGUMENT));
-    descriptors.push_back(std::make_pair(zeroDesc, EX_ILLEGAL_ARGUMENT));
-
-    auto& effectMap = mFactory.GetEffectMap();
-    mFactory.CreateEffectsAndExpect(descriptors);
-    EXPECT_EQ(effectMap.size(), 0UL);
+    std::vector<Descriptor::Identity> ids = {kNullDesc, kZeroDesc};
+    auto effects = createWithIds(ids, EX_ILLEGAL_ARGUMENT);
+    EXPECT_EQ(effects.size(), 0UL);
 }
 
 // Expect EX_ILLEGAL_ARGUMENT when destroy null interface.
 TEST_P(EffectFactoryTest, DestroyWithInvalidInterface) {
     std::shared_ptr<IEffect> spDummyEffect(nullptr);
-
-    mFactory.DestroyEffectAndExpect(spDummyEffect, EX_ILLEGAL_ARGUMENT);
+    destroyEffects({spDummyEffect}, EX_ILLEGAL_ARGUMENT);
 }
 
-TEST_P(EffectFactoryTest, CreateAndRemoveReference) {
-    std::vector<Descriptor::Identity> descriptors;
-    mFactory.QueryEffects(std::nullopt, std::nullopt, std::nullopt, &descriptors);
-    auto numIds = mFactory.GetEffectIds().size();
-    EXPECT_NE(numIds, 0UL);
+// Same descriptor ID should work after service restart.
+TEST_P(EffectFactoryTest, CreateDestroyWithRestart) {
+    std::vector<Descriptor::Identity> ids;
+    EXPECT_IS_OK(mEffectFactory->queryEffects(std::nullopt, std::nullopt, std::nullopt, &ids));
+    EXPECT_NE(ids.size(), 0UL);
+    creatAndDestroyIds(ids);
 
-    auto& effectMap = mFactory.GetEffectMap();
-    EXPECT_EQ(effectMap.size(), 0UL);
-    mFactory.CreateEffects();
-    EXPECT_EQ(effectMap.size(), numIds);
-    // remove all reference
-    mFactory.ClearEffectMap();
-    EXPECT_EQ(effectMap.size(), 0UL);
+    mFactoryHelper->RestartFactoryService();
+
+    connectAndGetFactory();
+    creatAndDestroyIds(ids);
 }
 
-TEST_P(EffectFactoryTest, CreateRemoveReferenceAndCreateDestroy) {
-    std::vector<Descriptor::Identity> descriptors;
-    mFactory.QueryEffects(std::nullopt, std::nullopt, std::nullopt, &descriptors);
-    auto numIds = mFactory.GetEffectIds().size();
-    EXPECT_NE(numIds, 0UL);
+// Effect handle invalid after restart.
+TEST_P(EffectFactoryTest, EffectInvalidAfterRestart) {
+    std::vector<Descriptor::Identity> ids;
+    EXPECT_IS_OK(mEffectFactory->queryEffects(std::nullopt, std::nullopt, std::nullopt, &ids));
+    EXPECT_NE(ids.size(), 0UL);
+    std::vector<std::shared_ptr<IEffect>> effects = createWithIds(ids);
 
-    auto& effectMap = mFactory.GetEffectMap();
-    EXPECT_EQ(effectMap.size(), 0UL);
-    mFactory.CreateEffects();
-    EXPECT_EQ(effectMap.size(), numIds);
-    // remove all reference
-    mFactory.ClearEffectMap();
-    EXPECT_EQ(effectMap.size(), 0UL);
+    ASSERT_NO_FATAL_FAILURE(mFactoryHelper->RestartFactoryService());
 
-    // Create and destroy again
-    mFactory.CreateEffects();
-    EXPECT_EQ(effectMap.size(), numIds);
-    mFactory.DestroyEffects();
-    EXPECT_EQ(effectMap.size(), 0UL);
+    connectAndGetFactory();
+    destroyEffects(effects, EX_ILLEGAL_ARGUMENT);
 }
 
-TEST_P(EffectFactoryTest, CreateRestartAndCreateDestroy) {
-    std::vector<Descriptor::Identity> descriptors;
-    mFactory.QueryEffects(std::nullopt, std::nullopt, std::nullopt, &descriptors);
-    auto numIds = mFactory.GetEffectIds().size();
-    auto& effectMap = mFactory.GetEffectMap();
-    mFactory.CreateEffects();
-    EXPECT_EQ(effectMap.size(), numIds);
-    ASSERT_NO_FATAL_FAILURE(mFactory.RestartFactoryService());
-
-    mFactory.CreateEffects();
-    EXPECT_EQ(effectMap.size(), numIds);
-    mFactory.DestroyEffects();
-    EXPECT_EQ(effectMap.size(), 0UL);
-}
-
+// expect no error with the queryProcessing interface, but don't check number of processing
 TEST_P(EffectFactoryTest, QueryProcess) {
     std::vector<Processing> processing;
-    mFactory.QueryProcessing(std::nullopt, &processing);
-    // TODO: verify the number of process in example implementation after audio_effects.xml migrated
+    EXPECT_IS_OK(mEffectFactory->queryProcessing(std::nullopt, &processing));
+
+    Processing::Type streamType =
+            Processing::Type::make<Processing::Type::streamType>(AudioStreamType::SYSTEM);
+    std::vector<Processing> processingFilteredByStream;
+    EXPECT_IS_OK(mEffectFactory->queryProcessing(streamType, &processingFilteredByStream));
+
+    Processing::Type source =
+            Processing::Type::make<Processing::Type::source>(AudioSource::DEFAULT);
+    std::vector<Processing> processingFilteredBySource;
+    EXPECT_IS_OK(mEffectFactory->queryProcessing(source, &processingFilteredBySource));
+
+    EXPECT_TRUE(processing.size() >= processingFilteredByStream.size());
+    EXPECT_TRUE(processing.size() >= processingFilteredBySource.size());
 }
 
 INSTANTIATE_TEST_SUITE_P(EffectFactoryTest, EffectFactoryTest,
diff --git a/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp b/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
index 3ea67bc..8212149 100644
--- a/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
@@ -16,26 +16,24 @@
 
 #define LOG_TAG "VtsHalAudioEffectTargetTest"
 
+#include <chrono>
 #include <memory>
 #include <string>
-#include <unordered_map>
-#include <unordered_set>
 #include <vector>
 
+#include <Utils.h>
 #include <aidl/Gtest.h>
 #include <aidl/Vintf.h>
+#include <aidl/android/hardware/audio/effect/IEffect.h>
+#include <aidl/android/hardware/audio/effect/IFactory.h>
 #include <android-base/logging.h>
-#include <android-base/properties.h>
 #include <android/binder_interface_utils.h>
 #include <android/binder_manager.h>
 #include <android/binder_process.h>
-
-#include <Utils.h>
-#include <aidl/android/hardware/audio/effect/IEffect.h>
-#include <aidl/android/hardware/audio/effect/IFactory.h>
-#include <aidl/android/media/audio/common/AudioDeviceType.h>
+#include <fmq/AidlMessageQueue.h>
 
 #include "AudioHalBinderServiceUtil.h"
+#include "EffectFactoryHelper.h"
 #include "EffectHelper.h"
 #include "TestUtils.h"
 
@@ -49,309 +47,725 @@
 using aidl::android::hardware::audio::effect::IFactory;
 using aidl::android::hardware::audio::effect::Parameter;
 using aidl::android::hardware::audio::effect::State;
-using aidl::android::media::audio::common::AudioDeviceType;
 
-class AudioEffectTest : public testing::TestWithParam<std::string>, public EffectHelper {
+enum ParamName { PARAM_INSTANCE_NAME };
+using EffectTestParam = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor::Identity>>;
+
+class AudioEffectTest : public testing::TestWithParam<EffectTestParam>, public EffectHelper {
   public:
-    AudioEffectTest() : EffectHelper(GetParam()) {}
+    AudioEffectTest() { std::tie(mFactory, mIdentity) = std::get<PARAM_INSTANCE_NAME>(GetParam()); }
 
-    void SetUp() override {
-        CreateEffects();
-        initParamCommonFormat();
-        initParamCommon();
-    }
+    void SetUp() override {}
+    void TearDown() override {}
 
-    void TearDown() override {
-        CloseEffects();
-        DestroyEffects();
-    }
+    static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
+    std::shared_ptr<IFactory> mFactory;
+    Descriptor::Identity mIdentity;
 };
 
-TEST_P(AudioEffectTest, OpenEffectTest) {
-    OpenEffects();
+TEST_P(AudioEffectTest, SetupAndTearDown) {
+    // Intentionally empty test body.
 }
 
-TEST_P(AudioEffectTest, OpenAndCloseEffect) {
-    OpenEffects();
-    CloseEffects();
+TEST_P(AudioEffectTest, CreateAndDestroy) {
+    std::shared_ptr<IEffect> effect;
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
 }
 
-TEST_P(AudioEffectTest, CloseUnopenedEffectTest) {
-    CloseEffects();
+TEST_P(AudioEffectTest, OpenAndClose) {
+    std::shared_ptr<IEffect> effect;
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+    ASSERT_NO_FATAL_FAILURE(open(effect));
+    ASSERT_NO_FATAL_FAILURE(close(effect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
 }
 
-TEST_P(AudioEffectTest, DoubleOpenCloseEffects) {
-    OpenEffects();
-    CloseEffects();
-    OpenEffects();
-    CloseEffects();
-
-    OpenEffects();
-    OpenEffects();
-    CloseEffects();
-
-    OpenEffects();
-    CloseEffects();
-    CloseEffects();
+TEST_P(AudioEffectTest, CloseUnopenedEffect) {
+    std::shared_ptr<IEffect> effect;
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+    ASSERT_NO_FATAL_FAILURE(close(effect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
 }
 
-TEST_P(AudioEffectTest, GetDescriptors) {
-    GetEffectDescriptors();
+TEST_P(AudioEffectTest, DoubleOpenAndClose) {
+    std::shared_ptr<IEffect> effect1, effect2;
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect1, mIdentity));
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect2, mIdentity));
+    ASSERT_NO_FATAL_FAILURE(open(effect1));
+    ASSERT_NO_FATAL_FAILURE(open(effect2, 1 /* session */));
+    ASSERT_NO_FATAL_FAILURE(close(effect1));
+    ASSERT_NO_FATAL_FAILURE(close(effect2));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect1));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect2));
 }
 
-TEST_P(AudioEffectTest, DescriptorIdExistAndUnique) {
-    auto checker = [&](const std::shared_ptr<IEffect>& effect) {
-        Descriptor desc;
-        std::vector<Descriptor::Identity> idList;
-        EXPECT_IS_OK(effect->getDescriptor(&desc));
-        QueryEffects(desc.common.id.type, desc.common.id.uuid, desc.common.id.proxy, &idList);
-        // Must have at least one instance.
-        EXPECT_NE(idList.size(), 0UL);
-    };
-    ForEachEffect(checker);
+TEST_P(AudioEffectTest, TripleOpenAndClose) {
+    std::shared_ptr<IEffect> effect1, effect2, effect3;
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect1, mIdentity));
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect2, mIdentity));
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect3, mIdentity));
+    ASSERT_NO_FATAL_FAILURE(open(effect1));
+    ASSERT_NO_FATAL_FAILURE(open(effect2, 1 /* session */));
+    ASSERT_NO_FATAL_FAILURE(open(effect3, 2 /* session */));
+    ASSERT_NO_FATAL_FAILURE(close(effect1));
+    ASSERT_NO_FATAL_FAILURE(close(effect2));
+    ASSERT_NO_FATAL_FAILURE(close(effect3));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect1));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect2));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect3));
+}
 
-    // Check unique with a set
-    auto stringHash = [](const Descriptor::Identity& id) {
-        return std::hash<std::string>()(id.toString());
-    };
-    auto vec = GetCompleteEffectIdList();
-    std::unordered_set<Descriptor::Identity, decltype(stringHash)> idSet(0, stringHash);
-    for (auto it : vec) {
-        EXPECT_EQ(idSet.count(it), 0UL) << it.toString();
-        idSet.insert(it);
+TEST_P(AudioEffectTest, GetDescritorBeforeOpen) {
+    std::shared_ptr<IEffect> effect;
+    Descriptor desc;
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+    ASSERT_NO_FATAL_FAILURE(getDescriptor(effect, desc));
+    EXPECT_EQ(mIdentity.toString(), desc.common.id.toString());
+    EXPECT_NE("", desc.common.name);
+    EXPECT_NE("", desc.common.implementor);
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
+}
+
+TEST_P(AudioEffectTest, GetDescritorAfterOpen) {
+    std::shared_ptr<IEffect> effect;
+    Descriptor beforeOpen, afterOpen, afterClose;
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+    ASSERT_NO_FATAL_FAILURE(getDescriptor(effect, beforeOpen));
+    ASSERT_NO_FATAL_FAILURE(open(effect));
+    ASSERT_NO_FATAL_FAILURE(getDescriptor(effect, afterOpen));
+    EXPECT_EQ(beforeOpen.toString(), afterOpen.toString()) << "\n"
+                                                           << beforeOpen.toString() << "\n"
+                                                           << afterOpen.toString();
+    ASSERT_NO_FATAL_FAILURE(close(effect));
+    ASSERT_NO_FATAL_FAILURE(getDescriptor(effect, afterClose));
+    EXPECT_EQ(beforeOpen.toString(), afterClose.toString()) << "\n"
+                                                            << beforeOpen.toString() << "\n"
+                                                            << afterClose.toString();
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
+}
+
+TEST_P(AudioEffectTest, DescriptorExistAndUnique) {
+    std::shared_ptr<IEffect> effect;
+    Descriptor desc;
+
+    auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor);
+    std::set<Descriptor::Identity> idSet;
+    for (const auto& it : descList) {
+        auto& id = it.second;
+        EXPECT_EQ(0ul, idSet.count(id));
+        idSet.insert(id);
     }
+
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+    ASSERT_NO_FATAL_FAILURE(getDescriptor(effect, desc));
+    EXPECT_EQ(1ul, idSet.count(desc.common.id));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
 }
 
 /// State testing.
 // An effect instance is in INIT state by default after it was created.
 TEST_P(AudioEffectTest, InitStateAfterCreation) {
-    ExpectState(State::INIT);
+    std::shared_ptr<IEffect> effect;
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::INIT));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
 }
 
-// An effect instance transfer to INIT state after it was open successfully with IEffect.open().
+// An effect instance transfer to IDLE state after IEffect.ASSERT_NO_FATAL_FAILURE(open().
 TEST_P(AudioEffectTest, IdleStateAfterOpen) {
-    OpenEffects();
-    ExpectState(State::IDLE);
-    CloseEffects();
+    std::shared_ptr<IEffect> effect;
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+    ASSERT_NO_FATAL_FAILURE(open(effect));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(close(effect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
 }
 
 // An effect instance is in PROCESSING state after it receive an START command.
 TEST_P(AudioEffectTest, ProcessingStateAfterStart) {
-    OpenEffects();
-    CommandEffects(CommandId::START);
-    ExpectState(State::PROCESSING);
-    CommandEffects(CommandId::STOP);
-    CloseEffects();
+    std::shared_ptr<IEffect> effect;
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::INIT));
+    ASSERT_NO_FATAL_FAILURE(open(effect));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::PROCESSING));
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(close(effect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
 }
 
 // An effect instance transfer to IDLE state after Command.Id.STOP in PROCESSING state.
 TEST_P(AudioEffectTest, IdleStateAfterStop) {
-    OpenEffects();
-    CommandEffects(CommandId::START);
-    ExpectState(State::PROCESSING);
-    CommandEffects(CommandId::STOP);
-    ExpectState(State::IDLE);
-    CloseEffects();
+    std::shared_ptr<IEffect> effect;
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+    ASSERT_NO_FATAL_FAILURE(open(effect));
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::PROCESSING));
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(close(effect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
 }
 
 // An effect instance transfer to IDLE state after Command.Id.RESET in PROCESSING state.
 TEST_P(AudioEffectTest, IdleStateAfterReset) {
-    OpenEffects();
-    CommandEffects(CommandId::START);
-    ExpectState(State::PROCESSING);
-    CommandEffects(CommandId::RESET);
-    ExpectState(State::IDLE);
-    CloseEffects();
+    std::shared_ptr<IEffect> effect;
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+    ASSERT_NO_FATAL_FAILURE(open(effect));
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::PROCESSING));
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::RESET));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(close(effect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
 }
 
-// An effect instance transfer to INIT if instance receive a close() call.
+// An effect instance transfer to INIT after IEffect.ASSERT_NO_FATAL_FAILURE(close().
 TEST_P(AudioEffectTest, InitStateAfterClose) {
-    OpenEffects();
-    CommandEffects(CommandId::START);
-    ExpectState(State::PROCESSING);
-    CommandEffects(CommandId::STOP);
-    ExpectState(State::IDLE);
-    CloseEffects();
-    ExpectState(State::INIT);
+    std::shared_ptr<IEffect> effect;
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+    ASSERT_NO_FATAL_FAILURE(open(effect));
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(close(effect));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::INIT));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
 }
 
 // An effect instance shouldn't accept any command before open.
 TEST_P(AudioEffectTest, NoCommandAcceptedBeforeOpen) {
-    ExpectState(State::INIT);
-    CommandEffectsExpectStatus(CommandId::START, EX_ILLEGAL_STATE);
-    CommandEffectsExpectStatus(CommandId::STOP, EX_ILLEGAL_STATE);
-    CommandEffectsExpectStatus(CommandId::RESET, EX_ILLEGAL_STATE);
-    ExpectState(State::INIT);
+    std::shared_ptr<IEffect> effect;
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START, EX_ILLEGAL_STATE));
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::STOP, EX_ILLEGAL_STATE));
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::RESET, EX_ILLEGAL_STATE));
+    ASSERT_NO_FATAL_FAILURE(open(effect));
+    ASSERT_NO_FATAL_FAILURE(close(effect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
 }
 
 // No-op when receive STOP command in IDLE state.
 TEST_P(AudioEffectTest, StopCommandInIdleStateNoOp) {
-    ExpectState(State::INIT);
-    OpenEffects();
-    ExpectState(State::IDLE);
-    CommandEffects(CommandId::STOP);
-    ExpectState(State::IDLE);
-    CloseEffects();
+    std::shared_ptr<IEffect> effect;
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+    ASSERT_NO_FATAL_FAILURE(open(effect));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(close(effect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
 }
 
-// No-op when receive STOP command in IDLE state.
+// No-op when receive RESET command in IDLE state.
 TEST_P(AudioEffectTest, ResetCommandInIdleStateNoOp) {
-    ExpectState(State::INIT);
-    OpenEffects();
-    ExpectState(State::IDLE);
-    CommandEffects(CommandId::RESET);
-    ExpectState(State::IDLE);
-    CloseEffects();
+    std::shared_ptr<IEffect> effect;
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+    ASSERT_NO_FATAL_FAILURE(open(effect));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::RESET));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(close(effect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
 }
 
 // Repeat START and STOP command.
 TEST_P(AudioEffectTest, RepeatStartAndStop) {
-    OpenEffects();
-    CommandEffects(CommandId::START);
-    ExpectState(State::PROCESSING);
-    CommandEffects(CommandId::STOP);
-    ExpectState(State::IDLE);
-    CommandEffects(CommandId::START);
-    ExpectState(State::PROCESSING);
-    CommandEffects(CommandId::STOP);
-    ExpectState(State::IDLE);
-    CloseEffects();
+    std::shared_ptr<IEffect> effect;
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+    ASSERT_NO_FATAL_FAILURE(open(effect));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::PROCESSING));
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::PROCESSING));
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(close(effect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
 }
 
 // Repeat START and RESET command.
 TEST_P(AudioEffectTest, RepeatStartAndReset) {
-    OpenEffects();
-    CommandEffects(CommandId::START);
-    ExpectState(State::PROCESSING);
-    CommandEffects(CommandId::RESET);
-    ExpectState(State::IDLE);
-    CommandEffects(CommandId::START);
-    ExpectState(State::PROCESSING);
-    CommandEffects(CommandId::RESET);
-    ExpectState(State::IDLE);
-    CloseEffects();
+    std::shared_ptr<IEffect> effect;
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+    ASSERT_NO_FATAL_FAILURE(open(effect));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::PROCESSING));
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::RESET));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::PROCESSING));
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::RESET));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(close(effect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
 }
 
-// Repeat START and STOP command, try to close at PROCESSING state.
+// Try to close an effect instance at PROCESSING state.
 TEST_P(AudioEffectTest, CloseProcessingStateEffects) {
-    OpenEffects();
-    CommandEffects(CommandId::START);
-    ExpectState(State::PROCESSING);
-    CommandEffects(CommandId::STOP);
-    ExpectState(State::IDLE);
-    CommandEffects(CommandId::START);
-    ExpectState(State::PROCESSING);
-    CloseEffects(EX_ILLEGAL_STATE);
-    // cleanup
-    CommandEffects(CommandId::STOP);
-    ExpectState(State::IDLE);
+    std::shared_ptr<IEffect> effect;
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+    ASSERT_NO_FATAL_FAILURE(open(effect));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::PROCESSING));
+
+    ASSERT_NO_FATAL_FAILURE(close(effect, EX_ILLEGAL_STATE));
+
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(close(effect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
 }
 
 // Expect EX_ILLEGAL_STATE if the effect instance is not in a proper state to be destroyed.
 TEST_P(AudioEffectTest, DestroyOpenEffects) {
-    // cleanup all effects.
-    CloseEffects();
-    DestroyEffects();
+    std::shared_ptr<IEffect> effect;
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+    ASSERT_NO_FATAL_FAILURE(open(effect));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
 
-    // open effects, destroy without close, expect to get EX_ILLEGAL_STATE status.
-    CreateEffects();
-    OpenEffects();
-    auto vec = GetCompleteEffectIdList();
-    DestroyEffects(EX_ILLEGAL_STATE, vec.size());
-    CloseEffects();
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect, EX_ILLEGAL_STATE));
+}
+
+// Expect EX_ILLEGAL_STATE if the effect instance is not in a proper state to be destroyed.
+TEST_P(AudioEffectTest, DestroyProcessingEffects) {
+    std::shared_ptr<IEffect> effect;
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+    ASSERT_NO_FATAL_FAILURE(open(effect));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::PROCESSING));
+
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect, EX_ILLEGAL_STATE));
+}
+
+TEST_P(AudioEffectTest, NormalSequenceStates) {
+    std::shared_ptr<IEffect> effect;
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::INIT));
+    ASSERT_NO_FATAL_FAILURE(open(effect));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::PROCESSING));
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::PROCESSING));
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::RESET));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(close(effect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
 }
 
 /// Parameter testing.
 // Verify parameters pass in open can be successfully get.
-TEST_P(AudioEffectTest, VerifyParametersAfterOpen) {
-    OpenEffects();
-    VerifyParameters();
-    CloseEffects();
+TEST_P(AudioEffectTest, VerifyCommonParametersAfterOpen) {
+    std::shared_ptr<IEffect> effect;
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+
+    Parameter::Common common = EffectHelper::createParamCommon();
+    IEffect::OpenEffectReturn ret;
+    ASSERT_NO_FATAL_FAILURE(open(effect, common, std::nullopt /* specific */, &ret, EX_NONE));
+
+    Parameter get = Parameter(), expect = Parameter();
+    expect.set<Parameter::common>(common);
+    Parameter::Id id;
+    id.set<Parameter::Id::commonTag>(Parameter::common);
+    EXPECT_IS_OK(effect->getParameter(id, &get));
+    EXPECT_EQ(expect, get) << expect.toString() << " vs " << get.toString();
+
+    ASSERT_NO_FATAL_FAILURE(close(effect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
 }
 
 // Verify parameters pass in set can be successfully get.
-TEST_P(AudioEffectTest, SetAndGetParameter) {
-    OpenEffects();
-    VerifyParameters();
-    initParamCommon(1 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */,
-                    44100 /* oSampleRate */);
-    SetParameter();
-    VerifyParameters();
-    CloseEffects();
+TEST_P(AudioEffectTest, SetAndGetCommonParameter) {
+    std::shared_ptr<IEffect> effect;
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+    ASSERT_NO_FATAL_FAILURE(open(effect));
+
+    Parameter::Common common = EffectHelper::createParamCommon(
+            0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */);
+    Parameter get = Parameter(), set = Parameter();
+    set.set<Parameter::common>(common);
+    EXPECT_IS_OK(effect->setParameter(set));
+
+    Parameter::Id id;
+    id.set<Parameter::Id::commonTag>(Parameter::common);
+    EXPECT_IS_OK(effect->getParameter(id, &get));
+    EXPECT_EQ(set, get) << set.toString() << " vs " << get.toString();
+
+    ASSERT_NO_FATAL_FAILURE(close(effect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
 }
 
-// Verify parameters pass in set can be successfully get.
+// Verify parameters set and get in PROCESSING state.
 TEST_P(AudioEffectTest, SetAndGetParameterInProcessing) {
-    OpenEffects();
-    VerifyParameters();
-    CommandEffects(CommandId::START);
-    ExpectState(State::PROCESSING);
-    initParamCommon(1 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */,
-                    44100 /* oSampleRate */);
-    SetParameter();
-    VerifyParameters();
-    CommandEffects(CommandId::STOP);
-    ExpectState(State::IDLE);
-    CloseEffects();
+    std::shared_ptr<IEffect> effect;
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+    ASSERT_NO_FATAL_FAILURE(open(effect));
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::PROCESSING));
+
+    Parameter::Common common = EffectHelper::createParamCommon(
+            0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */);
+    Parameter get = Parameter(), set = Parameter();
+    set.set<Parameter::common>(common);
+    EXPECT_IS_OK(effect->setParameter(set));
+
+    Parameter::Id id;
+    id.set<Parameter::Id::commonTag>(Parameter::common);
+    EXPECT_IS_OK(effect->getParameter(id, &get));
+    EXPECT_EQ(set, get) << set.toString() << " vs " << get.toString();
+
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(close(effect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
 }
 
-// Parameters kept after reset.
-TEST_P(AudioEffectTest, ResetAndVerifyParameter) {
-    OpenEffects();
-    VerifyParameters();
-    CommandEffects(CommandId::START);
-    ExpectState(State::PROCESSING);
-    initParamCommon(1 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */,
-                    44100 /* oSampleRate */);
-    SetParameter();
-    VerifyParameters();
-    CommandEffects(CommandId::RESET);
-    ExpectState(State::IDLE);
-    VerifyParameters();
-    CloseEffects();
+// Verify parameters set and get in IDLE state.
+TEST_P(AudioEffectTest, SetAndGetParameterInIdle) {
+    std::shared_ptr<IEffect> effect;
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+    ASSERT_NO_FATAL_FAILURE(open(effect));
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::PROCESSING));
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+
+    Parameter::Common common = EffectHelper::createParamCommon(
+            0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */);
+    Parameter get = Parameter(), set = Parameter();
+    set.set<Parameter::common>(common);
+    EXPECT_IS_OK(effect->setParameter(set));
+
+    Parameter::Id id;
+    id.set<Parameter::Id::commonTag>(Parameter::common);
+    EXPECT_IS_OK(effect->getParameter(id, &get));
+    EXPECT_EQ(set, get) << set.toString() << " vs " << get.toString();
+
+    ASSERT_NO_FATAL_FAILURE(close(effect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
 }
 
-// TODO: need a way to support setting different sessionId to different effect instances
-#if 0
-// Multiple instances of same implementation running.
-TEST_P(AudioEffectTest, MultipleInstancesRunningWithDiffSessionId) {
-    CreateEffects();
-    ExpectState(State::INIT);
-    OpenEffects();
-    ExpectState(State::IDLE);
-    CommandEffects(CommandId::START);
-    ExpectState(State::PROCESSING);
-    initParamCommon(1 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */,
-                    44100 /* oSampleRate */);
-    SetParameter();
-    VerifyParameters();
-    CommandEffects(CommandId::STOP);
-    ExpectState(State::IDLE);
-    VerifyParameters();
-    CloseEffects();
-}
-#endif
+// Verify Parameters kept after stop.
+TEST_P(AudioEffectTest, SetAndGetParameterAfterStop) {
+    std::shared_ptr<IEffect> effect;
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+    ASSERT_NO_FATAL_FAILURE(open(effect));
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::PROCESSING));
 
-// Send data to effects and expect it to consume by check statusMQ.
-TEST_P(AudioEffectTest, ExpectEffectsToConsumeDataInMQ) {
-    OpenEffects();
-    PrepareInputData(mWriteMQBytes);
+    Parameter::Common common = EffectHelper::createParamCommon(
+            0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */);
+    Parameter get = Parameter(), set = Parameter();
+    set.set<Parameter::common>(common);
+    EXPECT_IS_OK(effect->setParameter(set));
 
-    CommandEffects(CommandId::START);
-    writeToFmq(mWriteMQBytes);
-    readFromFmq(mWriteMQBytes);
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
 
-    ExpectState(State::PROCESSING);
-    CommandEffects(CommandId::STOP);
-    // cleanup
-    CommandEffects(CommandId::STOP);
-    ExpectState(State::IDLE);
-    CloseEffects();
+    Parameter::Id id;
+    id.set<Parameter::Id::commonTag>(Parameter::common);
+    EXPECT_IS_OK(effect->getParameter(id, &get));
+    EXPECT_EQ(set, get) << set.toString() << " vs " << get.toString();
+
+    ASSERT_NO_FATAL_FAILURE(close(effect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
 }
 
-INSTANTIATE_TEST_SUITE_P(AudioEffectTestTest, AudioEffectTest,
-                         testing::ValuesIn(android::getAidlHalInstanceNames(IFactory::descriptor)),
-                         android::PrintInstanceNameToString);
+// Verify Parameters kept after reset.
+TEST_P(AudioEffectTest, SetAndGetParameterAfterReset) {
+    std::shared_ptr<IEffect> effect;
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+    ASSERT_NO_FATAL_FAILURE(open(effect));
+
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::PROCESSING));
+
+    Parameter::Common common = EffectHelper::createParamCommon(
+            0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */);
+    Parameter get = Parameter(), set = Parameter();
+    set.set<Parameter::common>(common);
+    EXPECT_IS_OK(effect->setParameter(set));
+
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::RESET));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+
+    Parameter::Id id;
+    id.set<Parameter::Id::commonTag>(Parameter::common);
+    EXPECT_IS_OK(effect->getParameter(id, &get));
+    EXPECT_EQ(set, get) << set.toString() << " vs " << get.toString();
+
+    ASSERT_NO_FATAL_FAILURE(close(effect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
+}
+
+/// Data processing test
+// Send data to effects and expect it to be consumed by checking statusMQ.
+TEST_P(AudioEffectTest, ConsumeDataInProcessingState) {
+    std::shared_ptr<IEffect> effect;
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+
+    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(effect, common, std::nullopt /* specific */, &ret, EX_NONE));
+    auto statusMQ = std::make_unique<EffectHelper::StatusMQ>(ret.statusMQ);
+    auto inputMQ = std::make_unique<EffectHelper::DataMQ>(ret.inputDataMQ);
+    auto outputMQ = std::make_unique<EffectHelper::DataMQ>(ret.outputDataMQ);
+
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::PROCESSING));
+
+    std::vector<float> buffer;
+    EffectHelper::allocateInputData(common, inputMQ, buffer);
+    EffectHelper::writeToFmq(inputMQ, buffer);
+    EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer);
+
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+
+    ASSERT_NO_FATAL_FAILURE(close(effect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
+}
+
+// Send data to effects and expect it to be consumed after effect restart.
+TEST_P(AudioEffectTest, ConsumeDataAfterRestart) {
+    std::shared_ptr<IEffect> effect;
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+
+    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(effect, common, std::nullopt /* specific */, &ret, EX_NONE));
+    auto statusMQ = std::make_unique<EffectHelper::StatusMQ>(ret.statusMQ);
+    auto inputMQ = std::make_unique<EffectHelper::DataMQ>(ret.inputDataMQ);
+    auto outputMQ = std::make_unique<EffectHelper::DataMQ>(ret.outputDataMQ);
+
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::PROCESSING));
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::PROCESSING));
+
+    std::vector<float> buffer;
+    EffectHelper::allocateInputData(common, inputMQ, buffer);
+    EffectHelper::writeToFmq(inputMQ, buffer);
+    EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer);
+
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+
+    ASSERT_NO_FATAL_FAILURE(close(effect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
+}
+
+// Send data to IDLE effects and expect it to be consumed after effect start.
+TEST_P(AudioEffectTest, SendDataAtIdleAndConsumeDataInProcessing) {
+    std::shared_ptr<IEffect> effect;
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+
+    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(effect, common, std::nullopt /* specific */, &ret, EX_NONE));
+    auto statusMQ = std::make_unique<EffectHelper::StatusMQ>(ret.statusMQ);
+    auto inputMQ = std::make_unique<EffectHelper::DataMQ>(ret.inputDataMQ);
+    auto outputMQ = std::make_unique<EffectHelper::DataMQ>(ret.outputDataMQ);
+
+    std::vector<float> buffer;
+    EffectHelper::allocateInputData(common, inputMQ, buffer);
+    EffectHelper::writeToFmq(inputMQ, buffer);
+    EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer);
+
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::PROCESSING));
+
+    EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer);
+
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+
+    ASSERT_NO_FATAL_FAILURE(close(effect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
+}
+
+// Send data multiple times.
+TEST_P(AudioEffectTest, ProcessDataMultipleTimes) {
+    std::shared_ptr<IEffect> effect;
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+
+    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(effect, common, std::nullopt /* specific */, &ret, EX_NONE));
+    auto statusMQ = std::make_unique<EffectHelper::StatusMQ>(ret.statusMQ);
+    auto inputMQ = std::make_unique<EffectHelper::DataMQ>(ret.inputDataMQ);
+    auto outputMQ = std::make_unique<EffectHelper::DataMQ>(ret.outputDataMQ);
+
+    std::vector<float> buffer;
+    EffectHelper::allocateInputData(common, inputMQ, buffer);
+    EffectHelper::writeToFmq(inputMQ, buffer);
+    EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer);
+
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::PROCESSING));
+
+    EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer);
+    // expect no status and data after consume
+    EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer);
+
+    EffectHelper::writeToFmq(inputMQ, buffer);
+    EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer);
+    // expect no status and data after consume
+    EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer);
+
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+
+    ASSERT_NO_FATAL_FAILURE(close(effect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
+}
+
+// Send data to IDLE state effects and expect it not be consumed.
+TEST_P(AudioEffectTest, NotConsumeDataInIdleState) {
+    std::shared_ptr<IEffect> effect;
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+
+    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(effect, common, std::nullopt /* specific */, &ret, EX_NONE));
+    auto statusMQ = std::make_unique<EffectHelper::StatusMQ>(ret.statusMQ);
+    auto inputMQ = std::make_unique<EffectHelper::DataMQ>(ret.inputDataMQ);
+    auto outputMQ = std::make_unique<EffectHelper::DataMQ>(ret.outputDataMQ);
+
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::PROCESSING));
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+
+    std::vector<float> buffer;
+    EffectHelper::allocateInputData(common, inputMQ, buffer);
+    EffectHelper::writeToFmq(inputMQ, buffer);
+    EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer);
+
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::PROCESSING));
+    EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer);
+
+    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+
+    ASSERT_NO_FATAL_FAILURE(close(effect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
+}
+
+// Send data to closed effects and expect it not be consumed.
+TEST_P(AudioEffectTest, NotConsumeDataByClosedEffect) {
+    std::shared_ptr<IEffect> effect;
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+
+    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(effect, common, std::nullopt /* specific */, &ret, EX_NONE));
+    ASSERT_NO_FATAL_FAILURE(close(effect));
+
+    auto statusMQ = std::make_unique<EffectHelper::StatusMQ>(ret.statusMQ);
+    auto inputMQ = std::make_unique<EffectHelper::DataMQ>(ret.inputDataMQ);
+    auto outputMQ = std::make_unique<EffectHelper::DataMQ>(ret.outputDataMQ);
+
+    std::vector<float> buffer;
+    EffectHelper::allocateInputData(common, inputMQ, buffer);
+    EffectHelper::writeToFmq(inputMQ, buffer);
+    EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer);
+
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
+}
+
+// Send data to multiple effects.
+TEST_P(AudioEffectTest, ConsumeDataMultipleEffects) {
+    std::shared_ptr<IEffect> effect1, effect2;
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect1, mIdentity));
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect2, mIdentity));
+
+    Parameter::Common common1 = EffectHelper::createParamCommon(
+            0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
+            kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
+    Parameter::Common common2 = EffectHelper::createParamCommon(
+            1 /* session */, 1 /* ioHandle */, 48000 /* iSampleRate */, 48000 /* oSampleRate */,
+            2 * kInputFrameCount /* iFrameCount */, 2 * kOutputFrameCount /* oFrameCount */);
+    IEffect::OpenEffectReturn ret1, ret2;
+    ASSERT_NO_FATAL_FAILURE(open(effect1, common1, std::nullopt /* specific */, &ret1, EX_NONE));
+    ASSERT_NO_FATAL_FAILURE(open(effect2, common2, std::nullopt /* specific */, &ret2, EX_NONE));
+    ASSERT_NO_FATAL_FAILURE(command(effect1, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect1, State::PROCESSING));
+    ASSERT_NO_FATAL_FAILURE(command(effect2, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect2, State::PROCESSING));
+
+    auto statusMQ1 = std::make_unique<EffectHelper::StatusMQ>(ret1.statusMQ);
+    auto inputMQ1 = std::make_unique<EffectHelper::DataMQ>(ret1.inputDataMQ);
+    auto outputMQ1 = std::make_unique<EffectHelper::DataMQ>(ret1.outputDataMQ);
+
+    std::vector<float> buffer1, buffer2;
+    EffectHelper::allocateInputData(common1, inputMQ1, buffer1);
+    EffectHelper::writeToFmq(inputMQ1, buffer1);
+    EffectHelper::readFromFmq(statusMQ1, 1, outputMQ1, buffer1.size(), buffer1);
+
+    auto statusMQ2 = std::make_unique<EffectHelper::StatusMQ>(ret2.statusMQ);
+    auto inputMQ2 = std::make_unique<EffectHelper::DataMQ>(ret2.inputDataMQ);
+    auto outputMQ2 = std::make_unique<EffectHelper::DataMQ>(ret2.outputDataMQ);
+    EffectHelper::allocateInputData(common2, inputMQ2, buffer2);
+    EffectHelper::writeToFmq(inputMQ2, buffer2);
+    EffectHelper::readFromFmq(statusMQ2, 1, outputMQ2, buffer2.size(), buffer2);
+
+    ASSERT_NO_FATAL_FAILURE(command(effect1, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect1, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(close(effect1));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect1));
+
+    ASSERT_NO_FATAL_FAILURE(command(effect2, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect2, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(close(effect2));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect2));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        SingleEffectInstanceTest, AudioEffectTest,
+        ::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::replace_if(
+                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+            return name;
+        });
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioEffectTest);
 
 int main(int argc, char** argv) {
diff --git a/audio/aidl/vts/VtsHalEqualizerTargetTest.cpp b/audio/aidl/vts/VtsHalEqualizerTargetTest.cpp
index 4162551..f19dff6 100644
--- a/audio/aidl/vts/VtsHalEqualizerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalEqualizerTargetTest.cpp
@@ -35,8 +35,6 @@
 #include <Utils.h>
 #include <aidl/android/hardware/audio/effect/IEffect.h>
 #include <aidl/android/hardware/audio/effect/IFactory.h>
-#include <aidl/android/media/audio/common/AudioChannelLayout.h>
-#include <aidl/android/media/audio/common/AudioDeviceType.h>
 
 #include "AudioHalBinderServiceUtil.h"
 #include "EffectHelper.h"
@@ -47,103 +45,126 @@
 
 using aidl::android::hardware::audio::effect::Capability;
 using aidl::android::hardware::audio::effect::Descriptor;
-using aidl::android::hardware::audio::effect::EffectNullUuid;
 using aidl::android::hardware::audio::effect::Equalizer;
-using aidl::android::hardware::audio::effect::EqualizerTypeUUID;
 using aidl::android::hardware::audio::effect::IEffect;
 using aidl::android::hardware::audio::effect::IFactory;
+using aidl::android::hardware::audio::effect::kEqualizerTypeUUID;
 using aidl::android::hardware::audio::effect::Parameter;
 
 /**
- * Here we focus on specific parameter checking, general IEffect interfaces testing performed in
- * VtsAudioEfectTargetTest.
+ * Here we focus on specific effect (equalizer) parameter checking, general IEffect interfaces
+ * testing performed in VtsAudioEfectTargetTest.
  */
-enum ParamName { PARAM_INSTANCE_NAME, PARAM_PRESET_INDEX, PARAM_BAND_INDEX, PARAM_BAND_LEVEL };
-using EqualizerParamTestParam = std::tuple<std::string, int, int, int>;
+
+enum ParamName { PARAM_INSTANCE_NAME, PARAM_BAND_LEVEL };
+using EqualizerParamTestParam =
+        std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor::Identity>, int>;
 
 /*
 Testing parameter range, assuming the parameter supported by effect is in this range.
 This range is verified with IEffect.getDescriptor(), for any index supported vts expect EX_NONE
 from IEffect.setParameter(), otherwise expect EX_ILLEGAL_ARGUMENT.
 */
-constexpr std::pair<int, int> kPresetIndexRange = {-1, 10};  // valid range [0, 9]
-constexpr std::pair<int, int> kBandIndexRange = {-1, 5};     // valid range [0, 4]
-constexpr std::pair<int, int> kBandLevelRange = {-5, 5};     // needs update with implementation
+const std::vector<int> kBandLevels = {0, -10, 10};  // needs update with implementation
 
-class EqualizerParamTest : public ::testing::TestWithParam<EqualizerParamTestParam>,
-                           public EffectHelper {
+class EqualizerTest : public ::testing::TestWithParam<EqualizerParamTestParam>,
+                      public EffectHelper {
   public:
-    EqualizerParamTest()
-        : EffectHelper(std::get<PARAM_INSTANCE_NAME>(GetParam())),
-          mParamPresetIndex(std::get<PARAM_PRESET_INDEX>(GetParam())),
-          mParamBandIndex(std::get<PARAM_BAND_INDEX>(GetParam())),
-          mParamBandLevel(std::get<PARAM_BAND_LEVEL>(GetParam())) {}
+    EqualizerTest() : mBandLevel(std::get<PARAM_BAND_LEVEL>(GetParam())) {
+        std::tie(mFactory, mIdentity) = std::get<PARAM_INSTANCE_NAME>(GetParam());
+    }
 
     void SetUp() override {
-        CreateEffectsWithUUID(EqualizerTypeUUID);
-        initParamCommonFormat();
-        initParamCommon();
-        initParamSpecific();
-        OpenEffects(EqualizerTypeUUID);
-        SCOPED_TRACE(testing::Message() << "preset: " << mParamPresetIndex << " bandIdx "
-                                        << mParamBandIndex << " level " << mParamBandLevel);
-    }
+        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);
+        ASSERT_NO_FATAL_FAILURE(setTagRange());
+    }
     void TearDown() override {
-        CloseEffects();
-        DestroyEffects();
-        CleanUp();
+        ASSERT_NO_FATAL_FAILURE(close(mEffect));
+        ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
     }
 
-    int mParamPresetIndex = 0;
-    int mParamBandIndex = 0;
-    int mParamBandLevel = 0;
+    std::pair<int, int> setPresetIndexRange(const Equalizer::Capability& cap) const {
+        const auto [min, max] =
+                std::minmax_element(cap.presets.begin(), cap.presets.end(),
+                                    [](const auto& a, const auto& b) { return a.index < b.index; });
+        return {min->index, max->index};
+    }
+    std::pair<int, int> setBandIndexRange(const Equalizer::Capability& cap) const {
+        const auto [min, max] =
+                std::minmax_element(cap.bandFrequencies.begin(), cap.bandFrequencies.end(),
+                                    [](const auto& a, const auto& b) { return a.index < b.index; });
+        return {min->index, max->index};
+    }
+    void setTagRange() {
+        Descriptor desc;
+        ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
+        Equalizer::Capability& eqCap = desc.capability.get<Capability::equalizer>();
+        mPresetIndex = setPresetIndexRange(eqCap);
+        mBandIndex = setBandIndexRange(eqCap);
+    }
+
+    static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
+    std::shared_ptr<IFactory> mFactory;
+    std::shared_ptr<IEffect> mEffect;
+    Descriptor::Identity mIdentity;
+    std::pair<int, int> mPresetIndex;
+    std::pair<int, int> mBandIndex;
+    const int mBandLevel;
+    Descriptor mDesc;
 
     void SetAndGetEqualizerParameters() {
-        auto functor = [&](const std::shared_ptr<IEffect>& effect) {
-            for (auto& it : mTags) {
-                auto& tag = it.first;
-                auto& eq = it.second;
+        ASSERT_NE(nullptr, mEffect);
+        for (auto& it : mTags) {
+            auto& tag = it.first;
+            auto& eq = it.second;
 
-                // validate parameter
-                Descriptor desc;
-                ASSERT_STATUS(EX_NONE, effect->getDescriptor(&desc));
-                const bool valid = isTagInRange(it.first, it.second, desc);
-                const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
+            // validate parameter
+            const bool valid = isTagInRange(it.first, it.second);
+            const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
 
-                // set
-                Parameter expectParam;
-                Parameter::Specific specific;
-                specific.set<Parameter::Specific::equalizer>(*eq.get());
-                expectParam.set<Parameter::specific>(specific);
-                EXPECT_STATUS(expected, effect->setParameter(expectParam))
-                        << expectParam.toString();
+            // set
+            Parameter expectParam;
+            Parameter::Specific specific;
+            specific.set<Parameter::Specific::equalizer>(eq);
+            expectParam.set<Parameter::specific>(specific);
+            EXPECT_STATUS(expected, mEffect->setParameter(expectParam))
+                    << expectParam.toString() << "\n"
+                    << mDesc.toString();
 
-                // only get if parameter in range and set success
-                if (expected == EX_NONE) {
-                    Parameter getParam;
-                    Parameter::Id id;
-                    Equalizer::Id eqId;
-                    eqId.set<Equalizer::Id::commonTag>(tag);
-                    id.set<Parameter::Id::equalizerTag>(eqId);
-                    // if set success, then get should match
-                    EXPECT_STATUS(expected, effect->getParameter(id, &getParam));
-                    EXPECT_TRUE(isEqParameterExpected(expectParam, getParam));
-                }
+            // only get if parameter in range and set success
+            if (expected == EX_NONE) {
+                Parameter getParam;
+                Parameter::Id id;
+                Equalizer::Id eqId;
+                eqId.set<Equalizer::Id::commonTag>(tag);
+                id.set<Parameter::Id::equalizerTag>(eqId);
+                // if set success, then get should match
+                EXPECT_STATUS(expected, mEffect->getParameter(id, &getParam));
+                EXPECT_TRUE(isEqParameterExpected(expectParam, getParam))
+                        << "\nexpect:" << expectParam.toString()
+                        << "\ngetParam:" << getParam.toString();
             }
-        };
-        EXPECT_NO_FATAL_FAILURE(ForEachEffect(functor));
+        }
     }
 
     bool isEqParameterExpected(const Parameter& expect, const Parameter& target) {
-        // if parameter same, then for sure matched
+        // if parameter same, then for sure they are matched
         if (expect == target) return true;
 
         // if not, see if target include the expect parameter, and others all default (0).
         /*
-            This is verify the case of client setParameter to a single bandLevel ({3, -1} for
-           example), and return of getParameter must be [{0, 0}, {1, 0}, {2, 0}, {3, -1}, {4, 0}]
-        */
+         * This is to verify the case of client setParameter to a single bandLevel ({3, -1} for
+         * example), and return of getParameter must be [{0, 0}, {1, 0}, {2, 0}, {3, -1}, {4, 0}]
+         */
         EXPECT_EQ(expect.getTag(), Parameter::specific);
         EXPECT_EQ(target.getTag(), Parameter::specific);
 
@@ -160,10 +181,16 @@
         switch (eqTag) {
             case Equalizer::bandLevels: {
                 auto expectBl = expectEq.get<Equalizer::bandLevels>();
+                std::sort(expectBl.begin(), expectBl.end(),
+                          [](const auto& a, const auto& b) { return a.index < b.index; });
+                expectBl.erase(std::unique(expectBl.begin(), expectBl.end()), expectBl.end());
                 auto targetBl = targetEq.get<Equalizer::bandLevels>();
                 return std::includes(targetBl.begin(), targetBl.end(), expectBl.begin(),
                                      expectBl.end());
             }
+            case Equalizer::preset: {
+                return expectEq.get<Equalizer::preset>() == targetEq.get<Equalizer::preset>();
+            }
             default:
                 return false;
         }
@@ -173,27 +200,24 @@
     void addPresetParam(int preset) {
         Equalizer eq;
         eq.set<Equalizer::preset>(preset);
-        mTags.push_back({Equalizer::preset, std::make_unique<Equalizer>(std::move(eq))});
+        mTags.push_back({Equalizer::preset, eq});
     }
 
     void addBandLevelsParam(std::vector<Equalizer::BandLevel>& bandLevels) {
         Equalizer eq;
         eq.set<Equalizer::bandLevels>(bandLevels);
-        mTags.push_back({Equalizer::bandLevels, std::make_unique<Equalizer>(std::move(eq))});
+        mTags.push_back({Equalizer::bandLevels, eq});
     }
 
-    bool isTagInRange(const Equalizer::Tag& tag, const std::unique_ptr<Equalizer>& eq,
-                      const Descriptor& desc) const {
-        std::cout << "xxx" << toString(tag) << " " << desc.toString();
-        const Equalizer::Capability& eqCap = desc.capability.get<Capability::equalizer>();
+    bool isTagInRange(const Equalizer::Tag& tag, const Equalizer& eq) const {
         switch (tag) {
             case Equalizer::preset: {
-                int index = eq->get<Equalizer::preset>();
-                return isPresetIndexInRange(eqCap, index);
+                int index = eq.get<Equalizer::preset>();
+                return index >= mPresetIndex.first && index <= mPresetIndex.second;
             }
             case Equalizer::bandLevels: {
-                auto& bandLevel = eq->get<Equalizer::bandLevels>();
-                return isBandIndexInRange(eqCap, bandLevel);
+                auto& bandLevel = eq.get<Equalizer::bandLevels>();
+                return isBandInRange(bandLevel);
             }
             default:
                 return false;
@@ -201,78 +225,125 @@
         return false;
     }
 
-    bool isPresetIndexInRange(const Equalizer::Capability& cap, int idx) const {
-        const auto [min, max] =
-                std::minmax_element(cap.presets.begin(), cap.presets.end(),
-                                    [](const auto& a, const auto& b) { return a.index < b.index; });
-        return idx >= min->index && idx <= max->index;
-    }
-
-    bool isBandIndexInRange(const Equalizer::Capability& cap,
-                            const std::vector<Equalizer::BandLevel>& bandLevel) const {
+    bool isBandInRange(const std::vector<Equalizer::BandLevel>& bandLevel) const {
         for (auto& it : bandLevel) {
-            if (!isBandIndexInRange(cap, it.index)) return false;
+            if (it.index < mBandIndex.first || it.index > mBandIndex.second) return false;
         }
         return true;
     }
 
-    bool isBandIndexInRange(const Equalizer::Capability& cap, int idx) const {
-        const auto [min, max] =
-                std::minmax_element(cap.bandFrequencies.begin(), cap.bandFrequencies.end(),
-                                    [](const auto& a, const auto& b) { return a.index < b.index; });
-        return idx >= min->index && idx <= max->index;
+    Parameter::Specific getDefaultParamSpecific() {
+        Equalizer eq = Equalizer::make<Equalizer::preset>(0);
+        Parameter::Specific specific =
+                Parameter::Specific::make<Parameter::Specific::equalizer>(eq);
+        return specific;
     }
 
   private:
-    std::vector<std::pair<Equalizer::Tag, std::unique_ptr<Equalizer>>> mTags;
+    std::vector<std::pair<Equalizer::Tag, Equalizer>> mTags;
 
     bool validCapabilityTag(Capability& cap) { return cap.getTag() == Capability::equalizer; }
 
-    void initParamSpecific() {
-        Equalizer eq;
-        eq.set<Equalizer::preset>(0);
-        Parameter::Specific specific;
-        specific.set<Parameter::Specific::equalizer>(eq);
-        setSpecific(specific);
-    }
-
     void CleanUp() { mTags.clear(); }
 };
 
-TEST_P(EqualizerParamTest, SetAndGetPreset) {
-    EXPECT_NO_FATAL_FAILURE(addPresetParam(mParamPresetIndex));
-    SetAndGetEqualizerParameters();
+TEST_P(EqualizerTest, SetAndGetPresetOutOfLowerBound) {
+    addPresetParam(mPresetIndex.second - 1);
+    ASSERT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
 }
 
-TEST_P(EqualizerParamTest, SetAndGetSingleBand) {
-    std::vector<Equalizer::BandLevel> bandLevels;
-    Equalizer::BandLevel bandLevel = {mParamBandIndex, mParamBandLevel};
-    bandLevels.push_back(bandLevel);
-    EXPECT_NO_FATAL_FAILURE(addBandLevelsParam(bandLevels));
-    SetAndGetEqualizerParameters();
+TEST_P(EqualizerTest, SetAndGetPresetOutOfUpperBound) {
+    addPresetParam(mPresetIndex.second + 1);
+    EXPECT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
+}
+
+TEST_P(EqualizerTest, SetAndGetPresetAtLowerBound) {
+    addPresetParam(mPresetIndex.first);
+    EXPECT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
+}
+
+TEST_P(EqualizerTest, SetAndGetPresetAtHigherBound) {
+    addPresetParam(mPresetIndex.second);
+    EXPECT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
+}
+
+TEST_P(EqualizerTest, SetAndGetPresetInBound) {
+    addPresetParam((mPresetIndex.first + mPresetIndex.second) >> 1);
+    EXPECT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
+}
+
+TEST_P(EqualizerTest, SetAndGetBandOutOfLowerBound) {
+    std::vector<Equalizer::BandLevel> bandLevels{{mBandIndex.first - 1, mBandLevel}};
+    addBandLevelsParam(bandLevels);
+    EXPECT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
+}
+
+TEST_P(EqualizerTest, SetAndGetBandOutOfUpperBound) {
+    std::vector<Equalizer::BandLevel> bandLevels{{mBandIndex.second + 1, mBandLevel}};
+    addBandLevelsParam(bandLevels);
+    EXPECT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
+}
+
+TEST_P(EqualizerTest, SetAndGetBandAtLowerBound) {
+    std::vector<Equalizer::BandLevel> bandLevels{{mBandIndex.first, mBandLevel}};
+    addBandLevelsParam(bandLevels);
+    EXPECT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
+}
+
+TEST_P(EqualizerTest, SetAndGetBandAtHigherBound) {
+    std::vector<Equalizer::BandLevel> bandLevels{{mBandIndex.second, mBandLevel}};
+    addBandLevelsParam(bandLevels);
+    EXPECT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
+}
+
+TEST_P(EqualizerTest, SetAndGetBandInBound) {
+    std::vector<Equalizer::BandLevel> bandLevels{
+            {(mBandIndex.first + mBandIndex.second) >> 1, mBandLevel}};
+    addBandLevelsParam(bandLevels);
+    EXPECT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
+}
+
+TEST_P(EqualizerTest, SetAndGetMultiBands) {
+    addPresetParam(mPresetIndex.first);
+    std::vector<Equalizer::BandLevel> bandLevels{
+            {mBandIndex.first, mBandLevel},
+            {mBandIndex.second, mBandLevel},
+            {(mBandIndex.first + mBandIndex.second) >> 1, mBandLevel}};
+    addBandLevelsParam(bandLevels);
+    EXPECT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
+}
+
+TEST_P(EqualizerTest, SetAndGetMultipleParams) {
+    std::vector<Equalizer::BandLevel> bandLevels{
+            {(mBandIndex.first + mBandIndex.second) >> 1, mBandLevel}};
+    addBandLevelsParam(bandLevels);
+    addPresetParam((mPresetIndex.first + mPresetIndex.second) >> 1);
+    EXPECT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
 }
 
 INSTANTIATE_TEST_SUITE_P(
-        EqualizerTest, EqualizerParamTest,
-        ::testing::Combine(
-                testing::ValuesIn(android::getAidlHalInstanceNames(IFactory::descriptor)),
-                testing::Range(kPresetIndexRange.first, kPresetIndexRange.second),
-                testing::Range(kBandIndexRange.first, kBandIndexRange.second),
-                testing::Range(kBandLevelRange.first, kBandLevelRange.second)),
-        [](const testing::TestParamInfo<EqualizerParamTest::ParamType>& info) {
-            std::string instance = std::get<PARAM_INSTANCE_NAME>(info.param);
-            std::string presetIdx = std::to_string(std::get<PARAM_PRESET_INDEX>(info.param));
-            std::string bandIdx = std::to_string(std::get<PARAM_BAND_INDEX>(info.param));
+        EqualizerTest, EqualizerTest,
+        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+                                   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::string name = instance + "_presetIndex" + presetIdx + "_bandIndex" + bandIdx +
-                               "_bandLevel" + bandLevel;
+            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::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
         });
-
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EqualizerParamTest);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EqualizerTest);
 
 int main(int argc, char** argv) {
     ::testing::InitGoogleTest(&argc, argv);
diff --git a/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp b/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
index 2ad016d..1485657 100644
--- a/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
@@ -27,8 +27,8 @@
 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::kLoudnessEnhancerTypeUUID;
 using aidl::android::hardware::audio::effect::LoudnessEnhancer;
-using aidl::android::hardware::audio::effect::LoudnessEnhancerTypeUUID;
 using aidl::android::hardware::audio::effect::Parameter;
 
 /**
@@ -36,7 +36,8 @@
  * VtsAudioEffectTargetTest.
  */
 enum ParamName { PARAM_INSTANCE_NAME, PARAM_GAIN_MB };
-using LoudnessEnhancerParamTestParam = std::tuple<std::string, int>;
+using LoudnessEnhancerParamTestParam =
+        std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor::Identity>, int>;
 
 // Every int 32 bit value is a valid gain, so testing the corner cases and one regular value.
 // TODO : Update the test values once range/capability is updated by implementation.
@@ -46,53 +47,64 @@
 class LoudnessEnhancerParamTest : public ::testing::TestWithParam<LoudnessEnhancerParamTestParam>,
                                   public EffectHelper {
   public:
-    LoudnessEnhancerParamTest()
-        : EffectHelper(std::get<PARAM_INSTANCE_NAME>(GetParam())),
-          mParamGainMb(std::get<PARAM_GAIN_MB>(GetParam())) {}
+    LoudnessEnhancerParamTest() : mParamGainMb(std::get<PARAM_GAIN_MB>(GetParam())) {
+        std::tie(mFactory, mIdentity) = std::get<PARAM_INSTANCE_NAME>(GetParam());
+    }
 
     void SetUp() override {
-        CreateEffectsWithUUID(LoudnessEnhancerTypeUUID);
-        initParamCommonFormat();
-        initParamCommon();
-        initParamSpecific();
-        OpenEffects(LoudnessEnhancerTypeUUID);
-        SCOPED_TRACE(testing::Message() << "gainMb: " << mParamGainMb);
-    }
+        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 {
-        CloseEffects();
-        DestroyEffects();
-        CleanUp();
+        ASSERT_NO_FATAL_FAILURE(close(mEffect));
+        ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
     }
 
+    Parameter::Specific getDefaultParamSpecific() {
+        LoudnessEnhancer le = LoudnessEnhancer::make<LoudnessEnhancer::gainMb>(0);
+        Parameter::Specific specific =
+                Parameter::Specific::make<Parameter::Specific::loudnessEnhancer>(le);
+        return specific;
+    }
+
+    static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
+    std::shared_ptr<IFactory> mFactory;
+    std::shared_ptr<IEffect> mEffect;
+    Descriptor::Identity mIdentity;
     int mParamGainMb = 0;
 
-    void SetAndGetLoudnessEnhancerParameters() {
-        auto functor = [&](const std::shared_ptr<IEffect>& effect) {
-            for (auto& it : mTags) {
-                auto& tag = it.first;
-                auto& le = it.second;
+    void SetAndGetParameters() {
+        for (auto& it : mTags) {
+            auto& tag = it.first;
+            auto& le = it.second;
 
-                // set parameter
-                Parameter expectParam;
-                Parameter::Specific specific;
-                specific.set<Parameter::Specific::loudnessEnhancer>(le);
-                expectParam.set<Parameter::specific>(specific);
-                // All values are valid, set parameter should succeed
-                EXPECT_STATUS(EX_NONE, effect->setParameter(expectParam)) << expectParam.toString();
+            // set parameter
+            Parameter expectParam;
+            Parameter::Specific specific;
+            specific.set<Parameter::Specific::loudnessEnhancer>(le);
+            expectParam.set<Parameter::specific>(specific);
+            // All values are valid, set parameter should succeed
+            EXPECT_STATUS(EX_NONE, mEffect->setParameter(expectParam)) << expectParam.toString();
 
-                // get parameter
-                Parameter getParam;
-                Parameter::Id id;
-                LoudnessEnhancer::Id leId;
-                leId.set<LoudnessEnhancer::Id::commonTag>(tag);
-                id.set<Parameter::Id::loudnessEnhancerTag>(leId);
-                EXPECT_STATUS(EX_NONE, effect->getParameter(id, &getParam));
+            // get parameter
+            Parameter getParam;
+            Parameter::Id id;
+            LoudnessEnhancer::Id leId;
+            leId.set<LoudnessEnhancer::Id::commonTag>(tag);
+            id.set<Parameter::Id::loudnessEnhancerTag>(leId);
+            EXPECT_STATUS(EX_NONE, mEffect->getParameter(id, &getParam));
 
-                EXPECT_EQ(expectParam, getParam);
-            }
-        };
-        EXPECT_NO_FATAL_FAILURE(ForEachEffect(functor));
+            EXPECT_EQ(expectParam, getParam) << "\nexpect:" << expectParam.toString()
+                                             << "\ngetParam:" << getParam.toString();
+        }
     }
 
     void addGainMbParam(int gainMb) {
@@ -103,33 +115,33 @@
 
   private:
     std::vector<std::pair<LoudnessEnhancer::Tag, LoudnessEnhancer>> mTags;
-
-    void initParamSpecific() {
-        LoudnessEnhancer le;
-        le.set<LoudnessEnhancer::gainMb>(0);
-        Parameter::Specific specific;
-        specific.set<Parameter::Specific::loudnessEnhancer>(le);
-        setSpecific(specific);
-    }
-
     void CleanUp() { mTags.clear(); }
 };
 
 TEST_P(LoudnessEnhancerParamTest, SetAndGetGainMb) {
     EXPECT_NO_FATAL_FAILURE(addGainMbParam(mParamGainMb));
-    SetAndGetLoudnessEnhancerParameters();
+    SetAndGetParameters();
 }
 
 INSTANTIATE_TEST_SUITE_P(
         LoudnessEnhancerTest, LoudnessEnhancerParamTest,
-        ::testing::Combine(
-                testing::ValuesIn(android::getAidlHalInstanceNames(IFactory::descriptor)),
-                testing::ValuesIn(kGainMbValues)),
+        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+                                   IFactory::descriptor, kLoudnessEnhancerTypeUUID)),
+                           testing::ValuesIn(kGainMbValues)),
         [](const testing::TestParamInfo<LoudnessEnhancerParamTest::ParamType>& info) {
-            std::string instance = std::get<PARAM_INSTANCE_NAME>(info.param);
+            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::string name = instance + "_gainMb" + gainMb;
+            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::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
