Merge changes from topic "cherrypicker-L74500030002769125:N35700030046036139" into 24D1-dev

* changes:
  Adapt CheckApfIsSupported for VSR-15 compatibility
  Update APF VTS for VSR-14 compliance
diff --git a/audio/aidl/common/include/Utils.h b/audio/aidl/common/include/Utils.h
index ef312d5..f8011e5 100644
--- a/audio/aidl/common/include/Utils.h
+++ b/audio/aidl/common/include/Utils.h
@@ -47,6 +47,9 @@
 
 namespace aidl::android::hardware::audio::common {
 
+// TODO: b/275135031 - move this string to AIDL interfaces.
+static constexpr char kDumpFromAudioServerArgument[] = "dump_from_audioserver";
+
 // Some values are reserved for use by the system code only.
 // HALs must not accept or emit values outside from the provided list.
 constexpr std::array<::aidl::android::media::audio::common::AudioMode, 5> kValidAudioModes = {
diff --git a/audio/aidl/default/EffectImpl.cpp b/audio/aidl/default/EffectImpl.cpp
index 03de74f..7192d97 100644
--- a/audio/aidl/default/EffectImpl.cpp
+++ b/audio/aidl/default/EffectImpl.cpp
@@ -23,6 +23,9 @@
 #include "include/effect-impl/EffectTypes.h"
 
 using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::kEventFlagDataMqNotEmpty;
+using aidl::android::hardware::audio::effect::kEventFlagNotEmpty;
+using aidl::android::hardware::audio::effect::kReopenSupportedVersion;
 using aidl::android::hardware::audio::effect::State;
 using aidl::android::media::audio::common::PcmType;
 using ::android::hardware::EventFlag;
@@ -43,7 +46,6 @@
 ndk::ScopedAStatus EffectImpl::open(const Parameter::Common& common,
                                     const std::optional<Parameter::Specific>& specific,
                                     OpenEffectReturn* ret) {
-    LOG(DEBUG) << getEffectName() << __func__;
     // effect only support 32bits float
     RETURN_IF(common.input.base.format.pcm != common.output.base.format.pcm ||
                       common.input.base.format.pcm != PcmType::FLOAT_32_BIT,
@@ -54,11 +56,12 @@
     mImplContext = createContext(common);
     RETURN_IF(!mImplContext, EX_NULL_POINTER, "nullContext");
 
-    int version = 0;
-    RETURN_IF(!getInterfaceVersion(&version).isOk(), EX_UNSUPPORTED_OPERATION,
+    RETURN_IF(!getInterfaceVersion(&mVersion).isOk(), EX_UNSUPPORTED_OPERATION,
               "FailedToGetInterfaceVersion");
-    mImplContext->setVersion(version);
+    mImplContext->setVersion(mVersion);
     mEventFlag = mImplContext->getStatusEventFlag();
+    mDataMqNotEmptyEf =
+            mVersion >= kReopenSupportedVersion ? kEventFlagDataMqNotEmpty : kEventFlagNotEmpty;
 
     if (specific.has_value()) {
         RETURN_IF_ASTATUS_NOT_OK(setParameterSpecific(specific.value()), "setSpecParamErr");
@@ -66,8 +69,9 @@
 
     mState = State::IDLE;
     mImplContext->dupeFmq(ret);
-    RETURN_IF(createThread(getEffectName()) != RetCode::SUCCESS, EX_UNSUPPORTED_OPERATION,
-              "FailedToCreateWorker");
+    RETURN_IF(createThread(getEffectNameWithVersion()) != RetCode::SUCCESS,
+              EX_UNSUPPORTED_OPERATION, "FailedToCreateWorker");
+    LOG(INFO) << getEffectNameWithVersion() << __func__;
     return ndk::ScopedAStatus::ok();
 }
 
@@ -89,7 +93,7 @@
         mState = State::INIT;
     }
 
-    RETURN_IF(notifyEventFlag(kEventFlagNotEmpty) != RetCode::SUCCESS, EX_ILLEGAL_STATE,
+    RETURN_IF(notifyEventFlag(mDataMqNotEmptyEf) != RetCode::SUCCESS, EX_ILLEGAL_STATE,
               "notifyEventFlagNotEmptyFailed");
     // stop the worker thread, ignore the return code
     RETURN_IF(destroyThread() != RetCode::SUCCESS, EX_UNSUPPORTED_OPERATION,
@@ -101,13 +105,13 @@
         mImplContext.reset();
     }
 
-    LOG(DEBUG) << getEffectName() << __func__;
+    LOG(INFO) << getEffectNameWithVersion() << __func__;
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus EffectImpl::setParameter(const Parameter& param) {
     std::lock_guard lg(mImplMutex);
-    LOG(VERBOSE) << getEffectName() << __func__ << " with: " << param.toString();
+    LOG(VERBOSE) << getEffectNameWithVersion() << __func__ << " with: " << param.toString();
 
     const auto& tag = param.getTag();
     switch (tag) {
@@ -122,7 +126,7 @@
             return setParameterSpecific(param.get<Parameter::specific>());
         }
         default: {
-            LOG(ERROR) << getEffectName() << __func__ << " unsupportedParameterTag "
+            LOG(ERROR) << getEffectNameWithVersion() << __func__ << " unsupportedParameterTag "
                        << toString(tag);
             return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
                                                                     "ParameterNotSupported");
@@ -147,7 +151,7 @@
             break;
         }
     }
-    LOG(VERBOSE) << getEffectName() << __func__ << id.toString() << param->toString();
+    LOG(VERBOSE) << getEffectNameWithVersion() << __func__ << id.toString() << param->toString();
     return ndk::ScopedAStatus::ok();
 }
 
@@ -180,7 +184,7 @@
                       EX_ILLEGAL_ARGUMENT, "setVolumeStereoFailed");
             break;
         default: {
-            LOG(ERROR) << getEffectName() << __func__ << " unsupportedParameterTag "
+            LOG(ERROR) << getEffectNameWithVersion() << __func__ << " unsupportedParameterTag "
                        << toString(tag);
             return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
                                                                     "commonParamNotSupported");
@@ -214,7 +218,8 @@
             break;
         }
         default: {
-            LOG(DEBUG) << getEffectName() << __func__ << " unsupported tag " << toString(tag);
+            LOG(DEBUG) << getEffectNameWithVersion() << __func__ << " unsupported tag "
+                       << toString(tag);
             return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
                                                                     "tagNotSupported");
         }
@@ -236,7 +241,7 @@
             RETURN_OK_IF(mState == State::PROCESSING);
             RETURN_IF_ASTATUS_NOT_OK(commandImpl(command), "commandImplFailed");
             mState = State::PROCESSING;
-            RETURN_IF(notifyEventFlag(kEventFlagNotEmpty) != RetCode::SUCCESS, EX_ILLEGAL_STATE,
+            RETURN_IF(notifyEventFlag(mDataMqNotEmptyEf) != RetCode::SUCCESS, EX_ILLEGAL_STATE,
                       "notifyEventFlagNotEmptyFailed");
             startThread();
             break;
@@ -244,17 +249,18 @@
         case CommandId::RESET:
             RETURN_OK_IF(mState == State::IDLE);
             mState = State::IDLE;
-            RETURN_IF(notifyEventFlag(kEventFlagNotEmpty) != RetCode::SUCCESS, EX_ILLEGAL_STATE,
+            RETURN_IF(notifyEventFlag(mDataMqNotEmptyEf) != RetCode::SUCCESS, EX_ILLEGAL_STATE,
                       "notifyEventFlagNotEmptyFailed");
             stopThread();
             RETURN_IF_ASTATUS_NOT_OK(commandImpl(command), "commandImplFailed");
             break;
         default:
-            LOG(ERROR) << getEffectName() << __func__ << " instance still processing";
+            LOG(ERROR) << getEffectNameWithVersion() << __func__ << " instance still processing";
             return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
                                                                     "CommandIdNotSupported");
     }
-    LOG(VERBOSE) << getEffectName() << __func__ << " transfer to state: " << toString(mState);
+    LOG(VERBOSE) << getEffectNameWithVersion() << __func__
+                 << " transfer to state: " << toString(mState);
     return ndk::ScopedAStatus::ok();
 }
 
