Merge "Secretkeeper: more VTS tests" into main
diff --git a/audio/aidl/default/EffectConfig.cpp b/audio/aidl/default/EffectConfig.cpp
index a1fbefa..eb0c015 100644
--- a/audio/aidl/default/EffectConfig.cpp
+++ b/audio/aidl/default/EffectConfig.cpp
@@ -37,7 +37,6 @@
 EffectConfig::EffectConfig(const std::string& file) {
     tinyxml2::XMLDocument doc;
     doc.LoadFile(file.c_str());
-    LOG(DEBUG) << __func__ << " loading " << file;
     // parse the xml file into maps
     if (doc.Error()) {
         LOG(ERROR) << __func__ << " tinyxml2 failed to load " << file
@@ -143,7 +142,7 @@
     std::string name = xml.Attribute("name");
     RETURN_VALUE_IF(name == "", false, "effectsNoName");
 
-    LOG(DEBUG) << __func__ << dump(xml);
+    LOG(VERBOSE) << __func__ << dump(xml);
     struct Library library;
     if (std::strcmp(xml.Name(), "effectProxy") == 0) {
         // proxy lib and uuid
@@ -187,11 +186,11 @@
     }
     RETURN_VALUE_IF((library.uuid == getEffectUuidZero()), false, "invalidUuidAttribute");
 
-    LOG(DEBUG) << __func__ << (isProxy ? " proxy " : library.name) << " : uuid "
-               << ::android::audio::utils::toString(library.uuid)
-               << (library.type.has_value()
-                           ? ::android::audio::utils::toString(library.type.value())
-                           : "");
+    LOG(VERBOSE) << __func__ << (isProxy ? " proxy " : library.name) << " : uuid "
+                 << ::android::audio::utils::toString(library.uuid)
+                 << (library.type.has_value()
+                             ? ::android::audio::utils::toString(library.type.value())
+                             : "");
     return true;
 }
 
@@ -245,7 +244,7 @@
 }
 
 bool EffectConfig::parseProcessing(Processing::Type::Tag typeTag, const tinyxml2::XMLElement& xml) {
-    LOG(DEBUG) << __func__ << dump(xml);
+    LOG(VERBOSE) << __func__ << dump(xml);
     const char* typeStr = xml.Attribute("type");
     auto aidlType = stringToProcessingType(typeTag, typeStr);
     RETURN_VALUE_IF(!aidlType.has_value(), false, "illegalStreamType");
@@ -259,7 +258,6 @@
         }
         RETURN_VALUE_IF(!name, false, "noEffectAttribute");
         mProcessingMap[aidlType.value()].emplace_back(mEffectsMap[name]);
-        LOG(WARNING) << __func__ << " " << typeStr << " : " << name;
     }
     return true;
 }
diff --git a/audio/aidl/default/EffectContext.cpp b/audio/aidl/default/EffectContext.cpp
index 9575790..7b8cfb1 100644
--- a/audio/aidl/default/EffectContext.cpp
+++ b/audio/aidl/default/EffectContext.cpp
@@ -157,7 +157,6 @@
 }
 
 RetCode EffectContext::setCommon(const Parameter::Common& common) {
-    LOG(VERBOSE) << __func__ << common.toString();
     auto& input = common.input;
     auto& output = common.output;
 
@@ -186,7 +185,6 @@
 }
 
 Parameter::Common EffectContext::getCommon() {
-    LOG(VERBOSE) << __func__ << mCommon.toString();
     return mCommon;
 }
 
@@ -241,7 +239,7 @@
         LOG(ERROR) << __func__ << ": wake failure with ret " << ret;
         return RetCode::ERROR_EVENT_FLAG_ERROR;
     }
-    LOG(DEBUG) << __func__ << " : signal client for reopen";
+    LOG(VERBOSE) << __func__ << " : signal client for reopen";
     return RetCode::SUCCESS;
 }
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/EffectFactory.cpp b/audio/aidl/default/EffectFactory.cpp
index 96f13ba..ba5b141 100644
--- a/audio/aidl/default/EffectFactory.cpp
+++ b/audio/aidl/default/EffectFactory.cpp
@@ -43,12 +43,12 @@
 
 Factory::~Factory() {
     if (auto count = mEffectMap.size()) {
-        LOG(ERROR) << __func__ << " remaining " << count
-                   << " effect instances not destroyed indicating resource leak!";
+        LOG(WARNING) << __func__ << " remaining " << count
+                     << " effect instances not destroyed indicating resource leak!";
         for (const auto& it : mEffectMap) {
             if (auto spEffect = it.first.lock()) {
-                LOG(ERROR) << __func__ << " erase remaining instance UUID "
-                           << ::android::audio::utils::toString(it.second.first);
+                LOG(WARNING) << __func__ << " erase remaining instance UUID "
+                             << ::android::audio::utils::toString(it.second.first);
                 destroyEffectImpl_l(spEffect);
             }
         }
@@ -139,7 +139,7 @@
         std::shared_ptr<IEffect> effectSp;
         RETURN_IF_BINDER_EXCEPTION(libInterface->createEffectFunc(&in_impl_uuid, &effectSp));
         if (!effectSp) {
-            LOG(ERROR) << __func__ << ": library created null instance without return error!";
+            LOG(WARNING) << __func__ << ": library created null instance without return error!";
             return ndk::ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED);
         }
         *_aidl_return = effectSp;
@@ -147,7 +147,6 @@
         AIBinder_setMinSchedulerPolicy(effectBinder.get(), SCHED_NORMAL, ANDROID_PRIORITY_AUDIO);
         mEffectMap[std::weak_ptr<IEffect>(effectSp)] =
                 std::make_pair(in_impl_uuid, std::move(effectBinder));
-        LOG(DEBUG) << __func__ << ": instance " << effectSp.get() << " created successfully";
         return ndk::ScopedAStatus::ok();
     } else {
         LOG(ERROR) << __func__ << ": library doesn't exist";
@@ -192,7 +191,6 @@
 }
 
 ndk::ScopedAStatus Factory::destroyEffect(const std::shared_ptr<IEffect>& in_handle) {
-    LOG(DEBUG) << __func__ << ": instance " << in_handle.get();
     std::lock_guard lg(mMutex);
     ndk::ScopedAStatus status = destroyEffectImpl_l(in_handle);
     // always do the cleanup
@@ -215,8 +213,8 @@
         return false;
     }
 
-    LOG(INFO) << __func__ << " dlopen lib:" << path
-              << "\nimpl:" << ::android::audio::utils::toString(impl) << "\nhandle:" << libHandle;
+    LOG(DEBUG) << __func__ << " dlopen lib: " << path
+               << "\nimpl:" << ::android::audio::utils::toString(impl) << "\nhandle:" << libHandle;
     auto interface = new effect_dl_interface_s{nullptr, nullptr, nullptr};
     mEffectLibMap.insert(
             {impl,
@@ -235,11 +233,12 @@
         id.type = typeUuid;
         id.uuid = configLib.uuid;
         id.proxy = proxyUuid;
-        LOG(DEBUG) << __func__ << " loading lib " << path->second << ": typeUuid "
-                   << ::android::audio::utils::toString(id.type) << "\nimplUuid "
-                   << ::android::audio::utils::toString(id.uuid) << " proxyUuid "
-                   << (proxyUuid.has_value() ? ::android::audio::utils::toString(proxyUuid.value())
-                                             : "null");
+        LOG(WARNING) << __func__ << " loading lib " << path->second << ": typeUuid "
+                     << ::android::audio::utils::toString(id.type) << "\nimplUuid "
+                     << ::android::audio::utils::toString(id.uuid) << " proxyUuid "
+                     << (proxyUuid.has_value()
+                                 ? ::android::audio::utils::toString(proxyUuid.value())
+                                 : "null");
         if (openEffectLibrary(id.uuid, path->second)) {
             mIdentitySet.insert(std::move(id));
         }
@@ -263,8 +262,8 @@
                 createIdentityWithConfig(configLib, type, proxyUuid);
             }
         } else {
-            LOG(ERROR) << __func__ << ": can not find type UUID for effect " << configEffects.first
-                       << " skipping!";
+            LOG(WARNING) << __func__ << ": can not find type UUID for effect "
+                         << configEffects.first << " skipping!";
         }
     }
 }
diff --git a/audio/aidl/default/EffectImpl.cpp b/audio/aidl/default/EffectImpl.cpp
index 4d7b980..03de74f 100644
--- a/audio/aidl/default/EffectImpl.cpp
+++ b/audio/aidl/default/EffectImpl.cpp
@@ -35,7 +35,6 @@
                    << " in state: " << toString(state) << ", status: " << status.getDescription();
         return EX_ILLEGAL_STATE;
     }
-    LOG(DEBUG) << __func__ << " instance " << instanceSp.get() << " destroyed";
     return EX_NONE;
 }
 
@@ -91,7 +90,7 @@
     }
 
     RETURN_IF(notifyEventFlag(kEventFlagNotEmpty) != RetCode::SUCCESS, EX_ILLEGAL_STATE,
-              "notifyEventFlagFailed");
+              "notifyEventFlagNotEmptyFailed");
     // stop the worker thread, ignore the return code
     RETURN_IF(destroyThread() != RetCode::SUCCESS, EX_UNSUPPORTED_OPERATION,
               "FailedToDestroyWorker");
@@ -231,8 +230,6 @@
 ndk::ScopedAStatus EffectImpl::command(CommandId command) {
     std::lock_guard lg(mImplMutex);
     RETURN_IF(mState == State::INIT, EX_ILLEGAL_STATE, "instanceNotOpen");
-    LOG(DEBUG) << getEffectName() << __func__ << ": receive command: " << toString(command)
-               << " at state " << toString(mState);
 
     switch (command) {
         case CommandId::START:
@@ -240,7 +237,7 @@
             RETURN_IF_ASTATUS_NOT_OK(commandImpl(command), "commandImplFailed");
             mState = State::PROCESSING;
             RETURN_IF(notifyEventFlag(kEventFlagNotEmpty) != RetCode::SUCCESS, EX_ILLEGAL_STATE,
-                      "notifyEventFlagFailed");
+                      "notifyEventFlagNotEmptyFailed");
             startThread();
             break;
         case CommandId::STOP:
@@ -248,7 +245,7 @@
             RETURN_OK_IF(mState == State::IDLE);
             mState = State::IDLE;
             RETURN_IF(notifyEventFlag(kEventFlagNotEmpty) != RetCode::SUCCESS, EX_ILLEGAL_STATE,
-                      "notifyEventFlagFailed");
+                      "notifyEventFlagNotEmptyFailed");
             stopThread();
             RETURN_IF_ASTATUS_NOT_OK(commandImpl(command), "commandImplFailed");
             break;
@@ -257,7 +254,7 @@
             return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
                                                                     "CommandIdNotSupported");
     }
-    LOG(DEBUG) << getEffectName() << __func__ << " transfer to state: " << toString(mState);
+    LOG(VERBOSE) << getEffectName() << __func__ << " transfer to state: " << toString(mState);
     return ndk::ScopedAStatus::ok();
 }
 
@@ -294,6 +291,7 @@
         LOG(ERROR) << getEffectName() << __func__ << ": wake failure with ret " << ret;
         return RetCode::ERROR_EVENT_FLAG_ERROR;
     }
+    LOG(VERBOSE) << getEffectName() << __func__ << ": " << std::hex << mEventFlag;
     return RetCode::SUCCESS;
 }
 
@@ -306,7 +304,7 @@
 }
 
 void EffectImpl::process() {
-    ATRACE_CALL();
+    ATRACE_NAME(getEffectName().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).
@@ -344,8 +342,6 @@
             IEffect::Status status = effectProcessImpl(buffer, buffer, processSamples);
             outputMQ->write(buffer, status.fmqProduced);
             statusMQ->writeBlocking(&status, 1);
-            LOG(VERBOSE) << getEffectName() << __func__ << ": done processing, effect consumed "
-                         << status.fmqConsumed << " produced " << status.fmqProduced;
         }
     }
 }
@@ -355,7 +351,6 @@
     for (int i = 0; i < samples; i++) {
         *out++ = *in++;
     }
-    LOG(VERBOSE) << getEffectName() << __func__ << " done processing " << samples << " samples";
     return {STATUS_OK, samples, samples};
 }
 
diff --git a/audio/aidl/default/EffectThread.cpp b/audio/aidl/default/EffectThread.cpp
index fdd4803..b515385 100644
--- a/audio/aidl/default/EffectThread.cpp
+++ b/audio/aidl/default/EffectThread.cpp
@@ -27,13 +27,8 @@
 
 namespace aidl::android::hardware::audio::effect {
 
-EffectThread::EffectThread() {
-    LOG(DEBUG) << __func__;
-}
-
 EffectThread::~EffectThread() {
     destroyThread();
-    LOG(DEBUG) << __func__ << " done";
 }
 
 RetCode EffectThread::createThread(const std::string& name, int priority) {
@@ -51,7 +46,7 @@
     }
 
     mThread = std::thread(&EffectThread::threadLoop, this);
-    LOG(DEBUG) << mName << __func__ << " priority " << mPriority << " done";
+    LOG(VERBOSE) << mName << __func__ << " priority " << mPriority << " done";
     return RetCode::SUCCESS;
 }
 
@@ -66,7 +61,7 @@
         mThread.join();
     }
 
-    LOG(DEBUG) << mName << __func__;
+    LOG(VERBOSE) << mName << __func__;
     return RetCode::SUCCESS;
 }
 
@@ -77,7 +72,7 @@
         mCv.notify_one();
     }
 
-    LOG(DEBUG) << mName << __func__;
+    LOG(VERBOSE) << mName << __func__;
     return RetCode::SUCCESS;
 }
 
@@ -88,7 +83,7 @@
         mCv.notify_one();
     }
 
-    LOG(DEBUG) << mName << __func__;
+    LOG(VERBOSE) << mName << __func__;
     return RetCode::SUCCESS;
 }
 
@@ -101,7 +96,7 @@
             ::android::base::ScopedLockAssertion lock_assertion(mThreadMutex);
             mCv.wait(l, [&]() REQUIRES(mThreadMutex) { return mExit || !mStop; });
             if (mExit) {
-                LOG(INFO) << __func__ << " EXIT!";
+                LOG(VERBOSE) << mName << " threadLoop EXIT!";
                 return;
             }
         }
diff --git a/audio/aidl/default/bluetooth/ModuleBluetooth.cpp b/audio/aidl/default/bluetooth/ModuleBluetooth.cpp
index ac375a0..8c381cd 100644
--- a/audio/aidl/default/bluetooth/ModuleBluetooth.cpp
+++ b/audio/aidl/default/bluetooth/ModuleBluetooth.cpp
@@ -224,31 +224,19 @@
     const auto& devicePort = audioPort->ext.get<AudioPortExt::device>();
     const auto& description = devicePort.device.type;
     // This method must return an error when the device can not be connected.
