Merge changes Ib89e0924,Id2816580

* changes:
  Add default implementation and VTS for ISoundDose
  Add HAL interface definition for sound dose
diff --git a/audio/aidl/default/equalizer/EqualizerSw.h b/audio/aidl/default/equalizer/EqualizerSw.h
index 81bcd7a..65a8002 100644
--- a/audio/aidl/default/equalizer/EqualizerSw.h
+++ b/audio/aidl/default/equalizer/EqualizerSw.h
@@ -53,8 +53,9 @@
                 LOG(ERROR) << __func__ << " index illegal, skip: " << it.index << " - "
                            << it.levelMb;
                 ret = RetCode::ERROR_ILLEGAL_PARAMETER;
+            } else {
+                mBandLevels[it.index] = it.levelMb;
             }
-            mBandLevels[it.index] = it.levelMb;
         }
         return ret;
     }
diff --git a/audio/aidl/default/include/effect-impl/EffectContext.h b/audio/aidl/default/include/effect-impl/EffectContext.h
index 95645d5..1f39db0 100644
--- a/audio/aidl/default/include/effect-impl/EffectContext.h
+++ b/audio/aidl/default/include/effect-impl/EffectContext.h
@@ -72,13 +72,11 @@
 
     float* getWorkBuffer() { return static_cast<float*>(mWorkBuffer.data()); }
 
-    // reset buffer status by abandon all data and status in FMQ
+    // reset buffer status by abandon input data in FMQ
     void resetBuffer() {
         auto buffer = static_cast<float*>(mWorkBuffer.data());
         std::vector<IEffect::Status> status(mStatusMQ->availableToRead());
         mInputMQ->read(buffer, mInputMQ->availableToRead());
-        mOutputMQ->read(buffer, mOutputMQ->availableToRead());
-        mStatusMQ->read(status.data(), mStatusMQ->availableToRead());
     }
 
     void dupeFmq(IEffect::OpenEffectReturn* effectRet) {
diff --git a/audio/aidl/vts/EffectFactoryHelper.h b/audio/aidl/vts/EffectFactoryHelper.h
index b649d9e..0d5c649 100644
--- a/audio/aidl/vts/EffectFactoryHelper.h
+++ b/audio/aidl/vts/EffectFactoryHelper.h
@@ -49,11 +49,11 @@
 
     std::shared_ptr<IFactory> GetFactory() const { return mEffectFactory; }
 
-    static std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor::Identity>>
-    getAllEffectDescriptors(std::string serviceName, std::optional<AudioUuid> type = std::nullopt) {
+    static std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> 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;
+        std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> result;
 
         for (const auto& name : names) {
             auto factory = IFactory::fromBinder(util.connectToService(name));
@@ -62,11 +62,10 @@
                     factory->queryEffects(std::nullopt, std::nullopt, std::nullopt, &descs)
                             .isOk()) {
                     for (const auto& desc : descs) {
-                        const auto& id = desc.common.id;
-                        if (type.has_value() && id.type != type.value()) {
+                        if (type.has_value() && desc.common.id.type != type.value()) {
                             continue;
                         }
-                        result.emplace_back(factory, id);
+                        result.emplace_back(factory, desc);
                     }
                 }
             }
diff --git a/audio/aidl/vts/EffectHelper.h b/audio/aidl/vts/EffectHelper.h
index 73a1f49..7222d4f 100644
--- a/audio/aidl/vts/EffectHelper.h
+++ b/audio/aidl/vts/EffectHelper.h
@@ -58,26 +58,34 @@
 class EffectHelper {
   public:
     static void create(std::shared_ptr<IFactory> factory, std::shared_ptr<IEffect>& effect,
-                       Descriptor::Identity id, binder_status_t status = EX_NONE) {
+                       Descriptor& desc, binder_status_t status = EX_NONE) {
         ASSERT_NE(factory, nullptr);
-        EXPECT_STATUS(status, factory->createEffect(id.uuid, &effect));
+        auto& id = desc.common.id;
+        ASSERT_STATUS(status, factory->createEffect(id.uuid, &effect));
         if (status == EX_NONE) {
             ASSERT_NE(effect, nullptr) << id.uuid.toString();
         }
     }
 
+    static void destroyIgnoreRet(std::shared_ptr<IFactory> factory,
+                                 std::shared_ptr<IEffect> effect) {
+        if (factory && effect) {
+            factory->destroyEffect(effect);
+        }
+    }
+
     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));
+        ASSERT_STATUS(status, factory->destroyEffect(effect));
     }
 
     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));
+        ASSERT_STATUS(status, effect->open(common, specific, ret));
     }
 
     static void open(std::shared_ptr<IEffect> effect, int session = 0,
@@ -85,30 +93,40 @@
         ASSERT_NE(effect, nullptr);
         Parameter::Common common = EffectHelper::createParamCommon(session);
         IEffect::OpenEffectReturn ret;
-        open(effect, common, std::nullopt /* specific */, &ret, status);
+        ASSERT_NO_FATAL_FAILURE(open(effect, common, std::nullopt /* specific */, &ret, status));
     }
 
+    static void closeIgnoreRet(std::shared_ptr<IEffect> effect) {
+        if (effect) {
+            effect->close();
+        }
+    }
     static void close(std::shared_ptr<IEffect> effect, binder_status_t status = EX_NONE) {
         if (effect) {
-            EXPECT_STATUS(status, effect->close());
+            ASSERT_STATUS(status, effect->close());
         }
     }
     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));
+        ASSERT_STATUS(status, effect->getDescriptor(&desc));
     }
     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);
+        ASSERT_STATUS(status, effect->getState(&state));
+        ASSERT_EQ(expectState, state);
+    }
+    static void commandIgnoreRet(std::shared_ptr<IEffect> effect, CommandId command) {
+        if (effect) {
+            effect->command(command);
+        }
     }
     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));
+        ASSERT_STATUS(status, effect->command(command));
     }
     static void allocateInputData(const Parameter::Common common, std::unique_ptr<DataMQ>& mq,
                                   std::vector<float>& buffer) {
@@ -116,29 +134,29 @@
         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));
+        ASSERT_NE(0UL, floatsToWrite);
+        ASSERT_EQ(frameSize * common.input.frameCount, floatsToWrite * sizeof(float));
         buffer.resize(floatsToWrite);
         std::fill(buffer.begin(), buffer.end(), 0x5a);
     }
     static void writeToFmq(std::unique_ptr<DataMQ>& mq, const std::vector<float>& buffer) {
         const size_t available = mq->availableToWrite();
-        EXPECT_NE(0Ul, available);
+        ASSERT_NE(0Ul, available);
         auto bufferFloats = buffer.size();
         auto floatsToWrite = std::min(available, bufferFloats);
-        EXPECT_TRUE(mq->write(buffer.data(), floatsToWrite));
+        ASSERT_TRUE(mq->write(buffer.data(), floatsToWrite));
     }
     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);
+        ASSERT_TRUE(statusMq->readBlocking(&status, statusNum));
+        ASSERT_EQ(STATUS_OK, status.status);
         if (statusNum != 0) {
-            EXPECT_EQ(expectFloats, (unsigned)status.fmqProduced);
-            EXPECT_EQ(expectFloats, dataMq->availableToRead());
+            ASSERT_EQ(expectFloats, (unsigned)status.fmqProduced);
+            ASSERT_EQ(expectFloats, dataMq->availableToRead());
             if (expectFloats != 0) {
-                EXPECT_TRUE(dataMq->read(buffer.data(), expectFloats));
+                ASSERT_TRUE(dataMq->read(buffer.data(), expectFloats));
             }
         }
     }
diff --git a/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp b/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
index 4f14bf0..8938618 100644
--- a/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
@@ -49,18 +49,30 @@
 using aidl::android::hardware::audio::effect::State;
 
 enum ParamName { PARAM_INSTANCE_NAME };
-using EffectTestParam = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor::Identity>>;
+using EffectTestParam = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>>;
 
 class AudioEffectTest : public testing::TestWithParam<EffectTestParam>, public EffectHelper {
   public:
-    AudioEffectTest() { std::tie(mFactory, mIdentity) = std::get<PARAM_INSTANCE_NAME>(GetParam()); }
+    AudioEffectTest() {
+        std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
+    }
 
     void SetUp() override {}
-    void TearDown() override {}
+
+    void TearDown() override {
+        // Do the cleanup for every test case
+        if (mEffect) {
+            ASSERT_NO_FATAL_FAILURE(commandIgnoreRet(mEffect, CommandId::STOP));
+            ASSERT_NO_FATAL_FAILURE(closeIgnoreRet(mEffect));
+            ASSERT_NO_FATAL_FAILURE(destroyIgnoreRet(mFactory, mEffect));
+            mEffect.reset();
+        }
+    }
 
     static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
     std::shared_ptr<IFactory> mFactory;
-    Descriptor::Identity mIdentity;
+    std::shared_ptr<IEffect> mEffect;
+    Descriptor mDescriptor;
 };
 
 TEST_P(AudioEffectTest, SetupAndTearDown) {
@@ -68,30 +80,27 @@
 }
 
 TEST_P(AudioEffectTest, CreateAndDestroy) {
-    std::shared_ptr<IEffect> effect;
-    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
-    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
 }
 
 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));
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
 }
 
 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));
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
 }
 
 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(create(mFactory, effect1, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect2, mDescriptor));
     ASSERT_NO_FATAL_FAILURE(open(effect1));
     ASSERT_NO_FATAL_FAILURE(open(effect2, 1 /* session */));
     ASSERT_NO_FATAL_FAILURE(close(effect1));
@@ -102,9 +111,9 @@
 
 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(create(mFactory, effect1, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect2, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect3, mDescriptor));
     ASSERT_NO_FATAL_FAILURE(open(effect1));
     ASSERT_NO_FATAL_FAILURE(open(effect2, 1 /* session */));
     ASSERT_NO_FATAL_FAILURE(open(effect3, 2 /* session */));
@@ -117,513 +126,505 @@
 }
 
 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());
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(getDescriptor(mEffect, desc));
+    EXPECT_EQ(mDescriptor.common, desc.common);
+    // Effect implementation Must fill in implementor and name
     EXPECT_NE("", desc.common.name);
     EXPECT_NE("", desc.common.implementor);
-    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
 }
 
 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));
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(getDescriptor(mEffect, beforeOpen));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect));
+    ASSERT_NO_FATAL_FAILURE(getDescriptor(mEffect, 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));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(getDescriptor(mEffect, afterClose));
     EXPECT_EQ(beforeOpen.toString(), afterClose.toString()) << "\n"
                                                             << beforeOpen.toString() << "\n"
                                                             << afterClose.toString();
-    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
 }
 
 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;
+        auto& id = it.second.common.id;
         EXPECT_EQ(0ul, idSet.count(id));
         idSet.insert(id);
     }
 
-    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
-    ASSERT_NO_FATAL_FAILURE(getDescriptor(effect, desc));
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(getDescriptor(mEffect, desc));
     EXPECT_EQ(1ul, idSet.count(desc.common.id));