@@ -284,14 +290,14 @@
 
 RetCode EffectImpl::notifyEventFlag(uint32_t flag) {
     if (!mEventFlag) {
-        LOG(ERROR) << getEffectName() << __func__ << ": StatusEventFlag invalid";
+        LOG(ERROR) << getEffectNameWithVersion() << __func__ << ": StatusEventFlag invalid";
         return RetCode::ERROR_EVENT_FLAG_ERROR;
     }
     if (const auto ret = mEventFlag->wake(flag); ret != ::android::OK) {
-        LOG(ERROR) << getEffectName() << __func__ << ": wake failure with ret " << ret;
+        LOG(ERROR) << getEffectNameWithVersion() << __func__ << ": wake failure with ret " << ret;
         return RetCode::ERROR_EVENT_FLAG_ERROR;
     }
-    LOG(VERBOSE) << getEffectName() << __func__ << ": " << std::hex << mEventFlag;
+    LOG(VERBOSE) << getEffectNameWithVersion() << __func__ << ": " << std::hex << mEventFlag;
     return RetCode::SUCCESS;
 }
 
@@ -304,17 +310,17 @@
 }
 
 void EffectImpl::process() {
-    ATRACE_NAME(getEffectName().c_str());
+    ATRACE_NAME(getEffectNameWithVersion().c_str());
     /**
      * wait for the EventFlag without lock, it's ok because the mEfGroup pointer will not change
      * in the life cycle of workerThread (threadLoop).
      */
     uint32_t efState = 0;
     if (!mEventFlag ||
-        ::android::OK != mEventFlag->wait(kEventFlagNotEmpty, &efState, 0 /* no timeout */,
+        ::android::OK != mEventFlag->wait(mDataMqNotEmptyEf, &efState, 0 /* no timeout */,
                                           true /* retry */) ||
-        !(efState & kEventFlagNotEmpty)) {
-        LOG(ERROR) << getEffectName() << __func__ << ": StatusEventFlag - " << mEventFlag
+        !(efState & mDataMqNotEmptyEf)) {
+        LOG(ERROR) << getEffectNameWithVersion() << __func__ << ": StatusEventFlag - " << mEventFlag
                    << " efState - " << std::hex << efState;
         return;
     }
@@ -322,7 +328,8 @@
     {
         std::lock_guard lg(mImplMutex);
         if (mState != State::PROCESSING) {
-            LOG(DEBUG) << getEffectName() << " skip process in state: " << toString(mState);
+            LOG(DEBUG) << getEffectNameWithVersion()
+                       << " skip process in state: " << toString(mState);
             return;
         }
         RETURN_VALUE_IF(!mImplContext, void(), "nullContext");
diff --git a/audio/aidl/default/bluetooth/StreamBluetooth.cpp b/audio/aidl/default/bluetooth/StreamBluetooth.cpp
index f22b7a9..efab470 100644
--- a/audio/aidl/default/bluetooth/StreamBluetooth.cpp
+++ b/audio/aidl/default/bluetooth/StreamBluetooth.cpp
@@ -93,17 +93,18 @@
 ::android::status_t StreamBluetooth::transfer(void* buffer, size_t frameCount,
                                               size_t* actualFrameCount, int32_t* latencyMs) {
     std::lock_guard guard(mLock);
+    *actualFrameCount = 0;
+    *latencyMs = StreamDescriptor::LATENCY_UNKNOWN;
     if (mBtDeviceProxy == nullptr || mBtDeviceProxy->getState() == BluetoothStreamState::DISABLED) {
-        *actualFrameCount = 0;
-        *latencyMs = StreamDescriptor::LATENCY_UNKNOWN;
+        // The BT session is turned down, silently ignore write.
         return ::android::OK;
     }
-    *actualFrameCount = 0;
-    *latencyMs = 0;
     if (!mBtDeviceProxy->start()) {
-        LOG(ERROR) << __func__ << ": state= " << mBtDeviceProxy->getState() << " failed to start";
-        return -EIO;
+        LOG(WARNING) << __func__ << ": state= " << mBtDeviceProxy->getState()
+                     << " failed to start, will retry";
+        return ::android::OK;
     }
+    *latencyMs = 0;
     const size_t bytesToTransfer = frameCount * mFrameSizeBytes;
     const size_t bytesTransferred = mIsInput ? mBtDeviceProxy->readData(buffer, bytesToTransfer)
                                              : mBtDeviceProxy->writeData(buffer, bytesToTransfer);
diff --git a/audio/aidl/default/include/effect-impl/EffectImpl.h b/audio/aidl/default/include/effect-impl/EffectImpl.h
index 21f6502..d3bb7f4 100644
--- a/audio/aidl/default/include/effect-impl/EffectImpl.h
+++ b/audio/aidl/default/include/effect-impl/EffectImpl.h
@@ -89,6 +89,11 @@
     void process() override;
 
   protected:
+    // current Hal version
+    int mVersion = 0;
+    // Use kEventFlagNotEmpty for V1 HAL, kEventFlagDataMqNotEmpty for V2 and above
+    int mDataMqNotEmptyEf = aidl::android::hardware::audio::effect::kEventFlagDataMqNotEmpty;
+
     State mState GUARDED_BY(mImplMutex) = State::INIT;
 
     IEffect::Status status(binder_status_t status, size_t consumed, size_t produced);
@@ -107,6 +112,11 @@
     virtual ndk::ScopedAStatus commandImpl(CommandId id) REQUIRES(mImplMutex);
 
     RetCode notifyEventFlag(uint32_t flag);
+
+    std::string getEffectNameWithVersion() {
+        return getEffectName() + "V" + std::to_string(mVersion);
+    }
+
     ::android::hardware::EventFlag* mEventFlag;
 };
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/vts/EffectHelper.h b/audio/aidl/vts/EffectHelper.h
index 82a07fd..9c6fed4 100644
--- a/audio/aidl/vts/EffectHelper.h
+++ b/audio/aidl/vts/EffectHelper.h
@@ -43,8 +43,10 @@
 using aidl::android::hardware::audio::effect::CommandId;
 using aidl::android::hardware::audio::effect::Descriptor;
 using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::kEventFlagDataMqNotEmpty;
 using aidl::android::hardware::audio::effect::kEventFlagDataMqUpdate;
 using aidl::android::hardware::audio::effect::kEventFlagNotEmpty;
+using aidl::android::hardware::audio::effect::kReopenSupportedVersion;
 using aidl::android::hardware::audio::effect::Parameter;
 using aidl::android::hardware::audio::effect::Range;
 using aidl::android::hardware::audio::effect::State;
@@ -158,7 +160,7 @@
         std::fill(buffer.begin(), buffer.end(), 0x5a);
     }
     static void writeToFmq(std::unique_ptr<StatusMQ>& statusMq, std::unique_ptr<DataMQ>& dataMq,
-                           const std::vector<float>& buffer) {
+                           const std::vector<float>& buffer, int version) {
         const size_t available = dataMq->availableToWrite();
         ASSERT_NE(0Ul, available);
         auto bufferFloats = buffer.size();
@@ -169,7 +171,8 @@
         ASSERT_EQ(::android::OK,
                   EventFlag::createEventFlag(statusMq->getEventFlagWord(), &efGroup));
         ASSERT_NE(nullptr, efGroup);
-        efGroup->wake(kEventFlagNotEmpty);
+        efGroup->wake(version >= kReopenSupportedVersion ? kEventFlagDataMqNotEmpty
+                                                         : kEventFlagNotEmpty);
         ASSERT_EQ(::android::OK, EventFlag::deleteEventFlag(&efGroup));
     }
     static void readFromFmq(std::unique_ptr<StatusMQ>& statusMq, size_t statusNum,
@@ -320,7 +323,10 @@
         ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
 
         // Write from buffer to message queues and calling process
-        EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, inputBuffer));
+        EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, inputBuffer, [&]() {
+            int version = 0;
+            return (mEffect && mEffect->getInterfaceVersion(&version).isOk()) ? version : 0;
+        }()));
 
         // Read the updated message queues into buffer
         EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(statusMQ, 1, outputMQ,
diff --git a/audio/aidl/vts/TestUtils.h b/audio/aidl/vts/TestUtils.h
index 0a5addc..3a6c137 100644
--- a/audio/aidl/vts/TestUtils.h
+++ b/audio/aidl/vts/TestUtils.h
@@ -108,7 +108,7 @@
     ({                                                                                            \
         if ((flags).hwAcceleratorMode ==                                                          \
                     aidl::android::hardware::audio::effect::Flags::HardwareAccelerator::TUNNEL || \
-            (flags).bypass) {                                                                     \
+            (flags).bypass || (flags).offloadIndication) {                                        \
             GTEST_SKIP() << "Skip data path for offload";                                         \
         }                                                                                         \
     })
diff --git a/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp b/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
index 4693f10..5b83d73 100644
--- a/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
@@ -42,7 +42,6 @@
 using aidl::android::hardware::audio::effect::Flags;
 using aidl::android::hardware::audio::effect::IEffect;
 using aidl::android::hardware::audio::effect::IFactory;
-using aidl::android::hardware::audio::effect::kReopenSupportedVersion;
 using aidl::android::hardware::audio::effect::Parameter;
 using aidl::android::hardware::audio::effect::State;
 using aidl::android::media::audio::common::AudioDeviceDescription;
@@ -58,6 +57,7 @@
   public:
     AudioEffectTest() {
         std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
+        mVersion = EffectFactoryHelper::getHalVersion(mFactory);
     }
 
     void SetUp() override {}
@@ -76,6 +76,7 @@
     std::shared_ptr<IFactory> mFactory;
     std::shared_ptr<IEffect> mEffect;
     Descriptor mDescriptor;
+    int mVersion = 0;
 
     void setAndGetParameter(Parameter::Id id, const Parameter& set) {
         Parameter get;
@@ -682,7 +683,7 @@
 
     std::vector<float> buffer;
     EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer));