-    if (description.connection == AudioDeviceDescription::CONNECTION_BT_A2DP) {
-        bool isA2dpEnabled = false;
-        if (!!mBluetoothA2dp) {
-            RETURN_STATUS_IF_ERROR((*mBluetoothA2dp).isEnabled(&isA2dpEnabled));
-        }
-        LOG(DEBUG) << __func__ << ": isA2dpEnabled: " << isA2dpEnabled;
-        if (!isA2dpEnabled) return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
-    } else if (description.connection == AudioDeviceDescription::CONNECTION_BT_LE) {
-        bool isLeEnabled = false;
-        if (!!mBluetoothLe) {
-            RETURN_STATUS_IF_ERROR((*mBluetoothLe).isEnabled(&isLeEnabled));
-        }
-        LOG(DEBUG) << __func__ << ": isLeEnabled: " << isLeEnabled;
-        if (!isLeEnabled) return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
-    } else if (description.connection == AudioDeviceDescription::CONNECTION_WIRELESS &&
-               description.type == AudioDeviceType::OUT_HEARING_AID) {
-        // Hearing aids can use a number of profiles, no single switch exists.
-    } else {
+    // Since A2DP/LE status events are sent asynchronously, it is more reliable
+    // to attempt connecting to the BT stack rather than judge by the A2DP/LE status.
+    if (description.connection != AudioDeviceDescription::CONNECTION_BT_A2DP &&
+        description.connection != AudioDeviceDescription::CONNECTION_BT_LE &&
+        !(description.connection == AudioDeviceDescription::CONNECTION_WIRELESS &&
+          description.type == AudioDeviceType::OUT_HEARING_AID)) {
         LOG(ERROR) << __func__ << ": unsupported device type: " << audioPort->toString();
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
     }
     CachedProxy proxy;
     RETURN_STATUS_IF_ERROR(createProxy(*audioPort, nextPortId, proxy));
-    // Since the device is already connected and configured by the BT stack, provide
-    // the current configuration instead of all possible profiles.
+    // If the device is actually connected, it is configured by the BT stack.
+    // Provide the current configuration instead of all possible profiles.
     const auto& pcmConfig = proxy.pcmConfig;
     audioPort->profiles.clear();
     audioPort->profiles.push_back(
diff --git a/audio/aidl/default/include/core-impl/Module.h b/audio/aidl/default/include/core-impl/Module.h
index d6e8905..a326217 100644
--- a/audio/aidl/default/include/core-impl/Module.h
+++ b/audio/aidl/default/include/core-impl/Module.h
@@ -213,7 +213,7 @@
                                                                                  sampleRateHz);
         // Round up to nearest 16 frames since in the framework this is the size of a mixer burst.
         const int32_t multipleOf16 = (rawSizeFrames + 15) & ~15;
-        if (multipleOf16 <= 512) return multipleOf16;
+        if (sampleRateHz < 44100 || multipleOf16 <= 512) return multipleOf16;
         // Larger buffers should use powers of 2.
         int32_t powerOf2 = 1;
         while (powerOf2 < multipleOf16) powerOf2 <<= 1;
diff --git a/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h b/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h
index b2cdc28..0d50c96 100644
--- a/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h
+++ b/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h
@@ -55,8 +55,8 @@
     r_submix::AudioConfig mStreamConfig;
     std::shared_ptr<r_submix::SubmixRoute> mCurrentRoute = nullptr;
 
-    // limit for number of read error log entries to avoid spamming the logs
-    static constexpr int kMaxReadErrorLogs = 5;
+    // Limit for the number of error log entries to avoid spamming the logs.
+    static constexpr int kMaxErrorLogs = 5;
     // The duration of kMaxReadFailureAttempts * READ_ATTEMPT_SLEEP_MS must be strictly inferior
     // to the duration of a record buffer at the current record sample rate (of the device, not of
     // the recording itself). Here we have: 3 * 5ms = 15ms < 1024 frames * 1000 / 48000 = 21.333ms
@@ -68,6 +68,7 @@
     long mFramesSinceStart = 0;
     int mReadErrorCount = 0;
     int mReadFailureCount = 0;
+    int mWriteShutdownCount = 0;
 };
 
 class StreamInRemoteSubmix final : public StreamIn, public StreamSwitcher {
diff --git a/audio/aidl/default/include/effect-impl/EffectThread.h b/audio/aidl/default/include/effect-impl/EffectThread.h
index 3dbb0e6..ec2a658 100644
--- a/audio/aidl/default/include/effect-impl/EffectThread.h
+++ b/audio/aidl/default/include/effect-impl/EffectThread.h
@@ -31,11 +31,9 @@
 
 class EffectThread {
   public:
-    // default priority is same as HIDL: ANDROID_PRIORITY_URGENT_AUDIO
-    EffectThread();
     virtual ~EffectThread();
 
-    // called by effect implementation.
+    // called by effect implementation
     RetCode createThread(const std::string& name, int priority = ANDROID_PRIORITY_URGENT_AUDIO);
     RetCode destroyThread();
     RetCode startThread();
diff --git a/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp b/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp
index 2376ed9..ca3f91a 100644
--- a/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp
+++ b/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp
@@ -134,11 +134,16 @@
     *latencyMs = getDelayInUsForFrameCount(getStreamPipeSizeInFrames()) / 1000;
     LOG(VERBOSE) << __func__ << ": Latency " << *latencyMs << "ms";
     mCurrentRoute->exitStandby(mIsInput);
-    RETURN_STATUS_IF_ERROR(mIsInput ? inRead(buffer, frameCount, actualFrameCount)
-                                    : outWrite(buffer, frameCount, actualFrameCount));
+    ::android::status_t status = mIsInput ? inRead(buffer, frameCount, actualFrameCount)
+                                          : outWrite(buffer, frameCount, actualFrameCount);
+    if ((status != ::android::OK && mIsInput) ||
+        ((status != ::android::OK && status != ::android::DEAD_OBJECT) && !mIsInput)) {
+        return status;
+    }
     mFramesSinceStart += *actualFrameCount;
-    if (!mIsInput) return ::android::OK;
-    // Only input streams need to block, for output this is implemented by MonoPipe.
+    if (!mIsInput && status != ::android::DEAD_OBJECT) return ::android::OK;
+    // Input streams always need to block, output streams need to block when there is no sink.
+    // When the sink exists, more sophisticated blocking algorithm is implemented by MonoPipe.
     const long bufferDurationUs =
             (*actualFrameCount) * MICROS_PER_SECOND / mContext.getSampleRate();
     const auto totalDurationUs = (::android::uptimeNanos() - mStartTimeNs) / NANOS_PER_MICROSECOND;
@@ -188,14 +193,17 @@
     if (sink != nullptr) {
         if (sink->isShutdown()) {
             sink.clear();
-            LOG(DEBUG) << __func__ << ": pipe shutdown, ignoring the write";
+            if (++mWriteShutdownCount < kMaxErrorLogs) {
+                LOG(DEBUG) << __func__ << ": pipe shutdown, ignoring the write. (limited logging)";
+            }
             *actualFrameCount = frameCount;
-            return ::android::OK;
+            return ::android::DEAD_OBJECT;  // Induce wait in `transfer`.
         }
     } else {
         LOG(FATAL) << __func__ << ": without a pipe!";
         return ::android::UNKNOWN_ERROR;
     }
+    mWriteShutdownCount = 0;
 
     LOG(VERBOSE) << __func__ << ": " << mDeviceAddress.toString() << ", " << frameCount
                  << " frames";
@@ -262,7 +270,7 @@
     // about to read from audio source
     sp<MonoPipeReader> source = mCurrentRoute->getSource();
     if (source == nullptr) {
-        if (++mReadErrorCount < kMaxReadErrorLogs) {
+        if (++mReadErrorCount < kMaxErrorLogs) {
             LOG(ERROR) << __func__
                        << ": no audio pipe yet we're trying to read! (not all errors will be "
                           "logged)";
diff --git a/audio/aidl/vts/TestUtils.h b/audio/aidl/vts/TestUtils.h
index 515b8a2..0a5addc 100644
--- a/audio/aidl/vts/TestUtils.h
+++ b/audio/aidl/vts/TestUtils.h
@@ -104,11 +104,13 @@
     EXPECT_PRED_FORMAT2(::android::hardware::audio::common::testing::detail::assertResult, \
                         expected, ret)
 
-#define SKIP_TEST_IF_DATA_UNSUPPORTED(flags)                                                     \
-    ({                                                                                           \
-        if ((flags).hwAcceleratorMode == Flags::HardwareAccelerator::TUNNEL || (flags).bypass) { \
-            GTEST_SKIP() << "Skip data path for offload";                                        \
-        }                                                                                        \
+#define SKIP_TEST_IF_DATA_UNSUPPORTED(flags)                                                      \
+    ({                                                                                            \
+        if ((flags).hwAcceleratorMode ==                                                          \
+                    aidl::android::hardware::audio::effect::Flags::HardwareAccelerator::TUNNEL || \
+            (flags).bypass) {                                                                     \
+            GTEST_SKIP() << "Skip data path for offload";                                         \
+        }                                                                                         \
     })
 
 // Test that the transaction status 'isOk' if it is a known transaction
diff --git a/audio/aidl/vts/VtsHalAudioEffectFactoryTargetTest.cpp b/audio/aidl/vts/VtsHalAudioEffectFactoryTargetTest.cpp
index 21df163..a19aa56 100644
--- a/audio/aidl/vts/VtsHalAudioEffectFactoryTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioEffectFactoryTargetTest.cpp
@@ -65,7 +65,7 @@
         }
     }
 
-    std::string kServiceName = GetParam();
+    const std::string kServiceName = GetParam();
     std::shared_ptr<IFactory> mEffectFactory;
     std::vector<std::shared_ptr<IEffect>> mEffects;
     const Descriptor::Identity kNullId = {.uuid = getEffectUuidNull()};
@@ -118,6 +118,10 @@
         mEffectFactory = IFactory::fromBinder(mBinderUtil.connectToService(kServiceName));
         ASSERT_NE(mEffectFactory, nullptr);
     }
+    void restartAndGetFactory() {
+        mEffectFactory = IFactory::fromBinder(mBinderUtil.restartService());
+        ASSERT_NE(mEffectFactory, nullptr);
+    }
 };
 
 TEST_P(EffectFactoryTest, SetupAndTearDown) {
@@ -126,8 +130,7 @@
 
 TEST_P(EffectFactoryTest, CanBeRestarted) {
     ASSERT_NE(mEffectFactory, nullptr);
-    mEffectFactory = IFactory::fromBinder(mBinderUtil.restartService());
-    ASSERT_NE(mEffectFactory, nullptr);
+    restartAndGetFactory();
 }
 
 /**
@@ -249,9 +252,7 @@
     EXPECT_NE(descs.size(), 0UL);
     creatAndDestroyDescs(descs);
 
-    mEffectFactory = IFactory::fromBinder(mBinderUtil.restartService());
-    ASSERT_NE(mEffectFactory, nullptr);
-
+    restartAndGetFactory();
     connectAndGetFactory();
     creatAndDestroyDescs(descs);
 }
@@ -263,9 +264,7 @@
     EXPECT_NE(descs.size(), 0UL);
     std::vector<std::shared_ptr<IEffect>> effects = createWithDescs(descs);
 
-    mEffectFactory = IFactory::fromBinder(mBinderUtil.restartService());
-    ASSERT_NE(mEffectFactory, nullptr);
-
+    restartAndGetFactory();
     connectAndGetFactory();
     destroyEffects(effects, EX_ILLEGAL_ARGUMENT);
 }
diff --git a/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp b/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp
index b54b442..4cb1f49 100644
--- a/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp
@@ -166,6 +166,7 @@
     }
 
     void SetUp() override {
+        SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
         ASSERT_NO_FATAL_FAILURE(SetUpBassBoost(mChannelLayout));
         if (int32_t version;
             mEffect->getInterfaceVersion(&version).isOk() && version < kMinDataTestHalVersion) {
@@ -173,7 +174,10 @@
         }
     }
 
-    void TearDown() override { TearDownBassBoost(); }
+    void TearDown() override {
+        SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
+        TearDownBassBoost();
+    }
 
     // Find FFT bin indices for testFrequencies and get bin center frequencies
     void roundToFreqCenteredToFftBin(std::vector<int>& testFrequencies,
diff --git a/audio/aidl/vts/VtsHalDownmixTargetTest.cpp b/audio/aidl/vts/VtsHalDownmixTargetTest.cpp
index 360bf26..ef77f4d 100644
--- a/audio/aidl/vts/VtsHalDownmixTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalDownmixTargetTest.cpp
@@ -230,6 +230,7 @@
     }
 
     void SetUp() override {
+        SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
         SetUpDownmix(mInputChannelLayout);
         if (int32_t version;
             mEffect->getInterfaceVersion(&version).isOk() && version < kMinDataTestHalVersion) {
@@ -241,7 +242,10 @@
         setDataTestParams(mInputChannelLayout);
     }
 
-    void TearDown() override { TearDownDownmix(); }
+    void TearDown() override {
+        SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
+        TearDownDownmix();
+    }
 
     void checkAtLeft(int32_t position) {
         for (size_t i = 0, j = position; i < mOutputBufferSize;
diff --git a/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp b/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
index 7f0091f..a075423 100644
--- a/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
@@ -156,6 +156,7 @@
     }
 
     void SetUp() override {
+        SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
         SetUpLoudnessEnhancer();
 
         // Creating AidlMessageQueues
@@ -164,7 +165,10 @@
         mOutputMQ = std::make_unique<EffectHelper::DataMQ>(mOpenEffectReturn.outputDataMQ);
     }
 
-    void TearDown() override { TearDownLoudnessEnhancer(); }
+    void TearDown() override {
+        SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
+        TearDownLoudnessEnhancer();
+    }
 
     // Fill inputBuffer with random values between -kMaxAudioSample to kMaxAudioSample
     void generateInputBuffer() {
diff --git a/audio/aidl/vts/VtsHalVolumeTargetTest.cpp b/audio/aidl/vts/VtsHalVolumeTargetTest.cpp
index 059d6ab..1c1489d 100644
--- a/audio/aidl/vts/VtsHalVolumeTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalVolumeTargetTest.cpp
@@ -163,8 +163,14 @@
     // Convert Decibel value to Percentage
     int percentageDb(float level) { return std::round((1 - (pow(10, level / 20))) * 100); }
 
-    void SetUp() override { ASSERT_NO_FATAL_FAILURE(SetUpVolumeControl()); }
-    void TearDown() override { TearDownVolumeControl(); }
+    void SetUp() override {
+        SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
+        ASSERT_NO_FATAL_FAILURE(SetUpVolumeControl());
+    }
+    void TearDown() override {
+        SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
+        TearDownVolumeControl();
+    }
 
     static constexpr int kMaxAudioSample = 1;
     static constexpr int kTransitionDuration = 300;
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 395e4cc..608fde1 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)
@@ -1050,6 +1054,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(
diff --git a/camera/device/default/ExternalCameraDeviceSession.cpp b/camera/device/default/ExternalCameraDeviceSession.cpp
index a6ec4c7..126b782 100644
--- a/camera/device/default/ExternalCameraDeviceSession.cpp
+++ b/camera/device/default/ExternalCameraDeviceSession.cpp
@@ -789,8 +789,10 @@
                 outputBuffer.bufferId = buffer.bufferId;
                 outputBuffer.status = BufferStatus::ERROR;
                 if (buffer.acquireFence >= 0) {
-                    outputBuffer.releaseFence.fds.resize(1);
-                    outputBuffer.releaseFence.fds.at(0).set(buffer.acquireFence);
+                    native_handle_t* handle = native_handle_create(/*numFds*/ 1, /*numInts*/ 0);
+                    handle->data[0] = buffer.acquireFence;
+                    outputBuffer.releaseFence = android::dupToAidl(handle);
+                    native_handle_delete(handle);
                 }
             } else {
                 offlineBuffers.push_back(buffer);
@@ -1768,8 +1770,10 @@
         result.outputBuffers[i].bufferId = req->buffers[i].bufferId;
         result.outputBuffers[i].status = BufferStatus::ERROR;
         if (req->buffers[i].acquireFence >= 0) {
-            result.outputBuffers[i].releaseFence.fds.resize(1);
-            result.outputBuffers[i].releaseFence.fds.at(0).set(req->buffers[i].acquireFence);
+            native_handle_t* handle = native_handle_create(/*numFds*/ 1, /*numInts*/ 0);
+            handle->data[0] = req->buffers[i].acquireFence;
+            result.outputBuffers[i].releaseFence = android::dupToAidl(handle);
+            native_handle_delete(handle);
         }
     }
 
@@ -1813,16 +1817,20 @@
         if (req->buffers[i].fenceTimeout) {
             result.outputBuffers[i].status = BufferStatus::ERROR;
             if (req->buffers[i].acquireFence >= 0) {
-                result.outputBuffers[i].releaseFence.fds.resize(1);
-                result.outputBuffers[i].releaseFence.fds.at(0).set(req->buffers[i].acquireFence);
+                native_handle_t* handle = native_handle_create(/*numFds*/ 1, /*numInts*/ 0);
+                handle->data[0] = req->buffers[i].acquireFence;
+                result.outputBuffers[i].releaseFence = android::dupToAidl(handle);
+                native_handle_delete(handle);
             }
             notifyError(req->frameNumber, req->buffers[i].streamId, ErrorCode::ERROR_BUFFER);
         } else {
             result.outputBuffers[i].status = BufferStatus::OK;
             // TODO: refactor
             if (req->buffers[i].acquireFence >= 0) {
-                result.outputBuffers[i].releaseFence.fds.resize(1);
-                result.outputBuffers[i].releaseFence.fds.at(0).set(req->buffers[i].acquireFence);
+                native_handle_t* handle = native_handle_create(/*numFds*/ 1, /*numInts*/ 0);
+                handle->data[0] = req->buffers[i].acquireFence;
+                result.outputBuffers[i].releaseFence = android::dupToAidl(handle);
+                native_handle_delete(handle);
             }
         }
     }
