Merge "Add test mapping for bcradio HAL" into main
diff --git a/.gitignore b/.gitignore
index 1d74e21..6c7f477 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,4 @@
 .vscode/
+
+# Vim temporary files
+**/*.swp
diff --git a/audio/aidl/TEST_MAPPING b/audio/aidl/TEST_MAPPING
index 36c88db..b5fcd86 100644
--- a/audio/aidl/TEST_MAPPING
+++ b/audio/aidl/TEST_MAPPING
@@ -70,6 +70,14 @@
     },
     {
       "name": "audiosystem_tests"
+    },
+    {
+      "name": "CtsVirtualDevicesTestCases",
+      "options" : [
+        {
+          "include-filter": "android.virtualdevice.cts.VirtualAudioTest"
+        }
+      ]
     }
   ]
 }
diff --git a/audio/aidl/default/Android.bp b/audio/aidl/default/Android.bp
index 7e06c2c..bfa2783 100644
--- a/audio/aidl/default/Android.bp
+++ b/audio/aidl/default/Android.bp
@@ -230,6 +230,7 @@
 filegroup {
     name: "effectCommonFile",
     srcs: [
+        "EffectContext.cpp",
         "EffectThread.cpp",
         "EffectImpl.cpp",
     ],
diff --git a/audio/aidl/default/EffectContext.cpp b/audio/aidl/default/EffectContext.cpp
new file mode 100644
index 0000000..2e12918
--- /dev/null
+++ b/audio/aidl/default/EffectContext.cpp
@@ -0,0 +1,227 @@
+/*
+ * Copyright (C) 2024 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 <memory>
+#define LOG_TAG "AHAL_EffectContext"
+#include "effect-impl/EffectContext.h"
+#include "include/effect-impl/EffectTypes.h"
+
+using aidl::android::hardware::audio::common::getChannelCount;
+using aidl::android::hardware::audio::common::getFrameSizeInBytes;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::media::audio::common::PcmType;
+using ::android::hardware::EventFlag;
+
+namespace aidl::android::hardware::audio::effect {
+
+EffectContext::EffectContext(size_t statusDepth, const Parameter::Common& common) {
+    LOG_ALWAYS_FATAL_IF(RetCode::SUCCESS != setCommon(common), "illegalCommonParameter");
+
+    // in/outBuffer size in float (FMQ data format defined for DataMQ)
+    size_t inBufferSizeInFloat = common.input.frameCount * mInputFrameSize / sizeof(float);
+    size_t outBufferSizeInFloat = common.output.frameCount * mOutputFrameSize / sizeof(float);
+
+    // only status FMQ use the EventFlag
+    mStatusMQ = std::make_shared<StatusMQ>(statusDepth, true /*configureEventFlagWord*/);
+    mInputMQ = std::make_shared<DataMQ>(inBufferSizeInFloat);
+    mOutputMQ = std::make_shared<DataMQ>(outBufferSizeInFloat);
+
+    if (!mStatusMQ->isValid() || !mInputMQ->isValid() || !mOutputMQ->isValid()) {
+        LOG(ERROR) << __func__ << " created invalid FMQ";
+    }
+
+    ::android::status_t status =
+            EventFlag::createEventFlag(mStatusMQ->getEventFlagWord(), &mEfGroup);
+    LOG_ALWAYS_FATAL_IF(status != ::android::OK || !mEfGroup, " create EventFlagGroup failed ");
+    mWorkBuffer.reserve(std::max(inBufferSizeInFloat, outBufferSizeInFloat));
+}
+
+// reset buffer status by abandon input data in FMQ
+void EffectContext::resetBuffer() {
+    auto buffer = static_cast<float*>(mWorkBuffer.data());
+    std::vector<IEffect::Status> status(mStatusMQ->availableToRead());
+    if (mInputMQ) {
+        mInputMQ->read(buffer, mInputMQ->availableToRead());
+    }
+}
+
+void EffectContext::dupeFmqWithReopen(IEffect::OpenEffectReturn* effectRet) {
+    if (!mInputMQ) {
+        mInputMQ = std::make_shared<DataMQ>(mCommon.input.frameCount * mInputFrameSize /
+                                            sizeof(float));
+    }
+    if (!mOutputMQ) {
+        mOutputMQ = std::make_shared<DataMQ>(mCommon.output.frameCount * mOutputFrameSize /
+                                             sizeof(float));
+    }
+    dupeFmq(effectRet);
+}
+
+void EffectContext::dupeFmq(IEffect::OpenEffectReturn* effectRet) {
+    if (effectRet) {
+        effectRet->statusMQ = mStatusMQ->dupeDesc();
+        effectRet->inputDataMQ = mInputMQ->dupeDesc();
+        effectRet->outputDataMQ = mOutputMQ->dupeDesc();
+    }
+}
+
+float* EffectContext::getWorkBuffer() {
+    return static_cast<float*>(mWorkBuffer.data());
+}
+
+std::shared_ptr<EffectContext::StatusMQ> EffectContext::getStatusFmq() const {
+    return mStatusMQ;
+}
+
+std::shared_ptr<EffectContext::DataMQ> EffectContext::getInputDataFmq() const {
+    return mInputMQ;
+}
+
+std::shared_ptr<EffectContext::DataMQ> EffectContext::getOutputDataFmq() const {
+    return mOutputMQ;
+}
+
+size_t EffectContext::getInputFrameSize() const {
+    return mInputFrameSize;
+}
+
+size_t EffectContext::getOutputFrameSize() const {
+    return mOutputFrameSize;
+}
+
+int EffectContext::getSessionId() const {
+    return mCommon.session;
+}
+
+int EffectContext::getIoHandle() const {
+    return mCommon.ioHandle;
+}
+
+RetCode EffectContext::setOutputDevice(
+        const std::vector<aidl::android::media::audio::common::AudioDeviceDescription>& device) {
+    mOutputDevice = device;
+    return RetCode::SUCCESS;
+}
+
+std::vector<aidl::android::media::audio::common::AudioDeviceDescription>
+EffectContext::getOutputDevice() {
+    return mOutputDevice;
+}
+
+RetCode EffectContext::setAudioMode(const aidl::android::media::audio::common::AudioMode& mode) {
+    mMode = mode;
+    return RetCode::SUCCESS;
+}
+aidl::android::media::audio::common::AudioMode EffectContext::getAudioMode() {
+    return mMode;
+}
+
+RetCode EffectContext::setAudioSource(
+        const aidl::android::media::audio::common::AudioSource& source) {
+    mSource = source;
+    return RetCode::SUCCESS;
+}
+
+aidl::android::media::audio::common::AudioSource EffectContext::getAudioSource() {
+    return mSource;
+}
+
+RetCode EffectContext::setVolumeStereo(const Parameter::VolumeStereo& volumeStereo) {
+    mVolumeStereo = volumeStereo;
+    return RetCode::SUCCESS;
+}
+
+Parameter::VolumeStereo EffectContext::getVolumeStereo() {
+    return mVolumeStereo;
+}
+
+RetCode EffectContext::setCommon(const Parameter::Common& common) {
+    LOG(VERBOSE) << __func__ << common.toString();
+    auto& input = common.input;
+    auto& output = common.output;
+
+    if (input.base.format.pcm != aidl::android::media::audio::common::PcmType::FLOAT_32_BIT ||
+        output.base.format.pcm != aidl::android::media::audio::common::PcmType::FLOAT_32_BIT) {
+        LOG(ERROR) << __func__ << " illegal IO, input "
+                   << ::android::internal::ToString(input.base.format) << ", output "
+                   << ::android::internal::ToString(output.base.format);
+        return RetCode::ERROR_ILLEGAL_PARAMETER;
+    }
+
+    if (auto ret = updateIOFrameSize(common); ret != RetCode::SUCCESS) {
+        return ret;
+    }
+
+    mInputChannelCount = getChannelCount(input.base.channelMask);
+    mOutputChannelCount = getChannelCount(output.base.channelMask);
+    if (mInputChannelCount == 0 || mOutputChannelCount == 0) {
+        LOG(ERROR) << __func__ << " illegal channel count input " << mInputChannelCount
+                   << ", output " << mOutputChannelCount;
+        return RetCode::ERROR_ILLEGAL_PARAMETER;
+    }
+
+    mCommon = common;
+    return RetCode::SUCCESS;
+}
+
+Parameter::Common EffectContext::getCommon() {
+    LOG(VERBOSE) << __func__ << mCommon.toString();
+    return mCommon;
+}
+
+EventFlag* EffectContext::getStatusEventFlag() {
+    return mEfGroup;
+}
+
+RetCode EffectContext::updateIOFrameSize(const Parameter::Common& common) {
+    const auto iFrameSize = ::aidl::android::hardware::audio::common::getFrameSizeInBytes(
+            common.input.base.format, common.input.base.channelMask);
+    const auto oFrameSize = ::aidl::android::hardware::audio::common::getFrameSizeInBytes(
+            common.output.base.format, common.output.base.channelMask);
+
+    bool needUpdateMq = false;
+    if (mInputMQ &&
+        (mInputFrameSize != iFrameSize || mCommon.input.frameCount != common.input.frameCount)) {
+        mInputMQ.reset();
+        needUpdateMq = true;
+    }
+    if (mOutputMQ &&
+        (mOutputFrameSize != oFrameSize || mCommon.output.frameCount != common.output.frameCount)) {
+        mOutputMQ.reset();
+        needUpdateMq = true;
+    }
+    mInputFrameSize = iFrameSize;
+    mOutputFrameSize = oFrameSize;
+    if (needUpdateMq) {
+        return notifyDataMqUpdate();
+    }
+    return RetCode::SUCCESS;
+}
+
+RetCode EffectContext::notifyDataMqUpdate() {
+    if (!mEfGroup) {
+        LOG(ERROR) << __func__ << ": invalid EventFlag group";
+        return RetCode::ERROR_EVENT_FLAG_ERROR;
+    }
+
+    if (const auto ret = mEfGroup->wake(kEventFlagDataMqUpdate); ret != ::android::OK) {
+        LOG(ERROR) << __func__ << ": wake failure with ret " << ret;
+        return RetCode::ERROR_EVENT_FLAG_ERROR;
+    }
+    LOG(DEBUG) << __func__ << " : signal client for reopen";
+    return RetCode::SUCCESS;
+}
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/EffectImpl.cpp b/audio/aidl/default/EffectImpl.cpp
index 3c12f83..b76269a 100644
--- a/audio/aidl/default/EffectImpl.cpp
+++ b/audio/aidl/default/EffectImpl.cpp
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <memory>
 #define LOG_TAG "AHAL_EffectImpl"
 #include "effect-impl/EffectImpl.h"
 #include "effect-impl/EffectTypes.h"
@@ -22,6 +23,7 @@
 using aidl::android::hardware::audio::effect::IEffect;
 using aidl::android::hardware::audio::effect::State;
 using aidl::android::media::audio::common::PcmType;
+using ::android::hardware::EventFlag;
 
 extern "C" binder_exception_t destroyEffect(const std::shared_ptr<IEffect>& instanceSp) {
     State state;
@@ -45,50 +47,62 @@
     RETURN_IF(common.input.base.format.pcm != common.output.base.format.pcm ||
                       common.input.base.format.pcm != PcmType::FLOAT_32_BIT,
               EX_ILLEGAL_ARGUMENT, "dataMustBe32BitsFloat");
+    std::lock_guard lg(mImplMutex);
     RETURN_OK_IF(mState != State::INIT);
-    auto context = createContext(common);
-    RETURN_IF(!context, EX_NULL_POINTER, "createContextFailed");
+    mImplContext = createContext(common);
+    RETURN_IF(!mImplContext, EX_NULL_POINTER, "nullContext");
+    mEventFlag = mImplContext->getStatusEventFlag();
 
     if (specific.has_value()) {
         RETURN_IF_ASTATUS_NOT_OK(setParameterSpecific(specific.value()), "setSpecParamErr");
     }
 
     mState = State::IDLE;
-    context->dupeFmq(ret);
-    RETURN_IF(createThread(context, getEffectName()) != RetCode::SUCCESS, EX_UNSUPPORTED_OPERATION,
+    mImplContext->dupeFmq(ret);
+    RETURN_IF(createThread(getEffectName()) != RetCode::SUCCESS, EX_UNSUPPORTED_OPERATION,
               "FailedToCreateWorker");
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus EffectImpl::reopen(OpenEffectReturn* ret) {
+    std::lock_guard lg(mImplMutex);
     RETURN_IF(mState == State::INIT, EX_ILLEGAL_STATE, "alreadyClosed");
 
     // TODO: b/302036943 add reopen implementation
-    auto context = getContext();
-    RETURN_IF(!context, EX_NULL_POINTER, "nullContext");
-    context->dupeFmq(ret);
+    RETURN_IF(!mImplContext, EX_NULL_POINTER, "nullContext");
+    mImplContext->dupeFmqWithReopen(ret);
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus EffectImpl::close() {
-    RETURN_OK_IF(mState == State::INIT);
-    RETURN_IF(mState == State::PROCESSING, EX_ILLEGAL_STATE, "closeAtProcessing");
+    {
+        std::lock_guard lg(mImplMutex);
+        RETURN_OK_IF(mState == State::INIT);
+        RETURN_IF(mState == State::PROCESSING, EX_ILLEGAL_STATE, "closeAtProcessing");
+        mState = State::INIT;
+    }
 
+    RETURN_IF(notifyEventFlag(kEventFlagNotEmpty) != RetCode::SUCCESS, EX_ILLEGAL_STATE,
+              "notifyEventFlagFailed");
     // stop the worker thread, ignore the return code
     RETURN_IF(destroyThread() != RetCode::SUCCESS, EX_UNSUPPORTED_OPERATION,
               "FailedToDestroyWorker");
-    mState = State::INIT;
-    RETURN_IF(releaseContext() != RetCode::SUCCESS, EX_UNSUPPORTED_OPERATION,
-              "FailedToCreateWorker");
+
+    {
+        std::lock_guard lg(mImplMutex);
+        releaseContext();
+        mImplContext.reset();
+    }
 
     LOG(DEBUG) << getEffectName() << __func__;
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus EffectImpl::setParameter(const Parameter& param) {
+    std::lock_guard lg(mImplMutex);
     LOG(VERBOSE) << getEffectName() << __func__ << " with: " << param.toString();
 
-    const auto tag = param.getTag();
+    const auto& tag = param.getTag();
     switch (tag) {
         case Parameter::common:
         case Parameter::deviceDescription:
@@ -110,8 +124,8 @@
 }
 
 ndk::ScopedAStatus EffectImpl::getParameter(const Parameter::Id& id, Parameter* param) {
-    auto tag = id.getTag();
-    switch (tag) {
+    std::lock_guard lg(mImplMutex);
+    switch (id.getTag()) {
         case Parameter::Id::commonTag: {
             RETURN_IF_ASTATUS_NOT_OK(getParameterCommon(id.get<Parameter::Id::commonTag>(), param),
                                      "CommonParamNotSupported");
@@ -131,30 +145,30 @@
 }
 
 ndk::ScopedAStatus EffectImpl::setParameterCommon(const Parameter& param) {
-    auto context = getContext();
-    RETURN_IF(!context, EX_NULL_POINTER, "nullContext");
+    RETURN_IF(!mImplContext, EX_NULL_POINTER, "nullContext");
 
-    auto tag = param.getTag();
+    const auto& tag = param.getTag();
     switch (tag) {
         case Parameter::common:
-            RETURN_IF(context->setCommon(param.get<Parameter::common>()) != RetCode::SUCCESS,
+            RETURN_IF(mImplContext->setCommon(param.get<Parameter::common>()) != RetCode::SUCCESS,
                       EX_ILLEGAL_ARGUMENT, "setCommFailed");
             break;
         case Parameter::deviceDescription:
-            RETURN_IF(context->setOutputDevice(param.get<Parameter::deviceDescription>()) !=
+            RETURN_IF(mImplContext->setOutputDevice(param.get<Parameter::deviceDescription>()) !=
                               RetCode::SUCCESS,
                       EX_ILLEGAL_ARGUMENT, "setDeviceFailed");
             break;
         case Parameter::mode:
-            RETURN_IF(context->setAudioMode(param.get<Parameter::mode>()) != RetCode::SUCCESS,
+            RETURN_IF(mImplContext->setAudioMode(param.get<Parameter::mode>()) != RetCode::SUCCESS,
                       EX_ILLEGAL_ARGUMENT, "setModeFailed");
             break;
         case Parameter::source:
-            RETURN_IF(context->setAudioSource(param.get<Parameter::source>()) != RetCode::SUCCESS,
+            RETURN_IF(mImplContext->setAudioSource(param.get<Parameter::source>()) !=
+                              RetCode::SUCCESS,
                       EX_ILLEGAL_ARGUMENT, "setSourceFailed");
             break;
         case Parameter::volumeStereo:
-            RETURN_IF(context->setVolumeStereo(param.get<Parameter::volumeStereo>()) !=
+            RETURN_IF(mImplContext->setVolumeStereo(param.get<Parameter::volumeStereo>()) !=
                               RetCode::SUCCESS,
                       EX_ILLEGAL_ARGUMENT, "setVolumeStereoFailed");
             break;
@@ -169,28 +183,27 @@
 }
 
 ndk::ScopedAStatus EffectImpl::getParameterCommon(const Parameter::Tag& tag, Parameter* param) {
-    auto context = getContext();
-    RETURN_IF(!context, EX_NULL_POINTER, "nullContext");
+    RETURN_IF(!mImplContext, EX_NULL_POINTER, "nullContext");
 
     switch (tag) {
         case Parameter::common: {
-            param->set<Parameter::common>(context->getCommon());
+            param->set<Parameter::common>(mImplContext->getCommon());
             break;
         }
         case Parameter::deviceDescription: {
-            param->set<Parameter::deviceDescription>(context->getOutputDevice());
+            param->set<Parameter::deviceDescription>(mImplContext->getOutputDevice());
             break;
         }
         case Parameter::mode: {
-            param->set<Parameter::mode>(context->getAudioMode());
+            param->set<Parameter::mode>(mImplContext->getAudioMode());
             break;
         }
         case Parameter::source: {
-            param->set<Parameter::source>(context->getAudioSource());
+            param->set<Parameter::source>(mImplContext->getAudioSource());
             break;
         }
         case Parameter::volumeStereo: {
-            param->set<Parameter::volumeStereo>(context->getVolumeStereo());
+            param->set<Parameter::volumeStereo>(mImplContext->getVolumeStereo());
             break;
         }
         default: {
@@ -202,30 +215,34 @@
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus EffectImpl::getState(State* state) {
+ndk::ScopedAStatus EffectImpl::getState(State* state) NO_THREAD_SAFETY_ANALYSIS {
     *state = mState;
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus EffectImpl::command(CommandId command) {
-    RETURN_IF(mState == State::INIT, EX_ILLEGAL_STATE, "CommandStateError");
+    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:
-            RETURN_IF(mState == State::INIT, EX_ILLEGAL_STATE, "instanceNotOpen");
             RETURN_OK_IF(mState == State::PROCESSING);
             RETURN_IF_ASTATUS_NOT_OK(commandImpl(command), "commandImplFailed");
-            startThread();
             mState = State::PROCESSING;
+            RETURN_IF(notifyEventFlag(kEventFlagNotEmpty) != RetCode::SUCCESS, EX_ILLEGAL_STATE,
+                      "notifyEventFlagFailed");
+            startThread();
             break;
         case CommandId::STOP:
         case CommandId::RESET:
             RETURN_OK_IF(mState == State::IDLE);
+            mState = State::IDLE;
+            RETURN_IF(notifyEventFlag(kEventFlagNotEmpty) != RetCode::SUCCESS, EX_ILLEGAL_STATE,
+                      "notifyEventFlagFailed");
             stopThread();
             RETURN_IF_ASTATUS_NOT_OK(commandImpl(command), "commandImplFailed");
-            mState = State::IDLE;
             break;
         default:
             LOG(ERROR) << getEffectName() << __func__ << " instance still processing";
@@ -237,19 +254,41 @@
 }
 
 ndk::ScopedAStatus EffectImpl::commandImpl(CommandId command) {
-    auto context = getContext();
-    RETURN_IF(!context, EX_NULL_POINTER, "nullContext");
+    RETURN_IF(!mImplContext, EX_NULL_POINTER, "nullContext");
     if (command == CommandId::RESET) {
-        context->resetBuffer();
+        mImplContext->resetBuffer();
     }
     return ndk::ScopedAStatus::ok();
 }
 
+std::shared_ptr<EffectContext> EffectImpl::createContext(const Parameter::Common& common) {
+    return std::make_shared<EffectContext>(1 /* statusMqDepth */, common);
+}
+
+RetCode EffectImpl::releaseContext() {
+    if (mImplContext) {
+        mImplContext.reset();
+    }
+    return RetCode::SUCCESS;
+}
+
 void EffectImpl::cleanUp() {
     command(CommandId::STOP);
     close();
 }
 
+RetCode EffectImpl::notifyEventFlag(uint32_t flag) {
+    if (!mEventFlag) {
+        LOG(ERROR) << getEffectName() << __func__ << ": StatusEventFlag invalid";
+        return RetCode::ERROR_EVENT_FLAG_ERROR;
+    }
+    if (const auto ret = mEventFlag->wake(flag); ret != ::android::OK) {
+        LOG(ERROR) << getEffectName() << __func__ << ": wake failure with ret " << ret;
+        return RetCode::ERROR_EVENT_FLAG_ERROR;
+    }
+    return RetCode::SUCCESS;
+}
+
 IEffect::Status EffectImpl::status(binder_status_t status, size_t consumed, size_t produced) {
     IEffect::Status ret;
     ret.status = status;
@@ -258,6 +297,48 @@
     return ret;
 }
 
+void EffectImpl::process() {
+    /**
+     * wait for the EventFlag without lock, it's ok because the mEfGroup pointer will not change
+     * in the life cycle of workerThread (threadLoop).
+     */
+    uint32_t efState = 0;
+    if (!mEventFlag ||
+        ::android::OK != mEventFlag->wait(kEventFlagNotEmpty, &efState, 0 /* no timeout */,
+                                          true /* retry */) ||
+        !(efState & kEventFlagNotEmpty)) {
+        LOG(ERROR) << getEffectName() << __func__ << ": StatusEventFlag - " << mEventFlag
+                   << " efState - " << std::hex << efState;
+        return;
+    }
+
+    {
+        std::lock_guard lg(mImplMutex);
+        if (mState != State::PROCESSING) {
+            LOG(DEBUG) << getEffectName() << " skip process in state: " << toString(mState);
+            return;
+        }
+        RETURN_VALUE_IF(!mImplContext, void(), "nullContext");
+        auto statusMQ = mImplContext->getStatusFmq();
+        auto inputMQ = mImplContext->getInputDataFmq();
+        auto outputMQ = mImplContext->getOutputDataFmq();
+        auto buffer = mImplContext->getWorkBuffer();
+        if (!inputMQ || !outputMQ) {
+            return;
+        }
+
+        auto processSamples = inputMQ->availableToRead();
+        if (processSamples) {
+            inputMQ->read(buffer, processSamples);
+            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;
+        }
+    }
+}
+
 // A placeholder processing implementation to copy samples from input to output
 IEffect::Status EffectImpl::effectProcessImpl(float* in, float* out, int samples) {
     for (int i = 0; i < samples; i++) {
diff --git a/audio/aidl/default/EffectThread.cpp b/audio/aidl/default/EffectThread.cpp
index 47ba9f4..fdd4803 100644
--- a/audio/aidl/default/EffectThread.cpp
+++ b/audio/aidl/default/EffectThread.cpp
@@ -25,8 +25,6 @@
 #include "effect-impl/EffectThread.h"
 #include "effect-impl/EffectTypes.h"
 
-using ::android::hardware::EventFlag;
-
 namespace aidl::android::hardware::audio::effect {
 
 EffectThread::EffectThread() {
@@ -38,31 +36,18 @@
     LOG(DEBUG) << __func__ << " done";
 }
 
-RetCode EffectThread::createThread(std::shared_ptr<EffectContext> context, const std::string& name,
-                                   int priority) {
+RetCode EffectThread::createThread(const std::string& name, int priority) {
     if (mThread.joinable()) {
         LOG(WARNING) << mName << __func__ << " thread already created, no-op";
         return RetCode::SUCCESS;
     }
+
     mName = name;
     mPriority = priority;
     {
         std::lock_guard lg(mThreadMutex);
         mStop = true;
         mExit = false;
-        mThreadContext = std::move(context);
-        auto statusMQ = mThreadContext->getStatusFmq();
-        EventFlag* efGroup = nullptr;
-        ::android::status_t status =
-                EventFlag::createEventFlag(statusMQ->getEventFlagWord(), &efGroup);
-        if (status != ::android::OK || !efGroup) {
-            LOG(ERROR) << mName << __func__ << " create EventFlagGroup failed " << status
-                       << " efGroup " << efGroup;
-            return RetCode::ERROR_THREAD;
-        }
-        mEfGroup.reset(efGroup);
-        // kickoff and wait for commands (CommandId::START/STOP) or IEffect.close from client
-        mEfGroup->wake(kEventFlagNotEmpty);
     }
 
     mThread = std::thread(&EffectThread::threadLoop, this);
@@ -75,16 +60,12 @@
         std::lock_guard lg(mThreadMutex);
         mStop = mExit = true;
     }
-    mCv.notify_one();
 
+    mCv.notify_one();
     if (mThread.joinable()) {
         mThread.join();
     }
 
-    {
-        std::lock_guard lg(mThreadMutex);
-        mThreadContext.reset();
-    }
     LOG(DEBUG) << mName << __func__;
     return RetCode::SUCCESS;
 }
@@ -96,7 +77,6 @@
         mCv.notify_one();
     }
 
-    mEfGroup->wake(kEventFlagNotEmpty);
     LOG(DEBUG) << mName << __func__;
     return RetCode::SUCCESS;
 }
@@ -108,7 +88,6 @@
         mCv.notify_one();
     }
 
-    mEfGroup->wake(kEventFlagNotEmpty);
     LOG(DEBUG) << mName << __func__;
     return RetCode::SUCCESS;
 }
@@ -117,13 +96,6 @@
     pthread_setname_np(pthread_self(), mName.substr(0, kMaxTaskNameLen - 1).c_str());
     setpriority(PRIO_PROCESS, 0, mPriority);
     while (true) {
-        /**
-         * wait for the EventFlag without lock, it's ok because the mEfGroup pointer will not change
-         * in the life cycle of workerThread (threadLoop).
-         */
-        uint32_t efState = 0;
-        mEfGroup->wait(kEventFlagNotEmpty, &efState);
-
         {
             std::unique_lock l(mThreadMutex);
             ::android::base::ScopedLockAssertion lock_assertion(mThreadMutex);
@@ -132,27 +104,8 @@
                 LOG(INFO) << __func__ << " EXIT!";
                 return;
             }
-            process_l();
         }
-    }
-}
-
-void EffectThread::process_l() {
-    RETURN_VALUE_IF(!mThreadContext, void(), "nullContext");
-
-    auto statusMQ = mThreadContext->getStatusFmq();
-    auto inputMQ = mThreadContext->getInputDataFmq();
-    auto outputMQ = mThreadContext->getOutputDataFmq();
-    auto buffer = mThreadContext->getWorkBuffer();
-
-    auto processSamples = inputMQ->availableToRead();
-    if (processSamples) {
-        inputMQ->read(buffer, processSamples);
-        IEffect::Status status = effectProcessImpl(buffer, buffer, processSamples);
-        outputMQ->write(buffer, status.fmqProduced);
-        statusMQ->writeBlocking(&status, 1);
-        LOG(VERBOSE) << mName << __func__ << ": done processing, effect consumed "
-                     << status.fmqConsumed << " produced " << status.fmqProduced;
+        process();
     }
 }
 
diff --git a/audio/aidl/default/Stream.cpp b/audio/aidl/default/Stream.cpp
index a805b87..cf0870e 100644
--- a/audio/aidl/default/Stream.cpp
+++ b/audio/aidl/default/Stream.cpp
@@ -180,17 +180,20 @@
     StreamDescriptor::Reply reply{};
     reply.status = STATUS_BAD_VALUE;
     switch (command.getTag()) {
-        case Tag::halReservedExit:
-            if (const int32_t cookie = command.get<Tag::halReservedExit>();
-                cookie == (mContext->getInternalCommandCookie() ^ getTid())) {
+        case Tag::halReservedExit: {
+            const int32_t cookie = command.get<Tag::halReservedExit>();
+            if (cookie == (mContext->getInternalCommandCookie() ^ getTid())) {
                 mDriver->shutdown();
                 setClosed();
-                // This is an internal command, no need to reply.
-                return Status::EXIT;
             } else {
                 LOG(WARNING) << __func__ << ": EXIT command has a bad cookie: " << cookie;
             }
-            break;
+            if (cookie != 0) {  // This is an internal command, no need to reply.
+                return Status::EXIT;
+            } else {
+                break;
+            }
+        }
         case Tag::getStatus:
             populateReply(&reply, mIsConnected);
             break;
@@ -400,17 +403,20 @@
     reply.status = STATUS_BAD_VALUE;
     using Tag = StreamDescriptor::Command::Tag;
     switch (command.getTag()) {
-        case Tag::halReservedExit:
-            if (const int32_t cookie = command.get<Tag::halReservedExit>();
-                cookie == (mContext->getInternalCommandCookie() ^ getTid())) {
+        case Tag::halReservedExit: {
+            const int32_t cookie = command.get<Tag::halReservedExit>();
+            if (cookie == (mContext->getInternalCommandCookie() ^ getTid())) {
                 mDriver->shutdown();
                 setClosed();
-                // This is an internal command, no need to reply.
-                return Status::EXIT;
             } else {
                 LOG(WARNING) << __func__ << ": EXIT command has a bad cookie: " << cookie;
             }
-            break;
+            if (cookie != 0) {  // This is an internal command, no need to reply.
+                return Status::EXIT;
+            } else {
+                break;
+            }
+        }
         case Tag::getStatus:
             populateReply(&reply, mIsConnected);
             break;
diff --git a/audio/aidl/default/acousticEchoCanceler/AcousticEchoCancelerSw.cpp b/audio/aidl/default/acousticEchoCanceler/AcousticEchoCancelerSw.cpp
index 5e18f1b..be0927c 100644
--- a/audio/aidl/default/acousticEchoCanceler/AcousticEchoCancelerSw.cpp
+++ b/audio/aidl/default/acousticEchoCanceler/AcousticEchoCancelerSw.cpp
@@ -168,10 +168,6 @@
     return mContext;
 }
 
-std::shared_ptr<EffectContext> AcousticEchoCancelerSw::getContext() {
-    return mContext;
-}
-
 RetCode AcousticEchoCancelerSw::releaseContext() {
     if (mContext) {
         mContext.reset();
diff --git a/audio/aidl/default/acousticEchoCanceler/AcousticEchoCancelerSw.h b/audio/aidl/default/acousticEchoCanceler/AcousticEchoCancelerSw.h
index 73cf42b..95738f8 100644
--- a/audio/aidl/default/acousticEchoCanceler/AcousticEchoCancelerSw.h
+++ b/audio/aidl/default/acousticEchoCanceler/AcousticEchoCancelerSw.h
@@ -52,21 +52,23 @@
     }
 
     ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
-    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
-    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
-                                            Parameter::Specific* specific) override;
+    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
+            REQUIRES(mImplMutex) override;
+    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
+            REQUIRES(mImplMutex) override;
 
-    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
-    std::shared_ptr<EffectContext> getContext() override;
-    RetCode releaseContext() override;
+    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
+            REQUIRES(mImplMutex) override;
+    RetCode releaseContext() REQUIRES(mImplMutex) override;
 
     std::string getEffectName() override { return kEffectName; };
     IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
 
   private:
     static const std::vector<Range::AcousticEchoCancelerRange> kRanges;
-    std::shared_ptr<AcousticEchoCancelerSwContext> mContext;
+    std::shared_ptr<AcousticEchoCancelerSwContext> mContext GUARDED_BY(mImplMutex);
     ndk::ScopedAStatus getParameterAcousticEchoCanceler(const AcousticEchoCanceler::Tag& tag,
-                                                        Parameter::Specific* specific);
+                                                        Parameter::Specific* specific)
+            REQUIRES(mImplMutex);
 };
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/automaticGainControlV1/AutomaticGainControlV1Sw.cpp b/audio/aidl/default/automaticGainControlV1/AutomaticGainControlV1Sw.cpp
index ce10ae1..d865b7e 100644
--- a/audio/aidl/default/automaticGainControlV1/AutomaticGainControlV1Sw.cpp
+++ b/audio/aidl/default/automaticGainControlV1/AutomaticGainControlV1Sw.cpp
@@ -177,10 +177,6 @@
     return mContext;
 }
 
-std::shared_ptr<EffectContext> AutomaticGainControlV1Sw::getContext() {
-    return mContext;
-}
-
 RetCode AutomaticGainControlV1Sw::releaseContext() {
     if (mContext) {
         mContext.reset();
diff --git a/audio/aidl/default/automaticGainControlV1/AutomaticGainControlV1Sw.h b/audio/aidl/default/automaticGainControlV1/AutomaticGainControlV1Sw.h
index 7d2a69f..76b91ae 100644
--- a/audio/aidl/default/automaticGainControlV1/AutomaticGainControlV1Sw.h
+++ b/audio/aidl/default/automaticGainControlV1/AutomaticGainControlV1Sw.h
@@ -53,21 +53,24 @@
     }
 
     ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
-    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
-    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
-                                            Parameter::Specific* specific) override;
+    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
+            REQUIRES(mImplMutex) override;
+    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
+            REQUIRES(mImplMutex) override;
 
-    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
-    std::shared_ptr<EffectContext> getContext() override;
-    RetCode releaseContext() override;
+    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
+            REQUIRES(mImplMutex) override;
+    RetCode releaseContext() REQUIRES(mImplMutex) override;
 
     std::string getEffectName() override { return kEffectName; };
-    IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+    IEffect::Status effectProcessImpl(float* in, float* out, int samples)
+            REQUIRES(mImplMutex) override;
 
   private:
     static const std::vector<Range::AutomaticGainControlV1Range> kRanges;
-    std::shared_ptr<AutomaticGainControlV1SwContext> mContext;
+    std::shared_ptr<AutomaticGainControlV1SwContext> mContext GUARDED_BY(mImplMutex);
     ndk::ScopedAStatus getParameterAutomaticGainControlV1(const AutomaticGainControlV1::Tag& tag,
-                                                          Parameter::Specific* specific);
+                                                          Parameter::Specific* specific)
+            REQUIRES(mImplMutex);
 };
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/automaticGainControlV2/AutomaticGainControlV2Sw.cpp b/audio/aidl/default/automaticGainControlV2/AutomaticGainControlV2Sw.cpp
index 1e336ac..3ff6e38 100644
--- a/audio/aidl/default/automaticGainControlV2/AutomaticGainControlV2Sw.cpp
+++ b/audio/aidl/default/automaticGainControlV2/AutomaticGainControlV2Sw.cpp
@@ -180,10 +180,6 @@
     return mContext;
 }
 
-std::shared_ptr<EffectContext> AutomaticGainControlV2Sw::getContext() {
-    return mContext;
-}
-
 RetCode AutomaticGainControlV2Sw::releaseContext() {
     if (mContext) {
         mContext.reset();
diff --git a/audio/aidl/default/automaticGainControlV2/AutomaticGainControlV2Sw.h b/audio/aidl/default/automaticGainControlV2/AutomaticGainControlV2Sw.h
index 9aa60ea..863d470 100644
--- a/audio/aidl/default/automaticGainControlV2/AutomaticGainControlV2Sw.h
+++ b/audio/aidl/default/automaticGainControlV2/AutomaticGainControlV2Sw.h
@@ -59,21 +59,24 @@
     }
 
     ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
-    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
-    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
-                                            Parameter::Specific* specific) override;
+    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
+            REQUIRES(mImplMutex) override;
+    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
+            REQUIRES(mImplMutex) override;
 
-    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
-    std::shared_ptr<EffectContext> getContext() override;
-    RetCode releaseContext() override;
+    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
+            REQUIRES(mImplMutex) override;
+    RetCode releaseContext() REQUIRES(mImplMutex) override;
 
     std::string getEffectName() override { return kEffectName; };
-    IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+    IEffect::Status effectProcessImpl(float* in, float* out, int samples)
+            REQUIRES(mImplMutex) override;
 
   private:
     static const std::vector<Range::AutomaticGainControlV2Range> kRanges;
-    std::shared_ptr<AutomaticGainControlV2SwContext> mContext;
+    std::shared_ptr<AutomaticGainControlV2SwContext> mContext GUARDED_BY(mImplMutex);
     ndk::ScopedAStatus getParameterAutomaticGainControlV2(const AutomaticGainControlV2::Tag& tag,
-                                                          Parameter::Specific* specific);
+                                                          Parameter::Specific* specific)
+            REQUIRES(mImplMutex);
 };
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/bassboost/BassBoostSw.cpp b/audio/aidl/default/bassboost/BassBoostSw.cpp
index 6072d89..60adc30 100644
--- a/audio/aidl/default/bassboost/BassBoostSw.cpp
+++ b/audio/aidl/default/bassboost/BassBoostSw.cpp
@@ -151,10 +151,6 @@
     return mContext;
 }
 
-std::shared_ptr<EffectContext> BassBoostSw::getContext() {
-    return mContext;
-}
-
 RetCode BassBoostSw::releaseContext() {
     if (mContext) {
         mContext.reset();
diff --git a/audio/aidl/default/bassboost/BassBoostSw.h b/audio/aidl/default/bassboost/BassBoostSw.h
index 1132472..901e455 100644
--- a/audio/aidl/default/bassboost/BassBoostSw.h
+++ b/audio/aidl/default/bassboost/BassBoostSw.h
@@ -51,21 +51,23 @@
     }
 
     ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
-    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
-    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
-                                            Parameter::Specific* specific) override;
+    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
+            REQUIRES(mImplMutex) override;
+    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
+            REQUIRES(mImplMutex) override;
 
-    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
-    std::shared_ptr<EffectContext> getContext() override;
-    RetCode releaseContext() override;
+    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
+            REQUIRES(mImplMutex) override;
+    RetCode releaseContext() REQUIRES(mImplMutex) override;
 
     std::string getEffectName() override { return kEffectName; };
-    IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+    IEffect::Status effectProcessImpl(float* in, float* out, int samples)
+            REQUIRES(mImplMutex) override;
 
   private:
     static const std::vector<Range::BassBoostRange> kRanges;
-    std::shared_ptr<BassBoostSwContext> mContext;
+    std::shared_ptr<BassBoostSwContext> mContext GUARDED_BY(mImplMutex);
     ndk::ScopedAStatus getParameterBassBoost(const BassBoost::Tag& tag,
-                                             Parameter::Specific* specific);
+                                             Parameter::Specific* specific) REQUIRES(mImplMutex);
 };
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/downmix/DownmixSw.cpp b/audio/aidl/default/downmix/DownmixSw.cpp
index ce5fe20..19ab2e8 100644
--- a/audio/aidl/default/downmix/DownmixSw.cpp
+++ b/audio/aidl/default/downmix/DownmixSw.cpp
@@ -144,10 +144,6 @@
     return mContext;
 }
 
-std::shared_ptr<EffectContext> DownmixSw::getContext() {
-    return mContext;
-}
-
 RetCode DownmixSw::releaseContext() {
     if (mContext) {
         mContext.reset();
diff --git a/audio/aidl/default/downmix/DownmixSw.h b/audio/aidl/default/downmix/DownmixSw.h
index 3f8a09b..1a9f0f0 100644
--- a/audio/aidl/default/downmix/DownmixSw.h
+++ b/audio/aidl/default/downmix/DownmixSw.h
@@ -55,20 +55,23 @@
     }
 
     ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
-    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
-    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
-                                            Parameter::Specific* specific) override;
+    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
+            REQUIRES(mImplMutex) override;
+    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
+            REQUIRES(mImplMutex) override;
 
-    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
-    std::shared_ptr<EffectContext> getContext() override;
-    RetCode releaseContext() override;
+    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
+            REQUIRES(mImplMutex) override;
+    RetCode releaseContext() REQUIRES(mImplMutex) override;
 
     std::string getEffectName() override { return kEffectName; };
-    IEffect::Status effectProcessImpl(float* in, float* out, int sample) override;
+    IEffect::Status effectProcessImpl(float* in, float* out, int sample)
+            REQUIRES(mImplMutex) override;
 
   private:
-    std::shared_ptr<DownmixSwContext> mContext;
+    std::shared_ptr<DownmixSwContext> mContext GUARDED_BY(mImplMutex);
 
-    ndk::ScopedAStatus getParameterDownmix(const Downmix::Tag& tag, Parameter::Specific* specific);
+    ndk::ScopedAStatus getParameterDownmix(const Downmix::Tag& tag, Parameter::Specific* specific)
+            REQUIRES(mImplMutex);
 };
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.cpp b/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.cpp
index e8f90b2..36face1 100644
--- a/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.cpp
+++ b/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.cpp
@@ -260,10 +260,6 @@
     return mContext;
 }
 
-std::shared_ptr<EffectContext> DynamicsProcessingSw::getContext() {
-    return mContext;
-}
-
 RetCode DynamicsProcessingSw::releaseContext() {
     if (mContext) {
         mContext.reset();
@@ -282,6 +278,9 @@
 }
 
 RetCode DynamicsProcessingSwContext::setCommon(const Parameter::Common& common) {
+    if (auto ret = updateIOFrameSize(common); ret != RetCode::SUCCESS) {
+        return ret;
+    }
     mCommon = common;
     mChannelCount = ::aidl::android::hardware::audio::common::getChannelCount(
             common.input.base.channelMask);
diff --git a/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.h b/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.h
index 641cf71..98edca0 100644
--- a/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.h
+++ b/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.h
@@ -113,15 +113,17 @@
     }
 
     ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
-    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
-    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
-                                            Parameter::Specific* specific) override;
+    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
+            REQUIRES(mImplMutex) override;
+    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
+            REQUIRES(mImplMutex) override;
 
-    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
-    std::shared_ptr<EffectContext> getContext() override;
-    RetCode releaseContext() override;
+    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
+            REQUIRES(mImplMutex) override;
+    RetCode releaseContext() REQUIRES(mImplMutex) override;
 
-    IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+    IEffect::Status effectProcessImpl(float* in, float* out, int samples)
+            REQUIRES(mImplMutex) override;
     std::string getEffectName() override { return kEffectName; };
 
   private:
@@ -130,9 +132,10 @@
     static const Range::DynamicsProcessingRange kPreEqBandRange;
     static const Range::DynamicsProcessingRange kPostEqBandRange;
     static const std::vector<Range::DynamicsProcessingRange> kRanges;
-    std::shared_ptr<DynamicsProcessingSwContext> mContext;
+    std::shared_ptr<DynamicsProcessingSwContext> mContext GUARDED_BY(mImplMutex);
     ndk::ScopedAStatus getParameterDynamicsProcessing(const DynamicsProcessing::Tag& tag,
-                                                      Parameter::Specific* specific);
+                                                      Parameter::Specific* specific)
+            REQUIRES(mImplMutex);
 
 };  // DynamicsProcessingSw
 
diff --git a/audio/aidl/default/envReverb/EnvReverbSw.cpp b/audio/aidl/default/envReverb/EnvReverbSw.cpp
index 73975c6..7937a6a 100644
--- a/audio/aidl/default/envReverb/EnvReverbSw.cpp
+++ b/audio/aidl/default/envReverb/EnvReverbSw.cpp
@@ -267,10 +267,6 @@
     return mContext;
 }
 
-std::shared_ptr<EffectContext> EnvReverbSw::getContext() {
-    return mContext;
-}
-
 RetCode EnvReverbSw::releaseContext() {
     if (mContext) {
         mContext.reset();
diff --git a/audio/aidl/default/envReverb/EnvReverbSw.h b/audio/aidl/default/envReverb/EnvReverbSw.h
index 5e31e2f..367462b 100644
--- a/audio/aidl/default/envReverb/EnvReverbSw.h
+++ b/audio/aidl/default/envReverb/EnvReverbSw.h
@@ -100,21 +100,23 @@
     }
 
     ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
-    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
-    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
-                                            Parameter::Specific* specific) override;
+    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
+            REQUIRES(mImplMutex) override;
+    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
+            REQUIRES(mImplMutex) override;
 
-    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
-    std::shared_ptr<EffectContext> getContext() override;
-    RetCode releaseContext() override;
+    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
+            REQUIRES(mImplMutex) override;
+    RetCode releaseContext() REQUIRES(mImplMutex) override;
 
     IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
     std::string getEffectName() override { return kEffectName; }
 
   private:
     static const std::vector<Range::EnvironmentalReverbRange> kRanges;
-    std::shared_ptr<EnvReverbSwContext> mContext;
+    std::shared_ptr<EnvReverbSwContext> mContext GUARDED_BY(mImplMutex);
     ndk::ScopedAStatus getParameterEnvironmentalReverb(const EnvironmentalReverb::Tag& tag,
-                                                       Parameter::Specific* specific);
+                                                       Parameter::Specific* specific)
+            REQUIRES(mImplMutex);
 };
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/equalizer/EqualizerSw.cpp b/audio/aidl/default/equalizer/EqualizerSw.cpp
index b2add31..640b3ba 100644
--- a/audio/aidl/default/equalizer/EqualizerSw.cpp
+++ b/audio/aidl/default/equalizer/EqualizerSw.cpp
@@ -198,10 +198,6 @@
     return mContext;
 }
 
-std::shared_ptr<EffectContext> EqualizerSw::getContext() {
-    return mContext;
-}
-
 RetCode EqualizerSw::releaseContext() {
     if (mContext) {
         mContext.reset();
diff --git a/audio/aidl/default/equalizer/EqualizerSw.h b/audio/aidl/default/equalizer/EqualizerSw.h
index 56af3b5..caaa129 100644
--- a/audio/aidl/default/equalizer/EqualizerSw.h
+++ b/audio/aidl/default/equalizer/EqualizerSw.h
@@ -97,15 +97,17 @@
     }
 
     ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
-    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
-    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
-                                            Parameter::Specific* specific) override;
+    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
+            REQUIRES(mImplMutex) override;
+    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
+            REQUIRES(mImplMutex) override;
 
-    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
-    std::shared_ptr<EffectContext> getContext() override;
-    RetCode releaseContext() override;
+    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
+            REQUIRES(mImplMutex) override;
+    RetCode releaseContext() REQUIRES(mImplMutex) override;
 
-    IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+    IEffect::Status effectProcessImpl(float* in, float* out, int samples)
+            REQUIRES(mImplMutex) override;
     std::string getEffectName() override { return kEffectName; }
 
   private:
@@ -113,7 +115,7 @@
     static const std::vector<Equalizer::Preset> kPresets;
     static const std::vector<Range::EqualizerRange> kRanges;
     ndk::ScopedAStatus getParameterEqualizer(const Equalizer::Tag& tag,
-                                             Parameter::Specific* specific);
+                                             Parameter::Specific* specific) REQUIRES(mImplMutex);
     std::shared_ptr<EqualizerSwContext> mContext;
 };
 
diff --git a/audio/aidl/default/extension/ExtensionEffect.cpp b/audio/aidl/default/extension/ExtensionEffect.cpp
index 4a4d71b6..11916c8 100644
--- a/audio/aidl/default/extension/ExtensionEffect.cpp
+++ b/audio/aidl/default/extension/ExtensionEffect.cpp
@@ -123,10 +123,6 @@
     return mContext;
 }
 
-std::shared_ptr<EffectContext> ExtensionEffect::getContext() {
-    return mContext;
-}
-
 RetCode ExtensionEffect::releaseContext() {
     if (mContext) {
         mContext.reset();
diff --git a/audio/aidl/default/extension/ExtensionEffect.h b/audio/aidl/default/extension/ExtensionEffect.h
index e7a068b..b560860 100644
--- a/audio/aidl/default/extension/ExtensionEffect.h
+++ b/audio/aidl/default/extension/ExtensionEffect.h
@@ -54,18 +54,20 @@
     }
 
     ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
-    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
-    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
-                                            Parameter::Specific* specific) override;
+    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
+            REQUIRES(mImplMutex) override;
+    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
+            REQUIRES(mImplMutex) override;
 
-    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
-    std::shared_ptr<EffectContext> getContext() override;
-    RetCode releaseContext() override;
+    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
+            REQUIRES(mImplMutex) override;
+    RetCode releaseContext() REQUIRES(mImplMutex) override;
 
     std::string getEffectName() override { return kEffectName; };
-    IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+    IEffect::Status effectProcessImpl(float* in, float* out, int samples)
+            REQUIRES(mImplMutex) override;
 
   private:
-    std::shared_ptr<ExtensionEffectContext> mContext;
+    std::shared_ptr<ExtensionEffectContext> mContext GUARDED_BY(mImplMutex);
 };
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/hapticGenerator/HapticGeneratorSw.cpp b/audio/aidl/default/hapticGenerator/HapticGeneratorSw.cpp
index 27cdac8..7469ab9 100644
--- a/audio/aidl/default/hapticGenerator/HapticGeneratorSw.cpp
+++ b/audio/aidl/default/hapticGenerator/HapticGeneratorSw.cpp
@@ -158,10 +158,6 @@
     return mContext;
 }
 
-std::shared_ptr<EffectContext> HapticGeneratorSw::getContext() {
-    return mContext;
-}
-
 RetCode HapticGeneratorSw::releaseContext() {
     if (mContext) {
         mContext.reset();
diff --git a/audio/aidl/default/hapticGenerator/HapticGeneratorSw.h b/audio/aidl/default/hapticGenerator/HapticGeneratorSw.h
index 3bbe41a..47f3848 100644
--- a/audio/aidl/default/hapticGenerator/HapticGeneratorSw.h
+++ b/audio/aidl/default/hapticGenerator/HapticGeneratorSw.h
@@ -67,21 +67,24 @@
     }
 
     ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
-    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
-    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
-                                            Parameter::Specific* specific) override;
+    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
+            REQUIRES(mImplMutex) override;
+    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
+            REQUIRES(mImplMutex) override;
 
-    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
-    std::shared_ptr<EffectContext> getContext() override;
-    RetCode releaseContext() override;
+    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
+            REQUIRES(mImplMutex) override;
+    RetCode releaseContext() REQUIRES(mImplMutex) override;
 
-    IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+    IEffect::Status effectProcessImpl(float* in, float* out, int samples)
+            REQUIRES(mImplMutex) override;
     std::string getEffectName() override { return kEffectName; }
 
   private:
-    std::shared_ptr<HapticGeneratorSwContext> mContext;
+    std::shared_ptr<HapticGeneratorSwContext> mContext GUARDED_BY(mImplMutex);
 
     ndk::ScopedAStatus getParameterHapticGenerator(const HapticGenerator::Tag& tag,
-                                                   Parameter::Specific* specific);
+                                                   Parameter::Specific* specific)
+            REQUIRES(mImplMutex);
 };
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/include/core-impl/Stream.h b/audio/aidl/default/include/core-impl/Stream.h
index aa9fb19..21e63f9 100644
--- a/audio/aidl/default/include/core-impl/Stream.h
+++ b/audio/aidl/default/include/core-impl/Stream.h
@@ -90,7 +90,7 @@
                   std::weak_ptr<sounddose::StreamDataProcessorInterface> streamDataProcessor,
                   DebugParameters debugParameters)
         : mCommandMQ(std::move(commandMQ)),
-          mInternalCommandCookie(std::rand()),
+          mInternalCommandCookie(std::rand() | 1 /* make sure it's not 0 */),
           mReplyMQ(std::move(replyMQ)),
           mFormat(format),
           mChannelLayout(channelLayout),
diff --git a/audio/aidl/default/include/effect-impl/EffectContext.h b/audio/aidl/default/include/effect-impl/EffectContext.h
index 89d0c7c..24f3b5d 100644
--- a/audio/aidl/default/include/effect-impl/EffectContext.h
+++ b/audio/aidl/default/include/effect-impl/EffectContext.h
@@ -21,6 +21,7 @@
 #include <Utils.h>
 #include <android-base/logging.h>
 #include <fmq/AidlMessageQueue.h>
+#include <fmq/EventFlag.h>
 
 #include <aidl/android/hardware/audio/effect/BnEffect.h>
 #include "EffectTypes.h"
@@ -36,127 +37,73 @@
             float, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>
             DataMQ;
 
-    EffectContext(size_t statusDepth, const Parameter::Common& common) {
-        auto& input = common.input;
-        auto& output = common.output;
-
-        LOG_ALWAYS_FATAL_IF(
-                input.base.format.pcm != aidl::android::media::audio::common::PcmType::FLOAT_32_BIT,
-                "inputFormatNotFloat");
-        LOG_ALWAYS_FATAL_IF(output.base.format.pcm !=
-                                    aidl::android::media::audio::common::PcmType::FLOAT_32_BIT,
-                            "outputFormatNotFloat");
-
-        size_t inputChannelCount =
-                ::aidl::android::hardware::audio::common::getChannelCount(input.base.channelMask);
-        LOG_ALWAYS_FATAL_IF(inputChannelCount == 0, "inputChannelCountNotValid");
-        size_t outputChannelCount =
-                ::aidl::android::hardware::audio::common::getChannelCount(output.base.channelMask);
-        LOG_ALWAYS_FATAL_IF(outputChannelCount == 0, "outputChannelCountNotValid");
-
-        mInputFrameSize = ::aidl::android::hardware::audio::common::getFrameSizeInBytes(
-                input.base.format, input.base.channelMask);
-        mOutputFrameSize = ::aidl::android::hardware::audio::common::getFrameSizeInBytes(
-                output.base.format, output.base.channelMask);
-        // in/outBuffer size in float (FMQ data format defined for DataMQ)
-        size_t inBufferSizeInFloat = input.frameCount * mInputFrameSize / sizeof(float);
-        size_t outBufferSizeInFloat = output.frameCount * mOutputFrameSize / sizeof(float);
-
-        // only status FMQ use the EventFlag
-        mStatusMQ = std::make_shared<StatusMQ>(statusDepth, true /*configureEventFlagWord*/);
-        mInputMQ = std::make_shared<DataMQ>(inBufferSizeInFloat);
-        mOutputMQ = std::make_shared<DataMQ>(outBufferSizeInFloat);
-
-        if (!mStatusMQ->isValid() || !mInputMQ->isValid() || !mOutputMQ->isValid()) {
-            LOG(ERROR) << __func__ << " created invalid FMQ";
+    EffectContext(size_t statusDepth, const Parameter::Common& common);
+    virtual ~EffectContext() {
+        if (mEfGroup) {
+            ::android::hardware::EventFlag::deleteEventFlag(&mEfGroup);
         }
-        mWorkBuffer.reserve(std::max(inBufferSizeInFloat, outBufferSizeInFloat));
-        mCommon = common;
     }
-    virtual ~EffectContext() {}
 
-    std::shared_ptr<StatusMQ> getStatusFmq() { return mStatusMQ; }
-    std::shared_ptr<DataMQ> getInputDataFmq() { return mInputMQ; }
-    std::shared_ptr<DataMQ> getOutputDataFmq() { return mOutputMQ; }
+    std::shared_ptr<StatusMQ> getStatusFmq() const;
+    std::shared_ptr<DataMQ> getInputDataFmq() const;
+    std::shared_ptr<DataMQ> getOutputDataFmq() const;
 
-    float* getWorkBuffer() { return static_cast<float*>(mWorkBuffer.data()); }
+    float* getWorkBuffer();
 
     // reset buffer status by abandon input data in FMQ
-    void resetBuffer() {
-        auto buffer = static_cast<float*>(mWorkBuffer.data());
-        std::vector<IEffect::Status> status(mStatusMQ->availableToRead());
-        mInputMQ->read(buffer, mInputMQ->availableToRead());
-    }
+    void resetBuffer();
+    void dupeFmq(IEffect::OpenEffectReturn* effectRet);
+    size_t getInputFrameSize() const;
+    size_t getOutputFrameSize() const;
+    int getSessionId() const;
+    int getIoHandle() const;
 
-    void dupeFmq(IEffect::OpenEffectReturn* effectRet) {
-        if (effectRet) {
-            effectRet->statusMQ = mStatusMQ->dupeDesc();
-            effectRet->inputDataMQ = mInputMQ->dupeDesc();
-            effectRet->outputDataMQ = mOutputMQ->dupeDesc();
-        }
-    }
-    size_t getInputFrameSize() { return mInputFrameSize; }
-    size_t getOutputFrameSize() { return mOutputFrameSize; }
-    int getSessionId() { return mCommon.session; }
-    int getIoHandle() { return mCommon.ioHandle; }
+    virtual void dupeFmqWithReopen(IEffect::OpenEffectReturn* effectRet);
 
     virtual RetCode setOutputDevice(
-            const std::vector<aidl::android::media::audio::common::AudioDeviceDescription>&
-                    device) {
-        mOutputDevice = device;
-        return RetCode::SUCCESS;
-    }
+            const std::vector<aidl::android::media::audio::common::AudioDeviceDescription>& device);
 
     virtual std::vector<aidl::android::media::audio::common::AudioDeviceDescription>
-    getOutputDevice() {
-        return mOutputDevice;
-    }
+    getOutputDevice();
 
-    virtual RetCode setAudioMode(const aidl::android::media::audio::common::AudioMode& mode) {
-        mMode = mode;
-        return RetCode::SUCCESS;
-    }
-    virtual aidl::android::media::audio::common::AudioMode getAudioMode() { return mMode; }
+    virtual RetCode setAudioMode(const aidl::android::media::audio::common::AudioMode& mode);
+    virtual aidl::android::media::audio::common::AudioMode getAudioMode();
 
-    virtual RetCode setAudioSource(const aidl::android::media::audio::common::AudioSource& source) {
-        mSource = source;
-        return RetCode::SUCCESS;
-    }
-    virtual aidl::android::media::audio::common::AudioSource getAudioSource() { return mSource; }
+    virtual RetCode setAudioSource(const aidl::android::media::audio::common::AudioSource& source);
+    virtual aidl::android::media::audio::common::AudioSource getAudioSource();
 
-    virtual RetCode setVolumeStereo(const Parameter::VolumeStereo& volumeStereo) {
-        mVolumeStereo = volumeStereo;
-        return RetCode::SUCCESS;
-    }
-    virtual Parameter::VolumeStereo getVolumeStereo() { return mVolumeStereo; }
+    virtual RetCode setVolumeStereo(const Parameter::VolumeStereo& volumeStereo);
+    virtual Parameter::VolumeStereo getVolumeStereo();
 
-    virtual RetCode setCommon(const Parameter::Common& common) {
-        mCommon = common;
-        LOG(VERBOSE) << __func__ << mCommon.toString();
-        return RetCode::SUCCESS;
-    }
-    virtual Parameter::Common getCommon() {
-        LOG(VERBOSE) << __func__ << mCommon.toString();
-        return mCommon;
-    }
+    virtual RetCode setCommon(const Parameter::Common& common);
+    virtual Parameter::Common getCommon();
+
+    virtual ::android::hardware::EventFlag* getStatusEventFlag();
 
   protected:
-    // common parameters
     size_t mInputFrameSize;
     size_t mOutputFrameSize;
-    Parameter::Common mCommon;
-    std::vector<aidl::android::media::audio::common::AudioDeviceDescription> mOutputDevice;
-    aidl::android::media::audio::common::AudioMode mMode;
-    aidl::android::media::audio::common::AudioSource mSource;
-    Parameter::VolumeStereo mVolumeStereo;
+    size_t mInputChannelCount;
+    size_t mOutputChannelCount;
+    Parameter::Common mCommon = {};
+    std::vector<aidl::android::media::audio::common::AudioDeviceDescription> mOutputDevice = {};
+    aidl::android::media::audio::common::AudioMode mMode =
+            aidl::android::media::audio::common::AudioMode::SYS_RESERVED_INVALID;
+    aidl::android::media::audio::common::AudioSource mSource =
+            aidl::android::media::audio::common::AudioSource::SYS_RESERVED_INVALID;
+    Parameter::VolumeStereo mVolumeStereo = {};
+    RetCode updateIOFrameSize(const Parameter::Common& common);
+    RetCode notifyDataMqUpdate();
 
   private:
     // fmq and buffers
     std::shared_ptr<StatusMQ> mStatusMQ;
     std::shared_ptr<DataMQ> mInputMQ;
     std::shared_ptr<DataMQ> mOutputMQ;
-    // TODO handle effect process input and output
+    // std::shared_ptr<IEffect::OpenEffectReturn> mRet;
     // work buffer set by effect instances, the access and update are in same thread
     std::vector<float> mWorkBuffer;
+
+    ::android::hardware::EventFlag* mEfGroup;
 };
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/include/effect-impl/EffectImpl.h b/audio/aidl/default/include/effect-impl/EffectImpl.h
index 242a268..21f6502 100644
--- a/audio/aidl/default/include/effect-impl/EffectImpl.h
+++ b/audio/aidl/default/include/effect-impl/EffectImpl.h
@@ -49,33 +49,54 @@
     virtual ndk::ScopedAStatus setParameter(const Parameter& param) override;
     virtual ndk::ScopedAStatus getParameter(const Parameter::Id& id, Parameter* param) override;
 
-    virtual ndk::ScopedAStatus setParameterCommon(const Parameter& param);
-    virtual ndk::ScopedAStatus getParameterCommon(const Parameter::Tag& tag, Parameter* param);
+    virtual ndk::ScopedAStatus setParameterCommon(const Parameter& param) REQUIRES(mImplMutex);
+    virtual ndk::ScopedAStatus getParameterCommon(const Parameter::Tag& tag, Parameter* param)
+            REQUIRES(mImplMutex);
 
     /* Methods MUST be implemented by each effect instances */
     virtual ndk::ScopedAStatus getDescriptor(Descriptor* desc) = 0;
-    virtual ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) = 0;
+    virtual ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
+            REQUIRES(mImplMutex) = 0;
     virtual ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
-                                                    Parameter::Specific* specific) = 0;
+                                                    Parameter::Specific* specific)
+            REQUIRES(mImplMutex) = 0;
 
     virtual std::string getEffectName() = 0;
-    virtual IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+    virtual std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
+            REQUIRES(mImplMutex);
+    virtual RetCode releaseContext() REQUIRES(mImplMutex) = 0;
 
     /**
-     * Effect context methods must be implemented by each effect.
-     * Each effect can derive from EffectContext and define its own context, but must upcast to
-     * EffectContext for EffectImpl to use.
+     * @brief effectProcessImpl is running in worker thread which created in EffectThread.
+     *
+     * EffectThread will make sure effectProcessImpl only be called after startThread() successful
+     * and before stopThread() successful.
+     *
+     * effectProcessImpl implementation must not call any EffectThread interface, otherwise it will
+     * cause deadlock.
+     *
+     * @param in address of input float buffer.
+     * @param out address of output float buffer.
+     * @param samples number of samples to process.
+     * @return IEffect::Status
      */
-    virtual std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) = 0;
-    virtual std::shared_ptr<EffectContext> getContext() = 0;
-    virtual RetCode releaseContext() = 0;
+    virtual IEffect::Status effectProcessImpl(float* in, float* out, int samples) = 0;
+
+    /**
+     * process() get data from data MQs, and call effectProcessImpl() for effect data processing.
+     * Its important for the implementation to use mImplMutex for context synchronization.
+     */
+    void process() override;
 
   protected:
-    State mState = State::INIT;
+    State mState GUARDED_BY(mImplMutex) = State::INIT;
 
     IEffect::Status status(binder_status_t status, size_t consumed, size_t produced);
     void cleanUp();
 
+    std::mutex mImplMutex;
+    std::shared_ptr<EffectContext> mImplContext GUARDED_BY(mImplMutex);
+
     /**
      * Optional CommandId handling methods for effects to override.
      * For CommandId::START, EffectImpl call commandImpl before starting the EffectThread
@@ -83,6 +104,9 @@
      * For CommandId::STOP and CommandId::RESET, EffectImpl call commandImpl after stop the
      * EffectThread processing.
      */
-    virtual ndk::ScopedAStatus commandImpl(CommandId id);
+    virtual ndk::ScopedAStatus commandImpl(CommandId id) REQUIRES(mImplMutex);
+
+    RetCode notifyEventFlag(uint32_t flag);
+    ::android::hardware::EventFlag* mEventFlag;
 };
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/include/effect-impl/EffectThread.h b/audio/aidl/default/include/effect-impl/EffectThread.h
index ae51ef7..3dbb0e6 100644
--- a/audio/aidl/default/include/effect-impl/EffectThread.h
+++ b/audio/aidl/default/include/effect-impl/EffectThread.h
@@ -36,8 +36,7 @@
     virtual ~EffectThread();
 
     // called by effect implementation.
-    RetCode createThread(std::shared_ptr<EffectContext> context, const std::string& name,
-                         int priority = ANDROID_PRIORITY_URGENT_AUDIO);
+    RetCode createThread(const std::string& name, int priority = ANDROID_PRIORITY_URGENT_AUDIO);
     RetCode destroyThread();
     RetCode startThread();
     RetCode stopThread();
@@ -46,32 +45,11 @@
     void threadLoop();
 
     /**
-     * @brief effectProcessImpl is running in worker thread which created in EffectThread.
-     *
-     * Effect implementation should think about concurrency in the implementation if necessary.
-     * Parameter setting usually implemented in context (derived from EffectContext), and some
-     * parameter maybe used in the processing, then effect implementation should consider using a
-     * mutex to protect these parameter.
-     *
-     * EffectThread will make sure effectProcessImpl only be called after startThread() successful
-     * and before stopThread() successful.
-     *
-     * effectProcessImpl implementation must not call any EffectThread interface, otherwise it will
-     * cause deadlock.
-     *
-     * @param in address of input float buffer.
-     * @param out address of output float buffer.
-     * @param samples number of samples to process.
-     * @return IEffect::Status
-     */
-    virtual IEffect::Status effectProcessImpl(float* in, float* out, int samples) = 0;
-
-    /**
      * process() call effectProcessImpl() for effect data processing, it is necessary for the
      * processing to be called under Effect thread mutex mThreadMutex, to avoid the effect state
      * change before/during data processing, and keep the thread and effect state consistent.
      */
-    virtual void process_l() REQUIRES(mThreadMutex);
+    virtual void process() = 0;
 
   private:
     static constexpr int kMaxTaskNameLen = 15;
@@ -80,16 +58,7 @@
     std::condition_variable mCv;
     bool mStop GUARDED_BY(mThreadMutex) = true;
     bool mExit GUARDED_BY(mThreadMutex) = false;
-    std::shared_ptr<EffectContext> mThreadContext GUARDED_BY(mThreadMutex);
 
-    struct EventFlagDeleter {
-        void operator()(::android::hardware::EventFlag* flag) const {
-            if (flag) {
-                ::android::hardware::EventFlag::deleteEventFlag(&flag);
-            }
-        }
-    };
-    std::unique_ptr<::android::hardware::EventFlag, EventFlagDeleter> mEfGroup;
     std::thread mThread;
     int mPriority;
     std::string mName;
diff --git a/audio/aidl/default/include/effect-impl/EffectTypes.h b/audio/aidl/default/include/effect-impl/EffectTypes.h
index 4bda7be..9740d6e 100644
--- a/audio/aidl/default/include/effect-impl/EffectTypes.h
+++ b/audio/aidl/default/include/effect-impl/EffectTypes.h
@@ -46,7 +46,8 @@
     ERROR_NULL_POINTER,      /* NULL pointer */
     ERROR_ALIGNMENT_ERROR,   /* Memory alignment error */
     ERROR_BLOCK_SIZE_EXCEED, /* Maximum block size exceeded */
-    ERROR_EFFECT_LIB_ERROR
+    ERROR_EFFECT_LIB_ERROR,  /* Effect implementation library error */
+    ERROR_EVENT_FLAG_ERROR   /* Error with effect event flags */
 };
 
 static const int INVALID_AUDIO_SESSION_ID = -1;
@@ -67,6 +68,8 @@
             return out << "ERROR_BLOCK_SIZE_EXCEED";
         case RetCode::ERROR_EFFECT_LIB_ERROR:
             return out << "ERROR_EFFECT_LIB_ERROR";
+        case RetCode::ERROR_EVENT_FLAG_ERROR:
+            return out << "ERROR_EVENT_FLAG_ERROR";
     }
 
     return out << "EnumError: " << code;
diff --git a/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.cpp b/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.cpp
index 7954316..1e70716 100644
--- a/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.cpp
+++ b/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.cpp
@@ -147,10 +147,6 @@
     return mContext;
 }
 
-std::shared_ptr<EffectContext> LoudnessEnhancerSw::getContext() {
-    return mContext;
-}
-
 RetCode LoudnessEnhancerSw::releaseContext() {
     if (mContext) {
         mContext.reset();
diff --git a/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.h b/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.h
index 25824f2..cf71a5f 100644
--- a/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.h
+++ b/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.h
@@ -54,20 +54,23 @@
     }
 
     ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
-    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
-    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
-                                            Parameter::Specific* specific) override;
+    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
+            REQUIRES(mImplMutex) override;
+    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
+            REQUIRES(mImplMutex) override;
 
-    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
-    std::shared_ptr<EffectContext> getContext() override;
-    RetCode releaseContext() override;
+    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
+            REQUIRES(mImplMutex) override;
+    RetCode releaseContext() REQUIRES(mImplMutex) override;
 
-    IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+    IEffect::Status effectProcessImpl(float* in, float* out, int samples)
+            REQUIRES(mImplMutex) override;
     std::string getEffectName() override { return kEffectName; }
 
   private:
-    std::shared_ptr<LoudnessEnhancerSwContext> mContext;
+    std::shared_ptr<LoudnessEnhancerSwContext> mContext GUARDED_BY(mImplMutex);
     ndk::ScopedAStatus getParameterLoudnessEnhancer(const LoudnessEnhancer::Tag& tag,
-                                                    Parameter::Specific* specific);
+                                                    Parameter::Specific* specific)
+            REQUIRES(mImplMutex);
 };
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/noiseSuppression/NoiseSuppressionSw.cpp b/audio/aidl/default/noiseSuppression/NoiseSuppressionSw.cpp
index a3208df..d304416 100644
--- a/audio/aidl/default/noiseSuppression/NoiseSuppressionSw.cpp
+++ b/audio/aidl/default/noiseSuppression/NoiseSuppressionSw.cpp
@@ -155,10 +155,6 @@
     return mContext;
 }
 
-std::shared_ptr<EffectContext> NoiseSuppressionSw::getContext() {
-    return mContext;
-}
-
 RetCode NoiseSuppressionSw::releaseContext() {
     if (mContext) {
         mContext.reset();
diff --git a/audio/aidl/default/noiseSuppression/NoiseSuppressionSw.h b/audio/aidl/default/noiseSuppression/NoiseSuppressionSw.h
index fc1e028..acef8ee 100644
--- a/audio/aidl/default/noiseSuppression/NoiseSuppressionSw.h
+++ b/audio/aidl/default/noiseSuppression/NoiseSuppressionSw.h
@@ -55,20 +55,23 @@
     }
 
     ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
-    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
-    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
-                                            Parameter::Specific* specific) override;
+    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
+            REQUIRES(mImplMutex) override;
+    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
+            REQUIRES(mImplMutex) override;
 
-    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
-    std::shared_ptr<EffectContext> getContext() override;
-    RetCode releaseContext() override;
+    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
+            REQUIRES(mImplMutex) override;
+    RetCode releaseContext() REQUIRES(mImplMutex) override;
 
     std::string getEffectName() override { return kEffectName; };
-    IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+    IEffect::Status effectProcessImpl(float* in, float* out, int samples)
+            REQUIRES(mImplMutex) override;
 
   private:
-    std::shared_ptr<NoiseSuppressionSwContext> mContext;
+    std::shared_ptr<NoiseSuppressionSwContext> mContext GUARDED_BY(mImplMutex);
     ndk::ScopedAStatus getParameterNoiseSuppression(const NoiseSuppression::Tag& tag,
-                                                    Parameter::Specific* specific);
+                                                    Parameter::Specific* specific)
+            REQUIRES(mImplMutex);
 };
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/presetReverb/PresetReverbSw.cpp b/audio/aidl/default/presetReverb/PresetReverbSw.cpp
index 3f02eb7..2ac2010 100644
--- a/audio/aidl/default/presetReverb/PresetReverbSw.cpp
+++ b/audio/aidl/default/presetReverb/PresetReverbSw.cpp
@@ -161,10 +161,6 @@
     return mContext;
 }
 
-std::shared_ptr<EffectContext> PresetReverbSw::getContext() {
-    return mContext;
-}
-
 RetCode PresetReverbSw::releaseContext() {
     if (mContext) {
         mContext.reset();
diff --git a/audio/aidl/default/presetReverb/PresetReverbSw.h b/audio/aidl/default/presetReverb/PresetReverbSw.h
index 9ceee7c..61fc88c 100644
--- a/audio/aidl/default/presetReverb/PresetReverbSw.h
+++ b/audio/aidl/default/presetReverb/PresetReverbSw.h
@@ -56,21 +56,23 @@
     }
 
     ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
-    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
-    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
-                                            Parameter::Specific* specific) override;
+    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
+            REQUIRES(mImplMutex) override;
+    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
+            REQUIRES(mImplMutex) override;
 
-    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
-    std::shared_ptr<EffectContext> getContext() override;
-    RetCode releaseContext() override;
+    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
+            REQUIRES(mImplMutex) override;
+    RetCode releaseContext() REQUIRES(mImplMutex) override;
 
-    IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+    IEffect::Status effectProcessImpl(float* in, float* out, int samples)
+            REQUIRES(mImplMutex) override;
     std::string getEffectName() override { return kEffectName; }
 
   private:
-    std::shared_ptr<PresetReverbSwContext> mContext;
+    std::shared_ptr<PresetReverbSwContext> mContext GUARDED_BY(mImplMutex);
 
     ndk::ScopedAStatus getParameterPresetReverb(const PresetReverb::Tag& tag,
-                                                Parameter::Specific* specific);
+                                                Parameter::Specific* specific) REQUIRES(mImplMutex);
 };
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/spatializer/SpatializerSw.cpp b/audio/aidl/default/spatializer/SpatializerSw.cpp
index 434ed5a..6d3c4bd 100644
--- a/audio/aidl/default/spatializer/SpatializerSw.cpp
+++ b/audio/aidl/default/spatializer/SpatializerSw.cpp
@@ -141,10 +141,6 @@
     return mContext;
 }
 
-std::shared_ptr<EffectContext> SpatializerSw::getContext() {
-    return mContext;
-}
-
 RetCode SpatializerSw::releaseContext() {
     if (mContext) {
         mContext.reset();
diff --git a/audio/aidl/default/spatializer/SpatializerSw.h b/audio/aidl/default/spatializer/SpatializerSw.h
index b205704..b321e83 100644
--- a/audio/aidl/default/spatializer/SpatializerSw.h
+++ b/audio/aidl/default/spatializer/SpatializerSw.h
@@ -50,19 +50,21 @@
     ~SpatializerSw();
 
     ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
-    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
-    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
-                                            Parameter::Specific* specific) override;
+    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
+            REQUIRES(mImplMutex) override;
+    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
+            REQUIRES(mImplMutex) override;
 
-    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
-    std::shared_ptr<EffectContext> getContext() override;
-    RetCode releaseContext() override;
+    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
+            REQUIRES(mImplMutex) override;
+    RetCode releaseContext() REQUIRES(mImplMutex) override;
 
     std::string getEffectName() override { return kEffectName; };
-    IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+    IEffect::Status effectProcessImpl(float* in, float* out, int samples)
+            REQUIRES(mImplMutex) override;
 
   private:
     static const std::vector<Range::SpatializerRange> kRanges;
-    std::shared_ptr<SpatializerSwContext> mContext = nullptr;
+    std::shared_ptr<SpatializerSwContext> mContext GUARDED_BY(mImplMutex) = nullptr;
 };
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/virtualizer/VirtualizerSw.cpp b/audio/aidl/default/virtualizer/VirtualizerSw.cpp
index 0e8435e..091b0b7 100644
--- a/audio/aidl/default/virtualizer/VirtualizerSw.cpp
+++ b/audio/aidl/default/virtualizer/VirtualizerSw.cpp
@@ -203,10 +203,6 @@
     return mContext;
 }
 
-std::shared_ptr<EffectContext> VirtualizerSw::getContext() {
-    return mContext;
-}
-
 RetCode VirtualizerSw::releaseContext() {
     if (mContext) {
         mContext.reset();
diff --git a/audio/aidl/default/virtualizer/VirtualizerSw.h b/audio/aidl/default/virtualizer/VirtualizerSw.h
index 5e114d9..9287838 100644
--- a/audio/aidl/default/virtualizer/VirtualizerSw.h
+++ b/audio/aidl/default/virtualizer/VirtualizerSw.h
@@ -59,24 +59,25 @@
     }
 
     ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
-    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
-    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
-                                            Parameter::Specific* specific) override;
+    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
+            REQUIRES(mImplMutex) override;
+    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
+            REQUIRES(mImplMutex) override;
 
-    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
-    std::shared_ptr<EffectContext> getContext() override;
-    RetCode releaseContext() override;
+    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
+            REQUIRES(mImplMutex) override;
+    RetCode releaseContext() REQUIRES(mImplMutex) override;
 
     IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
     std::string getEffectName() override { return kEffectName; }
 
   private:
     static const std::vector<Range::VirtualizerRange> kRanges;
-    std::shared_ptr<VirtualizerSwContext> mContext;
+    std::shared_ptr<VirtualizerSwContext> mContext GUARDED_BY(mImplMutex);
 
     ndk::ScopedAStatus getParameterVirtualizer(const Virtualizer::Tag& tag,
-                                               Parameter::Specific* specific);
+                                               Parameter::Specific* specific) REQUIRES(mImplMutex);
     ndk::ScopedAStatus getSpeakerAngles(const Virtualizer::SpeakerAnglesPayload payload,
-                                        Parameter::Specific* specific);
+                                        Parameter::Specific* specific) REQUIRES(mImplMutex);
 };
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/visualizer/VisualizerSw.cpp b/audio/aidl/default/visualizer/VisualizerSw.cpp
index 285c102..54f7f1c 100644
--- a/audio/aidl/default/visualizer/VisualizerSw.cpp
+++ b/audio/aidl/default/visualizer/VisualizerSw.cpp
@@ -190,10 +190,6 @@
     return mContext;
 }
 
-std::shared_ptr<EffectContext> VisualizerSw::getContext() {
-    return mContext;
-}
-
 RetCode VisualizerSw::releaseContext() {
     if (mContext) {
         mContext.reset();
diff --git a/audio/aidl/default/visualizer/VisualizerSw.h b/audio/aidl/default/visualizer/VisualizerSw.h
index 995774e..4b87b04 100644
--- a/audio/aidl/default/visualizer/VisualizerSw.h
+++ b/audio/aidl/default/visualizer/VisualizerSw.h
@@ -72,21 +72,23 @@
     }
 
     ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
-    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
-    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
-                                            Parameter::Specific* specific) override;
+    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
+            REQUIRES(mImplMutex) override;
+    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
+            REQUIRES(mImplMutex) override;
 
-    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
-    std::shared_ptr<EffectContext> getContext() override;
-    RetCode releaseContext() override;
+    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
+            REQUIRES(mImplMutex) override;
+    RetCode releaseContext() REQUIRES(mImplMutex) override;
 
-    IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+    IEffect::Status effectProcessImpl(float* in, float* out, int samples)
+            REQUIRES(mImplMutex) override;
     std::string getEffectName() override { return kEffectName; }
 
   private:
     static const std::vector<Range::VisualizerRange> kRanges;
-    std::shared_ptr<VisualizerSwContext> mContext;
+    std::shared_ptr<VisualizerSwContext> mContext GUARDED_BY(mImplMutex);
     ndk::ScopedAStatus getParameterVisualizer(const Visualizer::Tag& tag,
-                                              Parameter::Specific* specific);
+                                              Parameter::Specific* specific) REQUIRES(mImplMutex);
 };
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/volume/VolumeSw.cpp b/audio/aidl/default/volume/VolumeSw.cpp
index 8902584..dd019f6 100644
--- a/audio/aidl/default/volume/VolumeSw.cpp
+++ b/audio/aidl/default/volume/VolumeSw.cpp
@@ -160,10 +160,6 @@
     return mContext;
 }
 
-std::shared_ptr<EffectContext> VolumeSw::getContext() {
-    return mContext;
-}
-
 RetCode VolumeSw::releaseContext() {
     if (mContext) {
         mContext.reset();
diff --git a/audio/aidl/default/volume/VolumeSw.h b/audio/aidl/default/volume/VolumeSw.h
index 1432b2b..3fc0d97 100644
--- a/audio/aidl/default/volume/VolumeSw.h
+++ b/audio/aidl/default/volume/VolumeSw.h
@@ -57,21 +57,24 @@
     }
 
     ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
-    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
-    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
-                                            Parameter::Specific* specific) override;
+    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
+            REQUIRES(mImplMutex) override;
+    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
+            REQUIRES(mImplMutex) override;
 
-    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
-    std::shared_ptr<EffectContext> getContext() override;
-    RetCode releaseContext() override;
+    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
+            REQUIRES(mImplMutex) override;
+    RetCode releaseContext() REQUIRES(mImplMutex) override;
 
-    IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+    IEffect::Status effectProcessImpl(float* in, float* out, int samples)
+            REQUIRES(mImplMutex) override;
     std::string getEffectName() override { return kEffectName; }
 
   private:
     static const std::vector<Range::VolumeRange> kRanges;
-    std::shared_ptr<VolumeSwContext> mContext;
+    std::shared_ptr<VolumeSwContext> mContext GUARDED_BY(mImplMutex);
 
-    ndk::ScopedAStatus getParameterVolume(const Volume::Tag& tag, Parameter::Specific* specific);
+    ndk::ScopedAStatus getParameterVolume(const Volume::Tag& tag, Parameter::Specific* specific)
+            REQUIRES(mImplMutex);
 };
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/vts/EffectHelper.h b/audio/aidl/vts/EffectHelper.h
index 4a5c537..9fa7f9f 100644
--- a/audio/aidl/vts/EffectHelper.h
+++ b/audio/aidl/vts/EffectHelper.h
@@ -43,6 +43,7 @@
 using aidl::android::hardware::audio::effect::CommandId;
 using aidl::android::hardware::audio::effect::Descriptor;
 using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::kEventFlagDataMqUpdate;
 using aidl::android::hardware::audio::effect::kEventFlagNotEmpty;
 using aidl::android::hardware::audio::effect::Parameter;
 using aidl::android::hardware::audio::effect::Range;
@@ -191,6 +192,16 @@
             ASSERT_TRUE(dataMq->read(buffer.data(), expectFloats));
         }
     }
+    static void expectDataMqUpdateEventFlag(std::unique_ptr<StatusMQ>& statusMq) {
+        EventFlag* efGroup;
+        ASSERT_EQ(::android::OK,
+                  EventFlag::createEventFlag(statusMq->getEventFlagWord(), &efGroup));
+        ASSERT_NE(nullptr, efGroup);
+        uint32_t efState = 0;
+        EXPECT_EQ(::android::OK, efGroup->wait(kEventFlagDataMqUpdate, &efState, 1'000'000 /*1ms*/,
+                                               true /* retry */));
+        EXPECT_TRUE(efState & kEventFlagDataMqUpdate);
+    }
     static Parameter::Common createParamCommon(
             int session = 0, int ioHandle = -1, int iSampleRate = 48000, int oSampleRate = 48000,
             long iFrameCount = 0x100, long oFrameCount = 0x100,
diff --git a/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
index f91795b..7373073 100644
--- a/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
@@ -4583,8 +4583,7 @@
 static std::vector<std::string> getRemoteSubmixModuleInstance() {
     auto instances = android::getAidlHalInstanceNames(IModule::descriptor);
     for (auto instance : instances) {
-        if (instance.find("r_submix") != std::string::npos)
-            return (std::vector<std::string>{instance});
+        if (instance.ends_with("/r_submix")) return (std::vector<std::string>{instance});
     }
     return {};
 }
@@ -4672,6 +4671,9 @@
         // Turn off "debug" which enables connections simulation. Since devices of the remote
         // submix module are virtual, there is no need for simulation.
         ASSERT_NO_FATAL_FAILURE(SetUpImpl(GetParam(), false /*setUpDebug*/));
+        if (int32_t version; module->getInterfaceVersion(&version).isOk() && version < 2) {
+            GTEST_SKIP() << "V1 uses a deprecated remote submix device type encoding";
+        }
         ASSERT_NO_FATAL_FAILURE(SetUpModuleConfig());
     }
 };
diff --git a/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp b/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
index 418fedb..01cdd81 100644
--- a/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
@@ -609,6 +609,49 @@
     ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
 }
 
+// Verify Parameters kept after reset.
+TEST_P(AudioEffectTest, SetCommonParameterAndReopen) {
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+
+    Parameter::Common common = EffectHelper::createParamCommon(
+            0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
+            kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
+    IEffect::OpenEffectReturn ret;
+    ASSERT_NO_FATAL_FAILURE(open(mEffect, common, std::nullopt /* specific */, &ret, EX_NONE));
+    auto statusMQ = std::make_unique<EffectHelper::StatusMQ>(ret.statusMQ);
+    ASSERT_TRUE(statusMQ->isValid());
+    auto inputMQ = std::make_unique<EffectHelper::DataMQ>(ret.inputDataMQ);
+    ASSERT_TRUE(inputMQ->isValid());
+    auto outputMQ = std::make_unique<EffectHelper::DataMQ>(ret.outputDataMQ);
+    ASSERT_TRUE(outputMQ->isValid());
+
+    Parameter::Id id = Parameter::Id::make<Parameter::Id::commonTag>(Parameter::common);
+    common.input.frameCount++;
+    ASSERT_NO_FATAL_FAILURE(setAndGetParameter(id, Parameter::make<Parameter::common>(common)));
+    ASSERT_TRUE(statusMQ->isValid());
+    expectDataMqUpdateEventFlag(statusMQ);
+    EXPECT_IS_OK(mEffect->reopen(&ret));
+    inputMQ = std::make_unique<EffectHelper::DataMQ>(ret.inputDataMQ);
+    outputMQ = std::make_unique<EffectHelper::DataMQ>(ret.outputDataMQ);
+    ASSERT_TRUE(statusMQ->isValid());
+    ASSERT_TRUE(inputMQ->isValid());
+    ASSERT_TRUE(outputMQ->isValid());
+
+    common.output.frameCount++;
+    ASSERT_NO_FATAL_FAILURE(setAndGetParameter(id, Parameter::make<Parameter::common>(common)));
+    ASSERT_TRUE(statusMQ->isValid());
+    expectDataMqUpdateEventFlag(statusMQ);
+    EXPECT_IS_OK(mEffect->reopen(&ret));
+    inputMQ = std::make_unique<EffectHelper::DataMQ>(ret.inputDataMQ);
+    outputMQ = std::make_unique<EffectHelper::DataMQ>(ret.outputDataMQ);
+    ASSERT_TRUE(statusMQ->isValid());
+    ASSERT_TRUE(inputMQ->isValid());
+    ASSERT_TRUE(outputMQ->isValid());
+
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+}
+
 /// Data processing test
 // Send data to effects and expect it to be consumed by checking statusMQ.
 // Effects exposing bypass flags or operating in offload mode will be skipped.
@@ -684,6 +727,59 @@
     ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
 }
 
+// Send data to effects and expect it to be consumed after effect reopen (IO AudioConfig change).
+// Effects exposing bypass flags or operating in offload mode will be skipped.
+TEST_P(AudioEffectDataPathTest, ConsumeDataAfterReopen) {
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+
+    Parameter::Common common = EffectHelper::createParamCommon(
+            0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
+            kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
+    IEffect::OpenEffectReturn ret;
+    ASSERT_NO_FATAL_FAILURE(open(mEffect, common, std::nullopt /* specific */, &ret, EX_NONE));
+    auto statusMQ = std::make_unique<EffectHelper::StatusMQ>(ret.statusMQ);
+    ASSERT_TRUE(statusMQ->isValid());
+    auto inputMQ = std::make_unique<EffectHelper::DataMQ>(ret.inputDataMQ);
+    ASSERT_TRUE(inputMQ->isValid());
+    auto outputMQ = std::make_unique<EffectHelper::DataMQ>(ret.outputDataMQ);
+    ASSERT_TRUE(outputMQ->isValid());
+
+    std::vector<float> buffer;
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(
+            EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer));
+
+    // set a new common parameter with different IO frameCount, reopen
+    Parameter::Id id = Parameter::Id::make<Parameter::Id::commonTag>(Parameter::common);
+    common.input.frameCount += 4;
+    common.output.frameCount += 4;
+    ASSERT_NO_FATAL_FAILURE(setAndGetParameter(id, Parameter::make<Parameter::common>(common)));
+    ASSERT_TRUE(statusMQ->isValid());
+    expectDataMqUpdateEventFlag(statusMQ);
+    EXPECT_IS_OK(mEffect->reopen(&ret));
+    inputMQ = std::make_unique<EffectHelper::DataMQ>(ret.inputDataMQ);
+    outputMQ = std::make_unique<EffectHelper::DataMQ>(ret.outputDataMQ);
+    ASSERT_TRUE(statusMQ->isValid());
+    ASSERT_TRUE(inputMQ->isValid());
+    ASSERT_TRUE(outputMQ->isValid());
+
+    // verify data consume again
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(
+            EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer));
+
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer));
+
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+}
+
 // Send data to IDLE effects and expect it to be consumed after effect start.
 // Effects exposing bypass flags or operating in offload mode will be skipped.
 TEST_P(AudioEffectDataPathTest, SendDataAtIdleAndConsumeDataInProcessing) {
diff --git a/audio/aidl/vts/VtsHalDownmixTargetTest.cpp b/audio/aidl/vts/VtsHalDownmixTargetTest.cpp
index b82bde1..360bf26 100644
--- a/audio/aidl/vts/VtsHalDownmixTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalDownmixTargetTest.cpp
@@ -138,7 +138,6 @@
 
     void setDataTestParams(int32_t layoutType) {
         mInputBuffer.resize(kBufferSize);
-        mOutputBuffer.resize(kBufferSize);
 
         // Get the number of channels used
         mInputChannelCount = getChannelCount(
@@ -146,6 +145,7 @@
 
         // In case of downmix, output is always configured to stereo layout.
         mOutputBufferSize = (mInputBuffer.size() / mInputChannelCount) * kOutputChannelCount;
+        mOutputBuffer.resize(mOutputBufferSize);
     }
 
     // Generate mInputBuffer values between -kMaxDownmixSample to kMaxDownmixSample
@@ -262,13 +262,13 @@
         for (size_t i = 0, j = position; i < mOutputBufferSize;
              i += kOutputChannelCount, j += mInputChannelCount) {
             // Validate Left channel has no audio
-            ASSERT_EQ(mOutputBuffer[i], 0);
+            ASSERT_EQ(mOutputBuffer[i], 0) << " at " << i;
             // Validate Right channel has audio
             if (mInputBuffer[j] != 0) {
-                ASSERT_NE(mOutputBuffer[i + 1], 0);
+                ASSERT_NE(mOutputBuffer[i + 1], 0) << " at " << i;
             } else {
                 // No change in output when input is 0
-                ASSERT_EQ(mOutputBuffer[i + 1], mInputBuffer[j]);
+                ASSERT_EQ(mOutputBuffer[i + 1], mInputBuffer[j]) << " at " << i;
             }
         }
     }
@@ -402,9 +402,6 @@
             ASSERT_EQ(mOutputBuffer[j], mInputBuffer[i]);
             ASSERT_EQ(mOutputBuffer[j + 1], mInputBuffer[i + 1]);
         }
-        for (size_t i = mOutputBufferSize; i < kBufferSize; i++) {
-            ASSERT_EQ(mOutputBuffer[i], mInputBuffer[i]);
-        }
     }
 
     int32_t mInputChannelLayout;
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h b/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
index 96eff0e..1153217 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
@@ -256,6 +256,7 @@
     std::string dumpSaveProperty(const std::vector<std::string>& options);
     std::string dumpRestoreProperty(const std::vector<std::string>& options);
     std::string dumpInjectEvent(const std::vector<std::string>& options);
+    std::string dumpSubscriptions();
 
     template <typename T>
     android::base::Result<T> safelyParseInt(int index, const std::string& s) {
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
index d95ffd6..bcc765c 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
@@ -51,6 +51,8 @@
 
 namespace {
 
+#define PROP_ID_TO_CSTR(A) (propIdToString(A).c_str())
+
 using ::aidl::android::hardware::automotive::vehicle::CruiseControlCommand;
 using ::aidl::android::hardware::automotive::vehicle::CruiseControlType;
 using ::aidl::android::hardware::automotive::vehicle::DriverDistractionState;
@@ -725,7 +727,7 @@
 FakeVehicleHardware::ValueResultType FakeVehicleHardware::getUserHalProp(
         const VehiclePropValue& value) const {
     auto propId = value.prop;
-    ALOGI("get(): getting value for prop %d from User HAL", propId);
+    ALOGI("get(): getting value for prop %s from User HAL", PROP_ID_TO_CSTR(propId));
 
     auto result = mFakeUserHal->onGetProperty(value);
     if (!result.ok()) {
@@ -1088,7 +1090,7 @@
                                           const std::vector<SetValueRequest>& requests) {
     for (auto& request : requests) {
         if (FAKE_VEHICLEHARDWARE_DEBUG) {
-            ALOGD("Set value for property ID: %d", request.value.prop);
+            ALOGD("Set value for property ID: %s", PROP_ID_TO_CSTR(request.value.prop));
         }
 
         // In a real VHAL implementation, you could either send the setValue request to vehicle bus
@@ -1109,9 +1111,9 @@
     auto setSpecialValueResult = maybeSetSpecialValue(value, &isSpecialValue);
     if (isSpecialValue) {
         if (!setSpecialValueResult.ok()) {
-            return StatusError(getErrorCode(setSpecialValueResult))
-                   << StringPrintf("failed to set special value for property ID: %d, error: %s",
-                                   value.prop, getErrorMsg(setSpecialValueResult).c_str());
+            return StatusError(getErrorCode(setSpecialValueResult)) << StringPrintf(
+                           "failed to set special value for property ID: %s, error: %s",
+                           PROP_ID_TO_CSTR(value.prop), getErrorMsg(setSpecialValueResult).c_str());
         }
         return {};
     }
@@ -1150,7 +1152,7 @@
                                           const std::vector<GetValueRequest>& requests) const {
     for (auto& request : requests) {
         if (FAKE_VEHICLEHARDWARE_DEBUG) {
-            ALOGD("getValues(%d)", request.prop.prop);
+            ALOGD("getValues(%s)", PROP_ID_TO_CSTR(request.prop.prop));
         }
 
         // In a real VHAL implementation, you could either send the getValue request to vehicle bus
@@ -1189,8 +1191,8 @@
     if (isSpecialValue) {
         if (!result.ok()) {
             return StatusError(getErrorCode(result))
-                   << StringPrintf("failed to get special value: %d, error: %s", value.prop,
-                                   getErrorMsg(result).c_str());
+                   << StringPrintf("failed to get special value: %s, error: %s",
+                                   PROP_ID_TO_CSTR(value.prop), getErrorMsg(result).c_str());
         } else {
             return result;
         }
@@ -1249,6 +1251,8 @@
         mAddExtraTestVendorConfigs = false;
         result.refreshPropertyConfigs = true;
         result.buffer = "successfully restored vendor configs";
+    } else if (EqualsIgnoreCase(option, "--dumpSub")) {
+        result.buffer = dumpSubscriptions();
     } else {
         result.buffer = StringPrintf("Invalid option: %s\n", option.c_str());
     }
@@ -1380,7 +1384,8 @@
         if (mGeneratorHub->unregisterGenerator(propId)) {
             return "Linear event generator stopped successfully";
         }
-        return StringPrintf("No linear event generator found for property: %d", propId);
+        return StringPrintf("No linear event generator found for property: %s",
+                            PROP_ID_TO_CSTR(propId));
     } else if (command == "--startjson") {
         // --genfakedata --startjson --path path repetition
         // or
@@ -1650,6 +1655,26 @@
     mServerSidePropStore->writeValue(mValuePool->obtain(value));
 }
 
+std::string FakeVehicleHardware::dumpSubscriptions() {
+    std::scoped_lock<std::mutex> lockGuard(mLock);
+    std::string result = "Subscriptions: \n";
+    for (const auto& [interval, actionForInterval] : mActionByIntervalInNanos) {
+        for (const auto& propIdAreaId : actionForInterval.propIdAreaIdsToRefresh) {
+            const auto& refreshInfo = mRefreshInfoByPropIdAreaId[propIdAreaId];
+            bool vur = (refreshInfo.eventMode == VehiclePropertyStore::EventMode::ON_VALUE_CHANGE);
+            float sampleRateHz = 1'000'000'000. / refreshInfo.intervalInNanos;
+            result += StringPrintf("Continuous{property: %s, areaId: %d, rate: %lf hz, vur: %b}\n",
+                                   PROP_ID_TO_CSTR(propIdAreaId.propId), propIdAreaId.areaId,
+                                   sampleRateHz, vur);
+        }
+    }
+    for (const auto& propIdAreaId : mSubOnChangePropIdAreaIds) {
+        result += StringPrintf("OnChange{property: %s, areaId: %d}\n",
+                               PROP_ID_TO_CSTR(propIdAreaId.propId), propIdAreaId.areaId);
+    }
+    return result;
+}
+
 std::string FakeVehicleHardware::dumpHelp() {
     return "Usage: \n\n"
            "[no args]: dumps (id and value) all supported properties \n"
@@ -1717,8 +1742,9 @@
         result = mServerSidePropStore->readValue(value);
     }
     if (!result.ok()) {
-        return StringPrintf("failed to read property value: %d, error: %s, code: %d\n", propId,
-                            getErrorMsg(result).c_str(), getIntErrorCode(result));
+        return StringPrintf("failed to read property value: %s, error: %s, code: %d\n",
+                            PROP_ID_TO_CSTR(propId), getErrorMsg(result).c_str(),
+                            getIntErrorCode(result));
 
     } else {
         return result.value()->toString() + "\n";
@@ -1733,7 +1759,7 @@
     int rowNumber = 1;
     std::string msg = StringPrintf("listing %zu properties\n", configs.size());
     for (const auto& config : configs) {
-        msg += StringPrintf("%d: %d\n", rowNumber++, config.prop);
+        msg += StringPrintf("%d: %s\n", rowNumber++, PROP_ID_TO_CSTR(config.prop));
     }
     return msg;
 }
@@ -1766,7 +1792,7 @@
         int32_t prop = propResult.value();
         auto result = mServerSidePropStore->getPropConfig(prop);
         if (!result.ok()) {
-            msg += StringPrintf("No property %d\n", prop);
+            msg += StringPrintf("No property %s\n", PROP_ID_TO_CSTR(prop));
             continue;
         }
         msg += dumpOnePropertyByConfig(rowNumber++, result.value());
@@ -1952,8 +1978,9 @@
     }
 
     if (!result.ok()) {
-        return StringPrintf("failed to read property value: %d, error: %s, code: %d\n", prop.prop,
-                            getErrorMsg(result).c_str(), getIntErrorCode(result));
+        return StringPrintf("failed to read property value: %s, error: %s, code: %d\n",
+                            PROP_ID_TO_CSTR(prop.prop), getErrorMsg(result).c_str(),
+                            getIntErrorCode(result));
     }
     return StringPrintf("Get property result: %s\n", result.value()->toString().c_str());
 }
@@ -2046,7 +2073,7 @@
 
     eventFromVehicleBus(prop);
 
-    return StringPrintf("Event for property: %d injected", prop.prop);
+    return StringPrintf("Event for property: %s injected", PROP_ID_TO_CSTR(prop.prop));
 }
 
 StatusCode FakeVehicleHardware::checkHealth() {
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
index 909c89d..90643aa 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
@@ -2617,8 +2617,8 @@
     DumpResult result = getHardware()->dump(options);
     ASSERT_FALSE(result.callerShouldDumpState);
     ASSERT_NE(result.buffer, "");
-    ASSERT_THAT(result.buffer, ContainsRegex(StringPrintf("1:.*prop: %s.*\nNo property %d\n",
-                                                          prop1.c_str(), INVALID_PROP_ID)));
+    ASSERT_THAT(result.buffer, ContainsRegex(StringPrintf("1:.*prop: %s.*\nNo property INVALID\n",
+                                                          prop1.c_str())));
 }
 
 TEST_F(FakeVehicleHardwareTest, testDumpSpecificPropertiesNoArg) {
@@ -2701,8 +2701,7 @@
             {"--inject-event", propIdStr, "-i", "1234", "-t", std::to_string(timestamp)});
 
     ASSERT_FALSE(result.callerShouldDumpState);
-    ASSERT_THAT(result.buffer,
-                ContainsRegex(StringPrintf("Event for property: %d injected", prop)));
+    ASSERT_THAT(result.buffer, ContainsRegex("Event for property: ENGINE_OIL_LEVEL injected"));
     ASSERT_TRUE(waitForChangedProperties(prop, 0, /*count=*/1, milliseconds(1000)))
             << "No changed event received for injected event from vehicle bus";
     auto events = getChangedProperties();
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleApPowerStateShutdownParam.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleApPowerStateShutdownParam.aidl
index 966ff65..538b905 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleApPowerStateShutdownParam.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleApPowerStateShutdownParam.aidl
@@ -20,7 +20,7 @@
 @Backing(type="int")
 enum VehicleApPowerStateShutdownParam {
     /**
-     * AP must shutdown without Garage mode. Postponing is not allowed.
+     * AP must shutdown without Garage mode.
      * If AP need to shutdown as soon as possible, EMERGENCY_SHUTDOWN shall be used.
      */
     SHUTDOWN_IMMEDIATELY = 1,
@@ -36,13 +36,11 @@
     SHUTDOWN_ONLY = 3,
     /**
      * AP can enter deep sleep, without Garage mode.
-     * Postponing is not allowed.
      * Depending on the actual implementation, it may shut down immediately
      */
     SLEEP_IMMEDIATELY = 4,
     /**
      * AP can hibernate (suspend to disk) without Garage mode.
-     * Postponing is not allowed.
      * Depending on the actual implementation, it may shut down immediately.
      */
     HIBERNATE_IMMEDIATELY = 5,
diff --git a/biometrics/fingerprint/aidl/default/FakeFingerprintEngine.cpp b/biometrics/fingerprint/aidl/default/FakeFingerprintEngine.cpp
index 4e80052..a7acf3d 100644
--- a/biometrics/fingerprint/aidl/default/FakeFingerprintEngine.cpp
+++ b/biometrics/fingerprint/aidl/default/FakeFingerprintEngine.cpp
@@ -62,12 +62,17 @@
         return;
     }
 
+    waitForFingerDown(cb, cancel);
+
     updateContext(WorkMode::kEnroll, cb, const_cast<std::future<void>&>(cancel), 0, hat);
 }
 
 void FakeFingerprintEngine::authenticateImpl(ISessionCallback* cb, int64_t operationId,
                                              const std::future<void>& cancel) {
     BEGIN_OP(0);
+
+    waitForFingerDown(cb, cancel);
+
     updateContext(WorkMode::kAuthenticate, cb, const_cast<std::future<void>&>(cancel), operationId,
                   keymaster::HardwareAuthToken());
 }
@@ -84,6 +89,8 @@
         return;
     }
 
+    waitForFingerDown(cb, cancel);
+
     updateContext(WorkMode::kDetectInteract, cb, const_cast<std::future<void>&>(cancel), 0,
                   keymaster::HardwareAuthToken());
 }
@@ -398,6 +405,7 @@
 
 ndk::ScopedAStatus FakeFingerprintEngine::onPointerUpImpl(int32_t /*pointerId*/) {
     BEGIN_OP(0);
+    mFingerIsDown = false;
     return ndk::ScopedAStatus::ok();
 }
 
@@ -533,4 +541,17 @@
     isLockoutTimerStarted = false;
     isLockoutTimerAborted = false;
 }
+
+void FakeFingerprintEngine::waitForFingerDown(ISessionCallback* cb,
+                                              const std::future<void>& cancel) {
+    while (!mFingerIsDown) {
+        if (shouldCancel(cancel)) {
+            LOG(ERROR) << "waitForFingerDown, Fail: cancel";
+            cb->onError(Error::CANCELED, 0 /* vendorCode */);
+            return;
+        }
+        SLEEP_MS(10);
+    }
+}
+
 }  // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/Session.cpp b/biometrics/fingerprint/aidl/default/Session.cpp
index c06c931..0dd6603 100644
--- a/biometrics/fingerprint/aidl/default/Session.cpp
+++ b/biometrics/fingerprint/aidl/default/Session.cpp
@@ -249,6 +249,7 @@
 ndk::ScopedAStatus Session::onPointerDown(int32_t pointerId, int32_t x, int32_t y, float minor,
                                           float major) {
     LOG(INFO) << "onPointerDown";
+    mEngine->notifyFingerdown();
     mWorker->schedule(Callable::from([this, pointerId, x, y, minor, major] {
         mEngine->onPointerDownImpl(pointerId, x, y, minor, major);
         enterIdling();
diff --git a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h
index 15d8360..0d53575 100644
--- a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h
+++ b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h
@@ -75,6 +75,7 @@
     enum class WorkMode : int8_t { kIdle = 0, kAuthenticate, kEnroll, kDetectInteract };
 
     WorkMode getWorkMode() { return mWorkMode; }
+    void notifyFingerdown() { mFingerIsDown = true; }
 
     virtual std::string toString() const {
         std::ostringstream os;
@@ -100,6 +101,7 @@
     keymaster::HardwareAuthToken mHat;
     std::future<void> mCancel;
     int64_t mOperationId;
+    bool mFingerIsDown;
 
   private:
     static constexpr int32_t FINGERPRINT_ACQUIRED_VENDOR_BASE = 1000;
@@ -109,6 +111,7 @@
     int32_t getRandomInRange(int32_t bound1, int32_t bound2);
     bool checkSensorLockout(ISessionCallback*);
     void clearLockout(ISessionCallback* cb);
+    void waitForFingerDown(ISessionCallback* cb, const std::future<void>& cancel);
 
     FakeLockoutTracker mLockoutTracker;
 
diff --git a/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineTest.cpp b/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineTest.cpp
index eedcae1..8b06c8e 100644
--- a/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineTest.cpp
+++ b/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineTest.cpp
@@ -185,6 +185,7 @@
     FingerprintHalProperties::enrollments({});
     FingerprintHalProperties::next_enrollment("4:0,0:true");
     keymaster::HardwareAuthToken hat{.mac = {2, 4}};
+    mEngine.notifyFingerdown();
     mEngine.enrollImpl(mCallback.get(), hat, mCancel.get_future());
     ASSERT_EQ(mEngine.getWorkMode(), FakeFingerprintEngine::WorkMode::kEnroll);
     mEngine.fingerDownAction();
@@ -202,6 +203,7 @@
     FingerprintHalProperties::next_enrollment(next);
     keymaster::HardwareAuthToken hat{.mac = {2, 4}};
     mCancel.set_value();
+    mEngine.notifyFingerdown();
     mEngine.enrollImpl(mCallback.get(), hat, mCancel.get_future());
     mEngine.fingerDownAction();
     ASSERT_EQ(Error::CANCELED, mCallback->mError);
@@ -215,6 +217,7 @@
     auto next = "2:0,0:false";
     FingerprintHalProperties::next_enrollment(next);
     keymaster::HardwareAuthToken hat{.mac = {2, 4}};
+    mEngine.notifyFingerdown();
     mEngine.enrollImpl(mCallback.get(), hat, mCancel.get_future());
     mEngine.fingerDownAction();
     ASSERT_EQ(Error::UNABLE_TO_PROCESS, mCallback->mError);
@@ -228,6 +231,7 @@
     FingerprintHalProperties::next_enrollment("4:0,5-[12,1013]:true");
     keymaster::HardwareAuthToken hat{.mac = {2, 4}};
     int32_t prevCnt = mCallback->mLastAcquiredCount;
+    mEngine.notifyFingerdown();
     mEngine.enrollImpl(mCallback.get(), hat, mCancel.get_future());
     mEngine.fingerDownAction();
     ASSERT_FALSE(FingerprintHalProperties::next_enrollment().has_value());
@@ -242,6 +246,7 @@
 TEST_F(FakeFingerprintEngineTest, Authenticate) {
     FingerprintHalProperties::enrollments({1, 2});
     FingerprintHalProperties::enrollment_hit(2);
+    mEngine.notifyFingerdown();
     mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
     ASSERT_EQ(mEngine.getWorkMode(), FakeFingerprintEngine::WorkMode::kAuthenticate);
     mEngine.fingerDownAction();
@@ -255,6 +260,7 @@
     FingerprintHalProperties::enrollments({2});
     FingerprintHalProperties::enrollment_hit(2);
     mCancel.set_value();
+    mEngine.notifyFingerdown();
     mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
     mEngine.fingerDownAction();
     ASSERT_EQ(Error::CANCELED, mCallback->mError);
@@ -264,6 +270,7 @@
 TEST_F(FakeFingerprintEngineTest, AuthenticateNotSet) {
     FingerprintHalProperties::enrollments({1, 2});
     FingerprintHalProperties::enrollment_hit({});
+    mEngine.notifyFingerdown();
     mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
     mEngine.fingerDownAction();
     ASSERT_TRUE(mCallback->mAuthenticateFailed);
@@ -272,6 +279,7 @@
 TEST_F(FakeFingerprintEngineTest, AuthenticateNotEnrolled) {
     FingerprintHalProperties::enrollments({1, 2});
     FingerprintHalProperties::enrollment_hit(3);
+    mEngine.notifyFingerdown();
     mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
     mEngine.fingerDownAction();
     ASSERT_TRUE(mCallback->mAuthenticateFailed);
@@ -282,6 +290,7 @@
     FingerprintHalProperties::enrollments({22, 2});
     FingerprintHalProperties::enrollment_hit(2);
     FingerprintHalProperties::lockout(true);
+    mEngine.notifyFingerdown();
     mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
     mEngine.fingerDownAction();
     ASSERT_TRUE(mCallback->mLockoutPermanent);
@@ -290,6 +299,7 @@
 
 TEST_F(FakeFingerprintEngineTest, AuthenticateError8) {
     FingerprintHalProperties::operation_authenticate_error(8);
+    mEngine.notifyFingerdown();
     mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
     mEngine.fingerDownAction();
     ASSERT_EQ(mCallback->mError, (Error)8);
@@ -298,6 +308,7 @@
 
 TEST_F(FakeFingerprintEngineTest, AuthenticateError9) {
     FingerprintHalProperties::operation_authenticate_error(1009);
+    mEngine.notifyFingerdown();
     mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
     mEngine.fingerDownAction();
     ASSERT_EQ(mCallback->mError, (Error)7);
@@ -306,6 +317,7 @@
 
 TEST_F(FakeFingerprintEngineTest, AuthenticateFails) {
     FingerprintHalProperties::operation_authenticate_fails(true);
+    mEngine.notifyFingerdown();
     mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
     mEngine.fingerDownAction();
     ASSERT_TRUE(mCallback->mAuthenticateFailed);
@@ -318,6 +330,7 @@
     FingerprintHalProperties::enrollment_hit(2);
     FingerprintHalProperties::operation_authenticate_acquired("4,1009");
     int32_t prevCount = mCallback->mLastAcquiredCount;
+    mEngine.notifyFingerdown();
     mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
     mEngine.fingerDownAction();
     ASSERT_FALSE(mCallback->mAuthenticateFailed);
@@ -332,6 +345,7 @@
     FingerprintHalProperties::enrollments({1, 2});
     FingerprintHalProperties::enrollment_hit(2);
     FingerprintHalProperties::operation_detect_interaction_acquired("");
+    mEngine.notifyFingerdown();
     mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
     ASSERT_EQ(mEngine.getWorkMode(), FakeFingerprintEngine::WorkMode::kDetectInteract);
     mEngine.fingerDownAction();
@@ -345,6 +359,7 @@
     FingerprintHalProperties::enrollments({1, 2});
     FingerprintHalProperties::enrollment_hit(2);
     mCancel.set_value();
+    mEngine.notifyFingerdown();
     mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
     mEngine.fingerDownAction();
     ASSERT_EQ(Error::CANCELED, mCallback->mError);
@@ -355,6 +370,7 @@
     FingerprintHalProperties::detect_interaction(true);
     FingerprintHalProperties::enrollments({1, 2});
     FingerprintHalProperties::enrollment_hit({});
+    mEngine.notifyFingerdown();
     mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
     mEngine.fingerDownAction();
     ASSERT_EQ(1, mCallback->mInteractionDetectedCount);
@@ -363,6 +379,7 @@
 TEST_F(FakeFingerprintEngineTest, InteractionDetectNotEnrolled) {
     FingerprintHalProperties::enrollments({1, 2});
     FingerprintHalProperties::enrollment_hit(25);
+    mEngine.notifyFingerdown();
     mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
     mEngine.fingerDownAction();
     ASSERT_EQ(1, mCallback->mInteractionDetectedCount);
@@ -371,6 +388,7 @@
 TEST_F(FakeFingerprintEngineTest, InteractionDetectError) {
     FingerprintHalProperties::detect_interaction(true);
     FingerprintHalProperties::operation_detect_interaction_error(8);
+    mEngine.notifyFingerdown();
     mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
     mEngine.fingerDownAction();
     ASSERT_EQ(0, mCallback->mInteractionDetectedCount);
@@ -384,6 +402,7 @@
     FingerprintHalProperties::enrollment_hit(2);
     FingerprintHalProperties::operation_detect_interaction_acquired("4,1013");
     int32_t prevCount = mCallback->mLastAcquiredCount;
+    mEngine.notifyFingerdown();
     mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
     mEngine.fingerDownAction();
     ASSERT_EQ(1, mCallback->mInteractionDetectedCount);
diff --git a/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineUdfpsTest.cpp b/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineUdfpsTest.cpp
index f551899..5a30db1 100644
--- a/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineUdfpsTest.cpp
+++ b/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineUdfpsTest.cpp
@@ -145,6 +145,7 @@
 TEST_F(FakeFingerprintEngineUdfpsTest, authenticate) {
     std::shared_ptr<TestSessionCallback> cb = ndk::SharedRefBase::make<TestSessionCallback>();
     std::promise<void> cancel;
+    mEngine.notifyFingerdown();
     mEngine.authenticateImpl(cb.get(), 1, cancel.get_future());
     ASSERT_TRUE(mEngine.getWorkMode() == FakeFingerprintEngineUdfps::WorkMode::kAuthenticate);
     mEngine.onPointerDownImpl(1, 2, 3, 4.0, 5.0);
@@ -158,6 +159,7 @@
     std::promise<void> cancel;
     keymaster::HardwareAuthToken hat{.mac = {5, 6}};
     FingerprintHalProperties::next_enrollment("5:0,0:true");
+    mEngine.notifyFingerdown();
     mEngine.enrollImpl(cb.get(), hat, cancel.get_future());
     ASSERT_TRUE(mEngine.getWorkMode() == FakeFingerprintEngineUdfps::WorkMode::kEnroll);
     mEngine.onPointerDownImpl(1, 2, 3, 4.0, 5.0);
@@ -173,6 +175,7 @@
     FingerprintHalProperties::operation_detect_interaction_acquired("");
     std::shared_ptr<TestSessionCallback> cb = ndk::SharedRefBase::make<TestSessionCallback>();
     std::promise<void> cancel;
+    mEngine.notifyFingerdown();
     mEngine.detectInteractionImpl(cb.get(), cancel.get_future());
     ASSERT_TRUE(mEngine.getWorkMode() == FakeFingerprintEngineUdfps::WorkMode::kDetectInteract);
     mEngine.onPointerDownImpl(1, 2, 3, 4.0, 5.0);
diff --git a/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp b/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
index b598044..85bc48a 100644
--- a/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
+++ b/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
@@ -120,6 +120,16 @@
     ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
 static std::vector<LatencyMode> latency_modes = {LatencyMode::FREE};
 
+enum class BluetoothAudioHalVersion : int32_t {
+  VERSION_UNAVAILABLE = 0,
+  VERSION_2_0,
+  VERSION_2_1,
+  VERSION_AIDL_V1,
+  VERSION_AIDL_V2,
+  VERSION_AIDL_V3,
+  VERSION_AIDL_V4,
+};
+
 // Some valid configs for HFP PCM configuration (software sessions)
 static constexpr int32_t hfp_sample_rates_[] = {8000, 16000, 32000};
 static constexpr int8_t hfp_bits_per_samples_[] = {16};
@@ -221,7 +231,6 @@
     temp_provider_info_ = std::nullopt;
     auto aidl_reval =
         provider_factory_->getProviderInfo(session_type, &temp_provider_info_);
-    ASSERT_TRUE(aidl_reval.isOk());
   }
 
   void GetProviderCapabilitiesHelper(const SessionType& session_type) {
@@ -623,9 +632,38 @@
       SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
       SessionType::A2DP_SOFTWARE_DECODING_DATAPATH,
       SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH,
+  };
+
+  static constexpr SessionType kAndroidVSessionType[] = {
       SessionType::HFP_SOFTWARE_ENCODING_DATAPATH,
       SessionType::HFP_SOFTWARE_DECODING_DATAPATH,
   };
+
+  BluetoothAudioHalVersion GetProviderFactoryInterfaceVersion() {
+    int32_t aidl_version = 0;
+    if (provider_factory_ == nullptr) {
+      return BluetoothAudioHalVersion::VERSION_UNAVAILABLE;
+    }
+
+    auto aidl_retval = provider_factory_->getInterfaceVersion(&aidl_version);
+    if (!aidl_retval.isOk()) {
+      return BluetoothAudioHalVersion::VERSION_UNAVAILABLE;
+    }
+    switch (aidl_version) {
+      case 1:
+        return BluetoothAudioHalVersion::VERSION_AIDL_V1;
+      case 2:
+        return BluetoothAudioHalVersion::VERSION_AIDL_V2;
+      case 3:
+        return BluetoothAudioHalVersion::VERSION_AIDL_V3;
+      case 4:
+        return BluetoothAudioHalVersion::VERSION_AIDL_V4;
+      default:
+        return BluetoothAudioHalVersion::VERSION_UNAVAILABLE;
+    }
+
+    return BluetoothAudioHalVersion::VERSION_UNAVAILABLE;
+  }
 };
 
 /**
@@ -647,6 +685,15 @@
     EXPECT_TRUE(temp_provider_capabilities_.empty() ||
                 audio_provider_ != nullptr);
   }
+  if (GetProviderFactoryInterfaceVersion() >=
+      BluetoothAudioHalVersion::VERSION_AIDL_V4) {
+    for (auto session_type : kAndroidVSessionType) {
+      GetProviderCapabilitiesHelper(session_type);
+      OpenProviderHelper(session_type);
+      EXPECT_TRUE(temp_provider_capabilities_.empty() ||
+                  audio_provider_ != nullptr);
+    }
+  }
 }
 
 /**
@@ -1464,8 +1511,8 @@
 
 /**
  * Test whether each provider of type
- * SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH can be started and stopped with
- * different PCM config
+ * SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH can be started and stopped
+ * with different PCM config
  */
 TEST_P(BluetoothAudioProviderA2dpEncodingSoftwareAidl,
        StartAndEndA2dpEncodingSoftwareSessionWithPossiblePcmConfig) {
@@ -1502,6 +1549,10 @@
  public:
   virtual void SetUp() override {
     BluetoothAudioProviderFactoryAidl::SetUp();
+    if (GetProviderFactoryInterfaceVersion() <
+        BluetoothAudioHalVersion::VERSION_AIDL_V4) {
+      GTEST_SKIP();
+    }
     GetProviderCapabilitiesHelper(SessionType::HFP_SOFTWARE_ENCODING_DATAPATH);
     OpenProviderHelper(SessionType::HFP_SOFTWARE_ENCODING_DATAPATH);
     ASSERT_NE(audio_provider_, nullptr);
@@ -1569,6 +1620,10 @@
  public:
   virtual void SetUp() override {
     BluetoothAudioProviderFactoryAidl::SetUp();
+    if (GetProviderFactoryInterfaceVersion() <
+        BluetoothAudioHalVersion::VERSION_AIDL_V4) {
+      GTEST_SKIP();
+    }
     GetProviderCapabilitiesHelper(SessionType::HFP_SOFTWARE_DECODING_DATAPATH);
     OpenProviderHelper(SessionType::HFP_SOFTWARE_DECODING_DATAPATH);
     ASSERT_NE(audio_provider_, nullptr);
@@ -1657,8 +1712,8 @@
 
 /**
  * Test whether each provider of type
- * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
- * SBC hardware encoding config
+ * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped
+ * with SBC hardware encoding config
  */
 TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
        StartAndEndA2dpSbcEncodingHardwareSession) {
@@ -1687,8 +1742,8 @@
 
 /**
  * Test whether each provider of type
- * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
- * AAC hardware encoding config
+ * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped
+ * with AAC hardware encoding config
  */
 TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
        StartAndEndA2dpAacEncodingHardwareSession) {
@@ -1717,8 +1772,8 @@
 
 /**
  * Test whether each provider of type
- * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
- * LDAC hardware encoding config
+ * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped
+ * with LDAC hardware encoding config
  */
 TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
        StartAndEndA2dpLdacEncodingHardwareSession) {
@@ -1747,8 +1802,8 @@
 
 /**
  * Test whether each provider of type
- * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
- * Opus hardware encoding config
+ * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped
+ * with Opus hardware encoding config
  */
 TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
        StartAndEndA2dpOpusEncodingHardwareSession) {
@@ -1777,8 +1832,8 @@
 
 /**
  * Test whether each provider of type
- * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
- * AptX hardware encoding config
+ * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped
+ * with AptX hardware encoding config
  */
 TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
        StartAndEndA2dpAptxEncodingHardwareSession) {
@@ -1813,8 +1868,8 @@
 
 /**
  * Test whether each provider of type
- * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
- * an invalid codec config
+ * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped
+ * with an invalid codec config
  */
 TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
        StartAndEndA2dpEncodingHardwareSessionInvalidCodecConfig) {
@@ -1885,6 +1940,10 @@
  public:
   virtual void SetUp() override {
     BluetoothAudioProviderFactoryAidl::SetUp();
+    if (GetProviderFactoryInterfaceVersion() <
+        BluetoothAudioHalVersion::VERSION_AIDL_V4) {
+      GTEST_SKIP();
+    }
     OpenProviderHelper(SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH);
     // Can open or empty capability
     ASSERT_TRUE(temp_provider_capabilities_.empty() ||
@@ -2418,6 +2477,10 @@
 TEST_P(
     BluetoothAudioProviderLeAudioOutputHardwareAidl,
     StartAndEndLeAudioOutputSessionWithPossibleUnicastConfigFromProviderInfo) {
+  if (GetProviderFactoryInterfaceVersion() <
+      BluetoothAudioHalVersion::VERSION_AIDL_V4) {
+    GTEST_SKIP();
+  }
   if (!IsOffloadOutputProviderInfoSupported()) {
     GTEST_SKIP();
   }
@@ -2443,6 +2506,10 @@
 
 TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
        GetEmptyAseConfigurationEmptyCapability) {
+  if (GetProviderFactoryInterfaceVersion() <
+      BluetoothAudioHalVersion::VERSION_AIDL_V4) {
+    GTEST_SKIP();
+  }
   std::vector<std::optional<LeAudioDeviceCapabilities>> empty_capability;
   std::vector<LeAudioConfigurationRequirement> empty_requirement;
   std::vector<LeAudioAseConfigurationSetting> configurations;
@@ -2464,6 +2531,10 @@
 
 TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
        GetEmptyAseConfigurationMismatchedRequirement) {
+  if (GetProviderFactoryInterfaceVersion() <
+      BluetoothAudioHalVersion::VERSION_AIDL_V4) {
+    GTEST_SKIP();
+  }
   std::vector<std::optional<LeAudioDeviceCapabilities>> capabilities = {
       GetDefaultRemoteCapability()};
 
@@ -2488,6 +2559,10 @@
 }
 
 TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl, GetQoSConfiguration) {
+  if (GetProviderFactoryInterfaceVersion() <
+      BluetoothAudioHalVersion::VERSION_AIDL_V4) {
+    GTEST_SKIP();
+  }
   IBluetoothAudioProvider::LeAudioAseQosConfigurationRequirement requirement;
   std::vector<IBluetoothAudioProvider::LeAudioAseQosConfiguration>
       QoSConfigurations;
@@ -2862,16 +2937,16 @@
 
 /**
  * Test whether each provider of type
- * SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH can be started and
- * stopped
+ * SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH can be started
+ * and stopped
  */
 TEST_P(BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,
        OpenLeAudioOutputSoftwareProvider) {}
 
 /**
  * Test whether each provider of type
- * SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH can be started and
- * stopped with different PCM config
+ * SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH can be started
+ * and stopped with different PCM config
  */
 TEST_P(BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,
        StartAndEndLeAudioOutputSessionWithPossiblePcmConfig) {
@@ -3045,6 +3120,10 @@
 TEST_P(
     BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
     StartAndEndLeAudioBroadcastSessionWithPossibleUnicastConfigFromProviderInfo) {
+  if (GetProviderFactoryInterfaceVersion() <
+      BluetoothAudioHalVersion::VERSION_AIDL_V4) {
+    GTEST_SKIP();
+  }
   if (!IsBroadcastOffloadProviderInfoSupported()) {
     return;
   }
@@ -3076,6 +3155,10 @@
 
 TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
        GetEmptyBroadcastConfigurationEmptyCapability) {
+  if (GetProviderFactoryInterfaceVersion() <
+      BluetoothAudioHalVersion::VERSION_AIDL_V4) {
+    GTEST_SKIP();
+  }
   std::vector<std::optional<LeAudioDeviceCapabilities>> empty_capability;
   IBluetoothAudioProvider::LeAudioBroadcastConfigurationRequirement
       empty_requirement;
@@ -3190,8 +3273,8 @@
 
 /**
  * Test whether each provider of type
- * SessionType::A2DP_SOFTWARE_DECODING_DATAPATH can be started and stopped with
- * different PCM config
+ * SessionType::A2DP_SOFTWARE_DECODING_DATAPATH can be started and stopped
+ * with different PCM config
  */
 TEST_P(BluetoothAudioProviderA2dpDecodingSoftwareAidl,
        StartAndEndA2dpDecodingSoftwareSessionWithPossiblePcmConfig) {
@@ -3252,8 +3335,8 @@
 
 /**
  * Test whether each provider of type
- * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
- * SBC hardware encoding config
+ * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped
+ * with SBC hardware encoding config
  */
 TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
        StartAndEndA2dpSbcDecodingHardwareSession) {
@@ -3282,8 +3365,8 @@
 
 /**
  * Test whether each provider of type
- * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
- * AAC hardware encoding config
+ * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped
+ * with AAC hardware encoding config
  */
 TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
        StartAndEndA2dpAacDecodingHardwareSession) {
@@ -3312,8 +3395,8 @@
 
 /**
  * Test whether each provider of type
- * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
- * LDAC hardware encoding config
+ * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped
+ * with LDAC hardware encoding config
  */
 TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
        StartAndEndA2dpLdacDecodingHardwareSession) {
@@ -3342,8 +3425,8 @@
 
 /**
  * Test whether each provider of type
- * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
- * Opus hardware encoding config
+ * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped
+ * with Opus hardware encoding config
  */
 TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
        StartAndEndA2dpOpusDecodingHardwareSession) {
@@ -3372,8 +3455,8 @@
 
 /**
  * Test whether each provider of type
- * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
- * AptX hardware encoding config
+ * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped
+ * with AptX hardware encoding config
  */
 TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
        StartAndEndA2dpAptxDecodingHardwareSession) {
@@ -3408,8 +3491,8 @@
 
 /**
  * Test whether each provider of type
- * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
- * an invalid codec config
+ * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped
+ * with an invalid codec config
  */
 TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
        StartAndEndA2dpDecodingHardwareSessionInvalidCodecConfig) {
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/ChannelSoundingSingleSideData.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/ChannelSoundingSingleSideData.aidl
index ddaba72..172ac5e 100644
--- a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/ChannelSoundingSingleSideData.aidl
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/ChannelSoundingSingleSideData.aidl
@@ -34,13 +34,13 @@
 package android.hardware.bluetooth.ranging;
 @VintfStability
 parcelable ChannelSoundingSingleSideData {
-  @nullable List<android.hardware.bluetooth.ranging.StepTonePct> stepTonePcts;
+  @nullable android.hardware.bluetooth.ranging.StepTonePct[] stepTonePcts;
   @nullable byte[] packetQuality;
   @nullable byte[] packetRssiDbm;
   @nullable android.hardware.bluetooth.ranging.Nadm[] packetNadm;
   @nullable int[] measuredFreqOffset;
-  @nullable List<android.hardware.bluetooth.ranging.ComplexNumber> packetPct1;
-  @nullable List<android.hardware.bluetooth.ranging.ComplexNumber> packetPct2;
+  @nullable android.hardware.bluetooth.ranging.ComplexNumber[] packetPct1;
+  @nullable android.hardware.bluetooth.ranging.ComplexNumber[] packetPct2;
   byte referencePowerDbm;
   @nullable byte[] vendorSpecificCsSingleSidedata;
 }
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/ModeType.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/ModeType.aidl
index 75cdabc..1e8ae91 100644
--- a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/ModeType.aidl
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/ModeType.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.bluetooth.ranging;
-@Backing(type="int") @VintfStability
+@Backing(type="byte") @VintfStability
 enum ModeType {
   ZERO = 0x00,
   ONE = 0x01,
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/SubModeType.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/SubModeType.aidl
index f660c91..b72a97d 100644
--- a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/SubModeType.aidl
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/SubModeType.aidl
@@ -32,10 +32,10 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.bluetooth.ranging;
-@Backing(type="int") @VintfStability
+@Backing(type="byte") @VintfStability
 enum SubModeType {
   ONE = 0x01,
   TWO = 0x02,
   THREE = 0x03,
-  UNUSED = 0xff,
+  UNUSED = 0xffu8,
 }
diff --git a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/AddressType.aidl b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/AddressType.aidl
index bd03213..499d42f 100644
--- a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/AddressType.aidl
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/AddressType.aidl
@@ -16,9 +16,13 @@
 
 package android.hardware.bluetooth.ranging;
 
+/**
+ * Same as the BLE address type, except anonymous isn't supported for ranging.
+ */
 @VintfStability
 @Backing(type="int")
 enum AddressType {
     PUBLIC = 0x00,
+    /* Still may be fixed on the device and is not randomized on boot */
     RANDOM = 0x01,
 }
diff --git a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ChannelSoudingRawData.aidl b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ChannelSoudingRawData.aidl
index 0106865..78ce4f4 100644
--- a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ChannelSoudingRawData.aidl
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ChannelSoudingRawData.aidl
@@ -21,6 +21,9 @@
 
 /**
  * Raw ranging data of Channel Sounding.
+ * See Channel Sounding CR_PR 3.1.10 and Channel Sounding HCI Updates CR_PR 3.1.23 for details.
+ *
+ * Specification: https://www.bluetooth.com/specifications/specs/channel-sounding-cr-pr/
  */
 @VintfStability
 parcelable ChannelSoudingRawData {
diff --git a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ChannelSoundingSingleSideData.aidl b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ChannelSoundingSingleSideData.aidl
index 942fc0d..9c4b472 100644
--- a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ChannelSoundingSingleSideData.aidl
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ChannelSoundingSingleSideData.aidl
@@ -21,14 +21,17 @@
 import android.hardware.bluetooth.ranging.StepTonePct;
 
 /**
- * Raw ranging data of Channel Sounding from either Initator or Reflector
+ * Raw ranging data of Channel Sounding from either Initator or Reflector.
+ * See Channel Sounding CR_PR 3.1.10 and Channel Sounding HCI Updates CR_PR 3.1.23 for details.
+ *
+ * Specification: https://www.bluetooth.com/specifications/specs/channel-sounding-cr-pr/
  */
 @VintfStability
 parcelable ChannelSoundingSingleSideData {
     /**
      * PCT (complex value) measured from mode-2 or mode-3 steps in a CS procedure (in time order).
      */
-    @nullable List<StepTonePct> stepTonePcts;
+    @nullable StepTonePct[] stepTonePcts;
     /**
      * Packet Quality from mode-1 or mode-3 steps in a CS procedures (in time order).
      */
@@ -49,8 +52,8 @@
      * Packet_PCT1 or packet_PCT2 of mode-1 or mode-3, if sounding sequence is used and sounding
      * phase-based ranging is supported.
      */
-    @nullable List<ComplexNumber> packetPct1;
-    @nullable List<ComplexNumber> packetPct2;
+    @nullable ComplexNumber[] packetPct1;
+    @nullable ComplexNumber[] packetPct2;
     /**
      * Reference power level (-127 to 20) of the signal in the procedure, in dBm.
      */
diff --git a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ModeType.aidl b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ModeType.aidl
index 2058ae8..3a727aa 100644
--- a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ModeType.aidl
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ModeType.aidl
@@ -17,7 +17,7 @@
 package android.hardware.bluetooth.ranging;
 
 @VintfStability
-@Backing(type="int")
+@Backing(type="byte")
 enum ModeType {
     ZERO = 0x00,
     ONE = 0x01,
diff --git a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/Nadm.aidl b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/Nadm.aidl
index 3cfb22f..74cf731 100644
--- a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/Nadm.aidl
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/Nadm.aidl
@@ -16,6 +16,12 @@
 
 package android.hardware.bluetooth.ranging;
 
+/**
+ * Normalized Attack Detector Metric.
+ * See Channel Sounding CR_PR, 3.13.24 for details.
+ *
+ * Specification: https://www.bluetooth.com/specifications/specs/channel-sounding-cr-pr/
+ */
 @VintfStability
 @Backing(type="byte")
 enum Nadm {
@@ -26,5 +32,7 @@
     ATTACK_IS_LIKELY = 0x04,
     ATTACK_IS_VERY_LIKELY = 0x05,
     ATTACK_IS_EXTREMELY_LIKELY = 0x06,
+    /* If a device is unable to determine a NADM value, then it shall report a NADM value of Unknown
+     */
     UNKNOWN = 0xFFu8,
 }
diff --git a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/SubModeType.aidl b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/SubModeType.aidl
index ca9bfcb..b775002 100644
--- a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/SubModeType.aidl
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/SubModeType.aidl
@@ -17,10 +17,10 @@
 package android.hardware.bluetooth.ranging;
 
 @VintfStability
-@Backing(type="int")
+@Backing(type="byte")
 enum SubModeType {
     ONE = 0x01,
     TWO = 0x02,
     THREE = 0x03,
-    UNUSED = 0xff,
+    UNUSED = 0xffu8,
 }
diff --git a/broadcastradio/1.0/vts/functional/VtsHalBroadcastradioV1_0TargetTest.cpp b/broadcastradio/1.0/vts/functional/VtsHalBroadcastradioV1_0TargetTest.cpp
index cac3dd0..dec1f17 100644
--- a/broadcastradio/1.0/vts/functional/VtsHalBroadcastradioV1_0TargetTest.cpp
+++ b/broadcastradio/1.0/vts/functional/VtsHalBroadcastradioV1_0TargetTest.cpp
@@ -52,10 +52,9 @@
 using ::android::hardware::broadcastradio::V1_0::Result;
 using ::android::hardware::broadcastradio::V1_0::vts::RadioClassFromString;
 
-#define RETURN_IF_SKIPPED \
-    if (skipped) { \
-        std::cout << "[  SKIPPED ] This device class is not supported. " << std::endl; \
-        return; \
+#define RETURN_IF_SKIPPED                                                   \
+    if (skipped) {                                                          \
+        GTEST_SKIP() << "This device class is not supported."; \
     }
 
 // The main test class for Broadcast Radio HIDL HAL.
@@ -734,4 +733,4 @@
         testing::Combine(testing::ValuesIn(android::hardware::getAllHalInstanceNames(
                                  IBroadcastRadioFactory::descriptor)),
                          ::testing::Values("AM_FM", "SAT", "DT")),
-        android::hardware::PrintInstanceTupleNameToString<>);
\ No newline at end of file
+        android::hardware::PrintInstanceTupleNameToString<>);
diff --git a/broadcastradio/1.1/vts/functional/VtsHalBroadcastradioV1_1TargetTest.cpp b/broadcastradio/1.1/vts/functional/VtsHalBroadcastradioV1_1TargetTest.cpp
index caf6cbd..b54e9d8 100644
--- a/broadcastradio/1.1/vts/functional/VtsHalBroadcastradioV1_1TargetTest.cpp
+++ b/broadcastradio/1.1/vts/functional/VtsHalBroadcastradioV1_1TargetTest.cpp
@@ -73,10 +73,6 @@
     ProgramType::AM,  ProgramType::FM,   ProgramType::AM_HD, ProgramType::FM_HD,
     ProgramType::DAB, ProgramType::DRMO, ProgramType::SXM};
 
-static void printSkipped(std::string msg) {
-    std::cout << "[  SKIPPED ] " << msg << std::endl;
-}
-
 struct TunerCallbackMock : public ITunerCallback {
     TunerCallbackMock() { EXPECT_CALL(*this, hardwareFailure()).Times(0); }
 
@@ -106,7 +102,6 @@
     bool getProgramList(std::function<void(const hidl_vec<ProgramInfo>& list)> cb);
 
     Class radioClass;
-    bool skipped = false;
 
     sp<IBroadcastRadio> mRadioModule;
     sp<ITuner> mTuner;
@@ -137,9 +132,7 @@
     ASSERT_TRUE(onConnect.waitForCall(kConnectModuleTimeout));
 
     if (connectResult == Result::INVALID_ARGUMENTS) {
-        printSkipped("This device class is not supported.");
-        skipped = true;
-        return;
+        GTEST_SKIP() << "This device class is not supported.";
     }
     ASSERT_EQ(connectResult, Result::OK);
     ASSERT_NE(nullptr, mRadioModule.get());
@@ -285,8 +278,6 @@
  * might fail.
  */
 TEST_P(BroadcastRadioHalTest, OpenTunerTwice) {
-    if (skipped) return;
-
     ASSERT_TRUE(openTuner());
 
     auto secondTuner = mTuner;
@@ -306,7 +297,6 @@
  *  - getProgramInformation_1_1 returns the same selector as returned in tuneComplete_1_1 call.
  */
 TEST_P(BroadcastRadioHalTest, TuneFromProgramList) {
-    if (skipped) return;
     ASSERT_TRUE(openTuner());
 
     ProgramInfo firstProgram;
@@ -320,8 +310,7 @@
     } while (nextBand());
     if (HasFailure()) return;
     if (!foundAny) {
-        printSkipped("Program list is empty.");
-        return;
+        GTEST_SKIP() << "Program list is empty.";
     }
 
     ProgramInfo infoCb;
@@ -356,7 +345,6 @@
  *    identifier for program types other than VENDORn.
  */
 TEST_P(BroadcastRadioHalTest, TuneFailsForPrimaryVendor) {
-    if (skipped) return;
     ASSERT_TRUE(openTuner());
 
     for (auto ptype : kStandardProgramTypes) {
@@ -377,7 +365,6 @@
  *  - tuneByProgramSelector fails with INVALID_ARGUMENT when unknown program type is passed.
  */
 TEST_P(BroadcastRadioHalTest, TuneFailsForUnknownProgram) {
-    if (skipped) return;
     ASSERT_TRUE(openTuner());
 
     // Program type is 1-based, so 0 will be always invalid.
@@ -393,7 +380,6 @@
  *  - cancelAnnouncement succeeds either when there is an announcement or there is none.
  */
 TEST_P(BroadcastRadioHalTest, CancelAnnouncement) {
-    if (skipped) return;
     ASSERT_TRUE(openTuner());
 
     auto hidlResult = mTuner->cancelAnnouncement();
@@ -407,8 +393,6 @@
  * - getImage call handles argument 0 gracefully.
  */
 TEST_P(BroadcastRadioHalTest, GetNoImage) {
-    if (skipped) return;
-
     size_t len = 0;
     auto hidlResult =
         mRadioModule->getImage(0, [&](hidl_vec<uint8_t> rawImage) { len = rawImage.size(); });
@@ -425,7 +409,6 @@
  * - images are available for getImage call.
  */
 TEST_P(BroadcastRadioHalTest, OobImagesOnly) {
-    if (skipped) return;
     ASSERT_TRUE(openTuner());
 
     std::vector<int> imageIds;
@@ -446,8 +429,7 @@
     } while (nextBand());
 
     if (imageIds.size() == 0) {
-        printSkipped("No images found");
-        return;
+        GTEST_SKIP() << "No images found";
     }
 
     for (auto id : imageIds) {
@@ -469,7 +451,6 @@
  * - setAnalogForced results either with INVALID_STATE, or isAnalogForced replying the same.
  */
 TEST_P(BroadcastRadioHalTest, AnalogForcedSwitch) {
-    if (skipped) return;
     ASSERT_TRUE(openTuner());
 
     bool forced;
@@ -584,7 +565,6 @@
  * - values of ProgramIdentifier match their definitions at IdentifierType.
  */
 TEST_P(BroadcastRadioHalTest, VerifyIdentifiersFormat) {
-    if (skipped) return;
     ASSERT_TRUE(openTuner());
 
     do {
diff --git a/broadcastradio/aidl/vts/src/VtsHalBroadcastradioAidlTargetTest.cpp b/broadcastradio/aidl/vts/src/VtsHalBroadcastradioAidlTargetTest.cpp
index 754b05b..9633ebb 100644
--- a/broadcastradio/aidl/vts/src/VtsHalBroadcastradioAidlTargetTest.cpp
+++ b/broadcastradio/aidl/vts/src/VtsHalBroadcastradioAidlTargetTest.cpp
@@ -250,6 +250,16 @@
         }
     }
 
+    for (const auto& metadataItem : info.metadata) {
+        bool validMetadata = false;
+        if (mCallbackAidlVersion == kAidlVersion1) {
+            validMetadata = bcutils::isValidMetadata(metadataItem);
+        } else {
+            validMetadata = bcutils::isValidMetadataV2(metadataItem);
+        }
+        EXPECT_TRUE(validMetadata) << "Invalid metadata " << metadataItem.toString().c_str();
+    }
+
     {
         std::lock_guard<std::mutex> lk(mLock);
         mCurrentProgramInfo = info;
diff --git a/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/Utils.h b/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/Utils.h
index 3ced685..25c96d0 100644
--- a/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/Utils.h
+++ b/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/Utils.h
@@ -143,6 +143,8 @@
 
 bool satisfies(const ProgramFilter& filter, const ProgramSelector& sel);
 
+bool isValidMetadata(const Metadata& metadata);
+
 struct ProgramSelectorComparator {
     bool operator()(const ProgramSelector& lhs, const ProgramSelector& rhs) const;
 };
diff --git a/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/UtilsV2.h b/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/UtilsV2.h
index e411aa4..734758d 100644
--- a/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/UtilsV2.h
+++ b/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/UtilsV2.h
@@ -28,6 +28,7 @@
 
 bool isValidV2(const ProgramIdentifier& id);
 bool isValidV2(const ProgramSelector& sel);
+bool isValidMetadataV2(const Metadata& metadata);
 std::optional<std::string> getMetadataStringV2(const ProgramInfo& info, const Metadata::Tag& tag);
 
 }  // namespace utils
diff --git a/broadcastradio/common/utilsaidl/src/Utils.cpp b/broadcastradio/common/utilsaidl/src/Utils.cpp
index b647442..ddc5b8d 100644
--- a/broadcastradio/common/utilsaidl/src/Utils.cpp
+++ b/broadcastradio/common/utilsaidl/src/Utils.cpp
@@ -442,9 +442,9 @@
 }
 
 std::optional<std::string> getMetadataString(const ProgramInfo& info, const Metadata::Tag& tag) {
-    auto isRdsPs = [tag](const Metadata& item) { return item.getTag() == tag; };
+    auto hasMetadataType = [tag](const Metadata& item) { return item.getTag() == tag; };
 
-    auto it = std::find_if(info.metadata.begin(), info.metadata.end(), isRdsPs);
+    auto it = std::find_if(info.metadata.begin(), info.metadata.end(), hasMetadataType);
     if (it == info.metadata.end()) {
         return std::nullopt;
     }
@@ -579,6 +579,45 @@
     return getHdFrequency(sel);
 }
 
+bool isValidMetadata(const Metadata& metadata) {
+    bool valid = true;
+
+    auto expect = [&valid](bool condition, const std::string& message) {
+        if (!condition) {
+            valid = false;
+            LOG(ERROR) << "metadata not valid, expected " << message;
+        }
+    };
+
+    switch (metadata.getTag()) {
+        case Metadata::rdsPty:
+            expect(metadata.get<Metadata::rdsPty>() >= 0, "RDS PTY >= 0");
+            expect(metadata.get<Metadata::rdsPty>() <= std::numeric_limits<uint8_t>::max(),
+                   "8bit RDS PTY");
+            break;
+        case Metadata::rbdsPty:
+            expect(metadata.get<Metadata::rbdsPty>() >= 0, "RBDS PTY >= 0");
+            expect(metadata.get<Metadata::rbdsPty>() <= std::numeric_limits<uint8_t>::max(),
+                   "8bit RBDS PTY");
+            break;
+        case Metadata::dabEnsembleNameShort:
+            expect(metadata.get<Metadata::dabEnsembleNameShort>().size() <= 8,
+                   "Dab ensemble name abbreviated length <= 8");
+            break;
+        case Metadata::dabServiceNameShort:
+            expect(metadata.get<Metadata::dabServiceNameShort>().size() <= 8,
+                   "Dab component name abbreviated length <= 8");
+            break;
+        case Metadata::dabComponentNameShort:
+            expect(metadata.get<Metadata::dabComponentNameShort>().size() <= 8,
+                   "Dab component name abbreviated length <= 8");
+            break;
+        default:
+            break;
+    }
+    return valid;
+}
+
 bool parseArgInt(const std::string& s, int* out) {
     return ::android::base::ParseInt(s, out);
 }
diff --git a/broadcastradio/common/utilsaidl/src/UtilsV2.cpp b/broadcastradio/common/utilsaidl/src/UtilsV2.cpp
index ef739df..6c75759 100644
--- a/broadcastradio/common/utilsaidl/src/UtilsV2.cpp
+++ b/broadcastradio/common/utilsaidl/src/UtilsV2.cpp
@@ -17,6 +17,7 @@
 #define LOG_TAG "BcRadioAidlDef.utilsV2"
 
 #include "broadcastradio-utils-aidl/UtilsV2.h"
+#include "broadcastradio-utils-aidl/Utils.h"
 
 #include <android-base/logging.h>
 #include <android-base/strings.h>
@@ -137,10 +138,33 @@
     return isValidV2(sel.primaryId);
 }
 
-std::optional<std::string> getMetadataStringV2(const ProgramInfo& info, const Metadata::Tag& tag) {
-    auto isRdsPs = [tag](const Metadata& item) { return item.getTag() == tag; };
+bool isValidMetadataV2(const Metadata& metadata) {
+    if (!isValidMetadata(metadata)) {
+        return false;
+    }
 
-    auto it = std::find_if(info.metadata.begin(), info.metadata.end(), isRdsPs);
+    if (metadata.getTag() == Metadata::hdStationNameShort) {
+        if (metadata.get<Metadata::hdStationNameShort>().size() > 12) {
+            LOG(ERROR) << "metadata not valid, expected HD short name length <= 12";
+            return false;
+        }
+    } else if (metadata.getTag() == Metadata::hdSubChannelsAvailable) {
+        if (metadata.get<Metadata::hdSubChannelsAvailable>() < 0) {
+            LOG(ERROR) << "metadata not valid, expected HD subchannels available >= 0";
+            return false;
+        } else if (metadata.get<Metadata::hdSubChannelsAvailable>() >
+                   std::numeric_limits<uint8_t>::max()) {
+            LOG(ERROR) << "metadata not valid, expected 8bit HD subchannels available";
+            return false;
+        }
+    }
+    return true;
+}
+
+std::optional<std::string> getMetadataStringV2(const ProgramInfo& info, const Metadata::Tag& tag) {
+    auto hasMetadataType = [tag](const Metadata& item) { return item.getTag() == tag; };
+
+    auto it = std::find_if(info.metadata.begin(), info.metadata.end(), hasMetadataType);
     if (it == info.metadata.end()) {
         return std::nullopt;
     }
diff --git a/broadcastradio/common/utilsaidl/test/BroadcastRadioUtilsTest.cpp b/broadcastradio/common/utilsaidl/test/BroadcastRadioUtilsTest.cpp
index b2dc94a..b115f75 100644
--- a/broadcastradio/common/utilsaidl/test/BroadcastRadioUtilsTest.cpp
+++ b/broadcastradio/common/utilsaidl/test/BroadcastRadioUtilsTest.cpp
@@ -32,8 +32,139 @@
 constexpr uint64_t kHdStationId = 0xA0000001u;
 constexpr uint64_t kHdSubChannel = 1u;
 constexpr uint64_t kHdFrequency = 97700u;
+
+const Properties kAmFmTunerProp = {
+        .maker = "makerTest",
+        .product = "productTest",
+        .supportedIdentifierTypes = {IdentifierType::AMFM_FREQUENCY_KHZ, IdentifierType::RDS_PI,
+                                     IdentifierType::HD_STATION_ID_EXT}};
+
+struct GetBandTestCase {
+    std::string name;
+    int64_t frequency;
+    utils::FrequencyBand bandResult;
+};
+
+std::vector<GetBandTestCase> getBandTestCases() {
+    return std::vector<GetBandTestCase>(
+            {GetBandTestCase{.name = "unknown_low_band",
+                             .frequency = 0,
+                             .bandResult = utils::FrequencyBand::UNKNOWN},
+             GetBandTestCase{.name = "am_lw_band",
+                             .frequency = 30,
+                             .bandResult = utils::FrequencyBand::AM_LW},
+             GetBandTestCase{.name = "am_mw_band",
+                             .frequency = 700,
+                             .bandResult = utils::FrequencyBand::AM_MW},
+             GetBandTestCase{.name = "am_sw_band",
+                             .frequency = 2000,
+                             .bandResult = utils::FrequencyBand::AM_SW},
+             GetBandTestCase{
+                     .name = "fm_band", .frequency = 97900, .bandResult = utils::FrequencyBand::FM},
+             GetBandTestCase{.name = "unknown_high_band",
+                             .frequency = 110000,
+                             .bandResult = utils::FrequencyBand::UNKNOWN}});
+}
+
+struct IsValidMetadataTestCase {
+    std::string name;
+    Metadata metadata;
+    bool valid;
+};
+
+std::vector<IsValidMetadataTestCase> getIsValidMetadataTestCases() {
+    return std::vector<IsValidMetadataTestCase>({
+            IsValidMetadataTestCase{.name = "valid_rds_pty",
+                                    .metadata = Metadata::make<Metadata::rdsPty>(1),
+                                    .valid = true},
+            IsValidMetadataTestCase{.name = "negative_rds_pty",
+                                    .metadata = Metadata::make<Metadata::rdsPty>(-1),
+                                    .valid = false},
+            IsValidMetadataTestCase{.name = "large_rds_pty",
+                                    .metadata = Metadata::make<Metadata::rdsPty>(256),
+                                    .valid = false},
+            IsValidMetadataTestCase{.name = "valid_rbds_pty",
+                                    .metadata = Metadata::make<Metadata::rbdsPty>(1),
+                                    .valid = true},
+            IsValidMetadataTestCase{.name = "negative_rbds_pty",
+                                    .metadata = Metadata::make<Metadata::rbdsPty>(-1),
+                                    .valid = false},
+            IsValidMetadataTestCase{.name = "large_rbds_pty",
+                                    .metadata = Metadata::make<Metadata::rbdsPty>(256),
+                                    .valid = false},
+            IsValidMetadataTestCase{
+                    .name = "valid_dab_ensemble_name_short",
+                    .metadata = Metadata::make<Metadata::dabEnsembleNameShort>("name"),
+                    .valid = true},
+            IsValidMetadataTestCase{
+                    .name = "too_long_dab_ensemble_name_short",
+                    .metadata = Metadata::make<Metadata::dabEnsembleNameShort>("name_long"),
+                    .valid = false},
+            IsValidMetadataTestCase{
+                    .name = "valid_dab_service_name_short",
+                    .metadata = Metadata::make<Metadata::dabServiceNameShort>("name"),
+                    .valid = true},
+            IsValidMetadataTestCase{
+                    .name = "too_long_dab_service_name_short",
+                    .metadata = Metadata::make<Metadata::dabServiceNameShort>("name_long"),
+                    .valid = false},
+            IsValidMetadataTestCase{
+                    .name = "valid_dab_component_name_short",
+                    .metadata = Metadata::make<Metadata::dabComponentNameShort>("name"),
+                    .valid = true},
+            IsValidMetadataTestCase{
+                    .name = "too_long_dab_component_name_short",
+                    .metadata = Metadata::make<Metadata::dabComponentNameShort>("name_long"),
+                    .valid = false},
+    });
+}
 }  // namespace
 
+class GetBandTest : public testing::TestWithParam<GetBandTestCase> {};
+
+INSTANTIATE_TEST_SUITE_P(GetBandTests, GetBandTest, testing::ValuesIn(getBandTestCases()),
+                         [](const testing::TestParamInfo<GetBandTest::ParamType>& info) {
+                             return info.param.name;
+                         });
+
+TEST_P(GetBandTest, GetBand) {
+    GetBandTestCase testcase = GetParam();
+
+    ASSERT_EQ(utils::getBand(testcase.frequency), testcase.bandResult);
+}
+
+class IsValidMetadataTest : public testing::TestWithParam<IsValidMetadataTestCase> {};
+
+INSTANTIATE_TEST_SUITE_P(IsValidMetadataTests, IsValidMetadataTest,
+                         testing::ValuesIn(getIsValidMetadataTestCases()),
+                         [](const testing::TestParamInfo<IsValidMetadataTest::ParamType>& info) {
+                             return info.param.name;
+                         });
+
+TEST_P(IsValidMetadataTest, IsValidMetadata) {
+    IsValidMetadataTestCase testParam = GetParam();
+
+    ASSERT_EQ(utils::isValidMetadata(testParam.metadata), testParam.valid);
+}
+
+TEST(BroadcastRadioUtilsTest, IsSupportedWithSupportedSelector) {
+    ProgramSelector sel = utils::makeSelectorAmfm(kFmFrequencyKHz);
+
+    ASSERT_TRUE(utils::isSupported(kAmFmTunerProp, sel));
+}
+
+TEST(BroadcastRadioUtilsTest, IsSupportedWithUnsupportedSelector) {
+    ProgramSelector sel = utils::makeSelectorDab(kDabSidExt, kDabEnsemble, kDabFrequencyKhz);
+
+    ASSERT_FALSE(utils::isSupported(kAmFmTunerProp, sel));
+}
+
+TEST(BroadcastRadioUtilsTest, GetBandWithFmFrequency) {
+    ProgramSelector sel = utils::makeSelectorAmfm(kFmFrequencyKHz);
+
+    ASSERT_TRUE(utils::hasId(sel, IdentifierType::AMFM_FREQUENCY_KHZ));
+}
+
 TEST(BroadcastRadioUtilsTest, HasIdWithPrimaryIdType) {
     ProgramSelector sel = utils::makeSelectorAmfm(kFmFrequencyKHz);
 
@@ -85,6 +216,25 @@
               static_cast<int64_t>(kFmFrequencyKHz));
 }
 
+TEST(BroadcastRadioUtilsTest, GetAllIdsWithAvailableIds) {
+    int64_t secondaryFrequencyKHz = kFmFrequencyKHz + 200;
+    ProgramSelector sel = utils::makeSelectorAmfm(kFmFrequencyKHz);
+    sel.secondaryIds.push_back(
+            utils::makeIdentifier(IdentifierType::AMFM_FREQUENCY_KHZ, secondaryFrequencyKHz));
+
+    std::vector<int> allIds = utils::getAllIds(sel, IdentifierType::AMFM_FREQUENCY_KHZ);
+
+    ASSERT_EQ(allIds.size(), 2u);
+    EXPECT_NE(std::find(allIds.begin(), allIds.end(), kFmFrequencyKHz), allIds.end());
+    EXPECT_NE(std::find(allIds.begin(), allIds.end(), secondaryFrequencyKHz), allIds.end());
+}
+
+TEST(BroadcastRadioUtilsTest, GetAllIdsWithIdNotFound) {
+    ProgramSelector sel = utils::makeSelectorDab(kDabSidExt, kDabEnsemble, kDabFrequencyKhz);
+
+    ASSERT_TRUE(utils::getAllIds(sel, IdentifierType::AMFM_FREQUENCY_KHZ).empty());
+}
+
 TEST(BroadcastRadioUtilsTest, MakeIdentifier) {
     ProgramIdentifier id =
             utils::makeIdentifier(IdentifierType::AMFM_FREQUENCY_KHZ, kFmFrequencyKHz);
@@ -205,4 +355,36 @@
     ASSERT_EQ(utils::getDabSCIdS(sel), kDabSCIdS);
 }
 
+TEST(BroadcastRadioUtilsTest, SatisfiesWithSatisfiedIdTypesFilter) {
+    ProgramFilter filter = ProgramFilter{.identifierTypes = {IdentifierType::DAB_FREQUENCY_KHZ}};
+    ProgramSelector sel = utils::makeSelectorDab(kDabSidExt, kDabEnsemble, kDabFrequencyKhz);
+
+    ASSERT_TRUE(utils::satisfies(filter, sel));
+}
+
+TEST(BroadcastRadioUtilsTest, SatisfiesWithUnsatisfiedIdTypesFilter) {
+    ProgramFilter filter = ProgramFilter{.identifierTypes = {IdentifierType::DAB_FREQUENCY_KHZ}};
+    ProgramSelector sel = utils::makeSelectorAmfm(kFmFrequencyKHz);
+
+    ASSERT_FALSE(utils::satisfies(filter, sel));
+}
+
+TEST(BroadcastRadioUtilsTest, SatisfiesWithSatisfiedIdsFilter) {
+    ProgramFilter filter =
+            ProgramFilter{.identifiers = {utils::makeIdentifier(IdentifierType::DAB_FREQUENCY_KHZ,
+                                                                kDabFrequencyKhz)}};
+    ProgramSelector sel = utils::makeSelectorDab(kDabSidExt, kDabEnsemble, kDabFrequencyKhz);
+
+    ASSERT_TRUE(utils::satisfies(filter, sel));
+}
+
+TEST(BroadcastRadioUtilsTest, SatisfiesWithUnsatisfiedIdsFilter) {
+    ProgramFilter filter =
+            ProgramFilter{.identifiers = {utils::makeIdentifier(IdentifierType::DAB_FREQUENCY_KHZ,
+                                                                kDabFrequencyKhz)}};
+    ProgramSelector sel = utils::makeSelectorDab(kDabSidExt, kDabEnsemble, kDabFrequencyKhz + 100);
+
+    ASSERT_FALSE(utils::satisfies(filter, sel));
+}
+
 }  // namespace aidl::android::hardware::broadcastradio
diff --git a/broadcastradio/common/utilsaidl/test/BroadcastRadioUtilsV2Test.cpp b/broadcastradio/common/utilsaidl/test/BroadcastRadioUtilsV2Test.cpp
new file mode 100644
index 0000000..cf9f9e9
--- /dev/null
+++ b/broadcastradio/common/utilsaidl/test/BroadcastRadioUtilsV2Test.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2024 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 <broadcastradio-utils-aidl/UtilsV2.h>
+#include <gtest/gtest.h>
+
+namespace aidl::android::hardware::broadcastradio {
+
+namespace {
+struct IsValidMetadataV2TestCase {
+    std::string name;
+    Metadata metadata;
+    bool valid;
+};
+
+std::vector<IsValidMetadataV2TestCase> getIsValidMetadataV2TestCases() {
+    return std::vector<IsValidMetadataV2TestCase>({
+            IsValidMetadataV2TestCase{.name = "valid_rds_pty",
+                                      .metadata = Metadata::make<Metadata::rdsPty>(1),
+                                      .valid = true},
+            IsValidMetadataV2TestCase{.name = "negative_rds_pty",
+                                      .metadata = Metadata::make<Metadata::rdsPty>(-1),
+                                      .valid = false},
+            IsValidMetadataV2TestCase{
+                    .name = "valid_hd_station_name_short",
+                    .metadata = Metadata::make<Metadata::hdStationNameShort>("name_short"),
+                    .valid = true},
+            IsValidMetadataV2TestCase{
+                    .name = "too_long_hd_station_name_short",
+                    .metadata = Metadata::make<Metadata::hdStationNameShort>("name_too_long"),
+                    .valid = false},
+            IsValidMetadataV2TestCase{
+                    .name = "valid_hd_subchannel_available",
+                    .metadata = Metadata::make<Metadata::hdSubChannelsAvailable>(1),
+                    .valid = true},
+            IsValidMetadataV2TestCase{
+                    .name = "negative_subchannel_available",
+                    .metadata = Metadata::make<Metadata::hdSubChannelsAvailable>(-1),
+                    .valid = false},
+            IsValidMetadataV2TestCase{
+                    .name = "large_subchannel_available",
+                    .metadata = Metadata::make<Metadata::hdSubChannelsAvailable>(256),
+                    .valid = false},
+    });
+}
+}  // namespace
+
+class IsValidMetadataV2Test : public testing::TestWithParam<IsValidMetadataV2TestCase> {};
+
+INSTANTIATE_TEST_SUITE_P(IsValidMetadataV2Tests, IsValidMetadataV2Test,
+                         testing::ValuesIn(getIsValidMetadataV2TestCases()),
+                         [](const testing::TestParamInfo<IsValidMetadataV2Test::ParamType>& info) {
+                             return info.param.name;
+                         });
+
+TEST_P(IsValidMetadataV2Test, IsValidMetadataV2) {
+    IsValidMetadataV2TestCase testParam = GetParam();
+
+    ASSERT_EQ(utils::isValidMetadataV2(testParam.metadata), testParam.valid);
+}
+
+}  // namespace aidl::android::hardware::broadcastradio
diff --git a/camera/device/aidl/Android.bp b/camera/device/aidl/Android.bp
index 4115c65..0104636 100644
--- a/camera/device/aidl/Android.bp
+++ b/camera/device/aidl/Android.bp
@@ -17,7 +17,7 @@
         "android.hardware.common-V2",
         "android.hardware.common.fmq-V1",
         "android.hardware.camera.common-V1",
-        "android.hardware.camera.metadata-V2",
+        "android.hardware.camera.metadata-V3",
         "android.hardware.graphics.common-V5",
     ],
     backend: {
diff --git a/camera/device/aidl/android/hardware/camera/device/ICameraDevice.aidl b/camera/device/aidl/android/hardware/camera/device/ICameraDevice.aidl
index 01009ad..da3d5df 100644
--- a/camera/device/aidl/android/hardware/camera/device/ICameraDevice.aidl
+++ b/camera/device/aidl/android/hardware/camera/device/ICameraDevice.aidl
@@ -365,16 +365,20 @@
      * isStreamCombinationWithSettingsSupported:
      *
      * This is the same as isStreamCombinationSupported with below exceptions:
-     *
      * 1. The input StreamConfiguration parameter may contain session parameters
-     * supported by this camera device. When checking if the particular StreamConfiguration
-     * is supported, the camera HAL must take the session parameters into consideration.
+     * as well as additional CaptureRequest keys. See the comment
+     * sections below on what additional capture request keys are passed in
+     * StreamConfiguration::sessionParameters for each interface version. When checking if
+     * the particular StreamConfiguration is supported, the camera HAL must take all
+     * the keys in sessionParameters into consideration.
      *
      * 2. For version 3 of this interface, the camera compliance test will verify that
      * isStreamCombinationWithSettingsSupported behaves properly for all combinations of
      * below features. This function must return true for all supported combinations,
      * and return false for non-supported feature combinations. The list of features
-     * required may grow in future versions.
+     * required may grow in future versions. The additional metadata entries in
+     * StreamConfiguration::sessionParameters are {CONTROL_AE_TARGET_FPS_RANGE,
+     * CONTROL_VIDEO_STABILIZATION_MODE}.
      *
      * - Stream Combinations (a subset of LEGACY device mandatory stream combinations):
      *   {
@@ -429,7 +433,7 @@
      * 4032 x 3024, the camera compliance test will verify both
      * {PRIV, 1920 x 1440, JPEG, 4032 x 3024} and {PRIV, 2560 x 1440, JPEG, 4032 x 2268}.
      *
-     * @param streams The StreamConfiguration to be tested, with optional session parameters.
+     * @param streams The StreamConfiguration to be tested, with optional CaptureRequest parameters.
      *
      * @return true in case the stream combination is supported, false otherwise.
      *
diff --git a/camera/device/aidl/android/hardware/camera/device/StreamConfiguration.aidl b/camera/device/aidl/android/hardware/camera/device/StreamConfiguration.aidl
index 197d9af..0f5bad9 100644
--- a/camera/device/aidl/android/hardware/camera/device/StreamConfiguration.aidl
+++ b/camera/device/aidl/android/hardware/camera/device/StreamConfiguration.aidl
@@ -59,6 +59,14 @@
      * pipeline updates. The field is optional, clients can choose to ignore it and avoid
      * including any initial settings. If parameters are present, then hal must examine
      * their values and configure the internal camera pipeline accordingly.
+     *
+     * A null pointer is equivalent to a valid CameraMetadata object with zero entries.
+     *
+     * For a StreamConfiguration passed to ICameraDevice.isStreamCombinationWithSettingsSupported
+     * or ICameraDevice.getSessionCharacteristics, this variable may also contain keys
+     * that are not session parameters, but are used to specify certain features for a
+     * session. For example, CONTROL_VIDEO_STABILIZATION_MODE may be included even if it's not a
+     * session parameter.
      */
     CameraMetadata sessionParams;
 
diff --git a/camera/device/default/ExternalCameraDevice.cpp b/camera/device/default/ExternalCameraDevice.cpp
index 649bf43..8e84748 100644
--- a/camera/device/default/ExternalCameraDevice.cpp
+++ b/camera/device/default/ExternalCameraDevice.cpp
@@ -497,6 +497,9 @@
     const int32_t maxLatency = ANDROID_SYNC_MAX_LATENCY_UNKNOWN;
     UPDATE(ANDROID_SYNC_MAX_LATENCY, &maxLatency, 1);
 
+    const uint8_t sensorReadoutTimestamp = ANDROID_SENSOR_READOUT_TIMESTAMP_NOT_SUPPORTED;
+    UPDATE(ANDROID_SENSOR_READOUT_TIMESTAMP, &sensorReadoutTimestamp, 1);
+
     /* Other sensor/RAW related keys:
      * android.sensor.info.colorFilterArrangement -> no need if we don't do RAW
      * android.sensor.info.physicalSize           -> not available
@@ -1002,4 +1005,4 @@
 }  // namespace device
 }  // namespace camera
 }  // namespace hardware
-}  // namespace android
\ No newline at end of file
+}  // namespace android
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataTag.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataTag.aidl
index 542b296..9321ec0 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataTag.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataTag.aidl
@@ -246,6 +246,7 @@
   ANDROID_SENSOR_OPAQUE_RAW_SIZE_MAXIMUM_RESOLUTION,
   ANDROID_SENSOR_PIXEL_MODE,
   ANDROID_SENSOR_RAW_BINNING_FACTOR_USED,
+  ANDROID_SENSOR_READOUT_TIMESTAMP,
   ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_SENSOR_INFO_START /* 983040 */,
   ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
   ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorReadoutTimestamp.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorReadoutTimestamp.aidl
new file mode 100644
index 0000000..35dc1a9
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorReadoutTimestamp.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2024 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.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.camera.metadata;
+@Backing(type="int") @VintfStability
+enum SensorReadoutTimestamp {
+  ANDROID_SENSOR_READOUT_TIMESTAMP_NOT_SUPPORTED,
+  ANDROID_SENSOR_READOUT_TIMESTAMP_HARDWARE,
+}
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataTag.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataTag.aidl
index 03cfba1..f133372 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataTag.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataTag.aidl
@@ -1591,6 +1591,13 @@
      */
     ANDROID_SENSOR_RAW_BINNING_FACTOR_USED,
     /**
+     * android.sensor.readoutTimestamp [static, enum, java_public]
+     *
+     * <p>Whether or not the camera device supports readout timestamp and
+     * {@code onReadoutStarted} callback.</p>
+     */
+    ANDROID_SENSOR_READOUT_TIMESTAMP,
+    /**
      * android.sensor.info.activeArraySize [static, int32[], public]
      *
      * <p>The area of the image sensor which corresponds to active pixels after any geometric
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/SensorReadoutTimestamp.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/SensorReadoutTimestamp.aidl
new file mode 100644
index 0000000..1678515
--- /dev/null
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/SensorReadoutTimestamp.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2024 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.
+ */
+
+/*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+
+package android.hardware.camera.metadata;
+
+/**
+ * android.sensor.readoutTimestamp enumeration values
+ * @see ANDROID_SENSOR_READOUT_TIMESTAMP
+ */
+@VintfStability
+@Backing(type="int")
+enum SensorReadoutTimestamp {
+    ANDROID_SENSOR_READOUT_TIMESTAMP_NOT_SUPPORTED,
+    ANDROID_SENSOR_READOUT_TIMESTAMP_HARDWARE,
+}
diff --git a/camera/provider/aidl/vts/Android.bp b/camera/provider/aidl/vts/Android.bp
index f9305bb..1c106f6 100644
--- a/camera/provider/aidl/vts/Android.bp
+++ b/camera/provider/aidl/vts/Android.bp
@@ -61,7 +61,7 @@
         "android.hardware.camera.common@1.0-helper",
         "android.hardware.camera.common-V1-ndk",
         "android.hardware.camera.device-V3-ndk",
-        "android.hardware.camera.metadata-V2-ndk",
+        "android.hardware.camera.metadata-V3-ndk",
         "android.hardware.camera.provider-V3-ndk",
         "android.hidl.allocator@1.0",
         "libgrallocusage",
diff --git a/camera/provider/aidl/vts/camera_aidl_test.cpp b/camera/provider/aidl/vts/camera_aidl_test.cpp
index d2a409e..4fc01bf 100644
--- a/camera/provider/aidl/vts/camera_aidl_test.cpp
+++ b/camera/provider/aidl/vts/camera_aidl_test.cpp
@@ -319,14 +319,7 @@
     // Check capabilities
     int retcode =
             find_camera_metadata_ro_entry(metadata, ANDROID_REQUEST_AVAILABLE_CAPABILITIES, &entry);
-    bool hasStreamUseCaseCap = false;
-    if ((0 == retcode) && (entry.count > 0)) {
-        if (std::find(entry.data.u8, entry.data.u8 + entry.count,
-                      ANDROID_REQUEST_AVAILABLE_CAPABILITIES_STREAM_USE_CASE) !=
-            entry.data.u8 + entry.count) {
-            hasStreamUseCaseCap = true;
-        }
-    }
+    bool hasStreamUseCaseCap = supportsStreamUseCaseCap(metadata);
 
     bool supportMandatoryUseCases = false;
     retcode = find_camera_metadata_ro_entry(metadata, ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES,
@@ -1919,13 +1912,8 @@
             if (supportFeatureCombinationQuery) {
                 ret = device->isStreamCombinationWithSettingsSupported(config,
                                                                        &streamCombinationSupported);
-                // TODO: Do not allow OPERATION_NOT_SUPPORTED once HAL
-                // implementation is in place.
-                ASSERT_TRUE(ret.isOk() || static_cast<Status>(ret.getServiceSpecificError()) ==
-                                                  Status::OPERATION_NOT_SUPPORTED);
-                if (ret.isOk()) {
-                    ASSERT_EQ(expectedStatus, streamCombinationSupported);
-                }
+                ASSERT_TRUE(ret.isOk());
+                ASSERT_EQ(expectedStatus, streamCombinationSupported);
             }
         }
     }
@@ -2436,10 +2424,10 @@
                                &cameraDevice /*out*/);
 
         camera_metadata_t* staticMeta = reinterpret_cast<camera_metadata_t*>(meta.metadata.data());
-        // Check if camera support depth only
-        if (isDepthOnly(staticMeta) ||
-                (threshold.format == static_cast<int32_t>(PixelFormat::RAW16) &&
-                        !supportsCroppedRawUseCase(staticMeta))) {
+        // Check if camera support depth only or doesn't support stream use case capability
+        if (isDepthOnly(staticMeta) || !supportsStreamUseCaseCap(staticMeta) ||
+            (threshold.format == static_cast<int32_t>(PixelFormat::RAW16) &&
+             !supportsCroppedRawUseCase(staticMeta))) {
             ndk::ScopedAStatus ret = mSession->close();
             mSession = nullptr;
             ASSERT_TRUE(ret.isOk());
@@ -3508,6 +3496,21 @@
     return false;
 }
 
+bool CameraAidlTest::supportsStreamUseCaseCap(const camera_metadata_t* staticMeta) {
+    camera_metadata_ro_entry entry;
+    int retcode = find_camera_metadata_ro_entry(staticMeta, ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
+                                                &entry);
+    bool hasStreamUseCaseCap = false;
+    if ((0 == retcode) && (entry.count > 0)) {
+        if (std::find(entry.data.u8, entry.data.u8 + entry.count,
+                      ANDROID_REQUEST_AVAILABLE_CAPABILITIES_STREAM_USE_CASE) !=
+            entry.data.u8 + entry.count) {
+            hasStreamUseCaseCap = true;
+        }
+    }
+    return hasStreamUseCaseCap;
+}
+
 bool CameraAidlTest::isPerFrameControl(const camera_metadata_t* staticMeta) {
     camera_metadata_ro_entry syncLatencyEntry;
     int rc = find_camera_metadata_ro_entry(staticMeta, ANDROID_SYNC_MAX_LATENCY,
diff --git a/camera/provider/aidl/vts/camera_aidl_test.h b/camera/provider/aidl/vts/camera_aidl_test.h
index 507a637..7bcf430 100644
--- a/camera/provider/aidl/vts/camera_aidl_test.h
+++ b/camera/provider/aidl/vts/camera_aidl_test.h
@@ -439,7 +439,8 @@
             int32_t frameCount, const bool *overrideSequence, const bool *expectedResults);
 
     bool supportZoomSettingsOverride(const camera_metadata_t* staticMeta);
-    bool supportsCroppedRawUseCase(const camera_metadata_t *staticMeta);
+    static bool supportsStreamUseCaseCap(const camera_metadata_t* staticMeta);
+    static bool supportsCroppedRawUseCase(const camera_metadata_t* staticMeta);
     bool isPerFrameControl(const camera_metadata_t* staticMeta);
 
     void getSupportedSizes(const camera_metadata_t* ch, uint32_t tag, int32_t format,
diff --git a/compatibility_matrices/Android.bp b/compatibility_matrices/Android.bp
index 9bee3b9..eefca39 100644
--- a/compatibility_matrices/Android.bp
+++ b/compatibility_matrices/Android.bp
@@ -84,10 +84,10 @@
 }
 
 vintf_compatibility_matrix {
-    name: "framework_compatibility_matrix.9.xml",
-    stem: "compatibility_matrix.9.xml",
+    name: "framework_compatibility_matrix.202404.xml",
+    stem: "compatibility_matrix.202404.xml",
     srcs: [
-        "compatibility_matrix.9.xml",
+        "compatibility_matrix.202404.xml",
     ],
     kernel_configs: [
         "kernel_config_v_6.1",
diff --git a/compatibility_matrices/Android.mk b/compatibility_matrices/Android.mk
index c2ffb84..72ead58 100644
--- a/compatibility_matrices/Android.mk
+++ b/compatibility_matrices/Android.mk
@@ -112,7 +112,7 @@
 # interfaces (in the `next` release configuration).
 ifeq ($(RELEASE_AIDL_USE_UNFROZEN),true)
 my_system_matrix_deps += \
-    framework_compatibility_matrix.9.xml
+    framework_compatibility_matrix.202404.xml
 endif
 
 my_framework_matrix_deps += \
diff --git a/compatibility_matrices/compatibility_matrix.9.xml b/compatibility_matrices/compatibility_matrix.202404.xml
similarity index 83%
rename from compatibility_matrices/compatibility_matrix.9.xml
rename to compatibility_matrices/compatibility_matrix.202404.xml
index 90dd414..2080c69 100644
--- a/compatibility_matrices/compatibility_matrix.9.xml
+++ b/compatibility_matrices/compatibility_matrix.202404.xml
@@ -1,5 +1,5 @@
-<compatibility-matrix version="1.0" type="framework" level="9">
-    <hal format="aidl" optional="true">
+<compatibility-matrix version="1.0" type="framework" level="202404">
+    <hal format="aidl">
         <name>android.hardware.audio.core</name>
         <version>1-2</version>
         <interface>
@@ -18,7 +18,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.audio.effect</name>
         <version>1-2</version>
         <interface>
@@ -26,7 +26,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.audio.sounddose</name>
         <version>1-2</version>
         <interface>
@@ -34,7 +34,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true" updatable-via-apex="true">
+    <hal format="aidl" updatable-via-apex="true">
          <name>android.hardware.authsecret</name>
          <version>1</version>
          <interface>
@@ -42,7 +42,7 @@
              <instance>default</instance>
          </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.automotive.audiocontrol</name>
         <version>2-4</version>
         <interface>
@@ -50,7 +50,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.automotive.can</name>
         <version>1</version>
         <interface>
@@ -58,7 +58,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.automotive.evs</name>
         <version>1-2</version>
         <interface>
@@ -66,7 +66,7 @@
             <regex-instance>[a-z]+/[0-9]+</regex-instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.macsec</name>
         <version>1</version>
         <interface>
@@ -74,7 +74,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.automotive.occupant_awareness</name>
         <version>1</version>
         <interface>
@@ -82,7 +82,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.automotive.vehicle</name>
         <version>1-3</version>
         <interface>
@@ -90,7 +90,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.automotive.remoteaccess</name>
         <version>1-2</version>
         <interface>
@@ -98,14 +98,14 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.automotive.ivn</name>
         <interface>
             <name>IIvnAndroidDevice</name>
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true" updatable-via-apex="true">
+    <hal format="aidl" updatable-via-apex="true">
         <name>android.hardware.biometrics.face</name>
         <version>3-4</version>
         <interface>
@@ -114,7 +114,7 @@
             <instance>virtual</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true" updatable-via-apex="true">
+    <hal format="aidl" updatable-via-apex="true">
         <name>android.hardware.biometrics.fingerprint</name>
         <version>3-4</version>
         <interface>
@@ -123,14 +123,14 @@
             <instance>virtual</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.bluetooth</name>
         <interface>
             <name>IBluetoothHci</name>
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.bluetooth.audio</name>
         <version>3-4</version>
         <interface>
@@ -138,7 +138,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.bluetooth.ranging</name>
         <version>1</version>
         <interface>
@@ -146,7 +146,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.bluetooth.finder</name>
         <version>1</version>
         <interface>
@@ -154,7 +154,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.bluetooth.lmp_event</name>
         <version>1</version>
         <interface>
@@ -162,14 +162,14 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.boot</name>
         <interface>
             <name>IBootControl</name>
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.broadcastradio</name>
         <version>1-2</version>
         <interface>
@@ -177,7 +177,7 @@
             <regex-instance>.*</regex-instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true" updatable-via-apex="true">
+    <hal format="aidl" updatable-via-apex="true">
         <name>android.hardware.camera.provider</name>
         <version>1-3</version>
         <interface>
@@ -185,14 +185,14 @@
             <regex-instance>[^/]+/[0-9]+</regex-instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.cas</name>
         <interface>
             <name>IMediaCasService</name>
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.confirmationui</name>
         <version>1</version>
         <interface>
@@ -200,7 +200,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.contexthub</name>
         <version>3</version>
         <interface>
@@ -208,7 +208,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true" updatable-via-apex="true">
+    <hal format="aidl" updatable-via-apex="true">
         <name>android.hardware.drm</name>
         <version>1</version>
         <interface>
@@ -216,14 +216,14 @@
             <regex-instance>.*</regex-instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.dumpstate</name>
         <interface>
             <name>IDumpstateDevice</name>
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.gatekeeper</name>
         <version>1</version>
         <interface>
@@ -231,7 +231,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.gnss</name>
         <version>2-4</version>
         <interface>
@@ -239,7 +239,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.graphics.allocator</name>
         <version>1-2</version>
         <interface>
@@ -247,7 +247,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.graphics.composer3</name>
         <version>3</version>
         <interface>
@@ -255,7 +255,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.health</name>
         <version>3</version>
         <interface>
@@ -263,7 +263,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.health.storage</name>
         <version>1</version>
         <interface>
@@ -271,7 +271,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.identity</name>
         <version>1-5</version>
         <interface>
@@ -279,14 +279,14 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.net.nlinterceptor</name>
         <interface>
             <name>IInterceptor</name>
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.oemlock</name>
         <version>1</version>
         <interface>
@@ -294,7 +294,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.ir</name>
         <version>1</version>
         <interface>
@@ -302,7 +302,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.input.processor</name>
         <version>1</version>
         <interface>
@@ -310,7 +310,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.security.secretkeeper</name>
         <version>1</version>
         <interface>
@@ -319,7 +319,7 @@
             <instance>nonsecure</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true" updatable-via-apex="true">
+    <hal format="aidl" updatable-via-apex="true">
         <name>android.hardware.security.keymint</name>
         <version>1-3</version>
         <interface>
@@ -328,7 +328,7 @@
             <instance>strongbox</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true" updatable-via-apex="true">
+    <hal format="aidl" updatable-via-apex="true">
         <name>android.hardware.security.keymint</name>
         <version>1-3</version>
         <interface>
@@ -337,7 +337,7 @@
             <instance>strongbox</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.light</name>
         <version>2</version>
         <interface>
@@ -345,7 +345,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.media.c2</name>
         <version>1.0-2</version>
         <interface>
@@ -355,7 +355,7 @@
             <regex-instance>vendor[0-9]*_software</regex-instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.media.c2</name>
         <version>1.0</version>
         <interface>
@@ -364,7 +364,7 @@
             <instance>software</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.media.c2</name>
         <version>1</version>
         <interface>
@@ -373,7 +373,7 @@
             <regex-instance>vendor[0-9]*_software</regex-instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.memtrack</name>
         <version>1</version>
         <interface>
@@ -381,7 +381,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true" updatable-via-apex="true">
+    <hal format="aidl" updatable-via-apex="true">
         <name>android.hardware.neuralnetworks</name>
         <version>1-4</version>
         <interface>
@@ -389,14 +389,14 @@
             <regex-instance>.*</regex-instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true" updatable-via-apex="true">
+    <hal format="aidl" updatable-via-apex="true">
         <name>android.hardware.nfc</name>
         <interface>
             <name>INfc</name>
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.power</name>
         <version>5</version>
         <interface>
@@ -404,7 +404,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.power.stats</name>
         <version>2</version>
         <interface>
@@ -412,7 +412,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.radio.config</name>
         <version>3</version>
         <interface>
@@ -420,7 +420,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.radio.data</name>
         <version>3</version>
         <interface>
@@ -430,7 +430,7 @@
             <instance>slot3</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.radio.messaging</name>
         <version>3</version>
         <interface>
@@ -440,7 +440,7 @@
             <instance>slot3</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.radio.modem</name>
         <version>3</version>
         <interface>
@@ -450,7 +450,7 @@
             <instance>slot3</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.radio.network</name>
         <version>3</version>
         <interface>
@@ -460,7 +460,7 @@
             <instance>slot3</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.radio.sim</name>
         <version>3</version>
         <interface>
@@ -470,7 +470,7 @@
             <instance>slot3</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.radio.sap</name>
         <version>1</version>
         <interface>
@@ -480,7 +480,7 @@
             <instance>slot3</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.radio.voice</name>
         <version>3</version>
         <interface>
@@ -490,7 +490,7 @@
             <instance>slot3</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.radio.ims</name>
         <version>2</version>
         <interface>
@@ -500,7 +500,7 @@
             <instance>slot3</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.radio.ims.media</name>
         <version>2</version>
         <interface>
@@ -508,7 +508,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.rebootescrow</name>
         <version>1</version>
         <interface>
@@ -516,7 +516,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.secure_element</name>
         <version>1</version>
         <interface>
@@ -525,7 +525,7 @@
             <regex-instance>SIM[1-9][0-9]*</regex-instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true" updatable-via-apex="true">
+    <hal format="aidl" updatable-via-apex="true">
         <name>android.hardware.security.authgraph</name>
         <version>1</version>
         <interface>
@@ -533,7 +533,7 @@
             <instance>nonsecure</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true" updatable-via-apex="true">
+    <hal format="aidl" updatable-via-apex="true">
         <name>android.hardware.security.secureclock</name>
         <version>1</version>
         <interface>
@@ -541,7 +541,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true" updatable-via-apex="true">
+    <hal format="aidl" updatable-via-apex="true">
         <name>android.hardware.security.sharedsecret</name>
         <version>1</version>
         <interface>
@@ -550,7 +550,7 @@
             <instance>strongbox</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.sensors</name>
         <version>2</version>
         <interface>
@@ -558,7 +558,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
          <name>android.hardware.soundtrigger3</name>
          <version>1-2</version>
          <interface>
@@ -566,7 +566,7 @@
              <instance>default</instance>
          </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.tetheroffload</name>
         <version>1</version>
         <interface>
@@ -574,7 +574,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.thermal</name>
         <version>2</version>
         <interface>
@@ -582,7 +582,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true" updatable-via-apex="true">
+    <hal format="aidl" updatable-via-apex="true">
         <name>android.hardware.threadnetwork</name>
         <version>1</version>
         <interface>
@@ -590,7 +590,7 @@
             <regex-instance>chip[0-9]+</regex-instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.tv.hdmi.cec</name>
         <version>1</version>
         <interface>
@@ -598,7 +598,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.tv.hdmi.earc</name>
         <version>1</version>
         <interface>
@@ -606,7 +606,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.tv.hdmi.connection</name>
         <version>1</version>
         <interface>
@@ -614,7 +614,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.tv.tuner</name>
         <version>1-2</version>
         <interface>
@@ -622,7 +622,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.tv.input</name>
         <version>1-2</version>
         <interface>
@@ -630,7 +630,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.usb</name>
         <version>1-3</version>
         <interface>
@@ -638,14 +638,14 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.usb.gadget</name>
         <interface>
             <name>IUsbGadget</name>
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.vibrator</name>
         <version>1-2</version>
         <interface>
@@ -653,7 +653,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.vibrator</name>
         <version>1-2</version>
         <interface>
@@ -661,7 +661,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.weaver</name>
         <version>2</version>
         <interface>
@@ -669,7 +669,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true" updatable-via-apex="true">
+    <hal format="aidl" updatable-via-apex="true">
         <name>android.hardware.wifi</name>
         <version>1-2</version>
         <interface>
@@ -677,7 +677,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true" updatable-via-apex="true">
+    <hal format="aidl" updatable-via-apex="true">
         <name>android.hardware.uwb</name>
         <version>1</version>
         <interface>
@@ -685,7 +685,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.wifi.hostapd</name>
         <version>1-2</version>
         <interface>
@@ -693,7 +693,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.wifi.supplicant</name>
         <version>2-3</version>
         <interface>
@@ -702,7 +702,7 @@
         </interface>
     </hal>
     <!-- The native mapper HAL must exist on the device -->
-    <hal format="native" optional="true">
+    <hal format="native">
         <name>mapper</name>
         <version>5.0</version>
         <interface>
diff --git a/compatibility_matrices/compatibility_matrix.4.xml b/compatibility_matrices/compatibility_matrix.4.xml
index bb7637a..952f53d 100644
--- a/compatibility_matrices/compatibility_matrix.4.xml
+++ b/compatibility_matrices/compatibility_matrix.4.xml
@@ -1,5 +1,5 @@
 <compatibility-matrix version="1.0" type="framework" level="4">
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.atrace</name>
         <version>1.0</version>
         <interface>
@@ -7,7 +7,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.audio</name>
         <version>5.0</version>
         <interface>
@@ -15,7 +15,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.audio.effect</name>
         <version>5.0</version>
         <interface>
@@ -23,7 +23,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.authsecret</name>
         <version>1.0</version>
         <interface>
@@ -31,7 +31,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.automotive.audiocontrol</name>
         <version>1.0</version>
         <interface>
@@ -39,7 +39,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.automotive.evs</name>
         <version>1.0</version>
         <interface>
@@ -47,7 +47,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.automotive.vehicle</name>
         <version>2.0</version>
         <interface>
@@ -55,7 +55,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.biometrics.face</name>
         <version>1.0</version>
         <interface>
@@ -63,7 +63,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.biometrics.fingerprint</name>
         <version>2.1</version>
         <interface>
@@ -71,7 +71,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.bluetooth</name>
         <version>1.0</version>
         <interface>
@@ -79,7 +79,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.bluetooth.audio</name>
         <version>2.0</version>
         <interface>
@@ -87,7 +87,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.boot</name>
         <version>1.0</version>
         <interface>
@@ -95,7 +95,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.broadcastradio</name>
         <version>1.0-1</version>
         <interface>
@@ -103,7 +103,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.broadcastradio</name>
         <version>2.0</version>
         <interface>
@@ -111,7 +111,7 @@
             <regex-instance>.*</regex-instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.camera.provider</name>
         <version>2.4-5</version>
         <interface>
@@ -119,7 +119,7 @@
             <regex-instance>[^/]+/[0-9]+</regex-instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.cas</name>
         <version>1.1</version>
         <interface>
@@ -127,7 +127,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.configstore</name>
         <version>1.1</version>
         <interface>
@@ -135,7 +135,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.confirmationui</name>
         <version>1.0</version>
         <interface>
@@ -143,7 +143,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.contexthub</name>
         <version>1.0</version>
         <interface>
@@ -151,7 +151,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.drm</name>
         <version>1.0-2</version>
         <interface>
@@ -163,7 +163,7 @@
             <regex-instance>.*</regex-instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.dumpstate</name>
         <version>1.0</version>
         <interface>
@@ -171,7 +171,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.gatekeeper</name>
         <version>1.0</version>
         <interface>
@@ -179,7 +179,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.gnss</name>
         <version>2.0</version>
         <interface>
@@ -190,7 +190,7 @@
     <!-- Either the AIDL or the HIDL allocator HAL must exist on the device.
          If the HIDL composer HAL exists, it must be at least version 2.0.
          See DeviceManifestTest.GrallocHal -->
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.graphics.allocator</name>
         <version>2.0</version>
         <version>3.0</version>
@@ -199,7 +199,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.graphics.composer</name>
         <version>2.1-3</version>
         <interface>
@@ -207,7 +207,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.graphics.mapper</name>
         <version>2.1</version>
         <version>3.0</version>
@@ -219,7 +219,7 @@
     <!-- Either the AIDL or the HIDL health HAL must exist on the device.
          If the HIDL health HAL exists, it must be at least version 2.0.
          See DeviceManifestTest.HealthHal -->
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.health</name>
         <version>2.0</version>
         <interface>
@@ -227,7 +227,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.health.storage</name>
         <version>1.0</version>
         <interface>
@@ -235,7 +235,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.ir</name>
         <version>1.0</version>
         <interface>
@@ -243,7 +243,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.input.classifier</name>
         <version>1.0</version>
         <interface>
@@ -251,7 +251,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.keymaster</name>
         <version>3.0</version>
         <version>4.0</version>
@@ -260,7 +260,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.keymaster</name>
         <version>4.0</version>
         <interface>
@@ -268,7 +268,7 @@
             <instance>strongbox</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.light</name>
         <version>2.0</version>
         <interface>
@@ -276,7 +276,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.media.c2</name>
         <version>1.0</version>
         <interface>
@@ -291,7 +291,7 @@
             <instance>software</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.media.omx</name>
         <version>1.0</version>
         <interface>
@@ -303,7 +303,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.memtrack</name>
         <version>1.0</version>
         <interface>
@@ -311,7 +311,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.neuralnetworks</name>
         <version>1.0-2</version>
         <interface>
@@ -319,7 +319,7 @@
             <regex-instance>.*</regex-instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.nfc</name>
         <version>1.2</version>
         <interface>
@@ -327,7 +327,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.oemlock</name>
         <version>1.0</version>
         <interface>
@@ -335,7 +335,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.power</name>
         <version>1.0-3</version>
         <interface>
@@ -343,7 +343,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.power.stats</name>
         <version>1.0</version>
         <interface>
@@ -351,7 +351,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.radio</name>
         <version>1.4</version>
         <interface>
@@ -361,7 +361,7 @@
             <instance>slot3</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.radio</name>
         <version>1.2</version>
         <interface>
@@ -370,7 +370,7 @@
             <instance>slot2</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.radio.config</name>
         <!--
         Note: Devices launching with target-level 4, if implementing the
@@ -384,7 +384,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.renderscript</name>
         <version>1.0</version>
         <interface>
@@ -392,7 +392,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.secure_element</name>
         <version>1.0</version>
         <interface>
@@ -401,7 +401,7 @@
             <regex-instance>SIM[1-9][0-9]*</regex-instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.sensors</name>
         <version>1.0</version>
         <version>2.0</version>
@@ -410,7 +410,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.soundtrigger</name>
         <version>2.0-2</version>
         <interface>
@@ -418,7 +418,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.tetheroffload.config</name>
         <version>1.0</version>
         <interface>
@@ -426,7 +426,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.tetheroffload.control</name>
         <version>1.0</version>
         <interface>
@@ -434,7 +434,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.thermal</name>
         <version>2.0</version>
         <interface>
@@ -442,7 +442,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.tv.cec</name>
         <version>1.0</version>
         <interface>
@@ -450,7 +450,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.tv.input</name>
         <version>1.0</version>
         <interface>
@@ -458,7 +458,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.usb</name>
         <version>1.0-2</version>
         <interface>
@@ -466,7 +466,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.usb.gadget</name>
         <version>1.0</version>
         <interface>
@@ -474,7 +474,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.vibrator</name>
         <version>1.0-3</version>
         <interface>
@@ -482,7 +482,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.vr</name>
         <version>1.0</version>
         <interface>
@@ -490,7 +490,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.weaver</name>
         <version>1.0</version>
         <interface>
@@ -498,7 +498,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.wifi</name>
         <version>1.0-3</version>
         <interface>
@@ -506,7 +506,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.wifi.hostapd</name>
         <version>1.0-1</version>
         <interface>
@@ -514,7 +514,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.wifi.supplicant</name>
         <version>1.0-2</version>
         <interface>
diff --git a/compatibility_matrices/compatibility_matrix.5.xml b/compatibility_matrices/compatibility_matrix.5.xml
index dad1558..1cf98b0 100644
--- a/compatibility_matrices/compatibility_matrix.5.xml
+++ b/compatibility_matrices/compatibility_matrix.5.xml
@@ -1,5 +1,5 @@
 <compatibility-matrix version="1.0" type="framework" level="5">
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.atrace</name>
         <version>1.0</version>
         <interface>
@@ -7,7 +7,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.audio</name>
         <version>6.0</version>
         <interface>
@@ -15,7 +15,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.audio.effect</name>
         <version>6.0</version>
         <interface>
@@ -23,7 +23,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.authsecret</name>
         <version>1.0</version>
         <interface>
@@ -31,7 +31,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.automotive.audiocontrol</name>
         <version>1.0</version>
         <version>2.0</version>
@@ -40,7 +40,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.automotive.can</name>
         <version>1.0</version>
         <interface>
@@ -52,7 +52,7 @@
             <regex-instance>.*</regex-instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.automotive.evs</name>
         <version>1.0-1</version>
         <interface>
@@ -61,14 +61,14 @@
             <regex-instance>[a-z]+/[0-9]+</regex-instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.automotive.occupant_awareness</name>
         <interface>
             <name>IOccupantAwareness</name>
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.automotive.sv</name>
         <version>1.0</version>
         <interface>
@@ -76,7 +76,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.automotive.vehicle</name>
         <version>2.0</version>
         <interface>
@@ -84,7 +84,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.biometrics.face</name>
         <version>1.0</version>
         <interface>
@@ -92,7 +92,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.biometrics.fingerprint</name>
         <version>2.1-2</version>
         <interface>
@@ -100,7 +100,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.bluetooth</name>
         <version>1.0-1</version>
         <interface>
@@ -108,7 +108,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.bluetooth.audio</name>
         <version>2.0</version>
         <interface>
@@ -116,7 +116,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.boot</name>
         <version>1.1</version>
         <interface>
@@ -124,7 +124,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.broadcastradio</name>
         <version>1.0-1</version>
         <interface>
@@ -132,7 +132,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.broadcastradio</name>
         <version>2.0</version>
         <interface>
@@ -140,7 +140,7 @@
             <regex-instance>.*</regex-instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.camera.provider</name>
         <version>2.4-6</version>
         <interface>
@@ -148,7 +148,7 @@
             <regex-instance>[^/]+/[0-9]+</regex-instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.cas</name>
         <version>1.1-2</version>
         <interface>
@@ -156,7 +156,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.confirmationui</name>
         <version>1.0</version>
         <interface>
@@ -164,7 +164,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.contexthub</name>
         <version>1.0-1</version>
         <interface>
@@ -172,7 +172,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.drm</name>
         <version>1.3</version>
         <interface>
@@ -184,7 +184,7 @@
             <regex-instance>.*</regex-instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.dumpstate</name>
         <version>1.1</version>
         <interface>
@@ -192,7 +192,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.gatekeeper</name>
         <version>1.0</version>
         <interface>
@@ -200,7 +200,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.gnss</name>
         <version>2.0-1</version>
         <interface>
@@ -211,7 +211,7 @@
     <!-- Either the AIDL or the HIDL allocator HAL must exist on the device.
          If the HIDL composer HAL exists, it must be at least version 2.0.
          See DeviceManifestTest.GrallocHal -->
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.graphics.allocator</name>
         <!-- New, non-Go devices should use 4.0, tested in vts_treble_vintf_vendor_test -->
         <version>2.0</version>
@@ -222,7 +222,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.graphics.composer</name>
         <version>2.1-4</version>
         <interface>
@@ -230,7 +230,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.graphics.mapper</name>
         <!-- New, non-Go devices should use 4.0, tested in vts_treble_vintf_vendor_test -->
         <version>2.1</version>
@@ -244,7 +244,7 @@
     <!-- Either the AIDL or the HIDL health HAL must exist on the device.
          If the HIDL health HAL exists, it must be at least version 2.1.
          See DeviceManifestTest.HealthHal -->
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.health</name>
         <version>2.1</version>
         <interface>
@@ -252,7 +252,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.health.storage</name>
         <version>1.0</version>
         <interface>
@@ -260,7 +260,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.identity</name>
         <!--
           b/178458001: identity V2 is introduced in R, but Android R VINTF does not support AIDL
@@ -274,7 +274,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.ir</name>
         <version>1.0</version>
         <interface>
@@ -282,7 +282,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.input.classifier</name>
         <version>1.0</version>
         <interface>
@@ -290,7 +290,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.keymaster</name>
         <version>3.0</version>
         <version>4.0-1</version>
@@ -299,7 +299,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.keymaster</name>
         <version>4.0-1</version>
         <interface>
@@ -307,14 +307,14 @@
             <instance>strongbox</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.light</name>
         <interface>
             <name>ILights</name>
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.media.c2</name>
         <version>1.0-1</version>
         <interface>
@@ -324,7 +324,7 @@
             <regex-instance>vendor[0-9]*_software</regex-instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.media.c2</name>
         <version>1.0</version>
         <interface>
@@ -333,7 +333,7 @@
             <instance>software</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.media.omx</name>
         <version>1.0</version>
         <interface>
@@ -345,7 +345,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.memtrack</name>
         <version>1.0</version>
         <interface>
@@ -353,7 +353,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.neuralnetworks</name>
         <version>1.0-3</version>
         <interface>
@@ -361,7 +361,7 @@
             <regex-instance>.*</regex-instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.nfc</name>
         <version>1.2</version>
         <interface>
@@ -369,7 +369,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.oemlock</name>
         <version>1.0</version>
         <interface>
@@ -377,14 +377,14 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.power</name>
         <interface>
             <name>IPower</name>
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.power.stats</name>
         <version>1.0</version>
         <interface>
@@ -392,7 +392,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.radio</name>
         <version>1.4</version>
         <version>1.5</version>
@@ -403,7 +403,7 @@
             <instance>slot3</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.radio</name>
         <version>1.2</version>
         <interface>
@@ -412,7 +412,7 @@
             <instance>slot2</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.radio.config</name>
         <!--
         See compatibility_matrix.4.xml on versioning of radio config HAL.
@@ -423,7 +423,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.renderscript</name>
         <version>1.0</version>
         <interface>
@@ -431,14 +431,14 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.rebootescrow</name>
         <interface>
             <name>IRebootEscrow</name>
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.secure_element</name>
         <version>1.0-2</version>
         <interface>
@@ -447,7 +447,7 @@
             <regex-instance>SIM[1-9][0-9]*</regex-instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.sensors</name>
         <version>1.0</version>
         <version>2.0-1</version>
@@ -456,7 +456,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.soundtrigger</name>
         <version>2.0-3</version>
         <interface>
@@ -464,7 +464,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.tetheroffload.config</name>
         <version>1.0</version>
         <interface>
@@ -472,7 +472,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.tetheroffload.control</name>
         <version>1.0</version>
         <interface>
@@ -480,7 +480,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.thermal</name>
         <version>2.0</version>
         <interface>
@@ -488,7 +488,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.tv.cec</name>
         <version>1.0</version>
         <interface>
@@ -496,7 +496,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.tv.input</name>
         <version>1.0</version>
         <interface>
@@ -504,7 +504,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.tv.tuner</name>
         <version>1.0</version>
         <interface>
@@ -512,7 +512,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.usb</name>
         <version>1.0-2</version>
         <interface>
@@ -520,7 +520,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.usb.gadget</name>
         <version>1.0-1</version>
         <interface>
@@ -528,14 +528,14 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.vibrator</name>
         <interface>
             <name>IVibrator</name>
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.vr</name>
         <version>1.0</version>
         <interface>
@@ -543,7 +543,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.weaver</name>
         <version>1.0</version>
         <interface>
@@ -551,7 +551,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.wifi</name>
         <version>1.0-4</version>
         <interface>
@@ -559,7 +559,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.wifi.hostapd</name>
         <version>1.0-2</version>
         <interface>
@@ -567,7 +567,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.wifi.supplicant</name>
         <version>1.0-3</version>
         <interface>
diff --git a/compatibility_matrices/compatibility_matrix.6.xml b/compatibility_matrices/compatibility_matrix.6.xml
index 23f634d..fdd7952 100644
--- a/compatibility_matrices/compatibility_matrix.6.xml
+++ b/compatibility_matrices/compatibility_matrix.6.xml
@@ -1,5 +1,5 @@
 <compatibility-matrix version="1.0" type="framework" level="6">
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.atrace</name>
         <version>1.0</version>
         <interface>
@@ -7,7 +7,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.audio</name>
         <version>6.0</version>
         <version>7.0</version>
@@ -16,7 +16,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.audio.effect</name>
         <version>6.0</version>
         <version>7.0</version>
@@ -25,7 +25,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
          <name>android.hardware.authsecret</name>
          <version>1</version>
          <interface>
@@ -33,7 +33,7 @@
              <instance>default</instance>
          </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.authsecret</name>
         <version>1.0</version>
         <interface>
@@ -41,14 +41,14 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.automotive.audiocontrol</name>
         <interface>
             <name>IAudioControl</name>
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.automotive.can</name>
         <version>1.0</version>
         <interface>
@@ -60,7 +60,7 @@
             <regex-instance>.*</regex-instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.automotive.evs</name>
         <version>1.0-1</version>
         <interface>
@@ -69,7 +69,7 @@
             <regex-instance>[a-z]+/[0-9]+</regex-instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.automotive.occupant_awareness</name>
         <version>1</version>
         <interface>
@@ -77,7 +77,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.automotive.sv</name>
         <version>1.0</version>
         <interface>
@@ -85,7 +85,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.automotive.vehicle</name>
         <version>2.0</version>
         <interface>
@@ -93,7 +93,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.biometrics.face</name>
         <version>1.0</version>
         <interface>
@@ -101,14 +101,14 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.biometrics.face</name>
         <interface>
             <name>IFace</name>
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.biometrics.fingerprint</name>
         <version>2.1-3</version>
         <interface>
@@ -116,14 +116,14 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.biometrics.fingerprint</name>
         <interface>
             <name>IFingerprint</name>
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.bluetooth</name>
         <version>1.0-1</version>
         <interface>
@@ -131,7 +131,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.bluetooth.audio</name>
         <version>2.0-1</version>
         <interface>
@@ -139,7 +139,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.boot</name>
         <version>1.2</version>
         <interface>
@@ -147,7 +147,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.broadcastradio</name>
         <version>1.0-1</version>
         <interface>
@@ -155,7 +155,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.broadcastradio</name>
         <version>2.0</version>
         <interface>
@@ -163,7 +163,7 @@
             <regex-instance>.*</regex-instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.camera.provider</name>
         <version>2.4-7</version>
         <interface>
@@ -171,7 +171,7 @@
             <regex-instance>[^/]+/[0-9]+</regex-instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.cas</name>
         <version>1.1-2</version>
         <interface>
@@ -179,7 +179,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.confirmationui</name>
         <version>1.0</version>
         <interface>
@@ -187,7 +187,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.contexthub</name>
         <version>1.2</version>
         <interface>
@@ -195,7 +195,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.drm</name>
         <version>1.3-4</version>
         <interface>
@@ -207,7 +207,7 @@
             <regex-instance>.*</regex-instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.dumpstate</name>
         <version>1.1</version>
         <interface>
@@ -215,7 +215,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.gatekeeper</name>
         <version>1.0</version>
         <interface>
@@ -223,7 +223,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.gnss</name>
         <version>2.0-1</version>
         <interface>
@@ -231,7 +231,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.gnss</name>
         <interface>
             <name>IGnss</name>
@@ -241,7 +241,7 @@
     <!-- Either the AIDL or the HIDL allocator HAL must exist on the device.
          If the HIDL composer HAL exists, it must be at least version 2.0.
          See DeviceManifestTest.GrallocHal -->
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.graphics.allocator</name>
         <!-- New, non-Go devices should use 4.0, tested in vts_treble_vintf_vendor_test -->
         <version>2.0</version>
@@ -252,7 +252,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.graphics.composer</name>
         <version>2.1-4</version>
         <interface>
@@ -260,7 +260,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.graphics.mapper</name>
         <!-- New, non-Go devices should use 4.0, tested in vts_treble_vintf_vendor_test -->
         <version>2.1</version>
@@ -274,7 +274,7 @@
     <!-- Either the AIDL or the HIDL health HAL must exist on the device.
          If the HIDL health HAL exists, it must be at least version 2.1.
          See DeviceManifestTest.HealthHal -->
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.health</name>
         <version>2.1</version>
         <interface>
@@ -282,7 +282,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.health.storage</name>
         <version>1</version>
         <interface>
@@ -290,7 +290,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.identity</name>
         <version>1-3</version>
         <interface>
@@ -298,7 +298,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.oemlock</name>
         <version>1</version>
         <interface>
@@ -306,7 +306,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.ir</name>
         <version>1.0</version>
         <interface>
@@ -314,7 +314,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.input.classifier</name>
         <version>1.0</version>
         <interface>
@@ -322,7 +322,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.keymaster</name>
         <version>3.0</version>
         <version>4.0-1</version>
@@ -331,7 +331,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.keymaster</name>
         <version>4.0-1</version>
         <interface>
@@ -339,7 +339,7 @@
             <instance>strongbox</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.security.keymint</name>
         <version>1</version>
         <interface>
@@ -348,14 +348,14 @@
             <instance>strongbox</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.security.keymint</name>
         <interface>
             <name>IRemotelyProvisionedComponent</name>
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.light</name>
         <version>1</version>
         <interface>
@@ -363,7 +363,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.media.c2</name>
         <version>1.0-2</version>
         <interface>
@@ -373,7 +373,7 @@
             <regex-instance>vendor[0-9]*_software</regex-instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.media.c2</name>
         <version>1.0</version>
         <interface>
@@ -382,7 +382,7 @@
             <instance>software</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.media.omx</name>
         <version>1.0</version>
         <interface>
@@ -394,7 +394,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.memtrack</name>
         <version>1</version>
         <interface>
@@ -402,7 +402,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.neuralnetworks</name>
         <version>1.0-3</version>
         <interface>
@@ -410,14 +410,14 @@
             <regex-instance>.*</regex-instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.neuralnetworks</name>
         <interface>
             <name>IDevice</name>
             <regex-instance>.*</regex-instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.nfc</name>
         <version>1.2</version>
         <interface>
@@ -425,7 +425,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.oemlock</name>
         <version>1.0</version>
         <interface>
@@ -433,7 +433,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.power</name>
         <version>1-2</version>
         <interface>
@@ -441,14 +441,14 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.power.stats</name>
         <interface>
             <name>IPowerStats</name>
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.radio</name>
         <version>1.6</version>
         <interface>
@@ -458,7 +458,7 @@
             <instance>slot3</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.radio</name>
         <version>1.2</version>
         <interface>
@@ -467,7 +467,7 @@
             <instance>slot2</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.radio.config</name>
         <!--
         See compatibility_matrix.4.xml on versioning of radio config HAL.
@@ -478,7 +478,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.radio.config</name>
         <version>1.3</version>
         <interface>
@@ -486,7 +486,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.renderscript</name>
         <version>1.0</version>
         <interface>
@@ -494,7 +494,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.rebootescrow</name>
         <version>1</version>
         <interface>
@@ -502,7 +502,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.secure_element</name>
         <version>1.0-2</version>
         <interface>
@@ -511,7 +511,7 @@
             <regex-instance>SIM[1-9][0-9]*</regex-instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.security.secureclock</name>
         <version>1</version>
         <interface>
@@ -519,7 +519,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.security.sharedsecret</name>
         <version>1</version>
         <interface>
@@ -528,7 +528,7 @@
             <instance>strongbox</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.sensors</name>
         <version>1.0</version>
         <version>2.0-1</version>
@@ -537,7 +537,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.soundtrigger</name>
         <version>2.3</version>
         <interface>
@@ -545,7 +545,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.tetheroffload.config</name>
         <version>1.0</version>
         <interface>
@@ -553,7 +553,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.tetheroffload.control</name>
         <version>1.1</version>
         <interface>
@@ -561,7 +561,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.thermal</name>
         <version>2.0</version>
         <interface>
@@ -569,7 +569,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.tv.cec</name>
         <version>1.0-1</version>
         <interface>
@@ -577,7 +577,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.tv.input</name>
         <version>1.0</version>
         <interface>
@@ -585,7 +585,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.tv.tuner</name>
         <version>1.0-1</version>
         <interface>
@@ -593,7 +593,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.usb</name>
         <version>1.0-3</version>
         <interface>
@@ -601,7 +601,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.usb.gadget</name>
         <version>1.0-2</version>
         <interface>
@@ -609,7 +609,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.vibrator</name>
         <version>1-2</version>
         <interface>
@@ -617,7 +617,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.vibrator</name>
         <version>1-2</version>
         <interface>
@@ -625,7 +625,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.weaver</name>
         <version>1.0</version>
         <interface>
@@ -633,7 +633,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.weaver</name>
         <version>1</version>
         <interface>
@@ -641,7 +641,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.wifi</name>
         <version>1.3-5</version>
         <interface>
@@ -649,7 +649,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.wifi.hostapd</name>
         <version>1.0-3</version>
         <interface>
@@ -657,7 +657,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.wifi.supplicant</name>
         <version>1.2-4</version>
         <interface>
diff --git a/compatibility_matrices/compatibility_matrix.7.xml b/compatibility_matrices/compatibility_matrix.7.xml
index fe424bd..8dcc4ae 100644
--- a/compatibility_matrices/compatibility_matrix.7.xml
+++ b/compatibility_matrices/compatibility_matrix.7.xml
@@ -1,5 +1,5 @@
 <compatibility-matrix version="1.0" type="framework" level="7">
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.atrace</name>
         <version>1.0</version>
         <interface>
@@ -7,7 +7,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.audio</name>
         <version>6.0</version>
         <version>7.0-1</version>
@@ -16,7 +16,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.audio.effect</name>
         <version>6.0</version>
         <version>7.0</version>
@@ -25,7 +25,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
          <name>android.hardware.authsecret</name>
          <version>1</version>
          <interface>
@@ -33,7 +33,7 @@
              <instance>default</instance>
          </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.authsecret</name>
         <version>1.0</version>
         <interface>
@@ -41,7 +41,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.automotive.audiocontrol</name>
         <version>1-2</version>
         <interface>
@@ -49,7 +49,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.automotive.can</name>
         <version>1.0</version>
         <interface>
@@ -61,7 +61,7 @@
             <regex-instance>.*</regex-instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.automotive.evs</name>
         <interface>
             <name>IEvsEnumerator</name>
@@ -69,7 +69,7 @@
             <regex-instance>[a-z]+/[0-9]+</regex-instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.automotive.evs</name>
         <version>1.0-1</version>
         <interface>
@@ -78,7 +78,7 @@
             <regex-instance>[a-z]+/[0-9]+</regex-instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.automotive.occupant_awareness</name>
         <version>1</version>
         <interface>
@@ -86,14 +86,14 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.automotive.vehicle</name>
         <interface>
             <name>IVehicle</name>
             <regex-instance>.*</regex-instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.automotive.vehicle</name>
         <version>2.0</version>
         <interface>
@@ -101,7 +101,7 @@
             <regex-instance>.*</regex-instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.biometrics.face</name>
         <version>1.0</version>
         <interface>
@@ -109,7 +109,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.biometrics.face</name>
         <version>2</version>
         <interface>
@@ -117,7 +117,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.biometrics.fingerprint</name>
         <version>2.1-3</version>
         <interface>
@@ -125,7 +125,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.biometrics.fingerprint</name>
         <version>2</version>
         <interface>
@@ -133,7 +133,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.bluetooth</name>
         <version>1.0-1</version>
         <interface>
@@ -141,7 +141,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.bluetooth.audio</name>
         <version>2</version>
         <interface>
@@ -149,7 +149,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.boot</name>
         <version>1.2</version>
         <interface>
@@ -157,7 +157,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.broadcastradio</name>
         <version>1.0-1</version>
         <interface>
@@ -165,7 +165,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.broadcastradio</name>
         <version>2.0</version>
         <interface>
@@ -173,7 +173,7 @@
             <regex-instance>.*</regex-instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.camera.provider</name>
         <version>2.4-7</version>
         <interface>
@@ -181,7 +181,7 @@
             <regex-instance>[^/]+/[0-9]+</regex-instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.camera.provider</name>
         <version>1</version>
         <interface>
@@ -189,7 +189,7 @@
             <regex-instance>[^/]+/[0-9]+</regex-instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.cas</name>
         <version>1.1-2</version>
         <interface>
@@ -197,7 +197,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.confirmationui</name>
         <version>1.0</version>
         <interface>
@@ -205,14 +205,14 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.contexthub</name>
         <interface>
             <name>IContextHub</name>
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.drm</name>
         <version>1</version>
         <interface>
@@ -220,7 +220,7 @@
             <regex-instance>.*</regex-instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.drm</name>
         <version>1.3-4</version>
         <interface>
@@ -232,14 +232,14 @@
             <regex-instance>.*</regex-instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.dumpstate</name>
         <interface>
             <name>IDumpstateDevice</name>
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.gatekeeper</name>
         <version>1.0</version>
         <interface>
@@ -247,7 +247,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.gnss</name>
         <version>2.0-1</version>
         <interface>
@@ -255,7 +255,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.gnss</name>
         <version>2</version>
         <interface>
@@ -263,7 +263,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.graphics.allocator</name>
         <!-- New, non-Go devices should use 4.0 or the AIDL hal. -->
         <version>2.0</version>
@@ -274,7 +274,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.graphics.allocator</name>
         <version>1</version>
         <interface>
@@ -285,7 +285,7 @@
     <!-- Either the AIDL or the HIDL composer HAL must exist on the device.
          If the HIDL composer HAL exists, it must be at least version 2.1.
          See DeviceManifestTest.ComposerHal -->
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.graphics.composer</name>
         <version>2.1-4</version>
         <interface>
@@ -293,7 +293,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.graphics.composer3</name>
         <version>1</version>
         <interface>
@@ -301,7 +301,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.graphics.mapper</name>
         <!-- New, non-Go devices should use 4.0, tested in vts_treble_vintf_vendor_test -->
         <version>2.1</version>
@@ -312,7 +312,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.health</name>
         <version>1</version>
         <interface>
@@ -320,7 +320,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.health.storage</name>
         <version>1</version>
         <interface>
@@ -328,7 +328,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.identity</name>
         <version>1-4</version>
         <interface>
@@ -336,14 +336,14 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.net.nlinterceptor</name>
         <interface>
             <name>IInterceptor</name>
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.oemlock</name>
         <version>1</version>
         <interface>
@@ -351,7 +351,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.ir</name>
         <version>1</version>
         <interface>
@@ -359,7 +359,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.input.processor</name>
         <version>1</version>
         <interface>
@@ -367,7 +367,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.keymaster</name>
         <version>3.0</version>
         <version>4.0-1</version>
@@ -376,7 +376,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.keymaster</name>
         <version>4.0-1</version>
         <interface>
@@ -384,7 +384,7 @@
             <instance>strongbox</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.security.keymint</name>
         <version>1-2</version>
         <interface>
@@ -393,7 +393,7 @@
             <instance>strongbox</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.security.keymint</name>
         <version>1-2</version>
         <interface>
@@ -402,7 +402,7 @@
             <instance>strongbox</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.light</name>
         <version>1-2</version>
         <interface>
@@ -410,7 +410,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.media.c2</name>
         <version>1.0-2</version>
         <interface>
@@ -420,7 +420,7 @@
             <regex-instance>vendor[0-9]*_software</regex-instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.media.c2</name>
         <version>1.0</version>
         <interface>
@@ -429,7 +429,7 @@
             <instance>software</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.media.omx</name>
         <version>1.0</version>
         <interface>
@@ -441,7 +441,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.memtrack</name>
         <version>1</version>
         <interface>
@@ -449,7 +449,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.neuralnetworks</name>
         <version>1.0-3</version>
         <interface>
@@ -457,7 +457,7 @@
             <regex-instance>.*</regex-instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.neuralnetworks</name>
         <version>1-4</version>
         <interface>
@@ -465,7 +465,7 @@
             <regex-instance>.*</regex-instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.nfc</name>
         <version>1.2</version>
         <interface>
@@ -473,14 +473,14 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.nfc</name>
         <interface>
             <name>INfc</name>
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.oemlock</name>
         <version>1.0</version>
         <interface>
@@ -488,7 +488,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.power</name>
         <version>2-3</version>
         <interface>
@@ -496,14 +496,14 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.power.stats</name>
         <interface>
             <name>IPowerStats</name>
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.radio.config</name>
         <version>1</version>
         <interface>
@@ -511,7 +511,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.radio.data</name>
         <version>1</version>
         <interface>
@@ -521,7 +521,7 @@
             <instance>slot3</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.radio.messaging</name>
         <version>1</version>
         <interface>
@@ -531,7 +531,7 @@
             <instance>slot3</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.radio.modem</name>
         <version>1</version>
         <interface>
@@ -541,7 +541,7 @@
             <instance>slot3</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.radio.network</name>
         <version>1</version>
         <interface>
@@ -551,7 +551,7 @@
             <instance>slot3</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.radio.sim</name>
         <version>1</version>
         <interface>
@@ -561,7 +561,7 @@
             <instance>slot3</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.radio.voice</name>
         <version>1</version>
         <interface>
@@ -571,7 +571,7 @@
             <instance>slot3</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.radio</name>
         <version>1.2</version>
         <interface>
@@ -580,7 +580,7 @@
             <instance>slot2</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.renderscript</name>
         <version>1.0</version>
         <interface>
@@ -588,7 +588,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.rebootescrow</name>
         <version>1</version>
         <interface>
@@ -596,7 +596,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.secure_element</name>
         <version>1.0-2</version>
         <interface>
@@ -605,7 +605,7 @@
             <regex-instance>SIM[1-9][0-9]*</regex-instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.security.secureclock</name>
         <version>1</version>
         <interface>
@@ -613,7 +613,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.security.sharedsecret</name>
         <version>1</version>
         <interface>
@@ -622,14 +622,14 @@
             <instance>strongbox</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.sensors</name>
         <interface>
             <name>ISensors</name>
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.sensors</name>
         <version>1.0</version>
         <version>2.0-1</version>
@@ -638,7 +638,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.soundtrigger</name>
         <version>2.3</version>
         <interface>
@@ -646,7 +646,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
          <name>android.hardware.soundtrigger3</name>
          <version>1</version>
          <interface>
@@ -654,7 +654,7 @@
              <instance>default</instance>
          </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.tetheroffload.config</name>
         <version>1.0</version>
         <interface>
@@ -662,7 +662,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.tetheroffload.control</name>
         <version>1.1</version>
         <interface>
@@ -670,7 +670,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.thermal</name>
         <version>2.0</version>
         <interface>
@@ -678,7 +678,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.tv.cec</name>
         <version>1.0-1</version>
         <interface>
@@ -686,7 +686,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.tv.input</name>
         <version>1.0</version>
         <interface>
@@ -694,7 +694,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.tv.tuner</name>
         <version>1.0-1</version>
         <interface>
@@ -702,7 +702,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.tv.tuner</name>
         <version>1</version>
         <interface>
@@ -710,7 +710,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.usb</name>
         <version>1.0-3</version>
         <interface>
@@ -718,14 +718,14 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.usb</name>
         <interface>
             <name>IUsb</name>
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.usb.gadget</name>
         <version>1.0-2</version>
         <interface>
@@ -733,7 +733,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.vibrator</name>
         <version>1-2</version>
         <interface>
@@ -741,7 +741,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.vibrator</name>
         <version>1-2</version>
         <interface>
@@ -749,7 +749,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.weaver</name>
         <version>1.0</version>
         <interface>
@@ -757,7 +757,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.weaver</name>
         <version>1</version>
         <interface>
@@ -765,7 +765,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.wifi</name>
         <version>1.3-6</version>
         <interface>
@@ -773,7 +773,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.uwb</name>
         <version>1</version>
         <interface>
@@ -781,7 +781,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.wifi.hostapd</name>
         <version>1</version>
         <interface>
@@ -789,7 +789,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.wifi.supplicant</name>
         <interface>
             <name>ISupplicant</name>
diff --git a/compatibility_matrices/compatibility_matrix.8.xml b/compatibility_matrices/compatibility_matrix.8.xml
index 777eb84..7054bfa 100644
--- a/compatibility_matrices/compatibility_matrix.8.xml
+++ b/compatibility_matrices/compatibility_matrix.8.xml
@@ -1,5 +1,5 @@
 <compatibility-matrix version="1.0" type="framework" level="8">
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.audio</name>
         <version>6.0</version>
         <version>7.0-1</version>
@@ -8,7 +8,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.audio.effect</name>
         <version>6.0</version>
         <version>7.0</version>
@@ -17,7 +17,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.audio.core</name>
         <version>1</version>
         <interface>
@@ -36,7 +36,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.audio.effect</name>
         <version>1</version>
         <interface>
@@ -44,7 +44,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.audio.sounddose</name>
         <version>1</version>
         <interface>
@@ -52,7 +52,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true" updatable-via-apex="true">
+    <hal format="aidl" updatable-via-apex="true">
          <name>android.hardware.authsecret</name>
          <version>1</version>
          <interface>
@@ -60,7 +60,7 @@
              <instance>default</instance>
          </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.automotive.audiocontrol</name>
         <version>2-3</version>
         <interface>
@@ -68,7 +68,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.automotive.can</name>
         <version>1</version>
         <interface>
@@ -76,7 +76,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.automotive.evs</name>
         <version>1-2</version>
         <interface>
@@ -84,7 +84,7 @@
             <regex-instance>[a-z]+/[0-9]+</regex-instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.automotive.occupant_awareness</name>
         <version>1</version>
         <interface>
@@ -92,7 +92,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.automotive.vehicle</name>
         <version>1-2</version>
         <interface>
@@ -100,21 +100,21 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.automotive.remoteaccess</name>
         <interface>
             <name>IRemoteAccess</name>
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.automotive.ivn</name>
         <interface>
             <name>IIvnAndroidDevice</name>
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true" updatable-via-apex="true">
+    <hal format="aidl" updatable-via-apex="true">
         <name>android.hardware.biometrics.face</name>
         <version>3-4</version>
         <interface>
@@ -123,7 +123,7 @@
             <instance>virtual</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true" updatable-via-apex="true">
+    <hal format="aidl" updatable-via-apex="true">
         <name>android.hardware.biometrics.fingerprint</name>
         <version>3</version>
         <interface>
@@ -132,7 +132,7 @@
             <instance>virtual</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.bluetooth</name>
         <version>1.0-1</version>
         <interface>
@@ -140,14 +140,14 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.bluetooth</name>
         <interface>
             <name>IBluetoothHci</name>
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.bluetooth.audio</name>
         <version>3</version>
         <interface>
@@ -155,21 +155,21 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.boot</name>
         <interface>
             <name>IBootControl</name>
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.broadcastradio</name>
         <interface>
             <name>IBroadcastRadio</name>
             <regex-instance>.*</regex-instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true" updatable-via-apex="true">
+    <hal format="aidl" updatable-via-apex="true">
         <name>android.hardware.camera.provider</name>
         <version>1-2</version>
         <interface>
@@ -177,14 +177,14 @@
             <regex-instance>[^/]+/[0-9]+</regex-instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.cas</name>
         <interface>
             <name>IMediaCasService</name>
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.confirmationui</name>
         <version>1</version>
         <interface>
@@ -192,7 +192,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.contexthub</name>
         <version>2</version>
         <interface>
@@ -200,7 +200,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true" updatable-via-apex="true">
+    <hal format="aidl" updatable-via-apex="true">
         <name>android.hardware.drm</name>
         <version>1</version>
         <interface>
@@ -208,14 +208,14 @@
             <regex-instance>.*</regex-instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.dumpstate</name>
         <interface>
             <name>IDumpstateDevice</name>
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.gatekeeper</name>
         <version>1</version>
         <interface>
@@ -223,7 +223,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.gnss</name>
         <version>2-3</version>
         <interface>
@@ -231,7 +231,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.graphics.allocator</name>
         <version>1-2</version>
         <interface>
@@ -239,7 +239,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.graphics.composer3</name>
         <version>2</version>
         <interface>
@@ -248,7 +248,7 @@
         </interface>
     </hal>
     <!-- Either the native or the HIDL mapper HAL must exist on the device -->
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.graphics.mapper</name>
         <!-- New, non-Go devices should use 4.0, tested in vts_treble_vintf_vendor_test -->
         <version>2.1</version>
@@ -259,7 +259,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.health</name>
         <version>1-2</version>
         <interface>
@@ -267,7 +267,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.health.storage</name>
         <version>1</version>
         <interface>
@@ -275,7 +275,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.identity</name>
         <version>1-5</version>
         <interface>
@@ -283,14 +283,14 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.net.nlinterceptor</name>
         <interface>
             <name>IInterceptor</name>
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.oemlock</name>
         <version>1</version>
         <interface>
@@ -298,7 +298,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.ir</name>
         <version>1</version>
         <interface>
@@ -306,7 +306,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.input.processor</name>
         <version>1</version>
         <interface>
@@ -314,7 +314,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true" updatable-via-apex="true">
+    <hal format="aidl" updatable-via-apex="true">
         <name>android.hardware.security.keymint</name>
         <version>1-3</version>
         <interface>
@@ -323,7 +323,7 @@
             <instance>strongbox</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true" updatable-via-apex="true">
+    <hal format="aidl" updatable-via-apex="true">
         <name>android.hardware.security.keymint</name>
         <version>1-3</version>
         <interface>
@@ -333,7 +333,7 @@
             <instance>widevine</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.light</name>
         <version>2</version>
         <interface>
@@ -341,7 +341,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.media.c2</name>
         <version>1.0-2</version>
         <interface>
@@ -351,7 +351,7 @@
             <regex-instance>vendor[0-9]*_software</regex-instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.media.c2</name>
         <version>1.0</version>
         <interface>
@@ -360,7 +360,7 @@
             <instance>software</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.media.omx</name>
         <version>1.0</version>
         <interface>
@@ -372,7 +372,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.memtrack</name>
         <version>1</version>
         <interface>
@@ -380,7 +380,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true" updatable-via-apex="true">
+    <hal format="aidl" updatable-via-apex="true">
         <name>android.hardware.neuralnetworks</name>
         <version>1-4</version>
         <interface>
@@ -388,14 +388,14 @@
             <regex-instance>.*</regex-instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true" updatable-via-apex="true">
+    <hal format="aidl" updatable-via-apex="true">
         <name>android.hardware.nfc</name>
         <interface>
             <name>INfc</name>
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.power</name>
         <version>4</version>
         <interface>
@@ -403,7 +403,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.power.stats</name>
         <version>2</version>
         <interface>
@@ -411,7 +411,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.radio.config</name>
         <version>2</version>
         <interface>
@@ -419,7 +419,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.radio.data</name>
         <version>2</version>
         <interface>
@@ -429,7 +429,7 @@
             <instance>slot3</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.radio.messaging</name>
         <version>2</version>
         <interface>
@@ -439,7 +439,7 @@
             <instance>slot3</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.radio.modem</name>
         <version>2</version>
         <interface>
@@ -449,7 +449,7 @@
             <instance>slot3</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.radio.network</name>
         <version>2</version>
         <interface>
@@ -459,7 +459,7 @@
             <instance>slot3</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.radio.sim</name>
         <version>2</version>
         <interface>
@@ -469,7 +469,7 @@
             <instance>slot3</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.radio.sap</name>
         <version>1</version>
         <interface>
@@ -479,7 +479,7 @@
             <instance>slot3</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.radio.voice</name>
         <version>2</version>
         <interface>
@@ -489,7 +489,7 @@
             <instance>slot3</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.radio.ims</name>
         <version>1</version>
         <interface>
@@ -499,7 +499,7 @@
             <instance>slot3</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.radio.ims.media</name>
         <version>1</version>
         <interface>
@@ -507,7 +507,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.renderscript</name>
         <version>1.0</version>
         <interface>
@@ -515,7 +515,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.rebootescrow</name>
         <version>1</version>
         <interface>
@@ -523,7 +523,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.secure_element</name>
         <version>1</version>
         <interface>
@@ -532,7 +532,7 @@
             <regex-instance>SIM[1-9][0-9]*</regex-instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true" updatable-via-apex="true">
+    <hal format="aidl" updatable-via-apex="true">
         <name>android.hardware.security.secureclock</name>
         <version>1</version>
         <interface>
@@ -540,7 +540,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true" updatable-via-apex="true">
+    <hal format="aidl" updatable-via-apex="true">
         <name>android.hardware.security.sharedsecret</name>
         <version>1</version>
         <interface>
@@ -549,7 +549,7 @@
             <instance>strongbox</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.sensors</name>
         <version>2</version>
         <interface>
@@ -557,7 +557,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.soundtrigger</name>
         <version>2.3</version>
         <interface>
@@ -565,7 +565,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
          <name>android.hardware.soundtrigger3</name>
          <version>1</version>
          <interface>
@@ -573,7 +573,7 @@
              <instance>default</instance>
          </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.tetheroffload.config</name>
         <version>1.0</version>
         <interface>
@@ -581,7 +581,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="hidl">
         <name>android.hardware.tetheroffload.control</name>
         <version>1.1</version>
         <interface>
@@ -589,7 +589,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.tetheroffload</name>
         <version>1</version>
         <interface>
@@ -597,7 +597,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.thermal</name>
         <version>1</version>
         <interface>
@@ -605,7 +605,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.tv.hdmi.cec</name>
         <version>1</version>
         <interface>
@@ -613,7 +613,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.tv.hdmi.earc</name>
         <version>1</version>
         <interface>
@@ -621,7 +621,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.tv.hdmi.connection</name>
         <version>1</version>
         <interface>
@@ -629,7 +629,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.tv.tuner</name>
         <version>1-2</version>
         <interface>
@@ -637,7 +637,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.tv.input</name>
         <version>1</version>
         <interface>
@@ -645,7 +645,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.usb</name>
         <version>1-2</version>
         <interface>
@@ -653,14 +653,14 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.usb.gadget</name>
         <interface>
             <name>IUsbGadget</name>
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.vibrator</name>
         <version>1-2</version>
         <interface>
@@ -668,7 +668,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.vibrator</name>
         <version>1-2</version>
         <interface>
@@ -676,7 +676,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.weaver</name>
         <version>2</version>
         <interface>
@@ -684,7 +684,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true" updatable-via-apex="true">
+    <hal format="aidl" updatable-via-apex="true">
         <name>android.hardware.wifi</name>
         <version>1</version>
         <interface>
@@ -692,7 +692,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true" updatable-via-apex="true">
+    <hal format="aidl" updatable-via-apex="true">
         <name>android.hardware.uwb</name>
         <version>1</version>
         <interface>
@@ -700,7 +700,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.wifi.hostapd</name>
         <version>1</version>
         <interface>
@@ -708,7 +708,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="true">
+    <hal format="aidl">
         <name>android.hardware.wifi.supplicant</name>
         <version>2</version>
         <interface>
@@ -717,7 +717,7 @@
         </interface>
     </hal>
     <!-- Either the native or the HIDL mapper HAL must exist on the device -->
-    <hal format="native" optional="true">
+    <hal format="native">
         <name>mapper</name>
         <version>5.0</version>
         <interface>
diff --git a/media/bufferpool/aidl/Android.bp b/media/bufferpool/aidl/Android.bp
index 8e013e0..9dcc90e 100644
--- a/media/bufferpool/aidl/Android.bp
+++ b/media/bufferpool/aidl/Android.bp
@@ -26,6 +26,9 @@
     vendor_available: true,
     double_loadable: true,
     srcs: ["android/hardware/media/bufferpool2/*.aidl"],
+    headers: [
+        "HardwareBuffer_aidl",
+    ],
     imports: [
         "android.hardware.common-V2",
         "android.hardware.common.fmq-V1",
@@ -44,10 +47,13 @@
                 "//apex_available:platform",
                 "com.android.media.swcodec",
             ],
+            additional_shared_libraries: [
+                "libnativewindow",
+            ],
             min_sdk_version: "29",
         },
         rust: {
-            enabled: true,
+            enabled: false,
         },
     },
     versions_with_info: [
@@ -59,6 +65,6 @@
             ],
         },
     ],
-    frozen: true,
+    frozen: false,
 
 }
diff --git a/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/Buffer.aidl b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/Buffer.aidl
index 4ea0bba..85a78ad 100644
--- a/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/Buffer.aidl
+++ b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/Buffer.aidl
@@ -35,5 +35,6 @@
 @VintfStability
 parcelable Buffer {
   int id;
-  android.hardware.common.NativeHandle buffer;
+  @nullable android.hardware.common.NativeHandle buffer;
+  @nullable android.hardware.HardwareBuffer hwbBuffer;
 }
diff --git a/media/bufferpool/aidl/android/hardware/media/bufferpool2/Buffer.aidl b/media/bufferpool/aidl/android/hardware/media/bufferpool2/Buffer.aidl
index 976f674..79b3f23 100644
--- a/media/bufferpool/aidl/android/hardware/media/bufferpool2/Buffer.aidl
+++ b/media/bufferpool/aidl/android/hardware/media/bufferpool2/Buffer.aidl
@@ -17,6 +17,7 @@
 package android.hardware.media.bufferpool2;
 
 import android.hardware.common.NativeHandle;
+import android.hardware.HardwareBuffer;
 
 /**
  * Generic buffer for fast recycling for media/stagefright.
@@ -26,10 +27,14 @@
  * by a buffer pool, and are recycled to the buffer pool when they are
  * no longer referenced by the clients.
  *
+ * Initially all buffers in media HAL should be NativeHandle(actually native_handle_t).
+ * HardwareBuffer(actually AHardwareBuffer) for GraphicBuffer is added from V2.
+ *
  * E.g. ion or gralloc buffer
  */
 @VintfStability
 parcelable Buffer {
     int id;
-    NativeHandle buffer;
+    @nullable NativeHandle buffer;
+    @nullable HardwareBuffer hwbBuffer;
 }
diff --git a/media/bufferpool/aidl/default/Android.bp b/media/bufferpool/aidl/default/Android.bp
index 11a6163..4d12d63 100644
--- a/media/bufferpool/aidl/default/Android.bp
+++ b/media/bufferpool/aidl/default/Android.bp
@@ -33,15 +33,16 @@
         "libcutils",
         "libfmq",
         "liblog",
+        "libnativewindow",
         "libutils",
-        "android.hardware.media.bufferpool2-V1-ndk",
+        "android.hardware.media.bufferpool2-V2-ndk",
     ],
     static_libs: [
         "libaidlcommonsupport",
     ],
     export_shared_lib_headers: [
         "libfmq",
-        "android.hardware.media.bufferpool2-V1-ndk",
+        "android.hardware.media.bufferpool2-V2-ndk",
     ],
     double_loadable: true,
     cflags: [
diff --git a/media/bufferpool/aidl/default/BufferPoolClient.cpp b/media/bufferpool/aidl/default/BufferPoolClient.cpp
index 0e249d5..ce4ad8e 100644
--- a/media/bufferpool/aidl/default/BufferPoolClient.cpp
+++ b/media/bufferpool/aidl/default/BufferPoolClient.cpp
@@ -757,7 +757,13 @@
         return svcSpecific ? svcSpecific : ResultStatus::CRITICAL_ERROR;
     }
     if (results[0].getTag() == FetchResult::buffer) {
-        *handle = ::android::dupFromAidl(results[0].get<FetchResult::buffer>().buffer);
+        if (results[0].get<FetchResult::buffer>().buffer.has_value()) {
+            *handle = ::android::dupFromAidl(results[0].get<FetchResult::buffer>().buffer.value());
+        } else {
+            // TODO: Support HardwareBuffer
+            ALOGW("handle nullptr");
+            *handle = nullptr;
+        }
         return ResultStatus::OK;
     }
     return results[0].get<FetchResult::failure>();
diff --git a/media/bufferpool/aidl/default/tests/Android.bp b/media/bufferpool/aidl/default/tests/Android.bp
index 549af57..487ed4c 100644
--- a/media/bufferpool/aidl/default/tests/Android.bp
+++ b/media/bufferpool/aidl/default/tests/Android.bp
@@ -36,8 +36,9 @@
         "libcutils",
         "libfmq",
         "liblog",
+        "libnativewindow",
         "libutils",
-        "android.hardware.media.bufferpool2-V1-ndk",
+        "android.hardware.media.bufferpool2-V2-ndk",
     ],
     static_libs: [
         "libaidlcommonsupport",
@@ -59,8 +60,9 @@
         "libcutils",
         "libfmq",
         "liblog",
+        "libnativewindow",
         "libutils",
-        "android.hardware.media.bufferpool2-V1-ndk",
+        "android.hardware.media.bufferpool2-V2-ndk",
     ],
     static_libs: [
         "libaidlcommonsupport",
@@ -82,8 +84,9 @@
         "libcutils",
         "libfmq",
         "liblog",
+        "libnativewindow",
         "libutils",
-        "android.hardware.media.bufferpool2-V1-ndk",
+        "android.hardware.media.bufferpool2-V2-ndk",
     ],
     static_libs: [
         "libaidlcommonsupport",
diff --git a/media/c2/aidl/Android.bp b/media/c2/aidl/Android.bp
index b511e45..2eaeb01 100644
--- a/media/c2/aidl/Android.bp
+++ b/media/c2/aidl/Android.bp
@@ -20,7 +20,7 @@
     ],
     imports: [
         "android.hardware.common-V2",
-        "android.hardware.media.bufferpool2-V1",
+        "android.hardware.media.bufferpool2-V2",
     ],
     include_dirs: [
         "frameworks/native/aidl/gui",
diff --git a/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp b/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp
index b36735f..8210ff0 100644
--- a/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp
+++ b/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp
@@ -354,13 +354,6 @@
     res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
     EXPECT_TRUE(res.no_timeout);
     EXPECT_EQ((int)NfcStatus::OK, res.args->last_data_[3]);
-    if (nci_version == NCI_VERSION_2 && res.args->last_data_.size() > 13 &&
-        res.args->last_data_[13] == 0x00) {
-        // Wait for CORE_CONN_CREDITS_NTF
-        res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
-        EXPECT_TRUE(res.no_timeout);
-    }
-
     cmd = CORE_CONN_CREATE_CMD;
     data = cmd;
     EXPECT_EQ(data.size(), nfc_->write(data));
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RegistrationFailCause.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RegistrationFailCause.aidl
index 56f516d..fcc079e 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RegistrationFailCause.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RegistrationFailCause.aidl
@@ -50,7 +50,11 @@
   ROAMING_NOT_ALLOWED = 13,
   GPRS_SERVICES_NOT_ALLOWED_IN_PLMN = 14,
   NO_SUITABLE_CELLS = 15,
+  /**
+   * @deprecated MSC_TEMPORARILY_NOT_REACHABLE value is wrong and should not be used. Use MSC_TEMP_NOT_REACHABLE instead.
+   */
   MSC_TEMPORARILY_NOT_REACHABLE = 15,
+  MSC_TEMP_NOT_REACHABLE = 16,
   NETWORK_FAILURE = 17,
   MAC_FAILURE = 20,
   SYNC_FAILURE = 21,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CarrierInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CarrierInfo.aidl
index 5838959..7d4a54b 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CarrierInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CarrierInfo.aidl
@@ -41,7 +41,7 @@
   @nullable String gid1;
   @nullable String gid2;
   @nullable String imsiPrefix;
-  @nullable List<android.hardware.radio.sim.Plmn> ephlmn;
+  @nullable List<android.hardware.radio.sim.Plmn> ehplmn;
   @nullable String iccid;
   @nullable String impi;
 }
diff --git a/radio/aidl/android/hardware/radio/network/RegistrationFailCause.aidl b/radio/aidl/android/hardware/radio/network/RegistrationFailCause.aidl
index 2955f96..11fd8c5 100644
--- a/radio/aidl/android/hardware/radio/network/RegistrationFailCause.aidl
+++ b/radio/aidl/android/hardware/radio/network/RegistrationFailCause.aidl
@@ -86,10 +86,15 @@
      */
     NO_SUITABLE_CELLS = 15,
     /**
-     * 16 - MSC temporarily not reachable
+     * @deprecated MSC_TEMPORARILY_NOT_REACHABLE value is wrong and should not be used.
+     * Use MSC_TEMP_NOT_REACHABLE instead.
      */
     MSC_TEMPORARILY_NOT_REACHABLE = 15,
     /**
+     * 16 - MSC temporarily not reachable
+     */
+    MSC_TEMP_NOT_REACHABLE = 16,
+    /**
      * 17 - Network Failure
      */
     NETWORK_FAILURE = 17,
diff --git a/radio/aidl/android/hardware/radio/sim/CarrierInfo.aidl b/radio/aidl/android/hardware/radio/sim/CarrierInfo.aidl
index a890497..74fe31b 100644
--- a/radio/aidl/android/hardware/radio/sim/CarrierInfo.aidl
+++ b/radio/aidl/android/hardware/radio/sim/CarrierInfo.aidl
@@ -56,7 +56,7 @@
      * Equivalent HPLMN of the SIM card of the Carrier.
      */
     @nullable
-    List<Plmn> ephlmn;
+    List<Plmn> ehplmn;
     /**
      * ICCID (Integrated Circuit Card Identification) of the SIM card.
      */
diff --git a/radio/aidl/vts/radio_network_test.cpp b/radio/aidl/vts/radio_network_test.cpp
index 32b246a..2e218c0 100644
--- a/radio/aidl/vts/radio_network_test.cpp
+++ b/radio/aidl/vts/radio_network_test.cpp
@@ -1422,19 +1422,12 @@
     EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
     EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
 
-    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
-        ASSERT_TRUE(CheckAnyOfErrors(
-                radioRsp_network->rspInfo.error,
-                {RadioError::NONE, RadioError::ILLEGAL_SIM_OR_ME, RadioError::INVALID_ARGUMENTS,
-                 RadioError::INVALID_STATE, RadioError::RADIO_NOT_AVAILABLE, RadioError::NO_MEMORY,
-                 RadioError::INTERNAL_ERR, RadioError::SYSTEM_ERR, RadioError::CANCELLED}));
-    } else if (cardStatus.cardState == CardStatus::STATE_PRESENT) {
-        ASSERT_TRUE(CheckAnyOfErrors(
-                radioRsp_network->rspInfo.error,
-                {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::INVALID_ARGUMENTS,
-                 RadioError::INVALID_STATE, RadioError::NO_MEMORY, RadioError::INTERNAL_ERR,
-                 RadioError::SYSTEM_ERR, RadioError::CANCELLED}));
-    }
+    ASSERT_TRUE(CheckAnyOfErrors(
+            radioRsp_network->rspInfo.error,
+            {RadioError::NONE, RadioError::ILLEGAL_SIM_OR_ME, RadioError::RADIO_NOT_AVAILABLE,
+             RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::NO_MEMORY,
+             RadioError::INTERNAL_ERR, RadioError::SYSTEM_ERR, RadioError::CANCELLED,
+             RadioError::MODEM_ERR, RadioError::OPERATION_NOT_ALLOWED, RadioError::NO_RESOURCES}));
 }
 
 /*
diff --git a/security/authgraph/aidl/android/hardware/security/authgraph/ExplicitKeyDiceCertChain.cddl b/security/authgraph/aidl/android/hardware/security/authgraph/ExplicitKeyDiceCertChain.cddl
index 3de5617..2d6c696 100644
--- a/security/authgraph/aidl/android/hardware/security/authgraph/ExplicitKeyDiceCertChain.cddl
+++ b/security/authgraph/aidl/android/hardware/security/authgraph/ExplicitKeyDiceCertChain.cddl
@@ -19,11 +19,10 @@
     * DiceChainEntry
 ]
 
-DiceCertChainInitialPayload = {
-    -4670552 : bstr .cbor PubKeyEd25519 /
-               bstr .cbor PubKeyECDSA256 /
-               bstr .cbor PubKeyECDSA384 ; subjectPublicKey
-}
+; Encoded in accordance with Core Deterministic Encoding Requirements [RFC 8949 s4.2.1]
+DiceCertChainInitialPayload = bstr .cbor PubKeyEd25519
+                            / bstr .cbor PubKeyECDSA256
+                            / bstr .cbor PubKeyECDSA384 ; subjectPublicKey
 
 ; INCLUDE generateCertificateRequestV2.cddl for: PubKeyEd25519, PubKeyECDSA256, PubKeyECDSA384,
 ;                                                DiceChainEntry
diff --git a/security/secretkeeper/aidl/vts/Android.bp b/security/secretkeeper/aidl/vts/Android.bp
index 1e01149..9d1701a 100644
--- a/security/secretkeeper/aidl/vts/Android.bp
+++ b/security/secretkeeper/aidl/vts/Android.bp
@@ -18,6 +18,19 @@
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
+rust_library {
+    name: "libsecretkeeper_test",
+    crate_name: "secretkeeper_test",
+    srcs: ["lib.rs"],
+    rustlibs: [
+        "libciborium",
+        "libcoset",
+        "libdiced_open_dice",
+        "liblog_rust",
+        "libsecretkeeper_client",
+    ],
+}
+
 rust_test {
     name: "VtsSecretkeeperTargetTest",
     srcs: ["secretkeeper_test_client.rs"],
@@ -30,17 +43,40 @@
     ],
     test_config: "AndroidTest.xml",
     rustlibs: [
-        "libsecretkeeper_client",
-        "libsecretkeeper_comm_nostd",
-        "libsecretkeeper_core_nostd",
         "android.hardware.security.secretkeeper-V1-rust",
         "libauthgraph_boringssl",
         "libauthgraph_core",
-        "libcoset",
         "libauthgraph_vts_test",
         "libbinder_rs",
+        "libciborium",
         "libcoset",
+        "libdice_policy",
         "liblog_rust",
+        "libsecretkeeper_client",
+        "libsecretkeeper_comm_nostd",
+        "libsecretkeeper_core_nostd",
+        "libsecretkeeper_test",
     ],
     require_root: true,
 }
+
+rust_binary {
+    name: "secretkeeper_cli",
+    srcs: ["secretkeeper_cli.rs"],
+    lints: "android",
+    rlibs: [
+        "android.hardware.security.secretkeeper-V1-rust",
+        "libanyhow",
+        "libauthgraph_boringssl",
+        "libauthgraph_core",
+        "libbinder_rs",
+        "libclap",
+        "libcoset",
+        "libdice_policy",
+        "libhex",
+        "liblog_rust",
+        "libsecretkeeper_client",
+        "libsecretkeeper_comm_nostd",
+        "libsecretkeeper_test",
+    ],
+}
diff --git a/security/secretkeeper/aidl/vts/dice_sample.rs b/security/secretkeeper/aidl/vts/dice_sample.rs
new file mode 100644
index 0000000..db532b1
--- /dev/null
+++ b/security/secretkeeper/aidl/vts/dice_sample.rs
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+//! This module provides a set of sample DICE chains for testing purpose only. Note that this
+//! module duplicates a large chunk of code in libdiced_sample_inputs. We avoid modifying the
+//! latter for testing purposes because it is installed on device.
+
+use ciborium::{de, ser, value::Value};
+use core::ffi::CStr;
+use coset::{iana, Algorithm, AsCborValue, CoseKey, KeyOperation, KeyType, Label};
+use diced_open_dice::{
+    derive_cdi_private_key_seed, keypair_from_seed, retry_bcc_format_config_descriptor,
+    retry_bcc_main_flow, retry_dice_main_flow, Config, DiceArtifacts, DiceConfigValues, DiceError,
+    DiceMode, InputValues, OwnedDiceArtifacts, CDI_SIZE, HASH_SIZE, HIDDEN_SIZE,
+};
+use log::error;
+use secretkeeper_client::dice::OwnedDiceArtifactsWithExplicitKey;
+
+/// Sample UDS used to perform the root DICE flow by `make_sample_bcc_and_cdis`.
+const UDS: &[u8; CDI_SIZE] = &[
+    0x65, 0x4f, 0xab, 0xa9, 0xa5, 0xad, 0x0f, 0x5e, 0x15, 0xc3, 0x12, 0xf7, 0x77, 0x45, 0xfa, 0x55,
+    0x18, 0x6a, 0xa6, 0x34, 0xb6, 0x7c, 0x82, 0x7b, 0x89, 0x4c, 0xc5, 0x52, 0xd3, 0x27, 0x35, 0x8e,
+];
+
+const CODE_HASH_ABL: [u8; HASH_SIZE] = [
+    0x16, 0x48, 0xf2, 0x55, 0x53, 0x23, 0xdd, 0x15, 0x2e, 0x83, 0x38, 0xc3, 0x64, 0x38, 0x63, 0x26,
+    0x0f, 0xcf, 0x5b, 0xd1, 0x3a, 0xd3, 0x40, 0x3e, 0x23, 0xf8, 0x34, 0x4c, 0x6d, 0xa2, 0xbe, 0x25,
+    0x1c, 0xb0, 0x29, 0xe8, 0xc3, 0xfb, 0xb8, 0x80, 0xdc, 0xb1, 0xd2, 0xb3, 0x91, 0x4d, 0xd3, 0xfb,
+    0x01, 0x0f, 0xe4, 0xe9, 0x46, 0xa2, 0xc0, 0x26, 0x57, 0x5a, 0xba, 0x30, 0xf7, 0x15, 0x98, 0x14,
+];
+const AUTHORITY_HASH_ABL: [u8; HASH_SIZE] = [
+    0xf9, 0x00, 0x9d, 0xc2, 0x59, 0x09, 0xe0, 0xb6, 0x98, 0xbd, 0xe3, 0x97, 0x4a, 0xcb, 0x3c, 0xe7,
+    0x6b, 0x24, 0xc3, 0xe4, 0x98, 0xdd, 0xa9, 0x6a, 0x41, 0x59, 0x15, 0xb1, 0x23, 0xe6, 0xc8, 0xdf,
+    0xfb, 0x52, 0xb4, 0x52, 0xc1, 0xb9, 0x61, 0xdd, 0xbc, 0x5b, 0x37, 0x0e, 0x12, 0x12, 0xb2, 0xfd,
+    0xc1, 0x09, 0xb0, 0xcf, 0x33, 0x81, 0x4c, 0xc6, 0x29, 0x1b, 0x99, 0xea, 0xae, 0xfd, 0xaa, 0x0d,
+];
+const HIDDEN_ABL: [u8; HIDDEN_SIZE] = [
+    0xa2, 0x01, 0xd0, 0xc0, 0xaa, 0x75, 0x3c, 0x06, 0x43, 0x98, 0x6c, 0xc3, 0x5a, 0xb5, 0x5f, 0x1f,
+    0x0f, 0x92, 0x44, 0x3b, 0x0e, 0xd4, 0x29, 0x75, 0xe3, 0xdb, 0x36, 0xda, 0xc8, 0x07, 0x97, 0x4d,
+    0xff, 0xbc, 0x6a, 0xa4, 0x8a, 0xef, 0xc4, 0x7f, 0xf8, 0x61, 0x7d, 0x51, 0x4d, 0x2f, 0xdf, 0x7e,
+    0x8c, 0x3d, 0xa3, 0xfc, 0x63, 0xd4, 0xd4, 0x74, 0x8a, 0xc4, 0x14, 0x45, 0x83, 0x6b, 0x12, 0x7e,
+];
+const CODE_HASH_AVB: [u8; HASH_SIZE] = [
+    0xa4, 0x0c, 0xcb, 0xc1, 0xbf, 0xfa, 0xcc, 0xfd, 0xeb, 0xf4, 0xfc, 0x43, 0x83, 0x7f, 0x46, 0x8d,
+    0xd8, 0xd8, 0x14, 0xc1, 0x96, 0x14, 0x1f, 0x6e, 0xb3, 0xa0, 0xd9, 0x56, 0xb3, 0xbf, 0x2f, 0xfa,
+    0x88, 0x70, 0x11, 0x07, 0x39, 0xa4, 0xd2, 0xa9, 0x6b, 0x18, 0x28, 0xe8, 0x29, 0x20, 0x49, 0x0f,
+    0xbb, 0x8d, 0x08, 0x8c, 0xc6, 0x54, 0xe9, 0x71, 0xd2, 0x7e, 0xa4, 0xfe, 0x58, 0x7f, 0xd3, 0xc7,
+];
+const AUTHORITY_HASH_AVB: [u8; HASH_SIZE] = [
+    0xb2, 0x69, 0x05, 0x48, 0x56, 0xb5, 0xfa, 0x55, 0x6f, 0xac, 0x56, 0xd9, 0x02, 0x35, 0x2b, 0xaa,
+    0x4c, 0xba, 0x28, 0xdd, 0x82, 0x3a, 0x86, 0xf5, 0xd4, 0xc2, 0xf1, 0xf9, 0x35, 0x7d, 0xe4, 0x43,
+    0x13, 0xbf, 0xfe, 0xd3, 0x36, 0xd8, 0x1c, 0x12, 0x78, 0x5c, 0x9c, 0x3e, 0xf6, 0x66, 0xef, 0xab,
+    0x3d, 0x0f, 0x89, 0xa4, 0x6f, 0xc9, 0x72, 0xee, 0x73, 0x43, 0x02, 0x8a, 0xef, 0xbc, 0x05, 0x98,
+];
+const HIDDEN_AVB: [u8; HIDDEN_SIZE] = [
+    0x5b, 0x3f, 0xc9, 0x6b, 0xe3, 0x95, 0x59, 0x40, 0x5e, 0x64, 0xe5, 0x64, 0x3f, 0xfd, 0x21, 0x09,
+    0x9d, 0xf3, 0xcd, 0xc7, 0xa4, 0x2a, 0xe2, 0x97, 0xdd, 0xe2, 0x4f, 0xb0, 0x7d, 0x7e, 0xf5, 0x8e,
+    0xd6, 0x4d, 0x84, 0x25, 0x54, 0x41, 0x3f, 0x8f, 0x78, 0x64, 0x1a, 0x51, 0x27, 0x9d, 0x55, 0x8a,
+    0xe9, 0x90, 0x35, 0xab, 0x39, 0x80, 0x4b, 0x94, 0x40, 0x84, 0xa2, 0xfd, 0x73, 0xeb, 0x35, 0x7a,
+];
+const AUTHORITY_HASH_ANDROID: [u8; HASH_SIZE] = [
+    0x04, 0x25, 0x5d, 0x60, 0x5f, 0x5c, 0x45, 0x0d, 0xf2, 0x9a, 0x6e, 0x99, 0x30, 0x03, 0xb8, 0xd6,
+    0xe1, 0x99, 0x71, 0x1b, 0xf8, 0x44, 0xfa, 0xb5, 0x31, 0x79, 0x1c, 0x37, 0x68, 0x4e, 0x1d, 0xc0,
+    0x24, 0x74, 0x68, 0xf8, 0x80, 0x20, 0x3e, 0x44, 0xb1, 0x43, 0xd2, 0x9c, 0xfc, 0x12, 0x9e, 0x77,
+    0x0a, 0xde, 0x29, 0x24, 0xff, 0x2e, 0xfa, 0xc7, 0x10, 0xd5, 0x73, 0xd4, 0xc6, 0xdf, 0x62, 0x9f,
+];
+
+/// Encode the public key to CBOR Value. The input (raw 32 bytes) is wrapped into CoseKey.
+fn ed25519_public_key_to_cbor_value(public_key: &[u8]) -> Value {
+    let key = CoseKey {
+        kty: KeyType::Assigned(iana::KeyType::OKP),
+        alg: Some(Algorithm::Assigned(iana::Algorithm::EdDSA)),
+        key_ops: vec![KeyOperation::Assigned(iana::KeyOperation::Verify)].into_iter().collect(),
+        params: vec![
+            (
+                Label::Int(iana::Ec2KeyParameter::Crv as i64),
+                Value::from(iana::EllipticCurve::Ed25519 as u64),
+            ),
+            (Label::Int(iana::Ec2KeyParameter::X as i64), Value::Bytes(public_key.to_vec())),
+        ],
+        ..Default::default()
+    };
+    key.to_cbor_value().unwrap()
+}
+
+/// Makes a DICE chain (BCC) from the sample input.
+///
+/// The DICE chain is of the following format:
+/// public key derived from UDS -> ABL certificate -> AVB certificate -> Android certificate
+/// The `security_version` is included in the Android certificate.
+pub fn make_explicit_owned_dice(security_version: u64) -> OwnedDiceArtifactsWithExplicitKey {
+    let dice = make_sample_bcc_and_cdis(security_version);
+    OwnedDiceArtifactsWithExplicitKey::from_owned_artifacts(dice).unwrap()
+}
+
+fn make_sample_bcc_and_cdis(security_version: u64) -> OwnedDiceArtifacts {
+    let private_key_seed = derive_cdi_private_key_seed(UDS).unwrap();
+
+    // Gets the root public key in DICE chain (BCC).
+    let (public_key, _) = keypair_from_seed(private_key_seed.as_array()).unwrap();
+    let ed25519_public_key_value = ed25519_public_key_to_cbor_value(&public_key);
+
+    // Gets the ABL certificate to as the root certificate of DICE chain.
+    let config_values = DiceConfigValues {
+        component_name: Some(CStr::from_bytes_with_nul(b"ABL\0").unwrap()),
+        component_version: Some(1),
+        resettable: true,
+        ..Default::default()
+    };
+    let config_descriptor = retry_bcc_format_config_descriptor(&config_values).unwrap();
+    let input_values = InputValues::new(
+        CODE_HASH_ABL,
+        Config::Descriptor(config_descriptor.as_slice()),
+        AUTHORITY_HASH_ABL,
+        DiceMode::kDiceModeNormal,
+        HIDDEN_ABL,
+    );
+    let (cdi_values, cert) = retry_dice_main_flow(UDS, UDS, &input_values).unwrap();
+    let bcc_value =
+        Value::Array(vec![ed25519_public_key_value, de::from_reader(&cert[..]).unwrap()]);
+    let mut bcc: Vec<u8> = vec![];
+    ser::into_writer(&bcc_value, &mut bcc).unwrap();
+
+    // Appends AVB certificate to DICE chain.
+    let config_values = DiceConfigValues {
+        component_name: Some(CStr::from_bytes_with_nul(b"AVB\0").unwrap()),
+        component_version: Some(1),
+        resettable: true,
+        ..Default::default()
+    };
+    let config_descriptor = retry_bcc_format_config_descriptor(&config_values).unwrap();
+    let input_values = InputValues::new(
+        CODE_HASH_AVB,
+        Config::Descriptor(config_descriptor.as_slice()),
+        AUTHORITY_HASH_AVB,
+        DiceMode::kDiceModeNormal,
+        HIDDEN_AVB,
+    );
+    let dice_artifacts =
+        retry_bcc_main_flow(&cdi_values.cdi_attest, &cdi_values.cdi_seal, &bcc, &input_values)
+            .unwrap();
+
+    // Appends Android certificate to DICE chain.
+    let config_values = DiceConfigValues {
+        component_name: Some(CStr::from_bytes_with_nul(b"Android\0").unwrap()),
+        component_version: Some(12),
+        security_version: Some(security_version),
+        resettable: true,
+        ..Default::default()
+    };
+    let config_descriptor = retry_bcc_format_config_descriptor(&config_values).unwrap();
+    let input_values = InputValues::new(
+        [0u8; HASH_SIZE], // code_hash
+        Config::Descriptor(config_descriptor.as_slice()),
+        AUTHORITY_HASH_ANDROID,
+        DiceMode::kDiceModeNormal,
+        [0u8; HIDDEN_SIZE], // hidden
+    );
+    retry_bcc_main_flow(
+        dice_artifacts.cdi_attest(),
+        dice_artifacts.cdi_seal(),
+        dice_artifacts
+            .bcc()
+            .ok_or_else(|| {
+                error!("bcc is none");
+                DiceError::InvalidInput
+            })
+            .unwrap(),
+        &input_values,
+    )
+    .unwrap()
+}
diff --git a/security/secretkeeper/aidl/vts/lib.rs b/security/secretkeeper/aidl/vts/lib.rs
new file mode 100644
index 0000000..9f98165
--- /dev/null
+++ b/security/secretkeeper/aidl/vts/lib.rs
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+//! Test helper functions.
+
+pub mod dice_sample;
+
+// Constants for DICE map keys.
+
+/// Map key for authority hash.
+pub const AUTHORITY_HASH: i64 = -4670549;
+/// Map key for config descriptor.
+pub const CONFIG_DESC: i64 = -4670548;
+/// Map key for component name.
+pub const COMPONENT_NAME: i64 = -70002;
+/// Map key for component version.
+pub const COMPONENT_VERSION: i64 = -70003;
+/// Map key for security version.
+pub const SECURITY_VERSION: i64 = -70005;
+/// Map key for mode.
+pub const MODE: i64 = -4670551;
diff --git a/security/secretkeeper/aidl/vts/secretkeeper_cli.rs b/security/secretkeeper/aidl/vts/secretkeeper_cli.rs
new file mode 100644
index 0000000..5f08482
--- /dev/null
+++ b/security/secretkeeper/aidl/vts/secretkeeper_cli.rs
@@ -0,0 +1,347 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+//! Command line test tool for interacting with Secretkeeper.
+
+use android_hardware_security_secretkeeper::aidl::android::hardware::security::secretkeeper::{
+    ISecretkeeper::ISecretkeeper, SecretId::SecretId,
+};
+use anyhow::{anyhow, bail, Context, Result};
+use authgraph_boringssl::BoringSha256;
+use authgraph_core::traits::Sha256;
+use clap::{Args, Parser, Subcommand};
+use coset::CborSerializable;
+use dice_policy::{ConstraintSpec, ConstraintType, DicePolicy, MissingAction};
+use secretkeeper_client::{dice::OwnedDiceArtifactsWithExplicitKey, SkSession};
+use secretkeeper_comm::data_types::{
+    error::SecretkeeperError,
+    packet::{ResponsePacket, ResponseType},
+    request::Request,
+    request_response_impl::{GetSecretRequest, GetSecretResponse, StoreSecretRequest},
+    response::Response,
+    {Id, Secret},
+};
+use secretkeeper_test::{
+    dice_sample::make_explicit_owned_dice, AUTHORITY_HASH, CONFIG_DESC, MODE, SECURITY_VERSION,
+};
+use std::io::Write;
+
+#[derive(Parser, Debug)]
+#[command(about = "Interact with Secretkeeper HAL")]
+#[command(version = "0.1")]
+#[command(propagate_version = true)]
+struct Cli {
+    #[command(subcommand)]
+    command: Command,
+
+    /// Secretkeeper instance to connect to.
+    #[arg(long, short)]
+    instance: Option<String>,
+
+    /// Security version in leaf DICE node.
+    #[clap(default_value_t = 100)]
+    #[arg(long, short = 'v')]
+    dice_version: u64,
+
+    /// Show hex versions of secrets and their IDs.
+    #[clap(default_value_t = false)]
+    #[arg(long, short = 'v')]
+    hex: bool,
+}
+
+#[derive(Subcommand, Debug)]
+enum Command {
+    /// Store a secret value.
+    Store(StoreArgs),
+    /// Get a secret value.
+    Get(GetArgs),
+    /// Delete a secret value.
+    Delete(DeleteArgs),
+    /// Delete all secret values.
+    DeleteAll(DeleteAllArgs),
+}
+
+#[derive(Args, Debug)]
+struct StoreArgs {
+    /// Identifier for the secret, as either a short (< 32 byte) string, or as 32 bytes of hex.
+    id: String,
+    /// Value to use as the secret value. If specified as 32 bytes of hex, the decoded value
+    /// will be used as-is; otherwise, a string (less than 31 bytes in length) will be encoded
+    /// as the secret.
+    value: String,
+}
+
+#[derive(Args, Debug)]
+struct GetArgs {
+    /// Identifier for the secret, as either a short (< 32 byte) string, or as 32 bytes of hex.
+    id: String,
+}
+
+#[derive(Args, Debug)]
+struct DeleteArgs {
+    /// Identifier for the secret, as either a short (< 32 byte) string, or as 32 bytes of hex.
+    id: String,
+}
+
+#[derive(Args, Debug)]
+struct DeleteAllArgs {
+    /// Confirm deletion of all secrets.
+    yes: bool,
+}
+
+const SECRETKEEPER_SERVICE: &str = "android.hardware.security.secretkeeper.ISecretkeeper";
+
+/// Secretkeeper client information.
+struct SkClient {
+    sk: binder::Strong<dyn ISecretkeeper>,
+    session: SkSession,
+    dice_artifacts: OwnedDiceArtifactsWithExplicitKey,
+}
+
+impl SkClient {
+    fn new(instance: &str, dice_artifacts: OwnedDiceArtifactsWithExplicitKey) -> Self {
+        let sk: binder::Strong<dyn ISecretkeeper> =
+            binder::get_interface(&format!("{SECRETKEEPER_SERVICE}/{instance}")).unwrap();
+        let session = SkSession::new(sk.clone(), &dice_artifacts).unwrap();
+        Self { sk, session, dice_artifacts }
+    }
+
+    fn secret_management_request(&mut self, req_data: &[u8]) -> Result<Vec<u8>> {
+        self.session
+            .secret_management_request(req_data)
+            .map_err(|e| anyhow!("secret management: {e:?}"))
+    }
+
+    /// Construct a sealing policy on the DICE chain with constraints:
+    /// 1. `ExactMatch` on `AUTHORITY_HASH` (non-optional).
+    /// 2. `ExactMatch` on `MODE` (non-optional).
+    /// 3. `GreaterOrEqual` on `SECURITY_VERSION` (optional).
+    fn sealing_policy(&self) -> Result<Vec<u8>> {
+        let dice =
+            self.dice_artifacts.explicit_key_dice_chain().context("extract explicit DICE chain")?;
+
+        let constraint_spec = [
+            ConstraintSpec::new(
+                ConstraintType::ExactMatch,
+                vec![AUTHORITY_HASH],
+                MissingAction::Fail,
+            ),
+            ConstraintSpec::new(ConstraintType::ExactMatch, vec![MODE], MissingAction::Fail),
+            ConstraintSpec::new(
+                ConstraintType::GreaterOrEqual,
+                vec![CONFIG_DESC, SECURITY_VERSION],
+                MissingAction::Ignore,
+            ),
+        ];
+        DicePolicy::from_dice_chain(dice, &constraint_spec)
+            .unwrap()
+            .to_vec()
+            .context("serialize DICE policy")
+    }
+
+    fn store(&mut self, id: &Id, secret: &Secret) -> Result<()> {
+        let store_request = StoreSecretRequest {
+            id: id.clone(),
+            secret: secret.clone(),
+            sealing_policy: self.sealing_policy().context("build sealing policy")?,
+        };
+        let store_request =
+            store_request.serialize_to_packet().to_vec().context("serialize StoreSecretRequest")?;
+
+        let store_response = self.secret_management_request(&store_request)?;
+        let store_response =
+            ResponsePacket::from_slice(&store_response).context("deserialize ResponsePacket")?;
+        let response_type = store_response.response_type().unwrap();
+        if response_type == ResponseType::Success {
+            Ok(())
+        } else {
+            let err = *SecretkeeperError::deserialize_from_packet(store_response).unwrap();
+            Err(anyhow!("STORE failed: {err:?}"))
+        }
+    }
+
+    fn get(&mut self, id: &Id) -> Result<Option<Secret>> {
+        let get_request = GetSecretRequest { id: id.clone(), updated_sealing_policy: None }
+            .serialize_to_packet()
+            .to_vec()
+            .context("serialize GetSecretRequest")?;
+
+        let get_response = self.secret_management_request(&get_request).context("secret mgmt")?;
+        let get_response =
+            ResponsePacket::from_slice(&get_response).context("deserialize ResponsePacket")?;
+
+        if get_response.response_type().unwrap() == ResponseType::Success {
+            let get_response = *GetSecretResponse::deserialize_from_packet(get_response).unwrap();
+            Ok(Some(Secret(get_response.secret.0)))
+        } else {
+            // Only expect a not-found failure.
+            let err = *SecretkeeperError::deserialize_from_packet(get_response).unwrap();
+            if err == SecretkeeperError::EntryNotFound {
+                Ok(None)
+            } else {
+                Err(anyhow!("GET failed: {err:?}"))
+            }
+        }
+    }
+
+    /// Helper method to delete secrets.
+    fn delete(&self, ids: &[&Id]) -> Result<()> {
+        let ids: Vec<SecretId> = ids.iter().map(|id| SecretId { id: id.0 }).collect();
+        self.sk.deleteIds(&ids).context("deleteIds")
+    }
+
+    /// Helper method to delete everything.
+    fn delete_all(&self) -> Result<()> {
+        self.sk.deleteAll().context("deleteAll")
+    }
+}
+
+/// Convert a string input into an `Id`.  Input can be 64 bytes of hex, or a string
+/// that will be hashed to give the `Id` value. Returns the `Id` and a display string.
+fn string_to_id(s: &str, show_hex: bool) -> (Id, String) {
+    if let Ok(data) = hex::decode(s) {
+        if data.len() == 64 {
+            // Assume something that parses as 64 bytes of hex is it.
+            return (Id(data.try_into().unwrap()), s.to_string().to_lowercase());
+        }
+    }
+    // Create a secret ID by repeating the SHA-256 hash of the string twice.
+    let hash = BoringSha256.compute_sha256(s.as_bytes()).unwrap();
+    let mut id = Id([0; 64]);
+    id.0[..32].copy_from_slice(&hash);
+    id.0[32..].copy_from_slice(&hash);
+    if show_hex {
+        let hex_id = hex::encode(&id.0);
+        (id, format!("'{s}' (as {hex_id})"))
+    } else {
+        (id, format!("'{s}'"))
+    }
+}
+
+/// Convert a string input into a `Secret`.  Input can be 32 bytes of hex, or a short string
+/// that will be encoded as the `Secret` value. Returns the `Secret` and a display string.
+fn value_to_secret(s: &str, show_hex: bool) -> Result<(Secret, String)> {
+    if let Ok(data) = hex::decode(s) {
+        if data.len() == 32 {
+            // Assume something that parses as 32 bytes of hex is it.
+            return Ok((Secret(data.try_into().unwrap()), s.to_string().to_lowercase()));
+        }
+    }
+    let data = s.as_bytes();
+    if data.len() > 31 {
+        return Err(anyhow!("secret too long"));
+    }
+    let mut secret = Secret([0; 32]);
+    secret.0[0] = data.len() as u8;
+    secret.0[1..1 + data.len()].copy_from_slice(data);
+    Ok(if show_hex {
+        let hex_secret = hex::encode(&secret.0);
+        (secret, format!("'{s}' (as {hex_secret})"))
+    } else {
+        (secret, format!("'{s}'"))
+    })
+}
+
+/// Convert a `Secret` into a displayable string. If the secret looks like an encoded
+/// string, show that, otherwise show the value in hex.
+fn secret_to_value_display(secret: &Secret, show_hex: bool) -> String {
+    let hex = hex::encode(&secret.0);
+    secret_to_value(secret)
+        .map(|s| if show_hex { format!("'{s}' (from {hex})") } else { format!("'{s}'") })
+        .unwrap_or_else(|_e| format!("{hex}"))
+}
+
+/// Attempt to convert a `Secret` back to a string.
+fn secret_to_value(secret: &Secret) -> Result<String> {
+    let len = secret.0[0] as usize;
+    if len > 31 {
+        return Err(anyhow!("too long"));
+    }
+    std::str::from_utf8(&secret.0[1..1 + len]).map(|s| s.to_string()).context("not UTF-8 string")
+}
+
+fn main() -> Result<()> {
+    let cli = Cli::parse();
+
+    // Figure out which Secretkeeper instance is desired, and connect to it.
+    let instance = if let Some(instance) = &cli.instance {
+        // Explicitly specified.
+        instance.clone()
+    } else {
+        // If there's only one instance, use that.
+        let instances: Vec<String> = binder::get_declared_instances(SECRETKEEPER_SERVICE)
+            .unwrap_or_default()
+            .into_iter()
+            .collect();
+        match instances.len() {
+            0 => bail!("No Secretkeeper instances available on device!"),
+            1 => instances[0].clone(),
+            _ => {
+                bail!(
+                    concat!(
+                        "Multiple Secretkeeper instances available on device: {}\n",
+                        "Use --instance <instance> to specify one."
+                    ),
+                    instances.join(", ")
+                );
+            }
+        }
+    };
+    let dice = make_explicit_owned_dice(cli.dice_version);
+    let mut sk_client = SkClient::new(&instance, dice);
+
+    match cli.command {
+        Command::Get(args) => {
+            let (id, display_id) = string_to_id(&args.id, cli.hex);
+            print!("GET key {display_id}: ");
+            match sk_client.get(&id).context("GET") {
+                Ok(None) => println!("not found"),
+                Ok(Some(s)) => println!("{}", secret_to_value_display(&s, cli.hex)),
+                Err(e) => {
+                    println!("failed!");
+                    return Err(e);
+                }
+            }
+        }
+        Command::Store(args) => {
+            let (id, display_id) = string_to_id(&args.id, cli.hex);
+            let (secret, display_secret) = value_to_secret(&args.value, cli.hex)?;
+            println!("STORE key {display_id}: {display_secret}");
+            sk_client.store(&id, &secret).context("STORE")?;
+        }
+        Command::Delete(args) => {
+            let (id, display_id) = string_to_id(&args.id, cli.hex);
+            println!("DELETE key {display_id}");
+            sk_client.delete(&[&id]).context("DELETE")?;
+        }
+        Command::DeleteAll(args) => {
+            if !args.yes {
+                // Request confirmation.
+                println!("Confirm delete all secrets: [y/N]");
+                let _ = std::io::stdout().flush();
+                let mut input = String::new();
+                std::io::stdin().read_line(&mut input)?;
+                let c = input.chars().next();
+                if c != Some('y') && c != Some('Y') {
+                    bail!("DELETE_ALL not confirmed");
+                }
+            }
+            println!("DELETE_ALL");
+            sk_client.delete_all().context("DELETE_ALL")?;
+        }
+    }
+    Ok(())
+}
diff --git a/security/secretkeeper/aidl/vts/secretkeeper_test_client.rs b/security/secretkeeper/aidl/vts/secretkeeper_test_client.rs
index eeef6fc..8c33f04 100644
--- a/security/secretkeeper/aidl/vts/secretkeeper_test_client.rs
+++ b/security/secretkeeper/aidl/vts/secretkeeper_test_client.rs
@@ -14,15 +14,15 @@
  * limitations under the License.
  */
 
-#![cfg(test)]
-
-use rdroidtest_macro::{ignore_if, rdroidtest};
 use android_hardware_security_secretkeeper::aidl::android::hardware::security::secretkeeper::ISecretkeeper::ISecretkeeper;
 use android_hardware_security_secretkeeper::aidl::android::hardware::security::secretkeeper::SecretId::SecretId;
 use authgraph_vts_test as ag_vts;
 use authgraph_boringssl as boring;
 use authgraph_core::key;
 use coset::{CborSerializable, CoseEncrypt0};
+use dice_policy::{ConstraintSpec, ConstraintType, DicePolicy, MissingAction};
+use rdroidtest::{ignore_if, rdroidtest};
+use secretkeeper_client::dice::OwnedDiceArtifactsWithExplicitKey;
 use secretkeeper_client::SkSession;
 use secretkeeper_core::cipher;
 use secretkeeper_comm::data_types::error::SecretkeeperError;
@@ -33,19 +33,14 @@
 use secretkeeper_comm::data_types::{Id, Secret, SeqNum};
 use secretkeeper_comm::data_types::response::Response;
 use secretkeeper_comm::data_types::packet::{ResponsePacket, ResponseType};
+use secretkeeper_test::{
+    AUTHORITY_HASH, MODE, CONFIG_DESC, SECURITY_VERSION,
+    dice_sample::make_explicit_owned_dice
+};
 
 const SECRETKEEPER_SERVICE: &str = "android.hardware.security.secretkeeper.ISecretkeeper";
 const CURRENT_VERSION: u64 = 1;
 
-// TODO(b/291238565): This will change once libdice_policy switches to Explicit-key DiceCertChain
-// This is generated by patching libdice_policy such that it dumps an example dice chain &
-// a policy, such that the former matches the latter.
-const HYPOTHETICAL_DICE_POLICY: [u8; 43] = [
-    0x83, 0x01, 0x81, 0x83, 0x01, 0x80, 0xA1, 0x01, 0x00, 0x82, 0x83, 0x01, 0x81, 0x01, 0x73, 0x74,
-    0x65, 0x73, 0x74, 0x69, 0x6E, 0x67, 0x5F, 0x64, 0x69, 0x63, 0x65, 0x5F, 0x70, 0x6F, 0x6C, 0x69,
-    0x63, 0x79, 0x83, 0x02, 0x82, 0x03, 0x18, 0x64, 0x19, 0xE9, 0x75,
-];
-
 // Random bytes (of ID_SIZE/SECRET_SIZE) generated for tests.
 const ID_EXAMPLE: Id = Id([
     0xF1, 0xB2, 0xED, 0x3B, 0xD1, 0xBD, 0xF0, 0x7D, 0xE1, 0xF0, 0x01, 0xFC, 0x61, 0x71, 0xD3, 0x42,
@@ -88,6 +83,7 @@
 struct SkClient {
     sk: binder::Strong<dyn ISecretkeeper>,
     session: SkSession,
+    dice_artifacts: OwnedDiceArtifactsWithExplicitKey,
 }
 
 impl Drop for SkClient {
@@ -98,15 +94,26 @@
 }
 
 impl SkClient {
+    /// Create an `SkClient` using the default `OwnedDiceArtifactsWithExplicitKey` for identity.
     fn new(instance: &str) -> Self {
+        let default_dice = make_explicit_owned_dice(/*Security version in a node */ 5);
+        Self::with_identity(instance, default_dice)
+    }
+
+    /// Create an `SkClient` using the given `OwnedDiceArtifactsWithExplicitKey` for identity.
+    fn with_identity(instance: &str, dice_artifacts: OwnedDiceArtifactsWithExplicitKey) -> Self {
         let sk = get_connection(instance);
-        Self { sk: sk.clone(), session: SkSession::new(sk).unwrap() }
+        Self {
+            sk: sk.clone(),
+            session: SkSession::new(sk, &dice_artifacts).unwrap(),
+            dice_artifacts,
+        }
     }
 
     /// This method is wrapper that use `SkSession::secret_management_request` which handles
     /// encryption and decryption.
-    fn secret_management_request(&mut self, req_data: &[u8]) -> Vec<u8> {
-        self.session.secret_management_request(req_data).unwrap()
+    fn secret_management_request(&mut self, req_data: &[u8]) -> Result<Vec<u8>, Error> {
+        Ok(self.session.secret_management_request(req_data)?)
     }
 
     /// Unlike the method [`secret_management_request`], this method directly uses
@@ -117,7 +124,7 @@
         req_data: &[u8],
         req_aad: &[u8],
         expected_res_aad: &[u8],
-    ) -> Vec<u8> {
+    ) -> Result<Vec<u8>, Error> {
         let aes_gcm = boring::BoringAes;
         let rng = boring::BoringRng;
         let request_bytes = cipher::encrypt_message(
@@ -128,54 +135,54 @@
             &req_data,
             req_aad,
         )
-        .unwrap();
+        .map_err(|e| secretkeeper_client::Error::CipherError(e))?;
 
         // Binder call!
-        let response_bytes = self.sk.processSecretManagementRequest(&request_bytes).unwrap();
+        let response_bytes = self.sk.processSecretManagementRequest(&request_bytes)?;
 
-        let response_encrypt0 = CoseEncrypt0::from_slice(&response_bytes).unwrap();
-        cipher::decrypt_message(
+        let response_encrypt0 = CoseEncrypt0::from_slice(&response_bytes)?;
+        Ok(cipher::decrypt_message(
             &aes_gcm,
             self.session.decryption_key(),
             &response_encrypt0,
             expected_res_aad,
         )
-        .unwrap()
+        .map_err(|e| secretkeeper_client::Error::CipherError(e))?)
     }
 
-    /// Helper method to store a secret.
-    fn store(&mut self, id: &Id, secret: &Secret) {
-        let store_request = StoreSecretRequest {
-            id: id.clone(),
-            secret: secret.clone(),
-            sealing_policy: HYPOTHETICAL_DICE_POLICY.to_vec(),
-        };
-        let store_request = store_request.serialize_to_packet().to_vec().unwrap();
+    /// Helper method to store a secret. This uses the default compatible sealing_policy on
+    /// dice_chain.
+    fn store(&mut self, id: &Id, secret: &Secret) -> Result<(), Error> {
+        let sealing_policy = sealing_policy(
+            self.dice_artifacts.explicit_key_dice_chain().ok_or(Error::UnexpectedError)?,
+        );
+        let store_request =
+            StoreSecretRequest { id: id.clone(), secret: secret.clone(), sealing_policy };
+        let store_request = store_request.serialize_to_packet().to_vec()?;
 
-        let store_response = self.secret_management_request(&store_request);
-        let store_response = ResponsePacket::from_slice(&store_response).unwrap();
+        let store_response = self.secret_management_request(&store_request)?;
+        let store_response = ResponsePacket::from_slice(&store_response)?;
 
-        assert_eq!(store_response.response_type().unwrap(), ResponseType::Success);
+        assert_eq!(store_response.response_type()?, ResponseType::Success);
         // Really just checking that the response is indeed StoreSecretResponse
-        let _ = StoreSecretResponse::deserialize_from_packet(store_response).unwrap();
+        let _ = StoreSecretResponse::deserialize_from_packet(store_response)?;
+        Ok(())
     }
 
     /// Helper method to get a secret.
-    fn get(&mut self, id: &Id) -> Option<Secret> {
+    fn get(&mut self, id: &Id) -> Result<Secret, Error> {
         let get_request = GetSecretRequest { id: id.clone(), updated_sealing_policy: None };
-        let get_request = get_request.serialize_to_packet().to_vec().unwrap();
+        let get_request = get_request.serialize_to_packet().to_vec()?;
 
-        let get_response = self.secret_management_request(&get_request);
-        let get_response = ResponsePacket::from_slice(&get_response).unwrap();
+        let get_response = self.secret_management_request(&get_request)?;
+        let get_response = ResponsePacket::from_slice(&get_response)?;
 
-        if get_response.response_type().unwrap() == ResponseType::Success {
-            let get_response = *GetSecretResponse::deserialize_from_packet(get_response).unwrap();
-            Some(Secret(get_response.secret.0))
+        if get_response.response_type()? == ResponseType::Success {
+            let get_response = *GetSecretResponse::deserialize_from_packet(get_response)?;
+            Ok(Secret(get_response.secret.0))
         } else {
-            // Only expect a not-found failure.
-            let err = *SecretkeeperError::deserialize_from_packet(get_response).unwrap();
-            assert_eq!(err, SecretkeeperError::EntryNotFound);
-            None
+            let err = *SecretkeeperError::deserialize_from_packet(get_response)?;
+            Err(Error::SecretkeeperError(err))
         }
     }
 
@@ -191,6 +198,69 @@
     }
 }
 
+#[derive(Debug)]
+enum Error {
+    // Errors from Secretkeeper API errors. These are thrown by core SecretManagement and
+    // not visible without decryption.
+    SecretkeeperError(SecretkeeperError),
+    InfraError(secretkeeper_client::Error),
+    UnexpectedError,
+}
+
+impl From<secretkeeper_client::Error> for Error {
+    fn from(e: secretkeeper_client::Error) -> Self {
+        Self::InfraError(e)
+    }
+}
+
+impl From<SecretkeeperError> for Error {
+    fn from(e: SecretkeeperError) -> Self {
+        Self::SecretkeeperError(e)
+    }
+}
+
+impl From<coset::CoseError> for Error {
+    fn from(e: coset::CoseError) -> Self {
+        Self::InfraError(secretkeeper_client::Error::from(e))
+    }
+}
+
+impl From<binder::Status> for Error {
+    fn from(s: binder::Status) -> Self {
+        Self::InfraError(secretkeeper_client::Error::from(s))
+    }
+}
+
+impl From<secretkeeper_comm::data_types::error::Error> for Error {
+    fn from(e: secretkeeper_comm::data_types::error::Error) -> Self {
+        Self::InfraError(secretkeeper_client::Error::from(e))
+    }
+}
+
+// Assert that the error is EntryNotFound
+fn assert_entry_not_found(res: Result<Secret, Error>) {
+    assert!(matches!(res.unwrap_err(), Error::SecretkeeperError(SecretkeeperError::EntryNotFound)))
+}
+
+/// Construct a sealing policy on the dice chain. This method uses the following set of
+/// constraints which are compatible with sample DICE chains used in VTS.
+/// 1. ExactMatch on AUTHORITY_HASH (non-optional).
+/// 2. ExactMatch on MODE (non-optional).
+/// 3. GreaterOrEqual on SECURITY_VERSION (optional).
+fn sealing_policy(dice: &[u8]) -> Vec<u8> {
+    let constraint_spec = [
+        ConstraintSpec::new(ConstraintType::ExactMatch, vec![AUTHORITY_HASH], MissingAction::Fail),
+        ConstraintSpec::new(ConstraintType::ExactMatch, vec![MODE], MissingAction::Fail),
+        ConstraintSpec::new(
+            ConstraintType::GreaterOrEqual,
+            vec![CONFIG_DESC, SECURITY_VERSION],
+            MissingAction::Ignore,
+        ),
+    ];
+
+    DicePolicy::from_dice_chain(dice, &constraint_spec).unwrap().to_vec().unwrap()
+}
+
 /// Perform AuthGraph key exchange, returning the session keys and session ID.
 fn authgraph_key_exchange(sk: binder::Strong<dyn ISecretkeeper>) -> ([key::AesKey; 2], Vec<u8>) {
     let sink = sk.getAuthGraphKe().expect("failed to get AuthGraph");
@@ -237,7 +307,7 @@
     let request_packet = request.serialize_to_packet();
     let request_bytes = request_packet.to_vec().unwrap();
 
-    let response_bytes = sk_client.secret_management_request(&request_bytes);
+    let response_bytes = sk_client.secret_management_request(&request_bytes).unwrap();
 
     let response_packet = ResponsePacket::from_slice(&response_bytes).unwrap();
     assert_eq!(response_packet.response_type().unwrap(), ResponseType::Success);
@@ -257,7 +327,7 @@
     // Deform the request
     request_bytes[0] = !request_bytes[0];
 
-    let response_bytes = sk_client.secret_management_request(&request_bytes);
+    let response_bytes = sk_client.secret_management_request(&request_bytes).unwrap();
 
     let response_packet = ResponsePacket::from_slice(&response_bytes).unwrap();
     assert_eq!(response_packet.response_type().unwrap(), ResponseType::Error);
@@ -269,10 +339,10 @@
 fn secret_management_store_get_secret_found(instance: String) {
     let mut sk_client = SkClient::new(&instance);
 
-    sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE);
+    sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE).unwrap();
 
     // Get the secret that was just stored
-    assert_eq!(sk_client.get(&ID_EXAMPLE), Some(SECRET_EXAMPLE));
+    assert_eq!(sk_client.get(&ID_EXAMPLE).unwrap(), SECRET_EXAMPLE);
 }
 
 #[rdroidtest(get_instances())]
@@ -280,64 +350,63 @@
     let mut sk_client = SkClient::new(&instance);
 
     // Store a secret (corresponding to an id).
-    sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE);
+    sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE).unwrap();
 
     // Get the secret that was never stored
-    assert_eq!(sk_client.get(&ID_NOT_STORED), None);
+    assert_entry_not_found(sk_client.get(&ID_NOT_STORED));
 }
 
 #[rdroidtest(get_instances())]
 fn secretkeeper_store_delete_ids(instance: String) {
     let mut sk_client = SkClient::new(&instance);
 
-    sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE);
-    sk_client.store(&ID_EXAMPLE_2, &SECRET_EXAMPLE);
+    sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE).unwrap();
+    sk_client.store(&ID_EXAMPLE_2, &SECRET_EXAMPLE).unwrap();
     sk_client.delete(&[&ID_EXAMPLE]);
-
-    assert_eq!(sk_client.get(&ID_EXAMPLE), None);
-    assert_eq!(sk_client.get(&ID_EXAMPLE_2), Some(SECRET_EXAMPLE));
+    assert_entry_not_found(sk_client.get(&ID_EXAMPLE));
+    assert_eq!(sk_client.get(&ID_EXAMPLE_2).unwrap(), SECRET_EXAMPLE);
 
     sk_client.delete(&[&ID_EXAMPLE_2]);
 
-    assert_eq!(sk_client.get(&ID_EXAMPLE), None);
-    assert_eq!(sk_client.get(&ID_EXAMPLE_2), None);
+    assert_entry_not_found(sk_client.get(&ID_EXAMPLE));
+    assert_entry_not_found(sk_client.get(&ID_EXAMPLE_2));
 }
 
 #[rdroidtest(get_instances())]
 fn secretkeeper_store_delete_multiple_ids(instance: String) {
     let mut sk_client = SkClient::new(&instance);
 
-    sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE);
-    sk_client.store(&ID_EXAMPLE_2, &SECRET_EXAMPLE);
+    sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE).unwrap();
+    sk_client.store(&ID_EXAMPLE_2, &SECRET_EXAMPLE).unwrap();
     sk_client.delete(&[&ID_EXAMPLE, &ID_EXAMPLE_2]);
 
-    assert_eq!(sk_client.get(&ID_EXAMPLE), None);
-    assert_eq!(sk_client.get(&ID_EXAMPLE_2), None);
+    assert_entry_not_found(sk_client.get(&ID_EXAMPLE));
+    assert_entry_not_found(sk_client.get(&ID_EXAMPLE_2));
 }
 #[rdroidtest(get_instances())]
 fn secretkeeper_store_delete_duplicate_ids(instance: String) {
     let mut sk_client = SkClient::new(&instance);
 
-    sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE);
-    sk_client.store(&ID_EXAMPLE_2, &SECRET_EXAMPLE);
+    sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE).unwrap();
+    sk_client.store(&ID_EXAMPLE_2, &SECRET_EXAMPLE).unwrap();
     // Delete the same secret twice.
     sk_client.delete(&[&ID_EXAMPLE, &ID_EXAMPLE]);
 
-    assert_eq!(sk_client.get(&ID_EXAMPLE), None);
-    assert_eq!(sk_client.get(&ID_EXAMPLE_2), Some(SECRET_EXAMPLE));
+    assert_entry_not_found(sk_client.get(&ID_EXAMPLE));
+    assert_eq!(sk_client.get(&ID_EXAMPLE_2).unwrap(), SECRET_EXAMPLE);
 }
 
 #[rdroidtest(get_instances())]
 fn secretkeeper_store_delete_nonexistent(instance: String) {
     let mut sk_client = SkClient::new(&instance);
 
-    sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE);
-    sk_client.store(&ID_EXAMPLE_2, &SECRET_EXAMPLE);
+    sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE).unwrap();
+    sk_client.store(&ID_EXAMPLE_2, &SECRET_EXAMPLE).unwrap();
     sk_client.delete(&[&ID_NOT_STORED]);
 
-    assert_eq!(sk_client.get(&ID_EXAMPLE), Some(SECRET_EXAMPLE));
-    assert_eq!(sk_client.get(&ID_EXAMPLE_2), Some(SECRET_EXAMPLE));
-    assert_eq!(sk_client.get(&ID_NOT_STORED), None);
+    assert_eq!(sk_client.get(&ID_EXAMPLE).unwrap(), SECRET_EXAMPLE);
+    assert_eq!(sk_client.get(&ID_EXAMPLE_2).unwrap(), SECRET_EXAMPLE);
+    assert_entry_not_found(sk_client.get(&ID_NOT_STORED));
 }
 
 // Don't run deleteAll() on a secure device, as it might affect real secrets.
@@ -346,22 +415,22 @@
 fn secretkeeper_store_delete_all(instance: String) {
     let mut sk_client = SkClient::new(&instance);
 
-    sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE);
-    sk_client.store(&ID_EXAMPLE_2, &SECRET_EXAMPLE);
+    sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE).unwrap();
+    sk_client.store(&ID_EXAMPLE_2, &SECRET_EXAMPLE).unwrap();
 
     sk_client.delete_all();
 
-    assert_eq!(sk_client.get(&ID_EXAMPLE), None);
-    assert_eq!(sk_client.get(&ID_EXAMPLE_2), None);
+    assert_entry_not_found(sk_client.get(&ID_EXAMPLE));
+    assert_entry_not_found(sk_client.get(&ID_EXAMPLE_2));
 
     // Store a new secret (corresponding to an id).
-    sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE);
+    sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE).unwrap();
 
     // Get the restored secret.
-    assert_eq!(sk_client.get(&ID_EXAMPLE), Some(SECRET_EXAMPLE));
+    assert_eq!(sk_client.get(&ID_EXAMPLE).unwrap(), SECRET_EXAMPLE);
 
     // (Try to) Get the secret that was never stored
-    assert_eq!(sk_client.get(&ID_NOT_STORED), None);
+    assert_entry_not_found(sk_client.get(&ID_NOT_STORED));
 }
 
 // This test checks that Secretkeeper uses the expected [`RequestSeqNum`] as aad while
@@ -369,9 +438,11 @@
 // first few messages.
 #[rdroidtest(get_instances())]
 fn secret_management_replay_protection_seq_num(instance: String) {
-    let sk_client = SkClient::new(&instance);
+    let dice_chain = make_explicit_owned_dice(/*Security version in a node */ 5);
+    let sealing_policy = sealing_policy(dice_chain.explicit_key_dice_chain().unwrap());
+    let sk_client = SkClient::with_identity(&instance, dice_chain);
     // Construct encoded request packets for the test
-    let (req_1, req_2, req_3) = construct_secret_management_requests();
+    let (req_1, req_2, req_3) = construct_secret_management_requests(sealing_policy);
 
     // Lets now construct the seq_numbers(in request & expected in response)
     let mut seq_a = SeqNum::new();
@@ -379,21 +450,21 @@
 
     // Check first request/response is successful
     let res = ResponsePacket::from_slice(
-        &sk_client.secret_management_request_custom_aad(&req_1, &seq_0, &seq_0),
+        &sk_client.secret_management_request_custom_aad(&req_1, &seq_0, &seq_0).unwrap(),
     )
     .unwrap();
     assert_eq!(res.response_type().unwrap(), ResponseType::Success);
 
     // Check 2nd request/response is successful
     let res = ResponsePacket::from_slice(
-        &sk_client.secret_management_request_custom_aad(&req_2, &seq_1, &seq_1),
+        &sk_client.secret_management_request_custom_aad(&req_2, &seq_1, &seq_1).unwrap(),
     )
     .unwrap();
     assert_eq!(res.response_type().unwrap(), ResponseType::Success);
 
     // Check 3rd request/response is successful
     let res = ResponsePacket::from_slice(
-        &sk_client.secret_management_request_custom_aad(&req_3, &seq_2, &seq_2),
+        &sk_client.secret_management_request_custom_aad(&req_3, &seq_2, &seq_2).unwrap(),
     )
     .unwrap();
     assert_eq!(res.response_type().unwrap(), ResponseType::Success);
@@ -403,17 +474,19 @@
 // for new sessions.
 #[rdroidtest(get_instances())]
 fn secret_management_replay_protection_seq_num_per_session(instance: String) {
-    let sk_client = SkClient::new(&instance);
+    let dice_chain = make_explicit_owned_dice(/*Security version in a node */ 5);
+    let sealing_policy = sealing_policy(dice_chain.explicit_key_dice_chain().unwrap());
+    let sk_client = SkClient::with_identity(&instance, dice_chain);
 
     // Construct encoded request packets for the test
-    let (req_1, _, _) = construct_secret_management_requests();
+    let (req_1, _, _) = construct_secret_management_requests(sealing_policy);
 
     // Lets now construct the seq_number (in request & expected in response)
     let mut seq_a = SeqNum::new();
     let seq_0 = seq_a.get_then_increment().unwrap();
     // Check first request/response is successful
     let res = ResponsePacket::from_slice(
-        &sk_client.secret_management_request_custom_aad(&req_1, &seq_0, &seq_0),
+        &sk_client.secret_management_request_custom_aad(&req_1, &seq_0, &seq_0).unwrap(),
     )
     .unwrap();
     assert_eq!(res.response_type().unwrap(), ResponseType::Success);
@@ -422,7 +495,7 @@
     let sk_client_diff = SkClient::new(&instance);
     // Check first request/response is with seq_0 is successful
     let res = ResponsePacket::from_slice(
-        &sk_client_diff.secret_management_request_custom_aad(&req_1, &seq_0, &seq_0),
+        &sk_client_diff.secret_management_request_custom_aad(&req_1, &seq_0, &seq_0).unwrap(),
     )
     .unwrap();
     assert_eq!(res.response_type().unwrap(), ResponseType::Success);
@@ -431,33 +504,58 @@
 // This test checks that Secretkeeper rejects requests with out of order [`RequestSeqNum`]
 // TODO(b/317416663): This test fails, when HAL is not present in the device. Refactor to fix this.
 #[rdroidtest(get_instances())]
-#[ignore]
 fn secret_management_replay_protection_out_of_seq_req_not_accepted(instance: String) {
-    let sk_client = SkClient::new(&instance);
+    let dice_chain = make_explicit_owned_dice(/*Security version in a node */ 5);
+    let sealing_policy = sealing_policy(dice_chain.explicit_key_dice_chain().unwrap());
+    let sk_client = SkClient::with_identity(&instance, dice_chain);
 
     // Construct encoded request packets for the test
-    let (req_1, req_2, _) = construct_secret_management_requests();
+    let (req_1, req_2, _) = construct_secret_management_requests(sealing_policy);
 
     // Lets now construct the seq_numbers(in request & expected in response)
     let mut seq_a = SeqNum::new();
     let [seq_0, seq_1, seq_2] = std::array::from_fn(|_| seq_a.get_then_increment().unwrap());
 
     // Assume First request/response is successful
-    sk_client.secret_management_request_custom_aad(&req_1, &seq_0, &seq_0);
+    sk_client.secret_management_request_custom_aad(&req_1, &seq_0, &seq_0).unwrap();
 
     // Check 2nd request/response with skipped seq_num in request is a binder error
-    // This should panic!
-    sk_client.secret_management_request_custom_aad(&req_2, /*Skipping seq_1*/ &seq_2, &seq_1);
+    let res = sk_client
+        .secret_management_request_custom_aad(&req_2, /*Skipping seq_1*/ &seq_2, &seq_1);
+    let err = res.expect_err("Out of Seq messages accepted!");
+    // Incorrect sequence numbers lead to failed decryption. The resultant error should be
+    // thrown in clear text & wrapped in Binder errors.
+    assert!(matches!(err, Error::InfraError(secretkeeper_client::Error::BinderStatus(_e))));
 }
 
-fn construct_secret_management_requests() -> (Vec<u8>, Vec<u8>, Vec<u8>) {
+// This test checks DICE policy based access control of Secretkeeper.
+#[rdroidtest(get_instances())]
+fn secret_management_policy_gate(instance: String) {
+    let dice_chain = make_explicit_owned_dice(/*Security version in a node */ 100);
+    let mut sk_client = SkClient::with_identity(&instance, dice_chain);
+    sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE).unwrap();
+
+    // Start a session with higher security_version & get the stored secret.
+    let dice_chain_upgraded = make_explicit_owned_dice(/*Security version in a node */ 101);
+    let mut sk_client_upgraded = SkClient::with_identity(&instance, dice_chain_upgraded);
+    assert_eq!(sk_client_upgraded.get(&ID_EXAMPLE).unwrap(), SECRET_EXAMPLE);
+
+    // Start a session with lower security_version (This should be denied access to the secret).
+    let dice_chain_downgraded = make_explicit_owned_dice(/*Security version in a node */ 99);
+    let mut sk_client_downgraded = SkClient::with_identity(&instance, dice_chain_downgraded);
+    assert!(matches!(
+        sk_client_downgraded.get(&ID_EXAMPLE).unwrap_err(),
+        Error::SecretkeeperError(SecretkeeperError::DicePolicyError)
+    ));
+}
+
+// Helper method that constructs 3 SecretManagement requests. Callers would usually not care about
+// what each of the request concretely is.
+fn construct_secret_management_requests(sealing_policy: Vec<u8>) -> (Vec<u8>, Vec<u8>, Vec<u8>) {
     let version_request = GetVersionRequest {};
     let version_request = version_request.serialize_to_packet().to_vec().unwrap();
-    let store_request = StoreSecretRequest {
-        id: ID_EXAMPLE,
-        secret: SECRET_EXAMPLE,
-        sealing_policy: HYPOTHETICAL_DICE_POLICY.to_vec(),
-    };
+    let store_request =
+        StoreSecretRequest { id: ID_EXAMPLE, secret: SECRET_EXAMPLE, sealing_policy };
     let store_request = store_request.serialize_to_packet().to_vec().unwrap();
     let get_request = GetSecretRequest { id: ID_EXAMPLE, updated_sealing_policy: None };
     let get_request = get_request.serialize_to_packet().to_vec().unwrap();
diff --git a/threadnetwork/aidl/vts/VtsHalThreadNetworkTargetTest.cpp b/threadnetwork/aidl/vts/VtsHalThreadNetworkTargetTest.cpp
index 5925b54..2f71b2f 100644
--- a/threadnetwork/aidl/vts/VtsHalThreadNetworkTargetTest.cpp
+++ b/threadnetwork/aidl/vts/VtsHalThreadNetworkTargetTest.cpp
@@ -87,11 +87,16 @@
 }
 
 TEST_P(ThreadNetworkAidl, Reset) {
+    ndk::ScopedAStatus status;
     std::shared_ptr<ThreadChipCallback> callback =
             ndk::SharedRefBase::make<ThreadChipCallback>([](auto /* data */) {});
 
     EXPECT_TRUE(thread_chip->open(callback).isOk());
-    EXPECT_TRUE(thread_chip->hardwareReset().isOk());
+    status = thread_chip->hardwareReset();
+    EXPECT_TRUE(status.isOk() || (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION));
+    if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
+        GTEST_SKIP() << "Hardware reset is not supported";
+    }
 }
 
 TEST_P(ThreadNetworkAidl, SendSpinelFrame) {
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 1ea1237..f09a26b 100644
--- a/wifi/aidl/vts/functional/wifi_sta_iface_aidl_test.cpp
+++ b/wifi/aidl/vts/functional/wifi_sta_iface_aidl_test.cpp
@@ -69,18 +69,9 @@
 
     std::shared_ptr<IWifiStaIface> wifi_sta_iface_;
 
-    // Checks if the MdnsOffloadManagerService is installed.
-    bool isMdnsOffloadServicePresent() {
-        int status =
-                // --query-flags MATCH_SYSTEM_ONLY(1048576) will only return matched service
-                // installed on system or system_ext partition. The MdnsOffloadManagerService should
-                // be installed on system_ext partition.
-                // NOLINTNEXTLINE(cert-env33-c)
-                system("pm query-services --query-flags 1048576"
-                       " com.android.tv.mdnsoffloadmanager/"
-                       "com.android.tv.mdnsoffloadmanager.MdnsOffloadManagerService"
-                       " | egrep -q mdnsoffloadmanager");
-        return status == 0;
+    // Checks if the mDNS Offload is supported by any NIC.
+    bool isMdnsOffloadPresentInNIC() {
+        return testing::deviceSupportsFeature("android.hardware.mdns_offload");
     }
 
     // Detected panel TV device by using ro.oem.key1 property.
@@ -146,7 +137,7 @@
 TEST_P(WifiStaIfaceAidlTest, CheckApfIsSupported) {
     // Flat panel TV devices that support MDNS offload do not have to implement APF if the WiFi
     // chipset does not have sufficient RAM to do so.
-    if (isPanelTvDevice() && isMdnsOffloadServicePresent()) {
+    if (isPanelTvDevice() && isMdnsOffloadPresentInNIC()) {
         GTEST_SKIP() << "Panel TV supports mDNS offload. It is not required to support APF";
     }
     int vendor_api_level = property_get_int32("ro.vendor.api_level", 0);
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl
index 05a7548..0b068e0 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl
@@ -35,7 +35,13 @@
 @VintfStability
 interface ISupplicantP2pIface {
   void addBonjourService(in byte[] query, in byte[] response);
+  /**
+   * @deprecated This method is deprecated from AIDL v3, newer HALs should use createGroupOwner.
+   */
   void addGroup(in boolean persistent, in int persistentNetworkId);
+  /**
+   * @deprecated This method is deprecated from AIDL v3, newer HALs should use addGroupWithConfigurationParams.
+   */
   void addGroupWithConfig(in byte[] ssid, in String pskPassphrase, in boolean persistent, in int freq, in byte[] peerAddress, in boolean joinExistingGroup);
   @PropagateAllowBlocking android.hardware.wifi.supplicant.ISupplicantP2pNetwork addNetwork();
   void addUpnpService(in int version, in String serviceName);
@@ -115,4 +121,6 @@
   String connectWithParams(in android.hardware.wifi.supplicant.P2pConnectInfo connectInfo);
   void findWithParams(in android.hardware.wifi.supplicant.P2pDiscoveryInfo discoveryInfo);
   void configureExtListenWithParams(in android.hardware.wifi.supplicant.P2pExtListenInfo extListenInfo);
+  void addGroupWithConfigurationParams(in android.hardware.wifi.supplicant.P2pAddGroupConfigurationParams groupConfigurationParams);
+  void createGroupOwner(in android.hardware.wifi.supplicant.P2pCreateGroupOwnerInfo groupOwnerInfo);
 }
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
index 4811565..65ad4c1 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
@@ -41,11 +41,17 @@
   oneway void onDeviceLost(in byte[] p2pDeviceAddress);
   oneway void onFindStopped();
   oneway void onGoNegotiationCompleted(in android.hardware.wifi.supplicant.P2pStatusCode status);
+  /**
+   * @deprecated This method is deprecated from AIDL v3, newer HALs should use onGoNegotiationRequestWithParams.
+   */
   oneway void onGoNegotiationRequest(in byte[] srcAddress, in android.hardware.wifi.supplicant.WpsDevPasswordId passwordId);
   oneway void onGroupFormationFailure(in String failureReason);
   oneway void onGroupFormationSuccess();
   oneway void onGroupRemoved(in String groupIfname, in boolean isGroupOwner);
   oneway void onGroupStarted(in String groupIfname, in boolean isGroupOwner, in byte[] ssid, in int frequency, in byte[] psk, in String passphrase, in byte[] goDeviceAddress, in boolean isPersistent);
+  /**
+   * @deprecated This method is deprecated from AIDL v3, newer HALs should use onInvitationReceivedWithParams.
+   */
   oneway void onInvitationReceived(in byte[] srcAddress, in byte[] goDeviceAddress, in byte[] bssid, in int persistentNetworkId, in int operatingFrequency);
   oneway void onInvitationResult(in byte[] bssid, in android.hardware.wifi.supplicant.P2pStatusCode status);
   /**
@@ -72,4 +78,6 @@
   oneway void onPeerClientDisconnected(in android.hardware.wifi.supplicant.P2pPeerClientDisconnectedEventParams clientDisconnectedEventParams);
   oneway void onProvisionDiscoveryCompletedEvent(in android.hardware.wifi.supplicant.P2pProvisionDiscoveryCompletedEventParams provisionDiscoveryCompletedEventParams);
   oneway void onDeviceFoundWithParams(in android.hardware.wifi.supplicant.P2pDeviceFoundEventParams deviceFoundEventParams);
+  oneway void onGoNegotiationRequestWithParams(in android.hardware.wifi.supplicant.P2pGoNegotiationReqEventParams params);
+  oneway void onInvitationReceivedWithParams(in android.hardware.wifi.supplicant.P2pInvitationEventParams params);
 }
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/KeyMgmtMask.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/KeyMgmtMask.aidl
index 35d51bc..06c22cb 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/KeyMgmtMask.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/KeyMgmtMask.aidl
@@ -51,4 +51,5 @@
   WAPI_CERT = (1 << 13) /* 8192 */,
   FILS_SHA256 = (1 << 18) /* 262144 */,
   FILS_SHA384 = (1 << 19) /* 524288 */,
+  PASN = (1 << 25) /* 33554432 */,
 }
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pAddGroupConfigurationParams.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pAddGroupConfigurationParams.aidl
new file mode 100644
index 0000000..ff73f84
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pAddGroupConfigurationParams.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2024 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@VintfStability
+parcelable P2pAddGroupConfigurationParams {
+  byte[] ssid;
+  String passphrase;
+  boolean isPersistent;
+  int frequencyMHzOrBand;
+  byte[6] goInterfaceAddress;
+  boolean joinExistingGroup;
+  int keyMgmtMask;
+  @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pCreateGroupOwnerInfo.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pCreateGroupOwnerInfo.aidl
new file mode 100644
index 0000000..4451fb5
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pCreateGroupOwnerInfo.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2024 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@VintfStability
+parcelable P2pCreateGroupOwnerInfo {
+  boolean persistent;
+  int persistentNetworkId;
+  @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pGoNegotiationReqEventParams.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pGoNegotiationReqEventParams.aidl
new file mode 100644
index 0000000..ba10b3e
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pGoNegotiationReqEventParams.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2024 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@VintfStability
+parcelable P2pGoNegotiationReqEventParams {
+  byte[6] srcAddress;
+  android.hardware.wifi.supplicant.WpsDevPasswordId passwordId;
+  @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pInvitationEventParams.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pInvitationEventParams.aidl
new file mode 100644
index 0000000..541ee4f
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pInvitationEventParams.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2024 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@VintfStability
+parcelable P2pInvitationEventParams {
+  byte[6] srcAddress;
+  byte[6] goDeviceAddress;
+  byte[6] bssid;
+  int persistentNetworkId;
+  int operatingFrequencyMHz;
+  @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl
index 8b78a4a..1230793 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl
@@ -22,7 +22,9 @@
 import android.hardware.wifi.supplicant.ISupplicantP2pNetwork;
 import android.hardware.wifi.supplicant.IfaceType;
 import android.hardware.wifi.supplicant.MiracastMode;
+import android.hardware.wifi.supplicant.P2pAddGroupConfigurationParams;
 import android.hardware.wifi.supplicant.P2pConnectInfo;
+import android.hardware.wifi.supplicant.P2pCreateGroupOwnerInfo;
 import android.hardware.wifi.supplicant.P2pDiscoveryInfo;
 import android.hardware.wifi.supplicant.P2pExtListenInfo;
 import android.hardware.wifi.supplicant.P2pFrameTypeMask;
@@ -52,6 +54,9 @@
      * negotiation with a specific peer). This is also known as autonomous
      * group owner. Optional |persistentNetworkId| may be used to specify
      * restart of a persistent group.
+     * <p>
+     * @deprecated This method is deprecated from AIDL v3, newer HALs should use
+     * createGroupOwner.
      *
      * @param persistent Used to request a persistent group to be formed.
      * @param persistentNetworkId Used to specify the restart of a persistent
@@ -74,6 +79,9 @@
      * whose network name and group owner's MAC address matches the specified SSID
      * and peer address without WPS process. If peerAddress is 00:00:00:00:00:00, the first found
      * group whose network name matches the specified SSID is joined.
+     * <p>
+     * @deprecated This method is deprecated from AIDL v3, newer HALs should use
+     * addGroupWithConfigurationParams.
      *
      * @param ssid The SSID of this group.
      * @param pskPassphrase The passphrase of this group.
@@ -903,4 +911,31 @@
      *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
      */
     void configureExtListenWithParams(in P2pExtListenInfo extListenInfo);
+
+    /**
+     * Set up a P2P group owner or join a group as a group client with the
+     * specified configuration. The group configurations required to establish
+     * a connection(SSID, password, channel, etc) are shared out of band.
+     * So the connection process doesn't require a P2P provision discovery or
+     * invitation message exchange.
+     *
+     * @param groupConfigurationParams Parameters associated with this add group operation.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void addGroupWithConfigurationParams(
+            in P2pAddGroupConfigurationParams groupConfigurationParams);
+
+    /**
+     * Set up a P2P group owner on this device. This is also known as autonomous
+     * group owner. The connection process requires P2P provision discovery
+     * message or invitation message exchange.
+     *
+     * @param groupOwnerInfo Parameters associated with this create group owner operation.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void createGroupOwner(in P2pCreateGroupOwnerInfo groupOwnerInfo);
 }
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
index b9273a8..44a5465 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
@@ -17,8 +17,10 @@
 package android.hardware.wifi.supplicant;
 
 import android.hardware.wifi.supplicant.P2pDeviceFoundEventParams;
+import android.hardware.wifi.supplicant.P2pGoNegotiationReqEventParams;
 import android.hardware.wifi.supplicant.P2pGroupCapabilityMask;
 import android.hardware.wifi.supplicant.P2pGroupStartedEventParams;
+import android.hardware.wifi.supplicant.P2pInvitationEventParams;
 import android.hardware.wifi.supplicant.P2pPeerClientDisconnectedEventParams;
 import android.hardware.wifi.supplicant.P2pPeerClientJoinedEventParams;
 import android.hardware.wifi.supplicant.P2pProvDiscStatusCode;
@@ -88,6 +90,10 @@
      * @param srcAddress MAC address of the device that initiated the GO
      *        negotiation request.
      * @param passwordId Type of password.
+     *
+     * <p>
+     * @deprecated This method is deprecated from AIDL v3, newer HALs should use
+     * onGoNegotiationRequestWithParams.
      */
     void onGoNegotiationRequest(in byte[] srcAddress, in WpsDevPasswordId passwordId);
 
@@ -135,6 +141,9 @@
      * @param bssid Bssid of the group.
      * @param persistentNetworkId Persistent network Id of the group.
      * @param operatingFrequency Frequency on which the invitation was received.
+     * <p>
+     * @deprecated This method is deprecated from AIDL v3, newer HALs should use
+     * onInvitationReceivedWithParams.
      */
     void onInvitationReceived(in byte[] srcAddress, in byte[] goDeviceAddress, in byte[] bssid,
             in int persistentNetworkId, in int operatingFrequency);
@@ -302,4 +311,18 @@
      * @param deviceFoundEventParams Parameters associated with the device found event.
      */
     void onDeviceFoundWithParams(in P2pDeviceFoundEventParams deviceFoundEventParams);
+
+    /**
+     * Used to indicate the reception of a P2P Group Owner negotiation request.
+     *
+     * @param params Parameters associated with the GO negotiation request event.
+     */
+    void onGoNegotiationRequestWithParams(in P2pGoNegotiationReqEventParams params);
+
+    /**
+     * Used to indicate the reception of a P2P invitation.
+     *
+     * @param params Parameters associated with the invitation request event.
+     */
+    void onInvitationReceivedWithParams(in P2pInvitationEventParams params);
 }
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/KeyMgmtMask.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/KeyMgmtMask.aidl
index f0c3345..8758645 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/KeyMgmtMask.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/KeyMgmtMask.aidl
@@ -71,4 +71,8 @@
      * FILS shared key authentication with sha-384
      */
     FILS_SHA384 = 1 << 19,
+    /**
+     * Pre-Association Security Negotiation (PASN) Key management
+     */
+    PASN = 1 << 25,
 }
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pAddGroupConfigurationParams.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pAddGroupConfigurationParams.aidl
new file mode 100644
index 0000000..15f2733
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pAddGroupConfigurationParams.aidl
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2024 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.
+ */
+
+package android.hardware.wifi.supplicant;
+
+import android.hardware.wifi.common.OuiKeyedData;
+import android.hardware.wifi.supplicant.KeyMgmtMask;
+
+/**
+ * Request parameters used for |ISupplicantP2pIface.addGroupWithConfigurationParams|
+ */
+@VintfStability
+parcelable P2pAddGroupConfigurationParams {
+    /** The SSID of the group. */
+    byte[] ssid;
+
+    /** The passphrase used to secure the group. */
+    String passphrase;
+
+    /** Whether this group is persisted. Only applied on the group owner side */
+    boolean isPersistent;
+
+    /**
+     * The required frequency or band of the group.
+     *  Only applied on the group owner side.
+     *  The following values are supported:
+     *      0: automatic channel selection,
+     *      2: for 2.4GHz channels
+     *      5: for 5GHz channels
+     *      6: for 6GHz channels
+     *      specific frequency in MHz, i.e., 2412, 5500, etc.
+     *        If an invalid band or unsupported frequency are specified,
+     *        |ISupplicantP2pIface.addGroupWithConfigurationParams| fails
+     */
+    int frequencyMHzOrBand;
+
+    /**
+     * The MAC Address of the P2P interface of the Peer GO device.
+     *        This field is valid only for the group client side.
+     *        If the MAC is "00:00:00:00:00:00", the device must try to find a peer GO device
+     *        whose network name matches the specified SSID.
+     */
+    byte[6] goInterfaceAddress;
+
+    /*
+     * True if join a group as a group client; false to create a group as a group owner
+     */
+    boolean joinExistingGroup;
+
+    /**
+     * The authentication Key management mask for the connection. Combination of |KeyMgmtMask|
+     * values. The supported authentication key management types are WPA_PSK, SAE and PASN.
+     *
+     */
+    int keyMgmtMask;
+
+    /**
+     * Optional vendor-specific parameters. Null value indicates
+     * that no vendor data is provided.
+     */
+    @nullable OuiKeyedData[] vendorData;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pCreateGroupOwnerInfo.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pCreateGroupOwnerInfo.aidl
new file mode 100644
index 0000000..51e6ed9
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pCreateGroupOwnerInfo.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2024 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.
+ */
+
+package android.hardware.wifi.supplicant;
+
+import android.hardware.wifi.common.OuiKeyedData;
+
+/**
+ * Parameters used for |ISupplicantP2pIface.createGroupOwner|
+ */
+@VintfStability
+parcelable P2pCreateGroupOwnerInfo {
+    /**
+     * Used to request a persistent group to be formed.
+     */
+    boolean persistent;
+
+    /**
+     * Optional parameter. Used to specify the restart of a persistent
+     * group. Set to UINT32_MAX for a non-persistent group.
+     */
+    int persistentNetworkId;
+
+    /**
+     * Optional vendor-specific parameters. Null value indicates
+     * that no vendor data is provided.
+     */
+    @nullable OuiKeyedData[] vendorData;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pGoNegotiationReqEventParams.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pGoNegotiationReqEventParams.aidl
new file mode 100644
index 0000000..3480734
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pGoNegotiationReqEventParams.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2024 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.
+ */
+
+package android.hardware.wifi.supplicant;
+
+import android.hardware.wifi.common.OuiKeyedData;
+import android.hardware.wifi.supplicant.WpsDevPasswordId;
+
+/**
+ * Parameters used for |ISupplicantP2pIfaceCallback.onGoNegotiationRequestWithParams|
+ */
+@VintfStability
+parcelable P2pGoNegotiationReqEventParams {
+    /**
+     * MAC address of the device that sent the Go negotiation request.
+     */
+    byte[6] srcAddress;
+
+    /**
+     * Type of password.
+     */
+    WpsDevPasswordId passwordId;
+
+    /**
+     * Optional vendor-specific parameters. Null value indicates
+     * that no vendor data is provided.
+     */
+    @nullable OuiKeyedData[] vendorData;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pInvitationEventParams.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pInvitationEventParams.aidl
new file mode 100644
index 0000000..4295c40
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pInvitationEventParams.aidl
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2024 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.
+ */
+
+package android.hardware.wifi.supplicant;
+
+import android.hardware.wifi.common.OuiKeyedData;
+
+/**
+ * Parameters used for |ISupplicantP2pIfaceCallback.onInvitationReceivedWithParams|
+ */
+@VintfStability
+parcelable P2pInvitationEventParams {
+    /**
+     * MAC address of the device that sent the invitation.
+     */
+    byte[6] srcAddress;
+
+    /**
+     * P2P device MAC Address of the group owner.
+     */
+    byte[6] goDeviceAddress;
+
+    /**
+     * BSSID of the group.
+     */
+    byte[6] bssid;
+
+    /**
+     * Persistent network ID of the group.
+     */
+    int persistentNetworkId;
+
+    /**
+     * Frequency on which the invitation was received.
+     */
+    int operatingFrequencyMHz;
+
+    /**
+     * Optional vendor-specific parameters. Null value indicates
+     * that no vendor data is provided.
+     */
+    @nullable OuiKeyedData[] vendorData;
+}
diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp b/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp
index 3f96414..2d6823f 100644
--- a/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp
+++ b/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp
@@ -37,8 +37,10 @@
 using aidl::android::hardware::wifi::supplicant::MiracastMode;
 using aidl::android::hardware::wifi::supplicant::P2pDeviceFoundEventParams;
 using aidl::android::hardware::wifi::supplicant::P2pFrameTypeMask;
+using aidl::android::hardware::wifi::supplicant::P2pGoNegotiationReqEventParams;
 using aidl::android::hardware::wifi::supplicant::P2pGroupCapabilityMask;
 using aidl::android::hardware::wifi::supplicant::P2pGroupStartedEventParams;
+using aidl::android::hardware::wifi::supplicant::P2pInvitationEventParams;
 using aidl::android::hardware::wifi::supplicant::P2pPeerClientDisconnectedEventParams;
 using aidl::android::hardware::wifi::supplicant::P2pPeerClientJoinedEventParams;
 using aidl::android::hardware::wifi::supplicant::P2pProvDiscStatusCode;
@@ -204,6 +206,14 @@
             const P2pDeviceFoundEventParams& /* deviceFoundEventParams */) override {
         return ndk::ScopedAStatus::ok();
     }
+    ::ndk::ScopedAStatus onGoNegotiationRequestWithParams(
+            const P2pGoNegotiationReqEventParams& /* goNegotiationReqEventParams */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onInvitationReceivedWithParams(
+            const P2pInvitationEventParams& /* invitationEventParams */) override {
+        return ndk::ScopedAStatus::ok();
+    }
 };
 
 class SupplicantP2pIfaceAidlTest : public testing::TestWithParam<std::string> {