-    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion));
     EXPECT_NO_FATAL_FAILURE(
             EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer));
 
@@ -722,7 +723,7 @@
     ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
 
     EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer));
-    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion));
     EXPECT_NO_FATAL_FAILURE(
             EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer));
 
@@ -759,7 +760,7 @@
     ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
     ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
     EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer));
-    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion));
     EXPECT_NO_FATAL_FAILURE(
             EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer));
 
@@ -779,7 +780,7 @@
 
     // verify data consume again
     EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer));
-    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion));
     EXPECT_NO_FATAL_FAILURE(
             EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer));
 
@@ -810,7 +811,7 @@
 
     std::vector<float> buffer;
     EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer));
-    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion));
 
     ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
     ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
@@ -844,7 +845,7 @@
 
     std::vector<float> buffer;
     EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer));
-    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion));
     EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer));
 
     ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
@@ -853,7 +854,7 @@
     EXPECT_NO_FATAL_FAILURE(
             EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer));
 
-    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion));
     EXPECT_NO_FATAL_FAILURE(
             EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer));
 
@@ -886,13 +887,13 @@
     ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
     std::vector<float> buffer;
     EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer));
-    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion));
     EXPECT_NO_FATAL_FAILURE(
             EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer));
 
     ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
     ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
-    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion));
     EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer));
 
     ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
@@ -928,7 +929,7 @@
 
     std::vector<float> buffer;
     EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer));
-    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion));
     EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer));
 
     ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
@@ -964,7 +965,7 @@
 
     std::vector<float> buffer1, buffer2;
     EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common1, inputMQ1, buffer1));
-    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ1, inputMQ1, buffer1));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ1, inputMQ1, buffer1, mVersion));
     EXPECT_NO_FATAL_FAILURE(
             EffectHelper::readFromFmq(statusMQ1, 1, outputMQ1, buffer1.size(), buffer1));
 
@@ -975,7 +976,7 @@
     auto outputMQ2 = std::make_unique<EffectHelper::DataMQ>(ret2.outputDataMQ);
     ASSERT_TRUE(outputMQ2->isValid());
     EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common2, inputMQ2, buffer2));
-    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ2, inputMQ2, buffer2));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ2, inputMQ2, buffer2, mVersion));
     EXPECT_NO_FATAL_FAILURE(
             EffectHelper::readFromFmq(statusMQ2, 1, outputMQ2, buffer2.size(), buffer2));
 
diff --git a/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp b/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp
index 3f7a76d..12b1797 100644
--- a/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp
+++ b/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp
@@ -195,48 +195,42 @@
 
 template <typename T>
 bool DynamicsProcessingTestHelper::isBandConfigValid(const std::vector<T>& cfgs, int bandCount) {
-    std::vector<float> freqs(cfgs.size(), -1);
+    std::unordered_set<int> freqs;
     for (auto cfg : cfgs) {
         if (cfg.channel < 0 || cfg.channel >= mChannelCount) return false;
         if (cfg.band < 0 || cfg.band >= bandCount) return false;
-        freqs[cfg.band] = cfg.cutoffFrequencyHz;
+        // duplicated band index
+        if (freqs.find(cfg.band) != freqs.end()) return false;
+        freqs.insert(cfg.band);
     }
-    if (std::count(freqs.begin(), freqs.end(), -1)) return false;
-    return std::is_sorted(freqs.begin(), freqs.end());
+    return true;
 }
 
 bool DynamicsProcessingTestHelper::isParamValid(const DynamicsProcessing::Tag& tag,
                                                 const DynamicsProcessing& dp) {
     switch (tag) {
         case DynamicsProcessing::preEq: {
-            if (!mEngineConfigApplied.preEqStage.inUse) return false;
             return isChannelConfigValid(dp.get<DynamicsProcessing::preEq>());
         }
         case DynamicsProcessing::postEq: {
-            if (!mEngineConfigApplied.postEqStage.inUse) return false;
             return isChannelConfigValid(dp.get<DynamicsProcessing::postEq>());
         }
         case DynamicsProcessing::mbc: {
-            if (!mEngineConfigApplied.mbcStage.inUse) return false;
             return isChannelConfigValid(dp.get<DynamicsProcessing::mbc>());
         }
         case DynamicsProcessing::preEqBand: {
-            if (!mEngineConfigApplied.preEqStage.inUse) return false;
             return isBandConfigValid(dp.get<DynamicsProcessing::preEqBand>(),
                                      mEngineConfigApplied.preEqStage.bandCount);
         }
         case DynamicsProcessing::postEqBand: {
-            if (!mEngineConfigApplied.postEqStage.inUse) return false;
             return isBandConfigValid(dp.get<DynamicsProcessing::postEqBand>(),
                                      mEngineConfigApplied.postEqStage.bandCount);
         }
         case DynamicsProcessing::mbcBand: {
-            if (!mEngineConfigApplied.mbcStage.inUse) return false;
             return isBandConfigValid(dp.get<DynamicsProcessing::mbcBand>(),
                                      mEngineConfigApplied.mbcStage.bandCount);
         }
         case DynamicsProcessing::limiter: {
-            if (!mEngineConfigApplied.limiterInUse) return false;
             return isChannelConfigValid(dp.get<DynamicsProcessing::limiter>());
         }
         case DynamicsProcessing::inputGain: {
@@ -459,12 +453,11 @@
     ENGINE_TEST_INSTANCE_NAME,
     ENGINE_TEST_RESOLUTION_PREFERENCE,
     ENGINE_TEST_PREFERRED_DURATION,
-    ENGINE_TEST_STAGE_ENABLEMENT,
-    ENGINE_TEST_LIMITER_IN_USE
+    ENGINE_TEST_STAGE_ENABLEMENT
 };
 using EngineArchitectureTestParams = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>,
                                                 DynamicsProcessing::ResolutionPreference, float,
-                                                DynamicsProcessing::StageEnablement, bool>;
+                                                DynamicsProcessing::StageEnablement>;
 
 void fillEngineArchConfig(DynamicsProcessing::EngineArchitecture& cfg,
                           const EngineArchitectureTestParams& params) {
@@ -472,7 +465,7 @@
     cfg.preferredProcessingDurationMs = std::get<ENGINE_TEST_PREFERRED_DURATION>(params);
     cfg.preEqStage = cfg.postEqStage = cfg.mbcStage =
             std::get<ENGINE_TEST_STAGE_ENABLEMENT>(params);
-    cfg.limiterInUse = std::get<ENGINE_TEST_LIMITER_IN_USE>(params);
+    cfg.limiterInUse = true;
 }
 
 class DynamicsProcessingTestEngineArchitecture
@@ -507,8 +500,8 @@
                         static_cast<DynamicsProcessing::ResolutionPreference>(-1)),  // variant
                 testing::Values(-10.f, 0.f, 10.f),  // processing duration
                 testing::ValuesIn(
-                        DynamicsProcessingTestHelper::kStageEnablementTestSet),  // preEQ/postEQ/mbc
-                testing::Bool()),                                                // limiter enable
+                        DynamicsProcessingTestHelper::kStageEnablementTestSet)  // preEQ/postEQ/mbc
+                ),
         [](const auto& info) {
             auto descriptor = std::get<ENGINE_TEST_INSTANCE_NAME>(info.param).second;
             DynamicsProcessing::EngineArchitecture cfg;
@@ -559,7 +552,7 @@
                     ::android::internal::ToString(std::get<INPUT_GAIN_PARAM>(info.param));
             std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
                                descriptor.common.name + "_UUID_" +
-                               descriptor.common.id.uuid.toString() + "_inputGains_" + gains;
+                               toString(descriptor.common.id.uuid) + "_inputGains_" + gains;
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
@@ -574,7 +567,6 @@
     LIMITER_CHANNEL,
     LIMITER_ENABLE,
     LIMITER_LINK_GROUP,
-    LIMITER_ENGINE_IN_USE,
     LIMITER_ADDITIONAL,
 };
 enum LimiterConfigTestAdditionalParam {
@@ -593,9 +585,8 @@
          {1, -60, 2.5, -2, 3.14},
          {1, 60, 2.5, -2, 3.14}}};
 