diff --git a/camera/device/default/ExternalCameraOfflineSession.cpp b/camera/device/default/ExternalCameraOfflineSession.cpp
index 53bd44f..536fa47 100644
--- a/camera/device/default/ExternalCameraOfflineSession.cpp
+++ b/camera/device/default/ExternalCameraOfflineSession.cpp
@@ -110,7 +110,7 @@
             if (req->buffers[i].acquireFence >= 0) {
                 native_handle_t* handle = native_handle_create(/*numFds*/ 1, /*numInts*/ 0);
                 handle->data[0] = req->buffers[i].acquireFence;
-                result.outputBuffers[i].releaseFence = android::makeToAidl(handle);
+                result.outputBuffers[i].releaseFence = android::dupToAidl(handle);
             }
             notifyError(req->frameNumber, req->buffers[i].streamId, ErrorCode::ERROR_BUFFER);
         } else {
@@ -119,7 +119,7 @@
             if (req->buffers[i].acquireFence >= 0) {
                 native_handle_t* handle = native_handle_create(/*numFds*/ 1, /*numInts*/ 0);
                 handle->data[0] = req->buffers[i].acquireFence;
-                outputBuffer.releaseFence = android::makeToAidl(handle);
+                outputBuffer.releaseFence = android::dupToAidl(handle);
             }
         }
     }
@@ -247,7 +247,7 @@
         if (req->buffers[i].acquireFence >= 0) {
             native_handle_t* handle = native_handle_create(/*numFds*/ 1, /*numInts*/ 0);
             handle->data[0] = req->buffers[i].acquireFence;
-            outputBuffer.releaseFence = makeToAidl(handle);
+            outputBuffer.releaseFence = dupToAidl(handle);
         }
     }
 
diff --git a/camera/device/default/ExternalCameraUtils.cpp b/camera/device/default/ExternalCameraUtils.cpp
index 30c216f..2dc3c77 100644
--- a/camera/device/default/ExternalCameraUtils.cpp
+++ b/camera/device/default/ExternalCameraUtils.cpp
@@ -750,18 +750,12 @@
 
 void freeReleaseFences(std::vector<CaptureResult>& results) {
     for (auto& result : results) {
-        native_handle_t* inputReleaseFence =
-                ::android::makeFromAidl(result.inputBuffer.releaseFence);
-        if (inputReleaseFence != nullptr) {
-            native_handle_close(inputReleaseFence);
-            native_handle_delete(inputReleaseFence);
-        }
+        // NativeHandles free fd's on desctruction. Simply delete the objects!
+        result.inputBuffer.releaseFence.fds.clear();  // Implicitly closes fds
+        result.inputBuffer.releaseFence.ints.clear();
         for (auto& buf : result.outputBuffers) {
-            native_handle_t* outReleaseFence = ::android::makeFromAidl(buf.releaseFence);
-            if (outReleaseFence != nullptr) {
-                native_handle_close(outReleaseFence);
-                native_handle_delete(outReleaseFence);
-            }
+            buf.releaseFence.fds.clear();  // Implicitly closes fds
+            buf.releaseFence.ints.clear();
         }
     }
 }
diff --git a/graphics/composer/aidl/vts/ReadbackVts.cpp b/graphics/composer/aidl/vts/ReadbackVts.cpp
index 8605628..c72ec69 100644
--- a/graphics/composer/aidl/vts/ReadbackVts.cpp
+++ b/graphics/composer/aidl/vts/ReadbackVts.cpp
@@ -293,8 +293,8 @@
 TestBufferLayer::TestBufferLayer(const std::shared_ptr<VtsComposerClient>& client,
                                  TestRenderEngine& renderEngine, int64_t display, uint32_t width,
                                  uint32_t height, common::PixelFormat format,
-                                 Composition composition)
-    : TestLayer{client, display}, mRenderEngine(renderEngine) {
+                                 ComposerClientWriter& writer, Composition composition)
+    : TestLayer{client, display, writer}, mRenderEngine(renderEngine) {
     mComposition = composition;
     mWidth = width;
     mHeight = height;
diff --git a/graphics/composer/aidl/vts/ReadbackVts.h b/graphics/composer/aidl/vts/ReadbackVts.h
index ee20573..8ac0f4b 100644
--- a/graphics/composer/aidl/vts/ReadbackVts.h
+++ b/graphics/composer/aidl/vts/ReadbackVts.h
@@ -50,9 +50,10 @@
 
 class TestLayer {
   public:
-    TestLayer(const std::shared_ptr<VtsComposerClient>& client, int64_t display)
+    TestLayer(const std::shared_ptr<VtsComposerClient>& client, int64_t display,
+              ComposerClientWriter& writer)
         : mDisplay(display) {
-        const auto& [status, layer] = client->createLayer(display, kBufferSlotCount);
+        const auto& [status, layer] = client->createLayer(display, kBufferSlotCount, &writer);
         EXPECT_TRUE(status.isOk());
         mLayer = layer;
     }
@@ -108,8 +109,9 @@
 
 class TestColorLayer : public TestLayer {
   public:
-    TestColorLayer(const std::shared_ptr<VtsComposerClient>& client, int64_t display)
-        : TestLayer{client, display} {}
+    TestColorLayer(const std::shared_ptr<VtsComposerClient>& client, int64_t display,
+                   ComposerClientWriter& writer)
+        : TestLayer{client, display, writer} {}
 
     void write(ComposerClientWriter& writer) override;
 
@@ -125,7 +127,7 @@
   public:
     TestBufferLayer(const std::shared_ptr<VtsComposerClient>& client,
                     TestRenderEngine& renderEngine, int64_t display, uint32_t width,
-                    uint32_t height, common::PixelFormat format,
+                    uint32_t height, common::PixelFormat format, ComposerClientWriter& writer,
                     Composition composition = Composition::DEVICE);
 
     void write(ComposerClientWriter& writer) override;
diff --git a/graphics/composer/aidl/vts/VtsComposerClient.cpp b/graphics/composer/aidl/vts/VtsComposerClient.cpp
index ac08cd1..2c24bfb 100644
--- a/graphics/composer/aidl/vts/VtsComposerClient.cpp
+++ b/graphics/composer/aidl/vts/VtsComposerClient.cpp
@@ -33,6 +33,14 @@
         mComposer = IComposer::fromBinder(binder);
         ALOGE_IF(mComposer == nullptr, "Failed to acquire the composer from the binder");
     }
+
+    const auto& [status, capabilities] = getCapabilities();
+    EXPECT_TRUE(status.isOk());
+    if (std::any_of(capabilities.begin(), capabilities.end(), [&](const Capability& cap) {
+            return cap == Capability::LAYER_LIFECYCLE_BATCH_COMMAND;
+        })) {
+        mSupportsBatchedCreateLayer = true;
+    }
 }
 
 ScopedAStatus VtsComposerClient::createClient() {
@@ -54,8 +62,8 @@
     return mComposerClient->registerCallback(mComposerCallback);
 }
 
-bool VtsComposerClient::tearDown() {
-    return verifyComposerCallbackParams() && destroyAllLayers();
+bool VtsComposerClient::tearDown(ComposerClientWriter* writer) {
+    return verifyComposerCallbackParams() && destroyAllLayers(writer);
 }
 
 std::pair<ScopedAStatus, int32_t> VtsComposerClient::getInterfaceVersion() const {
@@ -86,7 +94,16 @@
 }
 
 std::pair<ScopedAStatus, int64_t> VtsComposerClient::createLayer(int64_t display,
-                                                                 int32_t bufferSlotCount) {
+                                                                 int32_t bufferSlotCount,
+                                                                 ComposerClientWriter* writer) {
+    if (mSupportsBatchedCreateLayer) {
+        int64_t layer = mNextLayerHandle++;
+        writer->setLayerLifecycleBatchCommandType(display, layer,
+                                                  LayerLifecycleBatchCommandType::CREATE);
+        writer->setNewBufferSlotCount(display, layer, bufferSlotCount);
+        return {addLayerToDisplayResources(display, layer), layer};
+    }
+
     int64_t outLayer;
     auto status = mComposerClient->createLayer(display, bufferSlotCount, &outLayer);
 
@@ -96,14 +113,20 @@
     return {addLayerToDisplayResources(display, outLayer), outLayer};
 }
 
-ScopedAStatus VtsComposerClient::destroyLayer(int64_t display, int64_t layer) {
-    auto status = mComposerClient->destroyLayer(display, layer);
-
-    if (!status.isOk()) {
-        return status;
+ScopedAStatus VtsComposerClient::destroyLayer(int64_t display, int64_t layer,
+                                              ComposerClientWriter* writer) {
+    if (mSupportsBatchedCreateLayer) {
+        writer->setLayerLifecycleBatchCommandType(display, layer,
+                                                  LayerLifecycleBatchCommandType::DESTROY);
+    } else {
+        auto status = mComposerClient->destroyLayer(display, layer);
+        if (!status.isOk()) {
+            return status;
+        }
     }
+
     removeLayerFromDisplayResources(display, layer);
-    return status;
+    return ScopedAStatus::ok();
 }
 
 std::pair<ScopedAStatus, int32_t> VtsComposerClient::getActiveConfig(int64_t display) {
@@ -632,7 +655,7 @@
     return interfaceVersion >= 3;
 }
 
-bool VtsComposerClient::destroyAllLayers() {
+bool VtsComposerClient::destroyAllLayers(ComposerClientWriter* writer) {
     std::unordered_map<int64_t, DisplayResource> physicalDisplays;
     while (!mDisplayResources.empty()) {
         const auto& it = mDisplayResources.begin();
@@ -640,7 +663,7 @@
 
         while (!resource.layers.empty()) {
             auto layer = *resource.layers.begin();
-            const auto status = destroyLayer(display, layer);
+            const auto status = destroyLayer(display, layer, writer);
             if (!status.isOk()) {
                 ALOGE("Unable to destroy all the layers, failed at layer %" PRId64 " with error %s",
                       layer, status.getDescription().c_str());
diff --git a/graphics/composer/aidl/vts/VtsComposerClient.h b/graphics/composer/aidl/vts/VtsComposerClient.h
index 292bc40..fabc82a 100644
--- a/graphics/composer/aidl/vts/VtsComposerClient.h
+++ b/graphics/composer/aidl/vts/VtsComposerClient.h
@@ -25,6 +25,7 @@
 #include <android/binder_manager.h>
 #include <android/binder_process.h>
 #include <android/hardware/graphics/composer3/ComposerClientReader.h>
+#include <android/hardware/graphics/composer3/ComposerClientWriter.h>
 #include <binder/ProcessState.h>
 #include <gtest/gtest.h>
 #include <ui/Fence.h>
@@ -59,7 +60,7 @@
 
     ScopedAStatus createClient();
 
-    bool tearDown();
+    bool tearDown(ComposerClientWriter*);
 
     std::pair<ScopedAStatus, int32_t> getInterfaceVersion() const;
 
@@ -69,9 +70,10 @@
 
     ScopedAStatus destroyVirtualDisplay(int64_t display);
 
-    std::pair<ScopedAStatus, int64_t> createLayer(int64_t display, int32_t bufferSlotCount);
+    std::pair<ScopedAStatus, int64_t> createLayer(int64_t display, int32_t bufferSlotCount,
+                                                  ComposerClientWriter*);
 
-    ScopedAStatus destroyLayer(int64_t display, int64_t layer);
+    ScopedAStatus destroyLayer(int64_t display, int64_t layer, ComposerClientWriter*);
 
     std::pair<ScopedAStatus, int32_t> getActiveConfig(int64_t display);
 
@@ -211,7 +213,7 @@
 
     void removeLayerFromDisplayResources(int64_t display, int64_t layer);
 
-    bool destroyAllLayers();
+    bool destroyAllLayers(ComposerClientWriter*);
 
     bool verifyComposerCallbackParams();
 
@@ -229,6 +231,8 @@
     std::shared_ptr<IComposerClient> mComposerClient;
     std::shared_ptr<GraphicsComposerCallback> mComposerCallback;
     std::unordered_map<int64_t, DisplayResource> mDisplayResources;
+    bool mSupportsBatchedCreateLayer = false;
+    std::atomic<int64_t> mNextLayerHandle = 1;
 };
 
 class VtsDisplay {
diff --git a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp
index 2e3f4df..164e6d5 100644
--- a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp
+++ b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp
@@ -86,7 +86,7 @@
 
     void TearDown() override {
         ASSERT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::OFF).isOk());
-        ASSERT_TRUE(mComposerClient->tearDown());
+        ASSERT_TRUE(mComposerClient->tearDown(mWriter.get()));
         mComposerClient.reset();
         const auto errors = mReader.takeErrors();
         ASSERT_TRUE(mReader.takeErrors().empty());
@@ -201,7 +201,8 @@
             return;
         }
 
-        auto layer = std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId());
+        auto layer =
+                std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId(), *mWriter);
         common::Rect coloredSquare({0, 0, getDisplayWidth(), getDisplayHeight()});
         layer->setColor(BLUE);
         layer->setDisplayFrame(coloredSquare);
@@ -270,7 +271,7 @@
 
         auto layer = std::make_shared<TestBufferLayer>(
                 mComposerClient, *mTestRenderEngine, getPrimaryDisplayId(), getDisplayWidth(),
-                getDisplayHeight(), common::PixelFormat::RGBA_8888);
+                getDisplayHeight(), common::PixelFormat::RGBA_8888, *mWriter);
         layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
         layer->setZOrder(10);
         layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode));
@@ -315,7 +316,8 @@
             return;
         }
 
-        auto layer = std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId());
+        auto layer =
+                std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId(), *mWriter);
         common::Rect coloredSquare({0, 0, getDisplayWidth(), getDisplayHeight()});
         layer->setColor(BLUE);
         layer->setDisplayFrame(coloredSquare);