-    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
 }
 
 /// State testing.
 // An effect instance is in INIT state by default after it was created.
 TEST_P(AudioEffectTest, InitStateAfterCreation) {
-    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));
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::INIT));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
 }
 
 // An effect instance transfer to IDLE state after IEffect.ASSERT_NO_FATAL_FAILURE(open().
 TEST_P(AudioEffectTest, IdleStateAfterOpen) {
-    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));
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
 }
 
 // An effect instance is in PROCESSING state after it receive an START command.
 TEST_P(AudioEffectTest, ProcessingStateAfterStart) {
-    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));
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::INIT));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
 }
 
 // An effect instance transfer to IDLE state after Command.Id.STOP in PROCESSING state.
 TEST_P(AudioEffectTest, IdleStateAfterStop) {
-    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));
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
 }
 
 // An effect instance transfer to IDLE state after Command.Id.RESET in PROCESSING state.
 TEST_P(AudioEffectTest, IdleStateAfterReset) {
-    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));
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::RESET));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
 }
 
 // An effect instance transfer to INIT after IEffect.ASSERT_NO_FATAL_FAILURE(close().
 TEST_P(AudioEffectTest, InitStateAfterClose) {
-    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));
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::INIT));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
 }
 
 // An effect instance shouldn't accept any command before open.
 TEST_P(AudioEffectTest, NoCommandAcceptedBeforeOpen) {
-    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));
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START, EX_ILLEGAL_STATE));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP, EX_ILLEGAL_STATE));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::RESET, EX_ILLEGAL_STATE));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
 }
 
 // No-op when receive STOP command in IDLE state.
 TEST_P(AudioEffectTest, StopCommandInIdleStateNoOp) {
-    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));
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
 }
 
 // No-op when receive RESET command in IDLE state.
 TEST_P(AudioEffectTest, ResetCommandInIdleStateNoOp) {
-    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));
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::RESET));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
 }
 
 // Repeat START and STOP command.
 TEST_P(AudioEffectTest, RepeatStartAndStop) {
-    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(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
 
-    ASSERT_NO_FATAL_FAILURE(command(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));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
 }
 
 // Repeat START and RESET command.
 TEST_P(AudioEffectTest, RepeatStartAndReset) {
-    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(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::RESET));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, 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));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::RESET));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
 }
 
 // Try to close an effect instance at PROCESSING state.
 TEST_P(AudioEffectTest, CloseProcessingStateEffects) {
-    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(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
 
-    ASSERT_NO_FATAL_FAILURE(close(effect, EX_ILLEGAL_STATE));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect, 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));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
 }
 
 // Expect EX_ILLEGAL_STATE if the effect instance is not in a proper state to be destroyed.
 TEST_P(AudioEffectTest, DestroyOpenEffects) {
-    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(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
 
-    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect, EX_ILLEGAL_STATE));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect, EX_ILLEGAL_STATE));
+
+    // cleanup
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
 }
 
 // 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(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
 
-    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect, EX_ILLEGAL_STATE));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect, EX_ILLEGAL_STATE));
+
+    // cleanup
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
 }
 
 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));
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::INIT));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::RESET));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
 }
 
 /// Parameter testing.
 // Verify parameters pass in open can be successfully get.
 TEST_P(AudioEffectTest, VerifyCommonParametersAfterOpen) {
-    std::shared_ptr<IEffect> effect;
-    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
 
     Parameter::Common common = EffectHelper::createParamCommon();
     IEffect::OpenEffectReturn ret;
-    ASSERT_NO_FATAL_FAILURE(open(effect, common, std::nullopt /* specific */, &ret, EX_NONE));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect, 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_IS_OK(mEffect->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));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
 }
 
 // Verify parameters pass in set can be successfully get.
 TEST_P(AudioEffectTest, SetAndGetCommonParameter) {
-    std::shared_ptr<IEffect> effect;
-    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
-    ASSERT_NO_FATAL_FAILURE(open(effect));
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect));
 
     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));
+    EXPECT_IS_OK(mEffect->setParameter(set));
 
     Parameter::Id id;
     id.set<Parameter::Id::commonTag>(Parameter::common);
-    EXPECT_IS_OK(effect->getParameter(id, &get));
+    EXPECT_IS_OK(mEffect->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));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
 }
 
 // Verify parameters set and get in PROCESSING state.
 TEST_P(AudioEffectTest, SetAndGetParameterInProcessing) {
-    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(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, 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));
+    EXPECT_IS_OK(mEffect->setParameter(set));
 
     Parameter::Id id;
     id.set<Parameter::Id::commonTag>(Parameter::common);
-    EXPECT_IS_OK(effect->getParameter(id, &get));
+    EXPECT_IS_OK(mEffect->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));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
 }
 
 // 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));
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
 
     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));
+    EXPECT_IS_OK(mEffect->setParameter(set));
 
     Parameter::Id id;
     id.set<Parameter::Id::commonTag>(Parameter::common);
-    EXPECT_IS_OK(effect->getParameter(id, &get));
+    EXPECT_IS_OK(mEffect->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));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
 }
 
 // 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));
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, 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));
+    EXPECT_IS_OK(mEffect->setParameter(set));
 
-    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::STOP));
-    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
 
     Parameter::Id id;
     id.set<Parameter::Id::commonTag>(Parameter::common);
-    EXPECT_IS_OK(effect->getParameter(id, &get));
+    EXPECT_IS_OK(mEffect->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));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
 }
 
 // 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(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect));
 
-    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START));
-    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::PROCESSING));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, 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));
+    EXPECT_IS_OK(mEffect->setParameter(set));
 
-    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::RESET));
-    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::RESET));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
 
     Parameter::Id id;
     id.set<Parameter::Id::commonTag>(Parameter::common);
-    EXPECT_IS_OK(effect->getParameter(id, &get));
+    EXPECT_IS_OK(mEffect->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));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
 }
-
 /// 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));
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
 
     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(open(mEffect, common, std::nullopt /* specific */, &ret, EX_NONE));
     auto statusMQ = std::make_unique<EffectHelper::StatusMQ>(ret.statusMQ);
+    ASSERT_TRUE(statusMQ->isValid());
     auto inputMQ = std::make_unique<EffectHelper::DataMQ>(ret.inputDataMQ);
+    ASSERT_TRUE(inputMQ->isValid());
     auto outputMQ = std::make_unique<EffectHelper::DataMQ>(ret.outputDataMQ);
+    ASSERT_TRUE(outputMQ->isValid());
 
-    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START));
-    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::PROCESSING));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
 
     std::vector<float> buffer;
     EffectHelper::allocateInputData(common, inputMQ, buffer);
     EffectHelper::writeToFmq(inputMQ, buffer);
     EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer);
 
-    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::STOP));
-    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
 
-    ASSERT_NO_FATAL_FAILURE(close(effect));
-    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
 }
 
 // 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));
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
 
     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(open(mEffect, common, std::nullopt /* specific */, &ret, EX_NONE));
     auto statusMQ = std::make_unique<EffectHelper::StatusMQ>(ret.statusMQ);
+    ASSERT_TRUE(statusMQ->isValid());
     auto inputMQ = std::make_unique<EffectHelper::DataMQ>(ret.inputDataMQ);
+    ASSERT_TRUE(inputMQ->isValid());
     auto outputMQ = std::make_unique<EffectHelper::DataMQ>(ret.outputDataMQ);
+    ASSERT_TRUE(outputMQ->isValid());
 
-    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(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
 
     std::vector<float> buffer;
     EffectHelper::allocateInputData(common, inputMQ, buffer);
     EffectHelper::writeToFmq(inputMQ, buffer);
     EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer);
 
-    ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::STOP));
-    ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
 
-    ASSERT_NO_FATAL_FAILURE(close(effect));
-    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
 }
 
 // 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));
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
 
     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(open(mEffect, common, std::nullopt /* specific */, &ret, EX_NONE));
     auto statusMQ = std::make_unique<EffectHelper::StatusMQ>(ret.statusMQ);
+    ASSERT_TRUE(statusMQ->isValid());
     auto inputMQ = std::make_unique<EffectHelper::DataMQ>(ret.inputDataMQ);
+    ASSERT_TRUE(inputMQ->isValid());
     auto outputMQ = std::make_unique<EffectHelper::DataMQ>(ret.outputDataMQ);
+    ASSERT_TRUE(outputMQ->isValid());
 
     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));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, 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(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
 
-    ASSERT_NO_FATAL_FAILURE(close(effect));
-    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
 }
 
 // Send data multiple times.
 TEST_P(AudioEffectTest, ProcessDataMultipleTimes) {
-    std::shared_ptr<IEffect> effect;
-    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
 
     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(open(mEffect, common, std::nullopt /* specific */, &ret, EX_NONE));
     auto statusMQ = std::make_unique<EffectHelper::StatusMQ>(ret.statusMQ);
+    ASSERT_TRUE(statusMQ->isValid());
     auto inputMQ = std::make_unique<EffectHelper::DataMQ>(ret.inputDataMQ);
+    ASSERT_TRUE(inputMQ->isValid());
     auto outputMQ = std::make_unique<EffectHelper::DataMQ>(ret.outputDataMQ);
+    ASSERT_TRUE(outputMQ->isValid());
 
     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));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
 
     EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer);
     // expect no status and data after consume
@@ -634,77 +635,81 @@
     // 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(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
 
-    ASSERT_NO_FATAL_FAILURE(close(effect));
-    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
 }
 
 // Send data to IDLE state effects and expect it not be consumed.
 TEST_P(AudioEffectTest, NotConsumeDataInIdleState) {
-    std::shared_ptr<IEffect> effect;
-    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
 
     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(open(mEffect, common, std::nullopt /* specific */, &ret, EX_NONE));
     auto statusMQ = std::make_unique<EffectHelper::StatusMQ>(ret.statusMQ);
+    ASSERT_TRUE(statusMQ->isValid());
     auto inputMQ = std::make_unique<EffectHelper::DataMQ>(ret.inputDataMQ);
+    ASSERT_TRUE(inputMQ->isValid());
     auto outputMQ = std::make_unique<EffectHelper::DataMQ>(ret.outputDataMQ);
+    ASSERT_TRUE(outputMQ->isValid());
 
-    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(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
 
     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));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, 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(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
 
-    ASSERT_NO_FATAL_FAILURE(close(effect));
-    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
 }
 
 // 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));
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
 
     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));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect, common, std::nullopt /* specific */, &ret, EX_NONE));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
 
     auto statusMQ = std::make_unique<EffectHelper::StatusMQ>(ret.statusMQ);
+    ASSERT_TRUE(statusMQ->isValid());
     auto inputMQ = std::make_unique<EffectHelper::DataMQ>(ret.inputDataMQ);
+    ASSERT_TRUE(inputMQ->isValid());
     auto outputMQ = std::make_unique<EffectHelper::DataMQ>(ret.outputDataMQ);