-using LimiterConfigTestParams =
-        std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int32_t, bool, int32_t, bool,
-                   LimiterConfigTestAdditional>;
+using LimiterConfigTestParams = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>,
+                                           int32_t, bool, int32_t, LimiterConfigTestAdditional>;
 
 void fillLimiterConfig(DynamicsProcessing::LimiterConfig& cfg,
                        const LimiterConfigTestParams& params) {
@@ -615,8 +606,7 @@
       public DynamicsProcessingTestHelper {
   public:
     DynamicsProcessingTestLimiterConfig()
-        : DynamicsProcessingTestHelper(std::get<LIMITER_INSTANCE_NAME>(GetParam())),
-          mLimiterInUseEngine(std::get<LIMITER_ENGINE_IN_USE>(GetParam())) {
+        : DynamicsProcessingTestHelper(std::get<LIMITER_INSTANCE_NAME>(GetParam())) {
         fillLimiterConfig(mCfg, GetParam());
     }
 
@@ -625,11 +615,9 @@
     void TearDown() override { TearDownDynamicsProcessingEffect(); }
 
     DynamicsProcessing::LimiterConfig mCfg;
-    bool mLimiterInUseEngine;
 };
 
 TEST_P(DynamicsProcessingTestLimiterConfig, SetAndGetLimiterConfig) {
-    mEngineConfigPreset.limiterInUse = mLimiterInUseEngine;
     EXPECT_NO_FATAL_FAILURE(addEngineConfig(mEngineConfigPreset));
     EXPECT_NO_FATAL_FAILURE(addLimiterConfig({mCfg}));
     SetAndGetDynamicsProcessingParameters();
@@ -639,21 +627,18 @@
         DynamicsProcessingTest, DynamicsProcessingTestLimiterConfig,
         ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
                                    IFactory::descriptor, getEffectTypeUuidDynamicsProcessing())),
-                           testing::Values(-1, 0, 1, 2),  // channel count
-                           testing::Bool(),               // enable
-                           testing::Values(3),            // link group
-                           testing::Bool(),               // engine limiter enable
+                           testing::Values(-1, 0, 1, 2),                           // channel count
+                           testing::Bool(),                                        // enable
+                           testing::Values(3),                                     // link group
                            testing::ValuesIn(kLimiterConfigTestAdditionalParam)),  // Additional
         [](const auto& info) {
             auto descriptor = std::get<LIMITER_INSTANCE_NAME>(info.param).second;
             DynamicsProcessing::LimiterConfig cfg;
             fillLimiterConfig(cfg, info.param);
-            std::string engineLimiterInUse =
-                    std::to_string(std::get<LIMITER_ENGINE_IN_USE>(info.param));
             std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
                                descriptor.common.name + "_UUID_" +
-                               descriptor.common.id.uuid.toString() + "_limiterConfig_" +
-                               cfg.toString() + "_engineSetting_" + engineLimiterInUse;
+                               toString(descriptor.common.id.uuid) + "_limiterConfig_" +
+                               cfg.toString();
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
@@ -665,11 +650,10 @@
  */
 enum ChannelConfigTestParamName {
     BAND_CHANNEL_TEST_INSTANCE_NAME,
-    BAND_CHANNEL_TEST_CHANNEL_CONFIG,
-    BAND_CHANNEL_TEST_ENGINE_IN_USE
+    BAND_CHANNEL_TEST_CHANNEL_CONFIG
 };
 using ChannelConfigTestParams = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>,
-                                           std::vector<DynamicsProcessing::ChannelConfig>, bool>;
+                                           std::vector<DynamicsProcessing::ChannelConfig>>;
 
 class DynamicsProcessingTestChannelConfig
     : public ::testing::TestWithParam<ChannelConfigTestParams>,
@@ -677,33 +661,28 @@
   public:
     DynamicsProcessingTestChannelConfig()
         : DynamicsProcessingTestHelper(std::get<BAND_CHANNEL_TEST_INSTANCE_NAME>(GetParam())),
-          mCfg(std::get<BAND_CHANNEL_TEST_CHANNEL_CONFIG>(GetParam())),
-          mInUseEngine(std::get<BAND_CHANNEL_TEST_ENGINE_IN_USE>(GetParam())) {}
+          mCfg(std::get<BAND_CHANNEL_TEST_CHANNEL_CONFIG>(GetParam())) {}
 
     void SetUp() override { SetUpDynamicsProcessingEffect(); }
 
     void TearDown() override { TearDownDynamicsProcessingEffect(); }
 
     std::vector<DynamicsProcessing::ChannelConfig> mCfg;
-    const bool mInUseEngine;
 };
 
 TEST_P(DynamicsProcessingTestChannelConfig, SetAndGetPreEqChannelConfig) {
-    mEngineConfigPreset.preEqStage.inUse = mInUseEngine;
     EXPECT_NO_FATAL_FAILURE(addEngineConfig(mEngineConfigPreset));
     EXPECT_NO_FATAL_FAILURE(addPreEqChannelConfig(mCfg));
     SetAndGetDynamicsProcessingParameters();
 }
 
 TEST_P(DynamicsProcessingTestChannelConfig, SetAndGetPostEqChannelConfig) {
-    mEngineConfigPreset.postEqStage.inUse = mInUseEngine;
     EXPECT_NO_FATAL_FAILURE(addEngineConfig(mEngineConfigPreset));
     EXPECT_NO_FATAL_FAILURE(addPostEqChannelConfig(mCfg));
     SetAndGetDynamicsProcessingParameters();
 }
 
 TEST_P(DynamicsProcessingTestChannelConfig, SetAndGetMbcChannelConfig) {
-    mEngineConfigPreset.mbcStage.inUse = mInUseEngine;
     EXPECT_NO_FATAL_FAILURE(addEngineConfig(mEngineConfigPreset));
     EXPECT_NO_FATAL_FAILURE(addMbcChannelConfig(mCfg));
     SetAndGetDynamicsProcessingParameters();
@@ -715,19 +694,15 @@
                 testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
                         IFactory::descriptor, getEffectTypeUuidDynamicsProcessing())),
                 testing::ValuesIn(
-                        DynamicsProcessingTestHelper::kChannelConfigTestSet),  // channel config
-                testing::Bool()),                                              // Engine inUse
+                        DynamicsProcessingTestHelper::kChannelConfigTestSet)),  // channel config
         [](const auto& info) {
             auto descriptor = std::get<BAND_CHANNEL_TEST_INSTANCE_NAME>(info.param).second;
-            std::string engineInUse =
-                    std::to_string(std::get<BAND_CHANNEL_TEST_ENGINE_IN_USE>(info.param));
             std::string channelConfig = ::android::internal::ToString(
                     std::get<BAND_CHANNEL_TEST_CHANNEL_CONFIG>(info.param));
 
             std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
                                descriptor.common.name + "_UUID_" +
-                               descriptor.common.id.uuid.toString() + "_" + channelConfig +
-                               "_engineInUse_" + engineInUse;
+                               toString(descriptor.common.id.uuid) + "_" + channelConfig;
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
@@ -742,11 +717,10 @@
     EQ_BAND_CHANNEL,
     EQ_BAND_ENABLE,
     EQ_BAND_CUT_OFF_FREQ,
-    EQ_BAND_GAIN,
-    EQ_BAND_STAGE_IN_USE
+    EQ_BAND_GAIN
 };
 using EqBandConfigTestParams = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int32_t,