@@ -454,9 +456,9 @@
                 expectedColors, getDisplayWidth(),
                 {0, getDisplayHeight() / 2, getDisplayWidth(), getDisplayHeight()}, BLUE);
 
-        auto layer = std::make_shared<TestBufferLayer>(mComposerClient, *mTestRenderEngine,
-                                                       getPrimaryDisplayId(), getDisplayWidth(),
-                                                       getDisplayHeight(), PixelFormat::RGBA_FP16);
+        auto layer = std::make_shared<TestBufferLayer>(
+                mComposerClient, *mTestRenderEngine, getPrimaryDisplayId(), getDisplayWidth(),
+                getDisplayHeight(), PixelFormat::RGBA_FP16, *mWriter);
         layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
         layer->setZOrder(10);
         layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode));
@@ -550,7 +552,7 @@
 
         auto deviceLayer = std::make_shared<TestBufferLayer>(
                 mComposerClient, *mTestRenderEngine, getPrimaryDisplayId(), getDisplayWidth(),
-                getDisplayHeight() / 2, PixelFormat::RGBA_8888);
+                getDisplayHeight() / 2, PixelFormat::RGBA_8888, *mWriter);
         std::vector<Color> deviceColors(deviceLayer->getWidth() * deviceLayer->getHeight());
         ReadbackHelper::fillColorsArea(deviceColors, static_cast<int32_t>(deviceLayer->getWidth()),
                                        {0, 0, static_cast<int32_t>(deviceLayer->getWidth()),
@@ -574,7 +576,7 @@
 
         auto clientLayer = std::make_shared<TestBufferLayer>(
                 mComposerClient, *mTestRenderEngine, getPrimaryDisplayId(), clientWidth,
-                clientHeight, PixelFormat::RGBA_FP16, Composition::DEVICE);
+                clientHeight, PixelFormat::RGBA_FP16, *mWriter, Composition::DEVICE);
         common::Rect clientFrame = {0, getDisplayHeight() / 2, getDisplayWidth(),
                                     getDisplayHeight()};
         clientLayer->setDisplayFrame(clientFrame);
@@ -643,9 +645,9 @@
                 static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
         ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(), redRect, RED);
 
-        auto layer = std::make_shared<TestBufferLayer>(mComposerClient, *mTestRenderEngine,
-                                                       getPrimaryDisplayId(), getDisplayWidth(),
-                                                       getDisplayHeight(), PixelFormat::RGBA_8888);
+        auto layer = std::make_shared<TestBufferLayer>(
+                mComposerClient, *mTestRenderEngine, getPrimaryDisplayId(), getDisplayWidth(),
+                getDisplayHeight(), PixelFormat::RGBA_8888, *mWriter);
         layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
         layer->setZOrder(10);
         layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode));
@@ -714,7 +716,8 @@
             return;
         }
 
-        auto layer = std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId());
+        auto layer =
+                std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId(), *mWriter);
         layer->setColor(RED);
         layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
         layer->setZOrder(10);
@@ -774,9 +777,9 @@
                 expectedColors, getDisplayWidth(),
                 {0, getDisplayHeight() / 2, getDisplayWidth(), getDisplayHeight()}, BLUE);
 
-        auto layer = std::make_shared<TestBufferLayer>(mComposerClient, *mTestRenderEngine,
-                                                       getPrimaryDisplayId(), getDisplayWidth(),
-                                                       getDisplayHeight(), PixelFormat::RGBA_8888);
+        auto layer = std::make_shared<TestBufferLayer>(
+                mComposerClient, *mTestRenderEngine, getPrimaryDisplayId(), getDisplayWidth(),
+                getDisplayHeight(), PixelFormat::RGBA_8888, *mWriter);
         layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
         layer->setZOrder(10);
         layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode));
@@ -828,11 +831,13 @@
 
         common::Rect redRect = {0, 0, getDisplayWidth(), getDisplayHeight() / 2};
         common::Rect blueRect = {0, getDisplayHeight() / 4, getDisplayWidth(), getDisplayHeight()};
-        auto redLayer = std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId());
+        auto redLayer =
+                std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId(), *mWriter);
         redLayer->setColor(RED);
         redLayer->setDisplayFrame(redRect);
 
-        auto blueLayer = std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId());
+        auto blueLayer =
+                std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId(), *mWriter);
         blueLayer->setColor(BLUE);
         blueLayer->setDisplayFrame(blueRect);
         blueLayer->setZOrder(5);
@@ -914,14 +919,14 @@
         static constexpr float kMaxBrightnessNits = 300.f;
 
         const auto redLayer =
-                std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId());
+                std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId(), *mWriter);
         redLayer->setColor(RED);
         redLayer->setDisplayFrame(redRect);
         redLayer->setWhitePointNits(kMaxBrightnessNits);
         redLayer->setBrightness(1.f);
 
         const auto dimmerRedLayer =
-                std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId());
+                std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId(), *mWriter);
         dimmerRedLayer->setColor(RED);
         dimmerRedLayer->setDisplayFrame(dimmerRedRect);
         // Intentionally use a small dimming ratio as some implementations may be more likely to
@@ -992,14 +997,14 @@
                                        mTopLayerColor);
 
         auto backgroundLayer =
-                std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId());
+                std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId(), *mWriter);
         backgroundLayer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
         backgroundLayer->setZOrder(0);
         backgroundLayer->setColor(mBackgroundColor);
 
-        auto layer = std::make_shared<TestBufferLayer>(mComposerClient, *mTestRenderEngine,
-                                                       getPrimaryDisplayId(), getDisplayWidth(),
-                                                       getDisplayHeight(), PixelFormat::RGBA_8888);
+        auto layer = std::make_shared<TestBufferLayer>(
+                mComposerClient, *mTestRenderEngine, getPrimaryDisplayId(), getDisplayWidth(),
+                getDisplayHeight(), PixelFormat::RGBA_8888, *mWriter);
         layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
         layer->setZOrder(10);
         layer->setDataspace(Dataspace::UNKNOWN);
@@ -1190,7 +1195,7 @@
         GraphicsCompositionTest::SetUp();
 
         auto backgroundLayer =
-                std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId());
+                std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId(), *mWriter);
         backgroundLayer->setColor({0.0f, 0.0f, 0.0f, 0.0f});
         backgroundLayer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
         backgroundLayer->setZOrder(0);
@@ -1202,7 +1207,7 @@
 
         mLayer = std::make_shared<TestBufferLayer>(mComposerClient, *mTestRenderEngine,
                                                    getPrimaryDisplayId(), mSideLength, mSideLength,
-                                                   PixelFormat::RGBA_8888);
+                                                   PixelFormat::RGBA_8888, *mWriter);
         mLayer->setDisplayFrame({0, 0, mSideLength, mSideLength});
         mLayer->setZOrder(10);
 
@@ -1388,7 +1393,7 @@
     void makeLayer() {
         mLayer = std::make_shared<TestBufferLayer>(
                 mComposerClient, *mTestRenderEngine, getPrimaryDisplayId(), getDisplayWidth(),
-                getDisplayHeight(), common::PixelFormat::RGBA_8888);
+                getDisplayHeight(), common::PixelFormat::RGBA_8888, *mWriter);
         mLayer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
         mLayer->setZOrder(10);
         mLayer->setAlpha(1.f);
diff --git a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
index 086d290..d250562 100644
--- a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
+++ b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
@@ -70,7 +70,7 @@
     }
 
     void TearDown() override {
-        ASSERT_TRUE(mComposerClient->tearDown());
+        ASSERT_TRUE(mComposerClient->tearDown(nullptr));
         mComposerClient.reset();
     }
 
@@ -832,36 +832,58 @@
 }
 
 TEST_P(GraphicsComposerAidlTest, CreateLayer) {
+    if (hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
+        GTEST_SKIP() << "Create layer will be tested in GraphicsComposerAidlBatchedCommandTest";
+        return;
+    }
+
     const auto& [status, layer] =
-            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, nullptr);
 
     EXPECT_TRUE(status.isOk());
-    EXPECT_TRUE(mComposerClient->destroyLayer(getPrimaryDisplayId(), layer).isOk());
+    EXPECT_TRUE(mComposerClient->destroyLayer(getPrimaryDisplayId(), layer, nullptr).isOk());
 }
 
 TEST_P(GraphicsComposerAidlTest, CreateLayer_BadDisplay) {
-    const auto& [status, _] = mComposerClient->createLayer(getInvalidDisplayId(), kBufferSlotCount);
+    if (hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
+        GTEST_SKIP() << "Create layer will be tested in GraphicsComposerAidlBatchedCommandTest";
+        return;
+    }
+
+    const auto& [status, _] =
+            mComposerClient->createLayer(getInvalidDisplayId(), kBufferSlotCount, nullptr);
 
     EXPECT_FALSE(status.isOk());
     EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
 }
 
 TEST_P(GraphicsComposerAidlTest, DestroyLayer_BadDisplay) {
+    if (hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
+        GTEST_SKIP() << "Destroy layer will be tested in GraphicsComposerAidlBatchedCommandTest";
+        return;
+    }
+
     const auto& [status, layer] =
-            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, nullptr);
     EXPECT_TRUE(status.isOk());
 
-    const auto& destroyStatus = mComposerClient->destroyLayer(getInvalidDisplayId(), layer);
+    const auto& destroyStatus =
+            mComposerClient->destroyLayer(getInvalidDisplayId(), layer, nullptr);
 
     EXPECT_FALSE(destroyStatus.isOk());
     EXPECT_NO_FATAL_FAILURE(
             assertServiceSpecificError(destroyStatus, IComposerClient::EX_BAD_DISPLAY));
-    ASSERT_TRUE(mComposerClient->destroyLayer(getPrimaryDisplayId(), layer).isOk());
+    ASSERT_TRUE(mComposerClient->destroyLayer(getPrimaryDisplayId(), layer, nullptr).isOk());
 }
 
 TEST_P(GraphicsComposerAidlTest, DestroyLayer_BadLayerError) {
+    if (hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
+        GTEST_SKIP() << "Destroy layer will be tested in GraphicsComposerAidlBatchedCommandTest";
+        return;
+    }
+
     // We haven't created any layers yet, so any id should be invalid
-    const auto& status = mComposerClient->destroyLayer(getPrimaryDisplayId(), /*layer*/ 1);
+    const auto& status = mComposerClient->destroyLayer(getPrimaryDisplayId(), /*layer*/ 1, nullptr);
 
     EXPECT_FALSE(status.isOk());
     EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_LAYER));
@@ -1171,6 +1193,12 @@
     }
 }
 
+TEST_P(GraphicsComposerAidlTest, LayerLifecycleCapabilityNotSupportedOnOldVersions) {
+    if (hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
+        EXPECT_GE(getInterfaceVersion(), 3);
+    }
+}
+
 class GraphicsComposerAidlV2Test : public GraphicsComposerAidlTest {
   protected:
     void SetUp() override {
@@ -1376,6 +1404,7 @@
         ASSERT_TRUE(mReader.takeErrors().empty());
         ASSERT_TRUE(mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty());
 
+        ASSERT_TRUE(mComposerClient->tearDown(&getWriter(getPrimaryDisplayId())));
         ASSERT_NO_FATAL_FAILURE(GraphicsComposerAidlTest::TearDown());
     }
 
@@ -1463,10 +1492,10 @@
                                            RenderIntent::COLORIMETRIC)
                             .isOk());
 
-        const auto& [status, layer] =
-                mComposerClient->createLayer(display.getDisplayId(), kBufferSlotCount);
-        EXPECT_TRUE(status.isOk());
         auto& writer = getWriter(display.getDisplayId());
+        const auto& [status, layer] =
+                mComposerClient->createLayer(display.getDisplayId(), kBufferSlotCount, &writer);
+        EXPECT_TRUE(status.isOk());
         {
             const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
             ASSERT_NE(nullptr, buffer);
@@ -1506,7 +1535,7 @@
             execute();
         }
 
-        EXPECT_TRUE(mComposerClient->destroyLayer(display.getDisplayId(), layer).isOk());
+        EXPECT_TRUE(mComposerClient->destroyLayer(display.getDisplayId(), layer, &writer).isOk());
     }
 
     sp<::android::Fence> presentAndGetFence(
@@ -1541,15 +1570,16 @@
     }
 
     int64_t createOnScreenLayer(Composition composition = Composition::DEVICE) {
+        auto& writer = getWriter(getPrimaryDisplayId());
         const auto& [status, layer] =
-                mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+                mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
         EXPECT_TRUE(status.isOk());
         Rect displayFrame{0, 0, getPrimaryDisplay().getDisplayWidth(),
                           getPrimaryDisplay().getDisplayHeight()};
         FRect cropRect{0, 0, (float)getPrimaryDisplay().getDisplayWidth(),
                        (float)getPrimaryDisplay().getDisplayHeight()};
         configureLayer(getPrimaryDisplay(), layer, composition, displayFrame, cropRect);
-        auto& writer = getWriter(getPrimaryDisplayId());
+
         writer.setLayerDataspace(getPrimaryDisplayId(), layer, common::Dataspace::UNKNOWN);
         return layer;
     }