+    ASSERT_TRUE(outputMQ->isValid());
 
     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));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
 }
 
 // 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));
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect1, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect2, mDescriptor));
 
     Parameter::Common common1 = EffectHelper::createParamCommon(
             0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
@@ -721,8 +726,11 @@
     ASSERT_NO_FATAL_FAILURE(expectState(effect2, State::PROCESSING));
 
     auto statusMQ1 = std::make_unique<EffectHelper::StatusMQ>(ret1.statusMQ);
+    ASSERT_TRUE(statusMQ1->isValid());
     auto inputMQ1 = std::make_unique<EffectHelper::DataMQ>(ret1.inputDataMQ);
+    ASSERT_TRUE(inputMQ1->isValid());
     auto outputMQ1 = std::make_unique<EffectHelper::DataMQ>(ret1.outputDataMQ);
+    ASSERT_TRUE(outputMQ1->isValid());
 
     std::vector<float> buffer1, buffer2;
     EffectHelper::allocateInputData(common1, inputMQ1, buffer1);
@@ -730,8 +738,11 @@
     EffectHelper::readFromFmq(statusMQ1, 1, outputMQ1, buffer1.size(), buffer1);
 
     auto statusMQ2 = std::make_unique<EffectHelper::StatusMQ>(ret2.statusMQ);
+    ASSERT_TRUE(statusMQ2->isValid());
     auto inputMQ2 = std::make_unique<EffectHelper::DataMQ>(ret2.inputDataMQ);
+    ASSERT_TRUE(inputMQ2->isValid());
     auto outputMQ2 = std::make_unique<EffectHelper::DataMQ>(ret2.outputDataMQ);
+    ASSERT_TRUE(outputMQ2->isValid());
     EffectHelper::allocateInputData(common2, inputMQ2, buffer2);
     EffectHelper::writeToFmq(inputMQ2, buffer2);
     EffectHelper::readFromFmq(statusMQ2, 1, outputMQ2, buffer2.size(), buffer2);
@@ -752,9 +763,11 @@
         ::testing::Combine(testing::ValuesIn(
                 EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor))),
         [](const testing::TestParamInfo<AudioEffectTest::ParamType>& info) {
-            auto instance = std::get<PARAM_INSTANCE_NAME>(info.param);
-            std::string name = "TYPE_" + instance.second.type.toString() + "_UUID_" +
-                               instance.second.uuid.toString();
+            auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
+            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+                               descriptor.common.name + "_TYPE_" +
+                               descriptor.common.id.type.toString() + "_UUID_" +
+                               descriptor.common.id.uuid.toString();
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
diff --git a/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp b/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp
index 7adf63c..724a9c3 100644
--- a/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp
@@ -37,8 +37,7 @@
  * VtsAudioEffectTargetTest.
  */
 enum ParamName { PARAM_INSTANCE_NAME, PARAM_STRENGTH };
-using BassBoostParamTestParam =
-        std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor::Identity>, int>;
+using BassBoostParamTestParam = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int>;
 
 /*
  * Testing parameter range, assuming the parameter supported by effect is in this range.
@@ -60,12 +59,12 @@
                            public EffectHelper {
   public:
     BassBoostParamTest() : mParamStrength(std::get<PARAM_STRENGTH>(GetParam())) {
-        std::tie(mFactory, mIdentity) = std::get<PARAM_INSTANCE_NAME>(GetParam());
+        std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
     }
 
     void SetUp() override {
         ASSERT_NE(nullptr, mFactory);
-        ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mIdentity));
+        ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
 
         Parameter::Specific specific = getDefaultParamSpecific();
         Parameter::Common common = EffectHelper::createParamCommon(
@@ -91,7 +90,7 @@
     static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
     std::shared_ptr<IFactory> mFactory;
     std::shared_ptr<IEffect> mEffect;
-    Descriptor::Identity mIdentity;
+    Descriptor mDescriptor;
     int mParamStrength = BassBoost::MIN_PER_MILLE_STRENGTH;
 
     void SetAndGetBassBoostParameters() {
@@ -167,9 +166,11 @@
                                    IFactory::descriptor, kBassBoostTypeUUID)),
                            testing::ValuesIn(kStrengthValues)),
         [](const testing::TestParamInfo<BassBoostParamTest::ParamType>& info) {
-            auto instance = std::get<PARAM_INSTANCE_NAME>(info.param);
+            auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
             std::string strength = std::to_string(std::get<PARAM_STRENGTH>(info.param));
-            std::string name = instance.second.uuid.toString() + "_strength_" + strength;
+            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+                               descriptor.common.name + "_UUID_" +
+                               descriptor.common.id.uuid.toString() + "_strength_" + strength;
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
diff --git a/audio/aidl/vts/VtsHalEqualizerTargetTest.cpp b/audio/aidl/vts/VtsHalEqualizerTargetTest.cpp
index 1b147a6..e11a936 100644
--- a/audio/aidl/vts/VtsHalEqualizerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalEqualizerTargetTest.cpp
@@ -57,8 +57,7 @@
  */
 
 enum ParamName { PARAM_INSTANCE_NAME, PARAM_BAND_LEVEL };
-using EqualizerParamTestParam =
-        std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor::Identity>, int>;
+using EqualizerParamTestParam = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int>;
 
 /*
 Testing parameter range, assuming the parameter supported by effect is in this range.
@@ -71,12 +70,12 @@
                       public EffectHelper {
   public:
     EqualizerTest() : mBandLevel(std::get<PARAM_BAND_LEVEL>(GetParam())) {
-        std::tie(mFactory, mIdentity) = std::get<PARAM_INSTANCE_NAME>(GetParam());
+        std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
     }
 
     void SetUp() override {
         ASSERT_NE(nullptr, mFactory);
-        ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mIdentity));
+        ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
 
         Parameter::Specific specific = getDefaultParamSpecific();
         Parameter::Common common = EffectHelper::createParamCommon(
@@ -115,7 +114,7 @@
     static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
     std::shared_ptr<IFactory> mFactory;
     std::shared_ptr<IEffect> mEffect;
-    Descriptor::Identity mIdentity;
+    Descriptor mDescriptor;
     std::pair<int, int> mPresetIndex;
     std::pair<int, int> mBandIndex;
     const int mBandLevel;
@@ -327,9 +326,11 @@
                                    IFactory::descriptor, kEqualizerTypeUUID)),
                            testing::ValuesIn(kBandLevels)),
         [](const testing::TestParamInfo<EqualizerTest::ParamType>& info) {
-            auto instance = std::get<PARAM_INSTANCE_NAME>(info.param);
+            auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
             std::string bandLevel = std::to_string(std::get<PARAM_BAND_LEVEL>(info.param));
-            std::string name = instance.second.uuid.toString() + "_bandLevel_" + bandLevel;
+            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+                               descriptor.common.name + "_UUID_" +
+                               descriptor.common.id.uuid.toString() + "_bandLevel_" + bandLevel;
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
diff --git a/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp b/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
index 3fd2812..305c243 100644
--- a/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
@@ -38,7 +38,7 @@
  */
 enum ParamName { PARAM_INSTANCE_NAME, PARAM_GAIN_MB };
 using LoudnessEnhancerParamTestParam =
-        std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor::Identity>, int>;
+        std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, 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.
@@ -49,12 +49,12 @@
                                   public EffectHelper {
   public:
     LoudnessEnhancerParamTest() : mParamGainMb(std::get<PARAM_GAIN_MB>(GetParam())) {
-        std::tie(mFactory, mIdentity) = std::get<PARAM_INSTANCE_NAME>(GetParam());
+        std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
     }
 
     void SetUp() override {
         ASSERT_NE(nullptr, mFactory);
-        ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mIdentity));
+        ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
 
         Parameter::Specific specific = getDefaultParamSpecific();
         Parameter::Common common = EffectHelper::createParamCommon(
@@ -79,7 +79,7 @@
     static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
     std::shared_ptr<IFactory> mFactory;
     std::shared_ptr<IEffect> mEffect;
-    Descriptor::Identity mIdentity;
+    Descriptor mDescriptor;
     int mParamGainMb = 0;
 
     void SetAndGetParameters() {
@@ -130,9 +130,11 @@
                                    IFactory::descriptor, kLoudnessEnhancerTypeUUID)),
                            testing::ValuesIn(kGainMbValues)),
         [](const testing::TestParamInfo<LoudnessEnhancerParamTest::ParamType>& info) {
-            auto instance = std::get<PARAM_INSTANCE_NAME>(info.param);
+            auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
             std::string gainMb = std::to_string(std::get<PARAM_GAIN_MB>(info.param));
-            std::string name = instance.second.uuid.toString() + "_gainMb_" + gainMb;
+            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+                               descriptor.common.name + "_UUID_" +
+                               descriptor.common.id.uuid.toString() + "_gainMb_" + gainMb;
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
diff --git a/graphics/common/aidl/android/hardware/graphics/common/StandardMetadataType.aidl b/graphics/common/aidl/android/hardware/graphics/common/StandardMetadataType.aidl
index 8126143..4bca795 100644
--- a/graphics/common/aidl/android/hardware/graphics/common/StandardMetadataType.aidl
+++ b/graphics/common/aidl/android/hardware/graphics/common/StandardMetadataType.aidl
@@ -22,9 +22,9 @@
  * This is an enum that defines the common types of gralloc 4 buffer metadata. The comments for
  * each enum include a description of the metadata that is associated with the type.
  *
- * IMapper@4.x must support getting the following standard buffer metadata types, with the exception
- * of SMPTE 2094-10 metadata. IMapper@4.x may support setting these standard buffer metadata types
- * as well.
+ * IMapper@4.x & later must support getting the following standard buffer metadata types, with the
+ * exception of SMPTE 2094-10 and SMPTE 2094-40 metadata. IMapper@4.x & later may support setting
+ * these standard buffer metadata types as well.
  *
  * When encoding these StandardMetadataTypes into a byte stream, the associated MetadataType is
  * is first encoded followed by the StandardMetadataType value. The MetadataType is encoded by
diff --git a/graphics/mapper/stable-c/Android.bp b/graphics/mapper/stable-c/Android.bp
index c03f67e..d40e160 100644
--- a/graphics/mapper/stable-c/Android.bp
+++ b/graphics/mapper/stable-c/Android.bp
@@ -61,6 +61,10 @@
     srcs: [
         "implutils/impltests.cpp",
     ],
+    shared_libs: [
+        "libgralloctypes",
+        "libhidlbase",
+    ],
     visibility: [":__subpackages__"],
     cpp_std: "experimental",
 }
diff --git a/graphics/mapper/stable-c/implutils/impltests.cpp b/graphics/mapper/stable-c/implutils/impltests.cpp
index 9c5d70b..f12b069 100644
--- a/graphics/mapper/stable-c/implutils/impltests.cpp
+++ b/graphics/mapper/stable-c/implutils/impltests.cpp
@@ -18,123 +18,29 @@
 
 #include <android/hardware/graphics/mapper/utils/IMapperMetadataTypes.h>
 #include <android/hardware/graphics/mapper/utils/IMapperProvider.h>
+#include <drm/drm_fourcc.h>
+#include <gralloctypes/Gralloc4.h>
+#include <span>
 #include <vector>
 
+using namespace ::android;
 using namespace ::android::hardware::graphics::mapper;
 using namespace ::aidl::android::hardware::graphics::common;
+namespace gralloc4 = ::android::gralloc4;
+using ::android::hardware::hidl_vec;
 
 // These tests are primarily interested in hitting all the different *types* that can be
 // serialized/deserialized than in exhaustively testing all the StandardMetadataTypes.
 // Exhaustive testing of the actual metadata types is relegated for IMapper's VTS suite
 // where meaning & correctness of values are more narrowly defined (eg, read-only values)
 