-                                          bool, std::vector<std::pair<int, float>>, float, bool>;
+                                          bool, std::vector<std::pair<int, float>>, float>;
 
 void fillEqBandConfig(std::vector<DynamicsProcessing::EqBandConfig>& cfgs,
                       const EqBandConfigTestParams& params) {
@@ -766,8 +740,7 @@
                                            public DynamicsProcessingTestHelper {
   public:
     DynamicsProcessingTestEqBandConfig()
-        : DynamicsProcessingTestHelper(std::get<EQ_BAND_INSTANCE_NAME>(GetParam())),
-          mStageInUse(std::get<EQ_BAND_STAGE_IN_USE>(GetParam())) {
+        : DynamicsProcessingTestHelper(std::get<EQ_BAND_INSTANCE_NAME>(GetParam())) {
         fillEqBandConfig(mCfgs, GetParam());
     }
 
@@ -776,11 +749,9 @@
     void TearDown() override { TearDownDynamicsProcessingEffect(); }
 
     std::vector<DynamicsProcessing::EqBandConfig> mCfgs;
-    const bool mStageInUse;
 };
 
 TEST_P(DynamicsProcessingTestEqBandConfig, SetAndGetPreEqBandConfig) {
-    mEngineConfigPreset.preEqStage.inUse = mStageInUse;
     mEngineConfigPreset.preEqStage.bandCount = mCfgs.size();
     EXPECT_NO_FATAL_FAILURE(addEngineConfig(mEngineConfigPreset));
     std::vector<DynamicsProcessing::ChannelConfig> cfgs(mChannelCount);
@@ -794,7 +765,6 @@
 }
 
 TEST_P(DynamicsProcessingTestEqBandConfig, SetAndGetPostEqBandConfig) {
-    mEngineConfigPreset.postEqStage.inUse = mStageInUse;
     mEngineConfigPreset.postEqStage.bandCount = mCfgs.size();
     EXPECT_NO_FATAL_FAILURE(addEngineConfig(mEngineConfigPreset));
     std::vector<DynamicsProcessing::ChannelConfig> cfgs(mChannelCount);
@@ -855,21 +825,19 @@
         DynamicsProcessingTest, DynamicsProcessingTestEqBandConfig,
         ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
                                    IFactory::descriptor, getEffectTypeUuidDynamicsProcessing())),
-                           testing::Values(-1, 0, 10),      // channel ID
-                           testing::Bool(),                 // band enable
-                           testing::ValuesIn(kBands),       // cut off frequencies
-                           testing::Values(-3.14f, 3.14f),  // gain
-                           testing::Values(true)),          // stage in use
+                           testing::Values(-1, 0, 10),     // channel ID
+                           testing::Bool(),                // band enable
+                           testing::ValuesIn(kBands),      // cut off frequencies
+                           testing::Values(-3.14f, 3.14f)  // gain
+                           ),
         [](const auto& info) {
             auto descriptor = std::get<EQ_BAND_INSTANCE_NAME>(info.param).second;
             std::vector<DynamicsProcessing::EqBandConfig> cfgs;
             fillEqBandConfig(cfgs, info.param);
             std::string bands = ::android::internal::ToString(cfgs);
-            std::string stageInUse = std::to_string(std::get<EQ_BAND_STAGE_IN_USE>(info.param));
             std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
                                descriptor.common.name + "_UUID_" +
-                               descriptor.common.id.uuid.toString() + "_bands_" + bands +
-                               "_stageInUse_" + stageInUse;
+                               toString(descriptor.common.id.uuid) + "_bands_" + bands;
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
@@ -885,7 +853,6 @@
     MBC_BAND_CHANNEL,
     MBC_BAND_ENABLE,
     MBC_BAND_CUTOFF_FREQ,
-    MBC_BAND_STAGE_IN_USE,
     MBC_BAND_ADDITIONAL
 };
 enum MbcBandConfigAdditional {
@@ -911,7 +878,7 @@
 
 using TestParamsMbcBandConfig =
         std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int32_t, bool,
-                   std::vector<std::pair<int, float>>, bool, TestParamsMbcBandConfigAdditional>;
+                   std::vector<std::pair<int, float>>, TestParamsMbcBandConfigAdditional>;
 
 void fillMbcBandConfig(std::vector<DynamicsProcessing::MbcBandConfig>& cfgs,
                        const TestParamsMbcBandConfig& params) {
@@ -942,8 +909,7 @@
       public DynamicsProcessingTestHelper {
   public:
     DynamicsProcessingTestMbcBandConfig()
-        : DynamicsProcessingTestHelper(std::get<MBC_BAND_INSTANCE_NAME>(GetParam())),
-          mStageInUse(std::get<MBC_BAND_STAGE_IN_USE>(GetParam())) {
+        : DynamicsProcessingTestHelper(std::get<MBC_BAND_INSTANCE_NAME>(GetParam())) {
         fillMbcBandConfig(mCfgs, GetParam());
     }
 
@@ -952,11 +918,9 @@
     void TearDown() override { TearDownDynamicsProcessingEffect(); }
 
     std::vector<DynamicsProcessing::MbcBandConfig> mCfgs;
-    const bool mStageInUse;
 };
 
 TEST_P(DynamicsProcessingTestMbcBandConfig, SetAndGetMbcBandConfig) {
-    mEngineConfigPreset.mbcStage.inUse = mStageInUse;
     mEngineConfigPreset.mbcStage.bandCount = mCfgs.size();
     EXPECT_NO_FATAL_FAILURE(addEngineConfig(mEngineConfigPreset));
     std::vector<DynamicsProcessing::ChannelConfig> cfgs(mChannelCount);
@@ -976,18 +940,15 @@
                            testing::Values(-1, 0, 10),  // channel count
                            testing::Bool(),             // enable
                            testing::ValuesIn(kBands),   // cut off frequencies
-                           testing::Bool(),             // stage in use
                            testing::ValuesIn(kMbcBandConfigAdditionalParam)),  // Additional
         [](const auto& info) {
             auto descriptor = std::get<MBC_BAND_INSTANCE_NAME>(info.param).second;
             std::vector<DynamicsProcessing::MbcBandConfig> cfgs;
             fillMbcBandConfig(cfgs, info.param);
             std::string mbcBands = ::android::internal::ToString(cfgs);
-            std::string stageInUse = std::to_string(std::get<MBC_BAND_STAGE_IN_USE>(info.param));
             std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
                                descriptor.common.name + "_UUID_" +
-                               descriptor.common.id.uuid.toString() + "_bands_" + mbcBands +
-                               "_stageInUse_" + stageInUse;
+                               toString(descriptor.common.id.uuid) + "_bands_" + mbcBands;
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
diff --git a/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp b/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp
index 765c377..f641fa5 100644
--- a/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp
@@ -249,7 +249,7 @@
 
             std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
                                descriptor.common.name + "_UUID_" +
-                               descriptor.common.id.uuid.toString() + "_roomHfLevel" + roomHfLevel;
+                               toString(descriptor.common.id.uuid) + "_roomHfLevel" + roomHfLevel;
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
@@ -289,7 +289,7 @@
 
             std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
                                descriptor.common.name + "_UUID_" +
-                               descriptor.common.id.uuid.toString() + "_decayTime" + decayTime;
+                               toString(descriptor.common.id.uuid) + "_decayTime" + decayTime;
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
@@ -329,8 +329,7 @@
 
             std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
                                descriptor.common.name + "_UUID_" +
-                               descriptor.common.id.uuid.toString() + "_decayHfRatio" +
-                               decayHfRatio;
+                               toString(descriptor.common.id.uuid) + "_decayHfRatio" + decayHfRatio;
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
@@ -370,7 +369,7 @@
 
             std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
                                descriptor.common.name + "_UUID_" +
-                               descriptor.common.id.uuid.toString() + "_level" + level;
+                               toString(descriptor.common.id.uuid) + "_level" + level;
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
@@ -410,7 +409,7 @@
 
             std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
                                descriptor.common.name + "_UUID_" +
-                               descriptor.common.id.uuid.toString() + "_delay" + delay;
+                               toString(descriptor.common.id.uuid) + "_delay" + delay;
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
@@ -450,7 +449,7 @@
 
             std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
                                descriptor.common.name + "_UUID_" +
-                               descriptor.common.id.uuid.toString() + "_diffusion" + diffusion;
+                               toString(descriptor.common.id.uuid) + "_diffusion" + diffusion;
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
@@ -490,7 +489,7 @@
 
             std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
                                descriptor.common.name + "_UUID_" +
-                               descriptor.common.id.uuid.toString() + "_density" + density;
+                               toString(descriptor.common.id.uuid) + "_density" + density;
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
@@ -527,7 +526,7 @@
 
             std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
                                descriptor.common.name + "_UUID_" +
-                               descriptor.common.id.uuid.toString() + "_bypass" + bypass;
+                               toString(descriptor.common.id.uuid) + "_bypass" + bypass;
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
diff --git a/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp b/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp
index d312111..48e59dc 100644
--- a/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp
@@ -225,7 +225,7 @@
                     std::to_string(std::get<PARAM_VIBRATION_INFORMATION_MAX_AMPLITUDE>(info.param));
             std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
                                descriptor.common.name + "_UUID_" +
-                               descriptor.common.id.uuid.toString() + "_hapticScaleId" +
+                               toString(descriptor.common.id.uuid) + "_hapticScaleId" +
                                hapticScaleID + "_hapticScaleVibScale" + hapticScaleVibScale +
                                "_resonantFrequency" + resonantFrequency + "_qFactor" + qFactor +
                                "_maxAmplitude" + maxAmplitude;
@@ -422,7 +422,7 @@
             auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
             std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
                                descriptor.common.name + "_UUID_" +
-                               descriptor.common.id.uuid.toString();
+                               toString(descriptor.common.id.uuid);
             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 a075423..7a53502 100644
--- a/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
@@ -53,6 +53,7 @@
                 kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
         ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &mOpenEffectReturn, EX_NONE));
         ASSERT_NE(nullptr, mEffect);
+        mVersion = EffectFactoryHelper::getHalVersion(mFactory);
     }
 
     void TearDownLoudnessEnhancer() {
@@ -114,6 +115,7 @@
     std::shared_ptr<IFactory> mFactory;
     std::shared_ptr<IEffect> mEffect;
     Descriptor mDescriptor;
+    int mVersion = 0;
 };
 
 /**
@@ -190,7 +192,8 @@
         ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
 
         // Write from buffer to message queues and calling process
-        EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(mStatusMQ, mInputMQ, mInputBuffer));
+        EXPECT_NO_FATAL_FAILURE(
+                EffectHelper::writeToFmq(mStatusMQ, mInputMQ, mInputBuffer, mVersion));
 
         // Read the updated message queues into buffer
         EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(mStatusMQ, 1, mOutputMQ,
diff --git a/audio/aidl/vts/VtsHalVolumeTargetTest.cpp b/audio/aidl/vts/VtsHalVolumeTargetTest.cpp
index 1c1489d..4597b39 100644
--- a/audio/aidl/vts/VtsHalVolumeTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalVolumeTargetTest.cpp
@@ -140,7 +140,9 @@
 class VolumeDataTest : public ::testing::TestWithParam<VolumeDataTestParam>,
                        public VolumeControlHelper {
   public:
-    VolumeDataTest() {
+    VolumeDataTest()
+        : kVsrApiLevel(
+                  android::base::GetIntProperty("ro.vendor.api_level", __ANDROID_API_FUTURE__)) {
         std::tie(mFactory, mDescriptor) = GetParam();
         mInput.resize(kBufferSize);
         mInputMag.resize(mTestFrequencies.size());
@@ -165,13 +167,17 @@
 
     void SetUp() override {
         SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
+        // Skips test fixture if api_level <= 34 (__ANDROID_API_U__).
+        if (kVsrApiLevel <= __ANDROID_API_U__) GTEST_SKIP();
         ASSERT_NO_FATAL_FAILURE(SetUpVolumeControl());
     }
     void TearDown() override {
         SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
+        if (kVsrApiLevel <= __ANDROID_API_U__) GTEST_SKIP();
         TearDownVolumeControl();
     }
 
+    const int kVsrApiLevel;
     static constexpr int kMaxAudioSample = 1;
     static constexpr int kTransitionDuration = 300;
     static constexpr int kNPointFFT = 32768;
diff --git a/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp b/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp
index 9451087..82dda61 100644
--- a/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp
+++ b/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp
@@ -43,6 +43,8 @@
 
 #define HCI_MINIMUM_HCI_VERSION 5  // Bluetooth Core Specification 3.0 + HS
 #define HCI_MINIMUM_LMP_VERSION 5  // Bluetooth Core Specification 3.0 + HS
+#define HCI_BLUETOOTH4_2_HCI_VERSION 8 // Bluetooth 4.2
+#define HCI_BLUETOOTH4_2_LMP_VERSION 8 // Bluetooth 4.2
 #define NUM_HCI_COMMANDS_BANDWIDTH 1000
 #define NUM_SCO_PACKETS_BANDWIDTH 1000
 #define NUM_ACL_PACKETS_BANDWIDTH 1000
@@ -52,6 +54,7 @@
 #define WAIT_FOR_ACL_DATA_TIMEOUT std::chrono::milliseconds(1000)
 #define INTERFACE_CLOSE_DELAY_MS std::chrono::milliseconds(600)
 
+// { OCF, OGF << 2, Length of command parameters}
 #define COMMAND_HCI_SHOULD_BE_UNKNOWN \
   { 0xff, 0x3B, 0x08, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }
 #define COMMAND_HCI_READ_LOCAL_VERSION_INFORMATION \
@@ -64,6 +67,10 @@
   { 0x03, 0x0c, 0x00 }
 #define COMMAND_HCI_WRITE_LOCAL_NAME \
   { 0x13, 0x0c, 0xf8 }
+#define COMMAND_HCI_READ_LOCAL_SUPPORTED_FEATURES \
+  { 0x03, 0x04 << 2, 0x00 } // OGF=0x04, OCF=0x0003 / 7.4 INFORMATIONAL PARAMETERS
+#define COMMAND_HCI_LE_READ_LOCAL_SUPPORTED_FEATURES \
+  { 0x03, 0x08 << 2, 0x00 } // OGF=0x08, OCF=0x0003 / 7.8 LE CONTROLLER COMMANDS
 #define HCI_STATUS_SUCCESS 0x00
 #define HCI_STATUS_UNKNOWN_HCI_COMMAND 0x01
 
@@ -85,6 +92,30 @@
 #define EVENT_COMMAND_COMPLETE_FIRST_PARAM_BYTE 6
 #define EVENT_LOCAL_HCI_VERSION_BYTE EVENT_COMMAND_COMPLETE_FIRST_PARAM_BYTE
 #define EVENT_LOCAL_LMP_VERSION_BYTE EVENT_LOCAL_HCI_VERSION_BYTE + 3
+/**
+ * See Bluetooth Spec 5.4, Vol 2, Part C
+ * Link Manager Protocol, 3.3 Feature Mask Definition
+ *
+ * No  | Supported Feature           | Byte | Bit | Page
+ * ...
+ * 38  | LE Supported (Controller)   | 4    | 6   | 0
+ * ...
+ */
+#define EVENT_LOCAL_SUPPORTED_FEATURES_LE_SUPPORTED_BYTE \
+  (EVENT_COMMAND_COMPLETE_FIRST_PARAM_BYTE + 0x04)
+#define EVENT_LOCAL_SUPPORTED_FEATURES_LE_SUPPORTED_BITMASK (0x01 << 6)
+/**
+ * See Bluetooth Spec 5.4, Vol 6, Part B
+ * 4.6 Feature Support
+ *
+ * Bit | Link Layer Feature
+ * ...
+ * 5   | LE Data Packet Length Extension
+ * ...
+ */
+#define EVENT_LOCAL_LE_SUPPORTED_FEATURES_DATA_LENGTH_EXTENSION_BYTE \
+  (EVENT_COMMAND_COMPLETE_FIRST_PARAM_BYTE + 0x00)
+#define EVENT_LOCAL_LE_SUPPORTED_FEATURES_DATA_LENGTH_BITMASK (0x01 << 5)
 
 #define EVENT_CONNECTION_COMPLETE_PARAM_LENGTH 11
 #define EVENT_CONNECTION_COMPLETE_TYPE 11
@@ -209,7 +240,7 @@
                          std::vector<uint16_t>& acl_handles);
   void handle_no_ops();
   void wait_for_event(bool timeout_is_error);