@@ -1758,10 +1788,10 @@
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SetLayerColorTransform) {
-    const auto& [status, layer] =
-            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
-    EXPECT_TRUE(status.isOk());
     auto& writer = getWriter(getPrimaryDisplayId());
+    const auto& [status, layer] =
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
+    EXPECT_TRUE(status.isOk());
     writer.setLayerColorTransform(getPrimaryDisplayId(), layer, kIdentity.data());
     execute();
 
@@ -1900,7 +1930,7 @@
         ASSERT_NE(nullptr, handle);
 
         const auto& [layerStatus, layer] =
-                mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+                mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
         EXPECT_TRUE(layerStatus.isOk());
 
         Rect displayFrame{0, 0, getPrimaryDisplay().getDisplayWidth(),
@@ -1937,15 +1967,15 @@
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SetLayerCursorPosition) {
+    auto& writer = getWriter(getPrimaryDisplayId());
     const auto& [layerStatus, layer] =
-            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
     EXPECT_TRUE(layerStatus.isOk());
 
     const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
     const auto handle = buffer->handle;
     ASSERT_NE(nullptr, handle);
 
-    auto& writer = getWriter(getPrimaryDisplayId());
     writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle, /*acquireFence*/ -1);
 
     Rect displayFrame{0, 0, getPrimaryDisplay().getDisplayWidth(),
@@ -1981,19 +2011,19 @@
     const auto handle = buffer->handle;
     ASSERT_NE(nullptr, handle);
 
-    const auto& [layerStatus, layer] =
-            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
-    EXPECT_TRUE(layerStatus.isOk());
     auto& writer = getWriter(getPrimaryDisplayId());
+    const auto& [layerStatus, layer] =
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
+    EXPECT_TRUE(layerStatus.isOk());
     writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle, /*acquireFence*/ -1);
     execute();
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SetLayerBufferMultipleTimes) {
-    const auto& [layerStatus, layer] =
-            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
-    EXPECT_TRUE(layerStatus.isOk());
     auto& writer = getWriter(getPrimaryDisplayId());
+    const auto& [layerStatus, layer] =
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
+    EXPECT_TRUE(layerStatus.isOk());
 
     // Setup 3 buffers in the buffer cache, with the last buffer being active. Then, emulate the
     // Android platform code that clears all 3 buffer slots by setting all but the active buffer
@@ -2041,14 +2071,14 @@
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SetLayerSurfaceDamage) {
+    auto& writer = getWriter(getPrimaryDisplayId());
     const auto& [layerStatus, layer] =
-            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
     EXPECT_TRUE(layerStatus.isOk());
 
     Rect empty{0, 0, 0, 0};
     Rect unit{0, 0, 1, 1};
 
-    auto& writer = getWriter(getPrimaryDisplayId());
     writer.setLayerSurfaceDamage(getPrimaryDisplayId(), layer, std::vector<Rect>(1, empty));
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
@@ -2063,14 +2093,14 @@
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SetLayerBlockingRegion) {
+    auto& writer = getWriter(getPrimaryDisplayId());
     const auto& [layerStatus, layer] =
-            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
     EXPECT_TRUE(layerStatus.isOk());
 
     Rect empty{0, 0, 0, 0};
     Rect unit{0, 0, 1, 1};
 
-    auto& writer = getWriter(getPrimaryDisplayId());
     writer.setLayerBlockingRegion(getPrimaryDisplayId(), layer, std::vector<Rect>(1, empty));
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
@@ -2085,11 +2115,11 @@
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SetLayerBlendMode) {
+    auto& writer = getWriter(getPrimaryDisplayId());
     const auto& [layerStatus, layer] =
-            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
     EXPECT_TRUE(layerStatus.isOk());
 
-    auto& writer = getWriter(getPrimaryDisplayId());
     writer.setLayerBlendMode(getPrimaryDisplayId(), layer, BlendMode::NONE);
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
@@ -2104,11 +2134,11 @@
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SetLayerColor) {
+    auto& writer = getWriter(getPrimaryDisplayId());
     const auto& [layerStatus, layer] =
-            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
     EXPECT_TRUE(layerStatus.isOk());
 
-    auto& writer = getWriter(getPrimaryDisplayId());
     writer.setLayerColor(getPrimaryDisplayId(), layer, Color{1.0f, 1.0f, 1.0f, 1.0f});
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
@@ -2119,11 +2149,11 @@
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SetLayerCompositionType) {
+    auto& writer = getWriter(getPrimaryDisplayId());
     const auto& [layerStatus, layer] =
-            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
     EXPECT_TRUE(layerStatus.isOk());
 
-    auto& writer = getWriter(getPrimaryDisplayId());
     writer.setLayerCompositionType(getPrimaryDisplayId(), layer, Composition::CLIENT);
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
@@ -2142,8 +2172,9 @@
 
 TEST_P(GraphicsComposerAidlCommandTest, DisplayDecoration) {
     for (VtsDisplay& display : mDisplays) {
+        auto& writer = getWriter(display.getDisplayId());
         const auto [layerStatus, layer] =
-                mComposerClient->createLayer(display.getDisplayId(), kBufferSlotCount);
+                mComposerClient->createLayer(display.getDisplayId(), kBufferSlotCount, &writer);
         EXPECT_TRUE(layerStatus.isOk());
 
         const auto [error, support] =
@@ -2166,8 +2197,7 @@
         }
 
         configureLayer(display, layer, Composition::DISPLAY_DECORATION, display.getFrameRect(),
-                          display.getCrop());
-        auto& writer = getWriter(display.getDisplayId());
+                       display.getCrop());
         writer.setLayerBuffer(display.getDisplayId(), layer, /*slot*/ 0, decorBuffer->handle,
                               /*acquireFence*/ -1);
         writer.validateDisplay(display.getDisplayId(), ComposerClientWriter::kNoTimestamp,
@@ -2184,31 +2214,31 @@
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SetLayerDataspace) {
+    auto& writer = getWriter(getPrimaryDisplayId());
     const auto& [layerStatus, layer] =
-            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
     EXPECT_TRUE(layerStatus.isOk());
 
-    auto& writer = getWriter(getPrimaryDisplayId());
     writer.setLayerDataspace(getPrimaryDisplayId(), layer, Dataspace::UNKNOWN);
     execute();
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SetLayerDisplayFrame) {
+    auto& writer = getWriter(getPrimaryDisplayId());
     const auto& [layerStatus, layer] =
-            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
     EXPECT_TRUE(layerStatus.isOk());
 
-    auto& writer = getWriter(getPrimaryDisplayId());
     writer.setLayerDisplayFrame(getPrimaryDisplayId(), layer, Rect{0, 0, 1, 1});
     execute();
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SetLayerPlaneAlpha) {
+    auto& writer = getWriter(getPrimaryDisplayId());
     const auto& [layerStatus, layer] =
-            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
     EXPECT_TRUE(layerStatus.isOk());
 
-    auto& writer = getWriter(getPrimaryDisplayId());
     writer.setLayerPlaneAlpha(getPrimaryDisplayId(), layer, /*alpha*/ 0.0f);
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
@@ -2228,31 +2258,31 @@
     const auto handle = buffer->handle;
     ASSERT_NE(nullptr, handle);
 
+    auto& writer = getWriter(getPrimaryDisplayId());
     const auto& [layerStatus, layer] =
-            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
     EXPECT_TRUE(layerStatus.isOk());
 
-    auto& writer = getWriter(getPrimaryDisplayId());
     writer.setLayerSidebandStream(getPrimaryDisplayId(), layer, handle);
     execute();
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SetLayerSourceCrop) {
+    auto& writer = getWriter(getPrimaryDisplayId());
     const auto& [layerStatus, layer] =
-            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
     EXPECT_TRUE(layerStatus.isOk());
 
-    auto& writer = getWriter(getPrimaryDisplayId());
     writer.setLayerSourceCrop(getPrimaryDisplayId(), layer, FRect{0.0f, 0.0f, 1.0f, 1.0f});
     execute();
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SetLayerTransform) {
+    auto& writer = getWriter(getPrimaryDisplayId());
     const auto& [layerStatus, layer] =
-            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
     EXPECT_TRUE(layerStatus.isOk());
 
-    auto& writer = getWriter(getPrimaryDisplayId());
     writer.setLayerTransform(getPrimaryDisplayId(), layer, static_cast<Transform>(0));
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
@@ -2291,14 +2321,14 @@
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SetLayerVisibleRegion) {
+    auto& writer = getWriter(getPrimaryDisplayId());
     const auto& [layerStatus, layer] =
-            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
     EXPECT_TRUE(layerStatus.isOk());
 
     Rect empty{0, 0, 0, 0};
     Rect unit{0, 0, 1, 1};
 
-    auto& writer = getWriter(getPrimaryDisplayId());
     writer.setLayerVisibleRegion(getPrimaryDisplayId(), layer, std::vector<Rect>(1, empty));
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
@@ -2313,11 +2343,12 @@
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SetLayerZOrder) {
+    auto& writer = getWriter(getPrimaryDisplayId());
+
     const auto& [layerStatus, layer] =
-            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
     EXPECT_TRUE(layerStatus.isOk());
 
-    auto& writer = getWriter(getPrimaryDisplayId());
     writer.setLayerZOrder(getPrimaryDisplayId(), layer, /*z*/ 10);
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
@@ -2328,8 +2359,9 @@
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SetLayerPerFrameMetadata) {
+    auto& writer = getWriter(getPrimaryDisplayId());
     const auto& [layerStatus, layer] =
-            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
     EXPECT_TRUE(layerStatus.isOk());
 
     /**
@@ -2344,7 +2376,6 @@
      *  white (D65)     0.3127  0.3290
      */
 
-    auto& writer = getWriter(getPrimaryDisplayId());
     std::vector<PerFrameMetadata> aidlMetadata;
     aidlMetadata.push_back({PerFrameMetadataKey::DISPLAY_RED_PRIMARY_X, 0.680f});
     aidlMetadata.push_back({PerFrameMetadataKey::DISPLAY_RED_PRIMARY_Y, 0.320f});
@@ -2364,18 +2395,19 @@
     const auto errors = mReader.takeErrors();
     if (errors.size() == 1 && errors[0].errorCode == EX_UNSUPPORTED_OPERATION) {
         GTEST_SUCCEED() << "SetLayerPerFrameMetadata is not supported";
-        EXPECT_TRUE(mComposerClient->destroyLayer(getPrimaryDisplayId(), layer).isOk());
+        EXPECT_TRUE(mComposerClient->destroyLayer(getPrimaryDisplayId(), layer, &writer).isOk());
         return;
     }
 
-    EXPECT_TRUE(mComposerClient->destroyLayer(getPrimaryDisplayId(), layer).isOk());
+    EXPECT_TRUE(mComposerClient->destroyLayer(getPrimaryDisplayId(), layer, &writer).isOk());
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, setLayerBrightness) {
-    const auto& [layerStatus, layer] =
-            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
-
     auto& writer = getWriter(getPrimaryDisplayId());
+
+    const auto& [layerStatus, layer] =
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
+
     writer.setLayerBrightness(getPrimaryDisplayId(), layer, 0.2f);
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
@@ -2604,12 +2636,12 @@
 }
 
 TEST_P(GraphicsComposerAidlCommandV2Test, SetLayerBufferSlotsToClear) {
+    auto& writer = getWriter(getPrimaryDisplayId());
     // Older HAL versions use a backwards compatible way of clearing buffer slots
     // HAL at version 1 or lower does not have LayerCommand::bufferSlotsToClear
     const auto& [layerStatus, layer] =
-            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
     EXPECT_TRUE(layerStatus.isOk());
-    auto& writer = getWriter(getPrimaryDisplayId());
 
     // setup 3 buffers in the buffer cache, with the last buffer being active
     // then emulate the Android platform code that clears all 3 buffer slots
@@ -2868,7 +2900,8 @@
 
         EXPECT_TRUE(mComposerClient->setPowerMode(displayId, PowerMode::ON).isOk());
 
-        const auto& [status, layer] = mComposerClient->createLayer(displayId, kBufferSlotCount);
+        const auto& [status, layer] =
+                mComposerClient->createLayer(displayId, kBufferSlotCount, &writer);
         const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
         ASSERT_NE(nullptr, buffer);
         ASSERT_EQ(::android::OK, buffer->initCheck());
@@ -2918,7 +2951,8 @@
     }
 
     for (auto& [displayId, layer] : layers) {
-        EXPECT_TRUE(mComposerClient->destroyLayer(displayId, layer).isOk());
+        auto& writer = getWriter(displayId);
+        EXPECT_TRUE(mComposerClient->destroyLayer(displayId, layer, &writer).isOk());
     }
 
     std::lock_guard guard{readersMutex};
@@ -2928,22 +2962,22 @@
     }
 }
 