-TEST(Metadata, setGetBufferId) {
-    using BufferId = StandardMetadata<StandardMetadataType::BUFFER_ID>::value;
+static constexpr auto HeaderSize = 69;
 
-    std::vector<char> buffer;
-    buffer.resize(12, 0);
-    *reinterpret_cast<int64_t*>(buffer.data()) = 42;
-
-    EXPECT_EQ(8, BufferId::encode(18, buffer.data(), 0));
-    EXPECT_EQ(42, *reinterpret_cast<int64_t*>(buffer.data()));
-    EXPECT_EQ(8, BufferId::encode(18, buffer.data(), buffer.size()));
-    EXPECT_EQ(18, *reinterpret_cast<int64_t*>(buffer.data()));
-    EXPECT_FALSE(BufferId::decode(buffer.data(), 0));
-    auto read = BufferId::decode(buffer.data(), buffer.size());
-    EXPECT_TRUE(read.has_value());
-    EXPECT_EQ(18, read.value_or(0));
+static std::span<uint8_t> SkipHeader(std::vector<uint8_t>& buffer) {
+    return std::span<uint8_t>(buffer).subspan(HeaderSize);
 }
 
-TEST(Metadata, setGetDataspace) {
-    using DataspaceValue = StandardMetadata<StandardMetadataType::DATASPACE>::value;
-    using intType = std::underlying_type_t<Dataspace>;
-    std::vector<char> buffer;
-    buffer.resize(12, 0);
-
-    EXPECT_EQ(4, DataspaceValue::encode(Dataspace::BT2020, buffer.data(), 0));
-    EXPECT_EQ(0, *reinterpret_cast<intType*>(buffer.data()));
-    EXPECT_EQ(4, DataspaceValue::encode(Dataspace::BT2020, buffer.data(), buffer.size()));
-    EXPECT_EQ(static_cast<intType>(Dataspace::BT2020), *reinterpret_cast<intType*>(buffer.data()));
-    EXPECT_FALSE(DataspaceValue::decode(buffer.data(), 0));
-    auto read = DataspaceValue::decode(buffer.data(), buffer.size());
-    ASSERT_TRUE(read.has_value());
-    EXPECT_EQ(Dataspace::BT2020, *read);
-}
-
-TEST(Metadata, setGetValidName) {
-    using NameValue = StandardMetadata<StandardMetadataType::NAME>::value;
-
-    std::vector<char> buffer;
-    buffer.resize(100, 'a');
-    buffer[buffer.size() - 1] = '\0';
-
-    // len("Hello") + sizeof(int64)
-    constexpr int expectedSize = 5 + sizeof(int64_t);
-    EXPECT_EQ(expectedSize, NameValue::encode("Hello", buffer.data(), buffer.size()));
-    EXPECT_EQ(5, *reinterpret_cast<int64_t*>(buffer.data()));
-    // Verify didn't write past the end of the desired size
-    EXPECT_EQ('a', buffer[expectedSize]);
-
-    auto readValue = NameValue::decode(buffer.data(), buffer.size());
-    ASSERT_TRUE(readValue.has_value());
-    EXPECT_EQ(5, readValue->length());
-    EXPECT_EQ("Hello", *readValue);
-}
-
-TEST(Metadata, setGetInvalidName) {
-    using NameValue = StandardMetadata<StandardMetadataType::NAME>::value;
-
-    std::vector<char> buffer;
-    buffer.resize(12, 'a');
-    buffer[buffer.size() - 1] = '\0';
-
-    // len("This is a long string") + sizeof(int64)
-    constexpr int expectedSize = 21 + sizeof(int64_t);
-    EXPECT_EQ(expectedSize,
-              NameValue::encode("This is a long string", buffer.data(), buffer.size()));
-    EXPECT_EQ(21, *reinterpret_cast<int64_t*>(buffer.data()));
-    // Verify didn't write the too-long string
-    EXPECT_EQ('a', buffer[9]);
-    EXPECT_EQ('\0', buffer[buffer.size() - 1]);
-
-    auto readValue = NameValue::decode(buffer.data(), buffer.size());
-    EXPECT_FALSE(readValue.has_value());
-    readValue = NameValue::decode(buffer.data(), 0);
-    ASSERT_FALSE(readValue.has_value());
-}
-
-TEST(Metadata, wouldOverflowName) {
-    using NameValue = StandardMetadata<StandardMetadataType::NAME>::value;
-    std::vector<char> buffer(100, 0);
-
-    // int_max + sizeof(int64) overflows int32
-    std::string_view bad_string{"badbeef", std::numeric_limits<int32_t>::max()};
-    EXPECT_EQ(-AIMAPPER_ERROR_BAD_VALUE,
-              NameValue::encode(bad_string, buffer.data(), buffer.size()));
-
-    // check barely overflows
-    bad_string = std::string_view{"badbeef", std::numeric_limits<int32_t>::max() - 7};
-    EXPECT_EQ(-AIMAPPER_ERROR_BAD_VALUE,
-              NameValue::encode(bad_string, buffer.data(), buffer.size()));
-}
-
-TEST(Metadata, setGetCompression) {
-    using CompressionValue = StandardMetadata<StandardMetadataType::COMPRESSION>::value;
-    ExtendableType myCompression{"bestest_compression_ever", 42};
-    std::vector<char> buffer(100, '\0');
-    const int expectedSize = myCompression.name.length() + sizeof(int64_t) + sizeof(int64_t);
-    EXPECT_EQ(expectedSize, CompressionValue::encode(myCompression, buffer.data(), 0));
-    EXPECT_EQ(0, buffer[0]);
-    EXPECT_EQ(expectedSize, CompressionValue::encode(myCompression, buffer.data(), buffer.size()));
-    EXPECT_EQ(myCompression.name.length(), *reinterpret_cast<int64_t*>(buffer.data()));
-    EXPECT_FALSE(CompressionValue::decode(buffer.data(), 0).has_value());
-    auto read = CompressionValue::decode(buffer.data(), buffer.size());
-    ASSERT_TRUE(read.has_value());
-    EXPECT_EQ(myCompression, read.value());
-}
-
-TEST(Metadata, setGetPlaneLayout) {
-    using PlaneLayoutValue = StandardMetadata<StandardMetadataType::PLANE_LAYOUTS>::value;
+static std::vector<PlaneLayout> fakePlaneLayouts() {
     PlaneLayout myPlaneLayout;
     myPlaneLayout.offsetInBytes = 10;
     myPlaneLayout.sampleIncrementInBits = 11;
@@ -153,23 +59,147 @@
         it.sizeInBits = 30 + i;
     }
 
-    std::vector<PlaneLayout> layouts{myPlaneLayout, PlaneLayout{}};
+    return std::vector<PlaneLayout>{myPlaneLayout, PlaneLayout{}};
+}
 
-    std::vector<char> buffer(5000, '\0');
+TEST(Metadata, setGetBufferId) {
+    using BufferId = StandardMetadata<StandardMetadataType::BUFFER_ID>::value;
+
+    std::vector<uint8_t> buffer(10000, 0);
+    int64_t* payload = reinterpret_cast<int64_t*>(SkipHeader(buffer).data());
+    *payload = 42;
+
+    EXPECT_EQ(8 + HeaderSize, BufferId::encode(18, buffer.data(), 0));
+    EXPECT_EQ(42, *payload);
+    EXPECT_EQ(8 + HeaderSize, BufferId::encode(18, buffer.data(), buffer.size()));
+    EXPECT_EQ(18, *payload);
+    EXPECT_FALSE(BufferId::decode(buffer.data(), 0));
+    auto read = BufferId::decode(buffer.data(), buffer.size());
+    EXPECT_TRUE(read.has_value());
+    EXPECT_EQ(18, read.value_or(0));
+}
+
+TEST(Metadata, setGetDataspace) {
+    using DataspaceValue = StandardMetadata<StandardMetadataType::DATASPACE>::value;
+    using intType = std::underlying_type_t<Dataspace>;
+    std::vector<uint8_t> buffer(10000, 0);
+    auto data = SkipHeader(buffer);
+
+    EXPECT_EQ(4 + HeaderSize, DataspaceValue::encode(Dataspace::BT2020, buffer.data(), 0));
+    EXPECT_EQ(0, *reinterpret_cast<intType*>(data.data()));
+    EXPECT_EQ(4 + HeaderSize,
+              DataspaceValue::encode(Dataspace::BT2020, buffer.data(), buffer.size()));
+    EXPECT_EQ(static_cast<intType>(Dataspace::BT2020), *reinterpret_cast<intType*>(data.data()));
+    EXPECT_FALSE(DataspaceValue::decode(buffer.data(), 0));
+    auto read = DataspaceValue::decode(buffer.data(), buffer.size());
+    ASSERT_TRUE(read.has_value());
+    EXPECT_EQ(Dataspace::BT2020, *read);
+}
+
+TEST(Metadata, setGetValidName) {
+    using NameValue = StandardMetadata<StandardMetadataType::NAME>::value;
+
+    std::vector<uint8_t> buffer(10000, 'a');
+
+    // len("Hello") + sizeof(int64)
+    constexpr int expectedSize = 5 + sizeof(int64_t) + HeaderSize;
+    EXPECT_EQ(expectedSize, NameValue::encode("Hello", buffer.data(), buffer.size()));
+    EXPECT_EQ(5, *reinterpret_cast<int64_t*>(SkipHeader(buffer).data()));
+    // Verify didn't write past the end of the desired size
+    EXPECT_EQ('a', buffer[expectedSize]);
+
+    auto readValue = NameValue::decode(buffer.data(), buffer.size());
+    ASSERT_TRUE(readValue.has_value());
+    EXPECT_EQ(5, readValue->length());
+    EXPECT_EQ("Hello", *readValue);
+}
+
+TEST(Metadata, setGetInvalidName) {
+    using NameValue = StandardMetadata<StandardMetadataType::NAME>::value;
+
+    std::vector<uint8_t> buffer;
+    buffer.resize(12 + HeaderSize, 'a');
+    buffer[buffer.size() - 1] = '\0';
+
+    // len("This is a long string") + sizeof(int64)
+    constexpr int expectedSize = 21 + sizeof(int64_t) + HeaderSize;
+    EXPECT_EQ(expectedSize,
+              NameValue::encode("This is a long string", buffer.data(), buffer.size()));
+    EXPECT_EQ(21, *reinterpret_cast<int64_t*>(SkipHeader(buffer).data()));
+
+    auto readValue = NameValue::decode(buffer.data(), buffer.size());
+    EXPECT_FALSE(readValue.has_value());
+    readValue = NameValue::decode(buffer.data(), 0);
+    ASSERT_FALSE(readValue.has_value());
+}
+
+TEST(Metadata, wouldOverflowName) {
+    using NameValue = StandardMetadata<StandardMetadataType::NAME>::value;
+    std::vector<uint8_t> buffer(10000, 0);
+
+    // int_max + sizeof(int64) overflows int32
+    std::string_view bad_string{"badbeef", std::numeric_limits<int32_t>::max()};
+    EXPECT_EQ(-AIMAPPER_ERROR_BAD_VALUE,
+              NameValue::encode(bad_string, buffer.data(), buffer.size()));
+
+    // check barely overflows
+    bad_string = std::string_view{"badbeef", std::numeric_limits<int32_t>::max() - 7};
+    EXPECT_EQ(-AIMAPPER_ERROR_BAD_VALUE,
+              NameValue::encode(bad_string, buffer.data(), buffer.size()));
+}
+
+TEST(Metadata, setGetMismatchedWidthHight) {
+    // Validates that the header is properly validated on decode
+    using WidthValue = StandardMetadata<StandardMetadataType::WIDTH>::value;
+    using HeightValue = StandardMetadata<StandardMetadataType::HEIGHT>::value;
+    std::vector<uint8_t> buffer(10000, 0);
+
+    EXPECT_EQ(8 + HeaderSize, WidthValue::encode(100, buffer.data(), buffer.size()));
+    EXPECT_EQ(100, *reinterpret_cast<uint64_t*>(SkipHeader(buffer).data()));
+    auto read = WidthValue::decode(buffer.data(), buffer.size());
+    ASSERT_TRUE(read.has_value());
+    EXPECT_EQ(100, *read);
+    read = HeightValue::decode(buffer.data(), buffer.size());
+    EXPECT_FALSE(read.has_value());
+}
+
+TEST(Metadata, setGetCompression) {
+    using CompressionValue = StandardMetadata<StandardMetadataType::COMPRESSION>::value;
+    ExtendableType myCompression{"bestest_compression_ever", 42};
+    std::vector<uint8_t> buffer(10000, 0);
+    const int expectedSize =
+            myCompression.name.length() + sizeof(int64_t) + sizeof(int64_t) + HeaderSize;
+    EXPECT_EQ(expectedSize, CompressionValue::encode(myCompression, buffer.data(), 0));
+    EXPECT_EQ(0, buffer[0]);
+    EXPECT_EQ(expectedSize, CompressionValue::encode(myCompression, buffer.data(), buffer.size()));
+    EXPECT_EQ(myCompression.name.length(), *reinterpret_cast<int64_t*>(SkipHeader(buffer).data()));
+    EXPECT_FALSE(CompressionValue::decode(buffer.data(), 0).has_value());
+    auto read = CompressionValue::decode(buffer.data(), buffer.size());
+    ASSERT_TRUE(read.has_value());
+    EXPECT_EQ(myCompression, read.value());
+}
+
+TEST(Metadata, setGetPlaneLayout) {
+    using PlaneLayoutValue = StandardMetadata<StandardMetadataType::PLANE_LAYOUTS>::value;
+
+    std::vector<PlaneLayout> layouts = fakePlaneLayouts();
+
+    std::vector<uint8_t> buffer(10000, 0);
     constexpr int componentSize = 8 + (4 * sizeof(int64_t));
     constexpr int firstLayoutSize = (8 + 1) * sizeof(int64_t) + (3 * componentSize);
     constexpr int secondLayoutSize = (8 + 1) * sizeof(int64_t);
-    constexpr int expectedSize = firstLayoutSize + secondLayoutSize + sizeof(int64_t);
+    constexpr int expectedSize = firstLayoutSize + secondLayoutSize + sizeof(int64_t) + HeaderSize;
     EXPECT_EQ(expectedSize, PlaneLayoutValue::encode(layouts, buffer.data(), 0));
     EXPECT_EQ(0, buffer[0]);
     EXPECT_EQ(expectedSize, PlaneLayoutValue::encode(layouts, buffer.data(), buffer.size()));
-    EXPECT_EQ(3, reinterpret_cast<int64_t*>(buffer.data())[1]);
-    EXPECT_EQ(8, reinterpret_cast<int64_t*>(buffer.data())[2]);
-    EXPECT_EQ(40, reinterpret_cast<int64_t*>(buffer.data())[4]);
-    EXPECT_EQ(31, reinterpret_cast<int64_t*>(buffer.data())[11]);
-    EXPECT_EQ(22, reinterpret_cast<int64_t*>(buffer.data())[15]);
-    EXPECT_EQ(10, reinterpret_cast<int64_t*>(buffer.data())[17]);
-    EXPECT_EQ(11, reinterpret_cast<int64_t*>(buffer.data())[18]);
+    int64_t* payload = reinterpret_cast<int64_t*>(SkipHeader(buffer).data());
+    EXPECT_EQ(3, payload[1]);
+    EXPECT_EQ(8, payload[2]);
+    EXPECT_EQ(40, payload[4]);
+    EXPECT_EQ(31, payload[11]);
+    EXPECT_EQ(22, payload[15]);
+    EXPECT_EQ(10, payload[17]);
+    EXPECT_EQ(11, payload[18]);
     EXPECT_FALSE(PlaneLayoutValue::decode(buffer.data(), 0).has_value());
     auto read = PlaneLayoutValue::decode(buffer.data(), buffer.size());
     ASSERT_TRUE(read.has_value());
@@ -178,15 +208,15 @@
 
 TEST(Metadata, setGetRects) {
     using RectsValue = StandardMetadata<StandardMetadataType::CROP>::value;
-    std::vector<uint8_t> buffer(500, 0);
+    std::vector<uint8_t> buffer(10000, 0);
     std::vector<Rect> cropRects{2};
     cropRects[0] = Rect{10, 11, 12, 13};
     cropRects[1] = Rect{20, 21, 22, 23};
 
-    constexpr int expectedSize = sizeof(int64_t) + (8 * sizeof(int32_t));
+    constexpr int expectedSize = sizeof(int64_t) + (8 * sizeof(int32_t)) + HeaderSize;
     EXPECT_EQ(expectedSize, RectsValue::encode(cropRects, buffer.data(), buffer.size()));
-    EXPECT_EQ(2, reinterpret_cast<int64_t*>(buffer.data())[0]);
-    EXPECT_EQ(10, reinterpret_cast<int32_t*>(buffer.data())[2]);
+    EXPECT_EQ(2, reinterpret_cast<int64_t*>(SkipHeader(buffer).data())[0]);
+    EXPECT_EQ(10, reinterpret_cast<int32_t*>(SkipHeader(buffer).data())[2]);
     auto read = RectsValue::decode(buffer.data(), buffer.size());
     ASSERT_TRUE(read.has_value());
     EXPECT_EQ(cropRects.size(), read->size());
@@ -203,8 +233,8 @@
     source.primaryGreen = XyColor{.3f, .4f};
     source.primaryBlue = XyColor{.5f, .6f};
 
-    constexpr int expectedSize = 10 * sizeof(float);
-    std::vector<uint8_t> buffer(500, 0);
+    constexpr int expectedSize = 10 * sizeof(float) + HeaderSize;
+    std::vector<uint8_t> buffer(10000, 0);
     EXPECT_EQ(expectedSize, Smpte2086Value::encode(source, buffer.data(), buffer.size()));
     auto read = Smpte2086Value::decode(buffer.data(), buffer.size());
     ASSERT_TRUE(read.has_value());
@@ -223,8 +253,8 @@
     source.maxFrameAverageLightLevel = 244.55f;
     source.maxContentLightLevel = 202.202f;
 
-    constexpr int expectedSize = 2 * sizeof(float);
-    std::vector<uint8_t> buffer(500, 0);
+    constexpr int expectedSize = 2 * sizeof(float) + HeaderSize;
+    std::vector<uint8_t> buffer(10000, 0);
     EXPECT_EQ(expectedSize, Cta861_3Value::encode(source, buffer.data(), buffer.size()));
     auto read = Cta861_3Value::decode(buffer.data(), buffer.size());
     ASSERT_TRUE(read.has_value());
@@ -240,14 +270,14 @@
 TEST(Metadata, setGetSmpte2094_10) {
     using SMPTE2094_10Value = StandardMetadata<StandardMetadataType::SMPTE2094_10>::value;
 
-    std::vector<uint8_t> buffer(500, 0);
+    std::vector<uint8_t> buffer(10000, 0);
     EXPECT_EQ(0, SMPTE2094_10Value::encode(std::nullopt, buffer.data(), buffer.size()));
     auto read = SMPTE2094_10Value::decode(buffer.data(), 0);
     ASSERT_TRUE(read.has_value());
     EXPECT_FALSE(read->has_value());
 
     const std::vector<uint8_t> emptyBuffer;
-    EXPECT_EQ(sizeof(int64_t),
+    EXPECT_EQ(sizeof(int64_t) + HeaderSize,
               SMPTE2094_10Value::encode(emptyBuffer, buffer.data(), buffer.size()));
     read = SMPTE2094_10Value::decode(buffer.data(), buffer.size());
     ASSERT_TRUE(read.has_value());
@@ -255,7 +285,7 @@
     EXPECT_EQ(0, read->value().size());
 
     const std::vector<uint8_t> simpleBuffer{0, 1, 2, 3, 4, 5};
-    EXPECT_EQ(sizeof(int64_t) + 6,
+    EXPECT_EQ(sizeof(int64_t) + 6 + HeaderSize,
               SMPTE2094_10Value::encode(simpleBuffer, buffer.data(), buffer.size()));
     read = SMPTE2094_10Value::decode(buffer.data(), buffer.size());
     ASSERT_TRUE(read.has_value());
@@ -266,7 +296,7 @@
 
 TEST(MetadataProvider, bufferId) {
     using BufferId = StandardMetadata<StandardMetadataType::BUFFER_ID>::value;
-    std::vector<uint8_t> buffer(500, 0);
+    std::vector<uint8_t> buffer(10000, 0);
     int result = provideStandardMetadata(StandardMetadataType::BUFFER_ID, buffer.data(),
                                          buffer.size(), []<StandardMetadataType T>(auto&& provide) {
                                              if constexpr (T == StandardMetadataType::BUFFER_ID) {
@@ -275,7 +305,7 @@
                                              return 0;
                                          });
 
-    EXPECT_EQ(8, result);
+    EXPECT_EQ(8 + HeaderSize, result);
     auto read = BufferId::decode(buffer.data(), buffer.size());
     EXPECT_EQ(42, read.value_or(0));
 }
@@ -312,3 +342,193 @@
     EXPECT_EQ(-AIMAPPER_ERROR_UNSUPPORTED, result)
             << "100 (out of range) should have resulted in UNSUPPORTED";
 }
+
+template <StandardMetadataType T>
+std::vector<uint8_t> encode(const typename StandardMetadata<T>::value_type& value) {
+    using Value = typename StandardMetadata<T>::value;
+
+    int desiredSize = Value::encode(value, nullptr, 0);
+    EXPECT_GE(desiredSize, 0);
+    std::vector<uint8_t> buffer;
+    buffer.resize(desiredSize);
+    EXPECT_EQ(desiredSize, Value::encode(value, buffer.data(), buffer.size()));
+    return buffer;
+}
+
+TEST(MetadataGralloc4Interop, BufferId) {
+    auto mpbuf = encode<StandardMetadataType::BUFFER_ID>(42);
+    hidl_vec<uint8_t> g4buf;
+    ASSERT_EQ(NO_ERROR, gralloc4::encodeBufferId(42, &g4buf));
+    EXPECT_EQ(mpbuf, g4buf);
+}
+
+TEST(MetadataGralloc4Interop, Name) {
+    auto mpbuf = encode<StandardMetadataType::NAME>("Hello, Interop!");
+    hidl_vec<uint8_t> g4buf;
+    ASSERT_EQ(NO_ERROR, gralloc4::encodeName("Hello, Interop!", &g4buf));
+    EXPECT_EQ(mpbuf, g4buf);
+}
+
+TEST(MetadataGralloc4Interop, Width) {
+    auto mpbuf = encode<StandardMetadataType::WIDTH>(128);
+    hidl_vec<uint8_t> g4buf;
+    ASSERT_EQ(NO_ERROR, gralloc4::encodeWidth(128, &g4buf));
+    EXPECT_EQ(mpbuf, g4buf);
+}
+
+TEST(MetadataGralloc4Interop, Height) {
+    auto mpbuf = encode<StandardMetadataType::HEIGHT>(64);
+    hidl_vec<uint8_t> g4buf;
+    ASSERT_EQ(NO_ERROR, gralloc4::encodeHeight(64, &g4buf));
+    EXPECT_EQ(mpbuf, g4buf);
+}
+
+TEST(MetadataGralloc4Interop, LayerCount) {
+    auto mpbuf = encode<StandardMetadataType::LAYER_COUNT>(3);
+    hidl_vec<uint8_t> g4buf;
+    ASSERT_EQ(NO_ERROR, gralloc4::encodeLayerCount(3, &g4buf));
+    EXPECT_EQ(mpbuf, g4buf);
+}
+
+TEST(MetadataGralloc4Interop, PixelFormatRequested) {
+    auto mpbuf = encode<StandardMetadataType::PIXEL_FORMAT_REQUESTED>(PixelFormat::RGBX_8888);
+    hidl_vec<uint8_t> g4buf;
+    ASSERT_EQ(NO_ERROR, gralloc4::encodePixelFormatRequested(
+                                hardware::graphics::common::V1_2::PixelFormat::RGBX_8888, &g4buf));
+    EXPECT_EQ(mpbuf, g4buf);
+}
+
+TEST(MetadataGralloc4Interop, PixelFormatFourcc) {
+    auto mpbuf = encode<StandardMetadataType::PIXEL_FORMAT_FOURCC>(DRM_FORMAT_ABGR8888);
+    hidl_vec<uint8_t> g4buf;
+    ASSERT_EQ(NO_ERROR, gralloc4::encodePixelFormatFourCC(DRM_FORMAT_ABGR8888, &g4buf));
+    EXPECT_EQ(mpbuf, g4buf);
+}
+
+TEST(MetadataGralloc4Interop, PixelFormatModifier) {
+    auto mpbuf = encode<StandardMetadataType::PIXEL_FORMAT_MODIFIER>(123456);
+    hidl_vec<uint8_t> g4buf;
+    ASSERT_EQ(NO_ERROR, gralloc4::encodePixelFormatModifier(123456, &g4buf));
+    EXPECT_EQ(mpbuf, g4buf);
+}
+
+TEST(MetadataGralloc4Interop, Usage) {
+    auto mpbuf = encode<StandardMetadataType::USAGE>(BufferUsage::COMPOSER_OVERLAY);
+    hidl_vec<uint8_t> g4buf;
+    ASSERT_EQ(NO_ERROR,
+              gralloc4::encodeUsage(
+                      static_cast<uint64_t>(
+                              hardware::graphics::common::V1_2::BufferUsage::COMPOSER_OVERLAY),
+                      &g4buf));
+    EXPECT_EQ(mpbuf, g4buf);
+}
+
+TEST(MetadataGralloc4Interop, AllocationSize) {
+    auto mpbuf = encode<StandardMetadataType::ALLOCATION_SIZE>(10200);
+    hidl_vec<uint8_t> g4buf;
+    ASSERT_EQ(NO_ERROR, gralloc4::encodeAllocationSize(10200, &g4buf));
+    EXPECT_EQ(mpbuf, g4buf);
+}
+
+TEST(MetadataGralloc4Interop, ProtectedContent) {
+    auto mpbuf = encode<StandardMetadataType::PROTECTED_CONTENT>(1);
+    hidl_vec<uint8_t> g4buf;
+    ASSERT_EQ(NO_ERROR, gralloc4::encodeProtectedContent(1, &g4buf));
+    EXPECT_EQ(mpbuf, g4buf);
+}
+
+TEST(MetadataGralloc4Interop, Compression) {
+    auto mpbuf = encode<StandardMetadataType::COMPRESSION>(
+            gralloc4::Compression_DisplayStreamCompression);
+    hidl_vec<uint8_t> g4buf;
+    ASSERT_EQ(NO_ERROR,
+              gralloc4::encodeCompression(gralloc4::Compression_DisplayStreamCompression, &g4buf));
+    EXPECT_EQ(mpbuf, g4buf);
+}
+
+TEST(MetadataGralloc4Interop, Interlaced) {
+    auto mpbuf = encode<StandardMetadataType::INTERLACED>(gralloc4::Interlaced_TopBottom);
+    hidl_vec<uint8_t> g4buf;
+    ASSERT_EQ(NO_ERROR, gralloc4::encodeInterlaced(gralloc4::Interlaced_TopBottom, &g4buf));
+    EXPECT_EQ(mpbuf, g4buf);
+}
+
+TEST(MetadataGralloc4Interop, ChromeSitting) {
+    auto mpbuf =
+            encode<StandardMetadataType::CHROMA_SITING>(gralloc4::ChromaSiting_SitedInterstitial);
+    hidl_vec<uint8_t> g4buf;
+    ASSERT_EQ(NO_ERROR,
+              gralloc4::encodeChromaSiting(gralloc4::ChromaSiting_SitedInterstitial, &g4buf));
+    EXPECT_EQ(mpbuf, g4buf);
+}
+
+TEST(MetadataGralloc4Interop, PlaneLayouts) {
+    auto mpbuf = encode<StandardMetadataType::PLANE_LAYOUTS>(fakePlaneLayouts());
+    hidl_vec<uint8_t> g4buf;
+    ASSERT_EQ(NO_ERROR, gralloc4::encodePlaneLayouts(fakePlaneLayouts(), &g4buf));
+    EXPECT_EQ(mpbuf, g4buf);
+}
+
+TEST(MetadataGralloc4Interop, Crop) {
+    std::vector<Rect> cropRects{Rect{10, 11, 12, 13}, Rect{20, 21, 22, 23}};
+    auto mpbuf = encode<StandardMetadataType::CROP>(cropRects);
+    hidl_vec<uint8_t> g4buf;
+    ASSERT_EQ(NO_ERROR, gralloc4::encodeCrop(cropRects, &g4buf));
+    EXPECT_EQ(mpbuf, g4buf);
+}
+
+TEST(MetadataGralloc4Interop, Dataspace) {
+    auto mpbuf = encode<StandardMetadataType::DATASPACE>(Dataspace::DISPLAY_P3);
+    hidl_vec<uint8_t> g4buf;
+    ASSERT_EQ(NO_ERROR, gralloc4::encodeDataspace(Dataspace::DISPLAY_P3, &g4buf));
+    EXPECT_EQ(mpbuf, g4buf);
+}
+
+TEST(MetadataGralloc4Interop, BlendMode) {
+    auto mpbuf = encode<StandardMetadataType::BLEND_MODE>(BlendMode::PREMULTIPLIED);
+    hidl_vec<uint8_t> g4buf;
+    ASSERT_EQ(NO_ERROR, gralloc4::encodeBlendMode(BlendMode::PREMULTIPLIED, &g4buf));
+    EXPECT_EQ(mpbuf, g4buf);
+}
+
+TEST(MetadataGralloc4Interop, Smpte2086) {
+    Smpte2086 hdrdata{XyColor{.1f, .2f}, XyColor{.3f, .4f}, XyColor{.5f, .6f},
+                      XyColor{.7f, .8f}, 452.889f,          12.335f};
+
+    auto mpbuf = encode<StandardMetadataType::SMPTE2086>(hdrdata);
+    hidl_vec<uint8_t> g4buf;
+    ASSERT_EQ(NO_ERROR, gralloc4::encodeSmpte2086(hdrdata, &g4buf));
+    EXPECT_EQ(mpbuf, g4buf);
+}
+
+TEST(MetadataGralloc4Interop, Cta861_3) {
+    Cta861_3 hdrdata{302.202f, 244.55f};
+    auto mpbuf = encode<StandardMetadataType::CTA861_3>(hdrdata);
+    hidl_vec<uint8_t> g4buf;
+    ASSERT_EQ(NO_ERROR, gralloc4::encodeCta861_3(hdrdata, &g4buf));
+    EXPECT_EQ(mpbuf, g4buf);
+}
+
+TEST(MetadataGralloc4Interop, Smpte2094_10) {
+    auto mpbuf = encode<StandardMetadataType::SMPTE2094_10>(std::nullopt);
+    hidl_vec<uint8_t> g4buf;
+    ASSERT_EQ(NO_ERROR, gralloc4::encodeSmpte2094_10(std::nullopt, &g4buf));
+    EXPECT_EQ(mpbuf, g4buf);
+
+    std::vector<uint8_t> hdrdata{1, 2, 3, 4, 5, 6};
+    mpbuf = encode<StandardMetadataType::SMPTE2094_10>(hdrdata);
+    ASSERT_EQ(NO_ERROR, gralloc4::encodeSmpte2094_10(hdrdata, &g4buf));
+    EXPECT_EQ(mpbuf, g4buf);
+}
+
+TEST(MetadataGralloc4Interop, Smpte2094_40) {
+    auto mpbuf = encode<StandardMetadataType::SMPTE2094_40>(std::nullopt);
+    hidl_vec<uint8_t> g4buf;
+    ASSERT_EQ(NO_ERROR, gralloc4::encodeSmpte2094_40(std::nullopt, &g4buf));
+    EXPECT_EQ(mpbuf, g4buf);
+
+    std::vector<uint8_t> hdrdata{1, 2, 3, 4, 5, 6};
+    mpbuf = encode<StandardMetadataType::SMPTE2094_40>(hdrdata);
+    ASSERT_EQ(NO_ERROR, gralloc4::encodeSmpte2094_40(hdrdata, &g4buf));
+    EXPECT_EQ(mpbuf, g4buf);
+}
diff --git a/graphics/mapper/stable-c/implutils/include/android/hardware/graphics/mapper/utils/IMapperMetadataTypes.h b/graphics/mapper/stable-c/implutils/include/android/hardware/graphics/mapper/utils/IMapperMetadataTypes.h
index 7861af8..25af6d1 100644
--- a/graphics/mapper/stable-c/implutils/include/android/hardware/graphics/mapper/utils/IMapperMetadataTypes.h
+++ b/graphics/mapper/stable-c/implutils/include/android/hardware/graphics/mapper/utils/IMapperMetadataTypes.h
@@ -82,7 +82,12 @@
     explicit MetadataWriter(void* _Nullable destBuffer, size_t destBufferSize)
         : mDest(reinterpret_cast<uint8_t*>(destBuffer)), mSizeRemaining(destBufferSize) {}
 
-    int32_t desiredSize() const { return mDesiredSize; }
+    [[nodiscard]] int32_t desiredSize() const { return mDesiredSize; }
+
+    template <typename HEADER>
+    MetadataWriter& writeHeader() {
+        return write(HEADER::name).template write<int64_t>(HEADER::value);
+    }
 
     template <typename T, typename = std::enable_if_t<std::is_integral_v<T>>>
     MetadataWriter& write(T value) {
@@ -150,6 +155,18 @@
     [[nodiscard]] size_t remaining() const { return mSizeRemaining; }
     [[nodiscard]] bool ok() const { return mOk; }
 
+    template <typename HEADER>
+    MetadataReader& checkHeader() {
+        if (HEADER::name != readString()) {
+            mOk = false;
+        }
+        auto value = readInt<int64_t>();
+        if (!value || *value != HEADER::value) {
+            mOk = false;
+        }
+        return *this;
+    }
+
     template <typename T, typename = std::enable_if_t<std::is_integral_v<T>>>
     MetadataReader& read(T& dest) {
         if (const void* src = advance(sizeof(T))) {
@@ -228,27 +245,33 @@
     }
 };
 
-template <typename T, class Enable = void>
+template <typename HEADER, typename T, class Enable = void>
 struct MetadataValue {};
 
-template <typename T>
-struct MetadataValue<T, std::enable_if_t<std::is_integral_v<T>>> {
+template <typename HEADER, typename T>
+struct MetadataValue<HEADER, T, std::enable_if_t<std::is_integral_v<T>>> {
     [[nodiscard]] static int32_t encode(T value, void* _Nullable destBuffer,
                                         size_t destBufferSize) {
-        return MetadataWriter{destBuffer, destBufferSize}.write(value).desiredSize();
+        return MetadataWriter{destBuffer, destBufferSize}
+                .template writeHeader<HEADER>()
+                .write(value)
+                .desiredSize();
     }
 
     [[nodiscard]] static std::optional<T> decode(const void* _Nonnull metadata,
                                                  size_t metadataSize) {
-        return MetadataReader{metadata, metadataSize}.readInt<T>();
+        return MetadataReader{metadata, metadataSize}
+                .template checkHeader<HEADER>()
+                .template readInt<T>();
     }
 };
 
-template <typename T>
-struct MetadataValue<T, std::enable_if_t<std::is_enum_v<T>>> {
+template <typename HEADER, typename T>
+struct MetadataValue<HEADER, T, std::enable_if_t<std::is_enum_v<T>>> {
     [[nodiscard]] static int32_t encode(T value, void* _Nullable destBuffer,
                                         size_t destBufferSize) {
         return MetadataWriter{destBuffer, destBufferSize}
+                .template writeHeader<HEADER>()
                 .write(static_cast<std::underlying_type_t<T>>(value))
                 .desiredSize();
     }
@@ -256,47 +279,56 @@
     [[nodiscard]] static std::optional<T> decode(const void* _Nonnull metadata,
                                                  size_t metadataSize) {
         std::underlying_type_t<T> temp;
-        return MetadataReader{metadata, metadataSize}.read(temp).ok()
+        return MetadataReader{metadata, metadataSize}.template checkHeader<HEADER>().read(temp).ok()
                        ? std::optional<T>(static_cast<T>(temp))
                        : std::nullopt;
     }
 };
 
-template <>
-struct MetadataValue<std::string> {
+template <typename HEADER>
+struct MetadataValue<HEADER, std::string> {
     [[nodiscard]] static int32_t encode(const std::string_view& value, void* _Nullable destBuffer,
                                         size_t destBufferSize) {
-        return MetadataWriter{destBuffer, destBufferSize}.write(value).desiredSize();
+        return MetadataWriter{destBuffer, destBufferSize}
+                .template writeHeader<HEADER>()
+                .write(value)
+                .desiredSize();
     }
 
     [[nodiscard]] static std::optional<std::string> decode(const void* _Nonnull metadata,
                                                            size_t metadataSize) {
-        auto reader = MetadataReader{metadata, metadataSize};
+        auto reader = MetadataReader{metadata, metadataSize}.template checkHeader<HEADER>();
         auto result = reader.readString();
         return reader.ok() ? std::optional<std::string>{result} : std::nullopt;
     }
 };
 
-template <>
-struct MetadataValue<ExtendableType> {
+template <typename HEADER>
+struct MetadataValue<HEADER, ExtendableType> {
     static_assert(sizeof(int64_t) == sizeof(ExtendableType::value));
 
     [[nodiscard]] static int32_t encode(const ExtendableType& value, void* _Nullable destBuffer,
                                         size_t destBufferSize) {
-        return MetadataWriter{destBuffer, destBufferSize}.write(value).desiredSize();
+        return MetadataWriter{destBuffer, destBufferSize}
+                .template writeHeader<HEADER>()
+                .write(value)
+                .desiredSize();
     }
 
     [[nodiscard]] static std::optional<ExtendableType> decode(const void* _Nonnull metadata,
                                                               size_t metadataSize) {
-        return MetadataReader{metadata, metadataSize}.readExtendable();
+        return MetadataReader{metadata, metadataSize}
+                .template checkHeader<HEADER>()
+                .readExtendable();
     }
 };
 
-template <>
-struct MetadataValue<std::vector<PlaneLayout>> {
+template <typename HEADER>
+struct MetadataValue<HEADER, std::vector<PlaneLayout>> {
     [[nodiscard]] static int32_t encode(const std::vector<PlaneLayout>& values,
                                         void* _Nullable destBuffer, size_t destBufferSize) {
         MetadataWriter writer{destBuffer, destBufferSize};
+        writer.template writeHeader<HEADER>();
         writer.write<int64_t>(values.size());
         for (const auto& value : values) {
             writer.write<int64_t>(value.components.size());
@@ -321,13 +353,14 @@
     [[nodiscard]] static DecodeResult decode(const void* _Nonnull metadata, size_t metadataSize) {
         std::vector<PlaneLayout> values;
         MetadataReader reader{metadata, metadataSize};
+        reader.template checkHeader<HEADER>();
         auto numPlanes = reader.readInt<int64_t>().value_or(0);
         values.reserve(numPlanes);
         for (int i = 0; i < numPlanes && reader.ok(); i++) {
             PlaneLayout& value = values.emplace_back();
             auto numPlaneComponents = reader.readInt<int64_t>().value_or(0);
             value.components.reserve(numPlaneComponents);
-            for (int i = 0; i < numPlaneComponents && reader.ok(); i++) {
+            for (int j = 0; j < numPlaneComponents && reader.ok(); j++) {
                 PlaneLayoutComponent& component = value.components.emplace_back();
                 reader.read(component.type)
                         .read<int64_t>(component.offsetInBits)
@@ -346,11 +379,12 @@
     }
 };
 
-template <>
-struct MetadataValue<std::vector<Rect>> {
+template <typename HEADER>
+struct MetadataValue<HEADER, std::vector<Rect>> {
     [[nodiscard]] static int32_t encode(const std::vector<Rect>& value, void* _Nullable destBuffer,
                                         size_t destBufferSize) {
         MetadataWriter writer{destBuffer, destBufferSize};
+        writer.template writeHeader<HEADER>();
         writer.write<int64_t>(value.size());
         for (auto& rect : value) {
             writer.write<int32_t>(rect.left)
@@ -364,6 +398,7 @@
     using DecodeResult = std::optional<std::vector<Rect>>;
     [[nodiscard]] static DecodeResult decode(const void* _Nonnull metadata, size_t metadataSize) {
         MetadataReader reader{metadata, metadataSize};
+        reader.template checkHeader<HEADER>();
         std::vector<Rect> value;
         auto numRects = reader.readInt<int64_t>().value_or(0);
         value.reserve(numRects);
@@ -378,13 +413,14 @@
     }
 };
 
-template <>
-struct MetadataValue<std::optional<Smpte2086>> {
+template <typename HEADER>
+struct MetadataValue<HEADER, std::optional<Smpte2086>> {
     [[nodiscard]] static int32_t encode(const std::optional<Smpte2086>& optValue,
                                         void* _Nullable destBuffer, size_t destBufferSize) {
         if (optValue.has_value()) {
             const auto& value = *optValue;
             return MetadataWriter{destBuffer, destBufferSize}
+                    .template writeHeader<HEADER>()
                     .write(value.primaryRed)
                     .write(value.primaryGreen)
                     .write(value.primaryBlue)
@@ -404,6 +440,7 @@
         if (metadataSize > 0) {
             Smpte2086 value;
             MetadataReader reader{metadata, metadataSize};
+            reader.template checkHeader<HEADER>();
             reader.read(value.primaryRed)
                     .read(value.primaryGreen)
                     .read(value.primaryBlue)
@@ -420,13 +457,14 @@
     }
 };
 
-template <>
-struct MetadataValue<std::optional<Cta861_3>> {
+template <typename HEADER>
+struct MetadataValue<HEADER, std::optional<Cta861_3>> {
     [[nodiscard]] static int32_t encode(const std::optional<Cta861_3>& optValue,
                                         void* _Nullable destBuffer, size_t destBufferSize) {
         if (optValue.has_value()) {
             const auto& value = *optValue;
             return MetadataWriter{destBuffer, destBufferSize}
+                    .template writeHeader<HEADER>()
                     .write(value.maxContentLightLevel)
                     .write(value.maxFrameAverageLightLevel)
                     .desiredSize();
@@ -441,6 +479,7 @@
         std::optional<Cta861_3> optValue{std::nullopt};
         if (metadataSize > 0) {
             MetadataReader reader{metadata, metadataSize};
+            reader.template checkHeader<HEADER>();
             Cta861_3 value;
             reader.read(value.maxContentLightLevel).read(value.maxFrameAverageLightLevel);
             if (reader.ok()) {
@@ -453,14 +492,17 @@
     }
 };
 
-template <>
-struct MetadataValue<std::optional<std::vector<uint8_t>>> {
+template <typename HEADER>
+struct MetadataValue<HEADER, std::optional<std::vector<uint8_t>>> {
     [[nodiscard]] static int32_t encode(const std::optional<std::vector<uint8_t>>& value,
                                         void* _Nullable destBuffer, size_t destBufferSize) {
         if (!value.has_value()) {
             return 0;
         }
-        return MetadataWriter{destBuffer, destBufferSize}.write(*value).desiredSize();
+        return MetadataWriter{destBuffer, destBufferSize}
+                .template writeHeader<HEADER>()
+                .write(*value)
+                .desiredSize();
     }
 
     using DecodeResult = std::optional<std::optional<std::vector<uint8_t>>>;
@@ -468,6 +510,7 @@
         std::optional<std::vector<uint8_t>> optValue;
         if (metadataSize > 0) {
             MetadataReader reader{metadata, metadataSize};
+            reader.template checkHeader<HEADER>();
             auto value = reader.readBuffer();
             if (reader.ok()) {
                 optValue = std::move(value);
@@ -482,16 +525,20 @@
 template <StandardMetadataType>
 struct StandardMetadata {};
 
-#define DEFINE_TYPE(name, typeArg)                                                            \
-    template <>                                                                               \
-    struct StandardMetadata<StandardMetadataType::name> {                                     \
-        using value_type = typeArg;                                                           \
-        using value = MetadataValue<value_type>;                                              \
-        static_assert(                                                                        \
-                StandardMetadataType::name ==                                                 \
-                        ndk::internal::enum_values<StandardMetadataType>[static_cast<size_t>( \
-                                StandardMetadataType::name)],                                 \
-                "StandardMetadataType must have equivalent value to index");                  \
+#define DEFINE_TYPE(typeName, typeArg)                                                            \
+    template <>                                                                                   \
+    struct StandardMetadata<StandardMetadataType::typeName> {                                     \
+        using value_type = typeArg;                                                               \
+        struct Header {                                                                           \
+            static constexpr auto name = "android.hardware.graphics.common.StandardMetadataType"; \
+            static constexpr auto value = static_cast<int64_t>(StandardMetadataType::typeName);   \
+        };                                                                                        \
+        using value = MetadataValue<Header, value_type>;                                          \
+        static_assert(                                                                            \
+                StandardMetadataType::typeName ==                                                 \
+                        ndk::internal::enum_values<StandardMetadataType>[static_cast<size_t>(     \
+                                StandardMetadataType::typeName)],                                 \
+                "StandardMetadataType must have equivalent value to index");                      \
     }
 
 DEFINE_TYPE(BUFFER_ID, uint64_t);
diff --git a/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h b/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h
index f27b0f4..0f6d146 100644
--- a/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h
+++ b/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h
@@ -509,11 +509,12 @@
      * particular Metadata field.
      *
      * The framework will attempt to set the following StandardMetadataType
-     * values: DATASPACE, SMPTE2086, CTA861_3, SMPTE2094_40 and BLEND_MODE.
-     * We require everyone to support setting those fields. If a device's Composer
-     * implementation supports a field, it should be supported here. Over time these
-     * metadata fields will be moved out of Composer/BufferQueue/etc. and into the
-     * buffer's Metadata fields.
+     * values: DATASPACE, SMPTE2086, CTA861_3, and BLEND_MODE.
+     * We require everyone to support setting those fields. Framework will also attempt to set
+     * SMPTE2094_40 and SMPTE2094_10 if available, and it is required to support setting those
+     * if it is possible to get them. If a device's Composer implementation supports a field,
+     * it should be supported here. Over time these metadata fields will be moved out of
+     * Composer/BufferQueue/etc. and into the buffer's Metadata fields.
      *
      * @param buffer Buffer receiving desired metadata
      * @param metadataType MetadataType for the metadata value being set
@@ -546,11 +547,12 @@
      * particular Metadata field.
      *
      * The framework will attempt to set the following StandardMetadataType
-     * values: DATASPACE, SMPTE2086, CTA861_3, SMPTE2094_40 and BLEND_MODE.
-     * We require everyone to support setting those fields. If a device's Composer
-     * implementation supports a field, it should be supported here. Over time these
-     * metadata fields will be moved out of Composer/BufferQueue/etc. and into the
-     * buffer's Metadata fields.
+     * values: DATASPACE, SMPTE2086, CTA861_3, and BLEND_MODE.
+     * We require everyone to support setting those fields. Framework will also attempt to set
+     * SMPTE2094_40 and SMPTE2094_10 if available, and it is required to support setting those
+     * if it is possible to get them. If a device's Composer implementation supports a field,
+     * it should be supported here. Over time these metadata fields will be moved out of
+     * Composer/BufferQueue/etc. and into the buffer's Metadata fields.
      *
      * @param buffer Buffer receiving desired metadata
      * @param standardMetadataType StandardMetadataType for the metadata value being set
diff --git a/graphics/mapper/stable-c/vts/VtsHalGraphicsMapperStableC_TargetTest.cpp b/graphics/mapper/stable-c/vts/VtsHalGraphicsMapperStableC_TargetTest.cpp
index 6ab11a3..85246ee 100644
--- a/graphics/mapper/stable-c/vts/VtsHalGraphicsMapperStableC_TargetTest.cpp
+++ b/graphics/mapper/stable-c/vts/VtsHalGraphicsMapperStableC_TargetTest.cpp
@@ -24,6 +24,7 @@
 #include <aidl/android/hardware/graphics/common/BufferUsage.h>
 #include <aidl/android/hardware/graphics/common/PixelFormat.h>
 #include <aidlcommonsupport/NativeHandle.h>
+#include <android/binder_enums.h>
 #include <android/binder_manager.h>
 #include <android/dlext.h>
 #include <android/hardware/graphics/mapper/IMapper.h>
@@ -66,6 +67,24 @@
     int64_t verticalSubSampling;
 };
 
+constexpr const char* STANDARD_METADATA_NAME =
+        "android.hardware.graphics.common.StandardMetadataType";
+
+static bool isStandardMetadata(AIMapper_MetadataType metadataType) {
+    return strcmp(STANDARD_METADATA_NAME, metadataType.name) == 0;
+}
+
+static std::string toString(const std::vector<StandardMetadataType> types) {
+    std::stringstream buf;
+    buf << "[";
+    for (auto type : types) {
+        buf << toString(type) << ", ";
+    }
+    buf.seekp(-2, buf.cur);
+    buf << "]";
+    return buf.str();
+}
+
 class BufferHandle {
     AIMapper* mIMapper;
     buffer_handle_t mHandle = nullptr;
@@ -215,7 +234,7 @@
             sizeRequired = mapper()->v5.getStandardMetadata(bufferHandle, static_cast<int64_t>(T),
                                                             buffer.data(), buffer.size());
         }
-        if (sizeRequired < 0 || sizeRequired >= buffer.size()) {
+        if (sizeRequired < 0 || sizeRequired > buffer.size()) {
             ADD_FAILURE() << "getStandardMetadata failed, received " << sizeRequired
                           << " with buffer size " << buffer.size();
             // Generate a fail type
@@ -1533,8 +1552,187 @@
     auto bufferHandle = buffer->import();
     ASSERT_TRUE(bufferHandle);
     auto value = getStandardMetadata<StandardMetadataType::SMPTE2094_40>(*bufferHandle);
-    ASSERT_TRUE(value.has_value());
-    EXPECT_FALSE(value->has_value());
+    if (value.has_value()) {
+        EXPECT_FALSE(value->has_value());
+    }
+}
+
+TEST_P(GraphicsMapperStableCTests, SupportsRequiredGettersSetters) {
+    auto buffer = allocateGeneric();
+    ASSERT_TRUE(buffer);
+    auto bufferHandle = buffer->import();
+    ASSERT_TRUE(bufferHandle);
+    const AIMapper_MetadataTypeDescription* descriptions = nullptr;
+    size_t descriptionCount = 0;
+    ASSERT_EQ(AIMAPPER_ERROR_NONE,
+              mapper()->v5.listSupportedMetadataTypes(&descriptions, &descriptionCount));
+    std::vector<StandardMetadataType> requiredGetters = {
+            StandardMetadataType::BUFFER_ID,
+            StandardMetadataType::NAME,
+            StandardMetadataType::WIDTH,
+            StandardMetadataType::HEIGHT,
+            StandardMetadataType::LAYER_COUNT,
+            StandardMetadataType::PIXEL_FORMAT_REQUESTED,
+            StandardMetadataType::PIXEL_FORMAT_FOURCC,
+            StandardMetadataType::PIXEL_FORMAT_MODIFIER,
+            StandardMetadataType::USAGE,
+            StandardMetadataType::ALLOCATION_SIZE,
+            StandardMetadataType::PROTECTED_CONTENT,
+            StandardMetadataType::COMPRESSION,
+            StandardMetadataType::INTERLACED,
+            StandardMetadataType::CHROMA_SITING,
+            StandardMetadataType::PLANE_LAYOUTS,
+            StandardMetadataType::CROP,
+            StandardMetadataType::DATASPACE,
+            StandardMetadataType::BLEND_MODE,
+            StandardMetadataType::SMPTE2086,
+            StandardMetadataType::CTA861_3,
+    };
+
+    std::vector<StandardMetadataType> requiredSetters = {
+            StandardMetadataType::DATASPACE,
+            StandardMetadataType::BLEND_MODE,
+            StandardMetadataType::SMPTE2086,
+            StandardMetadataType::CTA861_3,
+    };
+
+    for (int i = 0; i < descriptionCount; i++) {
+        const auto& it = descriptions[i];
+        if (isStandardMetadata(it.metadataType)) {
+            EXPECT_GT(it.metadataType.value, static_cast<int64_t>(StandardMetadataType::INVALID));
+            EXPECT_LT(it.metadataType.value,
+                      ndk::internal::enum_values<StandardMetadataType>.size());
+
+            if (it.isGettable) {
+                std::erase(requiredGetters,
+                           static_cast<StandardMetadataType>(it.metadataType.value));
+            }
+            if (it.isSettable) {
+                std::erase(requiredSetters,
+                           static_cast<StandardMetadataType>(it.metadataType.value));
+            }
+        } else {
+            EXPECT_NE(nullptr, it.description) << "Non-standard metadata must have a description";
+            int len = strlen(it.description);
+            EXPECT_GE(len, 0) << "Non-standard metadata must have a description";
+        }
+    }
+
+    EXPECT_EQ(0, requiredGetters.size()) << "Missing required getters" << toString(requiredGetters);
+    EXPECT_EQ(0, requiredSetters.size()) << "Missing required setters" << toString(requiredSetters);
+}
+
+/*
+ * Test that verifies that if the optional StandardMetadataTypes have getters, they have
+ * the required setters as well
+ */
+TEST_P(GraphicsMapperStableCTests, CheckRequiredSettersIfHasGetters) {
+    auto buffer = allocateGeneric();
+    ASSERT_TRUE(buffer);
+    auto bufferHandle = buffer->import();
+    ASSERT_TRUE(bufferHandle);
+    const AIMapper_MetadataTypeDescription* descriptions = nullptr;
+    size_t descriptionCount = 0;
+    ASSERT_EQ(AIMAPPER_ERROR_NONE,
+              mapper()->v5.listSupportedMetadataTypes(&descriptions, &descriptionCount));
+
+    for (int i = 0; i < descriptionCount; i++) {
+        const auto& it = descriptions[i];
+        if (isStandardMetadata(it.metadataType)) {
+            const auto type = static_cast<StandardMetadataType>(it.metadataType.value);
+            switch (type) {
+                case StandardMetadataType::SMPTE2094_10:
+                case StandardMetadataType::SMPTE2094_40:
+                    if (it.isGettable) {
+                        EXPECT_TRUE(it.isSettable)
+                                << "Type " << toString(type) << " must be settable if gettable";
+                    }
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+}
+
+TEST_P(GraphicsMapperStableCTests, ListSupportedWorks) {
+    auto buffer = allocateGeneric();
+    ASSERT_TRUE(buffer);
+    auto bufferHandle = buffer->import();
+    ASSERT_TRUE(bufferHandle);
+    const AIMapper_MetadataTypeDescription* descriptions = nullptr;
+    size_t descriptionCount = 0;
+    ASSERT_EQ(AIMAPPER_ERROR_NONE,
+              mapper()->v5.listSupportedMetadataTypes(&descriptions, &descriptionCount));
+
+    std::vector<uint8_t> metadataBuffer;
+    auto get = [&](AIMapper_MetadataType metadataType) -> int32_t {
+        int32_t size = mapper()->v5.getMetadata(*bufferHandle, metadataType, nullptr, 0);
+        if (size >= 0) {
+            metadataBuffer.resize(size);
+            size = mapper()->v5.getMetadata(*bufferHandle, metadataType, metadataBuffer.data(),
+                                            metadataBuffer.size());
+            EXPECT_EQ(size, metadataBuffer.size());
+        }
+        return size;
+    };
+
+    for (int i = 0; i < descriptionCount; i++) {
+        const auto& it = descriptions[i];
+        if (!isStandardMetadata(it.metadataType)) {
+            continue;
+        }
+        if (!it.isGettable) {
+            EXPECT_FALSE(it.isSettable)
+                    << "StandardMetadata that isn't gettable must not be settable";
+            continue;
+        }
+        EXPECT_GE(get(it.metadataType), 0)
+                << "Get failed for claimed supported getter of "
+                << toString(static_cast<StandardMetadataType>(it.metadataType.value));
+        if (it.isSettable) {
+            EXPECT_EQ(AIMAPPER_ERROR_NONE,
+                      mapper()->v5.setMetadata(*bufferHandle, it.metadataType,
+                                               metadataBuffer.data(), metadataBuffer.size()))
+                    << "Failed to set metadata for "
+                    << toString(static_cast<StandardMetadataType>(it.metadataType.value));
+        }
+    }
+}
+
+TEST_P(GraphicsMapperStableCTests, GetMetadataBadValue) {
+    auto get = [this](StandardMetadataType type) -> AIMapper_Error {
+        // This is a _Nonnull parameter, but this is enough obfuscation to fool the linter
+        buffer_handle_t buffer = nullptr;
+        int32_t ret =
+                mapper()->v5.getStandardMetadata(buffer, static_cast<int64_t>(type), nullptr, 0);
+        return (ret < 0) ? (AIMapper_Error)-ret : AIMAPPER_ERROR_NONE;
+    };
+
+    for (auto type : ndk::enum_range<StandardMetadataType>()) {
+        if (type == StandardMetadataType::INVALID) {
+            continue;
+        }
+        EXPECT_EQ(AIMAPPER_ERROR_BAD_BUFFER, get(type)) << "Wrong error for " << toString(type);
+    }
+}
+
+TEST_P(GraphicsMapperStableCTests, GetUnsupportedMetadata) {
+    auto buffer = allocateGeneric();
+    ASSERT_TRUE(buffer);
+    auto bufferHandle = buffer->import();
+    ASSERT_TRUE(bufferHandle);
+
+    int result = mapper()->v5.getMetadata(*bufferHandle, {"Fake", 1}, nullptr, 0);
+    EXPECT_EQ(AIMAPPER_ERROR_UNSUPPORTED, -result);
+
+    result = mapper()->v5.getStandardMetadata(
+            *bufferHandle, static_cast<int64_t>(StandardMetadataType::INVALID), nullptr, 0);
+    EXPECT_EQ(AIMAPPER_ERROR_UNSUPPORTED, -result);
+
+    constexpr int64_t unknownStandardType = ndk::internal::enum_values<StandardMetadataType>.size();
+    result = mapper()->v5.getStandardMetadata(*bufferHandle, unknownStandardType, nullptr, 0);
+    EXPECT_EQ(AIMAPPER_ERROR_UNSUPPORTED, -result);
 }
 
 std::vector<std::tuple<std::string, std::shared_ptr<IAllocator>>> getIAllocatorsAtLeastVersion(