-  void wait_for_command_complete_event(hidl_vec<uint8_t> cmd);
+  hidl_vec<uint8_t> wait_for_command_complete_event(hidl_vec<uint8_t> cmd);
   int wait_for_completed_packets_event(uint16_t handle);
 
   class BluetoothHciDeathRecipient : public hidl_death_recipient {
@@ -338,17 +369,19 @@
 }
 
 // Wait until a COMMAND_COMPLETE is received.
-void BluetoothHidlTest::wait_for_command_complete_event(hidl_vec<uint8_t> cmd) {
+hidl_vec<uint8_t> BluetoothHidlTest::wait_for_command_complete_event(hidl_vec<uint8_t> cmd) {
   wait_for_event();
   hidl_vec<uint8_t> event = event_queue.front();
   event_queue.pop();
 
-  ASSERT_GT(event.size(),
+  EXPECT_GT(event.size(),
             static_cast<size_t>(EVENT_COMMAND_COMPLETE_STATUS_BYTE));
-  ASSERT_EQ(EVENT_COMMAND_COMPLETE, event[EVENT_CODE_BYTE]);
-  ASSERT_EQ(cmd[0], event[EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE]);
-  ASSERT_EQ(cmd[1], event[EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE + 1]);
-  ASSERT_EQ(HCI_STATUS_SUCCESS, event[EVENT_COMMAND_COMPLETE_STATUS_BYTE]);
+  EXPECT_EQ(EVENT_COMMAND_COMPLETE, event[EVENT_CODE_BYTE]);
+  EXPECT_EQ(cmd[0], event[EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE]);
+  EXPECT_EQ(cmd[1], event[EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE + 1]);
+  EXPECT_EQ(HCI_STATUS_SUCCESS, event[EVENT_COMMAND_COMPLETE_STATUS_BYTE]);
+
+  return event;
 }
 
 // Send the command to read the controller's buffer sizes.
@@ -623,6 +656,36 @@
   ASSERT_LE(HCI_MINIMUM_LMP_VERSION, event[EVENT_LOCAL_LMP_VERSION_BYTE]);
 }
 
+/**
+ * VSR-5.3.14-007 MUST support Bluetooth 4.2 and Bluetooth LE Data Length Extension.
+ * VSR-5.3.14-008 MUST support Bluetooth Low Energy (BLE).
+ */
+// @VsrTest = 5.3.14-007
+// @VsrTest = 5.3.14-008
+TEST_P(BluetoothHidlTest, Bluetooth4_2) {
+  // Bluetooth 4.2+
+  hidl_vec<uint8_t> cmd = COMMAND_HCI_READ_LOCAL_VERSION_INFORMATION;
+  bluetooth->sendHciCommand(cmd);
+  auto event = wait_for_command_complete_event(cmd);
+
+  EXPECT_LE(HCI_BLUETOOTH4_2_HCI_VERSION, event[EVENT_LOCAL_HCI_VERSION_BYTE]);
+  EXPECT_LE(HCI_BLUETOOTH4_2_LMP_VERSION, event[EVENT_LOCAL_LMP_VERSION_BYTE]);
+
+  // BLE
+  cmd = COMMAND_HCI_READ_LOCAL_SUPPORTED_FEATURES;
+  bluetooth->sendHciCommand(cmd);
+  event = wait_for_command_complete_event(cmd);
+  EXPECT_TRUE(event[EVENT_LOCAL_SUPPORTED_FEATURES_LE_SUPPORTED_BYTE] &
+    EVENT_LOCAL_SUPPORTED_FEATURES_LE_SUPPORTED_BITMASK);
+
+  // BLE Data Length Extension
+  cmd = COMMAND_HCI_LE_READ_LOCAL_SUPPORTED_FEATURES;
+  bluetooth->sendHciCommand(cmd);
+  event = wait_for_command_complete_event(cmd);
+  EXPECT_TRUE(event[EVENT_LOCAL_LE_SUPPORTED_FEATURES_DATA_LENGTH_EXTENSION_BYTE] &
+    EVENT_LOCAL_LE_SUPPORTED_FEATURES_DATA_LENGTH_BITMASK);
+}
+
 // Send an unknown HCI command and wait for the error message.
 TEST_P(BluetoothHidlTest, HciUnknownCommand) {
   hidl_vec<uint8_t> cmd = COMMAND_HCI_SHOULD_BE_UNKNOWN;
diff --git a/bluetooth/1.1/vts/functional/VtsHalBluetoothV1_1TargetTest.cpp b/bluetooth/1.1/vts/functional/VtsHalBluetoothV1_1TargetTest.cpp
index 28ac603..687765f 100644
--- a/bluetooth/1.1/vts/functional/VtsHalBluetoothV1_1TargetTest.cpp
+++ b/bluetooth/1.1/vts/functional/VtsHalBluetoothV1_1TargetTest.cpp
@@ -43,6 +43,8 @@
 
 #define HCI_MINIMUM_HCI_VERSION 5  // Bluetooth Core Specification 3.0 + HS
 #define HCI_MINIMUM_LMP_VERSION 5  // Bluetooth Core Specification 3.0 + HS
+#define HCI_BLUETOOTH4_2_HCI_VERSION 8 // Bluetooth 4.2
+#define HCI_BLUETOOTH4_2_LMP_VERSION 8 // Bluetooth 4.2
 #define NUM_HCI_COMMANDS_BANDWIDTH 1000
 #define NUM_SCO_PACKETS_BANDWIDTH 1000
 #define NUM_ACL_PACKETS_BANDWIDTH 1000
@@ -52,6 +54,7 @@
 #define WAIT_FOR_ACL_DATA_TIMEOUT std::chrono::milliseconds(1000)
 #define INTERFACE_CLOSE_DELAY_MS std::chrono::milliseconds(200)
 
+// { OCF, OGF << 2, Length of bytes of command parameters }
 #define COMMAND_HCI_SHOULD_BE_UNKNOWN \
   { 0xff, 0x3B, 0x08, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }
 #define COMMAND_HCI_READ_LOCAL_VERSION_INFORMATION \
@@ -64,6 +67,10 @@
   { 0x03, 0x0c, 0x00 }
 #define COMMAND_HCI_WRITE_LOCAL_NAME \
   { 0x13, 0x0c, 0xf8 }
+#define COMMAND_HCI_READ_LOCAL_SUPPORTED_FEATURES \
+  { 0x03, 0x04 << 2, 0x00 } // OGF=0x04, OCF=0x0003 / 7.4 INFORMATIONAL PARAMETERS
+#define COMMAND_HCI_LE_READ_LOCAL_SUPPORTED_FEATURES \
+  { 0x03, 0x08 << 2, 0x00 } // OGF=0x08, OCF=0x0003 / 7.8 LE CONTROLLER COMMANDS
 #define HCI_STATUS_SUCCESS 0x00
 #define HCI_STATUS_UNKNOWN_HCI_COMMAND 0x01
 
@@ -85,6 +92,30 @@
 #define EVENT_COMMAND_COMPLETE_FIRST_PARAM_BYTE 6
 #define EVENT_LOCAL_HCI_VERSION_BYTE EVENT_COMMAND_COMPLETE_FIRST_PARAM_BYTE
 #define EVENT_LOCAL_LMP_VERSION_BYTE EVENT_LOCAL_HCI_VERSION_BYTE + 3
+/**
+ * See Bluetooth Spec 5.4, Vol 2, Part C
+ * Link Manager Protocol, 3.3 Feature Mask Definition
+ *
+ * No  | Supported Feature           | Byte | Bit | Page
+ * ...
+ * 38  | LE Supported (Controller)   | 4    | 6   | 0
+ * ...
+ */
+#define EVENT_LOCAL_SUPPORTED_FEATURES_LE_SUPPORTED_BYTE \
+  (EVENT_COMMAND_COMPLETE_FIRST_PARAM_BYTE + 0x04)
+#define EVENT_LOCAL_SUPPORTED_FEATURES_LE_SUPPORTED_BITMASK (0x01 << 6)
+/**
+ * See Bluetooth Spec 5.4, Vol 6, Part B
+ * 4.6 Feature Support
+ *
+ * Bit | Link Layer Feature
+ * ...
+ * 5   | LE Data Packet Length Extension
+ * ...
+ */
+#define EVENT_LOCAL_LE_SUPPORTED_FEATURES_DATA_LENGTH_EXTENSION_BYTE \
+  (EVENT_COMMAND_COMPLETE_FIRST_PARAM_BYTE + 0x00)
+#define EVENT_LOCAL_LE_SUPPORTED_FEATURES_DATA_LENGTH_BITMASK (0x01 << 5)
 
 #define EVENT_CONNECTION_COMPLETE_PARAM_LENGTH 11
 #define EVENT_CONNECTION_COMPLETE_TYPE 11
@@ -211,7 +242,7 @@
                          std::vector<uint16_t>* acl_handles);
   void handle_no_ops();
   void wait_for_event(bool timeout_is_error);
-  void wait_for_command_complete_event(hidl_vec<uint8_t> cmd);
+  hidl_vec<uint8_t> wait_for_command_complete_event(hidl_vec<uint8_t> cmd);
   int wait_for_completed_packets_event(uint16_t handle);
 
   class BluetoothHciDeathRecipient : public hidl_death_recipient {
@@ -350,7 +381,7 @@
 }
 
 // Wait until a COMMAND_COMPLETE is received.
-void BluetoothHidlTest::wait_for_command_complete_event(hidl_vec<uint8_t> cmd) {
+hidl_vec<uint8_t> BluetoothHidlTest::wait_for_command_complete_event(hidl_vec<uint8_t> cmd) {
   wait_for_event();
   hidl_vec<uint8_t> event = event_queue.front();
   event_queue.pop();
@@ -361,6 +392,8 @@
   EXPECT_EQ(cmd[0], event[EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE]);
   EXPECT_EQ(cmd[1], event[EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE + 1]);
   EXPECT_EQ(HCI_STATUS_SUCCESS, event[EVENT_COMMAND_COMPLETE_STATUS_BYTE]);
+
+  return event;
 }
 
 // Send the command to read the controller's buffer sizes.
@@ -646,6 +679,36 @@
   EXPECT_LE(HCI_MINIMUM_LMP_VERSION, event[EVENT_LOCAL_LMP_VERSION_BYTE]);
 }
 
+/**
+ * VSR-5.3.14-007 MUST support Bluetooth 4.2 and Bluetooth LE Data Length Extension.
+ * VSR-5.3.14-008 MUST support Bluetooth Low Energy (BLE).
+ */
+// @VsrTest = 5.3.14-007
+// @VsrTest = 5.3.14-008
+TEST_P(BluetoothHidlTest, Bluetooth4_2) {
+  // Bluetooth 4.2+
+  hidl_vec<uint8_t> cmd = COMMAND_HCI_READ_LOCAL_VERSION_INFORMATION;
+  bluetooth->sendHciCommand(cmd);
+  auto event = wait_for_command_complete_event(cmd);
+
+  EXPECT_LE(HCI_BLUETOOTH4_2_HCI_VERSION, event[EVENT_LOCAL_HCI_VERSION_BYTE]);
+  EXPECT_LE(HCI_BLUETOOTH4_2_LMP_VERSION, event[EVENT_LOCAL_LMP_VERSION_BYTE]);
+
+  // BLE
+  cmd = COMMAND_HCI_READ_LOCAL_SUPPORTED_FEATURES;
+  bluetooth->sendHciCommand(cmd);
+  event = wait_for_command_complete_event(cmd);
+  EXPECT_TRUE(event[EVENT_LOCAL_SUPPORTED_FEATURES_LE_SUPPORTED_BYTE] &
+    EVENT_LOCAL_SUPPORTED_FEATURES_LE_SUPPORTED_BITMASK);
+
+  // BLE Data Length Extension
+  cmd = COMMAND_HCI_LE_READ_LOCAL_SUPPORTED_FEATURES;
+  bluetooth->sendHciCommand(cmd);
+  event = wait_for_command_complete_event(cmd);
+  EXPECT_TRUE(event[EVENT_LOCAL_LE_SUPPORTED_FEATURES_DATA_LENGTH_EXTENSION_BYTE] &
+    EVENT_LOCAL_LE_SUPPORTED_FEATURES_DATA_LENGTH_BITMASK);
+}
+
 // Send an unknown HCI command and wait for the error message.
 TEST_P(BluetoothHidlTest, HciUnknownCommand) {
   hidl_vec<uint8_t> cmd = COMMAND_HCI_SHOULD_BE_UNKNOWN;
diff --git a/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp b/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp
index 24eb4d0..87f0f11 100644
--- a/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp
+++ b/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp
@@ -118,6 +118,10 @@
          testing::deviceSupportsFeature("android.hardware.type.television");
 }
 
+static bool isHandheld() {
+  return testing::deviceSupportsFeature("android.hardware.type.handheld");
+}
+
 class ThroughputLogger {
  public:
   explicit ThroughputLogger(std::string task)
@@ -1039,6 +1043,47 @@
   ASSERT_GE(num_resolving_list, kMinLeResolvingListForBt5);
 }
 
+/**
+ * VSR-5.3.14-007 MUST support Bluetooth 4.2 and Bluetooth LE Data Length Extension.
+ * VSR-5.3.14-008 MUST support Bluetooth Low Energy (BLE).
+ */
+// @VsrTest = 5.3.14-007
+// @VsrTest = 5.3.14-008
+TEST_P(BluetoothAidlTest, Vsr_Bluetooth4_2Requirements) {
+  // test only applies to handheld devices
+  if (!isHandheld()) {
+    return;
+  }
+
+  std::vector<uint8_t> version_event;
+  send_and_wait_for_cmd_complete(ReadLocalVersionInformationBuilder::Create(),
+                                 version_event);
+  auto version_view = ReadLocalVersionInformationCompleteView::Create(
+      CommandCompleteView::Create(EventView::Create(PacketView<true>(
+          std::make_shared<std::vector<uint8_t>>(version_event)))));
+  ASSERT_TRUE(version_view.IsValid());
+  ASSERT_EQ(::bluetooth::hci::ErrorCode::SUCCESS, version_view.GetStatus());
+  auto version = version_view.GetLocalVersionInformation();
+  // Starting with Android 15, Fails when HCI version is lower than 4.2.
+  ASSERT_GE(static_cast<int>(version.hci_version_),
+    static_cast<int>(::bluetooth::hci::HciVersion::V_4_2));
+  ASSERT_GE(static_cast<int>(version.lmp_version_),
+    static_cast<int>(::bluetooth::hci::LmpVersion::V_4_2));
+
+  std::vector<uint8_t> le_features_event;
+  send_and_wait_for_cmd_complete(LeReadLocalSupportedFeaturesBuilder::Create(),
+                                 le_features_event);
+  auto le_features_view = LeReadLocalSupportedFeaturesCompleteView::Create(
+      CommandCompleteView::Create(EventView::Create(PacketView<true>(
+          std::make_shared<std::vector<uint8_t>>(le_features_event)))));
+  ASSERT_TRUE(le_features_view.IsValid());
+  ASSERT_EQ(::bluetooth::hci::ErrorCode::SUCCESS, le_features_view.GetStatus());
+  auto le_features = le_features_view.GetLeFeatures();
+  ASSERT_TRUE(le_features &
+              static_cast<uint64_t>(LLFeaturesBits::LE_EXTENDED_ADVERTISING));
+
+}
+
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BluetoothAidlTest);
 INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAidlTest,
                          testing::ValuesIn(android::getAidlHalInstanceNames(