-class GraphicsComposerAidlBatchedCommandTest : public GraphicsComposerAidlCommandTest {
+class GraphicsComposerAidlCommandV3Test : public GraphicsComposerAidlCommandTest {
   protected:
     void SetUp() override {
-        GraphicsComposerAidlCommandTest::SetUp();
+        GraphicsComposerAidlTest::SetUp();
         if (getInterfaceVersion() <= 2) {
             GTEST_SKIP() << "Device interface version is expected to be >= 3";
         }
     }
-    void TearDown() override {
-        const auto errors = mReader.takeErrors();
-        ASSERT_TRUE(mReader.takeErrors().empty());
-        ASSERT_NO_FATAL_FAILURE(GraphicsComposerAidlTest::TearDown());
-    }
 };
 
-TEST_P(GraphicsComposerAidlBatchedCommandTest, CreateBatchedCommand) {
+TEST_P(GraphicsComposerAidlCommandV3Test, CreateBatchedCommand) {
+    if (!hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
+        GTEST_SKIP() << "LAYER_LIFECYCLE_BATCH_COMMAND not supported by the implementation";
+        return;
+    }
+
     auto& writer = getWriter(getPrimaryDisplayId());
     int64_t layer = 5;
     writer.setLayerLifecycleBatchCommandType(getPrimaryDisplayId(), layer,
@@ -2955,7 +2989,30 @@
     ASSERT_TRUE(mReader.takeErrors().empty());
 }
 
-TEST_P(GraphicsComposerAidlBatchedCommandTest, DestroyBatchedCommand) {
+TEST_P(GraphicsComposerAidlCommandV3Test, CreateBatchedCommand_BadDisplay) {
+    if (!hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
+        GTEST_SKIP() << "LAYER_LIFECYCLE_BATCH_COMMAND not supported by the implementation";
+        return;
+    }
+
+    auto& writer = getWriter(getPrimaryDisplayId());
+    int64_t layer = 5;
+    writer.setLayerLifecycleBatchCommandType(getInvalidDisplayId(), layer,
+                                             LayerLifecycleBatchCommandType::CREATE);
+    writer.setNewBufferSlotCount(getPrimaryDisplayId(), layer, 1);
+    writer.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
+                           VtsComposerClient::kNoFrameIntervalNs);
+    execute();
+    const auto errors = mReader.takeErrors();
+    ASSERT_TRUE(errors.size() == 1 && errors[0].errorCode == IComposerClient::EX_BAD_DISPLAY);
+}
+
+TEST_P(GraphicsComposerAidlCommandV3Test, DestroyBatchedCommand) {
+    if (!hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
+        GTEST_SKIP() << "LAYER_LIFECYCLE_BATCH_COMMAND not supported by the implementation";
+        return;
+    }
+
     auto& writer = getWriter(getPrimaryDisplayId());
     int64_t layer = 5;
     writer.setLayerLifecycleBatchCommandType(getPrimaryDisplayId(), layer,
@@ -2973,10 +3030,42 @@
     writer.setNewBufferSlotCount(getPrimaryDisplayId(), layer, 1);
 
     execute();
+    const auto errors = mReader.takeErrors();
+    ASSERT_TRUE(errors.size() == 1 && errors[0].errorCode == IComposerClient::EX_BAD_DISPLAY);
+}
+
+TEST_P(GraphicsComposerAidlCommandV3Test, DestroyBatchedCommand_BadDisplay) {
+    if (!hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
+        GTEST_SKIP() << "LAYER_LIFECYCLE_BATCH_COMMAND not supported by the implementation";
+        return;
+    }
+
+    auto& writer = getWriter(getPrimaryDisplayId());
+    int64_t layer = 5;
+    writer.setLayerLifecycleBatchCommandType(getPrimaryDisplayId(), layer,
+                                             LayerLifecycleBatchCommandType::CREATE);
+    writer.setNewBufferSlotCount(getPrimaryDisplayId(), layer, 1);
+    writer.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
+                           VtsComposerClient::kNoFrameIntervalNs);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+    writer.setLayerLifecycleBatchCommandType(getInvalidDisplayId(), layer,
+                                             LayerLifecycleBatchCommandType::DESTROY);
+    layer++;
+    writer.setLayerLifecycleBatchCommandType(getInvalidDisplayId(), layer,
+                                             LayerLifecycleBatchCommandType::CREATE);
+    writer.setNewBufferSlotCount(getPrimaryDisplayId(), layer, 1);
+
+    execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
 }
 
-TEST_P(GraphicsComposerAidlBatchedCommandTest, NoCreateDestroyBatchedCommandIncorrectLayer) {
+TEST_P(GraphicsComposerAidlCommandV3Test, NoCreateDestroyBatchedCommandIncorrectLayer) {
+    if (!hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
+        GTEST_SKIP() << "LAYER_LIFECYCLE_BATCH_COMMAND not supported by the implementation";
+        return;
+    }
+
     auto& writer = getWriter(getPrimaryDisplayId());
     int64_t layer = 5;
     writer.setLayerLifecycleBatchCommandType(getPrimaryDisplayId(), layer,
@@ -2986,11 +3075,6 @@
     ASSERT_TRUE(errors.size() == 1 && errors[0].errorCode == IComposerClient::EX_BAD_LAYER);
 }
 
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerAidlBatchedCommandTest);
-INSTANTIATE_TEST_SUITE_P(
-        PerInstance, GraphicsComposerAidlBatchedCommandTest,
-        testing::ValuesIn(::android::getAidlHalInstanceNames(IComposer::descriptor)),
-        ::android::PrintInstanceNameToString);
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerAidlCommandTest);
 INSTANTIATE_TEST_SUITE_P(
         PerInstance, GraphicsComposerAidlCommandTest,
@@ -3016,6 +3100,11 @@
         PerInstance, GraphicsComposerAidlCommandV2Test,
         testing::ValuesIn(::android::getAidlHalInstanceNames(IComposer::descriptor)),
         ::android::PrintInstanceNameToString);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerAidlCommandV3Test);
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, GraphicsComposerAidlCommandV3Test,
+        testing::ValuesIn(::android::getAidlHalInstanceNames(IComposer::descriptor)),
+        ::android::PrintInstanceNameToString);
 }  // namespace aidl::android::hardware::graphics::composer3::vts
 
 int main(int argc, char** argv) {
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 75e436d..23de7b9 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
@@ -87,7 +87,7 @@
  *
  * Vendor-provided metadata should be prefixed with a "vendor.mycompanyname.*" namespace. It is
  * recommended that the metadata follows the pattern of StandardMetadaType.aidl. That is, an
- * aidl-defined enum with @VendorStability on it and the naming then matching that type such
+ * aidl-defined enum with @VintfStability on it and the naming then matching that type such
  * as "vendor.mycompanyname.graphics.common.MetadataType" with the value field then set to the
  * aidl's enum value.
  *
diff --git a/nfc/aidl/default/Android.bp b/nfc/aidl/default/Android.bp
deleted file mode 100644
index 0cda51d..0000000
--- a/nfc/aidl/default/Android.bp
+++ /dev/null
@@ -1,33 +0,0 @@
-package {
-    default_team: "trendy_team_fwk_nfc",
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "hardware_interfaces_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["hardware_interfaces_license"],
-}
-
-cc_binary {
-    name: "android.hardware.nfc-service.example",
-    relative_install_path: "hw",
-    init_rc: ["nfc-service-example.rc"],
-    vintf_fragments: ["nfc-service-example.xml"],
-    vendor: true,
-    cflags: [
-        "-Wall",
-        "-Wextra",
-    ],
-    shared_libs: [
-        "libbase",
-        "liblog",
-        "libutils",
-        "libbinder_ndk",
-        "android.hardware.nfc-V1-ndk",
-    ],
-    srcs: [
-        "main.cpp",
-        "Nfc.cpp",
-        "Vendor_hal_api.cpp",
-    ],
-}
diff --git a/nfc/aidl/default/Nfc.cpp b/nfc/aidl/default/Nfc.cpp
deleted file mode 100644
index 4685b59..0000000
--- a/nfc/aidl/default/Nfc.cpp
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "Nfc.h"
-
-#include <android-base/logging.h>
-
-#include "Vendor_hal_api.h"
-
-namespace aidl {
-namespace android {
-namespace hardware {
-namespace nfc {
-
-std::shared_ptr<INfcClientCallback> Nfc::mCallback = nullptr;
-AIBinder_DeathRecipient* clientDeathRecipient = nullptr;
-
-void OnDeath(void* cookie) {
-    if (Nfc::mCallback != nullptr && !AIBinder_isAlive(Nfc::mCallback->asBinder().get())) {
-        LOG(INFO) << __func__ << " Nfc service has died";
-        Nfc* nfc = static_cast<Nfc*>(cookie);
-        nfc->close(NfcCloseType::DISABLE);
-    }
-}
-
-::ndk::ScopedAStatus Nfc::open(const std::shared_ptr<INfcClientCallback>& clientCallback) {
-    LOG(INFO) << "open";
-    if (clientCallback == nullptr) {
-        LOG(INFO) << "Nfc::open null callback";
-        return ndk::ScopedAStatus::fromServiceSpecificError(
-                static_cast<int32_t>(NfcStatus::FAILED));
-    }
-    Nfc::mCallback = clientCallback;
-
-    clientDeathRecipient = AIBinder_DeathRecipient_new(OnDeath);
-    auto linkRet = AIBinder_linkToDeath(clientCallback->asBinder().get(), clientDeathRecipient,
-                                        this /* cookie */);
-    if (linkRet != STATUS_OK) {
-        LOG(ERROR) << __func__ << ": linkToDeath failed: " << linkRet;
-        // Just ignore the error.
-    }
-
-    int ret = Vendor_hal_open(eventCallback, dataCallback);
-    return ret == 0 ? ndk::ScopedAStatus::ok()
-                    : ndk::ScopedAStatus::fromServiceSpecificError(
-                              static_cast<int32_t>(NfcStatus::FAILED));
-}
-
-::ndk::ScopedAStatus Nfc::close(NfcCloseType type) {
-    LOG(INFO) << "close";
-    if (Nfc::mCallback == nullptr) {
-        LOG(ERROR) << __func__ << "mCallback null";
-        return ndk::ScopedAStatus::fromServiceSpecificError(
-                static_cast<int32_t>(NfcStatus::FAILED));
-    }
-    int ret = 0;
-    if (type == NfcCloseType::HOST_SWITCHED_OFF) {
-        ret = Vendor_hal_close_off();
-    } else {
-        ret = Vendor_hal_close();
-    }
-    Nfc::mCallback = nullptr;
-    AIBinder_DeathRecipient_delete(clientDeathRecipient);
-    clientDeathRecipient = nullptr;
-    return ret == 0 ? ndk::ScopedAStatus::ok()
-                    : ndk::ScopedAStatus::fromServiceSpecificError(
-                              static_cast<int32_t>(NfcStatus::FAILED));
-}
-
-::ndk::ScopedAStatus Nfc::coreInitialized() {
-    LOG(INFO) << "coreInitialized";
-    if (Nfc::mCallback == nullptr) {
-        LOG(ERROR) << __func__ << "mCallback null";
-        return ndk::ScopedAStatus::fromServiceSpecificError(
-                static_cast<int32_t>(NfcStatus::FAILED));
-    }
-    int ret = Vendor_hal_core_initialized();
-
-    return ret == 0 ? ndk::ScopedAStatus::ok()
-                    : ndk::ScopedAStatus::fromServiceSpecificError(
-                              static_cast<int32_t>(NfcStatus::FAILED));
-}
-
-::ndk::ScopedAStatus Nfc::factoryReset() {
-    LOG(INFO) << "factoryReset";
-    Vendor_hal_factoryReset();
-    return ndk::ScopedAStatus::ok();
-}
-
-::ndk::ScopedAStatus Nfc::getConfig(NfcConfig* _aidl_return) {
-    LOG(INFO) << "getConfig";
-    NfcConfig nfcVendorConfig;
-    Vendor_hal_getConfig(nfcVendorConfig);
-
-    *_aidl_return = nfcVendorConfig;
-    return ndk::ScopedAStatus::ok();
-}
-
-::ndk::ScopedAStatus Nfc::powerCycle() {
-    LOG(INFO) << "powerCycle";
-    if (Nfc::mCallback == nullptr) {
-        LOG(ERROR) << __func__ << "mCallback null";
-        return ndk::ScopedAStatus::fromServiceSpecificError(
-                static_cast<int32_t>(NfcStatus::FAILED));
-    }
-    return Vendor_hal_power_cycle() ? ndk::ScopedAStatus::fromServiceSpecificError(
-                                              static_cast<int32_t>(NfcStatus::FAILED))
-                                    : ndk::ScopedAStatus::ok();
-}
-
-::ndk::ScopedAStatus Nfc::preDiscover() {
-    LOG(INFO) << "preDiscover";
-    if (Nfc::mCallback == nullptr) {
-        LOG(ERROR) << __func__ << "mCallback null";
-        return ndk::ScopedAStatus::fromServiceSpecificError(
-                static_cast<int32_t>(NfcStatus::FAILED));
-    }
-    return Vendor_hal_pre_discover() ? ndk::ScopedAStatus::fromServiceSpecificError(
-                                               static_cast<int32_t>(NfcStatus::FAILED))
-                                     : ndk::ScopedAStatus::ok();
-}
-
-::ndk::ScopedAStatus Nfc::write(const std::vector<uint8_t>& data, int32_t* _aidl_return) {
-    LOG(INFO) << "write";
-    if (Nfc::mCallback == nullptr) {
-        LOG(ERROR) << __func__ << "mCallback null";
-        return ndk::ScopedAStatus::fromServiceSpecificError(
-                static_cast<int32_t>(NfcStatus::FAILED));
-    }
-    *_aidl_return = Vendor_hal_write(data.size(), &data[0]);
-    return ndk::ScopedAStatus::ok();
-}
-::ndk::ScopedAStatus Nfc::setEnableVerboseLogging(bool enable) {
-    LOG(INFO) << "setVerboseLogging";
-    Vendor_hal_setVerboseLogging(enable);
-    return ndk::ScopedAStatus::ok();
-}
-
-::ndk::ScopedAStatus Nfc::isVerboseLoggingEnabled(bool* _aidl_return) {
-    *_aidl_return = Vendor_hal_getVerboseLogging();
-    return ndk::ScopedAStatus::ok();
-}
-
-}  // namespace nfc
-}  // namespace hardware
-}  // namespace android
-}  // namespace aidl
diff --git a/nfc/aidl/default/Nfc.h b/nfc/aidl/default/Nfc.h
deleted file mode 100644
index 1b14534..0000000
--- a/nfc/aidl/default/Nfc.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <aidl/android/hardware/nfc/BnNfc.h>
-#include <aidl/android/hardware/nfc/INfcClientCallback.h>
-#include <android-base/logging.h>
-namespace aidl {
-namespace android {
-namespace hardware {
-namespace nfc {
-
-using ::aidl::android::hardware::nfc::NfcCloseType;
-using ::aidl::android::hardware::nfc::NfcConfig;
-using ::aidl::android::hardware::nfc::NfcStatus;
-
-// Default implementation that reports no support NFC.
-struct Nfc : public BnNfc {
-  public:
-    Nfc() = default;
-
-    ::ndk::ScopedAStatus open(const std::shared_ptr<INfcClientCallback>& clientCallback) override;
-    ::ndk::ScopedAStatus close(NfcCloseType type) override;
-    ::ndk::ScopedAStatus coreInitialized() override;
-    ::ndk::ScopedAStatus factoryReset() override;
-    ::ndk::ScopedAStatus getConfig(NfcConfig* _aidl_return) override;
-    ::ndk::ScopedAStatus powerCycle() override;
-    ::ndk::ScopedAStatus preDiscover() override;
-    ::ndk::ScopedAStatus write(const std::vector<uint8_t>& data, int32_t* _aidl_return) override;
-    ::ndk::ScopedAStatus setEnableVerboseLogging(bool enable) override;
-    ::ndk::ScopedAStatus isVerboseLoggingEnabled(bool* _aidl_return) override;
-
-    static void eventCallback(uint8_t event, uint8_t status) {
-        if (mCallback != nullptr) {
-            auto ret = mCallback->sendEvent((NfcEvent)event, (NfcStatus)status);
-            if (!ret.isOk()) {
-                LOG(ERROR) << "Failed to send event!";
-            }
-        }
-    }
-
-    static void dataCallback(uint16_t data_len, uint8_t* p_data) {
-        std::vector<uint8_t> data(p_data, p_data + data_len);
-        if (mCallback != nullptr) {
-            auto ret = mCallback->sendData(data);
-            if (!ret.isOk()) {
-                LOG(ERROR) << "Failed to send data!";
-            }
-        }
-    }
-
-    static std::shared_ptr<INfcClientCallback> mCallback;
-};
-
-}  // namespace nfc
-}  // namespace hardware
-}  // namespace android
-}  // namespace aidl
diff --git a/nfc/aidl/default/Vendor_hal_api.cpp b/nfc/aidl/default/Vendor_hal_api.cpp
deleted file mode 100644
index 66a2ebc..0000000
--- a/nfc/aidl/default/Vendor_hal_api.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <android-base/properties.h>
-#include <dlfcn.h>
-#include <errno.h>
-#include <string.h>
-
-#include "Vendor_hal_api.h"
-
-bool logging = false;
-
-int Vendor_hal_open(nfc_stack_callback_t* p_cback, nfc_stack_data_callback_t* p_data_cback) {
-    (void)p_cback;
-    (void)p_data_cback;
-    // nothing to open in this example
-    return -1;
-}
-
-int Vendor_hal_write(uint16_t data_len, const uint8_t* p_data) {
-    (void)data_len;
-    (void)p_data;
-    return -1;
-}
-
-int Vendor_hal_core_initialized() {
-    return -1;
-}
-
-int Vendor_hal_pre_discover() {
-    return -1;
-}
-
-int Vendor_hal_close() {
-    return -1;
-}
-
-int Vendor_hal_close_off() {
-    return -1;
-}
-
-int Vendor_hal_power_cycle() {
-    return -1;
-}
-
-void Vendor_hal_factoryReset() {}
-
-void Vendor_hal_getConfig(NfcConfig& config) {
-    (void)config;
-}
-
-void Vendor_hal_setVerboseLogging(bool enable) {
-    logging = enable;
-}
-
-bool Vendor_hal_getVerboseLogging() {
-    return logging;
-}
diff --git a/nfc/aidl/default/Vendor_hal_api.h b/nfc/aidl/default/Vendor_hal_api.h
deleted file mode 100644
index 595c2dd..0000000
--- a/nfc/aidl/default/Vendor_hal_api.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#pragma once
-
-#include <aidl/android/hardware/nfc/INfc.h>
-#include <aidl/android/hardware/nfc/NfcConfig.h>
-#include <aidl/android/hardware/nfc/NfcEvent.h>
-#include <aidl/android/hardware/nfc/NfcStatus.h>
-#include <aidl/android/hardware/nfc/PresenceCheckAlgorithm.h>
-#include <aidl/android/hardware/nfc/ProtocolDiscoveryConfig.h>
-#include "hardware_nfc.h"
-
-using aidl::android::hardware::nfc::NfcConfig;
-using aidl::android::hardware::nfc::NfcEvent;
-using aidl::android::hardware::nfc::NfcStatus;
-using aidl::android::hardware::nfc::PresenceCheckAlgorithm;
-using aidl::android::hardware::nfc::ProtocolDiscoveryConfig;
-
-int Vendor_hal_open(nfc_stack_callback_t* p_cback, nfc_stack_data_callback_t* p_data_cback);
-int Vendor_hal_write(uint16_t data_len, const uint8_t* p_data);
-
-int Vendor_hal_core_initialized();
-
-int Vendor_hal_pre_discover();
-
-int Vendor_hal_close();
-
-int Vendor_hal_close_off();
-
-int Vendor_hal_power_cycle();
-
-void Vendor_hal_factoryReset();
-
-void Vendor_hal_getConfig(NfcConfig& config);
-
-void Vendor_hal_setVerboseLogging(bool enable);
-
-bool Vendor_hal_getVerboseLogging();
diff --git a/nfc/aidl/default/hardware_nfc.h b/nfc/aidl/default/hardware_nfc.h
deleted file mode 100644
index 0f856c5..0000000
--- a/nfc/aidl/default/hardware_nfc.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#pragma once
-
-typedef uint8_t nfc_event_t;
-typedef uint8_t nfc_status_t;
-
-/*
- * The callback passed in from the NFC stack that the HAL
- * can use to pass events back to the stack.
- */
-typedef void(nfc_stack_callback_t)(nfc_event_t event, nfc_status_t event_status);
-
-/*
- * The callback passed in from the NFC stack that the HAL
- * can use to pass incomming data to the stack.
- */
-typedef void(nfc_stack_data_callback_t)(uint16_t data_len, uint8_t* p_data);
diff --git a/nfc/aidl/default/main.cpp b/nfc/aidl/default/main.cpp
deleted file mode 100644
index 0cc51e7..0000000
--- a/nfc/aidl/default/main.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <android-base/logging.h>
-#include <android/binder_manager.h>
-#include <android/binder_process.h>
-
-#include "Nfc.h"
-using ::aidl::android::hardware::nfc::Nfc;
-
-int main() {
-    LOG(INFO) << "NFC HAL starting up";
-    if (!ABinderProcess_setThreadPoolMaxThreadCount(1)) {
-        LOG(INFO) << "failed to set thread pool max thread count";
-        return 1;
-    }
-    std::shared_ptr<Nfc> nfc_service = ndk::SharedRefBase::make<Nfc>();
-
-    const std::string instance = std::string() + Nfc::descriptor + "/default";
-    binder_status_t status =
-            AServiceManager_addService(nfc_service->asBinder().get(), instance.c_str());
-    CHECK(status == STATUS_OK);
-    ABinderProcess_joinThreadPool();
-    return 0;
-}
diff --git a/nfc/aidl/default/nfc-service-example.rc b/nfc/aidl/default/nfc-service-example.rc
deleted file mode 100644
index 7d7052e..0000000
--- a/nfc/aidl/default/nfc-service-example.rc
+++ /dev/null
@@ -1,4 +0,0 @@
-service nfc_hal_service /vendor/bin/hw/android.hardware.nfc-service.st
-    class hal
-    user nfc
-    group nfc
diff --git a/nfc/aidl/default/nfc-service-example.xml b/nfc/aidl/default/nfc-service-example.xml
deleted file mode 100644
index 70fed20..0000000
--- a/nfc/aidl/default/nfc-service-example.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<manifest version="1.0" type="device">
-    <hal format="aidl">
-        <name>android.hardware.nfc</name>
-        <fqname>INfc/default</fqname>
-    </hal>
-</manifest>
diff --git a/security/keymint/aidl/default/Android.bp b/security/keymint/aidl/default/Android.bp
index 122a421..c707845 100644
--- a/security/keymint/aidl/default/Android.bp
+++ b/security/keymint/aidl/default/Android.bp
@@ -50,7 +50,7 @@
     name: "android.hardware.security.keymint-service.nonsecure",
     relative_install_path: "hw",
     vendor: true,
-    init_rc: ["android.hardware.security.keymint-service.rc"],
+    init_rc: ["android.hardware.security.keymint-service.nonsecure.rc"],
     vintf_fragments: [
         "android.hardware.security.keymint-service.xml",
         "android.hardware.security.sharedsecret-service.xml",
diff --git a/security/keymint/aidl/default/android.hardware.security.keymint-service.nonsecure.rc b/security/keymint/aidl/default/android.hardware.security.keymint-service.nonsecure.rc
new file mode 100644
index 0000000..c792eae
--- /dev/null
+++ b/security/keymint/aidl/default/android.hardware.security.keymint-service.nonsecure.rc
@@ -0,0 +1,3 @@
+service vendor.keymint-default /vendor/bin/hw/android.hardware.security.keymint-service.nonsecure
+    class early_hal
+    user nobody
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index 9575183..3bcdd8f 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -5222,6 +5222,149 @@
                                        .Padding(PaddingMode::RSA_OAEP)));
 }
 
+auto wrapped_rsa_key = hex2str(
+        "308206230201000482010060f81b63ae53aa4be2e91b0b7cbdabd108125836139e5b991f3e3c9a98eca6cb7188"
+        "fba1c1232605747ed118975870c886e583a0ff766fc32b789a17029955caaff39a9c6c439be168e24b51046683"
+        "ce16110e0df115ccabbadcbe7ea9118b9589e4cccf240b6f0a506dfee57e19738c3cabb7dbf63b43e1b9ab058b"
+        "41b9480f2797210ef2bfbecb82526ac60ac006ebe0a053e825ad996d0ce8a98dc1ebf6ad889e491e03e9ddcc05"
+        "63f31921b55a54c61aa7f846d814dfe548f2c7939940bc6cf20489733203732df924b2b2a5aa9b54d31e7e42b9"
+        "e6cf107182edd33cb8e41db88167a79a264bbf883e69300ac82aac8de9dca0a13900150111efead81b74040c78"
+        "01d20b1547cfef40de45da30350201013030a1083106020102020103a203020101a30402020800a40531030201"
+        "01a5053103020104a6053103020103bf8377020500048204c126cd1642e83dea941151d872de12b8aaa835446e"
+        "94d2c1ea99c030225c5cad125dabe2341d9aba63e4df7fefc51e8e6f623ffae2aab9927113562b674b3cc2d7fc"
+        "fc34f199151a56ab114e792e6a21bd3b31fbf0d93050b9f90fb8e6cad3a067a4033848c4380184990f19a141d9"
+        "527177fdc13d802c33d222206c36404518285fe7e631aaeb6072c22c351c8c9db06e0b24e11aecef305f6abefb"
+        "4f31111534f7c55da8cf0d33882edbb43765304d1d45545c5207a858ea8d4369393bf1c54624df03da86c0ed47"
+        "b9ce1297149622069d51d2512f656ad0d421e6ff746ce8f79920df6a204c31732414a2f7eb24f8c2950348187a"
+        "4ba20b88a72355a4ec2b383be9f9b5b9ad564aa4c81de47dd95d77a8156ed0901d005a26f523b2a82c2d25d64d"
+        "f7660a6d3a720a6ba1eafe71da9fed0265d37a475193525620e705a543a928827accad93aba90556da859808be"
+        "dc2a8105af252e883892f41679d0600ddefb84415145bc28a2d9b0c60cea1ed3876486950ae0532cc1e953b0b5"
+        "81314c74250550741b24e4221ebb2804428caa2f08356a7de853ccfc5b18c2179147a883fa5763dd54f0d45388"
+        "c72f1bea19675d14014a725e125cdfac98d1701d9562be9d75362ea238b93244f46306cee4d77cbb8cbe7bf22d"
+        "fe677bbb103c00a204e49a0731660a2b23ee73ec7297a17822d4c4468e271029f8f1e8995f1a37cdc38324ead3"
+        "2474e6ee3ff671803d8a98a870324364d408c4d966d3cf0b9bbcbdbdff34a3e9666705362bc78beb96df4b8964"
+        "d141022250f62d1433cba5d1f510859eff688e46ce65dea00f5ebcfe7a79081ef1f0f5584dba14b79bc5a5f309"
+        "a1e48fe2bd9e94fcd9793d9b3632ccc51f18f7453e897e33b729abd2d34be324acbc22dfbf1d089aa93a178f79"
+        "23344140a468ac120b2f0055c284576b968e1d5148c6879b207b6cdb4eb513bccca619ae12ef156a9df03d6d8c"
+        "2c1c2ea7109dbcb61e5a74b36d0a7529f38b9ea742a956376da823251a6126693e2e1dab55b643c4e9783db835"
+        "f64d91069a2de1cda55539da52cadeeba2d3278da9005d89b4de4c5571600823f53d9cab1b55f65a560479d9ee"
+        "edeb361ab80ccedd0a067ddf5de639d115ffb3acf07fbba1cba6daa524b99db0b785273f7b6c15c4237ce1dce8"
+        "1b81622f35f116b638c75f0e0b26ba6bd9c5caee60c8b4f9198052b25e8c101638598946cb02c14db0a21b46c6"
+        "61ea123b2a2b5a51eb059715ce26940c977715a32e288b713013d66d0dae398d546abcd8c80966190b77732a7c"
+        "e2b8fc83e0cd83f69adef2b24b69fba19c546362087c08c8dab941a8573a084be3407d45a318c9a299f69d79f6"
+        "fae0859d6f08ee7708cf6041cccd815c3515f792aefc23a624e8e58bd9c6fe2f8f1ca6dcf04c6fdfa23eb3ff74"
+        "c5e5c7388f9faa32c86b6cd7438774e6cf06cb23a32cddb04c30f7d11e221db306c7937796e70a4dcfb7415c04"
+        "7823b965bedeaea196dc30fe648c52f3c1bcee62b19d4cccdb740ca35c3f3daad998c99dc117fffb7d150d500f"
+        "812b60ebec8b2067b13938250d078768e77f898fcdfc5f3554b6eda9df3b42bef38bb4d67cb63b7ede01e93b4d"
+        "c7768b52aa8ad8fb7fb288a529b84671f1ff9e44bb7c8f05d99806b65eb8e90b530fef3817f9fc4c921d0d46af"
+        "11aee8252407adc6c54589e9f6e6c1e25fc7510cfe499ea20465610410bf575efdbeb5af763920c3b4cdc8401"
+        "2");
+
+auto wrapped_ec_key = hex2str(
+        "308201dd020100048201000bb910602f88b1419ada400c8ab7602cf2fdbb4ef5e36881255fd5f85d49c4110c52"
+        "c75eab5e27a1732c1afa17bfe2cd393dea0a78a77ee08759e984411d1c7f0dbdcb6b77e05556694534be4434d8"
+        "596a7152aec71481522c85f0cc4635df2875d58dc29a78317b2aedd3586055e6e2227616f6a8ac4b9db5a2ad0e"
+        "10f5c4b43374bd6c9f57f79a103e64084414cfab3d3e0b7c2f26eb00a62105b7d1c7f41b7292fd6fce9395f39c"
+        "e0b6da0b5bf0d29d8952b958bd29b47c5ebd20d53ade370f463e35a166c04af71e3d5ce550019d3d20a5544896"
+        "65d169875d0e6a52348b7ec39b674f818e9b60dfa284d7ae4188471d05b9b2d9a5f750f5a00af999c568040c31"
+        "4144bde8ada6279d32e61530270201013022a1083106020102020103a203020103a30402020100a50531030201"
+        "04bf837702050004818a96e0f8be5a263616b506371d3c2ff3a3c2bcffc3ce067b242af66e30d5cd975b9546eb"
+        "32216d4f083f08fde246ab05fd7e930a0f05701067b44840c01a6722e1b2408be5b6acd0b39a0329cb2f357515"
+        "876433b193382c0b18aed9ed244dcbef5d61d98ca480f99a6cf2a00efda22eb8750db1725e30f64770ac6862ac"
+        "44cfd08a2c55812b512a0b92f704105c80b6a23cf339b2b10c677613510b1b");
+
+auto wrapping_key_for_asym_keys = hex2str(
+        "308204bd020100300d06092a864886f70d0101010500048204a7308204a30201000282010100a7f521fe024ebc"
+        "659db8e7a32b41dba27c5d446cb3d064d594b811d4856c3a583d155b0ff9300df3745738c32c4c4cd15adb6090"
+        "72ca870364bb7f3485784fde12e598b486c91950b9c45016bcb73c3842747c871be02dfc5f0e4b96d1ff5c8a09"
+        "7ae77b27e46dc60f1f574d1bb5e97487c1c3f9b493509e07318e1a0f0e9fdae401f4a62a5dd54daa09bf88ef42"
+        "9923f6f6f55d239908f227676d0f0b618238728dc4babd2a1f7d15fa9827346a1a160ab9427461533006fdf34d"
+        "4efec9aeefcea80b3a7d4ee4a4550055f0030700c5d20abcc32ce74d90ffabf83e02a759ce9074809936564f3d"
+        "3039af9c5e8a6afd9aa5459ab35c3eb851f10b3ae88ba91f0203010001028201001885515124451a7c3b6aa366"
+        "cf09ee66ea81335c2b6461544d42125854a258624988b4a2c05ea3aac77174780a1f9997770c502cc6958ae093"
+        "f44bbdff3e716a9a97aa93b099eb783da6cb8a8642ba27fc8bc522748f66275239640fc0d8e749bfd891b3093f"
+        "f046da2e593088bb263a3d17ace4e7d81a0cf83fe3df2a139882bff509523a3f886922200168ddd8fb7b4c9f26"
+        "62ff941c37937cebbbfeba24dd78d5ccd42025cb0276fa5661965f529274520bbb9faf36c501cafb48e5e47ae0"
+        "6980334fa36b6c62e2da733a8c7f01067de17e38d32d4a0721a6d184405bceaebb39ed3838633e6fbe43ac8b23"
+        "337bfe33cdf0b67ac3938ddccc37d775ad150102818100d538885135037730fad28e987d7562c1ef8ca58f95f7"
+        "ed81cb165ca63e15e810552eb9d487c9b9cde563fb29d1de22a60d54a856385719a4028cf386bcdc88e858d963"
+        "6d644cea25e0ee54ad1237983d9a06a66ea2f764eb540a4992ba2291ea96d20dfbd98bf5b313322cda4eb6710d"
+        "020139e085beb8e52a3e69bd05c71c7b02818100c9a7c89b11fcf8d99eb41995b5641472ef972e5aaa1f1446d7"
+        "ea57a9979e8e64f72ef1cde358649b71be7f21dc19dab52814f9a521d8620bd994a9bb621a8182a250066a0728"
+        "f0b16ab93a106ed79bc19cd519e83196157a8c6f82b5144a285b9384415394905fe18863b0988b27e77c969a81"
+        "c34a074e8fef5908fdf3c51ead02818019d5e8c6963ade45640f01523ed96b66fe64b766e7900c0a4f165d9193"
+        "324a55384d1a1d437ad0f5bed6d78720b3ded4ea069903217e844fd833460acc75986d36ded86a57ddedfd3afd"
+        "05eb96aa7fdaeeffe148c49c5f711854cac769a068b7d92088ab3c97f5e485eded7b62503ef0898ea679ab1b0a"
+        "0252950f70e4f35463028181008ff4c027bb8aad17a5cd0a2aaea83854e8a73347340525d38115e0e8c7bd4007"
+        "e1d1d87ad35e69cbf2423cbdae43a2b70a5b16f0849dd53882663758f6aad763ab7d97669f9fe15bb6456ea706"
+        "89d2be3fb87d5b1df2f77859c2cd3b79b58ae3fd0640206b813981667d4c3749b7fdf01a0f48ad622e9f2def7e"
+        "cf0583bd67ad0281805bd8f20cc82cb5e08dc2e7eea977d4180a5ef4c558e01255b8475feb9084475e20328c93"
+        "5a2247a775c941d64372d01abb27c95ee7d4336b6cbce190808b2f7a8d314d785336397dd6edc0c778f563d37e"
+        "0057b13695600b92fececc3edb067f69b374f9b9c343220a8b927deb6104768edc72b87751e0a3fb1585e679c9"
+        "8564");
+
+TEST_P(ImportWrappedKeyTest, RsaKey) {
+    int vsr_api_level = get_vsr_api_level();
+    if (vsr_api_level < __ANDROID_API_V__) {
+        /*
+         * The Keymaster v4 spec introduced `importWrappedKey()` and did not restrict it to
+         * just symmetric keys.  However, the import of asymmetric wrapped keys was not tested
+         * at the time, so we can only be strict about checking this for implementations claiming
+         * support for VSR API level 35 and above.
+         */
+        GTEST_SKIP() << "Applies only to VSR API level 35, this device is: " << vsr_api_level;
+    }
+
+    auto wrapping_key_desc = AuthorizationSetBuilder()
+                                     .RsaEncryptionKey(2048, 65537)
+                                     .Digest(Digest::SHA_2_256)
+                                     .Padding(PaddingMode::RSA_OAEP)
+                                     .Authorization(TAG_PURPOSE, KeyPurpose::WRAP_KEY)
+                                     .SetDefaultValidity();
+
+    ASSERT_EQ(ErrorCode::OK, ImportWrappedKey(wrapped_rsa_key, wrapping_key_for_asym_keys,
+                                              wrapping_key_desc, zero_masking_key,
+                                              AuthorizationSetBuilder()
+                                                      .Digest(Digest::SHA_2_256)
+                                                      .Padding(PaddingMode::RSA_OAEP)));
+
+    string message = "Hello World!";
+    auto params = AuthorizationSetBuilder().Digest(Digest::SHA_2_256).Padding(PaddingMode::RSA_PSS);
+    string signature = SignMessage(message, params);
+    LocalVerifyMessage(message, signature, params);
+}
+
+TEST_P(ImportWrappedKeyTest, EcKey) {
+    int vsr_api_level = get_vsr_api_level();
+    if (vsr_api_level < __ANDROID_API_V__) {
+        /*
+         * The Keymaster v4 spec introduced `importWrappedKey()` and did not restrict it to
+         * just symmetric keys.  However, the import of asymmetric wrapped keys was not tested
+         * at the time, so we can only be strict about checking this for implementations claiming
+         * support for VSR API level 35 and above.
+         */
+        GTEST_SKIP() << "Applies only to VSR API level 35, this device is: " << vsr_api_level;
+    }
+
+    auto wrapping_key_desc = AuthorizationSetBuilder()
+                                     .RsaEncryptionKey(2048, 65537)
+                                     .Digest(Digest::SHA_2_256)
+                                     .Padding(PaddingMode::RSA_OAEP)
+                                     .Authorization(TAG_PURPOSE, KeyPurpose::WRAP_KEY)
+                                     .SetDefaultValidity();
+
+    ASSERT_EQ(ErrorCode::OK, ImportWrappedKey(wrapped_ec_key, wrapping_key_for_asym_keys,
+                                              wrapping_key_desc, zero_masking_key,
+                                              AuthorizationSetBuilder()
+                                                      .Digest(Digest::SHA_2_256)
+                                                      .Padding(PaddingMode::RSA_OAEP)));
+
+    string message = "Hello World!";
+    auto params = AuthorizationSetBuilder().Digest(Digest::SHA_2_256);
+    string signature = SignMessage(message, params);
+    LocalVerifyMessage(message, signature, params);
+}
+
 INSTANTIATE_KEYMINT_AIDL_TEST(ImportWrappedKeyTest);
 
 typedef KeyMintAidlTestBase EncryptionOperationsTest;
diff --git a/security/keymint/support/include/remote_prov/remote_prov_utils.h b/security/keymint/support/include/remote_prov/remote_prov_utils.h
index b8c69eb..1d7db6a 100644
--- a/security/keymint/support/include/remote_prov/remote_prov_utils.h
+++ b/security/keymint/support/include/remote_prov/remote_prov_utils.h
@@ -183,4 +183,7 @@
         const cppbor::Array& keysToSign, const std::vector<uint8_t>& csr,
         IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge);
 
+/** Checks whether the CSR has a proper DICE chain. */
+ErrMsgOr<bool> isCsrWithProperDiceChain(const std::vector<uint8_t>& csr);
+
 }  // namespace aidl::android::hardware::security::keymint::remote_prov
diff --git a/security/keymint/support/remote_prov_utils.cpp b/security/keymint/support/remote_prov_utils.cpp
index a830041..b74fd59 100644
--- a/security/keymint/support/remote_prov_utils.cpp
+++ b/security/keymint/support/remote_prov_utils.cpp
@@ -1081,4 +1081,40 @@
     return verifyCsr(keysToSign, csr, provisionable, challenge, /*isFactory=*/false);
 }
 
+ErrMsgOr<bool> isCsrWithProperDiceChain(const std::vector<uint8_t>& csr) {
+    auto [parsedRequest, _, csrErrMsg] = cppbor::parse(csr);
+    if (!parsedRequest) {
+        return csrErrMsg;
+    }
+    if (!parsedRequest->asArray()) {
+        return "AuthenticatedRequest is not a CBOR array.";
+    }
+    if (parsedRequest->asArray()->size() != 4U) {
+        return "AuthenticatedRequest must contain version, UDS certificates, DICE chain, and "
+               "signed data. However, the parsed AuthenticatedRequest has " +
+               std::to_string(parsedRequest->asArray()->size()) + " entries.";
+    }
+
+    auto version = parsedRequest->asArray()->get(0)->asUint();
+    auto diceCertChain = parsedRequest->asArray()->get(2)->asArray();
+
+    if (!version || version->value() != 1U) {
+        return "AuthenticatedRequest version must be an unsigned integer and must be equal to 1.";
+    }
+    if (!diceCertChain) {
+        return "AuthenticatedRequest DiceCertChain must be an Array.";
+    }
+
+    // DICE chain is [ pubkey, + DiceChainEntry ].
+    auto diceChainKind = getDiceChainKind();
+    if (!diceChainKind) {
+        return diceChainKind.message();
+    }
+
+    auto encodedDiceChain = diceCertChain->encode();
+    auto chain = hwtrust::DiceChain::Verify(encodedDiceChain, *diceChainKind);
+    if (!chain.ok()) return chain.error().message();
+    return chain->IsProper();
+}
+
 }  // namespace aidl::android::hardware::security::keymint::remote_prov
diff --git a/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp b/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
index 68b966c..2a8fd96 100644
--- a/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
+++ b/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
@@ -55,8 +55,12 @@
 
 constexpr uint8_t MIN_CHALLENGE_SIZE = 0;
 constexpr uint8_t MAX_CHALLENGE_SIZE = 64;
+const string DEFAULT_INSTANCE_NAME =
+        "android.hardware.security.keymint.IRemotelyProvisionedComponent/default";
 const string RKP_VM_INSTANCE_NAME =
         "android.hardware.security.keymint.IRemotelyProvisionedComponent/avf";
+const string KEYMINT_STRONGBOX_INSTANCE_NAME =
+        "android.hardware.security.keymint.IKeyMintDevice/strongbox";
 
 #define INSTANTIATE_REM_PROV_AIDL_TEST(name)                                         \
     GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(name);                             \
@@ -230,6 +234,37 @@
     }
 }
 
+/**
+ * Verify that the default implementation supports DICE if there is a StrongBox KeyMint instance
+ * on the device.
+ */
+// @VsrTest = 3.10-015
+TEST(NonParameterizedTests, requireDiceOnDefaultInstanceIfStrongboxPresent) {
+    int vsr_api_level = get_vsr_api_level();
+    if (vsr_api_level < 35) {
+        GTEST_SKIP() << "Applies only to VSR API level 35 or newer, this device is: "
+                     << vsr_api_level;
+    }
+
+    if (!AServiceManager_isDeclared(KEYMINT_STRONGBOX_INSTANCE_NAME.c_str())) {
+        GTEST_SKIP() << "Strongbox is not present on this device.";
+    }
+
+    ::ndk::SpAIBinder binder(AServiceManager_waitForService(DEFAULT_INSTANCE_NAME.c_str()));
+    std::shared_ptr<IRemotelyProvisionedComponent> rpc =
+            IRemotelyProvisionedComponent::fromBinder(binder);
+    ASSERT_NE(rpc, nullptr);
+
+    bytevec challenge = randomBytes(64);
+    bytevec csr;
+    auto status = rpc->generateCertificateRequestV2({} /* keysToSign */, challenge, &csr);
+    EXPECT_TRUE(status.isOk()) << status.getDescription();
+
+    auto result = isCsrWithProperDiceChain(csr);
+    ASSERT_TRUE(result) << result.message();
+    ASSERT_TRUE(*result);
+}
+
 using GetHardwareInfoTests = VtsRemotelyProvisionedComponentTests;
 
 INSTANTIATE_REM_PROV_AIDL_TEST(GetHardwareInfoTests);
diff --git a/sensors/OWNERS b/sensors/OWNERS
index e7ebd3e..5017a9a 100644
--- a/sensors/OWNERS
+++ b/sensors/OWNERS
@@ -1,5 +1,3 @@
 # Bug component: 62965
 
-arthuri@google.com
 bduddie@google.com
-stange@google.com
diff --git a/uwb/aidl/default/src/uwb_chip.rs b/uwb/aidl/default/src/uwb_chip.rs
index d1c3c67..878aa64 100644
--- a/uwb/aidl/default/src/uwb_chip.rs
+++ b/uwb/aidl/default/src/uwb_chip.rs
@@ -180,6 +180,8 @@
             let mut reader = AsyncFd::new(reader).unwrap();
 
             loop {
+                const MESSAGE_TYPE_MASK: u8 = 0b11100000;
+                const DATA_MESSAGE_TYPE: u8 = 0b000;
                 const UWB_HEADER_SIZE: usize = 4;
                 let mut buffer = vec![0; UWB_HEADER_SIZE];
 
@@ -224,12 +226,22 @@
                 // Read the remaining header bytes, if truncated.
                 read_exact(reader.get_mut(), &mut buffer[read_len..]).unwrap();
 
-                let length = buffer[3] as usize + UWB_HEADER_SIZE;
+                let common_header = buffer[0];
+                let mt = (common_header & MESSAGE_TYPE_MASK) >> 5;
+                let payload_length = if mt == DATA_MESSAGE_TYPE {
+                    let payload_length_fields: [u8; 2] = buffer[2..=3].try_into().unwrap();
+                    u16::from_le_bytes(payload_length_fields) as usize
+                } else {
+                    buffer[3] as usize
+                };
+
+                let length = payload_length + UWB_HEADER_SIZE;
                 buffer.resize(length, 0);
 
                 // Read the payload bytes.
                 read_exact(reader.get_mut(), &mut buffer[UWB_HEADER_SIZE..]).unwrap();
 
+                log::debug!(" <-- {:?}", buffer);
                 client_callbacks.onUciMessage(&buffer).unwrap();
             }
         });
@@ -284,10 +296,13 @@
         log::debug!("sendUciMessage");
 
         if let State::Opened { ref mut serial, .. } = &mut *self.state.lock().await {
-            serial
-                .write(data)
-                .map(|written| written as i32)
-                .map_err(|_| binder::StatusCode::UNKNOWN_ERROR.into())
+            log::debug!(" --> {:?}", data);
+            let result = serial
+                .write_all(data)
+                .map(|_| data.len() as i32)
+                .map_err(|_| binder::StatusCode::UNKNOWN_ERROR.into());
+            log::debug!(" status: {:?}", result);
+            result
         } else {
             Err(binder::ExceptionCode::ILLEGAL_STATE.into())
         }
diff --git a/uwb/aidl/vts/VtsHalUwbTargetTest.cpp b/uwb/aidl/vts/VtsHalUwbTargetTest.cpp
index 3b0b606..548cae0 100644
--- a/uwb/aidl/vts/VtsHalUwbTargetTest.cpp
+++ b/uwb/aidl/vts/VtsHalUwbTargetTest.cpp
@@ -39,6 +39,8 @@
 
 namespace {
 constexpr static int kCallbackTimeoutMs = 250;
+// this timeout should be same as AOSP stack timeout (HAL_OPEN_TIMEOUT_MS)
+constexpr static int kOpenCallbackTimeoutMs = 20000;
 }  // namespace
 
 class UwbClientCallback : public BnUwbClientCallback {
@@ -105,7 +107,7 @@
                         open_cb_promise.set_value();
                     }
                 });
-        std::chrono::milliseconds timeout{kCallbackTimeoutMs};
+        std::chrono::milliseconds timeout{kOpenCallbackTimeoutMs};
         const auto iuwb_chip = getAnyChip();
         EXPECT_TRUE(iuwb_chip->open(callback).isOk());
         EXPECT_EQ(open_cb_future.wait_for(timeout), std::future_status::ready);
@@ -137,7 +139,7 @@
                     open_cb_promise.set_value();
                 }
             });
-    std::chrono::milliseconds timeout{kCallbackTimeoutMs};
+    std::chrono::milliseconds timeout{kOpenCallbackTimeoutMs};
     const auto iuwb_chip = getAnyChip();
     EXPECT_TRUE(iuwb_chip->open(callback).isOk());
     EXPECT_EQ(open_cb_future.wait_for(timeout), std::future_status::ready);
@@ -158,12 +160,13 @@
                     close_cb_promise.set_value();
                 }
             });
-    std::chrono::milliseconds timeout{kCallbackTimeoutMs};
+    std::chrono::milliseconds open_timeout{kOpenCallbackTimeoutMs};
+    std::chrono::milliseconds close_timeout{kCallbackTimeoutMs};
     const auto iuwb_chip = getAnyChip();
     EXPECT_TRUE(iuwb_chip->open(callback).isOk());
-    EXPECT_EQ(open_cb_future.wait_for(timeout), std::future_status::ready);
+    EXPECT_EQ(open_cb_future.wait_for(open_timeout), std::future_status::ready);
     EXPECT_TRUE(iuwb_chip->close().isOk());
-    EXPECT_EQ(close_cb_future.wait_for(timeout), std::future_status::ready);
+    EXPECT_EQ(close_cb_future.wait_for(close_timeout), std::future_status::ready);
 }
 
 TEST_P(UwbAidl, ChipCoreInit) {
diff --git a/wifi/aidl/vts/functional/wifi_sta_iface_aidl_test.cpp b/wifi/aidl/vts/functional/wifi_sta_iface_aidl_test.cpp
index e456e49..d368715 100644
--- a/wifi/aidl/vts/functional/wifi_sta_iface_aidl_test.cpp
+++ b/wifi/aidl/vts/functional/wifi_sta_iface_aidl_test.cpp
@@ -171,14 +171,18 @@
         }
         StaApfPacketFilterCapabilities apf_caps = {};
         EXPECT_TRUE(wifi_sta_iface_->getApfPacketFilterCapabilities(&apf_caps).isOk());
-    } else {
-        EXPECT_TRUE(isFeatureSupported(IWifiStaIface::FeatureSetMask::APF));
-        StaApfPacketFilterCapabilities apf_caps = {};
-        EXPECT_TRUE(wifi_sta_iface_->getApfPacketFilterCapabilities(&apf_caps).isOk());
-        // The APF version must be 4 and the usable memory must be at least
-        // 1024 bytes.
-        EXPECT_EQ(apf_caps.version, 4);
-        EXPECT_GE(apf_caps.maxLength, 1024);
+        return;
+    }
+
+    EXPECT_TRUE(isFeatureSupported(IWifiStaIface::FeatureSetMask::APF));
+    StaApfPacketFilterCapabilities apf_caps = {};
+    EXPECT_TRUE(wifi_sta_iface_->getApfPacketFilterCapabilities(&apf_caps).isOk());
+    EXPECT_GE(apf_caps.version, 4);
+    // Based on VSR-14 the usable memory must be at least 1024 bytes.
+    EXPECT_GE(apf_caps.maxLength, 1024);
+    if (vendor_api_level >= __ANDROID_API_V__) {
+        // Based on VSR-15 the usable memory must be at least 2000 bytes.
+        EXPECT_GE(apf_caps.maxLength, 2000);
     }
 }