Merge 2024-06 Release (ab/AP2A.240605.024) to aosp-main-future

Bug: 343100748
Merged-In: If12d978ee69ee7f087a7e8758513a9c6bacf817f
Change-Id: I65adc22bdfae4793d763db08e65b8a89128c3ce4
diff --git a/audio/6.0/config/api/current.txt b/audio/6.0/config/api/current.txt
index 01db90e..1814b59 100644
--- a/audio/6.0/config/api/current.txt
+++ b/audio/6.0/config/api/current.txt
@@ -116,6 +116,7 @@
     enum_constant public static final audio.policy.configuration.V6_0.AudioFormat AUDIO_FORMAT_APTX_HD;
     enum_constant public static final audio.policy.configuration.V6_0.AudioFormat AUDIO_FORMAT_APTX_TWSP;
     enum_constant public static final audio.policy.configuration.V6_0.AudioFormat AUDIO_FORMAT_CELT;
+    enum_constant public static final audio.policy.configuration.V6_0.AudioFormat AUDIO_FORMAT_DEFAULT;
     enum_constant public static final audio.policy.configuration.V6_0.AudioFormat AUDIO_FORMAT_DOLBY_TRUEHD;
     enum_constant public static final audio.policy.configuration.V6_0.AudioFormat AUDIO_FORMAT_DSD;
     enum_constant public static final audio.policy.configuration.V6_0.AudioFormat AUDIO_FORMAT_DTS;
diff --git a/audio/6.0/config/audio_policy_configuration.xsd b/audio/6.0/config/audio_policy_configuration.xsd
index c2b8c5d..177af16 100644
--- a/audio/6.0/config/audio_policy_configuration.xsd
+++ b/audio/6.0/config/audio_policy_configuration.xsd
@@ -302,6 +302,7 @@
          TODO: generate from hidl to avoid manual sync. -->
     <xs:simpleType name="audioFormat">
         <xs:restriction base="xs:string">
+            <xs:enumeration value="AUDIO_FORMAT_DEFAULT" />
             <xs:enumeration value="AUDIO_FORMAT_PCM_16_BIT" />
             <xs:enumeration value="AUDIO_FORMAT_PCM_8_BIT"/>
             <xs:enumeration value="AUDIO_FORMAT_PCM_32_BIT"/>
diff --git a/audio/aidl/android/hardware/audio/core/stream-out-async-sm.gv b/audio/aidl/android/hardware/audio/core/stream-out-async-sm.gv
index a3f0de9..56b7926 100644
--- a/audio/aidl/android/hardware/audio/core/stream-out-async-sm.gv
+++ b/audio/aidl/android/hardware/audio/core/stream-out-async-sm.gv
@@ -51,9 +51,7 @@
     DRAIN_PAUSED -> DRAINING [label="start"];         // consumer -> active
     DRAIN_PAUSED -> TRANSFER_PAUSED [label="burst"];  // producer -> active
     DRAIN_PAUSED -> IDLE [label="flush"];             // buffer is cleared
-    IDLE -> ERROR [label="←IStreamCallback.onError"];
-    DRAINING -> ERROR [label="←IStreamCallback.onError"];
-    TRANSFERRING -> ERROR [label="←IStreamCallback.onError"];
+    ANY_STATE -> ERROR [label="←IStreamCallback.onError"];
     ANY_STATE -> CLOSED [label="→IStream*.close"];
     CLOSED -> F;
 }
diff --git a/audio/aidl/default/EffectConfig.cpp b/audio/aidl/default/EffectConfig.cpp
index a1fbefa..eb0c015 100644
--- a/audio/aidl/default/EffectConfig.cpp
+++ b/audio/aidl/default/EffectConfig.cpp
@@ -37,7 +37,6 @@
 EffectConfig::EffectConfig(const std::string& file) {
     tinyxml2::XMLDocument doc;
     doc.LoadFile(file.c_str());
-    LOG(DEBUG) << __func__ << " loading " << file;
     // parse the xml file into maps
     if (doc.Error()) {
         LOG(ERROR) << __func__ << " tinyxml2 failed to load " << file
@@ -143,7 +142,7 @@
     std::string name = xml.Attribute("name");
     RETURN_VALUE_IF(name == "", false, "effectsNoName");
 
-    LOG(DEBUG) << __func__ << dump(xml);
+    LOG(VERBOSE) << __func__ << dump(xml);
     struct Library library;
     if (std::strcmp(xml.Name(), "effectProxy") == 0) {
         // proxy lib and uuid
@@ -187,11 +186,11 @@
     }
     RETURN_VALUE_IF((library.uuid == getEffectUuidZero()), false, "invalidUuidAttribute");
 
-    LOG(DEBUG) << __func__ << (isProxy ? " proxy " : library.name) << " : uuid "
-               << ::android::audio::utils::toString(library.uuid)
-               << (library.type.has_value()
-                           ? ::android::audio::utils::toString(library.type.value())
-                           : "");
+    LOG(VERBOSE) << __func__ << (isProxy ? " proxy " : library.name) << " : uuid "
+                 << ::android::audio::utils::toString(library.uuid)
+                 << (library.type.has_value()
+                             ? ::android::audio::utils::toString(library.type.value())
+                             : "");
     return true;
 }
 
@@ -245,7 +244,7 @@
 }
 
 bool EffectConfig::parseProcessing(Processing::Type::Tag typeTag, const tinyxml2::XMLElement& xml) {
-    LOG(DEBUG) << __func__ << dump(xml);
+    LOG(VERBOSE) << __func__ << dump(xml);
     const char* typeStr = xml.Attribute("type");
     auto aidlType = stringToProcessingType(typeTag, typeStr);
     RETURN_VALUE_IF(!aidlType.has_value(), false, "illegalStreamType");
@@ -259,7 +258,6 @@
         }
         RETURN_VALUE_IF(!name, false, "noEffectAttribute");
         mProcessingMap[aidlType.value()].emplace_back(mEffectsMap[name]);
-        LOG(WARNING) << __func__ << " " << typeStr << " : " << name;
     }
     return true;
 }
diff --git a/audio/aidl/default/EffectContext.cpp b/audio/aidl/default/EffectContext.cpp
index 9575790..7b8cfb1 100644
--- a/audio/aidl/default/EffectContext.cpp
+++ b/audio/aidl/default/EffectContext.cpp
@@ -157,7 +157,6 @@
 }
 
 RetCode EffectContext::setCommon(const Parameter::Common& common) {
-    LOG(VERBOSE) << __func__ << common.toString();
     auto& input = common.input;
     auto& output = common.output;
 
@@ -186,7 +185,6 @@
 }
 
 Parameter::Common EffectContext::getCommon() {
-    LOG(VERBOSE) << __func__ << mCommon.toString();
     return mCommon;
 }
 
@@ -241,7 +239,7 @@
         LOG(ERROR) << __func__ << ": wake failure with ret " << ret;
         return RetCode::ERROR_EVENT_FLAG_ERROR;
     }
-    LOG(DEBUG) << __func__ << " : signal client for reopen";
+    LOG(VERBOSE) << __func__ << " : signal client for reopen";
     return RetCode::SUCCESS;
 }
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/EffectFactory.cpp b/audio/aidl/default/EffectFactory.cpp
index 96f13ba..e3894f9 100644
--- a/audio/aidl/default/EffectFactory.cpp
+++ b/audio/aidl/default/EffectFactory.cpp
@@ -43,12 +43,12 @@
 
 Factory::~Factory() {
     if (auto count = mEffectMap.size()) {
-        LOG(ERROR) << __func__ << " remaining " << count
-                   << " effect instances not destroyed indicating resource leak!";
+        LOG(WARNING) << __func__ << " remaining " << count
+                     << " effect instances not destroyed indicating resource leak!";
         for (const auto& it : mEffectMap) {
             if (auto spEffect = it.first.lock()) {
-                LOG(ERROR) << __func__ << " erase remaining instance UUID "
-                           << ::android::audio::utils::toString(it.second.first);
+                LOG(WARNING) << __func__ << " erase remaining instance UUID "
+                             << ::android::audio::utils::toString(it.second.first);
                 destroyEffectImpl_l(spEffect);
             }
         }
@@ -139,15 +139,15 @@
         std::shared_ptr<IEffect> effectSp;
         RETURN_IF_BINDER_EXCEPTION(libInterface->createEffectFunc(&in_impl_uuid, &effectSp));
         if (!effectSp) {
-            LOG(ERROR) << __func__ << ": library created null instance without return error!";
+            LOG(WARNING) << __func__ << ": library created null instance without return error!";
             return ndk::ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED);
         }
         *_aidl_return = effectSp;
         ndk::SpAIBinder effectBinder = effectSp->asBinder();
         AIBinder_setMinSchedulerPolicy(effectBinder.get(), SCHED_NORMAL, ANDROID_PRIORITY_AUDIO);
+        AIBinder_setInheritRt(effectBinder.get(), true);
         mEffectMap[std::weak_ptr<IEffect>(effectSp)] =
                 std::make_pair(in_impl_uuid, std::move(effectBinder));
-        LOG(DEBUG) << __func__ << ": instance " << effectSp.get() << " created successfully";
         return ndk::ScopedAStatus::ok();
     } else {
         LOG(ERROR) << __func__ << ": library doesn't exist";
@@ -192,7 +192,6 @@
 }
 
 ndk::ScopedAStatus Factory::destroyEffect(const std::shared_ptr<IEffect>& in_handle) {
-    LOG(DEBUG) << __func__ << ": instance " << in_handle.get();
     std::lock_guard lg(mMutex);
     ndk::ScopedAStatus status = destroyEffectImpl_l(in_handle);
     // always do the cleanup
@@ -215,8 +214,8 @@
         return false;
     }
 
-    LOG(INFO) << __func__ << " dlopen lib:" << path
-              << "\nimpl:" << ::android::audio::utils::toString(impl) << "\nhandle:" << libHandle;
+    LOG(DEBUG) << __func__ << " dlopen lib: " << path
+               << "\nimpl:" << ::android::audio::utils::toString(impl) << "\nhandle:" << libHandle;
     auto interface = new effect_dl_interface_s{nullptr, nullptr, nullptr};
     mEffectLibMap.insert(
             {impl,
@@ -235,11 +234,12 @@
         id.type = typeUuid;
         id.uuid = configLib.uuid;
         id.proxy = proxyUuid;
-        LOG(DEBUG) << __func__ << " loading lib " << path->second << ": typeUuid "
-                   << ::android::audio::utils::toString(id.type) << "\nimplUuid "
-                   << ::android::audio::utils::toString(id.uuid) << " proxyUuid "
-                   << (proxyUuid.has_value() ? ::android::audio::utils::toString(proxyUuid.value())
-                                             : "null");
+        LOG(WARNING) << __func__ << " loading lib " << path->second << ": typeUuid "
+                     << ::android::audio::utils::toString(id.type) << "\nimplUuid "
+                     << ::android::audio::utils::toString(id.uuid) << " proxyUuid "
+                     << (proxyUuid.has_value()
+                                 ? ::android::audio::utils::toString(proxyUuid.value())
+                                 : "null");
         if (openEffectLibrary(id.uuid, path->second)) {
             mIdentitySet.insert(std::move(id));
         }
@@ -263,8 +263,8 @@
                 createIdentityWithConfig(configLib, type, proxyUuid);
             }
         } else {
-            LOG(ERROR) << __func__ << ": can not find type UUID for effect " << configEffects.first
-                       << " skipping!";
+            LOG(WARNING) << __func__ << ": can not find type UUID for effect "
+                         << configEffects.first << " skipping!";
         }
     }
 }
diff --git a/audio/aidl/default/EffectImpl.cpp b/audio/aidl/default/EffectImpl.cpp
index 4d7b980..7192d97 100644
--- a/audio/aidl/default/EffectImpl.cpp
+++ b/audio/aidl/default/EffectImpl.cpp
@@ -23,6 +23,9 @@
 #include "include/effect-impl/EffectTypes.h"
 
 using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::kEventFlagDataMqNotEmpty;
+using aidl::android::hardware::audio::effect::kEventFlagNotEmpty;
+using aidl::android::hardware::audio::effect::kReopenSupportedVersion;
 using aidl::android::hardware::audio::effect::State;
 using aidl::android::media::audio::common::PcmType;
 using ::android::hardware::EventFlag;
@@ -35,7 +38,6 @@
                    << " in state: " << toString(state) << ", status: " << status.getDescription();
         return EX_ILLEGAL_STATE;
     }
-    LOG(DEBUG) << __func__ << " instance " << instanceSp.get() << " destroyed";
     return EX_NONE;
 }
 
@@ -44,7 +46,6 @@
 ndk::ScopedAStatus EffectImpl::open(const Parameter::Common& common,
                                     const std::optional<Parameter::Specific>& specific,
                                     OpenEffectReturn* ret) {
-    LOG(DEBUG) << getEffectName() << __func__;
     // effect only support 32bits float
     RETURN_IF(common.input.base.format.pcm != common.output.base.format.pcm ||
                       common.input.base.format.pcm != PcmType::FLOAT_32_BIT,
@@ -55,11 +56,12 @@
     mImplContext = createContext(common);
     RETURN_IF(!mImplContext, EX_NULL_POINTER, "nullContext");
 
-    int version = 0;
-    RETURN_IF(!getInterfaceVersion(&version).isOk(), EX_UNSUPPORTED_OPERATION,
+    RETURN_IF(!getInterfaceVersion(&mVersion).isOk(), EX_UNSUPPORTED_OPERATION,
               "FailedToGetInterfaceVersion");
-    mImplContext->setVersion(version);
+    mImplContext->setVersion(mVersion);
     mEventFlag = mImplContext->getStatusEventFlag();
+    mDataMqNotEmptyEf =
+            mVersion >= kReopenSupportedVersion ? kEventFlagDataMqNotEmpty : kEventFlagNotEmpty;
 
     if (specific.has_value()) {
         RETURN_IF_ASTATUS_NOT_OK(setParameterSpecific(specific.value()), "setSpecParamErr");
@@ -67,8 +69,9 @@
 
     mState = State::IDLE;
     mImplContext->dupeFmq(ret);
-    RETURN_IF(createThread(getEffectName()) != RetCode::SUCCESS, EX_UNSUPPORTED_OPERATION,
-              "FailedToCreateWorker");
+    RETURN_IF(createThread(getEffectNameWithVersion()) != RetCode::SUCCESS,
+              EX_UNSUPPORTED_OPERATION, "FailedToCreateWorker");
+    LOG(INFO) << getEffectNameWithVersion() << __func__;
     return ndk::ScopedAStatus::ok();
 }
 
@@ -90,8 +93,8 @@
         mState = State::INIT;
     }
 
-    RETURN_IF(notifyEventFlag(kEventFlagNotEmpty) != RetCode::SUCCESS, EX_ILLEGAL_STATE,
-              "notifyEventFlagFailed");
+    RETURN_IF(notifyEventFlag(mDataMqNotEmptyEf) != RetCode::SUCCESS, EX_ILLEGAL_STATE,
+              "notifyEventFlagNotEmptyFailed");
     // stop the worker thread, ignore the return code
     RETURN_IF(destroyThread() != RetCode::SUCCESS, EX_UNSUPPORTED_OPERATION,
               "FailedToDestroyWorker");
@@ -102,13 +105,13 @@
         mImplContext.reset();
     }
 
-    LOG(DEBUG) << getEffectName() << __func__;
+    LOG(INFO) << getEffectNameWithVersion() << __func__;
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus EffectImpl::setParameter(const Parameter& param) {
     std::lock_guard lg(mImplMutex);
-    LOG(VERBOSE) << getEffectName() << __func__ << " with: " << param.toString();
+    LOG(VERBOSE) << getEffectNameWithVersion() << __func__ << " with: " << param.toString();
 
     const auto& tag = param.getTag();
     switch (tag) {
@@ -123,7 +126,7 @@
             return setParameterSpecific(param.get<Parameter::specific>());
         }
         default: {
-            LOG(ERROR) << getEffectName() << __func__ << " unsupportedParameterTag "
+            LOG(ERROR) << getEffectNameWithVersion() << __func__ << " unsupportedParameterTag "
                        << toString(tag);
             return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
                                                                     "ParameterNotSupported");
@@ -148,7 +151,7 @@
             break;
         }
     }
-    LOG(VERBOSE) << getEffectName() << __func__ << id.toString() << param->toString();
+    LOG(VERBOSE) << getEffectNameWithVersion() << __func__ << id.toString() << param->toString();
     return ndk::ScopedAStatus::ok();
 }
 
@@ -181,7 +184,7 @@
                       EX_ILLEGAL_ARGUMENT, "setVolumeStereoFailed");
             break;
         default: {
-            LOG(ERROR) << getEffectName() << __func__ << " unsupportedParameterTag "
+            LOG(ERROR) << getEffectNameWithVersion() << __func__ << " unsupportedParameterTag "
                        << toString(tag);
             return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
                                                                     "commonParamNotSupported");
@@ -215,7 +218,8 @@
             break;
         }
         default: {
-            LOG(DEBUG) << getEffectName() << __func__ << " unsupported tag " << toString(tag);
+            LOG(DEBUG) << getEffectNameWithVersion() << __func__ << " unsupported tag "
+                       << toString(tag);
             return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
                                                                     "tagNotSupported");
         }
@@ -231,33 +235,32 @@
 ndk::ScopedAStatus EffectImpl::command(CommandId command) {
     std::lock_guard lg(mImplMutex);
     RETURN_IF(mState == State::INIT, EX_ILLEGAL_STATE, "instanceNotOpen");
-    LOG(DEBUG) << getEffectName() << __func__ << ": receive command: " << toString(command)
-               << " at state " << toString(mState);
 
     switch (command) {
         case CommandId::START:
             RETURN_OK_IF(mState == State::PROCESSING);
             RETURN_IF_ASTATUS_NOT_OK(commandImpl(command), "commandImplFailed");
             mState = State::PROCESSING;
-            RETURN_IF(notifyEventFlag(kEventFlagNotEmpty) != RetCode::SUCCESS, EX_ILLEGAL_STATE,
-                      "notifyEventFlagFailed");
+            RETURN_IF(notifyEventFlag(mDataMqNotEmptyEf) != RetCode::SUCCESS, EX_ILLEGAL_STATE,
+                      "notifyEventFlagNotEmptyFailed");
             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");
+            RETURN_IF(notifyEventFlag(mDataMqNotEmptyEf) != RetCode::SUCCESS, EX_ILLEGAL_STATE,
+                      "notifyEventFlagNotEmptyFailed");
             stopThread();
             RETURN_IF_ASTATUS_NOT_OK(commandImpl(command), "commandImplFailed");
             break;
         default:
-            LOG(ERROR) << getEffectName() << __func__ << " instance still processing";
+            LOG(ERROR) << getEffectNameWithVersion() << __func__ << " instance still processing";
             return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
                                                                     "CommandIdNotSupported");
     }
-    LOG(DEBUG) << getEffectName() << __func__ << " transfer to state: " << toString(mState);
+    LOG(VERBOSE) << getEffectNameWithVersion() << __func__
+                 << " transfer to state: " << toString(mState);
     return ndk::ScopedAStatus::ok();
 }
 
@@ -287,13 +290,14 @@
 
 RetCode EffectImpl::notifyEventFlag(uint32_t flag) {
     if (!mEventFlag) {
-        LOG(ERROR) << getEffectName() << __func__ << ": StatusEventFlag invalid";
+        LOG(ERROR) << getEffectNameWithVersion() << __func__ << ": StatusEventFlag invalid";
         return RetCode::ERROR_EVENT_FLAG_ERROR;
     }
     if (const auto ret = mEventFlag->wake(flag); ret != ::android::OK) {
-        LOG(ERROR) << getEffectName() << __func__ << ": wake failure with ret " << ret;
+        LOG(ERROR) << getEffectNameWithVersion() << __func__ << ": wake failure with ret " << ret;
         return RetCode::ERROR_EVENT_FLAG_ERROR;
     }
+    LOG(VERBOSE) << getEffectNameWithVersion() << __func__ << ": " << std::hex << mEventFlag;
     return RetCode::SUCCESS;
 }
 
@@ -306,17 +310,17 @@
 }
 
 void EffectImpl::process() {
-    ATRACE_CALL();
+    ATRACE_NAME(getEffectNameWithVersion().c_str());
     /**
      * wait for the EventFlag without lock, it's ok because the mEfGroup pointer will not change
      * in the life cycle of workerThread (threadLoop).
      */
     uint32_t efState = 0;
     if (!mEventFlag ||
-        ::android::OK != mEventFlag->wait(kEventFlagNotEmpty, &efState, 0 /* no timeout */,
+        ::android::OK != mEventFlag->wait(mDataMqNotEmptyEf, &efState, 0 /* no timeout */,
                                           true /* retry */) ||
-        !(efState & kEventFlagNotEmpty)) {
-        LOG(ERROR) << getEffectName() << __func__ << ": StatusEventFlag - " << mEventFlag
+        !(efState & mDataMqNotEmptyEf)) {
+        LOG(ERROR) << getEffectNameWithVersion() << __func__ << ": StatusEventFlag - " << mEventFlag
                    << " efState - " << std::hex << efState;
         return;
     }
@@ -324,7 +328,8 @@
     {
         std::lock_guard lg(mImplMutex);
         if (mState != State::PROCESSING) {
-            LOG(DEBUG) << getEffectName() << " skip process in state: " << toString(mState);
+            LOG(DEBUG) << getEffectNameWithVersion()
+                       << " skip process in state: " << toString(mState);
             return;
         }
         RETURN_VALUE_IF(!mImplContext, void(), "nullContext");
@@ -344,8 +349,6 @@
             IEffect::Status status = effectProcessImpl(buffer, buffer, processSamples);
             outputMQ->write(buffer, status.fmqProduced);
             statusMQ->writeBlocking(&status, 1);
-            LOG(VERBOSE) << getEffectName() << __func__ << ": done processing, effect consumed "
-                         << status.fmqConsumed << " produced " << status.fmqProduced;
         }
     }
 }
@@ -355,7 +358,6 @@
     for (int i = 0; i < samples; i++) {
         *out++ = *in++;
     }
-    LOG(VERBOSE) << getEffectName() << __func__ << " done processing " << samples << " samples";
     return {STATUS_OK, samples, samples};
 }
 
diff --git a/audio/aidl/default/EffectThread.cpp b/audio/aidl/default/EffectThread.cpp
index fdd4803..b515385 100644
--- a/audio/aidl/default/EffectThread.cpp
+++ b/audio/aidl/default/EffectThread.cpp
@@ -27,13 +27,8 @@
 
 namespace aidl::android::hardware::audio::effect {
 
-EffectThread::EffectThread() {
-    LOG(DEBUG) << __func__;
-}
-
 EffectThread::~EffectThread() {
     destroyThread();
-    LOG(DEBUG) << __func__ << " done";
 }
 
 RetCode EffectThread::createThread(const std::string& name, int priority) {
@@ -51,7 +46,7 @@
     }
 
     mThread = std::thread(&EffectThread::threadLoop, this);
-    LOG(DEBUG) << mName << __func__ << " priority " << mPriority << " done";
+    LOG(VERBOSE) << mName << __func__ << " priority " << mPriority << " done";
     return RetCode::SUCCESS;
 }
 
@@ -66,7 +61,7 @@
         mThread.join();
     }
 
-    LOG(DEBUG) << mName << __func__;
+    LOG(VERBOSE) << mName << __func__;
     return RetCode::SUCCESS;
 }
 
@@ -77,7 +72,7 @@
         mCv.notify_one();
     }
 
-    LOG(DEBUG) << mName << __func__;
+    LOG(VERBOSE) << mName << __func__;
     return RetCode::SUCCESS;
 }
 
@@ -88,7 +83,7 @@
         mCv.notify_one();
     }
 
-    LOG(DEBUG) << mName << __func__;
+    LOG(VERBOSE) << mName << __func__;
     return RetCode::SUCCESS;
 }
 
@@ -101,7 +96,7 @@
             ::android::base::ScopedLockAssertion lock_assertion(mThreadMutex);
             mCv.wait(l, [&]() REQUIRES(mThreadMutex) { return mExit || !mStop; });
             if (mExit) {
-                LOG(INFO) << __func__ << " EXIT!";
+                LOG(VERBOSE) << mName << " threadLoop EXIT!";
                 return;
             }
         }
diff --git a/audio/aidl/default/Module.cpp b/audio/aidl/default/Module.cpp
index 94aa4dc..0d6151e 100644
--- a/audio/aidl/default/Module.cpp
+++ b/audio/aidl/default/Module.cpp
@@ -173,7 +173,8 @@
         std::shared_ptr<IStreamCallback> asyncCallback,
         std::shared_ptr<IStreamOutEventCallback> outEventCallback, StreamContext* out_context) {
     if (in_bufferSizeFrames <= 0) {
-        LOG(ERROR) << __func__ << ": non-positive buffer size " << in_bufferSizeFrames;
+        LOG(ERROR) << __func__ << ": " << mType << ": non-positive buffer size "
+                   << in_bufferSizeFrames;
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
     }
     auto& configs = getConfig().portConfigs;
@@ -184,20 +185,21 @@
     const int32_t minimumStreamBufferSizeFrames =
             calculateBufferSizeFrames(nominalLatencyMs, portConfigIt->sampleRate.value().value);
     if (in_bufferSizeFrames < minimumStreamBufferSizeFrames) {
-        LOG(ERROR) << __func__ << ": insufficient buffer size " << in_bufferSizeFrames
-                   << ", must be at least " << minimumStreamBufferSizeFrames;
+        LOG(ERROR) << __func__ << ": " << mType << ": insufficient buffer size "
+                   << in_bufferSizeFrames << ", must be at least " << minimumStreamBufferSizeFrames;
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
     }
     const size_t frameSize =
             getFrameSizeInBytes(portConfigIt->format.value(), portConfigIt->channelMask.value());
     if (frameSize == 0) {
-        LOG(ERROR) << __func__ << ": could not calculate frame size for port config "
+        LOG(ERROR) << __func__ << ": " << mType
+                   << ": could not calculate frame size for port config "
                    << portConfigIt->toString();
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
     }
-    LOG(DEBUG) << __func__ << ": frame size " << frameSize << " bytes";
+    LOG(DEBUG) << __func__ << ": " << mType << ": frame size " << frameSize << " bytes";
     if (frameSize > static_cast<size_t>(kMaximumStreamBufferSizeBytes / in_bufferSizeFrames)) {
-        LOG(ERROR) << __func__ << ": buffer size " << in_bufferSizeFrames
+        LOG(ERROR) << __func__ << ": " << mType << ": buffer size " << in_bufferSizeFrames
                    << " frames is too large, maximum size is "
                    << kMaximumStreamBufferSizeBytes / frameSize;
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
@@ -256,7 +258,8 @@
     for (auto it = patchIdsRange.first; it != patchIdsRange.second; ++it) {
         auto patchIt = findById<AudioPatch>(patches, it->second);
         if (patchIt == patches.end()) {
-            LOG(FATAL) << __func__ << ": patch with id " << it->second << " taken from mPatches "
+            LOG(FATAL) << __func__ << ": " << mType << ": patch with id " << it->second
+                       << " taken from mPatches "
                        << "not found in the configuration";
         }
         if (std::find(patchIt->sourcePortConfigIds.begin(), patchIt->sourcePortConfigIds.end(),
@@ -273,7 +276,8 @@
     auto& configs = getConfig().portConfigs;
     auto portConfigIt = findById<AudioPortConfig>(configs, in_portConfigId);
     if (portConfigIt == configs.end()) {
-        LOG(ERROR) << __func__ << ": existing port config id " << in_portConfigId << " not found";
+        LOG(ERROR) << __func__ << ": " << mType << ": existing port config id " << in_portConfigId
+                   << " not found";
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
     }
     const int32_t portId = portConfigIt->portId;
@@ -282,23 +286,23 @@
     auto& ports = getConfig().ports;
     auto portIt = findById<AudioPort>(ports, portId);
     if (portIt == ports.end()) {
-        LOG(ERROR) << __func__ << ": port id " << portId << " used by port config id "
-                   << in_portConfigId << " not found";
+        LOG(ERROR) << __func__ << ": " << mType << ": port id " << portId
+                   << " used by port config id " << in_portConfigId << " not found";
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
     }
     if (mStreams.count(in_portConfigId) != 0) {
-        LOG(ERROR) << __func__ << ": port config id " << in_portConfigId
+        LOG(ERROR) << __func__ << ": " << mType << ": port config id " << in_portConfigId
                    << " already has a stream opened on it";
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
     }
     if (portIt->ext.getTag() != AudioPortExt::Tag::mix) {
-        LOG(ERROR) << __func__ << ": port config id " << in_portConfigId
+        LOG(ERROR) << __func__ << ": " << mType << ": port config id " << in_portConfigId
                    << " does not correspond to a mix port";
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
     }
     const size_t maxOpenStreamCount = portIt->ext.get<AudioPortExt::Tag::mix>().maxOpenStreamCount;
     if (maxOpenStreamCount != 0 && mStreams.count(portId) >= maxOpenStreamCount) {
-        LOG(ERROR) << __func__ << ": port id " << portId
+        LOG(ERROR) << __func__ << ": " << mType << ": port id " << portId
                    << " has already reached maximum allowed opened stream count: "
                    << maxOpenStreamCount;
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
@@ -326,7 +330,7 @@
         config->ext = port.ext;
         return true;
     }
-    LOG(ERROR) << __func__ << ": port " << port.id << " only has dynamic profiles";
+    LOG(ERROR) << __func__ << ": " << mType << ": port " << port.id << " only has dynamic profiles";
     return false;
 }
 
@@ -493,7 +497,8 @@
         }
     });
     if (!maybeFailure.isOk()) {
-        LOG(WARNING) << __func__ << ": Due to a failure, disconnecting streams on port config ids "
+        LOG(WARNING) << __func__ << ": " << mType
+                     << ": Due to a failure, disconnecting streams on port config ids "
                      << ::android::internal::ToString(idsToDisconnectOnFailure);
         std::for_each(idsToDisconnectOnFailure.begin(), idsToDisconnectOnFailure.end(),
                       [&](const auto& portConfigId) {
@@ -512,7 +517,8 @@
     if (mDebug.simulateDeviceConnections != in_debug.simulateDeviceConnections &&
         !mConnectedDevicePorts.empty()) {
         LOG(ERROR) << __func__ << ": " << mType
-                   << ": attempting to change device connections simulation while having external "
+                   << ": attempting to change device connections simulation while "
+                      "having external "
                    << "devices connected";
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
     }
@@ -527,25 +533,25 @@
 
 ndk::ScopedAStatus Module::getTelephony(std::shared_ptr<ITelephony>* _aidl_return) {
     *_aidl_return = nullptr;
-    LOG(DEBUG) << __func__ << ": returning null";
+    LOG(DEBUG) << __func__ << ": " << mType << ": returning null";
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus Module::getBluetooth(std::shared_ptr<IBluetooth>* _aidl_return) {
     *_aidl_return = nullptr;
-    LOG(DEBUG) << __func__ << ": returning null";
+    LOG(DEBUG) << __func__ << ": " << mType << ": returning null";
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus Module::getBluetoothA2dp(std::shared_ptr<IBluetoothA2dp>* _aidl_return) {
     *_aidl_return = nullptr;
-    LOG(DEBUG) << __func__ << ": returning null";
+    LOG(DEBUG) << __func__ << ": " << mType << ": returning null";
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus Module::getBluetoothLe(std::shared_ptr<IBluetoothLe>* _aidl_return) {
     *_aidl_return = nullptr;
-    LOG(DEBUG) << __func__ << ": returning null";
+    LOG(DEBUG) << __func__ << ": " << mType << ": returning null";
     return ndk::ScopedAStatus::ok();
 }
 
@@ -557,20 +563,23 @@
     {  // Scope the template port so that we don't accidentally modify it.
         auto templateIt = findById<AudioPort>(ports, templateId);
         if (templateIt == ports.end()) {
-            LOG(ERROR) << __func__ << ": port id " << templateId << " not found";
+            LOG(ERROR) << __func__ << ": " << mType << ": port id " << templateId << " not found";
             return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
         }
         if (templateIt->ext.getTag() != AudioPortExt::Tag::device) {
-            LOG(ERROR) << __func__ << ": port id " << templateId << " is not a device port";
+            LOG(ERROR) << __func__ << ": " << mType << ": port id " << templateId
+                       << " is not a device port";
             return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
         }
         auto& templateDevicePort = templateIt->ext.get<AudioPortExt::Tag::device>();
         if (templateDevicePort.device.type.connection.empty()) {
-            LOG(ERROR) << __func__ << ": port id " << templateId << " is permanently attached";
+            LOG(ERROR) << __func__ << ": " << mType << ": port id " << templateId
+                       << " is permanently attached";
             return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
         }
         if (mConnectedDevicePorts.find(templateId) != mConnectedDevicePorts.end()) {
-            LOG(ERROR) << __func__ << ": port id " << templateId << " is a connected device port";
+            LOG(ERROR) << __func__ << ": " << mType << ": port id " << templateId
+                       << " is a connected device port";
             return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
         }
         // Postpone id allocation until we ensure that there are no client errors.
@@ -580,14 +589,16 @@
                 in_templateIdAndAdditionalData.ext.get<AudioPortExt::Tag::device>();
         auto& connectedDevicePort = connectedPort.ext.get<AudioPortExt::Tag::device>();
         connectedDevicePort.device.address = inputDevicePort.device.address;
-        LOG(DEBUG) << __func__ << ": device port " << connectedPort.id << " device set to "
-                   << connectedDevicePort.device.toString();
+        LOG(DEBUG) << __func__ << ": " << mType << ": device port " << connectedPort.id
+                   << " device set to " << connectedDevicePort.device.toString();
         // Check if there is already a connected port with for the same external device.
+
         for (auto connectedPortPair : mConnectedDevicePorts) {
             auto connectedPortIt = findById<AudioPort>(ports, connectedPortPair.first);
             if (connectedPortIt->ext.get<AudioPortExt::Tag::device>().device ==
                 connectedDevicePort.device) {
-                LOG(ERROR) << __func__ << ": device " << connectedDevicePort.device.toString()
+                LOG(ERROR) << __func__ << ": " << mType << ": device "
+                           << connectedDevicePort.device.toString()
                            << " is already connected at the device port id "
                            << connectedPortPair.first;
                 return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
@@ -639,7 +650,8 @@
                                                             hasDynamicProfilesOnly(p.profiles);
                                                  });
             dynamicMixPortIt != ports.end()) {
-            LOG(ERROR) << __func__ << ": connected port only has dynamic profiles after connecting "
+            LOG(ERROR) << __func__ << ": " << mType
+                       << ": connected port only has dynamic profiles after connecting "
                        << "external device " << connectedPort.toString() << ", and there exist "
                        << "a routable mix port with dynamic profiles: "
                        << dynamicMixPortIt->toString();
@@ -650,7 +662,8 @@
     connectedPort.id = nextPortId;
     auto [connectedPortsIt, _] =
             mConnectedDevicePorts.insert(std::pair(connectedPort.id, std::set<int32_t>()));
-    LOG(DEBUG) << __func__ << ": template port " << templateId << " external device connected, "
+    LOG(DEBUG) << __func__ << ": " << mType << ": template port " << templateId
+               << " external device connected, "
                << "connected port ID " << connectedPort.id;
     ports.push_back(connectedPort);
     onExternalDeviceConnectionChanged(connectedPort, true /*connected*/);
@@ -700,16 +713,18 @@
     auto& ports = getConfig().ports;
     auto portIt = findById<AudioPort>(ports, in_portId);
     if (portIt == ports.end()) {
-        LOG(ERROR) << __func__ << ": port id " << in_portId << " not found";
+        LOG(ERROR) << __func__ << ": " << mType << ": port id " << in_portId << " not found";
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
     }
     if (portIt->ext.getTag() != AudioPortExt::Tag::device) {
-        LOG(ERROR) << __func__ << ": port id " << in_portId << " is not a device port";
+        LOG(ERROR) << __func__ << ": " << mType << ": port id " << in_portId
+                   << " is not a device port";
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
     }
     auto connectedPortsIt = mConnectedDevicePorts.find(in_portId);
     if (connectedPortsIt == mConnectedDevicePorts.end()) {
-        LOG(ERROR) << __func__ << ": port id " << in_portId << " is not a connected device port";
+        LOG(ERROR) << __func__ << ": " << mType << ": port id " << in_portId
+                   << " is not a connected device port";
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
     }
     auto& configs = getConfig().portConfigs;
@@ -723,13 +738,14 @@
         return false;
     });
     if (configIt != configs.end()) {
-        LOG(ERROR) << __func__ << ": port id " << in_portId << " has a non-default config with id "
-                   << configIt->id;
+        LOG(ERROR) << __func__ << ": " << mType << ": port id " << in_portId
+                   << " has a non-default config with id " << configIt->id;
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
     }
     onExternalDeviceConnectionChanged(*portIt, false /*connected*/);
     ports.erase(portIt);
-    LOG(DEBUG) << __func__ << ": connected device port " << in_portId << " released";
+    LOG(DEBUG) << __func__ << ": " << mType << ": connected device port " << in_portId
+               << " released";
 
     auto& routes = getConfig().routes;
     for (auto routesIt = routes.begin(); routesIt != routes.end();) {
@@ -765,16 +781,18 @@
     auto& ports = getConfig().ports;
     auto portIt = findById<AudioPort>(ports, in_portId);
     if (portIt == ports.end()) {
-        LOG(ERROR) << __func__ << ": port id " << in_portId << " not found";
+        LOG(ERROR) << __func__ << ": " << mType << ": port id " << in_portId << " not found";
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
     }
     if (portIt->ext.getTag() != AudioPortExt::Tag::device) {
-        LOG(ERROR) << __func__ << ": port id " << in_portId << " is not a device port";
+        LOG(ERROR) << __func__ << ": " << mType << ": port id " << in_portId
+                   << " is not a device port";
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
     }
     auto connectedPortsIt = mConnectedDevicePorts.find(in_portId);
     if (connectedPortsIt == mConnectedDevicePorts.end()) {
-        LOG(ERROR) << __func__ << ": port id " << in_portId << " is not a connected device port";
+        LOG(ERROR) << __func__ << ": " << mType << ": port id " << in_portId
+                   << " is not a connected device port";
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
     }
 
@@ -785,7 +803,7 @@
 
 ndk::ScopedAStatus Module::getAudioPatches(std::vector<AudioPatch>* _aidl_return) {
     *_aidl_return = getConfig().patches;
-    LOG(DEBUG) << __func__ << ": returning " << _aidl_return->size() << " patches";
+    LOG(DEBUG) << __func__ << ": " << mType << ": returning " << _aidl_return->size() << " patches";
     return ndk::ScopedAStatus::ok();
 }
 
@@ -794,28 +812,29 @@
     auto portIt = findById<AudioPort>(ports, in_portId);
     if (portIt != ports.end()) {
         *_aidl_return = *portIt;
-        LOG(DEBUG) << __func__ << ": returning port by id " << in_portId;
+        LOG(DEBUG) << __func__ << ": " << mType << ": returning port by id " << in_portId;
         return ndk::ScopedAStatus::ok();
     }
-    LOG(ERROR) << __func__ << ": port id " << in_portId << " not found";
+    LOG(ERROR) << __func__ << ": " << mType << ": port id " << in_portId << " not found";
     return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
 }
 
 ndk::ScopedAStatus Module::getAudioPortConfigs(std::vector<AudioPortConfig>* _aidl_return) {
     *_aidl_return = getConfig().portConfigs;
-    LOG(DEBUG) << __func__ << ": returning " << _aidl_return->size() << " port configs";
+    LOG(DEBUG) << __func__ << ": " << mType << ": returning " << _aidl_return->size()
+               << " port configs";
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus Module::getAudioPorts(std::vector<AudioPort>* _aidl_return) {
     *_aidl_return = getConfig().ports;
-    LOG(DEBUG) << __func__ << ": returning " << _aidl_return->size() << " ports";
+    LOG(DEBUG) << __func__ << ": " << mType << ": returning " << _aidl_return->size() << " ports";
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus Module::getAudioRoutes(std::vector<AudioRoute>* _aidl_return) {
     *_aidl_return = getConfig().routes;
-    LOG(DEBUG) << __func__ << ": returning " << _aidl_return->size() << " routes";
+    LOG(DEBUG) << __func__ << ": " << mType << ": returning " << _aidl_return->size() << " routes";
     return ndk::ScopedAStatus::ok();
 }
 
@@ -823,7 +842,7 @@
                                                       std::vector<AudioRoute>* _aidl_return) {
     auto& ports = getConfig().ports;
     if (auto portIt = findById<AudioPort>(ports, in_portId); portIt == ports.end()) {
-        LOG(ERROR) << __func__ << ": port id " << in_portId << " not found";
+        LOG(ERROR) << __func__ << ": " << mType << ": port id " << in_portId << " not found";
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
     }
     std::vector<AudioRoute*> routes = getAudioRoutesForAudioPortImpl(in_portId);
@@ -834,12 +853,12 @@
 
 ndk::ScopedAStatus Module::openInputStream(const OpenInputStreamArguments& in_args,
                                            OpenInputStreamReturn* _aidl_return) {
-    LOG(DEBUG) << __func__ << ": port config id " << in_args.portConfigId << ", buffer size "
-               << in_args.bufferSizeFrames << " frames";
+    LOG(DEBUG) << __func__ << ": " << mType << ": port config id " << in_args.portConfigId
+               << ", buffer size " << in_args.bufferSizeFrames << " frames";
     AudioPort* port = nullptr;
     RETURN_STATUS_IF_ERROR(findPortIdForNewStream(in_args.portConfigId, &port));
     if (port->flags.getTag() != AudioIoFlags::Tag::input) {
-        LOG(ERROR) << __func__ << ": port config id " << in_args.portConfigId
+        LOG(ERROR) << __func__ << ": " << mType << ": port config id " << in_args.portConfigId
                    << " does not correspond to an input mix port";
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
     }
@@ -855,8 +874,9 @@
         RETURN_STATUS_IF_ERROR(
                 streamWrapper.setConnectedDevices(findConnectedDevices(in_args.portConfigId)));
     }
-    AIBinder_setMinSchedulerPolicy(streamWrapper.getBinder().get(), SCHED_NORMAL,
-                                   ANDROID_PRIORITY_AUDIO);
+    auto streamBinder = streamWrapper.getBinder();
+    AIBinder_setMinSchedulerPolicy(streamBinder.get(), SCHED_NORMAL, ANDROID_PRIORITY_AUDIO);
+    AIBinder_setInheritRt(streamBinder.get(), true);
     mStreams.insert(port->id, in_args.portConfigId, std::move(streamWrapper));
     _aidl_return->stream = std::move(stream);
     return ndk::ScopedAStatus::ok();
@@ -864,27 +884,27 @@
 
 ndk::ScopedAStatus Module::openOutputStream(const OpenOutputStreamArguments& in_args,
                                             OpenOutputStreamReturn* _aidl_return) {
-    LOG(DEBUG) << __func__ << ": port config id " << in_args.portConfigId << ", has offload info? "
-               << (in_args.offloadInfo.has_value()) << ", buffer size " << in_args.bufferSizeFrames
-               << " frames";
+    LOG(DEBUG) << __func__ << ": " << mType << ": port config id " << in_args.portConfigId
+               << ", has offload info? " << (in_args.offloadInfo.has_value()) << ", buffer size "
+               << in_args.bufferSizeFrames << " frames";
     AudioPort* port = nullptr;
     RETURN_STATUS_IF_ERROR(findPortIdForNewStream(in_args.portConfigId, &port));
     if (port->flags.getTag() != AudioIoFlags::Tag::output) {
-        LOG(ERROR) << __func__ << ": port config id " << in_args.portConfigId
+        LOG(ERROR) << __func__ << ": " << mType << ": port config id " << in_args.portConfigId
                    << " does not correspond to an output mix port";
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
     }
     const bool isOffload = isBitPositionFlagSet(port->flags.get<AudioIoFlags::Tag::output>(),
                                                 AudioOutputFlags::COMPRESS_OFFLOAD);
     if (isOffload && !in_args.offloadInfo.has_value()) {
-        LOG(ERROR) << __func__ << ": port id " << port->id
+        LOG(ERROR) << __func__ << ": " << mType << ": port id " << port->id
                    << " has COMPRESS_OFFLOAD flag set, requires offload info";
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
     }
     const bool isNonBlocking = isBitPositionFlagSet(port->flags.get<AudioIoFlags::Tag::output>(),
                                                     AudioOutputFlags::NON_BLOCKING);
     if (isNonBlocking && in_args.callback == nullptr) {
-        LOG(ERROR) << __func__ << ": port id " << port->id
+        LOG(ERROR) << __func__ << ": " << mType << ": port id " << port->id
                    << " has NON_BLOCKING flag set, requires async callback";
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
     }
@@ -901,8 +921,9 @@
         RETURN_STATUS_IF_ERROR(
                 streamWrapper.setConnectedDevices(findConnectedDevices(in_args.portConfigId)));
     }
-    AIBinder_setMinSchedulerPolicy(streamWrapper.getBinder().get(), SCHED_NORMAL,
-                                   ANDROID_PRIORITY_AUDIO);
+    auto streamBinder = streamWrapper.getBinder();
+    AIBinder_setMinSchedulerPolicy(streamBinder.get(), SCHED_NORMAL, ANDROID_PRIORITY_AUDIO);
+    AIBinder_setInheritRt(streamBinder.get(), true);
     mStreams.insert(port->id, in_args.portConfigId, std::move(streamWrapper));
     _aidl_return->stream = std::move(stream);
     return ndk::ScopedAStatus::ok();
@@ -910,27 +931,29 @@
 
 ndk::ScopedAStatus Module::getSupportedPlaybackRateFactors(
         SupportedPlaybackRateFactors* _aidl_return) {
-    LOG(DEBUG) << __func__;
+    LOG(DEBUG) << __func__ << ": " << mType;
     (void)_aidl_return;
     return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
 }
 
 ndk::ScopedAStatus Module::setAudioPatch(const AudioPatch& in_requested, AudioPatch* _aidl_return) {
-    LOG(DEBUG) << __func__ << ": requested patch " << in_requested.toString();
+    LOG(DEBUG) << __func__ << ": " << mType << ": requested patch " << in_requested.toString();
     if (in_requested.sourcePortConfigIds.empty()) {
-        LOG(ERROR) << __func__ << ": requested patch has empty sources list";
+        LOG(ERROR) << __func__ << ": " << mType << ": requested patch has empty sources list";
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
     }
     if (!all_unique<int32_t>(in_requested.sourcePortConfigIds)) {
-        LOG(ERROR) << __func__ << ": requested patch has duplicate ids in the sources list";
+        LOG(ERROR) << __func__ << ": " << mType
+                   << ": requested patch has duplicate ids in the sources list";
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
     }
     if (in_requested.sinkPortConfigIds.empty()) {
-        LOG(ERROR) << __func__ << ": requested patch has empty sinks list";
+        LOG(ERROR) << __func__ << ": " << mType << ": requested patch has empty sinks list";
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
     }
     if (!all_unique<int32_t>(in_requested.sinkPortConfigIds)) {
-        LOG(ERROR) << __func__ << ": requested patch has duplicate ids in the sinks list";
+        LOG(ERROR) << __func__ << ": " << mType
+                   << ": requested patch has duplicate ids in the sinks list";
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
     }
 
@@ -939,13 +962,13 @@
     auto sources =
             selectByIds<AudioPortConfig>(configs, in_requested.sourcePortConfigIds, &missingIds);
     if (!missingIds.empty()) {
-        LOG(ERROR) << __func__ << ": following source port config ids not found: "
+        LOG(ERROR) << __func__ << ": " << mType << ": following source port config ids not found: "
                    << ::android::internal::ToString(missingIds);
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
     }
     auto sinks = selectByIds<AudioPortConfig>(configs, in_requested.sinkPortConfigIds, &missingIds);
     if (!missingIds.empty()) {
-        LOG(ERROR) << __func__ << ": following sink port config ids not found: "
+        LOG(ERROR) << __func__ << ": " << mType << ": following sink port config ids not found: "
                    << ::android::internal::ToString(missingIds);
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
     }
@@ -966,7 +989,8 @@
     }
     for (auto sink : sinks) {
         if (allowedSinkPorts.count(sink->portId) == 0) {
-            LOG(ERROR) << __func__ << ": there is no route to the sink port id " << sink->portId;
+            LOG(ERROR) << __func__ << ": " << mType << ": there is no route to the sink port id "
+                       << sink->portId;
             return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
         }
     }
@@ -981,14 +1005,15 @@
             patchesBackup = mPatches;
             cleanUpPatch(existing->id);
         } else {
-            LOG(ERROR) << __func__ << ": not found existing patch id " << in_requested.id;
+            LOG(ERROR) << __func__ << ": " << mType << ": not found existing patch id "
+                       << in_requested.id;
             return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
         }
     }
     // Validate the requested patch.
     for (const auto& [sinkPortId, nonExclusive] : allowedSinkPorts) {
         if (!nonExclusive && mPatches.count(sinkPortId) != 0) {
-            LOG(ERROR) << __func__ << ": sink port id " << sinkPortId
+            LOG(ERROR) << __func__ << ": " << mType << ": sink port id " << sinkPortId
                        << "is exclusive and is already used by some other patch";
             if (patchesBackup.has_value()) {
                 mPatches = std::move(*patchesBackup);
@@ -1031,8 +1056,8 @@
         return status;
     }
 
-    LOG(DEBUG) << __func__ << ": " << (oldPatch.id == 0 ? "created" : "updated") << " patch "
-               << _aidl_return->toString();
+    LOG(DEBUG) << __func__ << ": " << mType << ": " << (oldPatch.id == 0 ? "created" : "updated")
+               << " patch " << _aidl_return->toString();
     return ndk::ScopedAStatus::ok();
 }
 
@@ -1050,28 +1075,29 @@
                                  ::aidl::android::media::audio::common::AudioPortConfig* config)>&
                 fillPortConfig,
         AudioPortConfig* out_suggested, bool* applied) {
-    LOG(DEBUG) << __func__ << ": requested " << in_requested.toString();
+    LOG(DEBUG) << __func__ << ": " << mType << ": requested " << in_requested.toString();
     auto& configs = getConfig().portConfigs;
     auto existing = configs.end();
     if (in_requested.id != 0) {
         if (existing = findById<AudioPortConfig>(configs, in_requested.id);
             existing == configs.end()) {
-            LOG(ERROR) << __func__ << ": existing port config id " << in_requested.id
-                       << " not found";
+            LOG(ERROR) << __func__ << ": " << mType << ": existing port config id "
+                       << in_requested.id << " not found";
             return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
         }
     }
 
     const int portId = existing != configs.end() ? existing->portId : in_requested.portId;
     if (portId == 0) {
-        LOG(ERROR) << __func__ << ": requested port config does not specify portId";
+        LOG(ERROR) << __func__ << ": " << mType
+                   << ": requested port config does not specify portId";
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
     }
     auto& ports = getConfig().ports;
     auto portIt = findById<AudioPort>(ports, portId);
     if (portIt == ports.end()) {
-        LOG(ERROR) << __func__ << ": requested port config points to non-existent portId "
-                   << portId;
+        LOG(ERROR) << __func__ << ": " << mType
+                   << ": requested port config points to non-existent portId " << portId;
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
     }
     if (existing != configs.end()) {
@@ -1082,7 +1108,8 @@
         if (fillPortConfig(*portIt, &newConfig)) {
             *out_suggested = newConfig;
         } else {
-            LOG(ERROR) << __func__ << ": unable generate a default config for port " << portId;
+            LOG(ERROR) << __func__ << ": " << mType
+                       << ": unable generate a default config for port " << portId;
             return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
         }
     }
@@ -1099,7 +1126,7 @@
     AudioIoFlags portFlags = portIt->flags;
     if (in_requested.flags.has_value()) {
         if (in_requested.flags.value() != portFlags) {
-            LOG(WARNING) << __func__ << ": requested flags "
+            LOG(WARNING) << __func__ << ": " << mType << ": requested flags "
                          << in_requested.flags.value().toString() << " do not match port's "
                          << portId << " flags " << portFlags.toString();
             requestedIsValid = false;
@@ -1115,7 +1142,7 @@
             findAudioProfile(*portIt, format, &portProfile)) {
             out_suggested->format = format;
         } else {
-            LOG(WARNING) << __func__ << ": requested format " << format.toString()
+            LOG(WARNING) << __func__ << ": " << mType << ": requested format " << format.toString()
                          << " is not found in the profiles of port " << portId;
             requestedIsValid = false;
         }
@@ -1124,8 +1151,9 @@
     }
     if (!(out_suggested->format.value() == AudioFormatDescription{} && allowDynamicConfig) &&
         !findAudioProfile(*portIt, out_suggested->format.value(), &portProfile)) {
-        LOG(ERROR) << __func__ << ": port " << portId << " does not support format "
-                   << out_suggested->format.value().toString() << " anymore";
+        LOG(ERROR) << __func__ << ": " << mType << ": port " << portId
+                   << " does not support format " << out_suggested->format.value().toString()
+                   << " anymore";
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
     }
 
@@ -1136,9 +1164,9 @@
                     portProfile.channelMasks.end()) {
             out_suggested->channelMask = channelMask;
         } else {
-            LOG(WARNING) << __func__ << ": requested channel mask " << channelMask.toString()
-                         << " is not supported for the format " << portProfile.format.toString()
-                         << " by the port " << portId;
+            LOG(WARNING) << __func__ << ": " << mType << ": requested channel mask "
+                         << channelMask.toString() << " is not supported for the format "
+                         << portProfile.format.toString() << " by the port " << portId;
             requestedIsValid = false;
         }
     } else {
@@ -1152,9 +1180,9 @@
                  sampleRate.value) != portProfile.sampleRates.end()) {
             out_suggested->sampleRate = sampleRate;
         } else {
-            LOG(WARNING) << __func__ << ": requested sample rate " << sampleRate.value
-                         << " is not supported for the format " << portProfile.format.toString()
-                         << " by the port " << portId;
+            LOG(WARNING) << __func__ << ": " << mType << ": requested sample rate "
+                         << sampleRate.value << " is not supported for the format "
+                         << portProfile.format.toString() << " by the port " << portId;
             requestedIsValid = false;
         }
     } else {
@@ -1169,12 +1197,15 @@
     if (in_requested.ext.getTag() != AudioPortExt::Tag::unspecified) {
         if (in_requested.ext.getTag() == out_suggested->ext.getTag()) {
             if (out_suggested->ext.getTag() == AudioPortExt::Tag::mix) {
-                // 'AudioMixPortExt.handle' is set by the client, copy from in_requested
-                out_suggested->ext.get<AudioPortExt::Tag::mix>().handle =
-                        in_requested.ext.get<AudioPortExt::Tag::mix>().handle;
+                // 'AudioMixPortExt.handle' and '.usecase' are set by the client,
+                // copy from in_requested.
+                const auto& src = in_requested.ext.get<AudioPortExt::Tag::mix>();
+                auto& dst = out_suggested->ext.get<AudioPortExt::Tag::mix>();
+                dst.handle = src.handle;
+                dst.usecase = src.usecase;
             }
         } else {
-            LOG(WARNING) << __func__ << ": requested ext tag "
+            LOG(WARNING) << __func__ << ": " << mType << ": requested ext tag "
                          << toString(in_requested.ext.getTag()) << " do not match port's tag "
                          << toString(out_suggested->ext.getTag());
             requestedIsValid = false;
@@ -1185,15 +1216,17 @@
         out_suggested->id = getConfig().nextPortId++;
         configs.push_back(*out_suggested);
         *applied = true;
-        LOG(DEBUG) << __func__ << ": created new port config " << out_suggested->toString();
+        LOG(DEBUG) << __func__ << ": " << mType << ": created new port config "
+                   << out_suggested->toString();
     } else if (existing != configs.end() && requestedIsValid) {
         *existing = *out_suggested;
         *applied = true;
-        LOG(DEBUG) << __func__ << ": updated port config " << out_suggested->toString();
+        LOG(DEBUG) << __func__ << ": " << mType << ": updated port config "
+                   << out_suggested->toString();
     } else {
-        LOG(DEBUG) << __func__ << ": not applied; existing config ? " << (existing != configs.end())
-                   << "; requested is valid? " << requestedIsValid << ", fully specified? "
-                   << requestedIsFullySpecified;
+        LOG(DEBUG) << __func__ << ": " << mType << ": not applied; existing config ? "
+                   << (existing != configs.end()) << "; requested is valid? " << requestedIsValid
+                   << ", fully specified? " << requestedIsFullySpecified;
         *applied = false;
     }
     return ndk::ScopedAStatus::ok();
@@ -1210,10 +1243,10 @@
             return status;
         }
         patches.erase(patchIt);
-        LOG(DEBUG) << __func__ << ": erased patch " << in_patchId;
+        LOG(DEBUG) << __func__ << ": " << mType << ": erased patch " << in_patchId;
         return ndk::ScopedAStatus::ok();
     }
-    LOG(ERROR) << __func__ << ": patch id " << in_patchId << " not found";
+    LOG(ERROR) << __func__ << ": " << mType << ": patch id " << in_patchId << " not found";
     return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
 }
 
@@ -1222,13 +1255,13 @@
     auto configIt = findById<AudioPortConfig>(configs, in_portConfigId);
     if (configIt != configs.end()) {
         if (mStreams.count(in_portConfigId) != 0) {
-            LOG(ERROR) << __func__ << ": port config id " << in_portConfigId
+            LOG(ERROR) << __func__ << ": " << mType << ": port config id " << in_portConfigId
                        << " has a stream opened on it";
             return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
         }
         auto patchIt = mPatches.find(in_portConfigId);
         if (patchIt != mPatches.end()) {
-            LOG(ERROR) << __func__ << ": port config id " << in_portConfigId
+            LOG(ERROR) << __func__ << ": " << mType << ": port config id " << in_portConfigId
                        << " is used by the patch with id " << patchIt->second;
             return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
         }
@@ -1236,32 +1269,33 @@
         auto initialIt = findById<AudioPortConfig>(initials, in_portConfigId);
         if (initialIt == initials.end()) {
             configs.erase(configIt);
-            LOG(DEBUG) << __func__ << ": erased port config " << in_portConfigId;
+            LOG(DEBUG) << __func__ << ": " << mType << ": erased port config " << in_portConfigId;
         } else if (*configIt != *initialIt) {
             *configIt = *initialIt;
-            LOG(DEBUG) << __func__ << ": reset port config " << in_portConfigId;
+            LOG(DEBUG) << __func__ << ": " << mType << ": reset port config " << in_portConfigId;
         }
         return ndk::ScopedAStatus::ok();
     }
-    LOG(ERROR) << __func__ << ": port config id " << in_portConfigId << " not found";
+    LOG(ERROR) << __func__ << ": " << mType << ": port config id " << in_portConfigId
+               << " not found";
     return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
 }
 
 ndk::ScopedAStatus Module::getMasterMute(bool* _aidl_return) {
     *_aidl_return = mMasterMute;
-    LOG(DEBUG) << __func__ << ": returning " << *_aidl_return;
+    LOG(DEBUG) << __func__ << ": " << mType << ": returning " << *_aidl_return;
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus Module::setMasterMute(bool in_mute) {
-    LOG(DEBUG) << __func__ << ": " << in_mute;
+    LOG(DEBUG) << __func__ << ": " << mType << ": " << in_mute;
     auto result = mDebug.simulateDeviceConnections ? ndk::ScopedAStatus::ok()
                                                    : onMasterMuteChanged(in_mute);
     if (result.isOk()) {
         mMasterMute = in_mute;
     } else {
-        LOG(ERROR) << __func__ << ": failed calling onMasterMuteChanged(" << in_mute
-                   << "), error=" << result;
+        LOG(ERROR) << __func__ << ": " << mType << ": failed calling onMasterMuteChanged("
+                   << in_mute << "), error=" << result;
         // Reset master mute if it failed.
         onMasterMuteChanged(mMasterMute);
     }
@@ -1270,12 +1304,12 @@
 
 ndk::ScopedAStatus Module::getMasterVolume(float* _aidl_return) {
     *_aidl_return = mMasterVolume;
-    LOG(DEBUG) << __func__ << ": returning " << *_aidl_return;
+    LOG(DEBUG) << __func__ << ": " << mType << ": returning " << *_aidl_return;
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus Module::setMasterVolume(float in_volume) {
-    LOG(DEBUG) << __func__ << ": " << in_volume;
+    LOG(DEBUG) << __func__ << ": " << mType << ": " << in_volume;
     if (in_volume >= 0.0f && in_volume <= 1.0f) {
         auto result = mDebug.simulateDeviceConnections ? ndk::ScopedAStatus::ok()
                                                        : onMasterVolumeChanged(in_volume);
@@ -1283,51 +1317,52 @@
             mMasterVolume = in_volume;
         } else {
             // Reset master volume if it failed.
-            LOG(ERROR) << __func__ << ": failed calling onMasterVolumeChanged(" << in_volume
-                       << "), error=" << result;
+            LOG(ERROR) << __func__ << ": " << mType << ": failed calling onMasterVolumeChanged("
+                       << in_volume << "), error=" << result;
             onMasterVolumeChanged(mMasterVolume);
         }
         return result;
     }
-    LOG(ERROR) << __func__ << ": invalid master volume value: " << in_volume;
+    LOG(ERROR) << __func__ << ": " << mType << ": invalid master volume value: " << in_volume;
     return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
 }
 
 ndk::ScopedAStatus Module::getMicMute(bool* _aidl_return) {
     *_aidl_return = mMicMute;
-    LOG(DEBUG) << __func__ << ": returning " << *_aidl_return;
+    LOG(DEBUG) << __func__ << ": " << mType << ": returning " << *_aidl_return;
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus Module::setMicMute(bool in_mute) {
-    LOG(DEBUG) << __func__ << ": " << in_mute;
+    LOG(DEBUG) << __func__ << ": " << mType << ": " << in_mute;
     mMicMute = in_mute;
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus Module::getMicrophones(std::vector<MicrophoneInfo>* _aidl_return) {
     *_aidl_return = getMicrophoneInfos();
-    LOG(DEBUG) << __func__ << ": returning " << ::android::internal::ToString(*_aidl_return);
+    LOG(DEBUG) << __func__ << ": " << mType << ": returning "
+               << ::android::internal::ToString(*_aidl_return);
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus Module::updateAudioMode(AudioMode in_mode) {
     if (!isValidAudioMode(in_mode)) {
-        LOG(ERROR) << __func__ << ": invalid mode " << toString(in_mode);
+        LOG(ERROR) << __func__ << ": " << mType << ": invalid mode " << toString(in_mode);
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
     }
     // No checks for supported audio modes here, it's an informative notification.
-    LOG(DEBUG) << __func__ << ": " << toString(in_mode);
+    LOG(DEBUG) << __func__ << ": " << mType << ": " << toString(in_mode);
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus Module::updateScreenRotation(ScreenRotation in_rotation) {
-    LOG(DEBUG) << __func__ << ": " << toString(in_rotation);
+    LOG(DEBUG) << __func__ << ": " << mType << ": " << toString(in_rotation);
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus Module::updateScreenState(bool in_isTurnedOn) {
-    LOG(DEBUG) << __func__ << ": " << in_isTurnedOn;
+    LOG(DEBUG) << __func__ << ": " << mType << ": " << in_isTurnedOn;
     return ndk::ScopedAStatus::ok();
 }
 
@@ -1336,12 +1371,13 @@
         mSoundDose = ndk::SharedRefBase::make<sounddose::SoundDose>();
     }
     *_aidl_return = mSoundDose.getInstance();
-    LOG(DEBUG) << __func__ << ": returning instance of ISoundDose: " << _aidl_return->get();
+    LOG(DEBUG) << __func__ << ": " << mType
+               << ": returning instance of ISoundDose: " << _aidl_return->get();
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus Module::generateHwAvSyncId(int32_t* _aidl_return) {
-    LOG(DEBUG) << __func__;
+    LOG(DEBUG) << __func__ << ": " << mType;
     (void)_aidl_return;
     return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
 }
@@ -1351,7 +1387,7 @@
 
 ndk::ScopedAStatus Module::getVendorParameters(const std::vector<std::string>& in_ids,
                                                std::vector<VendorParameter>* _aidl_return) {
-    LOG(DEBUG) << __func__ << ": id count: " << in_ids.size();
+    LOG(VERBOSE) << __func__ << ": " << mType << ": id count: " << in_ids.size();
     bool allParametersKnown = true;
     for (const auto& id : in_ids) {
         if (id == VendorDebug::kForceTransientBurstName) {
@@ -1364,7 +1400,7 @@
             _aidl_return->push_back(std::move(forceSynchronousDrain));
         } else {
             allParametersKnown = false;
-            LOG(ERROR) << __func__ << ": unrecognized parameter \"" << id << "\"";
+            LOG(VERBOSE) << __func__ << ": " << mType << ": unrecognized parameter \"" << id << "\"";
         }
     }
     if (allParametersKnown) return ndk::ScopedAStatus::ok();
@@ -1390,8 +1426,8 @@
 
 ndk::ScopedAStatus Module::setVendorParameters(const std::vector<VendorParameter>& in_parameters,
                                                bool in_async) {
-    LOG(DEBUG) << __func__ << ": parameter count " << in_parameters.size()
-               << ", async: " << in_async;
+    LOG(VERBOSE) << __func__ << ": " << mType << ": parameter count " << in_parameters.size()
+                 << ", async: " << in_async;
     bool allParametersKnown = true;
     for (const auto& p : in_parameters) {
         if (p.id == VendorDebug::kForceTransientBurstName) {
@@ -1404,7 +1440,8 @@
             }
         } else {
             allParametersKnown = false;
-            LOG(ERROR) << __func__ << ": unrecognized parameter \"" << p.id << "\"";
+            LOG(VERBOSE) << __func__ << ": " << mType << ": unrecognized parameter \"" << p.id
+                         << "\"";
         }
     }
     if (allParametersKnown) return ndk::ScopedAStatus::ok();
@@ -1415,10 +1452,11 @@
         int32_t in_portConfigId,
         const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>& in_effect) {
     if (in_effect == nullptr) {
-        LOG(DEBUG) << __func__ << ": port id " << in_portConfigId << ", null effect";
+        LOG(DEBUG) << __func__ << ": " << mType << ": port id " << in_portConfigId
+                   << ", null effect";
     } else {
-        LOG(DEBUG) << __func__ << ": port id " << in_portConfigId << ", effect Binder "
-                   << in_effect->asBinder().get();
+        LOG(DEBUG) << __func__ << ": " << mType << ": port id " << in_portConfigId
+                   << ", effect Binder " << in_effect->asBinder().get();
     }
     return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
 }
@@ -1427,17 +1465,18 @@
         int32_t in_portConfigId,
         const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>& in_effect) {
     if (in_effect == nullptr) {
-        LOG(DEBUG) << __func__ << ": port id " << in_portConfigId << ", null effect";
+        LOG(DEBUG) << __func__ << ": " << mType << ": port id " << in_portConfigId
+                   << ", null effect";
     } else {
-        LOG(DEBUG) << __func__ << ": port id " << in_portConfigId << ", effect Binder "
-                   << in_effect->asBinder().get();
+        LOG(DEBUG) << __func__ << ": " << mType << ": port id " << in_portConfigId
+                   << ", effect Binder " << in_effect->asBinder().get();
     }
     return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
 }
 
 ndk::ScopedAStatus Module::getMmapPolicyInfos(AudioMMapPolicyType mmapPolicyType,
                                               std::vector<AudioMMapPolicyInfo>* _aidl_return) {
-    LOG(DEBUG) << __func__ << ": mmap policy type " << toString(mmapPolicyType);
+    LOG(DEBUG) << __func__ << ": " << mType << ": mmap policy type " << toString(mmapPolicyType);
     std::set<int32_t> mmapSinks;
     std::set<int32_t> mmapSources;
     auto& ports = getConfig().ports;
@@ -1465,7 +1504,8 @@
                 auto sourcePortIt = findById<AudioPort>(ports, sourcePortId);
                 if (sourcePortIt == ports.end()) {
                     // This must not happen
-                    LOG(ERROR) << __func__ << ": port id " << sourcePortId << " cannot be found";
+                    LOG(ERROR) << __func__ << ": " << mType << ": port id " << sourcePortId
+                               << " cannot be found";
                     continue;
                 }
                 if (sourcePortIt->ext.getTag() != AudioPortExt::Tag::device) {
@@ -1483,7 +1523,8 @@
             auto sinkPortIt = findById<AudioPort>(ports, route.sinkPortId);
             if (sinkPortIt == ports.end()) {
                 // This must not happen
-                LOG(ERROR) << __func__ << ": port id " << route.sinkPortId << " cannot be found";
+                LOG(ERROR) << __func__ << ": " << mType << ": port id " << route.sinkPortId
+                           << " cannot be found";
                 continue;
             }
             if (sinkPortIt->ext.getTag() != AudioPortExt::Tag::device) {
@@ -1504,28 +1545,28 @@
 }
 
 ndk::ScopedAStatus Module::supportsVariableLatency(bool* _aidl_return) {
-    LOG(DEBUG) << __func__;
+    LOG(DEBUG) << __func__ << ": " << mType;
     *_aidl_return = false;
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus Module::getAAudioMixerBurstCount(int32_t* _aidl_return) {
     if (!isMmapSupported()) {
-        LOG(DEBUG) << __func__ << ": mmap is not supported ";
+        LOG(DEBUG) << __func__ << ": " << mType << ": mmap is not supported ";
         return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
     }
     *_aidl_return = DEFAULT_AAUDIO_MIXER_BURST_COUNT;
-    LOG(DEBUG) << __func__ << ": returning " << *_aidl_return;
+    LOG(DEBUG) << __func__ << ": " << mType << ": returning " << *_aidl_return;
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus Module::getAAudioHardwareBurstMinUsec(int32_t* _aidl_return) {
     if (!isMmapSupported()) {
-        LOG(DEBUG) << __func__ << ": mmap is not supported ";
+        LOG(DEBUG) << __func__ << ": " << mType << ": mmap is not supported ";
         return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
     }
     *_aidl_return = DEFAULT_AAUDIO_HARDWARE_BURST_MIN_DURATION_US;
-    LOG(DEBUG) << __func__ << ": returning " << *_aidl_return;
+    LOG(DEBUG) << __func__ << ": " << mType << ": returning " << *_aidl_return;
     return ndk::ScopedAStatus::ok();
 }
 
@@ -1548,45 +1589,45 @@
 
 ndk::ScopedAStatus Module::populateConnectedDevicePort(AudioPort* audioPort, int32_t) {
     if (audioPort->ext.getTag() != AudioPortExt::device) {
-        LOG(ERROR) << __func__ << ": not a device port: " << audioPort->toString();
+        LOG(ERROR) << __func__ << ": " << mType << ": not a device port: " << audioPort->toString();
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
     }
     const auto& devicePort = audioPort->ext.get<AudioPortExt::device>();
     if (!devicePort.device.type.connection.empty()) {
-        LOG(ERROR) << __func__
-                   << ": module implementation must override 'populateConnectedDevicePort' "
+        LOG(ERROR) << __func__ << ": " << mType << ": module implementation must override "
+                                                  "'populateConnectedDevicePort' "
                    << "to handle connection of external devices.";
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
     }
-    LOG(VERBOSE) << __func__ << ": do nothing and return ok";
+    LOG(VERBOSE) << __func__ << ": " << mType << ": do nothing and return ok";
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus Module::checkAudioPatchEndpointsMatch(
         const std::vector<AudioPortConfig*>& sources __unused,
         const std::vector<AudioPortConfig*>& sinks __unused) {
-    LOG(VERBOSE) << __func__ << ": do nothing and return ok";
+    LOG(VERBOSE) << __func__ << ": " << mType << ": do nothing and return ok";
     return ndk::ScopedAStatus::ok();
 }
 
 void Module::onExternalDeviceConnectionChanged(
         const ::aidl::android::media::audio::common::AudioPort& audioPort __unused,
         bool connected __unused) {
-    LOG(DEBUG) << __func__ << ": do nothing and return";
+    LOG(DEBUG) << __func__ << ": " << mType << ": do nothing and return";
 }
 
 void Module::onPrepareToDisconnectExternalDevice(
         const ::aidl::android::media::audio::common::AudioPort& audioPort __unused) {
-    LOG(DEBUG) << __func__ << ": do nothing and return";
+    LOG(DEBUG) << __func__ << ": " << mType << ": do nothing and return";
 }
 
 ndk::ScopedAStatus Module::onMasterMuteChanged(bool mute __unused) {
-    LOG(VERBOSE) << __func__ << ": do nothing and return ok";
+    LOG(VERBOSE) << __func__ << ": " << mType << ": do nothing and return ok";
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus Module::onMasterVolumeChanged(float volume __unused) {
-    LOG(VERBOSE) << __func__ << ": do nothing and return ok";
+    LOG(VERBOSE) << __func__ << ": " << mType << ": do nothing and return ok";
     return ndk::ScopedAStatus::ok();
 }
 
diff --git a/audio/aidl/default/Stream.cpp b/audio/aidl/default/Stream.cpp
index 807348f..31b0645 100644
--- a/audio/aidl/default/Stream.cpp
+++ b/audio/aidl/default/Stream.cpp
@@ -21,6 +21,7 @@
 #include <Utils.h>
 #include <android-base/logging.h>
 #include <android/binder_ibinder_platform.h>
+#include <cutils/properties.h>
 #include <utils/SystemClock.h>
 #include <utils/Trace.h>
 
@@ -182,17 +183,19 @@
     switch (command.getTag()) {
         case Tag::halReservedExit: {
             const int32_t cookie = command.get<Tag::halReservedExit>();
+            StreamInWorkerLogic::Status status = Status::CONTINUE;
             if (cookie == (mContext->getInternalCommandCookie() ^ getTid())) {
                 mDriver->shutdown();
                 setClosed();
+                status = Status::EXIT;
             } else {
                 LOG(WARNING) << __func__ << ": EXIT command has a bad cookie: " << cookie;
             }
             if (cookie != 0) {  // This is an internal command, no need to reply.
-                return Status::EXIT;
-            } else {
-                break;
+                return status;
             }
+            // `cookie == 0` can only occur in the context of a VTS test, need to reply.
+            break;
         }
         case Tag::getStatus:
             populateReply(&reply, mIsConnected);
@@ -314,7 +317,11 @@
 bool StreamInWorkerLogic::read(size_t clientSize, StreamDescriptor::Reply* reply) {
     ATRACE_CALL();
     StreamContext::DataMQ* const dataMQ = mContext->getDataMQ();
-    const size_t byteCount = std::min({clientSize, dataMQ->availableToWrite(), mDataBufferSize});
+    StreamContext::DataMQ::Error fmqError = StreamContext::DataMQ::Error::NONE;
+    std::string fmqErrorMsg;
+    const size_t byteCount = std::min(
+            {clientSize, dataMQ->availableToWrite(&fmqError, &fmqErrorMsg), mDataBufferSize});
+    CHECK(fmqError == StreamContext::DataMQ::Error::NONE) << fmqErrorMsg;
     const bool isConnected = mIsConnected;
     const size_t frameSize = mContext->getFrameSize();
     size_t actualFrameCount = 0;
@@ -406,17 +413,19 @@
     switch (command.getTag()) {
         case Tag::halReservedExit: {
             const int32_t cookie = command.get<Tag::halReservedExit>();
+            StreamOutWorkerLogic::Status status = Status::CONTINUE;
             if (cookie == (mContext->getInternalCommandCookie() ^ getTid())) {
                 mDriver->shutdown();
                 setClosed();
+                status = Status::EXIT;
             } else {
                 LOG(WARNING) << __func__ << ": EXIT command has a bad cookie: " << cookie;
             }
             if (cookie != 0) {  // This is an internal command, no need to reply.
-                return Status::EXIT;
-            } else {
-                break;
+                return status;
             }
+            // `cookie == 0` can only occur in the context of a VTS test, need to reply.
+            break;
         }
         case Tag::getStatus:
             populateReply(&reply, mIsConnected);
@@ -586,7 +595,10 @@
 bool StreamOutWorkerLogic::write(size_t clientSize, StreamDescriptor::Reply* reply) {
     ATRACE_CALL();
     StreamContext::DataMQ* const dataMQ = mContext->getDataMQ();
-    const size_t readByteCount = dataMQ->availableToRead();
+    StreamContext::DataMQ::Error fmqError = StreamContext::DataMQ::Error::NONE;
+    std::string fmqErrorMsg;
+    const size_t readByteCount = dataMQ->availableToRead(&fmqError, &fmqErrorMsg);
+    CHECK(fmqError == StreamContext::DataMQ::Error::NONE) << fmqErrorMsg;
     const size_t frameSize = mContext->getFrameSize();
     bool fatal = false;
     int32_t latency = mContext->getNominalLatencyMs();
@@ -652,16 +664,34 @@
          isBitPositionFlagSet(flags.template get<AudioIoFlags::Tag::input>(),
                               AudioInputFlags::FAST)) ||
         (flags.getTag() == AudioIoFlags::Tag::output &&
-         isBitPositionFlagSet(flags.template get<AudioIoFlags::Tag::output>(),
-                              AudioOutputFlags::FAST))) {
+         (isBitPositionFlagSet(flags.template get<AudioIoFlags::Tag::output>(),
+                               AudioOutputFlags::FAST) ||
+          isBitPositionFlagSet(flags.template get<AudioIoFlags::Tag::output>(),
+                               AudioOutputFlags::SPATIALIZER)))) {
         // FAST workers should be run with a SCHED_FIFO scheduler, however the host process
         // might be lacking the capability to request it, thus a failure to set is not an error.
         pid_t workerTid = mWorker->getTid();
         if (workerTid > 0) {
-            struct sched_param param;
-            param.sched_priority = 3;  // Must match SchedulingPolicyService.PRIORITY_MAX (Java).
+            constexpr int32_t kRTPriorityMin = 1;  // SchedulingPolicyService.PRIORITY_MIN (Java).
+            constexpr int32_t kRTPriorityMax = 3;  // SchedulingPolicyService.PRIORITY_MAX (Java).
+            int priorityBoost = kRTPriorityMax;
+            if (flags.getTag() == AudioIoFlags::Tag::output &&
+                isBitPositionFlagSet(flags.template get<AudioIoFlags::Tag::output>(),
+                                     AudioOutputFlags::SPATIALIZER)) {
+                const int32_t sptPrio =
+                        property_get_int32("audio.spatializer.priority", kRTPriorityMin);
+                if (sptPrio >= kRTPriorityMin && sptPrio <= kRTPriorityMax) {
+                    priorityBoost = sptPrio;
+                } else {
+                    LOG(WARNING) << __func__ << ": invalid spatializer priority: " << sptPrio;
+                    return ndk::ScopedAStatus::ok();
+                }
+            }
+            struct sched_param param = {
+                    .sched_priority = priorityBoost,
+            };
             if (sched_setscheduler(workerTid, SCHED_FIFO | SCHED_RESET_ON_FORK, &param) != 0) {
-                PLOG(WARNING) << __func__ << ": failed to set FIFO scheduler for a fast thread";
+                PLOG(WARNING) << __func__ << ": failed to set FIFO scheduler and priority";
             }
         } else {
             LOG(WARNING) << __func__ << ": invalid worker tid: " << workerTid;
diff --git a/audio/aidl/default/apex/com.android.hardware.audio/Android.bp b/audio/aidl/default/apex/com.android.hardware.audio/Android.bp
index ee7e46e..ee92512 100644
--- a/audio/aidl/default/apex/com.android.hardware.audio/Android.bp
+++ b/audio/aidl/default/apex/com.android.hardware.audio/Android.bp
@@ -46,5 +46,6 @@
     prebuilts: [
         "android.hardware.audio.service-aidl.example.rc",
         "android.hardware.audio.service-aidl.xml",
+        "android.hardware.bluetooth.audio.xml",
     ],
 }
diff --git a/audio/aidl/default/audio_effects_config.xml b/audio/aidl/default/audio_effects_config.xml
index e859a0e..c01eb3f 100644
--- a/audio/aidl/default/audio_effects_config.xml
+++ b/audio/aidl/default/audio_effects_config.xml
@@ -77,8 +77,6 @@
         <effect name="dynamics_processing" library="dynamics_processing" uuid="e0e6539b-1781-7261-676f-6d7573696340"/>
         <effect name="haptic_generator" library="haptic_generator" uuid="97c4acd1-8b82-4f2f-832e-c2fe5d7a9931"/>
         <effect name="loudness_enhancer" library="loudness_enhancer" uuid="fa415329-2034-4bea-b5dc-5b381c8d1e2c"/>
-        <effect name="env_reverb" library="env_reverbsw" uuid="fa819886-588b-11ed-9b6a-0242ac120002"/>
-        <effect name="preset_reverb" library="preset_reverbsw" uuid="fa8199c6-588b-11ed-9b6a-0242ac120002"/>
         <effect name="reverb_env_aux" library="reverb" uuid="4a387fc0-8ab3-11df-8bad-0002a5d5c51b"/>
         <effect name="reverb_env_ins" library="reverb" uuid="c7a511a0-a3bb-11df-860e-0002a5d5c51b"/>
         <effect name="reverb_pre_aux" library="reverb" uuid="f29a1400-a3bb-11df-8ddc-0002a5d5c51b"/>
diff --git a/audio/aidl/default/bluetooth/ModuleBluetooth.cpp b/audio/aidl/default/bluetooth/ModuleBluetooth.cpp
index ac375a0..8c381cd 100644
--- a/audio/aidl/default/bluetooth/ModuleBluetooth.cpp
+++ b/audio/aidl/default/bluetooth/ModuleBluetooth.cpp
@@ -224,31 +224,19 @@
     const auto& devicePort = audioPort->ext.get<AudioPortExt::device>();
     const auto& description = devicePort.device.type;
     // This method must return an error when the device can not be connected.
-    if (description.connection == AudioDeviceDescription::CONNECTION_BT_A2DP) {
-        bool isA2dpEnabled = false;
-        if (!!mBluetoothA2dp) {
-            RETURN_STATUS_IF_ERROR((*mBluetoothA2dp).isEnabled(&isA2dpEnabled));
-        }
-        LOG(DEBUG) << __func__ << ": isA2dpEnabled: " << isA2dpEnabled;
-        if (!isA2dpEnabled) return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
-    } else if (description.connection == AudioDeviceDescription::CONNECTION_BT_LE) {
-        bool isLeEnabled = false;
-        if (!!mBluetoothLe) {
-            RETURN_STATUS_IF_ERROR((*mBluetoothLe).isEnabled(&isLeEnabled));
-        }
-        LOG(DEBUG) << __func__ << ": isLeEnabled: " << isLeEnabled;
-        if (!isLeEnabled) return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
-    } else if (description.connection == AudioDeviceDescription::CONNECTION_WIRELESS &&
-               description.type == AudioDeviceType::OUT_HEARING_AID) {
-        // Hearing aids can use a number of profiles, no single switch exists.
-    } else {
+    // Since A2DP/LE status events are sent asynchronously, it is more reliable
+    // to attempt connecting to the BT stack rather than judge by the A2DP/LE status.
+    if (description.connection != AudioDeviceDescription::CONNECTION_BT_A2DP &&
+        description.connection != AudioDeviceDescription::CONNECTION_BT_LE &&
+        !(description.connection == AudioDeviceDescription::CONNECTION_WIRELESS &&
+          description.type == AudioDeviceType::OUT_HEARING_AID)) {
         LOG(ERROR) << __func__ << ": unsupported device type: " << audioPort->toString();
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
     }
     CachedProxy proxy;
     RETURN_STATUS_IF_ERROR(createProxy(*audioPort, nextPortId, proxy));
-    // Since the device is already connected and configured by the BT stack, provide
-    // the current configuration instead of all possible profiles.
+    // If the device is actually connected, it is configured by the BT stack.
+    // Provide the current configuration instead of all possible profiles.
     const auto& pcmConfig = proxy.pcmConfig;
     audioPort->profiles.clear();
     audioPort->profiles.push_back(
diff --git a/audio/aidl/default/bluetooth/StreamBluetooth.cpp b/audio/aidl/default/bluetooth/StreamBluetooth.cpp
index 77e48df..efab470 100644
--- a/audio/aidl/default/bluetooth/StreamBluetooth.cpp
+++ b/audio/aidl/default/bluetooth/StreamBluetooth.cpp
@@ -16,16 +16,13 @@
 
 #include <algorithm>
 
-#define ATRACE_TAG ATRACE_TAG_AUDIO
 #define LOG_TAG "AHAL_StreamBluetooth"
 #include <Utils.h>
 #include <android-base/logging.h>
 #include <audio_utils/clock.h>
-#include <utils/Trace.h>
 
 #include "core-impl/StreamBluetooth.h"
 
-using aidl::android::hardware::audio::common::frameCountFromDurationUs;
 using aidl::android::hardware::audio::common::SinkMetadata;
 using aidl::android::hardware::audio::common::SourceMetadata;
 using aidl::android::hardware::audio::core::VendorParameter;
@@ -67,8 +64,6 @@
                                        : (mIsInput ? kBluetoothDefaultInputBufferMs
                                                    : kBluetoothDefaultOutputBufferMs) *
                                                  1000),
-      mPreferredFrameCount(
-              frameCountFromDurationUs(mPreferredDataIntervalUs, pcmConfig.sampleRateHz)),
       mBtDeviceProxy(btDeviceProxy) {}
 
 ::android::status_t StreamBluetooth::init() {
@@ -77,6 +72,7 @@
         // This is a normal situation in VTS tests.
         LOG(INFO) << __func__ << ": no BT HAL proxy, stream is non-functional";
     }
+    LOG(INFO) << __func__ << ": preferred data interval (us): " << mPreferredDataIntervalUs;
     return ::android::OK;
 }
 
@@ -97,23 +93,22 @@
 ::android::status_t StreamBluetooth::transfer(void* buffer, size_t frameCount,
                                               size_t* actualFrameCount, int32_t* latencyMs) {
     std::lock_guard guard(mLock);
+    *actualFrameCount = 0;
+    *latencyMs = StreamDescriptor::LATENCY_UNKNOWN;
     if (mBtDeviceProxy == nullptr || mBtDeviceProxy->getState() == BluetoothStreamState::DISABLED) {
-        *actualFrameCount = 0;
-        *latencyMs = StreamDescriptor::LATENCY_UNKNOWN;
+        // The BT session is turned down, silently ignore write.
         return ::android::OK;
     }
-    *actualFrameCount = 0;
-    *latencyMs = 0;
     if (!mBtDeviceProxy->start()) {
-        LOG(ERROR) << __func__ << ": state= " << mBtDeviceProxy->getState() << " failed to start";
-        return -EIO;
+        LOG(WARNING) << __func__ << ": state= " << mBtDeviceProxy->getState()
+                     << " failed to start, will retry";
+        return ::android::OK;
     }
-    const size_t fc = std::min(frameCount, mPreferredFrameCount);
-    const size_t bytesToTransfer = fc * mFrameSizeBytes;
+    *latencyMs = 0;
+    const size_t bytesToTransfer = frameCount * mFrameSizeBytes;
     const size_t bytesTransferred = mIsInput ? mBtDeviceProxy->readData(buffer, bytesToTransfer)
                                              : mBtDeviceProxy->writeData(buffer, bytesToTransfer);
     *actualFrameCount = bytesTransferred / mFrameSizeBytes;
-    ATRACE_INT("BTdropped", bytesToTransfer - bytesTransferred);
     PresentationPosition presentation_position;
     if (!mBtDeviceProxy->getPresentationPosition(presentation_position)) {
         presentation_position.remoteDeviceAudioDelayNanos =
diff --git a/audio/aidl/default/include/core-impl/ChildInterface.h b/audio/aidl/default/include/core-impl/ChildInterface.h
index f5f1855..161f6db 100644
--- a/audio/aidl/default/include/core-impl/ChildInterface.h
+++ b/audio/aidl/default/include/core-impl/ChildInterface.h
@@ -48,9 +48,9 @@
     }
     AIBinder* getBinder() {
         if (this->second.get() == nullptr) {
-            this->second = this->first->asBinder();
-            AIBinder_setMinSchedulerPolicy(this->second.get(), SCHED_NORMAL,
-                                           ANDROID_PRIORITY_AUDIO);
+            const auto binder = this->second = this->first->asBinder();
+            AIBinder_setMinSchedulerPolicy(binder.get(), SCHED_NORMAL, ANDROID_PRIORITY_AUDIO);
+            AIBinder_setInheritRt(binder.get(), true);
         }
         return this->second.get();
     }
diff --git a/audio/aidl/default/include/core-impl/Module.h b/audio/aidl/default/include/core-impl/Module.h
index ce71d70..a326217 100644
--- a/audio/aidl/default/include/core-impl/Module.h
+++ b/audio/aidl/default/include/core-impl/Module.h
@@ -211,9 +211,12 @@
         const int32_t rawSizeFrames =
                 aidl::android::hardware::audio::common::frameCountFromDurationMs(latencyMs,
                                                                                  sampleRateHz);
-        if (latencyMs >= 5) return rawSizeFrames;
+        // Round up to nearest 16 frames since in the framework this is the size of a mixer burst.
+        const int32_t multipleOf16 = (rawSizeFrames + 15) & ~15;
+        if (sampleRateHz < 44100 || multipleOf16 <= 512) return multipleOf16;
+        // Larger buffers should use powers of 2.
         int32_t powerOf2 = 1;
-        while (powerOf2 < rawSizeFrames) powerOf2 <<= 1;
+        while (powerOf2 < multipleOf16) powerOf2 <<= 1;
         return powerOf2;
     }
 
diff --git a/audio/aidl/default/include/core-impl/StreamBluetooth.h b/audio/aidl/default/include/core-impl/StreamBluetooth.h
index 35c3183..7f4239c 100644
--- a/audio/aidl/default/include/core-impl/StreamBluetooth.h
+++ b/audio/aidl/default/include/core-impl/StreamBluetooth.h
@@ -63,7 +63,6 @@
     const std::weak_ptr<IBluetoothA2dp> mBluetoothA2dp;
     const std::weak_ptr<IBluetoothLe> mBluetoothLe;
     const size_t mPreferredDataIntervalUs;
-    const size_t mPreferredFrameCount;
     mutable std::mutex mLock;
     // The lock is also used to serialize calls to the proxy.
     std::shared_ptr<::android::bluetooth::audio::aidl::BluetoothAudioPortAidl> mBtDeviceProxy
diff --git a/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h b/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h
index b2cdc28..0d50c96 100644
--- a/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h
+++ b/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h
@@ -55,8 +55,8 @@
     r_submix::AudioConfig mStreamConfig;
     std::shared_ptr<r_submix::SubmixRoute> mCurrentRoute = nullptr;
 
-    // limit for number of read error log entries to avoid spamming the logs
-    static constexpr int kMaxReadErrorLogs = 5;
+    // Limit for the number of error log entries to avoid spamming the logs.
+    static constexpr int kMaxErrorLogs = 5;
     // The duration of kMaxReadFailureAttempts * READ_ATTEMPT_SLEEP_MS must be strictly inferior
     // to the duration of a record buffer at the current record sample rate (of the device, not of
     // the recording itself). Here we have: 3 * 5ms = 15ms < 1024 frames * 1000 / 48000 = 21.333ms
@@ -68,6 +68,7 @@
     long mFramesSinceStart = 0;
     int mReadErrorCount = 0;
     int mReadFailureCount = 0;
+    int mWriteShutdownCount = 0;
 };
 
 class StreamInRemoteSubmix final : public StreamIn, public StreamSwitcher {
diff --git a/audio/aidl/default/include/effect-impl/EffectImpl.h b/audio/aidl/default/include/effect-impl/EffectImpl.h
index 21f6502..d3bb7f4 100644
--- a/audio/aidl/default/include/effect-impl/EffectImpl.h
+++ b/audio/aidl/default/include/effect-impl/EffectImpl.h
@@ -89,6 +89,11 @@
     void process() override;
 
   protected:
+    // current Hal version
+    int mVersion = 0;
+    // Use kEventFlagNotEmpty for V1 HAL, kEventFlagDataMqNotEmpty for V2 and above
+    int mDataMqNotEmptyEf = aidl::android::hardware::audio::effect::kEventFlagDataMqNotEmpty;
+
     State mState GUARDED_BY(mImplMutex) = State::INIT;
 
     IEffect::Status status(binder_status_t status, size_t consumed, size_t produced);
@@ -107,6 +112,11 @@
     virtual ndk::ScopedAStatus commandImpl(CommandId id) REQUIRES(mImplMutex);
 
     RetCode notifyEventFlag(uint32_t flag);
+
+    std::string getEffectNameWithVersion() {
+        return getEffectName() + "V" + std::to_string(mVersion);
+    }
+
     ::android::hardware::EventFlag* mEventFlag;
 };
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/include/effect-impl/EffectThread.h b/audio/aidl/default/include/effect-impl/EffectThread.h
index 3dbb0e6..ec2a658 100644
--- a/audio/aidl/default/include/effect-impl/EffectThread.h
+++ b/audio/aidl/default/include/effect-impl/EffectThread.h
@@ -31,11 +31,9 @@
 
 class EffectThread {
   public:
-    // default priority is same as HIDL: ANDROID_PRIORITY_URGENT_AUDIO
-    EffectThread();
     virtual ~EffectThread();
 
-    // called by effect implementation.
+    // called by effect implementation
     RetCode createThread(const std::string& name, int priority = ANDROID_PRIORITY_URGENT_AUDIO);
     RetCode destroyThread();
     RetCode startThread();
diff --git a/audio/aidl/default/include/effect-impl/EffectTypes.h b/audio/aidl/default/include/effect-impl/EffectTypes.h
index 9740d6e..66c0ff1 100644
--- a/audio/aidl/default/include/effect-impl/EffectTypes.h
+++ b/audio/aidl/default/include/effect-impl/EffectTypes.h
@@ -75,49 +75,49 @@
     return out << "EnumError: " << code;
 }
 
-#define RETURN_IF_ASTATUS_NOT_OK(status, message)                                              \
-    do {                                                                                       \
-        const ::ndk::ScopedAStatus curr_status = (status);                                     \
-        if (!curr_status.isOk()) {                                                             \
-            LOG(ERROR) << __func__ << ":" << __LINE__                                          \
-                       << "return with status: " << curr_status.getDescription() << (message); \
-            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(                           \
-                    curr_status.getExceptionCode(), (message));                                \
-        }                                                                                      \
+#define RETURN_IF_ASTATUS_NOT_OK(status, message)                                               \
+    do {                                                                                        \
+        const ::ndk::ScopedAStatus curr_status = (status);                                      \
+        if (!curr_status.isOk()) {                                                              \
+            LOG(ERROR) << __func__ << ": line" << __LINE__                                      \
+                       << " return with status: " << curr_status.getDescription() << (message); \
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(                            \
+                    curr_status.getExceptionCode(), (message));                                 \
+        }                                                                                       \
     } while (0)
 
 #define RETURN_IF(expr, exception, message)                                                  \
     do {                                                                                     \
         if (expr) {                                                                          \
-            LOG(ERROR) << __func__ << ":" << __LINE__ << " return with expr " << #expr;      \
+            LOG(ERROR) << __func__ << ": line" << __LINE__ << " return with expr " << #expr; \
             return ndk::ScopedAStatus::fromExceptionCodeWithMessage((exception), (message)); \
         }                                                                                    \
     } while (0)
 
-#define RETURN_OK_IF(expr)                                                             \
-    do {                                                                               \
-        if (expr) {                                                                    \
-            LOG(INFO) << __func__ << ":" << __LINE__ << " return with expr " << #expr; \
-            return ndk::ScopedAStatus::ok();                                           \
-        }                                                                              \
+#define RETURN_OK_IF(expr)                                                                  \
+    do {                                                                                    \
+        if (expr) {                                                                         \
+            LOG(INFO) << __func__ << ": line" << __LINE__ << " return with expr " << #expr; \
+            return ndk::ScopedAStatus::ok();                                                \
+        }                                                                                   \
     } while (0)
 
-#define RETURN_VALUE_IF(expr, ret, log)                                                  \
-    do {                                                                                 \
-        if (expr) {                                                                      \
-            LOG(ERROR) << __func__ << ":" << __LINE__ << " return with expr \"" << #expr \
-                       << "\":" << (log);                                                \
-            return ret;                                                                  \
-        }                                                                                \
+#define RETURN_VALUE_IF(expr, ret, log)                                                       \
+    do {                                                                                      \
+        if (expr) {                                                                           \
+            LOG(ERROR) << __func__ << ": line" << __LINE__ << " return with expr \"" << #expr \
+                       << "\":" << (log);                                                     \
+            return ret;                                                                       \
+        }                                                                                     \
     } while (0)
 
-#define RETURN_IF_BINDER_EXCEPTION(functor)                                 \
-    {                                                                       \
-        binder_exception_t exception = functor;                             \
-        if (EX_NONE != exception) {                                         \
-            LOG(ERROR) << #functor << ":  failed with error " << exception; \
-            return ndk::ScopedAStatus::fromExceptionCode(exception);        \
-        }                                                                   \
+#define RETURN_IF_BINDER_EXCEPTION(functor)                                \
+    {                                                                      \
+        binder_exception_t exception = functor;                            \
+        if (EX_NONE != exception) {                                        \
+            LOG(ERROR) << #functor << ": failed with error " << exception; \
+            return ndk::ScopedAStatus::fromExceptionCode(exception);       \
+        }                                                                  \
     }
 
 /**
diff --git a/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp b/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp
index fa4135d..ca3f91a 100644
--- a/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp
+++ b/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp
@@ -134,12 +134,19 @@
     *latencyMs = getDelayInUsForFrameCount(getStreamPipeSizeInFrames()) / 1000;
     LOG(VERBOSE) << __func__ << ": Latency " << *latencyMs << "ms";
     mCurrentRoute->exitStandby(mIsInput);
-    RETURN_STATUS_IF_ERROR(mIsInput ? inRead(buffer, frameCount, actualFrameCount)
-                                    : outWrite(buffer, frameCount, actualFrameCount));
+    ::android::status_t status = mIsInput ? inRead(buffer, frameCount, actualFrameCount)
+                                          : outWrite(buffer, frameCount, actualFrameCount);
+    if ((status != ::android::OK && mIsInput) ||
+        ((status != ::android::OK && status != ::android::DEAD_OBJECT) && !mIsInput)) {
+        return status;
+    }
+    mFramesSinceStart += *actualFrameCount;
+    if (!mIsInput && status != ::android::DEAD_OBJECT) return ::android::OK;
+    // Input streams always need to block, output streams need to block when there is no sink.
+    // When the sink exists, more sophisticated blocking algorithm is implemented by MonoPipe.
     const long bufferDurationUs =
             (*actualFrameCount) * MICROS_PER_SECOND / mContext.getSampleRate();
     const auto totalDurationUs = (::android::uptimeNanos() - mStartTimeNs) / NANOS_PER_MICROSECOND;
-    mFramesSinceStart += *actualFrameCount;
     const long totalOffsetUs =
             mFramesSinceStart * MICROS_PER_SECOND / mContext.getSampleRate() - totalDurationUs;
     LOG(VERBOSE) << __func__ << ": totalOffsetUs " << totalOffsetUs;
@@ -186,14 +193,17 @@
     if (sink != nullptr) {
         if (sink->isShutdown()) {
             sink.clear();
-            LOG(DEBUG) << __func__ << ": pipe shutdown, ignoring the write";
+            if (++mWriteShutdownCount < kMaxErrorLogs) {
+                LOG(DEBUG) << __func__ << ": pipe shutdown, ignoring the write. (limited logging)";
+            }
             *actualFrameCount = frameCount;
-            return ::android::OK;
+            return ::android::DEAD_OBJECT;  // Induce wait in `transfer`.
         }
     } else {
         LOG(FATAL) << __func__ << ": without a pipe!";
         return ::android::UNKNOWN_ERROR;
     }
+    mWriteShutdownCount = 0;
 
     LOG(VERBOSE) << __func__ << ": " << mDeviceAddress.toString() << ", " << frameCount
                  << " frames";
@@ -260,7 +270,7 @@
     // about to read from audio source
     sp<MonoPipeReader> source = mCurrentRoute->getSource();
     if (source == nullptr) {
-        if (++mReadErrorCount < kMaxReadErrorLogs) {
+        if (++mReadErrorCount < kMaxErrorLogs) {
             LOG(ERROR) << __func__
                        << ": no audio pipe yet we're trying to read! (not all errors will be "
                           "logged)";
@@ -275,8 +285,9 @@
     char* buff = (char*)buffer;
     size_t actuallyRead = 0;
     long remainingFrames = frameCount;
-    const int64_t deadlineTimeNs = ::android::uptimeNanos() +
-                                   getDelayInUsForFrameCount(frameCount) * NANOS_PER_MICROSECOND;
+    const int64_t deadlineTimeNs =
+            ::android::uptimeNanos() +
+            getDelayInUsForFrameCount(frameCount) * NANOS_PER_MICROSECOND / 2;
     while (remainingFrames > 0) {
         ssize_t framesRead = source->read(buff, remainingFrames);
         LOG(VERBOSE) << __func__ << ": frames read " << framesRead;
diff --git a/audio/aidl/default/spatializer/SpatializerSw.cpp b/audio/aidl/default/spatializer/SpatializerSw.cpp
index ab4a53e..fd3c192 100644
--- a/audio/aidl/default/spatializer/SpatializerSw.cpp
+++ b/audio/aidl/default/spatializer/SpatializerSw.cpp
@@ -64,7 +64,12 @@
 
 const std::string SpatializerSw::kEffectName = "SpatializerSw";
 
+const AudioChannelLayout kSupportedChannelMask =
+        AudioChannelLayout::make<AudioChannelLayout::layoutMask>(
+                AudioChannelLayout::LAYOUT_5POINT1);
 const std::vector<Range::SpatializerRange> SpatializerSw::kRanges = {
+        MAKE_RANGE(Spatializer, supportedChannelLayout, {kSupportedChannelMask},
+                   {kSupportedChannelMask}),
         MAKE_RANGE(Spatializer, spatializationLevel, Spatialization::Level::NONE,
                    Spatialization::Level::BED_PLUS_OBJECTS),
         MAKE_RANGE(Spatializer, spatializationMode, Spatialization::Mode::BINAURAL,
@@ -133,6 +138,11 @@
 }
 
 std::shared_ptr<EffectContext> SpatializerSw::createContext(const Parameter::Common& common) {
+    if (common.input.base.channelMask != kSupportedChannelMask) {
+        LOG(ERROR) << __func__
+                   << " channelMask not supported: " << common.input.base.channelMask.toString();
+        return nullptr;
+    }
     if (mContext) {
         LOG(DEBUG) << __func__ << " context already exist";
     } else {
diff --git a/audio/aidl/vts/Android.bp b/audio/aidl/vts/Android.bp
index d219fa4..cbd42c0 100644
--- a/audio/aidl/vts/Android.bp
+++ b/audio/aidl/vts/Android.bp
@@ -121,6 +121,9 @@
     name: "VtsHalEnvironmentalReverbTargetTest",
     defaults: ["VtsHalAudioEffectTargetTestDefaults"],
     srcs: ["VtsHalEnvironmentalReverbTargetTest.cpp"],
+    shared_libs: [
+        "libaudioutils",
+    ],
 }
 
 cc_test {
@@ -145,12 +148,18 @@
     name: "VtsHalPresetReverbTargetTest",
     defaults: ["VtsHalAudioEffectTargetTestDefaults"],
     srcs: ["VtsHalPresetReverbTargetTest.cpp"],
+    shared_libs: [
+        "libaudioutils",
+    ],
 }
 
 cc_test {
     name: "VtsHalVirtualizerTargetTest",
     defaults: ["VtsHalAudioEffectTargetTestDefaults"],
     srcs: ["VtsHalVirtualizerTargetTest.cpp"],
+    shared_libs: [
+        "libaudioutils",
+    ],
 }
 
 cc_test {
diff --git a/audio/aidl/vts/EffectFactoryHelper.h b/audio/aidl/vts/EffectFactoryHelper.h
index 7100431..54b82d3 100644
--- a/audio/aidl/vts/EffectFactoryHelper.h
+++ b/audio/aidl/vts/EffectFactoryHelper.h
@@ -23,6 +23,7 @@
 
 #include <aidl/Vintf.h>
 #include <android/binder_auto_utils.h>
+#include <system/audio_effects/aidl_effects_utils.h>
 
 #include "AudioHalBinderServiceUtil.h"
 #include "TestUtils.h"
@@ -35,21 +36,6 @@
 
 class EffectFactoryHelper {
   public:
-    explicit EffectFactoryHelper(const std::string& name) : mServiceName(name) {}
-
-    void ConnectToFactoryService() {
-        mEffectFactory = IFactory::fromBinder(binderUtil.connectToService(mServiceName));
-        ASSERT_NE(mEffectFactory, nullptr);
-    }
-
-    void RestartFactoryService() {
-        ASSERT_NE(mEffectFactory, nullptr);
-        mEffectFactory = IFactory::fromBinder(binderUtil.restartService());
-        ASSERT_NE(mEffectFactory, nullptr);
-    }
-
-    std::shared_ptr<IFactory> GetFactory() const { return mEffectFactory; }
-
     static std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> getAllEffectDescriptors(
             std::string serviceName, std::optional<AudioUuid> type = std::nullopt) {
         AudioHalBinderServiceUtil util;
@@ -74,8 +60,13 @@
         return result;
     }
 
-  private:
-    std::shared_ptr<IFactory> mEffectFactory;
-    std::string mServiceName;
-    AudioHalBinderServiceUtil binderUtil;
+    static int getHalVersion(const std::shared_ptr<IFactory>& factory) {
+        int version = 0;
+        return (factory && factory->getInterfaceVersion(&version).isOk()) ? version : 0;
+    }
+
+    static bool isReopenSupported(const std::shared_ptr<IFactory>& factory) {
+        return EffectFactoryHelper::getHalVersion(factory) >=
+               aidl::android::hardware::audio::effect::kReopenSupportedVersion;
+    }
 };
diff --git a/audio/aidl/vts/EffectHelper.h b/audio/aidl/vts/EffectHelper.h
index 82a07fd..72a4667 100644
--- a/audio/aidl/vts/EffectHelper.h
+++ b/audio/aidl/vts/EffectHelper.h
@@ -18,6 +18,7 @@
 
 #include <algorithm>
 #include <memory>
+#include <optional>
 #include <string>
 #include <type_traits>
 #include <unordered_map>
@@ -42,11 +43,18 @@
 using namespace android;
 using aidl::android::hardware::audio::effect::CommandId;
 using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidSpatializer;
+using aidl::android::hardware::audio::effect::getRange;
 using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::isRangeValid;
+using aidl::android::hardware::audio::effect::kEffectTypeUuidSpatializer;
+using aidl::android::hardware::audio::effect::kEventFlagDataMqNotEmpty;
 using aidl::android::hardware::audio::effect::kEventFlagDataMqUpdate;
 using aidl::android::hardware::audio::effect::kEventFlagNotEmpty;
+using aidl::android::hardware::audio::effect::kReopenSupportedVersion;
 using aidl::android::hardware::audio::effect::Parameter;
 using aidl::android::hardware::audio::effect::Range;
+using aidl::android::hardware::audio::effect::Spatializer;
 using aidl::android::hardware::audio::effect::State;
 using aidl::android::hardware::common::fmq::SynchronizedReadWrite;
 using aidl::android::media::audio::common::AudioChannelLayout;
@@ -70,19 +78,23 @@
 static inline std::string getPrefix(Descriptor& descriptor) {
     std::string prefix = "Implementor_" + descriptor.common.implementor + "_name_" +
                          descriptor.common.name + "_UUID_" + toString(descriptor.common.id.uuid);
+    std::replace_if(
+            prefix.begin(), prefix.end(), [](const char c) { return !std::isalnum(c); }, '_');
     return prefix;
 }
 
 class EffectHelper {
   public:
-    static void create(std::shared_ptr<IFactory> factory, std::shared_ptr<IEffect>& effect,
-                       Descriptor& desc, binder_status_t status = EX_NONE) {
+    void create(std::shared_ptr<IFactory> factory, std::shared_ptr<IEffect>& effect,
+                Descriptor& desc, binder_status_t status = EX_NONE) {
         ASSERT_NE(factory, nullptr);
         auto& id = desc.common.id;
         ASSERT_STATUS(status, factory->createEffect(id.uuid, &effect));
         if (status == EX_NONE) {
             ASSERT_NE(effect, nullptr) << toString(id.uuid);
         }
+        mIsSpatializer = id.type == getEffectTypeUuidSpatializer();
+        mDescriptor = desc;
     }
 
     static void destroyIgnoreRet(std::shared_ptr<IFactory> factory,
@@ -106,10 +118,9 @@
         ASSERT_STATUS(status, effect->open(common, specific, ret));
     }
 
-    static void open(std::shared_ptr<IEffect> effect, int session = 0,
-                     binder_status_t status = EX_NONE) {
+    void open(std::shared_ptr<IEffect> effect, int session = 0, binder_status_t status = EX_NONE) {
         ASSERT_NE(effect, nullptr);
-        Parameter::Common common = EffectHelper::createParamCommon(session);
+        Parameter::Common common = createParamCommon(session);
         IEffect::OpenEffectReturn ret;
         ASSERT_NO_FATAL_FAILURE(open(effect, common, std::nullopt /* specific */, &ret, status));
     }
@@ -158,7 +169,7 @@
         std::fill(buffer.begin(), buffer.end(), 0x5a);
     }
     static void writeToFmq(std::unique_ptr<StatusMQ>& statusMq, std::unique_ptr<DataMQ>& dataMq,
-                           const std::vector<float>& buffer) {
+                           const std::vector<float>& buffer, int version) {
         const size_t available = dataMq->availableToWrite();
         ASSERT_NE(0Ul, available);
         auto bufferFloats = buffer.size();
@@ -169,7 +180,8 @@
         ASSERT_EQ(::android::OK,
                   EventFlag::createEventFlag(statusMq->getEventFlagWord(), &efGroup));
         ASSERT_NE(nullptr, efGroup);
-        efGroup->wake(kEventFlagNotEmpty);
+        efGroup->wake(version >= kReopenSupportedVersion ? kEventFlagDataMqNotEmpty
+                                                         : kEventFlagNotEmpty);
         ASSERT_EQ(::android::OK, EventFlag::deleteEventFlag(&efGroup));
     }
     static void readFromFmq(std::unique_ptr<StatusMQ>& statusMq, size_t statusNum,
@@ -202,15 +214,31 @@
                                                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,
-            AudioChannelLayout inputChannelLayout =
-                    AudioChannelLayout::make<AudioChannelLayout::layoutMask>(
-                            AudioChannelLayout::LAYOUT_STEREO),
-            AudioChannelLayout outputChannelLayout =
-                    AudioChannelLayout::make<AudioChannelLayout::layoutMask>(
-                            AudioChannelLayout::LAYOUT_STEREO)) {
+
+    Parameter::Common createParamCommon(int session = 0, int ioHandle = -1, int iSampleRate = 48000,
+                                        int oSampleRate = 48000, long iFrameCount = 0x100,
+                                        long oFrameCount = 0x100) {
+        AudioChannelLayout defaultLayout = AudioChannelLayout::make<AudioChannelLayout::layoutMask>(
+                AudioChannelLayout::LAYOUT_STEREO);
+        // query supported input layout and use it as the default parameter in common
+        if (mIsSpatializer && isRangeValid<Range::spatializer>(Spatializer::supportedChannelLayout,
+                                                               mDescriptor.capability)) {
+            const auto layoutRange = getRange<Range::spatializer, Range::SpatializerRange>(
+                    mDescriptor.capability, Spatializer::supportedChannelLayout);
+            if (std::vector<AudioChannelLayout> layouts;
+                layoutRange &&
+                0 != (layouts = layoutRange->min.get<Spatializer::supportedChannelLayout>())
+                                .size()) {
+                defaultLayout = layouts[0];
+            }
+        }
+        return createParamCommon(session, ioHandle, iSampleRate, oSampleRate, iFrameCount,
+                                 oFrameCount, defaultLayout, defaultLayout);
+    }
+    static Parameter::Common createParamCommon(int session, int ioHandle, int iSampleRate,
+                                               int oSampleRate, long iFrameCount, long oFrameCount,
+                                               AudioChannelLayout inputChannelLayout,
+                                               AudioChannelLayout outputChannelLayout) {
         Parameter::Common common;
         common.session = session;
         common.ioHandle = ioHandle;
@@ -320,7 +348,10 @@
         ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
 
         // Write from buffer to message queues and calling process
-        EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, inputBuffer));
+        EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, inputBuffer, [&]() {
+            int version = 0;
+            return (mEffect && mEffect->getInterfaceVersion(&version).isOk()) ? version : 0;
+        }()));
 
         // Read the updated message queues into buffer
         EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(statusMQ, 1, outputMQ,
@@ -371,4 +402,7 @@
 
         return bufferMag;
     }
+
+    bool mIsSpatializer;
+    Descriptor mDescriptor;
 };
diff --git a/audio/aidl/vts/TestUtils.h b/audio/aidl/vts/TestUtils.h
index 0a5addc..3a6c137 100644
--- a/audio/aidl/vts/TestUtils.h
+++ b/audio/aidl/vts/TestUtils.h
@@ -108,7 +108,7 @@
     ({                                                                                            \
         if ((flags).hwAcceleratorMode ==                                                          \
                     aidl::android::hardware::audio::effect::Flags::HardwareAccelerator::TUNNEL || \
-            (flags).bypass) {                                                                     \
+            (flags).bypass || (flags).offloadIndication) {                                        \
             GTEST_SKIP() << "Skip data path for offload";                                         \
         }                                                                                         \
     })
diff --git a/audio/aidl/vts/VtsHalAECTargetTest.cpp b/audio/aidl/vts/VtsHalAECTargetTest.cpp
index f972b84..53b6757 100644
--- a/audio/aidl/vts/VtsHalAECTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAECTargetTest.cpp
@@ -52,7 +52,7 @@
         ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
 
         auto specific = getDefaultParamSpecific();
-        Parameter::Common common = EffectHelper::createParamCommon(
+        Parameter::Common common = createParamCommon(
                 0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
                 kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
         IEffect::OpenEffectReturn ret;
diff --git a/audio/aidl/vts/VtsHalAGC1TargetTest.cpp b/audio/aidl/vts/VtsHalAGC1TargetTest.cpp
index 75da589..f14afbc 100644
--- a/audio/aidl/vts/VtsHalAGC1TargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAGC1TargetTest.cpp
@@ -53,7 +53,7 @@
         ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
 
         Parameter::Specific specific = getDefaultParamSpecific();
-        Parameter::Common common = EffectHelper::createParamCommon(
+        Parameter::Common common = createParamCommon(
                 0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
                 kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
         IEffect::OpenEffectReturn ret;
diff --git a/audio/aidl/vts/VtsHalAGC2TargetTest.cpp b/audio/aidl/vts/VtsHalAGC2TargetTest.cpp
index 5f57a88..048d540 100644
--- a/audio/aidl/vts/VtsHalAGC2TargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAGC2TargetTest.cpp
@@ -54,7 +54,7 @@
         ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
 
         Parameter::Specific specific = getDefaultParamSpecific();
-        Parameter::Common common = EffectHelper::createParamCommon(
+        Parameter::Common common = createParamCommon(
                 0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
                 kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
         IEffect::OpenEffectReturn ret;
diff --git a/audio/aidl/vts/VtsHalAudioEffectFactoryTargetTest.cpp b/audio/aidl/vts/VtsHalAudioEffectFactoryTargetTest.cpp
index 4e86ec3..a19aa56 100644
--- a/audio/aidl/vts/VtsHalAudioEffectFactoryTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioEffectFactoryTargetTest.cpp
@@ -56,10 +56,7 @@
 /// Effect factory testing.
 class EffectFactoryTest : public testing::TestWithParam<std::string> {
   public:
-    void SetUp() override {
-        mFactoryHelper = std::make_unique<EffectFactoryHelper>(GetParam());
-        connectAndGetFactory();
-    }
+    void SetUp() override { connectAndGetFactory(); }
 
     void TearDown() override {
         for (auto& effect : mEffects) {
@@ -68,13 +65,14 @@
         }
     }
 
-    std::unique_ptr<EffectFactoryHelper> mFactoryHelper;
+    const std::string kServiceName = GetParam();
     std::shared_ptr<IFactory> mEffectFactory;
     std::vector<std::shared_ptr<IEffect>> mEffects;
     const Descriptor::Identity kNullId = {.uuid = getEffectUuidNull()};
     const Descriptor::Identity kZeroId = {.uuid = getEffectUuidZero()};
     const Descriptor kNullDesc = {.common.id = kNullId};
     const Descriptor kZeroDesc = {.common.id = kZeroId};
+    AudioHalBinderServiceUtil mBinderUtil;
 
     template <typename Functor>
     void ForEachId(const std::vector<Descriptor::Identity> ids, Functor functor) {
@@ -117,8 +115,11 @@
         }
     }
     void connectAndGetFactory() {
-        ASSERT_NO_FATAL_FAILURE(mFactoryHelper->ConnectToFactoryService());
-        mEffectFactory = mFactoryHelper->GetFactory();
+        mEffectFactory = IFactory::fromBinder(mBinderUtil.connectToService(kServiceName));
+        ASSERT_NE(mEffectFactory, nullptr);
+    }
+    void restartAndGetFactory() {
+        mEffectFactory = IFactory::fromBinder(mBinderUtil.restartService());
         ASSERT_NE(mEffectFactory, nullptr);
     }
 };
@@ -128,7 +129,8 @@
 }
 
 TEST_P(EffectFactoryTest, CanBeRestarted) {
-    ASSERT_NO_FATAL_FAILURE(mFactoryHelper->RestartFactoryService());
+    ASSERT_NE(mEffectFactory, nullptr);
+    restartAndGetFactory();
 }
 
 /**
@@ -250,8 +252,7 @@
     EXPECT_NE(descs.size(), 0UL);
     creatAndDestroyDescs(descs);
 
-    mFactoryHelper->RestartFactoryService();
-
+    restartAndGetFactory();
     connectAndGetFactory();
     creatAndDestroyDescs(descs);
 }
@@ -263,8 +264,7 @@
     EXPECT_NE(descs.size(), 0UL);
     std::vector<std::shared_ptr<IEffect>> effects = createWithDescs(descs);
 
-    ASSERT_NO_FATAL_FAILURE(mFactoryHelper->RestartFactoryService());
-
+    restartAndGetFactory();
     connectAndGetFactory();
     destroyEffects(effects, EX_ILLEGAL_ARGUMENT);
 }
diff --git a/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp b/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
index 5479825..2f47d07 100644
--- a/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
@@ -57,6 +57,7 @@
   public:
     AudioEffectTest() {
         std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
+        mVersion = EffectFactoryHelper::getHalVersion(mFactory);
     }
 
     void SetUp() override {}
@@ -75,6 +76,7 @@
     std::shared_ptr<IFactory> mFactory;
     std::shared_ptr<IEffect> mEffect;
     Descriptor mDescriptor;
+    int mVersion = 0;
 
     void setAndGetParameter(Parameter::Id id, const Parameter& set) {
         Parameter get;
@@ -394,7 +396,7 @@
 TEST_P(AudioEffectTest, VerifyCommonParametersAfterOpen) {
     ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
 
-    Parameter::Common common = EffectHelper::createParamCommon();
+    Parameter::Common common = createParamCommon();
     IEffect::OpenEffectReturn ret;
     ASSERT_NO_FATAL_FAILURE(open(mEffect, common, std::nullopt /* specific */, &ret, EX_NONE));
 
@@ -414,8 +416,8 @@
     ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
     ASSERT_NO_FATAL_FAILURE(open(mEffect));
 
-    Parameter::Common common = EffectHelper::createParamCommon(
-            0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */);
+    Parameter::Common common = createParamCommon(0 /* session */, 1 /* ioHandle */,
+                                                 44100 /* iSampleRate */, 44100 /* oSampleRate */);
     Parameter::Id id = Parameter::Id::make<Parameter::Id::commonTag>(Parameter::common);
     ASSERT_NO_FATAL_FAILURE(setAndGetParameter(id, Parameter::make<Parameter::common>(common)));
 
@@ -430,8 +432,8 @@
     ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
     ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
 
-    Parameter::Common common = EffectHelper::createParamCommon(
-            0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */);
+    Parameter::Common common = createParamCommon(0 /* session */, 1 /* ioHandle */,
+                                                 44100 /* iSampleRate */, 44100 /* oSampleRate */);
     Parameter::Id id = Parameter::Id::make<Parameter::Id::commonTag>(Parameter::common);
     ASSERT_NO_FATAL_FAILURE(setAndGetParameter(id, Parameter::make<Parameter::common>(common)));
 
@@ -449,8 +451,8 @@
     ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
     ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
 
-    Parameter::Common common = EffectHelper::createParamCommon(
-            0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */);
+    Parameter::Common common = createParamCommon(0 /* session */, 1 /* ioHandle */,
+                                                 44100 /* iSampleRate */, 44100 /* oSampleRate */);
     Parameter::Id id = Parameter::Id::make<Parameter::Id::commonTag>(Parameter::common);
     ASSERT_NO_FATAL_FAILURE(setAndGetParameter(id, Parameter::make<Parameter::common>(common)));
 
@@ -465,8 +467,8 @@
     ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
     ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
 
-    Parameter::Common common = EffectHelper::createParamCommon(
-            0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */);
+    Parameter::Common common = createParamCommon(0 /* session */, 1 /* ioHandle */,
+                                                 44100 /* iSampleRate */, 44100 /* oSampleRate */);
     Parameter::Id id = Parameter::Id::make<Parameter::Id::commonTag>(Parameter::common);
     ASSERT_NO_FATAL_FAILURE(setAndGetParameter(id, Parameter::make<Parameter::common>(common)));
 
@@ -484,8 +486,8 @@
     ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
     ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
 
-    Parameter::Common common = EffectHelper::createParamCommon(
-            0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */);
+    Parameter::Common common = createParamCommon(0 /* session */, 1 /* ioHandle */,
+                                                 44100 /* iSampleRate */, 44100 /* oSampleRate */);
     Parameter::Id id = Parameter::Id::make<Parameter::Id::commonTag>(Parameter::common);
     ASSERT_NO_FATAL_FAILURE(setAndGetParameter(id, Parameter::make<Parameter::common>(common)));
 
@@ -613,9 +615,13 @@
  * verify reopen sequence.
  */
 TEST_P(AudioEffectDataPathTest, SetCommonParameterAndReopen) {
+    if (!EffectFactoryHelper::isReopenSupported(mFactory)) {
+        GTEST_SKIP() << "Skipping test as effect does not support reopen";
+    }
+
     ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
 
-    Parameter::Common common = EffectHelper::createParamCommon(
+    Parameter::Common common = createParamCommon(
             0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
             kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
     IEffect::OpenEffectReturn ret;
@@ -660,7 +666,7 @@
 TEST_P(AudioEffectDataPathTest, ConsumeDataInProcessingState) {
     ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
 
-    Parameter::Common common = EffectHelper::createParamCommon(
+    Parameter::Common common = createParamCommon(
             0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
             kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
     IEffect::OpenEffectReturn ret;
@@ -677,7 +683,7 @@
 
     std::vector<float> buffer;
     EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer));
-    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion));
     EXPECT_NO_FATAL_FAILURE(
             EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer));
 
@@ -694,7 +700,7 @@
 TEST_P(AudioEffectDataPathTest, ConsumeDataAfterRestart) {
     ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
 
-    Parameter::Common common = EffectHelper::createParamCommon(
+    Parameter::Common common = createParamCommon(
             0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
             kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
     IEffect::OpenEffectReturn ret;
@@ -717,7 +723,7 @@
     ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
 
     EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer));
-    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion));
     EXPECT_NO_FATAL_FAILURE(
             EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer));
 
@@ -732,9 +738,13 @@
 // 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) {
+    if (!EffectFactoryHelper::isReopenSupported(mFactory)) {
+        GTEST_SKIP() << "Skipping test as effect does not support reopen";
+    }
+
     ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
 
-    Parameter::Common common = EffectHelper::createParamCommon(
+    Parameter::Common common = createParamCommon(
             0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
             kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
     IEffect::OpenEffectReturn ret;
@@ -750,7 +760,7 @@
     ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
     ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
     EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer));
-    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion));
     EXPECT_NO_FATAL_FAILURE(
             EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer));
 
@@ -770,7 +780,7 @@
 
     // verify data consume again
     EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer));
-    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion));
     EXPECT_NO_FATAL_FAILURE(
             EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer));
 
@@ -787,7 +797,7 @@
 TEST_P(AudioEffectDataPathTest, SendDataAtIdleAndConsumeDataInProcessing) {
     ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
 
-    Parameter::Common common = EffectHelper::createParamCommon(
+    Parameter::Common common = createParamCommon(
             0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
             kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
     IEffect::OpenEffectReturn ret;
@@ -801,7 +811,7 @@
 
     std::vector<float> buffer;
     EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer));
-    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion));
 
     ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
     ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
@@ -821,7 +831,7 @@
 TEST_P(AudioEffectDataPathTest, ProcessDataMultipleTimes) {
     ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
 
-    Parameter::Common common = EffectHelper::createParamCommon(
+    Parameter::Common common = createParamCommon(
             0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
             kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
     IEffect::OpenEffectReturn ret;
@@ -835,7 +845,7 @@
 
     std::vector<float> buffer;
     EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer));
-    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion));
     EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer));
 
     ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
@@ -844,7 +854,7 @@
     EXPECT_NO_FATAL_FAILURE(
             EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer));
 
-    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion));
     EXPECT_NO_FATAL_FAILURE(
             EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer));
 
@@ -861,7 +871,7 @@
 TEST_P(AudioEffectDataPathTest, ConsumeDataAndRestart) {
     ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
 
-    Parameter::Common common = EffectHelper::createParamCommon(
+    Parameter::Common common = createParamCommon(
             0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
             kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
     IEffect::OpenEffectReturn ret;
@@ -877,13 +887,13 @@
     ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
     std::vector<float> buffer;
     EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer));
-    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion));
     EXPECT_NO_FATAL_FAILURE(
             EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer));
 
     ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
     ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
-    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion));
     EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer));
 
     ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
@@ -903,7 +913,7 @@
 TEST_P(AudioEffectDataPathTest, NotConsumeDataByClosedEffect) {
     ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
 
-    Parameter::Common common = EffectHelper::createParamCommon(
+    Parameter::Common common = createParamCommon(
             0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
             kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
     IEffect::OpenEffectReturn ret;
@@ -919,7 +929,7 @@
 
     std::vector<float> buffer;
     EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer));
-    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion));
     EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer));
 
     ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
@@ -932,10 +942,10 @@
     ASSERT_NO_FATAL_FAILURE(create(mFactory, effect1, mDescriptor));
     ASSERT_NO_FATAL_FAILURE(create(mFactory, effect2, mDescriptor));
 
-    Parameter::Common common1 = EffectHelper::createParamCommon(
+    Parameter::Common common1 = createParamCommon(
             0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
             kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
-    Parameter::Common common2 = EffectHelper::createParamCommon(
+    Parameter::Common common2 = createParamCommon(
             1 /* session */, 1 /* ioHandle */, 48000 /* iSampleRate */, 48000 /* oSampleRate */,
             2 * kInputFrameCount /* iFrameCount */, 2 * kOutputFrameCount /* oFrameCount */);
     IEffect::OpenEffectReturn ret1, ret2;
@@ -955,7 +965,7 @@
 
     std::vector<float> buffer1, buffer2;
     EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common1, inputMQ1, buffer1));
-    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ1, inputMQ1, buffer1));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ1, inputMQ1, buffer1, mVersion));
     EXPECT_NO_FATAL_FAILURE(
             EffectHelper::readFromFmq(statusMQ1, 1, outputMQ1, buffer1.size(), buffer1));
 
@@ -966,7 +976,7 @@
     auto outputMQ2 = std::make_unique<EffectHelper::DataMQ>(ret2.outputDataMQ);
     ASSERT_TRUE(outputMQ2->isValid());
     EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common2, inputMQ2, buffer2));
-    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ2, inputMQ2, buffer2));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ2, inputMQ2, buffer2, mVersion));
     EXPECT_NO_FATAL_FAILURE(
             EffectHelper::readFromFmq(statusMQ2, 1, outputMQ2, buffer2.size(), buffer2));
 
diff --git a/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp b/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp
index 4cb1f49..abc5a91 100644
--- a/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp
@@ -57,7 +57,7 @@
                 AudioChannelLayout::make<AudioChannelLayout::layoutMask>(layout);
 
         Parameter::Specific specific = getDefaultParamSpecific();
-        Parameter::Common common = EffectHelper::createParamCommon(
+        Parameter::Common common = createParamCommon(
                 0 /* session */, 1 /* ioHandle */, kSamplingFrequency /* iSampleRate */,
                 kSamplingFrequency /* oSampleRate */, mInputFrameCount /* iFrameCount */,
                 mOutputFrameCount /* oFrameCount */, channelLayout, channelLayout);
diff --git a/audio/aidl/vts/VtsHalDownmixTargetTest.cpp b/audio/aidl/vts/VtsHalDownmixTargetTest.cpp
index ef77f4d..844a340 100644
--- a/audio/aidl/vts/VtsHalDownmixTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalDownmixTargetTest.cpp
@@ -97,7 +97,9 @@
         Parameter::Common common = EffectHelper::createParamCommon(
                 0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
                 kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */,
-                inputChannelLayout);
+                inputChannelLayout,
+                AudioChannelLayout::make<AudioChannelLayout::layoutMask>(
+                        AudioChannelLayout::LAYOUT_STEREO));
         ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &mOpenEffectReturn, EX_NONE));
         ASSERT_NE(nullptr, mEffect);
     }
diff --git a/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp b/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp
index e95bd4d..b023df1 100644
--- a/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp
+++ b/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp
@@ -57,7 +57,7 @@
         ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
 
         Parameter::Specific specific = getDefaultParamSpecific();
-        Parameter::Common common = EffectHelper::createParamCommon(
+        Parameter::Common common = createParamCommon(
                 0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
                 0x100 /* iFrameCount */, 0x100 /* oFrameCount */,
                 AudioChannelLayout::make<AudioChannelLayout::layoutMask>(mChannelLayout),
@@ -553,7 +553,7 @@
                     ::android::internal::ToString(std::get<INPUT_GAIN_PARAM>(info.param));
             std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
                                descriptor.common.name + "_UUID_" +
-                               descriptor.common.id.uuid.toString() + "_inputGains_" + gains;
+                               toString(descriptor.common.id.uuid) + "_inputGains_" + gains;
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
@@ -646,7 +646,7 @@
                     std::to_string(std::get<LIMITER_ENGINE_IN_USE>(info.param));
             std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
                                descriptor.common.name + "_UUID_" +
-                               descriptor.common.id.uuid.toString() + "_limiterConfig_" +
+                               toString(descriptor.common.id.uuid) + "_limiterConfig_" +
                                cfg.toString() + "_engineSetting_" + engineLimiterInUse;
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
@@ -720,7 +720,7 @@
 
             std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
                                descriptor.common.name + "_UUID_" +
-                               descriptor.common.id.uuid.toString() + "_" + channelConfig +
+                               toString(descriptor.common.id.uuid) + "_" + channelConfig +
                                "_engineInUse_" + engineInUse;
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
@@ -862,7 +862,7 @@
             std::string stageInUse = std::to_string(std::get<EQ_BAND_STAGE_IN_USE>(info.param));
             std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
                                descriptor.common.name + "_UUID_" +
-                               descriptor.common.id.uuid.toString() + "_bands_" + bands +
+                               toString(descriptor.common.id.uuid) + "_bands_" + bands +
                                "_stageInUse_" + stageInUse;
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
@@ -980,7 +980,7 @@
             std::string stageInUse = std::to_string(std::get<MBC_BAND_STAGE_IN_USE>(info.param));
             std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
                                descriptor.common.name + "_UUID_" +
-                               descriptor.common.id.uuid.toString() + "_bands_" + mbcBands +
+                               toString(descriptor.common.id.uuid) + "_bands_" + mbcBands +
                                "_stageInUse_" + stageInUse;
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
diff --git a/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp b/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp
index 765c377..c7c6505 100644
--- a/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp
@@ -16,28 +16,132 @@
 
 #define LOG_TAG "VtsHalEnvironmentalReverbTest"
 #include <android-base/logging.h>
+#include <audio_utils/power.h>
+#include <system/audio.h>
 
 #include "EffectHelper.h"
 
 using namespace android;
-
-using aidl::android::hardware::audio::effect::Descriptor;
-using aidl::android::hardware::audio::effect::EnvironmentalReverb;
-using aidl::android::hardware::audio::effect::getEffectTypeUuidEnvReverb;
-using aidl::android::hardware::audio::effect::IEffect;
-using aidl::android::hardware::audio::effect::IFactory;
-using aidl::android::hardware::audio::effect::Parameter;
+using namespace aidl::android::hardware::audio::effect;
+using aidl::android::hardware::audio::common::getChannelCount;
 using android::hardware::audio::common::testing::detail::TestExecutionTracer;
+using TagVectorPair = std::pair<EnvironmentalReverb::Tag, std::vector<int>>;
+using TagValuePair = std::pair<EnvironmentalReverb::Tag, int>;
 
+static constexpr int kMaxRoomLevel = 0;
+static constexpr int kMinRoomLevel = -6000;
+static constexpr int kMinRoomHfLevel = -4000;
+static constexpr int kMinDecayTime = 0;
+static constexpr int kMinHfRatio = 100;
+static constexpr int kMinLevel = -6000;
+static constexpr int kMinDensity = 0;
+static constexpr int kMinDiffusion = 0;
+static constexpr int kMinDelay = 0;
+
+static const std::vector<TagVectorPair> kParamsIncreasingVector = {
+
+        {EnvironmentalReverb::roomLevelMb, {-3500, -2800, -2100, -1400, -700, 0}},
+        {EnvironmentalReverb::roomHfLevelMb, {-4000, -3200, -2400, -1600, -800, 0}},
+        {EnvironmentalReverb::decayTimeMs, {800, 1600, 2400, 3200, 4000}},
+        {EnvironmentalReverb::decayHfRatioPm, {100, 600, 1100, 1600, 2000}},
+        {EnvironmentalReverb::levelMb, {-3500, -2800, -2100, -1400, -700, 0}},
+};
+
+static const std::vector<TagValuePair> kParamsMinimumValue = {
+        {EnvironmentalReverb::roomLevelMb, kMinRoomLevel},
+        {EnvironmentalReverb::decayTimeMs, kMinDecayTime},
+        {EnvironmentalReverb::levelMb, kMinLevel}};
+
+std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kDescPair;
+
+using Maker = std::set<int> (*)();
+static const std::array<Maker, static_cast<int>(EnvironmentalReverb::bypass) + 1>
+        kTestValueSetMaker = {
+                nullptr,
+                []() -> std::set<int> {
+                    return EffectHelper::getTestValueSet<EnvironmentalReverb, int,
+                                                         Range::environmentalReverb,
+                                                         EnvironmentalReverb::roomLevelMb>(
+                            kDescPair, EffectHelper::expandTestValueBasic<int>);
+                },
+                []() -> std::set<int> {
+                    return EffectHelper::getTestValueSet<EnvironmentalReverb, int,
+                                                         Range::environmentalReverb,
+                                                         EnvironmentalReverb::roomHfLevelMb>(
+                            kDescPair, EffectHelper::expandTestValueBasic<int>);
+                },
+                []() -> std::set<int> {
+                    return EffectHelper::getTestValueSet<EnvironmentalReverb, int,
+                                                         Range::environmentalReverb,
+                                                         EnvironmentalReverb::decayTimeMs>(
+                            kDescPair, EffectHelper::expandTestValueBasic<int>);
+                },
+                []() -> std::set<int> {
+                    return EffectHelper::getTestValueSet<EnvironmentalReverb, int,
+                                                         Range::environmentalReverb,
+                                                         EnvironmentalReverb::decayHfRatioPm>(
+                            kDescPair, EffectHelper::expandTestValueBasic<int>);
+                },
+                nullptr,
+                nullptr,
+                []() -> std::set<int> {
+                    return EffectHelper::getTestValueSet<EnvironmentalReverb, int,
+                                                         Range::environmentalReverb,
+                                                         EnvironmentalReverb::levelMb>(
+                            kDescPair, EffectHelper::expandTestValueBasic<int>);
+                },
+                []() -> std::set<int> {
+                    return EffectHelper::getTestValueSet<EnvironmentalReverb, int,
+                                                         Range::environmentalReverb,
+                                                         EnvironmentalReverb::delayMs>(
+                            kDescPair, EffectHelper::expandTestValueBasic<int>);
+                },
+                []() -> std::set<int> {
+                    return EffectHelper::getTestValueSet<EnvironmentalReverb, int,
+                                                         Range::environmentalReverb,
+                                                         EnvironmentalReverb::diffusionPm>(
+                            kDescPair, EffectHelper::expandTestValueBasic<int>);
+                },
+                []() -> std::set<int> {
+                    return EffectHelper::getTestValueSet<EnvironmentalReverb, int,
+                                                         Range::environmentalReverb,
+                                                         EnvironmentalReverb::densityPm>(
+                            kDescPair, EffectHelper::expandTestValueBasic<int>);
+                },
+                []() -> std::set<int> {
+                    return EffectHelper::getTestValueSet<EnvironmentalReverb, int,
+                                                         Range::environmentalReverb,
+                                                         EnvironmentalReverb::bypass>(
+                            kDescPair, EffectHelper::expandTestValueBasic<int>);
+                },
+};
+
+static std::vector<TagValuePair> buildSetAndGetTestParams() {
+    std::vector<TagValuePair> valueTag;
+    for (EnvironmentalReverb::Tag tag : ndk::enum_range<EnvironmentalReverb::Tag>()) {
+        std::set<int> values;
+        int intTag = static_cast<int>(tag);
+        if (intTag <= static_cast<int>(EnvironmentalReverb::bypass) &&
+            kTestValueSetMaker[intTag] != nullptr) {
+            values = kTestValueSetMaker[intTag]();
+        }
+
+        for (const auto& value : values) {
+            valueTag.push_back(std::make_pair(tag, value));
+        }
+    }
+
+    return valueTag;
+}
 /**
- * Here we focus on specific parameter checking, general IEffect interfaces testing performed in
- * VtsAudioEffectTargetTest.
- * Testing parameter range, assuming the parameter supported by effect is in this range.
- * This range is verified with IEffect.getDescriptor() and range defined in the documentation, for
- * any index supported value test expects EX_NONE from IEffect.setParameter(), otherwise expects
- * EX_ILLEGAL_ARGUMENT.
+ * Tests do the following:
+ * - Testing parameter range supported by the effect. Range is verified with IEffect.getDescriptor()
+ *   and range defined in the documentation.
+ * - Validating the effect by comparing the outputs of the supported parameters.
  */
 
+enum ParamName { DESCRIPTOR_INDEX, TAG_VALUE_PAIR };
+
 class EnvironmentalReverbHelper : public EffectHelper {
   public:
     EnvironmentalReverbHelper(std::pair<std::shared_ptr<IFactory>, Descriptor> pair) {
@@ -49,10 +153,9 @@
         ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
 
         Parameter::Specific specific = getDefaultParamSpecific();
-        Parameter::Common common = EffectHelper::createParamCommon(
+        Parameter::Common common = createParamCommon(
                 0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
-                kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
-        IEffect::OpenEffectReturn ret;
+                mFrameCount /* iFrameCount */, mFrameCount /* oFrameCount */);
         ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &ret, EX_NONE));
         ASSERT_NE(nullptr, mEffect);
     }
@@ -63,476 +166,291 @@
     }
 
     Parameter::Specific getDefaultParamSpecific() {
-        EnvironmentalReverb er = EnvironmentalReverb::make<EnvironmentalReverb::roomLevelMb>(-6000);
+        EnvironmentalReverb er =
+                EnvironmentalReverb::make<EnvironmentalReverb::roomLevelMb>(kMaxRoomLevel);
         Parameter::Specific specific =
                 Parameter::Specific::make<Parameter::Specific::environmentalReverb>(er);
         return specific;
     }
 
-    static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
-    std::shared_ptr<IFactory> mFactory;
-    std::shared_ptr<IEffect> mEffect;
-    Descriptor mDescriptor;
-    int mRoomLevel = -6000;
-    int mRoomHfLevel = 0;
-    int mDecayTime = 1000;
-    int mDecayHfRatio = 500;
-    int mLevel = -6000;
-    int mDelay = 40;
-    int mDiffusion = 1000;
-    int mDensity = 1000;
-    bool mBypass = false;
+    bool isParamValid(EnvironmentalReverb env) {
+        return isParameterValid<EnvironmentalReverb, Range::environmentalReverb>(env, mDescriptor);
+    }
 
-    void SetAndGetReverbParameters() {
-        for (auto& it : mTags) {
-            auto& tag = it.first;
-            auto& er = it.second;
+    Parameter createParam(EnvironmentalReverb env) {
+        return Parameter::make<Parameter::specific>(
+                Parameter::Specific::make<Parameter::Specific::environmentalReverb>(env));
+    }
 
-            // validate parameter
-            Descriptor desc;
-            ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
-            const bool valid = isParameterValid<EnvironmentalReverb, Range::environmentalReverb>(
-                    it.second, desc);
-            const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
+    void setAndVerifyParam(binder_exception_t expected, EnvironmentalReverb env,
+                           EnvironmentalReverb::Tag tag) {
+        auto expectedParam = createParam(env);
 
-            // set
-            Parameter expectParam;
-            Parameter::Specific specific;
-            specific.set<Parameter::Specific::environmentalReverb>(er);
-            expectParam.set<Parameter::specific>(specific);
-            EXPECT_STATUS(expected, mEffect->setParameter(expectParam)) << expectParam.toString();
+        EXPECT_STATUS(expected, mEffect->setParameter(expectedParam)) << expectedParam.toString();
 
-            // only get if parameter in range and set success
-            if (expected == EX_NONE) {
-                Parameter getParam;
-                Parameter::Id id;
-                EnvironmentalReverb::Id erId;
-                erId.set<EnvironmentalReverb::Id::commonTag>(tag);
-                id.set<Parameter::Id::environmentalReverbTag>(erId);
-                // if set success, then get should match
-                EXPECT_STATUS(expected, mEffect->getParameter(id, &getParam));
-                EXPECT_EQ(expectParam, getParam);
-            }
+        if (expected == EX_NONE) {
+            auto erId = EnvironmentalReverb::Id::make<EnvironmentalReverb::Id::commonTag>(
+                    EnvironmentalReverb::Tag(tag));
+
+            auto id = Parameter::Id::make<Parameter::Id::environmentalReverbTag>(erId);
+
+            // get parameter
+            Parameter getParam;
+            EXPECT_STATUS(EX_NONE, mEffect->getParameter(id, &getParam));
+            EXPECT_EQ(expectedParam, getParam) << "\nexpectedParam:" << expectedParam.toString()
+                                               << "\ngetParam:" << getParam.toString();
         }
     }
 
-    void addRoomLevelParam() {
-        EnvironmentalReverb er;
-        er.set<EnvironmentalReverb::roomLevelMb>(mRoomLevel);
-        mTags.push_back({EnvironmentalReverb::roomLevelMb, er});
+    bool isAuxiliary() {
+        return mDescriptor.common.flags.type ==
+               aidl::android::hardware::audio::effect::Flags::Type::AUXILIARY;
     }
 
-    void addRoomHfLevelParam(int roomHfLevel) {
-        EnvironmentalReverb er;
-        er.set<EnvironmentalReverb::roomHfLevelMb>(roomHfLevel);
-        mTags.push_back({EnvironmentalReverb::roomHfLevelMb, er});
+    float computeOutputEnergy(const std::vector<float>& input, std::vector<float> output) {
+        if (!isAuxiliary()) {
+            // Extract auxiliary output
+            for (size_t i = 0; i < output.size(); i++) {
+                output[i] -= input[i];
+            }
+        }
+        return audio_utils_compute_energy_mono(output.data(), AUDIO_FORMAT_PCM_FLOAT,
+                                               output.size());
     }
 
-    void addDecayTimeParam(int decayTime) {
-        EnvironmentalReverb er;
-        er.set<EnvironmentalReverb::decayTimeMs>(decayTime);
-        mTags.push_back({EnvironmentalReverb::decayTimeMs, er});
+    void generateSineWaveInput(std::vector<float>& input) {
+        int frequency = 1000;
+        size_t kSamplingFrequency = 44100;
+        for (size_t i = 0; i < input.size(); i++) {
+            input[i] = sin(2 * M_PI * frequency * i / kSamplingFrequency);
+        }
+    }
+    using Maker = EnvironmentalReverb (*)(int);
+
+    static constexpr std::array<Maker, static_cast<int>(EnvironmentalReverb::bypass) + 1>
+            kEnvironmentalReverbParamMaker = {
+                    nullptr,
+                    [](int value) -> EnvironmentalReverb {
+                        return EnvironmentalReverb::make<EnvironmentalReverb::roomLevelMb>(value);
+                    },
+                    [](int value) -> EnvironmentalReverb {
+                        return EnvironmentalReverb::make<EnvironmentalReverb::roomHfLevelMb>(value);
+                    },
+                    [](int value) -> EnvironmentalReverb {
+                        return EnvironmentalReverb::make<EnvironmentalReverb::decayTimeMs>(value);
+                    },
+                    [](int value) -> EnvironmentalReverb {
+                        return EnvironmentalReverb::make<EnvironmentalReverb::decayHfRatioPm>(
+                                value);
+                    },
+                    nullptr,
+                    nullptr,
+                    [](int value) -> EnvironmentalReverb {
+                        return EnvironmentalReverb::make<EnvironmentalReverb::levelMb>(value);
+                    },
+                    [](int value) -> EnvironmentalReverb {
+                        return EnvironmentalReverb::make<EnvironmentalReverb::delayMs>(value);
+                    },
+                    [](int value) -> EnvironmentalReverb {
+                        return EnvironmentalReverb::make<EnvironmentalReverb::diffusionPm>(value);
+                    },
+                    [](int value) -> EnvironmentalReverb {
+                        return EnvironmentalReverb::make<EnvironmentalReverb::densityPm>(value);
+                    },
+                    [](int value) -> EnvironmentalReverb {
+                        return EnvironmentalReverb::make<EnvironmentalReverb::bypass>(value);
+                    }};
+
+    void createEnvParam(EnvironmentalReverb::Tag tag, int paramValue) {
+        int intTag = static_cast<int>(tag);
+        if (intTag <= static_cast<int>(EnvironmentalReverb::bypass) &&
+            kEnvironmentalReverbParamMaker[intTag] != NULL) {
+            mEnvParam = kEnvironmentalReverbParamMaker[intTag](paramValue);
+        } else {
+            GTEST_SKIP() << "Invalid parameter, skipping the test\n";
+        }
     }
 
-    void addDecayHfRatioParam(int decayHfRatio) {
-        EnvironmentalReverb er;
-        er.set<EnvironmentalReverb::decayHfRatioPm>(decayHfRatio);
-        mTags.push_back({EnvironmentalReverb::decayHfRatioPm, er});
+    void setParameterAndProcess(std::vector<float>& input, std::vector<float>& output, int val,
+                                EnvironmentalReverb::Tag tag) {
+        createEnvParam(tag, val);
+        if (isParamValid(mEnvParam)) {
+            ASSERT_NO_FATAL_FAILURE(setAndVerifyParam(EX_NONE, mEnvParam, tag));
+            ASSERT_NO_FATAL_FAILURE(processAndWriteToOutput(input, output, mEffect, &ret));
+        }
     }
 
-    void addLevelParam(int level) {
-        EnvironmentalReverb er;
-        er.set<EnvironmentalReverb::levelMb>(level);
-        mTags.push_back({EnvironmentalReverb::levelMb, er});
-    }
+    static constexpr int kSamplingFrequency = 44100;
+    static constexpr int kDurationMilliSec = 500;
+    static constexpr int kBufferSize = kSamplingFrequency * kDurationMilliSec / 1000;
 
-    void addDelayParam(int delay) {
-        EnvironmentalReverb er;
-        er.set<EnvironmentalReverb::delayMs>(delay);
-        mTags.push_back({EnvironmentalReverb::delayMs, er});
-    }
+    int mStereoChannelCount =
+            getChannelCount(AudioChannelLayout::make<AudioChannelLayout::layoutMask>(
+                    AudioChannelLayout::LAYOUT_STEREO));
+    int mFrameCount = kBufferSize / mStereoChannelCount;
 
-    void addDiffusionParam(int diffusion) {
-        EnvironmentalReverb er;
-        er.set<EnvironmentalReverb::diffusionPm>(diffusion);
-        mTags.push_back({EnvironmentalReverb::diffusionPm, er});
-    }
-
-    void addDensityParam(int density) {
-        EnvironmentalReverb er;
-        er.set<EnvironmentalReverb::densityPm>(density);
-        mTags.push_back({EnvironmentalReverb::densityPm, er});
-    }
-
-    void addBypassParam(bool bypass) {
-        EnvironmentalReverb er;
-        er.set<EnvironmentalReverb::bypass>(bypass);
-        mTags.push_back({EnvironmentalReverb::bypass, er});
-    }
-
-  private:
-    std::vector<std::pair<EnvironmentalReverb::Tag, EnvironmentalReverb>> mTags;
-    void CleanUp() { mTags.clear(); }
+    std::shared_ptr<IFactory> mFactory;
+    std::shared_ptr<IEffect> mEffect;
+    IEffect::OpenEffectReturn ret;
+    Descriptor mDescriptor;
+    EnvironmentalReverb mEnvParam;
 };
 
-class EnvironmentalReverbRoomLevelTest
+class EnvironmentalReverbParamTest
     : public ::testing::TestWithParam<
-              std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int>>,
+              std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, TagValuePair>>,
       public EnvironmentalReverbHelper {
   public:
-    EnvironmentalReverbRoomLevelTest() : EnvironmentalReverbHelper(std::get<0>(GetParam())) {
-        mRoomLevel = std::get<1>(GetParam());
+    EnvironmentalReverbParamTest()
+        : EnvironmentalReverbHelper(std::get<DESCRIPTOR_INDEX>(GetParam())) {
+        std::tie(mTag, mParamValue) = std::get<TAG_VALUE_PAIR>(GetParam());
     }
-
     void SetUp() override { SetUpReverb(); }
-
     void TearDown() override { TearDownReverb(); }
+
+    EnvironmentalReverb::Tag mTag;
+    int mParamValue;
 };
 
-TEST_P(EnvironmentalReverbRoomLevelTest, SetAndGetRoomLevel) {
-    EXPECT_NO_FATAL_FAILURE(addRoomLevelParam());
-    SetAndGetReverbParameters();
+TEST_P(EnvironmentalReverbParamTest, SetAndGetParameter) {
+    createEnvParam(mTag, mParamValue);
+    ASSERT_NO_FATAL_FAILURE(setAndVerifyParam(
+            isParamValid(mEnvParam) ? EX_NONE : EX_ILLEGAL_ARGUMENT, mEnvParam, mTag));
 }
 
-std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kDescPair;
-
 INSTANTIATE_TEST_SUITE_P(
-        EnvironmentalReverbTest, EnvironmentalReverbRoomLevelTest,
+        EnvironmentalReverbTest, EnvironmentalReverbParamTest,
         ::testing::Combine(
                 testing::ValuesIn(kDescPair = EffectFactoryHelper::getAllEffectDescriptors(
                                           IFactory::descriptor, getEffectTypeUuidEnvReverb())),
-                testing::ValuesIn(EffectHelper::getTestValueSet<EnvironmentalReverb, int,
-                                                                Range::environmentalReverb,
-                                                                EnvironmentalReverb::roomLevelMb>(
-                        kDescPair, EffectHelper::expandTestValueBasic<int>))),
-        [](const testing::TestParamInfo<EnvironmentalReverbRoomLevelTest::ParamType>& info) {
-            auto descriptor = std::get<0>(info.param).second;
-            std::string roomLevel = std::to_string(std::get<1>(info.param));
-
-            std::string name = getPrefix(descriptor) + "_roomLevel" + roomLevel;
+                testing::ValuesIn(buildSetAndGetTestParams())),
+        [](const testing::TestParamInfo<EnvironmentalReverbParamTest::ParamType>& info) {
+            auto descriptor = std::get<DESCRIPTOR_INDEX>(info.param).second;
+            auto tag = std::get<TAG_VALUE_PAIR>(info.param).first;
+            auto val = std::get<TAG_VALUE_PAIR>(info.param).second;
+            std::string name =
+                    getPrefix(descriptor) + "_Tag_" + toString(tag) + std::to_string(val);
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
         });
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbRoomLevelTest);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbParamTest);
 
-class EnvironmentalReverbRoomHfLevelTest
+class EnvironmentalReverbDataTest
     : public ::testing::TestWithParam<
-              std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int>>,
+              std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, TagVectorPair>>,
       public EnvironmentalReverbHelper {
   public:
-    EnvironmentalReverbRoomHfLevelTest() : EnvironmentalReverbHelper(std::get<0>(GetParam())) {
-        mRoomHfLevel = std::get<1>(GetParam());
+    EnvironmentalReverbDataTest()
+        : EnvironmentalReverbHelper(std::get<DESCRIPTOR_INDEX>(GetParam())) {
+        std::tie(mTag, mParamValues) = std::get<TAG_VALUE_PAIR>(GetParam());
+        mInput.resize(kBufferSize);
+        generateSineWaveInput(mInput);
+    }
+    void SetUp() override { SetUpReverb(); }
+    void TearDown() override { TearDownReverb(); }
+
+    void assertEnergyIncreasingWithParameter(bool bypass) {
+        createEnvParam(EnvironmentalReverb::bypass, bypass);
+        ASSERT_NO_FATAL_FAILURE(setAndVerifyParam(EX_NONE, mEnvParam, EnvironmentalReverb::bypass));
+        float baseEnergy = 0;
+        for (int val : mParamValues) {
+            std::vector<float> output(kBufferSize);
+            setParameterAndProcess(mInput, output, val, mTag);
+            float energy = computeOutputEnergy(mInput, output);
+            ASSERT_GT(energy, baseEnergy);
+            baseEnergy = energy;
+        }
     }
 
-    void SetUp() override { SetUpReverb(); }
+    void assertZeroEnergyWithBypass(bool bypass) {
+        createEnvParam(EnvironmentalReverb::bypass, bypass);
+        ASSERT_NO_FATAL_FAILURE(setAndVerifyParam(EX_NONE, mEnvParam, EnvironmentalReverb::bypass));
+        for (int val : mParamValues) {
+            std::vector<float> output(kBufferSize);
+            setParameterAndProcess(mInput, output, val, mTag);
+            float energy = computeOutputEnergy(mInput, output);
+            ASSERT_EQ(energy, 0);
+        }
+    }
 
-    void TearDown() override { TearDownReverb(); }
+    EnvironmentalReverb::Tag mTag;
+    std::vector<int> mParamValues;
+    std::vector<float> mInput;
 };
 
-TEST_P(EnvironmentalReverbRoomHfLevelTest, SetAndGetRoomHfLevel) {
-    EXPECT_NO_FATAL_FAILURE(addRoomHfLevelParam(mRoomHfLevel));
-    SetAndGetReverbParameters();
+TEST_P(EnvironmentalReverbDataTest, IncreasingParamValue) {
+    assertEnergyIncreasingWithParameter(false);
+}
+
+TEST_P(EnvironmentalReverbDataTest, WithBypassEnabled) {
+    assertZeroEnergyWithBypass(true);
 }
 
 INSTANTIATE_TEST_SUITE_P(
-        EnvironmentalReverbTest, EnvironmentalReverbRoomHfLevelTest,
-        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
-                                   IFactory::descriptor, getEffectTypeUuidEnvReverb())),
-                           testing::ValuesIn(EffectHelper::getTestValueSet<
-                                             EnvironmentalReverb, int, Range::environmentalReverb,
-                                             EnvironmentalReverb::roomHfLevelMb>(
-                                   kDescPair, EffectHelper::expandTestValueBasic<int>))),
-        [](const testing::TestParamInfo<EnvironmentalReverbRoomHfLevelTest::ParamType>& info) {
-            auto descriptor = std::get<0>(info.param).second;
-            std::string roomHfLevel = std::to_string(std::get<1>(info.param));
-
-            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
-                               descriptor.common.name + "_UUID_" +
-                               descriptor.common.id.uuid.toString() + "_roomHfLevel" + roomHfLevel;
-            std::replace_if(
-                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+        EnvironmentalReverbTest, EnvironmentalReverbDataTest,
+        ::testing::Combine(
+                testing::ValuesIn(kDescPair = EffectFactoryHelper::getAllEffectDescriptors(
+                                          IFactory::descriptor, getEffectTypeUuidEnvReverb())),
+                testing::ValuesIn(kParamsIncreasingVector)),
+        [](const testing::TestParamInfo<EnvironmentalReverbDataTest::ParamType>& info) {
+            auto descriptor = std::get<DESCRIPTOR_INDEX>(info.param).second;
+            auto tag = std::get<TAG_VALUE_PAIR>(info.param).first;
+            std::string name = getPrefix(descriptor) + "_Tag_" + toString(tag);
             return name;
         });
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbRoomHfLevelTest);
 
-class EnvironmentalReverbDecayTimeTest
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbDataTest);
+
+class EnvironmentalReverbMinimumParamTest
     : public ::testing::TestWithParam<
-              std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int>>,
+              std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, TagValuePair>>,
       public EnvironmentalReverbHelper {
   public:
-    EnvironmentalReverbDecayTimeTest() : EnvironmentalReverbHelper(std::get<0>(GetParam())) {
-        mDecayTime = std::get<1>(GetParam());
+    EnvironmentalReverbMinimumParamTest()
+        : EnvironmentalReverbHelper(std::get<DESCRIPTOR_INDEX>(GetParam())) {
+        std::tie(mTag, mValue) = std::get<TAG_VALUE_PAIR>(GetParam());
     }
-
-    void SetUp() override { SetUpReverb(); }
-
+    void SetUp() override {
+        SetUpReverb();
+        createEnvParam(EnvironmentalReverb::roomLevelMb, kMinRoomLevel);
+        ASSERT_NO_FATAL_FAILURE(
+                setAndVerifyParam(EX_NONE, mEnvParam, EnvironmentalReverb::roomLevelMb));
+    }
     void TearDown() override { TearDownReverb(); }
+
+    EnvironmentalReverb::Tag mTag;
+    int mValue;
 };
 
-TEST_P(EnvironmentalReverbDecayTimeTest, SetAndGetDecayTime) {
-    EXPECT_NO_FATAL_FAILURE(addDecayTimeParam(mDecayTime));
-    SetAndGetReverbParameters();
+TEST_P(EnvironmentalReverbMinimumParamTest, MinimumValueTest) {
+    std::vector<float> input(kBufferSize);
+    generateSineWaveInput(input);
+    std::vector<float> output(kBufferSize);
+    setParameterAndProcess(input, output, mValue, mTag);
+    float energy = computeOutputEnergy(input, output);
+    // No Auxiliary output for minimum param values
+    ASSERT_EQ(energy, 0);
 }
 
 INSTANTIATE_TEST_SUITE_P(
-        EnvironmentalReverbTest, EnvironmentalReverbDecayTimeTest,
-        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
-                                   IFactory::descriptor, getEffectTypeUuidEnvReverb())),
-                           testing::ValuesIn(EffectHelper::getTestValueSet<
-                                             EnvironmentalReverb, int, Range::environmentalReverb,
-                                             EnvironmentalReverb::decayTimeMs>(
-                                   kDescPair, EffectHelper::expandTestValueBasic<int>))),
-        [](const testing::TestParamInfo<EnvironmentalReverbDecayTimeTest::ParamType>& info) {
-            auto descriptor = std::get<0>(info.param).second;
-            std::string decayTime = std::to_string(std::get<1>(info.param));
-
-            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
-                               descriptor.common.name + "_UUID_" +
-                               descriptor.common.id.uuid.toString() + "_decayTime" + decayTime;
+        EnvironmentalReverbTest, EnvironmentalReverbMinimumParamTest,
+        ::testing::Combine(
+                testing::ValuesIn(kDescPair = EffectFactoryHelper::getAllEffectDescriptors(
+                                          IFactory::descriptor, getEffectTypeUuidEnvReverb())),
+                testing::ValuesIn(kParamsMinimumValue)),
+        [](const testing::TestParamInfo<EnvironmentalReverbMinimumParamTest::ParamType>& info) {
+            auto descriptor = std::get<DESCRIPTOR_INDEX>(info.param).second;
+            auto tag = std::get<TAG_VALUE_PAIR>(info.param).first;
+            auto val = std::get<TAG_VALUE_PAIR>(info.param).second;
+            std::string name =
+                    getPrefix(descriptor) + "_Tag_" + toString(tag) + std::to_string(val);
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
         });
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbDecayTimeTest);
 
-class EnvironmentalReverbDecayHfRatioTest
-    : public ::testing::TestWithParam<
-              std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int>>,
-      public EnvironmentalReverbHelper {
-  public:
-    EnvironmentalReverbDecayHfRatioTest() : EnvironmentalReverbHelper(std::get<0>(GetParam())) {
-        mDecayHfRatio = std::get<1>(GetParam());
-    }
-
-    void SetUp() override { SetUpReverb(); }
-
-    void TearDown() override { TearDownReverb(); }
-};
-
-TEST_P(EnvironmentalReverbDecayHfRatioTest, SetAndGetDecayHfRatio) {
-    EXPECT_NO_FATAL_FAILURE(addDecayHfRatioParam(mDecayHfRatio));
-    SetAndGetReverbParameters();
-}
-
-INSTANTIATE_TEST_SUITE_P(
-        EnvironmentalReverbTest, EnvironmentalReverbDecayHfRatioTest,
-        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
-                                   IFactory::descriptor, getEffectTypeUuidEnvReverb())),
-                           testing::ValuesIn(EffectHelper::getTestValueSet<
-                                             EnvironmentalReverb, int, Range::environmentalReverb,
-                                             EnvironmentalReverb::decayHfRatioPm>(
-                                   kDescPair, EffectHelper::expandTestValueBasic<int>))),
-        [](const testing::TestParamInfo<EnvironmentalReverbDecayHfRatioTest::ParamType>& info) {
-            auto descriptor = std::get<0>(info.param).second;
-            std::string decayHfRatio = std::to_string(std::get<1>(info.param));
-
-            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
-                               descriptor.common.name + "_UUID_" +
-                               descriptor.common.id.uuid.toString() + "_decayHfRatio" +
-                               decayHfRatio;
-            std::replace_if(
-                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
-            return name;
-        });
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbDecayHfRatioTest);
-
-class EnvironmentalReverbLevelTest
-    : public ::testing::TestWithParam<
-              std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int>>,
-      public EnvironmentalReverbHelper {
-  public:
-    EnvironmentalReverbLevelTest() : EnvironmentalReverbHelper(std::get<0>(GetParam())) {
-        mLevel = std::get<1>(GetParam());
-    }
-
-    void SetUp() override { SetUpReverb(); }
-
-    void TearDown() override { TearDownReverb(); }
-};
-
-TEST_P(EnvironmentalReverbLevelTest, SetAndGetLevel) {
-    EXPECT_NO_FATAL_FAILURE(addLevelParam(mLevel));
-    SetAndGetReverbParameters();
-}
-
-INSTANTIATE_TEST_SUITE_P(
-        EnvironmentalReverbTest, EnvironmentalReverbLevelTest,
-        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
-                                   IFactory::descriptor, getEffectTypeUuidEnvReverb())),
-                           testing::ValuesIn(EffectHelper::getTestValueSet<
-                                             EnvironmentalReverb, int, Range::environmentalReverb,
-                                             EnvironmentalReverb::levelMb>(
-                                   kDescPair, EffectHelper::expandTestValueBasic<int>))),
-        [](const testing::TestParamInfo<EnvironmentalReverbDecayHfRatioTest::ParamType>& info) {
-            auto descriptor = std::get<0>(info.param).second;
-            std::string level = std::to_string(std::get<1>(info.param));
-
-            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
-                               descriptor.common.name + "_UUID_" +
-                               descriptor.common.id.uuid.toString() + "_level" + level;
-            std::replace_if(
-                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
-            return name;
-        });
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbLevelTest);
-
-class EnvironmentalReverbDelayTest
-    : public ::testing::TestWithParam<
-              std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int>>,
-      public EnvironmentalReverbHelper {
-  public:
-    EnvironmentalReverbDelayTest() : EnvironmentalReverbHelper(std::get<0>(GetParam())) {
-        mDelay = std::get<1>(GetParam());
-    }
-
-    void SetUp() override { SetUpReverb(); }
-
-    void TearDown() override { TearDownReverb(); }
-};
-
-TEST_P(EnvironmentalReverbDelayTest, SetAndGetDelay) {
-    EXPECT_NO_FATAL_FAILURE(addDelayParam(mDelay));
-    SetAndGetReverbParameters();
-}
-
-INSTANTIATE_TEST_SUITE_P(
-        EnvironmentalReverbTest, EnvironmentalReverbDelayTest,
-        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
-                                   IFactory::descriptor, getEffectTypeUuidEnvReverb())),
-                           testing::ValuesIn(EffectHelper::getTestValueSet<
-                                             EnvironmentalReverb, int, Range::environmentalReverb,
-                                             EnvironmentalReverb::delayMs>(
-                                   kDescPair, EffectHelper::expandTestValueBasic<int>))),
-        [](const testing::TestParamInfo<EnvironmentalReverbDelayTest::ParamType>& info) {
-            auto descriptor = std::get<0>(info.param).second;
-            std::string delay = std::to_string(std::get<1>(info.param));
-
-            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
-                               descriptor.common.name + "_UUID_" +
-                               descriptor.common.id.uuid.toString() + "_delay" + delay;
-            std::replace_if(
-                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
-            return name;
-        });
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbDelayTest);
-
-class EnvironmentalReverbDiffusionTest
-    : public ::testing::TestWithParam<
-              std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int>>,
-      public EnvironmentalReverbHelper {
-  public:
-    EnvironmentalReverbDiffusionTest() : EnvironmentalReverbHelper(std::get<0>(GetParam())) {
-        mDiffusion = std::get<1>(GetParam());
-    }
-
-    void SetUp() override { SetUpReverb(); }
-
-    void TearDown() override { TearDownReverb(); }
-};
-
-TEST_P(EnvironmentalReverbDiffusionTest, SetAndGetDiffusion) {
-    EXPECT_NO_FATAL_FAILURE(addDiffusionParam(mDiffusion));
-    SetAndGetReverbParameters();
-}
-
-INSTANTIATE_TEST_SUITE_P(
-        EnvironmentalReverbTest, EnvironmentalReverbDiffusionTest,
-        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
-                                   IFactory::descriptor, getEffectTypeUuidEnvReverb())),
-                           testing::ValuesIn(EffectHelper::getTestValueSet<
-                                             EnvironmentalReverb, int, Range::environmentalReverb,
-                                             EnvironmentalReverb::diffusionPm>(
-                                   kDescPair, EffectHelper::expandTestValueBasic<int>))),
-        [](const testing::TestParamInfo<EnvironmentalReverbDiffusionTest::ParamType>& info) {
-            auto descriptor = std::get<0>(info.param).second;
-            std::string diffusion = std::to_string(std::get<1>(info.param));
-
-            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
-                               descriptor.common.name + "_UUID_" +
-                               descriptor.common.id.uuid.toString() + "_diffusion" + diffusion;
-            std::replace_if(
-                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
-            return name;
-        });
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbDiffusionTest);
-
-class EnvironmentalReverbDensityTest
-    : public ::testing::TestWithParam<
-              std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int>>,
-      public EnvironmentalReverbHelper {
-  public:
-    EnvironmentalReverbDensityTest() : EnvironmentalReverbHelper(std::get<0>(GetParam())) {
-        mDensity = std::get<1>(GetParam());
-    }
-
-    void SetUp() override { SetUpReverb(); }
-
-    void TearDown() override { TearDownReverb(); }
-};
-
-TEST_P(EnvironmentalReverbDensityTest, SetAndGetDensity) {
-    EXPECT_NO_FATAL_FAILURE(addDensityParam(mDensity));
-    SetAndGetReverbParameters();
-}
-
-INSTANTIATE_TEST_SUITE_P(
-        EnvironmentalReverbTest, EnvironmentalReverbDensityTest,
-        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
-                                   IFactory::descriptor, getEffectTypeUuidEnvReverb())),
-                           testing::ValuesIn(EffectHelper::getTestValueSet<
-                                             EnvironmentalReverb, int, Range::environmentalReverb,
-                                             EnvironmentalReverb::densityPm>(
-                                   kDescPair, EffectHelper::expandTestValueBasic<int>))),
-        [](const testing::TestParamInfo<EnvironmentalReverbDensityTest::ParamType>& info) {
-            auto descriptor = std::get<0>(info.param).second;
-            std::string density = std::to_string(std::get<1>(info.param));
-
-            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
-                               descriptor.common.name + "_UUID_" +
-                               descriptor.common.id.uuid.toString() + "_density" + density;
-            std::replace_if(
-                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
-            return name;
-        });
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbDensityTest);
-
-class EnvironmentalReverbBypassTest
-    : public ::testing::TestWithParam<
-              std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, bool>>,
-      public EnvironmentalReverbHelper {
-  public:
-    EnvironmentalReverbBypassTest() : EnvironmentalReverbHelper(std::get<0>(GetParam())) {
-        mBypass = std::get<1>(GetParam());
-    }
-
-    void SetUp() override { SetUpReverb(); }
-
-    void TearDown() override { TearDownReverb(); }
-};
-
-TEST_P(EnvironmentalReverbBypassTest, SetAndGetBypass) {
-    EXPECT_NO_FATAL_FAILURE(addBypassParam(mBypass));
-    SetAndGetReverbParameters();
-}
-
-INSTANTIATE_TEST_SUITE_P(
-        EnvironmentalReverbTest, EnvironmentalReverbBypassTest,
-        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
-                                   IFactory::descriptor, getEffectTypeUuidEnvReverb())),
-                           testing::Bool()),
-        [](const testing::TestParamInfo<EnvironmentalReverbBypassTest::ParamType>& info) {
-            auto descriptor = std::get<0>(info.param).second;
-            std::string bypass = std::to_string(std::get<1>(info.param));
-
-            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
-                               descriptor.common.name + "_UUID_" +
-                               descriptor.common.id.uuid.toString() + "_bypass" + bypass;
-            std::replace_if(
-                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
-            return name;
-        });
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbBypassTest);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbMinimumParamTest);
 
 int main(int argc, char** argv) {
     ::testing::InitGoogleTest(&argc, argv);
diff --git a/audio/aidl/vts/VtsHalEqualizerTargetTest.cpp b/audio/aidl/vts/VtsHalEqualizerTargetTest.cpp
index d7dbe38..0c931ff 100644
--- a/audio/aidl/vts/VtsHalEqualizerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalEqualizerTargetTest.cpp
@@ -71,7 +71,7 @@
         ASSERT_NE(nullptr, mFactory);
         ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
 
-        Parameter::Common common = EffectHelper::createParamCommon(
+        Parameter::Common common = createParamCommon(
                 0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
                 kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
         IEffect::OpenEffectReturn ret;
diff --git a/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp b/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp
index d312111..6af326d 100644
--- a/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp
@@ -88,7 +88,7 @@
         ASSERT_NE(nullptr, mFactory);
         ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
 
-        Parameter::Common common = EffectHelper::createParamCommon(
+        Parameter::Common common = createParamCommon(
                 0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
                 kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
         IEffect::OpenEffectReturn ret;
@@ -225,7 +225,7 @@
                     std::to_string(std::get<PARAM_VIBRATION_INFORMATION_MAX_AMPLITUDE>(info.param));
             std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
                                descriptor.common.name + "_UUID_" +
-                               descriptor.common.id.uuid.toString() + "_hapticScaleId" +
+                               toString(descriptor.common.id.uuid) + "_hapticScaleId" +
                                hapticScaleID + "_hapticScaleVibScale" + hapticScaleVibScale +
                                "_resonantFrequency" + resonantFrequency + "_qFactor" + qFactor +
                                "_maxAmplitude" + maxAmplitude;
@@ -248,7 +248,7 @@
         ASSERT_NE(nullptr, mFactory);
         ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
 
-        Parameter::Common common = EffectHelper::createParamCommon(
+        Parameter::Common common = createParamCommon(
                 0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
                 kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
         IEffect::OpenEffectReturn ret;
@@ -422,7 +422,7 @@
             auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
             std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
                                descriptor.common.name + "_UUID_" +
-                               descriptor.common.id.uuid.toString();
+                               toString(descriptor.common.id.uuid);
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
diff --git a/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp b/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
index a075423..3c72dfa 100644
--- a/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
@@ -48,11 +48,12 @@
         ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
 
         Parameter::Specific specific = getDefaultParamSpecific();
-        Parameter::Common common = EffectHelper::createParamCommon(
+        Parameter::Common common = createParamCommon(
                 0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
                 kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
         ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &mOpenEffectReturn, EX_NONE));
         ASSERT_NE(nullptr, mEffect);
+        mVersion = EffectFactoryHelper::getHalVersion(mFactory);
     }
 
     void TearDownLoudnessEnhancer() {
@@ -114,6 +115,7 @@
     std::shared_ptr<IFactory> mFactory;
     std::shared_ptr<IEffect> mEffect;
     Descriptor mDescriptor;
+    int mVersion = 0;
 };
 
 /**
@@ -190,7 +192,8 @@
         ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
 
         // Write from buffer to message queues and calling process
-        EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(mStatusMQ, mInputMQ, mInputBuffer));
+        EXPECT_NO_FATAL_FAILURE(
+                EffectHelper::writeToFmq(mStatusMQ, mInputMQ, mInputBuffer, mVersion));
 
         // Read the updated message queues into buffer
         EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(mStatusMQ, 1, mOutputMQ,
diff --git a/audio/aidl/vts/VtsHalNSTargetTest.cpp b/audio/aidl/vts/VtsHalNSTargetTest.cpp
index 5c13512..a50e1b4 100644
--- a/audio/aidl/vts/VtsHalNSTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalNSTargetTest.cpp
@@ -49,7 +49,7 @@
         ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
 
         std::optional<Parameter::Specific> specific = getDefaultParamSpecific();
-        Parameter::Common common = EffectHelper::createParamCommon(
+        Parameter::Common common = createParamCommon(
                 0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
                 kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
         IEffect::OpenEffectReturn ret;
diff --git a/audio/aidl/vts/VtsHalPresetReverbTargetTest.cpp b/audio/aidl/vts/VtsHalPresetReverbTargetTest.cpp
index 1453495..2229ff8 100644
--- a/audio/aidl/vts/VtsHalPresetReverbTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalPresetReverbTargetTest.cpp
@@ -17,11 +17,14 @@
 #define LOG_TAG "VtsHalPresetReverbTargetTest"
 #include <android-base/logging.h>
 #include <android/binder_enums.h>
+#include <audio_utils/power.h>
+#include <system/audio.h>
 
 #include "EffectHelper.h"
 
 using namespace android;
 
+using aidl::android::hardware::audio::common::getChannelCount;
 using aidl::android::hardware::audio::effect::Descriptor;
 using aidl::android::hardware::audio::effect::getEffectTypeUuidPresetReverb;
 using aidl::android::hardware::audio::effect::IEffect;
@@ -30,6 +33,68 @@
 using aidl::android::hardware::audio::effect::PresetReverb;
 using android::hardware::audio::common::testing::detail::TestExecutionTracer;
 
+class PresetReverbHelper : public EffectHelper {
+  public:
+    void SetUpPresetReverb() {
+        ASSERT_NE(nullptr, mFactory);
+        ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+        Parameter::Specific specific = getDefaultParamSpecific();
+        Parameter::Common common = createParamCommon(
+                0 /* session */, 1 /* ioHandle */, kSamplingFrequency /* iSampleRate */,
+                kSamplingFrequency /* oSampleRate */, mFrameCount /* iFrameCount */,
+                mFrameCount /* oFrameCount */);
+        ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &mOpenEffectReturn, EX_NONE));
+        ASSERT_NE(nullptr, mEffect);
+    }
+
+    void TearDownPresetReverb() {
+        ASSERT_NO_FATAL_FAILURE(close(mEffect));
+        ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+        mOpenEffectReturn = IEffect::OpenEffectReturn{};
+    }
+
+    Parameter::Specific getDefaultParamSpecific() {
+        PresetReverb pr = PresetReverb::make<PresetReverb::preset>(kDefaultPreset);
+        Parameter::Specific specific =
+                Parameter::Specific::make<Parameter::Specific::presetReverb>(pr);
+        return specific;
+    }
+
+    Parameter createPresetReverbParam(const PresetReverb::Presets& param) {
+        return Parameter::make<Parameter::specific>(
+                Parameter::Specific::make<Parameter::Specific::presetReverb>(
+                        PresetReverb::make<PresetReverb::preset>(param)));
+    }
+
+    void setAndVerifyPreset(const PresetReverb::Presets& param) {
+        auto expectedParam = createPresetReverbParam(param);
+        EXPECT_STATUS(EX_NONE, mEffect->setParameter(expectedParam)) << expectedParam.toString();
+
+        PresetReverb::Id revId =
+                PresetReverb::Id::make<PresetReverb::Id::commonTag>(PresetReverb::preset);
+
+        auto id = Parameter::Id::make<Parameter::Id::presetReverbTag>(revId);
+        // get parameter
+        Parameter getParam;
+        EXPECT_STATUS(EX_NONE, mEffect->getParameter(id, &getParam));
+        EXPECT_EQ(expectedParam, getParam) << "\nexpectedParam:" << expectedParam.toString()
+                                           << "\ngetParam:" << getParam.toString();
+    }
+
+    static constexpr int kSamplingFrequency = 44100;
+    static constexpr int kDurationMilliSec = 2000;
+    static constexpr int kBufferSize = kSamplingFrequency * kDurationMilliSec / 1000;
+    int mStereoChannelCount =
+            getChannelCount(AudioChannelLayout::make<AudioChannelLayout::layoutMask>(
+                    AudioChannelLayout::LAYOUT_STEREO));
+    PresetReverb::Presets kDefaultPreset = PresetReverb::Presets::NONE;
+    int mFrameCount = kBufferSize / mStereoChannelCount;
+    std::shared_ptr<IFactory> mFactory;
+    std::shared_ptr<IEffect> mEffect;
+    IEffect::OpenEffectReturn mOpenEffectReturn;
+    Descriptor mDescriptor;
+};
+
 /**
  * Here we focus on specific parameter checking, general IEffect interfaces testing performed in
  * VtsAudioEffectTargetTest.
@@ -44,88 +109,116 @@
         ndk::enum_range<PresetReverb::Presets>().end()};
 
 class PresetReverbParamTest : public ::testing::TestWithParam<PresetReverbParamTestParam>,
-                              public EffectHelper {
+                              public PresetReverbHelper {
   public:
-    PresetReverbParamTest() : mParamPresets(std::get<PARAM_PRESETS>(GetParam())) {
+    PresetReverbParamTest() : mParamPreset(std::get<PARAM_PRESETS>(GetParam())) {
         std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
     }
 
-    void SetUp() override {
-        ASSERT_NE(nullptr, mFactory);
-        ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    void SetUp() override { ASSERT_NO_FATAL_FAILURE(SetUpPresetReverb()); }
 
-        Parameter::Specific specific = getDefaultParamSpecific();
-        Parameter::Common common = EffectHelper::createParamCommon(
-                0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
-                kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
-        IEffect::OpenEffectReturn ret;
-        ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &ret, EX_NONE));
-        ASSERT_NE(nullptr, mEffect);
-    }
+    void TearDown() override { TearDownPresetReverb(); }
 
-    void TearDown() override {
-        ASSERT_NO_FATAL_FAILURE(close(mEffect));
-        ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
-    }
-
-    static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
-    std::shared_ptr<IFactory> mFactory;
-    std::shared_ptr<IEffect> mEffect;
-    Descriptor mDescriptor;
-    PresetReverb::Presets mParamPresets = PresetReverb::Presets::NONE;
-
-    void SetAndGetPresetReverbParameters() {
-        for (auto& it : mTags) {
-            auto& tag = it.first;
-            auto& pr = it.second;
-
-            // validate parameter
-            Descriptor desc;
-            ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
-            const bool valid = isParameterValid<PresetReverb, Range::presetReverb>(it.second, desc);
-            const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
-
-            // set parameter
-            Parameter expectParam;
-            Parameter::Specific specific;
-            specific.set<Parameter::Specific::presetReverb>(pr);
-            expectParam.set<Parameter::specific>(specific);
-            // All values are valid, set parameter should succeed
-            EXPECT_STATUS(expected, mEffect->setParameter(expectParam)) << expectParam.toString();
-
-            // get parameter
-            Parameter getParam;
-            Parameter::Id id;
-            PresetReverb::Id prId;
-            prId.set<PresetReverb::Id::commonTag>(tag);
-            id.set<Parameter::Id::presetReverbTag>(prId);
-            EXPECT_STATUS(expected, mEffect->getParameter(id, &getParam));
-
-            EXPECT_EQ(expectParam, getParam);
-        }
-    }
-
-    void addPresetsParam(PresetReverb::Presets preset) {
-        PresetReverb pr;
-        pr.set<PresetReverb::preset>(preset);
-        mTags.push_back({PresetReverb::preset, pr});
-    }
-
-    Parameter::Specific getDefaultParamSpecific() {
-        PresetReverb pr = PresetReverb::make<PresetReverb::preset>(PresetReverb::Presets::NONE);
-        Parameter::Specific specific =
-                Parameter::Specific::make<Parameter::Specific::presetReverb>(pr);
-        return specific;
-    }
-
-  private:
-    std::vector<std::pair<PresetReverb::Tag, PresetReverb>> mTags;
-    void CleanUp() { mTags.clear(); }
+    const PresetReverb::Presets mParamPreset;
 };
 
 TEST_P(PresetReverbParamTest, SetAndGetPresets) {
-    EXPECT_NO_FATAL_FAILURE(addPresetsParam(mParamPresets));
-    SetAndGetPresetReverbParameters();
+    ASSERT_NO_FATAL_FAILURE(setAndVerifyPreset(mParamPreset));
+}
+
+using PresetReverbProcessTestParam = std::pair<std::shared_ptr<IFactory>, Descriptor>;
+
+class PresetReverbProcessTest : public ::testing::TestWithParam<PresetReverbProcessTestParam>,
+                                public PresetReverbHelper {
+  public:
+    PresetReverbProcessTest() {
+        std::tie(mFactory, mDescriptor) = GetParam();
+        generateSineWaveInput();
+    }
+
+    void SetUp() override {
+        SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
+        ASSERT_NO_FATAL_FAILURE(SetUpPresetReverb());
+    }
+    void TearDown() override {
+        SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
+        ASSERT_NO_FATAL_FAILURE(TearDownPresetReverb());
+    }
+
+    void generateSineWaveInput() {
+        int frequency = 1000;
+        for (size_t i = 0; i < kBufferSize; i++) {
+            mInput.push_back(sin(2 * M_PI * frequency * i / kSamplingFrequency));
+        }
+    }
+
+    bool isAuxiliary() {
+        return mDescriptor.common.flags.type ==
+               aidl::android::hardware::audio::effect::Flags::Type::AUXILIARY;
+    }
+
+    float computeReverbOutputEnergy(std::vector<float> output) {
+        if (!isAuxiliary()) {
+            // Extract auxiliary output
+            for (size_t i = 0; i < output.size(); i++) {
+                output[i] -= mInput[i];
+            }
+        }
+        return (audio_utils_compute_energy_mono(output.data(), AUDIO_FORMAT_PCM_FLOAT,
+                                                output.size()));
+    }
+
+    void setPresetAndProcess(const PresetReverb::Presets& preset, std::vector<float>& output) {
+        ASSERT_NO_FATAL_FAILURE(setAndVerifyPreset(preset));
+        ASSERT_NO_FATAL_FAILURE(
+                processAndWriteToOutput(mInput, output, mEffect, &mOpenEffectReturn));
+    }
+
+    void validateIncreasingEnergy(const std::vector<PresetReverb::Presets>& presets) {
+        float baseOutputEnergy = 0;
+
+        for (PresetReverb::Presets preset : presets) {
+            std::vector<float> output(kBufferSize);
+            setPresetAndProcess(preset, output);
+            float outputEnergy = computeReverbOutputEnergy(output);
+
+            ASSERT_GT(outputEnergy, baseOutputEnergy);
+            baseOutputEnergy = outputEnergy;
+        }
+    }
+
+    std::vector<float> mInput;
+};
+
+TEST_P(PresetReverbProcessTest, DecreasingRoomSize) {
+    std::vector<PresetReverb::Presets> roomPresets = {PresetReverb::Presets::LARGEROOM,
+                                                      PresetReverb::Presets::MEDIUMROOM,
+                                                      PresetReverb::Presets::SMALLROOM};
+    validateIncreasingEnergy(roomPresets);
+}
+
+TEST_P(PresetReverbProcessTest, DecreasingHallSize) {
+    std::vector<PresetReverb::Presets> hallPresets = {PresetReverb::Presets::LARGEHALL,
+                                                      PresetReverb::Presets::MEDIUMHALL};
+    validateIncreasingEnergy(hallPresets);
+}
+
+TEST_P(PresetReverbProcessTest, PresetPlate) {
+    std::vector<float> output(kBufferSize);
+
+    setPresetAndProcess(PresetReverb::Presets::PLATE, output);
+    float outputEnergy = computeReverbOutputEnergy(output);
+    // Since there is no comparator preset, validating it is greater than zero
+    ASSERT_GT(outputEnergy, 0);
+}
+
+TEST_P(PresetReverbProcessTest, PresetNone) {
+    std::vector<float> output(kBufferSize);
+
+    setPresetAndProcess(kDefaultPreset, output);
+    float outputEnergy = computeReverbOutputEnergy(output);
+    // NONE type doesn't create reverb effect
+    ASSERT_EQ(outputEnergy, 0);
 }
 
 INSTANTIATE_TEST_SUITE_P(
@@ -145,6 +238,17 @@
 
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(PresetReverbParamTest);
 
+INSTANTIATE_TEST_SUITE_P(
+        PresetReverbTest, PresetReverbProcessTest,
+        testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+                IFactory::descriptor, getEffectTypeUuidPresetReverb())),
+        [](const testing::TestParamInfo<PresetReverbProcessTest::ParamType>& info) {
+            auto descriptor = info.param;
+            return getPrefix(descriptor.second);
+        });
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(PresetReverbProcessTest);
+
 int main(int argc, char** argv) {
     ::testing::InitGoogleTest(&argc, argv);
     ::testing::UnitTest::GetInstance()->listeners().Append(new TestExecutionTracer());
diff --git a/audio/aidl/vts/VtsHalSpatializerTargetTest.cpp b/audio/aidl/vts/VtsHalSpatializerTargetTest.cpp
index f0b51b9..1f498e2 100644
--- a/audio/aidl/vts/VtsHalSpatializerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalSpatializerTargetTest.cpp
@@ -79,7 +79,7 @@
         ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
 
         Parameter::Specific specific = getDefaultParamSpecific();
-        Parameter::Common common = EffectHelper::createParamCommon(
+        Parameter::Common common = createParamCommon(
                 0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
                 kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
         IEffect::OpenEffectReturn ret;
diff --git a/audio/aidl/vts/VtsHalVirtualizerTargetTest.cpp b/audio/aidl/vts/VtsHalVirtualizerTargetTest.cpp
index 0c24f90..f121f7c 100644
--- a/audio/aidl/vts/VtsHalVirtualizerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalVirtualizerTargetTest.cpp
@@ -16,11 +16,14 @@
 
 #define LOG_TAG "VtsHalVirtualizerTest"
 #include <android-base/logging.h>
+#include <audio_utils/power.h>
+#include <system/audio.h>
 
 #include "EffectHelper.h"
 
 using namespace android;
 
+using aidl::android::hardware::audio::common::getChannelCount;
 using aidl::android::hardware::audio::effect::Descriptor;
 using aidl::android::hardware::audio::effect::getEffectTypeUuidVirtualizer;
 using aidl::android::hardware::audio::effect::IEffect;
@@ -29,6 +32,82 @@
 using aidl::android::hardware::audio::effect::Virtualizer;
 using android::hardware::audio::common::testing::detail::TestExecutionTracer;
 
+class VirtualizerHelper : public EffectHelper {
+  public:
+    void SetUpVirtualizer() {
+        ASSERT_NE(nullptr, mFactory);
+        ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+        initFrameCount();
+        Parameter::Specific specific = getDefaultParamSpecific();
+        Parameter::Common common = createParamCommon(
+                0 /* session */, 1 /* ioHandle */, kSamplingFrequency /* iSampleRate */,
+                kSamplingFrequency /* oSampleRate */, mInputFrameCount /* iFrameCount */,
+                mInputFrameCount /* oFrameCount */);
+        ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &mOpenEffectReturn, EX_NONE));
+        ASSERT_NE(nullptr, mEffect);
+    }
+
+    void TearDownVirtualizer() {
+        ASSERT_NO_FATAL_FAILURE(close(mEffect));
+        ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+        mOpenEffectReturn = IEffect::OpenEffectReturn{};
+    }
+
+    Parameter::Specific getDefaultParamSpecific() {
+        Virtualizer vr = Virtualizer::make<Virtualizer::strengthPm>(0);
+        Parameter::Specific specific =
+                Parameter::Specific::make<Parameter::Specific::virtualizer>(vr);
+        return specific;
+    }
+
+    Parameter createVirtualizerStrengthParam(int param) {
+        return Parameter::make<Parameter::specific>(
+                Parameter::Specific::make<Parameter::Specific::virtualizer>(
+                        Virtualizer::make<Virtualizer::strengthPm>(param)));
+    }
+
+    void initFrameCount() {
+        mInputFrameCount = kBufferSize / kChannelCount;
+        mOutputFrameCount = kBufferSize / kChannelCount;
+    }
+
+    bool isStrengthValid(int level) {
+        auto vir = Virtualizer::make<Virtualizer::strengthPm>(level);
+        return isParameterValid<Virtualizer, Range::virtualizer>(vir, mDescriptor);
+    }
+
+    void setAndVerifyStrength(int param, binder_exception_t expected) {
+        auto expectedParam = createVirtualizerStrengthParam(param);
+        EXPECT_STATUS(expected, mEffect->setParameter(expectedParam)) << expectedParam.toString();
+
+        if (expected == EX_NONE) {
+            Virtualizer::Id vrlId =
+                    Virtualizer::Id::make<Virtualizer::Id::commonTag>(Virtualizer::strengthPm);
+
+            auto id = Parameter::Id::make<Parameter::Id::virtualizerTag>(vrlId);
+            // get parameter
+            Parameter getParam;
+            // if set success, then get should match
+            EXPECT_STATUS(expected, mEffect->getParameter(id, &getParam));
+            EXPECT_EQ(expectedParam, getParam) << "\nexpectedParam:" << expectedParam.toString()
+                                               << "\ngetParam:" << getParam.toString();
+        }
+    }
+
+    static constexpr int kSamplingFrequency = 44100;
+    static constexpr int kDefaultChannelLayout = AudioChannelLayout::LAYOUT_STEREO;
+    static constexpr int kDurationMilliSec = 2000;
+    static constexpr int kBufferSize = kSamplingFrequency * kDurationMilliSec / 1000;
+    int kChannelCount = getChannelCount(
+            AudioChannelLayout::make<AudioChannelLayout::layoutMask>(kDefaultChannelLayout));
+    long mInputFrameCount;
+    long mOutputFrameCount;
+    std::shared_ptr<IFactory> mFactory;
+    std::shared_ptr<IEffect> mEffect;
+    IEffect::OpenEffectReturn mOpenEffectReturn;
+    Descriptor mDescriptor;
+};
+
 /**
  * Here we focus on specific parameter checking, general IEffect interfaces testing performed in
  * VtsAudioEffectTargetTest.
@@ -44,89 +123,89 @@
  */
 
 class VirtualizerParamTest : public ::testing::TestWithParam<VirtualizerParamTestParam>,
-                             public EffectHelper {
+                             public VirtualizerHelper {
   public:
     VirtualizerParamTest() : mParamStrength(std::get<PARAM_STRENGTH>(GetParam())) {
         std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
     }
+    void SetUp() override { ASSERT_NO_FATAL_FAILURE(SetUpVirtualizer()); }
+    void TearDown() override { TearDownVirtualizer(); }
+
+    int mParamStrength = 0;
+};
+
+TEST_P(VirtualizerParamTest, SetAndGetStrength) {
+    ASSERT_NO_FATAL_FAILURE(setAndVerifyStrength(
+            mParamStrength, isStrengthValid(mParamStrength) ? EX_NONE : EX_ILLEGAL_ARGUMENT));
+}
+
+enum ProcessTestParam { PROCESS_INSTANCE_NAME, PROCESS_ZERO_INPUT };
+using VirtualizerProcessTestParam =
+        std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, bool>;
+
+class VirtualizerProcessTest : public ::testing::TestWithParam<VirtualizerProcessTestParam>,
+                               public VirtualizerHelper {
+  public:
+    VirtualizerProcessTest() : mZeroInput(std::get<PROCESS_ZERO_INPUT>(GetParam())) {
+        std::tie(mFactory, mDescriptor) = std::get<PROCESS_INSTANCE_NAME>(GetParam());
+    }
 
     void SetUp() override {
-        ASSERT_NE(nullptr, mFactory);
-        ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
-
-        Parameter::Specific specific = getDefaultParamSpecific();
-        Parameter::Common common = EffectHelper::createParamCommon(
-                0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
-                kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
-        IEffect::OpenEffectReturn ret;
-        ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &ret, EX_NONE));
-        ASSERT_NE(nullptr, mEffect);
+        SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
+        ASSERT_NO_FATAL_FAILURE(SetUpVirtualizer());
     }
 
     void TearDown() override {
-        ASSERT_NO_FATAL_FAILURE(close(mEffect));
-        ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+        SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
+        ASSERT_NO_FATAL_FAILURE(TearDownVirtualizer());
     }
 
-    Parameter::Specific getDefaultParamSpecific() {
-        Virtualizer vr = Virtualizer::make<Virtualizer::strengthPm>(0);
-        Parameter::Specific specific =
-                Parameter::Specific::make<Parameter::Specific::virtualizer>(vr);
-        return specific;
-    }
-
-    static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
-    std::shared_ptr<IFactory> mFactory;
-    std::shared_ptr<IEffect> mEffect;
-    Descriptor mDescriptor;
-    int mParamStrength = 0;
-
-    void SetAndGetVirtualizerParameters() {
-        for (auto& it : mTags) {
-            auto& tag = it.first;
-            auto& vr = it.second;
-
-            // validate parameter
-            Descriptor desc;
-            ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
-            const bool valid = isParameterValid<Virtualizer, Range::virtualizer>(it.second, desc);
-            const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
-
-            // set parameter
-            Parameter expectParam;
-            Parameter::Specific specific;
-            specific.set<Parameter::Specific::virtualizer>(vr);
-            expectParam.set<Parameter::specific>(specific);
-            EXPECT_STATUS(expected, mEffect->setParameter(expectParam)) << expectParam.toString();
-
-            // only get if parameter in range and set success
-            if (expected == EX_NONE) {
-                Parameter getParam;
-                Parameter::Id id;
-                Virtualizer::Id vrId;
-                vrId.set<Virtualizer::Id::commonTag>(tag);
-                id.set<Parameter::Id::virtualizerTag>(vrId);
-                // if set success, then get should match
-                EXPECT_STATUS(expected, mEffect->getParameter(id, &getParam));
-                EXPECT_EQ(expectParam, getParam);
+    void generateInput(std::vector<float>& buffer) {
+        if (mZeroInput) {
+            std::fill(buffer.begin(), buffer.end(), 0);
+        } else {
+            int frequency = 100;
+            for (size_t i = 0; i < buffer.size(); i++) {
+                buffer[i] = sin(2 * M_PI * frequency * i / kSamplingFrequency);
             }
         }
     }
 
-    void addStrengthParam(int strength) {
-        Virtualizer vr;
-        vr.set<Virtualizer::strengthPm>(strength);
-        mTags.push_back({Virtualizer::strengthPm, vr});
-    }
-
-  private:
-    std::vector<std::pair<Virtualizer::Tag, Virtualizer>> mTags;
-    void CleanUp() { mTags.clear(); }
+    static constexpr float kAbsError = 0.00001;
+    bool mZeroInput;
 };
 
-TEST_P(VirtualizerParamTest, SetAndGetStrength) {
-    EXPECT_NO_FATAL_FAILURE(addStrengthParam(mParamStrength));
-    SetAndGetVirtualizerParameters();
+TEST_P(VirtualizerProcessTest, IncreasingStrength) {
+    std::vector<float> input(kBufferSize);
+    std::vector<float> output(kBufferSize);
+    std::vector<int> strengths = {250, 500, 750, 1000};
+
+    generateInput(input);
+
+    const float inputRmse =
+            audio_utils_compute_energy_mono(input.data(), AUDIO_FORMAT_PCM_FLOAT, input.size());
+
+    for (int strength : strengths) {
+        // Skipping the further steps for unnsupported Strength values
+        if (!isStrengthValid(strength)) {
+            continue;
+        }
+        setAndVerifyStrength(strength, EX_NONE);
+        ASSERT_NO_FATAL_FAILURE(
+                processAndWriteToOutput(input, output, mEffect, &mOpenEffectReturn));
+
+        const float outputRmse = audio_utils_compute_energy_mono(
+                output.data(), AUDIO_FORMAT_PCM_FLOAT, output.size());
+
+        if (inputRmse != 0) {
+            EXPECT_NE(outputRmse, 0);
+            if (strength != 0) {
+                EXPECT_GT(abs(outputRmse - inputRmse), kAbsError);
+            }
+        } else {
+            EXPECT_NEAR(outputRmse, inputRmse, kAbsError);
+        }
+    }
 }
 
 std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kDescPair;
@@ -149,6 +228,22 @@
 
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VirtualizerParamTest);
 
+INSTANTIATE_TEST_SUITE_P(
+        VirtualizerTest, VirtualizerProcessTest,
+        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+                                   IFactory::descriptor, getEffectTypeUuidVirtualizer())),
+                           testing::Bool()),
+        [](const testing::TestParamInfo<VirtualizerProcessTest::ParamType>& info) {
+            auto descriptor = std::get<PROCESS_INSTANCE_NAME>(info.param).second;
+            std::string isInputZero = std::to_string(std::get<PROCESS_ZERO_INPUT>(info.param));
+            std::string name = getPrefix(descriptor) + "_isInputZero_" + isInputZero;
+            std::replace_if(
+                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+            return name;
+        });
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VirtualizerProcessTest);
+
 int main(int argc, char** argv) {
     ::testing::InitGoogleTest(&argc, argv);
     ::testing::UnitTest::GetInstance()->listeners().Append(new TestExecutionTracer());
diff --git a/audio/aidl/vts/VtsHalVisualizerTargetTest.cpp b/audio/aidl/vts/VtsHalVisualizerTargetTest.cpp
index db83715..f215a8e 100644
--- a/audio/aidl/vts/VtsHalVisualizerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalVisualizerTargetTest.cpp
@@ -62,7 +62,7 @@
         ASSERT_NE(nullptr, mFactory);
         ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
 
-        Parameter::Common common = EffectHelper::createParamCommon(
+        Parameter::Common common = createParamCommon(
                 0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
                 kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
         IEffect::OpenEffectReturn ret;
diff --git a/audio/aidl/vts/VtsHalVolumeTargetTest.cpp b/audio/aidl/vts/VtsHalVolumeTargetTest.cpp
index 1c1489d..db2f4a9 100644
--- a/audio/aidl/vts/VtsHalVolumeTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalVolumeTargetTest.cpp
@@ -37,7 +37,7 @@
         ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
         initFrameCount();
         Parameter::Specific specific = getDefaultParamSpecific();
-        Parameter::Common common = EffectHelper::createParamCommon(
+        Parameter::Common common = createParamCommon(
                 0 /* session */, 1 /* ioHandle */, kSamplingFrequency /* iSampleRate */,
                 kSamplingFrequency /* oSampleRate */, mInputFrameCount /* iFrameCount */,
                 mInputFrameCount /* oFrameCount */);
diff --git a/audio/common/2.0/Android.bp b/audio/common/2.0/Android.bp
index 450e04f..679d6b0 100644
--- a/audio/common/2.0/Android.bp
+++ b/audio/common/2.0/Android.bp
@@ -15,9 +15,6 @@
     root: "android.hardware",
     // TODO(b/153609531): remove when no longer needed.
     native_bridge_supported: true,
-    vndk: {
-        enabled: true,
-    },
     srcs: [
         "types.hal",
     ],
diff --git a/automotive/audiocontrol/1.0/default/test/fuzzer/Android.bp b/automotive/audiocontrol/1.0/default/test/fuzzer/Android.bp
index 4308d52..d63695d 100644
--- a/automotive/audiocontrol/1.0/default/test/fuzzer/Android.bp
+++ b/automotive/audiocontrol/1.0/default/test/fuzzer/Android.bp
@@ -19,6 +19,7 @@
  */
 
 package {
+    default_team: "trendy_team_aaos_framework",
     // See: http://go/android-license-faq
     // A large-scale-change added 'default_applicable_licenses' to import
     // all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/automotive/audiocontrol/aidl/vts/Android.bp b/automotive/audiocontrol/aidl/vts/Android.bp
index c73ad79..d94ad55 100644
--- a/automotive/audiocontrol/aidl/vts/Android.bp
+++ b/automotive/audiocontrol/aidl/vts/Android.bp
@@ -13,6 +13,7 @@
 // limitations under the License.
 
 package {
+    default_team: "trendy_team_aaos_framework",
     // See: http://go/android-license-faq
     // A large-scale-change added 'default_applicable_licenses' to import
     // all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/automotive/can/1.0/default/Android.bp b/automotive/can/1.0/default/Android.bp
index 05691d9..0a68fbc 100644
--- a/automotive/can/1.0/default/Android.bp
+++ b/automotive/can/1.0/default/Android.bp
@@ -55,7 +55,6 @@
     ],
     static_libs: [
         "android.hardware.automotive.can@libnetdevice",
-        "android.hardware.automotive@libc++fs",
         "libnl++",
     ],
     vintf_fragments: ["manifest_android.hardware.automotive.can@1.0.xml"],
diff --git a/automotive/can/1.0/default/CanBus.h b/automotive/can/1.0/default/CanBus.h
index 8b73258..977bfcc 100644
--- a/automotive/can/1.0/default/CanBus.h
+++ b/automotive/can/1.0/default/CanBus.h
@@ -24,6 +24,7 @@
 #include <utils/Mutex.h>
 
 #include <atomic>
+#include <mutex>
 #include <thread>
 
 namespace android::hardware::automotive::can::V1_0::implementation {
diff --git a/automotive/can/1.0/default/CanController.cpp b/automotive/can/1.0/default/CanController.cpp
index 1b5bf5b..4a7ab7e 100644
--- a/automotive/can/1.0/default/CanController.cpp
+++ b/automotive/can/1.0/default/CanController.cpp
@@ -23,7 +23,7 @@
 #include <android-base/logging.h>
 #include <android/hidl/manager/1.2/IServiceManager.h>
 
-#include <automotive/filesystem>
+#include <filesystem>
 #include <fstream>
 #include <regex>
 
@@ -31,7 +31,7 @@
 
 using IfId = ICanController::BusConfig::InterfaceId;
 using IfIdDisc = ICanController::BusConfig::InterfaceId::hidl_discriminator;
-namespace fs = android::hardware::automotive::filesystem;
+namespace fs = ::std::filesystem;
 
 namespace fsErrors {
 static const std::error_code ok;
diff --git a/automotive/can/1.0/default/tests/fuzzer/Android.bp b/automotive/can/1.0/default/tests/fuzzer/Android.bp
index de0b96f..474b5a6 100644
--- a/automotive/can/1.0/default/tests/fuzzer/Android.bp
+++ b/automotive/can/1.0/default/tests/fuzzer/Android.bp
@@ -16,6 +16,7 @@
  */
 
 package {
+    default_team: "trendy_team_connectivity_telemetry",
     // See: http://go/android-license-faq
     // A large-scale-change added 'default_applicable_licenses' to import
     // all of the 'license_kinds' from "hardware_interfaces_license"
@@ -42,12 +43,12 @@
     ],
     static_libs: [
         "android.hardware.automotive.can@libnetdevice",
-        "android.hardware.automotive@libc++fs",
         "libnl++",
     ],
     fuzz_config: {
         cc: [
-            "android-media-fuzzing-reports@google.com",
+            "chrisweir@google.com",
+            "twasilczyk@google.com",
         ],
         componentid: 533764,
         hotlists: [
diff --git a/automotive/can/1.0/tools/libprotocan/include/libprotocan/MessageInjector.h b/automotive/can/1.0/tools/libprotocan/include/libprotocan/MessageInjector.h
index b0ea260..e35feee 100644
--- a/automotive/can/1.0/tools/libprotocan/include/libprotocan/MessageInjector.h
+++ b/automotive/can/1.0/tools/libprotocan/include/libprotocan/MessageInjector.h
@@ -22,6 +22,7 @@
 #include <libprotocan/MessageDef.h>
 #include <utils/Mutex.h>
 
+#include <mutex>
 #include <queue>
 
 namespace android::hardware::automotive::protocan {
diff --git a/automotive/can/1.0/tools/libprotocan/tests/Android.bp b/automotive/can/1.0/tools/libprotocan/tests/Android.bp
index 251cc06..f7e6d87 100644
--- a/automotive/can/1.0/tools/libprotocan/tests/Android.bp
+++ b/automotive/can/1.0/tools/libprotocan/tests/Android.bp
@@ -15,6 +15,7 @@
 //
 
 package {
+    default_team: "trendy_team_automotive",
     // See: http://go/android-license-faq
     // A large-scale-change added 'default_applicable_licenses' to import
     // all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/automotive/can/aidl/default/Android.bp b/automotive/can/aidl/default/Android.bp
index d44cb91..d4e2840 100644
--- a/automotive/can/aidl/default/Android.bp
+++ b/automotive/can/aidl/default/Android.bp
@@ -44,7 +44,6 @@
     ],
     static_libs: [
         "android.hardware.automotive.can@libnetdevice",
-        "android.hardware.automotive@libc++fs",
         "libnl++",
     ],
     vintf_fragments: ["android.hardware.automotive.can.xml"],
diff --git a/automotive/can/aidl/default/CanController.cpp b/automotive/can/aidl/default/CanController.cpp
index e4b5306..1435a02 100644
--- a/automotive/can/aidl/default/CanController.cpp
+++ b/automotive/can/aidl/default/CanController.cpp
@@ -23,13 +23,13 @@
 #include <android-base/format.h>
 #include <android-base/logging.h>
 
-#include <automotive/filesystem>
+#include <filesystem>
 #include <fstream>
 #include <regex>
 
 namespace aidl::android::hardware::automotive::can {
 
-namespace fs = ::android::hardware::automotive::filesystem;
+namespace fs = ::std::filesystem;
 
 namespace fsErrors {
 static const std::error_code ok;
diff --git a/automotive/evs/1.1/vts/fuzzing/Android.bp b/automotive/evs/1.1/vts/fuzzing/Android.bp
index 1764821..909d80d 100644
--- a/automotive/evs/1.1/vts/fuzzing/Android.bp
+++ b/automotive/evs/1.1/vts/fuzzing/Android.bp
@@ -15,6 +15,7 @@
 //
 
 package {
+    default_team: "trendy_team_automotive",
     // See: http://go/android-license-faq
     // A large-scale-change added 'default_applicable_licenses' to import
     // all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/automotive/evs/aidl/Android.bp b/automotive/evs/aidl/Android.bp
index 3bfe8f3..dfb15c6 100644
--- a/automotive/evs/aidl/Android.bp
+++ b/automotive/evs/aidl/Android.bp
@@ -42,9 +42,6 @@
             enabled: false,
         },
         ndk: {
-            vndk: {
-                enabled: false,
-            },
             min_sdk_version: "29",
         },
     },
diff --git a/automotive/evs/aidl/impl/default/Android.bp b/automotive/evs/aidl/impl/default/Android.bp
index 3d5b7c4..7818804 100644
--- a/automotive/evs/aidl/impl/default/Android.bp
+++ b/automotive/evs/aidl/impl/default/Android.bp
@@ -13,6 +13,7 @@
 // limitations under the License.
 
 package {
+    default_team: "trendy_team_automotive",
     // See: http://go/android-license-faq
     // A large-scale-change added 'default_applicable_licenses' to import
     // all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/automotive/evs/common/utils/default/test/fuzz/Android.bp b/automotive/evs/common/utils/default/test/fuzz/Android.bp
index a2cf273..b4581e4 100644
--- a/automotive/evs/common/utils/default/test/fuzz/Android.bp
+++ b/automotive/evs/common/utils/default/test/fuzz/Android.bp
@@ -15,6 +15,7 @@
 //
 
 package {
+    default_team: "trendy_team_automotive",
     // See: http://go/android-license-faq
     // A large-scale-change added 'default_applicable_licenses' to import
     // all of the 'license_kinds' from "hardware_interfaces_license"
@@ -25,12 +26,12 @@
 
 cc_fuzz {
     host_supported: true,
-    name : "FormatConvertFuzzer_copyNV21toRGB32",
+    name: "FormatConvertFuzzer_copyNV21toRGB32",
     srcs: [
         "FormatConvertFuzzer.cpp",
     ],
     static_libs: [
-        "android.hardware.automotive.evs@common-default-lib"
+        "android.hardware.automotive.evs@common-default-lib",
     ],
     cflags: [
         "-DCOPY_NV21_TO_RGB32",
@@ -39,12 +40,12 @@
 
 cc_fuzz {
     host_supported: true,
-    name : "FormatConvertFuzzer_copyNV21toBGR32",
+    name: "FormatConvertFuzzer_copyNV21toBGR32",
     srcs: [
         "FormatConvertFuzzer.cpp",
     ],
     static_libs: [
-        "android.hardware.automotive.evs@common-default-lib"
+        "android.hardware.automotive.evs@common-default-lib",
     ],
     cflags: [
         "-DCOPY_NV21_TO_BGR32",
@@ -53,12 +54,12 @@
 
 cc_fuzz {
     host_supported: true,
-    name : "FormatConvertFuzzer_copyYV12toRGB32",
+    name: "FormatConvertFuzzer_copyYV12toRGB32",
     srcs: [
         "FormatConvertFuzzer.cpp",
     ],
     static_libs: [
-        "android.hardware.automotive.evs@common-default-lib"
+        "android.hardware.automotive.evs@common-default-lib",
     ],
     cflags: [
         "-DCOPY_YV12_TO_RGB32",
@@ -67,12 +68,12 @@
 
 cc_fuzz {
     host_supported: true,
-    name : "FormatConvertFuzzer_copyYV12toBGR32",
+    name: "FormatConvertFuzzer_copyYV12toBGR32",
     srcs: [
         "FormatConvertFuzzer.cpp",
     ],
     static_libs: [
-        "android.hardware.automotive.evs@common-default-lib"
+        "android.hardware.automotive.evs@common-default-lib",
     ],
     cflags: [
         "-DCOPY_YV12_TO_BGR32",
@@ -81,12 +82,12 @@
 
 cc_fuzz {
     host_supported: true,
-    name : "FormatConvertFuzzer_copyYUYVtoRGB32",
+    name: "FormatConvertFuzzer_copyYUYVtoRGB32",
     srcs: [
         "FormatConvertFuzzer.cpp",
     ],
     static_libs: [
-        "android.hardware.automotive.evs@common-default-lib"
+        "android.hardware.automotive.evs@common-default-lib",
     ],
     cflags: [
         "-DCOPY_YUYV_TO_RGB32",
@@ -95,12 +96,12 @@
 
 cc_fuzz {
     host_supported: true,
-    name : "FormatConvertFuzzer_copyYUYVtoBGR32",
+    name: "FormatConvertFuzzer_copyYUYVtoBGR32",
     srcs: [
         "FormatConvertFuzzer.cpp",
     ],
     static_libs: [
-        "android.hardware.automotive.evs@common-default-lib"
+        "android.hardware.automotive.evs@common-default-lib",
     ],
     cflags: [
         "-DCOPY_YUYV_TO_BGR32",
diff --git a/automotive/ivn_android_device/impl/default/test/Android.bp b/automotive/ivn_android_device/impl/default/test/Android.bp
index a100575..1873e79 100644
--- a/automotive/ivn_android_device/impl/default/test/Android.bp
+++ b/automotive/ivn_android_device/impl/default/test/Android.bp
@@ -15,6 +15,7 @@
  */
 
 package {
+    default_team: "trendy_team_android_kernel",
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
diff --git a/automotive/ivn_android_device/vts/Android.bp b/automotive/ivn_android_device/vts/Android.bp
index e4b9d64..07388f3 100644
--- a/automotive/ivn_android_device/vts/Android.bp
+++ b/automotive/ivn_android_device/vts/Android.bp
@@ -15,6 +15,7 @@
  */
 
 package {
+    default_team: "trendy_team_aaos_framework",
     // See: http://go/android-license-faq
     // A large-scale-change added 'default_applicable_licenses' to import
     // all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/automotive/occupant_awareness/aidl/default/Android.bp b/automotive/occupant_awareness/aidl/default/Android.bp
index dc280df..5f009d8 100644
--- a/automotive/occupant_awareness/aidl/default/Android.bp
+++ b/automotive/occupant_awareness/aidl/default/Android.bp
@@ -15,6 +15,7 @@
  */
 
 package {
+    default_team: "trendy_team_android_kernel",
     // See: http://go/android-license-faq
     // A large-scale-change added 'default_applicable_licenses' to import
     // all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/automotive/occupant_awareness/aidl/vts/functional/Android.bp b/automotive/occupant_awareness/aidl/vts/functional/Android.bp
index f248aa9..648dd49 100644
--- a/automotive/occupant_awareness/aidl/vts/functional/Android.bp
+++ b/automotive/occupant_awareness/aidl/vts/functional/Android.bp
@@ -1,4 +1,5 @@
 package {
+    default_team: "trendy_team_aaos_framework",
     // See: http://go/android-license-faq
     // A large-scale-change added 'default_applicable_licenses' to import
     // all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/automotive/remoteaccess/hal/default/Android.bp b/automotive/remoteaccess/hal/default/Android.bp
index cf173d5..cc8f2b0 100644
--- a/automotive/remoteaccess/hal/default/Android.bp
+++ b/automotive/remoteaccess/hal/default/Android.bp
@@ -15,6 +15,7 @@
  */
 
 package {
+    default_team: "trendy_team_aaos_framework",
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
diff --git a/automotive/remoteaccess/hal/default/test/Android.bp b/automotive/remoteaccess/hal/default/test/Android.bp
index 227175a..378a330 100644
--- a/automotive/remoteaccess/hal/default/test/Android.bp
+++ b/automotive/remoteaccess/hal/default/test/Android.bp
@@ -13,6 +13,7 @@
 // limitations under the License.
 
 package {
+    default_team: "trendy_team_aaos_framework",
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
diff --git a/automotive/remoteaccess/test_grpc_server/impl/Android.bp b/automotive/remoteaccess/test_grpc_server/impl/Android.bp
index fd174bf..8d8d72a 100644
--- a/automotive/remoteaccess/test_grpc_server/impl/Android.bp
+++ b/automotive/remoteaccess/test_grpc_server/impl/Android.bp
@@ -13,6 +13,7 @@
 // limitations under the License.
 
 package {
+    default_team: "trendy_team_aaos_framework",
     // See: http://go/android-license-faq
     // A large-scale-change added 'default_applicable_licenses' to import
     // all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/automotive/sv/1.0/default/tests/fuzzer/Android.bp b/automotive/sv/1.0/default/tests/fuzzer/Android.bp
index 696bfad..accc470 100644
--- a/automotive/sv/1.0/default/tests/fuzzer/Android.bp
+++ b/automotive/sv/1.0/default/tests/fuzzer/Android.bp
@@ -16,6 +16,7 @@
  */
 
 package {
+    default_team: "trendy_team_automotive",
     // See: http://go/android-license-faq
     // A large-scale-change added 'default_applicable_licenses' to import
     // all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/automotive/vehicle/2.0/default/Android.bp b/automotive/vehicle/2.0/default/Android.bp
index 586a98e..94a5882 100644
--- a/automotive/vehicle/2.0/default/Android.bp
+++ b/automotive/vehicle/2.0/default/Android.bp
@@ -13,6 +13,7 @@
 // limitations under the License.
 
 package {
+    default_team: "trendy_team_aaos_framework",
     // See: http://go/android-license-faq
     // A large-scale-change added 'default_applicable_licenses' to import
     // all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/automotive/vehicle/2.0/utils/Android.bp b/automotive/vehicle/2.0/utils/Android.bp
index 770d447..802b4b3 100644
--- a/automotive/vehicle/2.0/utils/Android.bp
+++ b/automotive/vehicle/2.0/utils/Android.bp
@@ -14,6 +14,7 @@
 
 // User HAL helper library.
 package {
+    default_team: "trendy_team_aaos_framework",
     // See: http://go/android-license-faq
     // A large-scale-change added 'default_applicable_licenses' to import
     // all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/automotive/vehicle/OWNERS b/automotive/vehicle/OWNERS
index 9a6b65d..f099287 100644
--- a/automotive/vehicle/OWNERS
+++ b/automotive/vehicle/OWNERS
@@ -2,7 +2,7 @@
 shanyu@google.com
 
 # GRPC VHAL
-per-file aidl/impl/grpc/** = chenhaosjtuacm@google.com, egranata@google.com
+per-file aidl/impl/grpc/** =egranata@google.com
 
 # Property definition
 per-file aidl_property/** = tylertrephan@google.com
diff --git a/automotive/vehicle/TEST_MAPPING b/automotive/vehicle/TEST_MAPPING
index 7306b47..77629a9 100644
--- a/automotive/vehicle/TEST_MAPPING
+++ b/automotive/vehicle/TEST_MAPPING
@@ -55,5 +55,10 @@
     {
       "name": "VehicleHalProtoMessageConverterTest"
     }
+  ],
+  "postsubmit": [
+    {
+      "name": "VehicleHalProtoMessageConverterTest"
+    }
   ]
 }
diff --git a/automotive/vehicle/aidl/Android.bp b/automotive/vehicle/aidl/Android.bp
index ed18ebc..ce9e7a1 100644
--- a/automotive/vehicle/aidl/Android.bp
+++ b/automotive/vehicle/aidl/Android.bp
@@ -60,5 +60,5 @@
         },
 
     ],
-
+    host_supported: true,
 }
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/.hash b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/.hash
index b04a6b5..aae94d1 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/.hash
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/.hash
@@ -1 +1,2 @@
 a741c2814ba6e9852e106bc26e820d741f66ebb8
+2e101035a8abf667295ca2106bebb8850b9bdc9c
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/GetValueRequest.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/GetValueRequest.aidl
index d88cd8b..15a2024 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/GetValueRequest.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/GetValueRequest.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@JavaDerive(equals=true, toString=true) @VintfStability
+@JavaDerive(equals=true, toString=true) @RustDerive(Clone=true) @VintfStability
 parcelable GetValueRequest {
   long requestId;
   android.hardware.automotive.vehicle.VehiclePropValue prop;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/GetValueResult.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/GetValueResult.aidl
index 25f3575..a8e0ac8 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/GetValueResult.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/GetValueResult.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@JavaDerive(equals=true, toString=true) @VintfStability
+@JavaDerive(equals=true, toString=true) @RustDerive(Clone=true) @VintfStability
 parcelable GetValueResult {
   long requestId;
   android.hardware.automotive.vehicle.StatusCode status = android.hardware.automotive.vehicle.StatusCode.OK;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/RawPropValues.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/RawPropValues.aidl
index e7b0a13..80e81b2 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/RawPropValues.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/RawPropValues.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@JavaDerive(equals=true, toString=true) @VintfStability
+@JavaDerive(equals=true, toString=true) @RustDerive(Clone=true) @VintfStability
 parcelable RawPropValues {
   int[] int32Values = {};
   float[] floatValues;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/SetValueRequest.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/SetValueRequest.aidl
index 6a65307..9b392f5 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/SetValueRequest.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/SetValueRequest.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@JavaDerive(equals=true, toString=true) @VintfStability
+@JavaDerive(equals=true, toString=true) @RustDerive(Clone=true) @VintfStability
 parcelable SetValueRequest {
   long requestId;
   android.hardware.automotive.vehicle.VehiclePropValue value;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/SetValueResult.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/SetValueResult.aidl
index ec5fabb..57aa11f 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/SetValueResult.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/SetValueResult.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@JavaDerive(equals=true, toString=true) @VintfStability
+@JavaDerive(equals=true, toString=true) @RustDerive(Clone=true) @VintfStability
 parcelable SetValueResult {
   long requestId;
   android.hardware.automotive.vehicle.StatusCode status = android.hardware.automotive.vehicle.StatusCode.OK;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/SubscribeOptions.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/SubscribeOptions.aidl
index 91e7c14..1f89a01 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/SubscribeOptions.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/SubscribeOptions.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@JavaDerive(equals=true, toString=true) @VintfStability
+@JavaDerive(equals=true, toString=true) @RustDerive(Clone=true) @VintfStability
 parcelable SubscribeOptions {
   int propId;
   int[] areaIds;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
index 6960894..c8887d9 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@JavaDerive(equals=true, toString=true) @VintfStability
+@JavaDerive(equals=true, toString=true) @RustDerive(Clone=true) @VintfStability
 parcelable VehicleAreaConfig {
   int areaId;
   int minInt32Value;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/VehiclePropConfig.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/VehiclePropConfig.aidl
index 8602d2d..32dac44 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/VehiclePropConfig.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/VehiclePropConfig.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@JavaDerive(equals=true, toString=true) @VintfStability
+@JavaDerive(equals=true, toString=true) @RustDerive(Clone=true) @VintfStability
 parcelable VehiclePropConfig {
   int prop;
   android.hardware.automotive.vehicle.VehiclePropertyAccess access = android.hardware.automotive.vehicle.VehiclePropertyAccess.NONE;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/VehiclePropError.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/VehiclePropError.aidl
index 9835295..9d49f1d 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/VehiclePropError.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/VehiclePropError.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@JavaDerive(equals=true, toString=true) @VintfStability
+@JavaDerive(equals=true, toString=true) @RustDerive(Clone=true) @VintfStability
 parcelable VehiclePropError {
   int propId;
   int areaId;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/VehiclePropValue.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/VehiclePropValue.aidl
index c87379f..f9feff5 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/VehiclePropValue.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/VehiclePropValue.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@JavaDerive(equals=true, toString=true) @VintfStability
+@JavaDerive(equals=true, toString=true) @RustDerive(Clone=true) @VintfStability
 parcelable VehiclePropValue {
   long timestamp;
   int areaId;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/3/.hash b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/3/.hash
index 312f858..ce35dbb 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/3/.hash
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/3/.hash
@@ -1 +1,2 @@
 c6f1cc74f83dc53c6a5c08e6dbbb6e25e83e3a6b
+c046ced69d333e4470cd211e2159cce84faae233
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/3/android/hardware/automotive/vehicle/GetValueRequest.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/3/android/hardware/automotive/vehicle/GetValueRequest.aidl
index d88cd8b..15a2024 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/3/android/hardware/automotive/vehicle/GetValueRequest.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/3/android/hardware/automotive/vehicle/GetValueRequest.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@JavaDerive(equals=true, toString=true) @VintfStability
+@JavaDerive(equals=true, toString=true) @RustDerive(Clone=true) @VintfStability
 parcelable GetValueRequest {
   long requestId;
   android.hardware.automotive.vehicle.VehiclePropValue prop;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/3/android/hardware/automotive/vehicle/GetValueResult.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/3/android/hardware/automotive/vehicle/GetValueResult.aidl
index 25f3575..a8e0ac8 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/3/android/hardware/automotive/vehicle/GetValueResult.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/3/android/hardware/automotive/vehicle/GetValueResult.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@JavaDerive(equals=true, toString=true) @VintfStability
+@JavaDerive(equals=true, toString=true) @RustDerive(Clone=true) @VintfStability
 parcelable GetValueResult {
   long requestId;
   android.hardware.automotive.vehicle.StatusCode status = android.hardware.automotive.vehicle.StatusCode.OK;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/3/android/hardware/automotive/vehicle/RawPropValues.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/3/android/hardware/automotive/vehicle/RawPropValues.aidl
index e7b0a13..80e81b2 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/3/android/hardware/automotive/vehicle/RawPropValues.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/3/android/hardware/automotive/vehicle/RawPropValues.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@JavaDerive(equals=true, toString=true) @VintfStability
+@JavaDerive(equals=true, toString=true) @RustDerive(Clone=true) @VintfStability
 parcelable RawPropValues {
   int[] int32Values = {};
   float[] floatValues;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/3/android/hardware/automotive/vehicle/SetValueRequest.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/3/android/hardware/automotive/vehicle/SetValueRequest.aidl
index 6a65307..9b392f5 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/3/android/hardware/automotive/vehicle/SetValueRequest.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/3/android/hardware/automotive/vehicle/SetValueRequest.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@JavaDerive(equals=true, toString=true) @VintfStability
+@JavaDerive(equals=true, toString=true) @RustDerive(Clone=true) @VintfStability
 parcelable SetValueRequest {
   long requestId;
   android.hardware.automotive.vehicle.VehiclePropValue value;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/3/android/hardware/automotive/vehicle/SetValueResult.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/3/android/hardware/automotive/vehicle/SetValueResult.aidl
index ec5fabb..57aa11f 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/3/android/hardware/automotive/vehicle/SetValueResult.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/3/android/hardware/automotive/vehicle/SetValueResult.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@JavaDerive(equals=true, toString=true) @VintfStability
+@JavaDerive(equals=true, toString=true) @RustDerive(Clone=true) @VintfStability
 parcelable SetValueResult {
   long requestId;
   android.hardware.automotive.vehicle.StatusCode status = android.hardware.automotive.vehicle.StatusCode.OK;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/3/android/hardware/automotive/vehicle/SubscribeOptions.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/3/android/hardware/automotive/vehicle/SubscribeOptions.aidl
index 1b1696b..3e19ede 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/3/android/hardware/automotive/vehicle/SubscribeOptions.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/3/android/hardware/automotive/vehicle/SubscribeOptions.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@JavaDerive(equals=true, toString=true) @VintfStability
+@JavaDerive(equals=true, toString=true) @RustDerive(Clone=true) @VintfStability
 parcelable SubscribeOptions {
   int propId;
   int[] areaIds;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/3/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/3/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
index 08d4ee4..eb3028e 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/3/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/3/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@JavaDerive(equals=true, toString=true) @VintfStability
+@JavaDerive(equals=true, toString=true) @RustDerive(Clone=true) @VintfStability
 parcelable VehicleAreaConfig {
   int areaId;
   int minInt32Value;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/3/android/hardware/automotive/vehicle/VehiclePropConfig.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/3/android/hardware/automotive/vehicle/VehiclePropConfig.aidl
index 8602d2d..32dac44 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/3/android/hardware/automotive/vehicle/VehiclePropConfig.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/3/android/hardware/automotive/vehicle/VehiclePropConfig.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@JavaDerive(equals=true, toString=true) @VintfStability
+@JavaDerive(equals=true, toString=true) @RustDerive(Clone=true) @VintfStability
 parcelable VehiclePropConfig {
   int prop;
   android.hardware.automotive.vehicle.VehiclePropertyAccess access = android.hardware.automotive.vehicle.VehiclePropertyAccess.NONE;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/3/android/hardware/automotive/vehicle/VehiclePropError.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/3/android/hardware/automotive/vehicle/VehiclePropError.aidl
index 9835295..9d49f1d 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/3/android/hardware/automotive/vehicle/VehiclePropError.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/3/android/hardware/automotive/vehicle/VehiclePropError.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@JavaDerive(equals=true, toString=true) @VintfStability
+@JavaDerive(equals=true, toString=true) @RustDerive(Clone=true) @VintfStability
 parcelable VehiclePropError {
   int propId;
   int areaId;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/3/android/hardware/automotive/vehicle/VehiclePropValue.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/3/android/hardware/automotive/vehicle/VehiclePropValue.aidl
index c87379f..f9feff5 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/3/android/hardware/automotive/vehicle/VehiclePropValue.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/3/android/hardware/automotive/vehicle/VehiclePropValue.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@JavaDerive(equals=true, toString=true) @VintfStability
+@JavaDerive(equals=true, toString=true) @RustDerive(Clone=true) @VintfStability
 parcelable VehiclePropValue {
   long timestamp;
   int areaId;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueRequest.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueRequest.aidl
index d88cd8b..15a2024 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueRequest.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueRequest.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@JavaDerive(equals=true, toString=true) @VintfStability
+@JavaDerive(equals=true, toString=true) @RustDerive(Clone=true) @VintfStability
 parcelable GetValueRequest {
   long requestId;
   android.hardware.automotive.vehicle.VehiclePropValue prop;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueResult.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueResult.aidl
index 25f3575..a8e0ac8 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueResult.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueResult.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@JavaDerive(equals=true, toString=true) @VintfStability
+@JavaDerive(equals=true, toString=true) @RustDerive(Clone=true) @VintfStability
 parcelable GetValueResult {
   long requestId;
   android.hardware.automotive.vehicle.StatusCode status = android.hardware.automotive.vehicle.StatusCode.OK;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/RawPropValues.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/RawPropValues.aidl
index e7b0a13..80e81b2 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/RawPropValues.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/RawPropValues.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@JavaDerive(equals=true, toString=true) @VintfStability
+@JavaDerive(equals=true, toString=true) @RustDerive(Clone=true) @VintfStability
 parcelable RawPropValues {
   int[] int32Values = {};
   float[] floatValues;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueRequest.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueRequest.aidl
index 6a65307..9b392f5 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueRequest.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueRequest.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@JavaDerive(equals=true, toString=true) @VintfStability
+@JavaDerive(equals=true, toString=true) @RustDerive(Clone=true) @VintfStability
 parcelable SetValueRequest {
   long requestId;
   android.hardware.automotive.vehicle.VehiclePropValue value;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueResult.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueResult.aidl
index ec5fabb..57aa11f 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueResult.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueResult.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@JavaDerive(equals=true, toString=true) @VintfStability
+@JavaDerive(equals=true, toString=true) @RustDerive(Clone=true) @VintfStability
 parcelable SetValueResult {
   long requestId;
   android.hardware.automotive.vehicle.StatusCode status = android.hardware.automotive.vehicle.StatusCode.OK;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SubscribeOptions.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SubscribeOptions.aidl
index 1b1696b..3e19ede 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SubscribeOptions.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SubscribeOptions.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@JavaDerive(equals=true, toString=true) @VintfStability
+@JavaDerive(equals=true, toString=true) @RustDerive(Clone=true) @VintfStability
 parcelable SubscribeOptions {
   int propId;
   int[] areaIds;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
index 08d4ee4..eb3028e 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@JavaDerive(equals=true, toString=true) @VintfStability
+@JavaDerive(equals=true, toString=true) @RustDerive(Clone=true) @VintfStability
 parcelable VehicleAreaConfig {
   int areaId;
   int minInt32Value;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropConfig.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropConfig.aidl
index 8602d2d..32dac44 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropConfig.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropConfig.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@JavaDerive(equals=true, toString=true) @VintfStability
+@JavaDerive(equals=true, toString=true) @RustDerive(Clone=true) @VintfStability
 parcelable VehiclePropConfig {
   int prop;
   android.hardware.automotive.vehicle.VehiclePropertyAccess access = android.hardware.automotive.vehicle.VehiclePropertyAccess.NONE;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropError.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropError.aidl
index 9835295..9d49f1d 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropError.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropError.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@JavaDerive(equals=true, toString=true) @VintfStability
+@JavaDerive(equals=true, toString=true) @RustDerive(Clone=true) @VintfStability
 parcelable VehiclePropError {
   int propId;
   int areaId;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropValue.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropValue.aidl
index c87379f..f9feff5 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropValue.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropValue.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@JavaDerive(equals=true, toString=true) @VintfStability
+@JavaDerive(equals=true, toString=true) @RustDerive(Clone=true) @VintfStability
 parcelable VehiclePropValue {
   long timestamp;
   int areaId;
diff --git a/automotive/vehicle/aidl/aidl_test/Android.bp b/automotive/vehicle/aidl/aidl_test/Android.bp
index bb976af..2dc9ee1 100644
--- a/automotive/vehicle/aidl/aidl_test/Android.bp
+++ b/automotive/vehicle/aidl/aidl_test/Android.bp
@@ -15,6 +15,7 @@
  */
 
 package {
+    default_team: "trendy_team_aaos_framework",
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueRequest.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueRequest.aidl
index e5b3929..1989b3e 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueRequest.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueRequest.aidl
@@ -20,6 +20,7 @@
 
 @VintfStability
 @JavaDerive(equals=true, toString=true)
+@RustDerive(Clone=true)
 parcelable GetValueRequest {
     // A unique request ID. For every client, the request ID must start with 1
     // and monotonically increase for every SetValueRequest. If it hits
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueResult.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueResult.aidl
index 24c5757..208c882 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueResult.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueResult.aidl
@@ -21,6 +21,7 @@
 
 @VintfStability
 @JavaDerive(equals=true, toString=true)
+@RustDerive(Clone=true)
 parcelable GetValueResult {
     // The ID for the request this response is for.
     long requestId;
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/RawPropValues.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/RawPropValues.aidl
index 28ccc1d..032882d 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/RawPropValues.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/RawPropValues.aidl
@@ -18,6 +18,7 @@
 
 @VintfStability
 @JavaDerive(equals=true, toString=true)
+@RustDerive(Clone=true)
 parcelable RawPropValues {
     /**
      * This is used for properties of types VehiclePropertyType#INT32,
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueRequest.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueRequest.aidl
index 625f901..c8d413d 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueRequest.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueRequest.aidl
@@ -20,6 +20,7 @@
 
 @VintfStability
 @JavaDerive(equals=true, toString=true)
+@RustDerive(Clone=true)
 parcelable SetValueRequest {
     // A unique request ID. For every client, the request ID must start with 1
     // and monotonically increase for every SetValueRequest. If it hits
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueResult.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueResult.aidl
index b3feeaa..673f812 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueResult.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueResult.aidl
@@ -20,6 +20,7 @@
 
 @VintfStability
 @JavaDerive(equals=true, toString=true)
+@RustDerive(Clone=true)
 parcelable SetValueResult {
     // The ID for the request this response is for.
     long requestId;
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SubscribeOptions.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SubscribeOptions.aidl
index 14469b5..decd859 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SubscribeOptions.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SubscribeOptions.aidl
@@ -21,6 +21,7 @@
  */
 @VintfStability
 @JavaDerive(equals=true, toString=true)
+@RustDerive(Clone=true)
 parcelable SubscribeOptions {
     /** Property to subscribe */
     int propId;
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
index 96c4a74..726d419 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
@@ -20,6 +20,7 @@
 
 @VintfStability
 @JavaDerive(equals=true, toString=true)
+@RustDerive(Clone=true)
 parcelable VehicleAreaConfig {
     /**
      * Area id is always 0 for VehicleArea#GLOBAL properties.
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropConfig.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropConfig.aidl
index c629b82..3109621 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropConfig.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropConfig.aidl
@@ -22,6 +22,7 @@
 
 @VintfStability
 @JavaDerive(equals=true, toString=true)
+@RustDerive(Clone=true)
 parcelable VehiclePropConfig {
     /** Property identifier */
     int prop;
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropError.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropError.aidl
index 2c31c72..7c38b91 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropError.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropError.aidl
@@ -20,6 +20,7 @@
 
 @VintfStability
 @JavaDerive(equals=true, toString=true)
+@RustDerive(Clone=true)
 parcelable VehiclePropError {
     // Property ID.
     int propId;
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropValue.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropValue.aidl
index 289f270..c78c635 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropValue.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropValue.aidl
@@ -26,6 +26,7 @@
  */
 @VintfStability
 @JavaDerive(equals=true, toString=true)
+@RustDerive(Clone=true)
 parcelable VehiclePropValue {
     /** Time is elapsed nanoseconds since boot */
     long timestamp;
diff --git a/automotive/vehicle/aidl/generated_lib/cpp/Android.bp b/automotive/vehicle/aidl/generated_lib/cpp/Android.bp
index 11d3693..d14cbc2 100644
--- a/automotive/vehicle/aidl/generated_lib/cpp/Android.bp
+++ b/automotive/vehicle/aidl/generated_lib/cpp/Android.bp
@@ -24,4 +24,5 @@
     local_include_dirs: ["."],
     export_include_dirs: ["."],
     defaults: ["VehicleHalInterfaceDefaults"],
+    host_supported: true,
 }
diff --git a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/Android.bp b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/Android.bp
index 75a3541..d1974ac 100644
--- a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/Android.bp
+++ b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/Android.bp
@@ -49,6 +49,7 @@
     ],
     cflags: ["-DENABLE_VEHICLE_HAL_TEST_PROPERTIES"],
     shared_libs: ["libjsoncpp"],
+    host_supported: true,
 }
 
 cc_library_headers {
diff --git a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/test/Android.bp b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/test/Android.bp
index dae37b9..abf15c5 100644
--- a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/test/Android.bp
+++ b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/test/Android.bp
@@ -15,6 +15,7 @@
  */
 
 package {
+    default_team: "trendy_team_aaos_framework",
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
diff --git a/automotive/vehicle/aidl/impl/default_config/config/Android.bp b/automotive/vehicle/aidl/impl/default_config/config/Android.bp
index 8f1c7d1..c4f93c4 100644
--- a/automotive/vehicle/aidl/impl/default_config/config/Android.bp
+++ b/automotive/vehicle/aidl/impl/default_config/config/Android.bp
@@ -45,3 +45,24 @@
     sub_dir: "automotive/vhalconfig/",
     vendor: true,
 }
+
+prebuilt_etc_host {
+    name: "Host_Prebuilt_VehicleHalDefaultProperties_JSON",
+    filename_from_src: true,
+    src: "DefaultProperties.json",
+    relative_install_path: "automotive/vhalconfig/",
+}
+
+prebuilt_etc_host {
+    name: "Host_Prebuilt_VehicleHalTestProperties_JSON",
+    filename_from_src: true,
+    src: "TestProperties.json",
+    relative_install_path: "automotive/vhalconfig/",
+}
+
+prebuilt_etc_host {
+    name: "Host_Prebuilt_VehicleHalVendorClusterTestProperties_JSON",
+    filename_from_src: true,
+    src: "VendorClusterTestProperties.json",
+    relative_install_path: "automotive/vhalconfig/",
+}
diff --git a/automotive/vehicle/aidl/impl/default_config/test/Android.bp b/automotive/vehicle/aidl/impl/default_config/test/Android.bp
index 8702eae..651ed90 100644
--- a/automotive/vehicle/aidl/impl/default_config/test/Android.bp
+++ b/automotive/vehicle/aidl/impl/default_config/test/Android.bp
@@ -15,6 +15,7 @@
  */
 
 package {
+    default_team: "trendy_team_aaos_framework",
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
diff --git a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/Android.bp b/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/Android.bp
index ab223d3..a250a47 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/Android.bp
+++ b/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/Android.bp
@@ -32,4 +32,5 @@
     shared_libs: [
         "libjsoncpp",
     ],
+    host_supported: true,
 }
diff --git a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/test/Android.bp b/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/test/Android.bp
index 2eef13c..4bc0b12 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/test/Android.bp
+++ b/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/test/Android.bp
@@ -15,6 +15,7 @@
  */
 
 package {
+    default_team: "trendy_team_automotive",
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/Android.bp b/automotive/vehicle/aidl/impl/fake_impl/hardware/Android.bp
index 5fc07c9..6030e15 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/Android.bp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/Android.bp
@@ -37,6 +37,7 @@
     whole_static_libs: [
         "wakeup_client_protos",
     ],
+    host_supported: true,
 }
 
 cc_defaults {
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 644d1cd..583e40b 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
@@ -184,7 +184,7 @@
     std::unordered_set<int32_t> hvacPowerDependentProps;
 
     const bool mForceOverride;
-    bool mAddExtraTestVendorConfigs;
+    bool mAddExtraTestVendorConfigs = false;
 
     // Only used during initialization.
     JsonConfigLoader mLoader;
@@ -206,7 +206,7 @@
             EXCLUDES(mLock);
     // Load the config files in format '*.json' from the directory and parse the config files
     // into a map from property ID to ConfigDeclarations.
-    void loadPropConfigsFromDir(const std::string& dirPath,
+    bool loadPropConfigsFromDir(const std::string& dirPath,
                                 std::unordered_map<int32_t, ConfigDeclaration>* configs);
     // Function to be called when a value change event comes from vehicle bus. In our fake
     // implementation, this function is only called during "--inject-event" dump command.
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 c4bcdb3..9b880cd 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
@@ -363,7 +363,12 @@
 
 std::unordered_map<int32_t, ConfigDeclaration> FakeVehicleHardware::loadConfigDeclarations() {
     std::unordered_map<int32_t, ConfigDeclaration> configsByPropId;
-    loadPropConfigsFromDir(mDefaultConfigDir, &configsByPropId);
+    bool defaultConfigLoaded = loadPropConfigsFromDir(mDefaultConfigDir, &configsByPropId);
+    if (!defaultConfigLoaded) {
+        // This cannot work without a valid default config.
+        ALOGE("Failed to load default config, exiting");
+        exit(1);
+    }
     if (UseOverrideConfigDir()) {
         loadPropConfigsFromDir(mOverrideConfigDir, &configsByPropId);
     }
@@ -2378,30 +2383,35 @@
     (*mOnPropertyChangeCallback)(std::move(subscribedUpdatedValues));
 }
 
-void FakeVehicleHardware::loadPropConfigsFromDir(
+bool FakeVehicleHardware::loadPropConfigsFromDir(
         const std::string& dirPath,
         std::unordered_map<int32_t, ConfigDeclaration>* configsByPropId) {
     ALOGI("loading properties from %s", dirPath.c_str());
-    if (auto dir = opendir(dirPath.c_str()); dir != NULL) {
-        std::regex regJson(".*[.]json", std::regex::icase);
-        while (auto f = readdir(dir)) {
-            if (!std::regex_match(f->d_name, regJson)) {
-                continue;
-            }
-            std::string filePath = dirPath + "/" + std::string(f->d_name);
-            ALOGI("loading properties from %s", filePath.c_str());
-            auto result = mLoader.loadPropConfig(filePath);
-            if (!result.ok()) {
-                ALOGE("failed to load config file: %s, error: %s", filePath.c_str(),
-                      result.error().message().c_str());
-                continue;
-            }
-            for (auto& [propId, configDeclaration] : result.value()) {
-                (*configsByPropId)[propId] = std::move(configDeclaration);
-            }
-        }
-        closedir(dir);
+    auto dir = opendir(dirPath.c_str());
+    if (dir == nullptr) {
+        ALOGE("Failed to open config directory: %s", dirPath.c_str());
+        return false;
     }
+
+    std::regex regJson(".*[.]json", std::regex::icase);
+    while (auto f = readdir(dir)) {
+        if (!std::regex_match(f->d_name, regJson)) {
+            continue;
+        }
+        std::string filePath = dirPath + "/" + std::string(f->d_name);
+        ALOGI("loading properties from %s", filePath.c_str());
+        auto result = mLoader.loadPropConfig(filePath);
+        if (!result.ok()) {
+            ALOGE("failed to load config file: %s, error: %s", filePath.c_str(),
+                  result.error().message().c_str());
+            continue;
+        }
+        for (auto& [propId, configDeclaration] : result.value()) {
+            (*configsByPropId)[propId] = std::move(configDeclaration);
+        }
+    }
+    closedir(dir);
+    return true;
 }
 
 Result<float> FakeVehicleHardware::safelyParseFloat(int index, const std::string& s) {
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/Android.bp b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/Android.bp
index ac70b51..9f002dd 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/Android.bp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/Android.bp
@@ -15,6 +15,7 @@
  */
 
 package {
+    default_team: "trendy_team_aaos_framework",
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
@@ -55,6 +56,8 @@
     defaults: [
         "VehicleHalDefaults",
     ],
+    // Need root to use vendor lib: libgrpc++.
+    require_root: true,
     test_suites: ["device-tests"],
 }
 
diff --git a/automotive/vehicle/aidl/impl/fake_impl/obd2frame/Android.bp b/automotive/vehicle/aidl/impl/fake_impl/obd2frame/Android.bp
index c1cee84..8fc7341 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/obd2frame/Android.bp
+++ b/automotive/vehicle/aidl/impl/fake_impl/obd2frame/Android.bp
@@ -29,4 +29,5 @@
         "VehicleHalUtils",
     ],
     export_static_lib_headers: ["VehicleHalUtils"],
+    host_supported: true,
 }
diff --git a/automotive/vehicle/aidl/impl/fake_impl/obd2frame/test/Android.bp b/automotive/vehicle/aidl/impl/fake_impl/obd2frame/test/Android.bp
index 55b8c93..7c7c0ab 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/obd2frame/test/Android.bp
+++ b/automotive/vehicle/aidl/impl/fake_impl/obd2frame/test/Android.bp
@@ -15,6 +15,7 @@
  */
 
 package {
+    default_team: "trendy_team_aaos_framework",
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
diff --git a/automotive/vehicle/aidl/impl/fake_impl/userhal/Android.bp b/automotive/vehicle/aidl/impl/fake_impl/userhal/Android.bp
index 2e95531..181fd10 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/userhal/Android.bp
+++ b/automotive/vehicle/aidl/impl/fake_impl/userhal/Android.bp
@@ -29,4 +29,5 @@
         "VehicleHalUtils",
     ],
     export_static_lib_headers: ["VehicleHalUtils"],
+    host_supported: true,
 }
diff --git a/automotive/vehicle/aidl/impl/fake_impl/userhal/test/Android.bp b/automotive/vehicle/aidl/impl/fake_impl/userhal/test/Android.bp
index 7d0a534..30411f2 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/userhal/test/Android.bp
+++ b/automotive/vehicle/aidl/impl/fake_impl/userhal/test/Android.bp
@@ -15,6 +15,7 @@
  */
 
 package {
+    default_team: "trendy_team_aaos_framework",
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
diff --git a/automotive/vehicle/aidl/impl/grpc/Android.bp b/automotive/vehicle/aidl/impl/grpc/Android.bp
index e5106f8..7a8da59 100644
--- a/automotive/vehicle/aidl/impl/grpc/Android.bp
+++ b/automotive/vehicle/aidl/impl/grpc/Android.bp
@@ -22,7 +22,7 @@
         "aprotoc",
         "protoc-gen-grpc-cpp-plugin",
     ],
-    cmd: "$(location aprotoc) -I$$(dirname $(location proto/VehicleServer.proto)) -Ihardware/interfaces/automotive/vehicle/aidl/impl/proto -Iexternal/protobuf/src --plugin=protoc-gen-grpc=$(location protoc-gen-grpc-cpp-plugin) $(location proto/VehicleServer.proto) --grpc_out=$(genDir) --cpp_out=$(genDir)",
+    cmd: "$(location aprotoc) -I$$(dirname $(location proto/VehicleServer.proto)) -Ihardware/interfaces/automotive/vehicle/aidl/impl/proto -Iexternal/protobuf/src --plugin=protoc-gen-grpc=$(location protoc-gen-grpc-cpp-plugin) $(location proto/VehicleServer.proto) --grpc_opt=generate_mock_code=true --grpc_out=$(genDir) --cpp_out=$(genDir)",
     srcs: [
         "proto/VehicleServer.proto",
         ":libprotobuf-internal-protos",
@@ -31,6 +31,7 @@
     out: [
         "VehicleServer.pb.h",
         "VehicleServer.grpc.pb.h",
+        "VehicleServer_mock.grpc.pb.h",
     ],
     visibility: ["//visibility:private"],
 }
@@ -127,4 +128,5 @@
     cflags: [
         "-Wno-unused-parameter",
     ],
+    host_supported: true,
 }
diff --git a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.cpp b/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.cpp
index 0742283..f44573a 100644
--- a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.cpp
+++ b/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.cpp
@@ -39,6 +39,13 @@
       mGrpcStub(proto::VehicleServer::NewStub(mGrpcChannel)),
       mValuePollingThread([this] { ValuePollingLoop(); }) {}
 
+// Only used for unit testing.
+GRPCVehicleHardware::GRPCVehicleHardware(std::unique_ptr<proto::VehicleServer::StubInterface> stub)
+    : mServiceAddr(""),
+      mGrpcChannel(nullptr),
+      mGrpcStub(std::move(stub)),
+      mValuePollingThread([] {}) {}
+
 GRPCVehicleHardware::~GRPCVehicleHardware() {
     {
         std::lock_guard lck(mShutdownMutex);
@@ -181,6 +188,43 @@
     return static_cast<aidlvhal::StatusCode>(protoStatus.status_code());
 }
 
+aidlvhal::StatusCode GRPCVehicleHardware::subscribe(aidlvhal::SubscribeOptions options) {
+    proto::SubscribeRequest request;
+    ::grpc::ClientContext context;
+    proto::VehicleHalCallStatus protoStatus;
+    proto_msg_converter::aidlToProto(options, request.mutable_options());
+    auto grpc_status = mGrpcStub->Subscribe(&context, request, &protoStatus);
+    if (!grpc_status.ok()) {
+        if (grpc_status.error_code() == ::grpc::StatusCode::UNIMPLEMENTED) {
+            // This is a legacy sever. It should handle updateSampleRate.
+            LOG(INFO) << __func__ << ": GRPC Subscribe is not supported by the server";
+            return aidlvhal::StatusCode::OK;
+        }
+        LOG(ERROR) << __func__ << ": GRPC Subscribe Failed: " << grpc_status.error_message();
+        return aidlvhal::StatusCode::INTERNAL_ERROR;
+    }
+    return static_cast<aidlvhal::StatusCode>(protoStatus.status_code());
+}
+
+aidlvhal::StatusCode GRPCVehicleHardware::unsubscribe(int32_t propId, int32_t areaId) {
+    proto::UnsubscribeRequest request;
+    ::grpc::ClientContext context;
+    proto::VehicleHalCallStatus protoStatus;
+    request.set_prop_id(propId);
+    request.set_area_id(areaId);
+    auto grpc_status = mGrpcStub->Unsubscribe(&context, request, &protoStatus);
+    if (!grpc_status.ok()) {
+        if (grpc_status.error_code() == ::grpc::StatusCode::UNIMPLEMENTED) {
+            // This is a legacy sever. Ignore unsubscribe request.
+            LOG(INFO) << __func__ << ": GRPC Unsubscribe is not supported by the server";
+            return aidlvhal::StatusCode::OK;
+        }
+        LOG(ERROR) << __func__ << ": GRPC Unsubscribe Failed: " << grpc_status.error_message();
+        return aidlvhal::StatusCode::INTERNAL_ERROR;
+    }
+    return static_cast<aidlvhal::StatusCode>(protoStatus.status_code());
+}
+
 aidlvhal::StatusCode GRPCVehicleHardware::updateSampleRate(int32_t propId, int32_t areaId,
                                                            float sampleRate) {
     ::grpc::ClientContext context;
diff --git a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.h b/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.h
index ddd620e..9750f62 100644
--- a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.h
+++ b/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.h
@@ -43,6 +43,9 @@
   public:
     explicit GRPCVehicleHardware(std::string service_addr);
 
+    // Only used for unit testing.
+    explicit GRPCVehicleHardware(std::unique_ptr<proto::VehicleServer::StubInterface> stub);
+
     ~GRPCVehicleHardware();
 
     // Get all the property configs.
@@ -80,6 +83,10 @@
     aidlvhal::StatusCode updateSampleRate(int32_t propId, int32_t areaId,
                                           float sampleRate) override;
 
+    aidlvhal::StatusCode subscribe(aidlvhal::SubscribeOptions options) override;
+
+    aidlvhal::StatusCode unsubscribe(int32_t propId, int32_t areaId) override;
+
     bool waitForConnected(std::chrono::milliseconds waitTime);
 
   protected:
@@ -91,7 +98,7 @@
 
     std::string mServiceAddr;
     std::shared_ptr<::grpc::Channel> mGrpcChannel;
-    std::unique_ptr<proto::VehicleServer::Stub> mGrpcStub;
+    std::unique_ptr<proto::VehicleServer::StubInterface> mGrpcStub;
     std::thread mValuePollingThread;
 
     std::unique_ptr<const PropertySetErrorCallback> mOnSetErr;
diff --git a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleProxyServer.cpp b/automotive/vehicle/aidl/impl/grpc/GRPCVehicleProxyServer.cpp
index af3dd59..a6abfa3 100644
--- a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleProxyServer.cpp
+++ b/automotive/vehicle/aidl/impl/grpc/GRPCVehicleProxyServer.cpp
@@ -164,6 +164,27 @@
     return ::grpc::Status::OK;
 }
 
+::grpc::Status GrpcVehicleProxyServer::Subscribe(::grpc::ServerContext* context,
+                                                 const proto::SubscribeRequest* request,
+                                                 proto::VehicleHalCallStatus* status) {
+    const auto& protoSubscribeOptions = request->options();
+    aidlvhal::SubscribeOptions aidlSubscribeOptions = {};
+    proto_msg_converter::protoToAidl(protoSubscribeOptions, &aidlSubscribeOptions);
+    const auto status_code = mHardware->subscribe(aidlSubscribeOptions);
+    status->set_status_code(static_cast<proto::StatusCode>(status_code));
+    return ::grpc::Status::OK;
+}
+
+::grpc::Status GrpcVehicleProxyServer::Unsubscribe(::grpc::ServerContext* context,
+                                                   const proto::UnsubscribeRequest* request,
+                                                   proto::VehicleHalCallStatus* status) {
+    int32_t propId = request->prop_id();
+    int32_t areaId = request->area_id();
+    const auto status_code = mHardware->unsubscribe(propId, areaId);
+    status->set_status_code(static_cast<proto::StatusCode>(status_code));
+    return ::grpc::Status::OK;
+}
+
 ::grpc::Status GrpcVehicleProxyServer::CheckHealth(::grpc::ServerContext* context,
                                                    const ::google::protobuf::Empty*,
                                                    proto::VehicleHalCallStatus* status) {
diff --git a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleProxyServer.h b/automotive/vehicle/aidl/impl/grpc/GRPCVehicleProxyServer.h
index 3596354..dd9e2aa 100644
--- a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleProxyServer.h
+++ b/automotive/vehicle/aidl/impl/grpc/GRPCVehicleProxyServer.h
@@ -57,6 +57,13 @@
                                     const proto::UpdateSampleRateRequest* request,
                                     proto::VehicleHalCallStatus* status) override;
 
+    ::grpc::Status Subscribe(::grpc::ServerContext* context, const proto::SubscribeRequest* request,
+                             proto::VehicleHalCallStatus* status) override;
+
+    ::grpc::Status Unsubscribe(::grpc::ServerContext* context,
+                               const proto::UnsubscribeRequest* request,
+                               proto::VehicleHalCallStatus* status) override;
+
     ::grpc::Status CheckHealth(::grpc::ServerContext* context, const ::google::protobuf::Empty*,
                                proto::VehicleHalCallStatus* status) override;
 
diff --git a/automotive/vehicle/aidl/impl/grpc/proto/VehicleServer.proto b/automotive/vehicle/aidl/impl/grpc/proto/VehicleServer.proto
index 22b11d8..732957f 100644
--- a/automotive/vehicle/aidl/impl/grpc/proto/VehicleServer.proto
+++ b/automotive/vehicle/aidl/impl/grpc/proto/VehicleServer.proto
@@ -20,7 +20,9 @@
 
 import "android/hardware/automotive/vehicle/DumpOptions.proto";
 import "android/hardware/automotive/vehicle/DumpResult.proto";
+import "android/hardware/automotive/vehicle/SubscribeRequest.proto";
 import "android/hardware/automotive/vehicle/StatusCode.proto";
+import "android/hardware/automotive/vehicle/UnsubscribeRequest.proto";
 import "android/hardware/automotive/vehicle/VehiclePropConfig.proto";
 import "android/hardware/automotive/vehicle/VehiclePropValue.proto";
 import "android/hardware/automotive/vehicle/VehiclePropValueRequest.proto";
@@ -40,4 +42,8 @@
     rpc Dump(DumpOptions) returns (DumpResult) {}
 
     rpc StartPropertyValuesStream(google.protobuf.Empty) returns (stream VehiclePropValues) {}
+
+    rpc Subscribe(SubscribeRequest) returns (VehicleHalCallStatus) {}
+
+    rpc Unsubscribe(UnsubscribeRequest) returns (VehicleHalCallStatus) {}
 }
diff --git a/automotive/vehicle/aidl/impl/grpc/test/Android.bp b/automotive/vehicle/aidl/impl/grpc/test/Android.bp
index e53826f..b3c6089 100644
--- a/automotive/vehicle/aidl/impl/grpc/test/Android.bp
+++ b/automotive/vehicle/aidl/impl/grpc/test/Android.bp
@@ -13,6 +13,7 @@
 // limitations under the License.
 
 package {
+    default_team: "trendy_team_automotive",
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
diff --git a/automotive/vehicle/aidl/impl/grpc/test/GRPCVehicleHardwareUnitTest.cpp b/automotive/vehicle/aidl/impl/grpc/test/GRPCVehicleHardwareUnitTest.cpp
index f578021..3bd7e0e 100644
--- a/automotive/vehicle/aidl/impl/grpc/test/GRPCVehicleHardwareUnitTest.cpp
+++ b/automotive/vehicle/aidl/impl/grpc/test/GRPCVehicleHardwareUnitTest.cpp
@@ -15,6 +15,7 @@
 #include "GRPCVehicleHardware.h"
 #include "VehicleServer.grpc.pb.h"
 #include "VehicleServer.pb.h"
+#include "VehicleServer_mock.grpc.pb.h"
 
 #include <gmock/gmock.h>
 #include <grpc++/grpc++.h>
@@ -26,6 +27,17 @@
 
 namespace android::hardware::automotive::vehicle::virtualization {
 
+namespace aidlvhal = ::aidl::android::hardware::automotive::vehicle;
+
+using ::testing::_;
+using ::testing::DoAll;
+using ::testing::NiceMock;
+using ::testing::Return;
+using ::testing::SaveArg;
+using ::testing::SetArgPointee;
+
+using proto::MockVehicleServerStub;
+
 const std::string kFakeServerAddr = "0.0.0.0:54321";
 
 class FakeVehicleServer : public proto::VehicleServer::Service {
@@ -91,4 +103,131 @@
     }
 }
 
+class GRPCVehicleHardwareMockServerUnitTest : public ::testing::Test {
+  protected:
+    NiceMock<MockVehicleServerStub>* mGrpcStub;
+    std::unique_ptr<GRPCVehicleHardware> mHardware;
+
+    void SetUp() override {
+        auto stub = std::make_unique<NiceMock<MockVehicleServerStub>>();
+        ;
+        mGrpcStub = stub.get();
+        mHardware = std::make_unique<GRPCVehicleHardware>(std::move(stub));
+    }
+
+    void TearDown() override { mHardware.reset(); }
+};
+
+MATCHER_P(RepeatedInt32Eq, expected_values, "") {
+    return std::vector<int32_t>(arg.begin(), arg.end()) == expected_values;
+}
+
+TEST_F(GRPCVehicleHardwareMockServerUnitTest, Subscribe) {
+    proto::VehicleHalCallStatus protoStatus;
+    protoStatus.set_status_code(proto::StatusCode::OK);
+    proto::SubscribeRequest actualRequest;
+
+    EXPECT_CALL(*mGrpcStub, Subscribe(_, _, _))
+            .WillOnce(DoAll(SaveArg<1>(&actualRequest), SetArgPointee<2>(protoStatus),
+                            Return(::grpc::Status::OK)));
+
+    aidlvhal::SubscribeOptions options = {.propId = 1,
+                                          .areaIds = {1, 2, 3, 4},
+                                          .sampleRate = 1.234,
+                                          .resolution = 0.01,
+                                          .enableVariableUpdateRate = true};
+    auto status = mHardware->subscribe(options);
+
+    EXPECT_EQ(status, aidlvhal::StatusCode::OK);
+    const auto& protoOptions = actualRequest.options();
+    EXPECT_EQ(protoOptions.prop_id(), 1);
+    EXPECT_THAT(protoOptions.area_ids(), RepeatedInt32Eq(std::vector<int32_t>({1, 2, 3, 4})));
+    EXPECT_FLOAT_EQ(protoOptions.sample_rate(), 1.234);
+    EXPECT_FLOAT_EQ(protoOptions.resolution(), 0.01);
+    EXPECT_EQ(protoOptions.enable_variable_update_rate(), true);
+}
+
+TEST_F(GRPCVehicleHardwareMockServerUnitTest, SubscribeLegacyServer) {
+    EXPECT_CALL(*mGrpcStub, Subscribe(_, _, _))
+            .WillOnce(Return(::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "")));
+
+    aidlvhal::SubscribeOptions options;
+    auto status = mHardware->subscribe(options);
+
+    EXPECT_EQ(status, aidlvhal::StatusCode::OK);
+}
+
+TEST_F(GRPCVehicleHardwareMockServerUnitTest, SubscribeGrpcFailure) {
+    EXPECT_CALL(*mGrpcStub, Subscribe(_, _, _))
+            .WillOnce(Return(::grpc::Status(::grpc::StatusCode::INTERNAL, "GRPC Error")));
+
+    aidlvhal::SubscribeOptions options;
+    auto status = mHardware->subscribe(options);
+
+    EXPECT_EQ(status, aidlvhal::StatusCode::INTERNAL_ERROR);
+}
+
+TEST_F(GRPCVehicleHardwareMockServerUnitTest, SubscribeProtoFailure) {
+    proto::VehicleHalCallStatus protoStatus;
+    protoStatus.set_status_code(proto::StatusCode::NOT_AVAILABLE_SPEED_LOW);
+
+    EXPECT_CALL(*mGrpcStub, Subscribe(_, _, _))
+            .WillOnce(DoAll(SetArgPointee<2>(protoStatus),  // Set the output status
+                            Return(::grpc::Status::OK)));
+
+    aidlvhal::SubscribeOptions options;
+    auto status = mHardware->subscribe(options);
+
+    EXPECT_EQ(status, aidlvhal::StatusCode::NOT_AVAILABLE_SPEED_LOW);
+}
+
+TEST_F(GRPCVehicleHardwareMockServerUnitTest, Unsubscribe) {
+    proto::VehicleHalCallStatus protoStatus;
+    protoStatus.set_status_code(proto::StatusCode::OK);
+    proto::UnsubscribeRequest actualRequest;
+
+    EXPECT_CALL(*mGrpcStub, Unsubscribe(_, _, _))
+            .WillOnce(DoAll(SaveArg<1>(&actualRequest), SetArgPointee<2>(protoStatus),
+                            Return(::grpc::Status::OK)));
+
+    int32_t propId = 1;
+    int32_t areaId = 2;
+    auto status = mHardware->unsubscribe(propId, areaId);
+
+    EXPECT_EQ(status, aidlvhal::StatusCode::OK);
+    EXPECT_EQ(actualRequest.prop_id(), propId);
+    EXPECT_EQ(actualRequest.area_id(), areaId);
+}
+
+TEST_F(GRPCVehicleHardwareMockServerUnitTest, UnsubscribeLegacyServer) {
+    EXPECT_CALL(*mGrpcStub, Unsubscribe(_, _, _))
+            .WillOnce(Return(::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "")));
+
+    auto status = mHardware->unsubscribe(1, 2);
+
+    EXPECT_EQ(status, aidlvhal::StatusCode::OK);
+}
+
+TEST_F(GRPCVehicleHardwareMockServerUnitTest, UnsubscribeGrpcFailure) {
+    EXPECT_CALL(*mGrpcStub, Unsubscribe(_, _, _))
+            .WillOnce(Return(::grpc::Status(::grpc::StatusCode::INTERNAL, "GRPC Error")));
+
+    auto status = mHardware->unsubscribe(1, 2);
+
+    EXPECT_EQ(status, aidlvhal::StatusCode::INTERNAL_ERROR);
+}
+
+TEST_F(GRPCVehicleHardwareMockServerUnitTest, UnsubscribeProtoFailure) {
+    proto::VehicleHalCallStatus protoStatus;
+    protoStatus.set_status_code(proto::StatusCode::NOT_AVAILABLE_SPEED_LOW);
+
+    EXPECT_CALL(*mGrpcStub, Unsubscribe(_, _, _))
+            .WillOnce(DoAll(SetArgPointee<2>(protoStatus),  // Set the output status
+                            Return(::grpc::Status::OK)));
+
+    auto status = mHardware->unsubscribe(1, 2);
+
+    EXPECT_EQ(status, aidlvhal::StatusCode::NOT_AVAILABLE_SPEED_LOW);
+}
+
 }  // namespace android::hardware::automotive::vehicle::virtualization
diff --git a/automotive/vehicle/aidl/impl/grpc/test/GRPCVehicleProxyServerUnitTest.cpp b/automotive/vehicle/aidl/impl/grpc/test/GRPCVehicleProxyServerUnitTest.cpp
index 49e6fc9..ca5c2d5 100644
--- a/automotive/vehicle/aidl/impl/grpc/test/GRPCVehicleProxyServerUnitTest.cpp
+++ b/automotive/vehicle/aidl/impl/grpc/test/GRPCVehicleProxyServerUnitTest.cpp
@@ -30,6 +30,13 @@
 
 namespace android::hardware::automotive::vehicle::virtualization {
 
+namespace aidlvhal = ::aidl::android::hardware::automotive::vehicle;
+
+using ::testing::_;
+using ::testing::DoAll;
+using ::testing::Return;
+using ::testing::SaveArg;
+
 const std::string kFakeServerAddr = "0.0.0.0:54321";
 
 class VehicleHardwareForTest : public IVehicleHardware {
@@ -39,38 +46,30 @@
         mOnProp = std::move(callback);
     }
 
-    void onPropertyEvent(
-            std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropValue> values) {
+    void onPropertyEvent(std::vector<aidlvhal::VehiclePropValue> values) {
         if (mOnProp) {
             (*mOnProp)(std::move(values));
         }
     }
 
     // Functions that we do not care.
-    std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropConfig>
-    getAllPropertyConfigs() const override {
-        return {};
-    }
+    std::vector<aidlvhal::VehiclePropConfig> getAllPropertyConfigs() const override { return {}; }
 
-    aidl::android::hardware::automotive::vehicle::StatusCode setValues(
+    aidlvhal::StatusCode setValues(
             std::shared_ptr<const SetValuesCallback> callback,
-            const std::vector<aidl::android::hardware::automotive::vehicle::SetValueRequest>&
-                    requests) override {
-        return aidl::android::hardware::automotive::vehicle::StatusCode::OK;
+            const std::vector<aidlvhal::SetValueRequest>& requests) override {
+        return aidlvhal::StatusCode::OK;
     }
 
-    aidl::android::hardware::automotive::vehicle::StatusCode getValues(
+    aidlvhal::StatusCode getValues(
             std::shared_ptr<const GetValuesCallback> callback,
-            const std::vector<aidl::android::hardware::automotive::vehicle::GetValueRequest>&
-                    requests) const override {
-        return aidl::android::hardware::automotive::vehicle::StatusCode::OK;
+            const std::vector<aidlvhal::GetValueRequest>& requests) const override {
+        return aidlvhal::StatusCode::OK;
     }
 
     DumpResult dump(const std::vector<std::string>& options) override { return {}; }
 
-    aidl::android::hardware::automotive::vehicle::StatusCode checkHealth() override {
-        return aidl::android::hardware::automotive::vehicle::StatusCode::OK;
-    }
+    aidlvhal::StatusCode checkHealth() override { return aidlvhal::StatusCode::OK; }
 
     void registerOnPropertySetErrorEvent(
             std::unique_ptr<const PropertySetErrorCallback> callback) override {}
@@ -79,6 +78,35 @@
     std::unique_ptr<const PropertyChangeCallback> mOnProp;
 };
 
+class MockVehicleHardware : public IVehicleHardware {
+  public:
+    // Mock methods from IVehicleHardware
+    MOCK_METHOD(std::vector<aidlvhal::VehiclePropConfig>, getAllPropertyConfigs, (),
+                (const, override));
+
+    MOCK_METHOD((aidlvhal::StatusCode), setValues,
+                (std::shared_ptr<const SetValuesCallback> callback,
+                 const std::vector<aidlvhal::SetValueRequest>& requests),
+                (override));
+
+    MOCK_METHOD((aidlvhal::StatusCode), getValues,
+                (std::shared_ptr<const GetValuesCallback> callback,
+                 const std::vector<aidlvhal::GetValueRequest>& requests),
+                (const, override));
+
+    MOCK_METHOD(DumpResult, dump, (const std::vector<std::string>& options), (override));
+    MOCK_METHOD(aidlvhal::StatusCode, checkHealth, (), (override));
+    MOCK_METHOD(void, registerOnPropertyChangeEvent,
+                (std::unique_ptr<const PropertyChangeCallback> callback), (override));
+    MOCK_METHOD(void, registerOnPropertySetErrorEvent,
+                (std::unique_ptr<const PropertySetErrorCallback> callback), (override));
+    MOCK_METHOD(std::chrono::nanoseconds, getPropertyOnChangeEventBatchingWindow, (), (override));
+    MOCK_METHOD(aidlvhal::StatusCode, subscribe, (aidlvhal::SubscribeOptions options), (override));
+    MOCK_METHOD(aidlvhal::StatusCode, unsubscribe, (int32_t propId, int32_t areaId), (override));
+    MOCK_METHOD(aidlvhal::StatusCode, updateSampleRate,
+                (int32_t propId, int32_t areaId, float sampleRate), (override));
+};
+
 TEST(GRPCVehicleProxyServerUnitTest, ClientConnectDisconnect) {
     auto testHardware = std::make_unique<VehicleHardwareForTest>();
     // HACK: manipulate the underlying hardware via raw pointer for testing.
@@ -144,4 +172,70 @@
     vehicleServer->Shutdown().Wait();
 }
 
+TEST(GRPCVehicleProxyServerUnitTest, Subscribe) {
+    auto mockHardware = std::make_unique<MockVehicleHardware>();
+    // We make sure this is alive inside the function scope.
+    MockVehicleHardware* mockHardwarePtr = mockHardware.get();
+    GrpcVehicleProxyServer server = GrpcVehicleProxyServer("", std::move(mockHardware));
+    ::grpc::ServerContext context;
+    proto::SubscribeRequest request;
+    proto::VehicleHalCallStatus returnStatus;
+    aidlvhal::SubscribeOptions aidlOptions;
+    request.mutable_options()->set_prop_id(1);
+    request.mutable_options()->add_area_ids(2);
+    request.mutable_options()->set_sample_rate(1.234);
+    request.mutable_options()->set_resolution(0.01);
+    request.mutable_options()->set_enable_variable_update_rate(true);
+
+    EXPECT_CALL(*mockHardwarePtr, subscribe(_))
+            .WillOnce(DoAll(SaveArg<0>(&aidlOptions), Return(aidlvhal::StatusCode::OK)));
+
+    auto grpcStatus = server.Subscribe(&context, &request, &returnStatus);
+
+    EXPECT_TRUE(grpcStatus.ok());
+    EXPECT_EQ(returnStatus.status_code(), proto::StatusCode::OK);
+    EXPECT_EQ(aidlOptions.propId, 1);
+    EXPECT_EQ(aidlOptions.areaIds, std::vector<int32_t>{2});
+    EXPECT_FLOAT_EQ(aidlOptions.sampleRate, 1.234);
+    EXPECT_FLOAT_EQ(aidlOptions.resolution, 0.01);
+    EXPECT_TRUE(aidlOptions.enableVariableUpdateRate);
+}
+
+TEST(GRPCVehicleProxyServerUnitTest, SubscribeNotAvailable) {
+    auto mockHardware = std::make_unique<MockVehicleHardware>();
+    // We make sure this is alive inside the function scope.
+    MockVehicleHardware* mockHardwarePtr = mockHardware.get();
+    GrpcVehicleProxyServer server = GrpcVehicleProxyServer("", std::move(mockHardware));
+    ::grpc::ServerContext context;
+    proto::SubscribeRequest request;
+    proto::VehicleHalCallStatus returnStatus;
+
+    EXPECT_CALL(*mockHardwarePtr, subscribe(_))
+            .WillOnce(Return(aidlvhal::StatusCode::NOT_AVAILABLE));
+
+    auto grpcStatus = server.Subscribe(&context, &request, &returnStatus);
+
+    EXPECT_TRUE(grpcStatus.ok());
+    EXPECT_EQ(returnStatus.status_code(), proto::StatusCode::NOT_AVAILABLE);
+}
+
+TEST(GRPCVehicleProxyServerUnitTest, Unsubscribe) {
+    auto mockHardware = std::make_unique<MockVehicleHardware>();
+    // We make sure this is alive inside the function scope.
+    MockVehicleHardware* mockHardwarePtr = mockHardware.get();
+    GrpcVehicleProxyServer server = GrpcVehicleProxyServer("", std::move(mockHardware));
+    ::grpc::ServerContext context;
+    proto::UnsubscribeRequest request;
+    proto::VehicleHalCallStatus returnStatus;
+    request.set_prop_id(1);
+    request.set_area_id(2);
+
+    EXPECT_CALL(*mockHardwarePtr, unsubscribe(1, 2)).WillOnce(Return(aidlvhal::StatusCode::OK));
+
+    auto grpcStatus = server.Unsubscribe(&context, &request, &returnStatus);
+
+    EXPECT_TRUE(grpcStatus.ok());
+    EXPECT_EQ(returnStatus.status_code(), proto::StatusCode::OK);
+}
+
 }  // namespace android::hardware::automotive::vehicle::virtualization
diff --git a/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/Android.bp b/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/Android.bp
index 2b4059c..94c09aa 100644
--- a/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/Android.bp
+++ b/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/Android.bp
@@ -15,6 +15,7 @@
  */
 
 package {
+    default_team: "trendy_team_automotive",
     // See: http://go/android-license-faq
     // A large-scale-change added 'default_applicable_licenses' to import
     // all of the 'license_kinds' from "hardware_interfaces_license"
@@ -38,25 +39,24 @@
     ],
     defaults: ["VehicleHalDefaults"],
     export_static_lib_headers: ["VehicleHalUtils"],
+    host_supported: true,
 }
 
-cc_test {
+cc_test_host {
     name: "VehicleHalProtoMessageConverterTest",
     srcs: [
         "test/*.cpp",
     ],
     vendor: true,
     defaults: ["VehicleHalDefaults"],
-    shared_libs: [
-        "libprotobuf-cpp-full",
-        "libjsoncpp",
-    ],
     static_libs: [
         "VehicleHalJsonConfigLoaderEnableTestProperties",
         "VehicleHalProtoMessageConverter",
         "VehicleHalProtos",
         "VehicleHalUtils",
         "libgtest",
+        "libprotobuf-cpp-full",
+        "libjsoncpp",
     ],
     data: [
         ":VehicleHalDefaultProperties_JSON",
diff --git a/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/include/ProtoMessageConverter.h b/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/include/ProtoMessageConverter.h
index 1c26fe8..25c07ef 100644
--- a/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/include/ProtoMessageConverter.h
+++ b/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/include/ProtoMessageConverter.h
@@ -18,6 +18,7 @@
 #define android_hardware_automotive_vehicle_aidl_impl_grpc_utils_proto_message_converter_include_ProtoMessageConverter_H_
 
 #include <VehicleHalTypes.h>
+#include <android/hardware/automotive/vehicle/SubscribeOptions.pb.h>
 #include <android/hardware/automotive/vehicle/VehicleAreaConfig.pb.h>
 #include <android/hardware/automotive/vehicle/VehiclePropConfig.pb.h>
 #include <android/hardware/automotive/vehicle/VehiclePropValue.pb.h>
@@ -46,6 +47,12 @@
 void protoToAidl(
         const ::android::hardware::automotive::vehicle::proto::VehiclePropValue& inProtoVal,
         ::aidl::android::hardware::automotive::vehicle::VehiclePropValue* outAidlVal);
+// Convert AIDL SubscribeOptions to Protobuf SubscribeOptions.
+void aidlToProto(const ::aidl::android::hardware::automotive::vehicle::SubscribeOptions& in,
+                 ::android::hardware::automotive::vehicle::proto::SubscribeOptions* out);
+// Convert Protobuf SubscribeOptions to AIDL SubscribeOptions.
+void protoToAidl(const ::android::hardware::automotive::vehicle::proto::SubscribeOptions& in,
+                 ::aidl::android::hardware::automotive::vehicle::SubscribeOptions* out);
 
 }  // namespace proto_msg_converter
 }  // namespace vehicle
diff --git a/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/src/ProtoMessageConverter.cpp b/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/src/ProtoMessageConverter.cpp
index 1ea0df4..c40004a 100644
--- a/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/src/ProtoMessageConverter.cpp
+++ b/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/src/ProtoMessageConverter.cpp
@@ -152,6 +152,24 @@
     COPY_PROTOBUF_VEC_TO_VHAL_TYPE(in, float_values, out, value.floatValues);
 }
 
+void aidlToProto(const aidl_vehicle::SubscribeOptions& in, proto::SubscribeOptions* out) {
+    out->set_prop_id(in.propId);
+    for (int areaId : in.areaIds) {
+        out->add_area_ids(areaId);
+    }
+    out->set_sample_rate(in.sampleRate);
+    out->set_resolution(in.resolution);
+    out->set_enable_variable_update_rate(in.enableVariableUpdateRate);
+}
+
+void protoToAidl(const proto::SubscribeOptions& in, aidl_vehicle::SubscribeOptions* out) {
+    out->propId = in.prop_id();
+    COPY_PROTOBUF_VEC_TO_VHAL_TYPE(in, area_ids, out, areaIds);
+    out->sampleRate = in.sample_rate();
+    out->resolution = in.resolution();
+    out->enableVariableUpdateRate = in.enable_variable_update_rate();
+}
+
 #undef COPY_PROTOBUF_VEC_TO_VHAL_TYPE
 #undef CAST_COPY_PROTOBUF_VEC_TO_VHAL_TYPE
 
diff --git a/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/test/proto_message_converter_test.cpp b/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/test/proto_message_converter_test.cpp
index 308be46..2efda5b 100644
--- a/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/test/proto_message_converter_test.cpp
+++ b/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/test/proto_message_converter_test.cpp
@@ -22,6 +22,7 @@
 
 #include <android-base/file.h>
 #include <android-base/format.h>
+#include <android/hardware/automotive/vehicle/SubscribeOptions.pb.h>
 #include <android/hardware/automotive/vehicle/VehiclePropConfig.pb.h>
 #include <android/hardware/automotive/vehicle/VehiclePropValue.pb.h>
 #include <gtest/gtest.h>
@@ -114,6 +115,21 @@
                              return ::fmt::format("property_{:d}", info.param.prop);
                          });
 
+TEST_F(PropValueConversionTest, testConvertSubscribeOption) {
+    proto::SubscribeOptions protoOptions;
+    aidl_vehicle::SubscribeOptions aidlOptions = {.propId = 1,
+                                                  .areaIds = {1, 2},
+                                                  .sampleRate = 1.234,
+                                                  .resolution = 0.01,
+                                                  .enableVariableUpdateRate = true};
+    aidl_vehicle::SubscribeOptions outputOptions;
+
+    aidlToProto(aidlOptions, &protoOptions);
+    protoToAidl(protoOptions, &outputOptions);
+
+    EXPECT_EQ(aidlOptions, outputOptions);
+}
+
 }  // namespace proto_msg_converter
 }  // namespace vehicle
 }  // namespace automotive
diff --git a/automotive/vehicle/aidl/impl/hardware/Android.bp b/automotive/vehicle/aidl/impl/hardware/Android.bp
index edb0f29..52fd5e4 100644
--- a/automotive/vehicle/aidl/impl/hardware/Android.bp
+++ b/automotive/vehicle/aidl/impl/hardware/Android.bp
@@ -30,4 +30,5 @@
     export_header_lib_headers: [
         "VehicleHalUtilHeaders",
     ],
+    host_supported: true,
 }
diff --git a/automotive/vehicle/aidl/impl/proto/Android.bp b/automotive/vehicle/aidl/impl/proto/Android.bp
index 56fad7e..b2edf75 100644
--- a/automotive/vehicle/aidl/impl/proto/Android.bp
+++ b/automotive/vehicle/aidl/impl/proto/Android.bp
@@ -50,6 +50,9 @@
         "android/hardware/automotive/vehicle/VehiclePropertyStatus.pb.h",
         "android/hardware/automotive/vehicle/VehiclePropValue.pb.h",
         "android/hardware/automotive/vehicle/VehiclePropValueRequest.pb.h",
+        "android/hardware/automotive/vehicle/SubscribeOptions.pb.h",
+        "android/hardware/automotive/vehicle/SubscribeRequest.pb.h",
+        "android/hardware/automotive/vehicle/UnsubscribeRequest.pb.h",
     ],
 }
 
@@ -74,6 +77,9 @@
         "android/hardware/automotive/vehicle/VehiclePropertyStatus.pb.cc",
         "android/hardware/automotive/vehicle/VehiclePropValue.pb.cc",
         "android/hardware/automotive/vehicle/VehiclePropValueRequest.pb.cc",
+        "android/hardware/automotive/vehicle/SubscribeOptions.pb.cc",
+        "android/hardware/automotive/vehicle/SubscribeRequest.pb.cc",
+        "android/hardware/automotive/vehicle/UnsubscribeRequest.pb.cc",
     ],
 }
 
diff --git a/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/SubscribeOptions.proto b/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/SubscribeOptions.proto
new file mode 100644
index 0000000..3fc6581
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/SubscribeOptions.proto
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+syntax = "proto3";
+
+package android.hardware.automotive.vehicle.proto;
+
+message SubscribeOptions {
+    int32 prop_id = 1;
+    repeated int32 area_ids = 2;
+    float sample_rate = 3;
+    float resolution = 4;
+    bool enable_variable_update_rate = 5;
+}
\ No newline at end of file
diff --git a/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/SubscribeRequest.proto b/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/SubscribeRequest.proto
new file mode 100644
index 0000000..4ce6335
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/SubscribeRequest.proto
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+syntax = "proto3";
+
+package android.hardware.automotive.vehicle.proto;
+
+import "android/hardware/automotive/vehicle/SubscribeOptions.proto";
+
+message SubscribeRequest {
+    SubscribeOptions options = 1;
+}
\ No newline at end of file
diff --git a/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/UnsubscribeRequest.proto b/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/UnsubscribeRequest.proto
new file mode 100644
index 0000000..314fbf0
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/UnsubscribeRequest.proto
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+syntax = "proto3";
+
+package android.hardware.automotive.vehicle.proto;
+
+message UnsubscribeRequest {
+    int32 prop_id = 1;
+    int32 area_id = 2;
+}
\ No newline at end of file
diff --git a/automotive/vehicle/aidl/impl/utils/common/Android.bp b/automotive/vehicle/aidl/impl/utils/common/Android.bp
index e5d9346..5cd07b4 100644
--- a/automotive/vehicle/aidl/impl/utils/common/Android.bp
+++ b/automotive/vehicle/aidl/impl/utils/common/Android.bp
@@ -25,10 +25,12 @@
     local_include_dirs: ["include"],
     export_include_dirs: ["include"],
     defaults: ["VehicleHalDefaults"],
+    host_supported: true,
 }
 
 cc_library_headers {
     name: "VehicleHalUtilHeaders",
     export_include_dirs: ["include"],
     vendor: true,
+    host_supported: true,
 }
diff --git a/automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp b/automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp
index 6a2a695..3d0a524 100644
--- a/automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp
+++ b/automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp
@@ -173,9 +173,7 @@
     }
 
     if (onValuesChangeCallback == nullptr && onValueChangeCallback == nullptr) {
-        ALOGW("No callback registered, ignoring property update for propId: %" PRId32
-              ", area ID: %" PRId32,
-              propId, areaId);
+        // No callback registered.
         return {};
     }
 
diff --git a/automotive/vehicle/aidl/impl/utils/common/test/Android.bp b/automotive/vehicle/aidl/impl/utils/common/test/Android.bp
index dd43712..69ec7a2 100644
--- a/automotive/vehicle/aidl/impl/utils/common/test/Android.bp
+++ b/automotive/vehicle/aidl/impl/utils/common/test/Android.bp
@@ -15,6 +15,7 @@
  */
 
 package {
+    default_team: "trendy_team_aaos_framework",
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
diff --git a/automotive/vehicle/aidl/impl/vhal/Android.bp b/automotive/vehicle/aidl/impl/vhal/Android.bp
index aa30f80..ae1102f 100644
--- a/automotive/vehicle/aidl/impl/vhal/Android.bp
+++ b/automotive/vehicle/aidl/impl/vhal/Android.bp
@@ -15,6 +15,7 @@
  */
 
 package {
+    default_team: "trendy_team_aaos_framework",
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
diff --git a/automotive/vehicle/aidl/impl/vhal/test/Android.bp b/automotive/vehicle/aidl/impl/vhal/test/Android.bp
index 7122aa5..d6c2f8e 100644
--- a/automotive/vehicle/aidl/impl/vhal/test/Android.bp
+++ b/automotive/vehicle/aidl/impl/vhal/test/Android.bp
@@ -15,6 +15,7 @@
  */
 
 package {
+    default_team: "trendy_team_aaos_framework",
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
diff --git a/automotive/vehicle/aidl_property/Android.bp b/automotive/vehicle/aidl_property/Android.bp
index bce2284..2aaf6b6 100644
--- a/automotive/vehicle/aidl_property/Android.bp
+++ b/automotive/vehicle/aidl_property/Android.bp
@@ -61,6 +61,7 @@
         },
 
     ],
+    host_supported: true,
 }
 
 filegroup {
diff --git a/biometrics/common/thread/Android.bp b/biometrics/common/thread/Android.bp
index a497d01..e7a7e4c 100644
--- a/biometrics/common/thread/Android.bp
+++ b/biometrics/common/thread/Android.bp
@@ -1,3 +1,7 @@
+package {
+    default_team: "trendy_team_biometrics_framework",
+}
+
 cc_library {
     // See: http://go/android-license-faq
     // A large-scale-change added 'default_applicable_licenses' to import
diff --git a/biometrics/face/aidl/default/Android.bp b/biometrics/face/aidl/default/Android.bp
index 4e8390a..685639c 100644
--- a/biometrics/face/aidl/default/Android.bp
+++ b/biometrics/face/aidl/default/Android.bp
@@ -1,4 +1,5 @@
 package {
+    default_team: "trendy_team_biometrics_framework",
     // See: http://go/android-license-faq
     // A large-scale-change added 'default_applicable_licenses' to import
     // all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/biometrics/face/aidl/vts/Android.bp b/biometrics/face/aidl/vts/Android.bp
index f62c4e4..e037eac 100644
--- a/biometrics/face/aidl/vts/Android.bp
+++ b/biometrics/face/aidl/vts/Android.bp
@@ -1,4 +1,5 @@
 package {
+    default_team: "trendy_team_biometrics_framework",
     // See: http://go/android-license-faq
     // A large-scale-change added 'default_applicable_licenses' to import
     // all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/biometrics/fingerprint/2.3/vts/functional/Android.bp b/biometrics/fingerprint/2.3/vts/functional/Android.bp
index 100aa29..c299761 100644
--- a/biometrics/fingerprint/2.3/vts/functional/Android.bp
+++ b/biometrics/fingerprint/2.3/vts/functional/Android.bp
@@ -15,6 +15,7 @@
  */
 
 package {
+    default_team: "trendy_team_biometrics_framework",
     // See: http://go/android-license-faq
     // A large-scale-change added 'default_applicable_licenses' to import
     // all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/biometrics/fingerprint/aidl/default/Android.bp b/biometrics/fingerprint/aidl/default/Android.bp
index 501af07..2a73f5d 100644
--- a/biometrics/fingerprint/aidl/default/Android.bp
+++ b/biometrics/fingerprint/aidl/default/Android.bp
@@ -1,4 +1,5 @@
 package {
+    default_team: "trendy_team_biometrics_framework",
     // See: http://go/android-license-faq
     // A large-scale-change added 'default_applicable_licenses' to import
     // all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/biometrics/fingerprint/aidl/vts/Android.bp b/biometrics/fingerprint/aidl/vts/Android.bp
index 1652905..fc32fe6 100644
--- a/biometrics/fingerprint/aidl/vts/Android.bp
+++ b/biometrics/fingerprint/aidl/vts/Android.bp
@@ -1,4 +1,5 @@
 package {
+    default_team: "trendy_team_biometrics_framework",
     // See: http://go/android-license-faq
     // A large-scale-change added 'default_applicable_licenses' to import
     // all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/bluetooth/aidl/vts/Android.bp b/bluetooth/aidl/vts/Android.bp
index ade3bef..c69ced4 100644
--- a/bluetooth/aidl/vts/Android.bp
+++ b/bluetooth/aidl/vts/Android.bp
@@ -28,6 +28,7 @@
     static_libs: [
         "android.hardware.bluetooth-V1-ndk",
         "libbluetooth_hci_pdl",
+        "libbluetooth_log",
     ],
     test_config: "VtsHalBluetoothTargetTest.xml",
     test_suites: [
diff --git a/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp b/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp
index 87f0f11..aaf436f 100644
--- a/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp
+++ b/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp
@@ -154,6 +154,9 @@
 
 // The main test class for Bluetooth HAL.
 class BluetoothAidlTest : public ::testing::TestWithParam<std::string> {
+  std::chrono::time_point<std::chrono::system_clock>
+      time_after_initialize_complete;
+
  public:
   void SetUp() override {
     // currently test passthrough mode only
@@ -184,12 +187,16 @@
     event_cb_count = 0;
     acl_cb_count = 0;
     sco_cb_count = 0;
+    std::chrono::time_point<std::chrono::system_clock>
+        timeout_after_initialize =
+            std::chrono::system_clock::now() + kWaitForInitTimeout;
 
     ASSERT_TRUE(hci->initialize(hci_cb).isOk());
     auto future = initialized_promise.get_future();
     auto timeout_status = future.wait_for(kWaitForInitTimeout);
     ASSERT_EQ(timeout_status, std::future_status::ready);
     ASSERT_TRUE(future.get());
+    ASSERT_GE(timeout_after_initialize, time_after_initialize_complete);
   }
 
   void TearDown() override {
@@ -241,6 +248,10 @@
     ~BluetoothHciCallbacks() override = default;
 
     ndk::ScopedAStatus initializationComplete(Status status) override {
+      if (status == Status::SUCCESS) {
+        parent_.time_after_initialize_complete =
+            std::chrono::system_clock::now();
+      }
       parent_.initialized_promise.set_value(status == Status::SUCCESS);
       ALOGV("%s (status = %d)", __func__, static_cast<int>(status));
       return ScopedAStatus::ok();
@@ -1084,6 +1095,37 @@
 
 }
 
+/**
+ * VSR-5.3.14-012 MUST support at least eight LE concurrent connections with
+ *                three in peripheral role.
+ */
+// @VsrTest = 5.3.14-012
+TEST_P(BluetoothAidlTest, Vsr_BlE_Connection_Requirement) {
+  std::vector<uint8_t> version_event;
+  send_and_wait_for_cmd_complete(ReadLocalVersionInformationBuilder::Create(),
+                                 version_event);
+  auto version_view = ReadLocalVersionInformationCompleteView::Create(
+      CommandCompleteView::Create(EventView::Create(PacketView<true>(
+          std::make_shared<std::vector<uint8_t>>(version_event)))));
+  ASSERT_TRUE(version_view.IsValid());
+  ASSERT_EQ(::bluetooth::hci::ErrorCode::SUCCESS, version_view.GetStatus());
+  auto version = version_view.GetLocalVersionInformation();
+  if (version.hci_version_ < ::bluetooth::hci::HciVersion::V_5_0) {
+    // This test does not apply to controllers below 5.0
+    return;
+  };
+
+  int max_connections = ::android::base::GetIntProperty(
+      "bluetooth.core.le.max_number_of_concurrent_connections", -1);
+  if (max_connections == -1) {
+    // With the property not set the default minimum of 8 will be used
+    ALOGI("Max number of LE concurrent connections isn't set");
+    return;
+  }
+  ALOGI("Max number of LE concurrent connections = %d", max_connections);
+  ASSERT_GE(max_connections, 8);
+}
+
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BluetoothAidlTest);
 INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAidlTest,
                          testing::ValuesIn(android::getAidlHalInstanceNames(
diff --git a/bluetooth/audio/aidl/Android.bp b/bluetooth/audio/aidl/Android.bp
index f8818fd..f273c7a 100644
--- a/bluetooth/audio/aidl/Android.bp
+++ b/bluetooth/audio/aidl/Android.bp
@@ -105,3 +105,25 @@
         latest_android_hardware_bluetooth_audio + "-ndk",
     ],
 }
+
+cc_defaults {
+    name: "latest_android_hardware_bluetooth_audio_ndk_android_shared",
+    target: {
+        android: {
+            shared_libs: [
+                latest_android_hardware_bluetooth_audio + "-ndk",
+            ],
+        },
+    },
+}
+
+cc_defaults {
+    name: "latest_android_hardware_bluetooth_audio_ndk_android_static",
+    target: {
+        android: {
+            static_libs: [
+                latest_android_hardware_bluetooth_audio + "-ndk",
+            ],
+        },
+    },
+}
diff --git a/bluetooth/audio/aidl/default/Android.bp b/bluetooth/audio/aidl/default/Android.bp
index 69db1b3..af6bf86 100644
--- a/bluetooth/audio/aidl/default/Android.bp
+++ b/bluetooth/audio/aidl/default/Android.bp
@@ -40,3 +40,10 @@
         "libbluetooth_audio_session_aidl",
     ],
 }
+
+prebuilt_etc {
+    name: "android.hardware.bluetooth.audio.xml",
+    src: "bluetooth_audio.xml",
+    sub_dir: "vintf",
+    installable: false,
+}
diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp b/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp
index 584640b..2a2cab0 100644
--- a/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp
+++ b/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp
@@ -39,6 +39,9 @@
 static const std::string kLeAudioOffloadProviderName =
     "LE_AUDIO_OFFLOAD_HARDWARE_OFFLOAD_PROVIDER";
 
+static const std::string kHfpOffloadProviderName =
+    "HFP_OFFLOAD_HARDWARE_OFFLOAD_PROVIDER";
+
 BluetoothAudioProviderFactory::BluetoothAudioProviderFactory() {}
 
 ndk::ScopedAStatus BluetoothAudioProviderFactory::openProvider(
@@ -170,6 +173,7 @@
     provider_info.name = a2dp_offload_codec_factory_.name;
     for (auto codec : a2dp_offload_codec_factory_.codecs)
       provider_info.codecInfos.push_back(codec->info);
+    return ndk::ScopedAStatus::ok();
   }
 
   if (session_type ==
@@ -180,16 +184,28 @@
           SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
     std::vector<CodecInfo> db_codec_info =
         BluetoothAudioCodecs::GetLeAudioOffloadCodecInfo(session_type);
+    // Return provider info supports without checking db_codec_info
+    // This help with various flow implementation for multidirectional support.
+    auto& provider_info = _aidl_return->emplace();
+    provider_info.supportsMultidirectionalCapabilities = true;
+    provider_info.name = kLeAudioOffloadProviderName;
+    provider_info.codecInfos = db_codec_info;
+    return ndk::ScopedAStatus::ok();
+  }
+
+  if (session_type == SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH) {
+    std::vector<CodecInfo> db_codec_info =
+        BluetoothAudioCodecs::GetHfpOffloadCodecInfo();
     if (!db_codec_info.empty()) {
       auto& provider_info = _aidl_return->emplace();
-      provider_info.name = kLeAudioOffloadProviderName;
+      provider_info.name = kHfpOffloadProviderName;
       provider_info.codecInfos = db_codec_info;
-      *_aidl_return = provider_info;
       return ndk::ScopedAStatus::ok();
     }
   }
 
-  return ndk::ScopedAStatus::ok();
+  // Unsupported for other sessions
+  return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
 }
 
 }  // namespace audio
diff --git a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp
index a692d84..5002a1a 100644
--- a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp
+++ b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp
@@ -165,8 +165,8 @@
   return cfg_codec == req_codec;
 }
 
-bool LeAudioOffloadAudioProvider::isCapabilitiesMatchedContext(
-    AudioContext setting_context,
+bool LeAudioOffloadAudioProvider::filterCapabilitiesMatchedContext(
+    AudioContext& setting_context,
     const IBluetoothAudioProvider::LeAudioDeviceCapabilities& capabilities) {
   // If has no metadata, assume match
   if (!capabilities.metadata.has_value()) return true;
@@ -178,7 +178,11 @@
       auto& context = metadata.value()
                           .get<MetadataLtv::Tag::preferredAudioContexts>()
                           .values;
-      if (setting_context.bitmask & context.bitmask) return true;
+      if (setting_context.bitmask & context.bitmask) {
+        // New mask with matched capability
+        setting_context.bitmask &= context.bitmask;
+        return true;
+      }
     }
   }
 
@@ -189,8 +193,12 @@
     CodecSpecificConfigurationLtv::SamplingFrequency& cfg_freq,
     CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies&
         capability_freq) {
-  for (auto [freq, bitmask] : freq_to_support_bitmask_map)
-    if (cfg_freq == freq) return (capability_freq.bitmask & bitmask);
+  auto p = freq_to_support_bitmask_map.find(cfg_freq);
+  if (p != freq_to_support_bitmask_map.end()) {
+    if (capability_freq.bitmask & p->second) {
+      return true;
+    }
+  }
   return false;
 }
 
@@ -198,9 +206,11 @@
     CodecSpecificConfigurationLtv::FrameDuration& cfg_fduration,
     CodecSpecificCapabilitiesLtv::SupportedFrameDurations&
         capability_fduration) {
-  for (auto [fduration, bitmask] : fduration_to_support_fduration_map)
-    if (cfg_fduration == fduration)
-      return (capability_fduration.bitmask & bitmask);
+  auto p = fduration_to_support_fduration_map.find(cfg_fduration);
+  if (p != fduration_to_support_fduration_map.end())
+    if (capability_fduration.bitmask & p->second) {
+      return true;
+    }
   return false;
 }
 
@@ -240,50 +250,67 @@
 
   for (auto& codec_capability : codec_capabilities) {
     auto cfg = cfg_tag_map.find(cap_to_cfg_tag_map[codec_capability.getTag()]);
-    // Cannot find tag for the capability:
-    if (cfg == cfg_tag_map.end()) return false;
+    // If capability has this tag, but our configuration doesn't
+    // Then we will assume it is matched
+    if (cfg == cfg_tag_map.end()) {
+      continue;
+    }
 
-    // Matching logic for sampling frequency
-    if (codec_capability.getTag() ==
-        CodecSpecificCapabilitiesLtv::Tag::supportedSamplingFrequencies) {
-      if (!isMatchedSamplingFreq(
-              cfg->second
-                  .get<CodecSpecificConfigurationLtv::Tag::samplingFrequency>(),
-              codec_capability.get<CodecSpecificCapabilitiesLtv::Tag::
-                                       supportedSamplingFrequencies>()))
-        return false;
-    } else if (codec_capability.getTag() ==
-               CodecSpecificCapabilitiesLtv::Tag::supportedFrameDurations) {
-      if (!isMatchedFrameDuration(
-              cfg->second
-                  .get<CodecSpecificConfigurationLtv::Tag::frameDuration>(),
-              codec_capability.get<CodecSpecificCapabilitiesLtv::Tag::
-                                       supportedFrameDurations>()))
-        return false;
-    } else if (codec_capability.getTag() ==
-               CodecSpecificCapabilitiesLtv::Tag::supportedAudioChannelCounts) {
-      if (!isMatchedAudioChannel(
-              cfg->second.get<
-                  CodecSpecificConfigurationLtv::Tag::audioChannelAllocation>(),
-              codec_capability.get<CodecSpecificCapabilitiesLtv::Tag::
-                                       supportedAudioChannelCounts>()))
-        return false;
-    } else if (codec_capability.getTag() == CodecSpecificCapabilitiesLtv::Tag::
-                                                supportedMaxCodecFramesPerSDU) {
-      if (!isMatchedCodecFramesPerSDU(
-              cfg->second.get<
-                  CodecSpecificConfigurationLtv::Tag::codecFrameBlocksPerSDU>(),
-              codec_capability.get<CodecSpecificCapabilitiesLtv::Tag::
-                                       supportedMaxCodecFramesPerSDU>()))
-        return false;
-    } else if (codec_capability.getTag() == CodecSpecificCapabilitiesLtv::Tag::
-                                                supportedOctetsPerCodecFrame) {
-      if (!isMatchedOctetsPerCodecFrame(
-              cfg->second.get<
-                  CodecSpecificConfigurationLtv::Tag::octetsPerCodecFrame>(),
-              codec_capability.get<CodecSpecificCapabilitiesLtv::Tag::
-                                       supportedOctetsPerCodecFrame>()))
-        return false;
+    switch (codec_capability.getTag()) {
+      case CodecSpecificCapabilitiesLtv::Tag::supportedSamplingFrequencies: {
+        if (!isMatchedSamplingFreq(
+                cfg->second.get<
+                    CodecSpecificConfigurationLtv::Tag::samplingFrequency>(),
+                codec_capability.get<CodecSpecificCapabilitiesLtv::Tag::
+                                         supportedSamplingFrequencies>())) {
+          return false;
+        }
+        break;
+      }
+
+      case CodecSpecificCapabilitiesLtv::Tag::supportedFrameDurations: {
+        if (!isMatchedFrameDuration(
+                cfg->second
+                    .get<CodecSpecificConfigurationLtv::Tag::frameDuration>(),
+                codec_capability.get<CodecSpecificCapabilitiesLtv::Tag::
+                                         supportedFrameDurations>())) {
+          return false;
+        }
+        break;
+      }
+
+      case CodecSpecificCapabilitiesLtv::Tag::supportedAudioChannelCounts: {
+        if (!isMatchedAudioChannel(
+                cfg->second.get<CodecSpecificConfigurationLtv::Tag::
+                                    audioChannelAllocation>(),
+                codec_capability.get<CodecSpecificCapabilitiesLtv::Tag::
+                                         supportedAudioChannelCounts>())) {
+          return false;
+        }
+        break;
+      }
+
+      case CodecSpecificCapabilitiesLtv::Tag::supportedMaxCodecFramesPerSDU: {
+        if (!isMatchedCodecFramesPerSDU(
+                cfg->second.get<CodecSpecificConfigurationLtv::Tag::
+                                    codecFrameBlocksPerSDU>(),
+                codec_capability.get<CodecSpecificCapabilitiesLtv::Tag::
+                                         supportedMaxCodecFramesPerSDU>())) {
+          return false;
+        }
+        break;
+      }
+
+      case CodecSpecificCapabilitiesLtv::Tag::supportedOctetsPerCodecFrame: {
+        if (!isMatchedOctetsPerCodecFrame(
+                cfg->second.get<
+                    CodecSpecificConfigurationLtv::Tag::octetsPerCodecFrame>(),
+                codec_capability.get<CodecSpecificCapabilitiesLtv::Tag::
+                                         supportedOctetsPerCodecFrame>())) {
+          return false;
+        }
+        break;
+      }
     }
   }
 
@@ -298,11 +325,16 @@
   if (requirement_cfg.codecId.has_value()) {
     if (!setting_cfg.codecId.has_value()) return false;
     if (!isMatchedValidCodec(setting_cfg.codecId.value(),
-                             requirement_cfg.codecId.value()))
+                             requirement_cfg.codecId.value())) {
       return false;
+    }
   }
 
-  if (setting_cfg.targetLatency != requirement_cfg.targetLatency) return false;
+  if (requirement_cfg.targetLatency ==
+          LeAudioAseConfiguration::TargetLatency::UNDEFINED ||
+      setting_cfg.targetLatency != requirement_cfg.targetLatency) {
+    return false;
+  }
   // Ignore PHY requirement
 
   // Check all codec configuration
@@ -314,9 +346,13 @@
   for (auto requirement_cfg : requirement_cfg.codecConfiguration) {
     // Directly compare CodecSpecificConfigurationLtv
     auto cfg = cfg_tag_map.find(requirement_cfg.getTag());
-    if (cfg == cfg_tag_map.end()) return false;
+    if (cfg == cfg_tag_map.end()) {
+      return false;
+    }
 
-    if (cfg->second != requirement_cfg) return false;
+    if (cfg->second != requirement_cfg) {
+      return false;
+    }
   }
   // Ignore vendor configuration and metadata requirement
 
@@ -326,10 +362,13 @@
 bool LeAudioOffloadAudioProvider::isMatchedBISConfiguration(
     LeAudioBisConfiguration bis_cfg,
     const IBluetoothAudioProvider::LeAudioDeviceCapabilities& capabilities) {
-  if (!isMatchedValidCodec(bis_cfg.codecId, capabilities.codecId)) return false;
-  if (!isCapabilitiesMatchedCodecConfiguration(
-          bis_cfg.codecConfiguration, capabilities.codecSpecificCapabilities))
+  if (!isMatchedValidCodec(bis_cfg.codecId, capabilities.codecId)) {
     return false;
+  }
+  if (!isCapabilitiesMatchedCodecConfiguration(
+          bis_cfg.codecConfiguration, capabilities.codecSpecificCapabilities)) {
+    return false;
+  }
   return true;
 }
 
@@ -357,31 +396,35 @@
 }
 
 void LeAudioOffloadAudioProvider::filterRequirementAseDirectionConfiguration(
-    std::vector<std::optional<AseDirectionConfiguration>>&
+    std::optional<std::vector<std::optional<AseDirectionConfiguration>>>&
         direction_configurations,
-    const std::optional<std::vector<std::optional<AseDirectionRequirement>>>&
-        requirements,
-    std::vector<std::optional<AseDirectionConfiguration>>&
+    const std::vector<std::optional<AseDirectionRequirement>>& requirements,
+    std::optional<std::vector<std::optional<AseDirectionConfiguration>>>&
         valid_direction_configurations) {
-  for (auto direction_configuration : direction_configurations) {
-    if (!requirements.has_value()) {
-      // If there's no requirement, all are valid
-      valid_direction_configurations.push_back(direction_configuration);
-      continue;
-    }
-    if (!direction_configuration.has_value()) continue;
-
-    for (auto& requirement : requirements.value()) {
-      if (!requirement.has_value()) continue;
+  if (!valid_direction_configurations.has_value()) {
+    valid_direction_configurations =
+        std::vector<std::optional<AseDirectionConfiguration>>();
+  }
+  // For every requirement, find the matched ase configuration
+  if (!direction_configurations.has_value()) return;
+  for (auto& requirement : requirements) {
+    if (!requirement.has_value()) continue;
+    for (auto direction_configuration : direction_configurations.value()) {
+      if (!direction_configuration.has_value()) continue;
       if (!isMatchedAseConfiguration(
               direction_configuration.value().aseConfiguration,
               requirement.value().aseConfiguration))
         continue;
       // Valid if match any requirement.
-      valid_direction_configurations.push_back(direction_configuration);
+      valid_direction_configurations.value().push_back(direction_configuration);
       break;
     }
   }
+  // Ensure that each requirement will have one direction configurations
+  if (valid_direction_configurations.value().empty() ||
+      (valid_direction_configurations.value().size() != requirements.size())) {
+    valid_direction_configurations = std::nullopt;
+  }
 }
 
 /* Get a new LeAudioAseConfigurationSetting by matching a setting with a
@@ -392,8 +435,18 @@
     IBluetoothAudioProvider::LeAudioAseConfigurationSetting& setting,
     const IBluetoothAudioProvider::LeAudioDeviceCapabilities& capabilities,
     uint8_t direction) {
+  // Create a new LeAudioAseConfigurationSetting and return
+  // For other direction will contain all settings
+  LeAudioAseConfigurationSetting filtered_setting{
+      .audioContext = setting.audioContext,
+      .sinkAseConfiguration = setting.sinkAseConfiguration,
+      .sourceAseConfiguration = setting.sourceAseConfiguration,
+      .flags = setting.flags,
+      .packing = setting.packing,
+  };
   // Try to match context in metadata.
-  if (!isCapabilitiesMatchedContext(setting.audioContext, capabilities))
+  if (!filterCapabilitiesMatchedContext(filtered_setting.audioContext,
+                                        capabilities))
     return std::nullopt;
 
   // Get a list of all matched AseDirectionConfiguration
@@ -401,28 +454,30 @@
   std::vector<std::optional<AseDirectionConfiguration>>*
       direction_configuration = nullptr;
   if (direction == kLeAudioDirectionSink) {
-    if (!setting.sinkAseConfiguration.has_value()) return std::nullopt;
-    direction_configuration = &setting.sinkAseConfiguration.value();
+    if (!filtered_setting.sinkAseConfiguration.has_value()) return std::nullopt;
+    direction_configuration = &filtered_setting.sinkAseConfiguration.value();
   } else {
-    if (!setting.sourceAseConfiguration.has_value()) return std::nullopt;
-    direction_configuration = &setting.sourceAseConfiguration.value();
+    if (!filtered_setting.sourceAseConfiguration.has_value())
+      return std::nullopt;
+    direction_configuration = &filtered_setting.sourceAseConfiguration.value();
   }
   std::vector<std::optional<AseDirectionConfiguration>>
       valid_direction_configuration;
   filterCapabilitiesAseDirectionConfiguration(
       *direction_configuration, capabilities, valid_direction_configuration);
-  if (valid_direction_configuration.empty()) return std::nullopt;
+
+  // No valid configuration for this direction
+  if (valid_direction_configuration.empty()) {
+    return std::nullopt;
+  }
 
   // Create a new LeAudioAseConfigurationSetting and return
-  LeAudioAseConfigurationSetting filtered_setting;
-  filtered_setting.audioContext = setting.audioContext;
-  filtered_setting.packing = setting.packing;
+  // For other direction will contain all settings
   if (direction == kLeAudioDirectionSink) {
     filtered_setting.sinkAseConfiguration = valid_direction_configuration;
   } else {
     filtered_setting.sourceAseConfiguration = valid_direction_configuration;
   }
-  filtered_setting.flags = setting.flags;
 
   return filtered_setting;
 }
@@ -436,41 +491,49 @@
     const IBluetoothAudioProvider::LeAudioConfigurationRequirement&
         requirement) {
   // Try to match context in metadata.
-  if (setting.audioContext != requirement.audioContext) return std::nullopt;
+  if ((setting.audioContext.bitmask & requirement.audioContext.bitmask) !=
+      requirement.audioContext.bitmask)
+    return std::nullopt;
+
+  // Further filter setting's context
+  setting.audioContext.bitmask &= requirement.audioContext.bitmask;
 
   // Check requirement for the correct direction
   const std::optional<std::vector<std::optional<AseDirectionRequirement>>>*
       direction_requirement;
   std::vector<std::optional<AseDirectionConfiguration>>*
       direction_configuration;
-  if (setting.sinkAseConfiguration.has_value()) {
-    direction_configuration = &setting.sinkAseConfiguration.value();
-    direction_requirement = &requirement.sinkAseRequirement;
-  } else {
-    direction_configuration = &setting.sourceAseConfiguration.value();
-    direction_requirement = &requirement.sourceAseRequirement;
+
+  // Create a new LeAudioAseConfigurationSetting to return
+  LeAudioAseConfigurationSetting filtered_setting{
+      .audioContext = setting.audioContext,
+      .packing = setting.packing,
+      .flags = setting.flags,
+  };
+
+  if (requirement.sinkAseRequirement.has_value()) {
+    filterRequirementAseDirectionConfiguration(
+        setting.sinkAseConfiguration, requirement.sinkAseRequirement.value(),
+        filtered_setting.sinkAseConfiguration);
+    if (!filtered_setting.sinkAseConfiguration.has_value()) return std::nullopt;
   }
 
-  std::vector<std::optional<AseDirectionConfiguration>>
-      valid_direction_configuration;
-  filterRequirementAseDirectionConfiguration(*direction_configuration,
-                                             *direction_requirement,
-                                             valid_direction_configuration);
-  if (valid_direction_configuration.empty()) return std::nullopt;
-
-  // Create a new LeAudioAseConfigurationSetting and return
-  LeAudioAseConfigurationSetting filtered_setting;
-  filtered_setting.audioContext = setting.audioContext;
-  filtered_setting.packing = setting.packing;
-  if (setting.sinkAseConfiguration.has_value())
-    filtered_setting.sinkAseConfiguration = valid_direction_configuration;
-  else
-    filtered_setting.sourceAseConfiguration = valid_direction_configuration;
-  filtered_setting.flags = setting.flags;
+  if (requirement.sourceAseRequirement.has_value()) {
+    filterRequirementAseDirectionConfiguration(
+        setting.sourceAseConfiguration,
+        requirement.sourceAseRequirement.value(),
+        filtered_setting.sourceAseConfiguration);
+    if (!filtered_setting.sourceAseConfiguration.has_value())
+      return std::nullopt;
+  }
 
   return filtered_setting;
 }
 
+// For each requirement, a valid ASE configuration will satify:
+// - matched with any sink capability (if presented)
+// - OR matched with any source capability (if presented)
+// - and the setting need to pass the requirement
 ndk::ScopedAStatus LeAudioOffloadAudioProvider::getLeAudioAseConfiguration(
     const std::optional<std::vector<
         std::optional<IBluetoothAudioProvider::LeAudioDeviceCapabilities>>>&
@@ -487,46 +550,81 @@
       ase_configuration_settings =
           BluetoothAudioCodecs::GetLeAudioAseConfigurationSettings();
 
-  // Currently won't handle case where both sink and source capabilities
-  // are passed in. Only handle one of them.
-  const std::optional<std::vector<
-      std::optional<IBluetoothAudioProvider::LeAudioDeviceCapabilities>>>*
-      in_remoteAudioCapabilities;
-  uint8_t direction = 0;
-  if (in_remoteSinkAudioCapabilities.has_value()) {
-    direction = kLeAudioDirectionSink;
-    in_remoteAudioCapabilities = &in_remoteSinkAudioCapabilities;
-  } else {
-    direction = kLeAudioDirectionSource;
-    in_remoteAudioCapabilities = &in_remoteSourceAudioCapabilities;
+  if (!in_remoteSinkAudioCapabilities.has_value() &&
+      !in_remoteSourceAudioCapabilities.has_value()) {
+    return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
   }
 
+  // Each setting consist of source and sink AseDirectionConfiguration vector
+  // Filter every sink capability
   std::vector<IBluetoothAudioProvider::LeAudioAseConfigurationSetting>
-      capability_matched_ase_configuration_settings;
-  // Matching with remote capabilities
-  for (auto& setting : ase_configuration_settings) {
-    for (auto& capability : in_remoteAudioCapabilities->value()) {
-      if (!capability.has_value()) continue;
-      auto filtered_ase_configuration_setting =
-          getCapabilitiesMatchedAseConfigurationSettings(
-              setting, capability.value(), direction);
-      if (filtered_ase_configuration_setting.has_value()) {
-        capability_matched_ase_configuration_settings.push_back(
-            filtered_ase_configuration_setting.value());
+      matched_ase_configuration_settings;
+
+  if (in_remoteSinkAudioCapabilities.has_value()) {
+    // Matching each setting with any remote capabilities
+    for (auto& setting : ase_configuration_settings) {
+      for (auto& capability : in_remoteSinkAudioCapabilities.value()) {
+        if (!capability.has_value()) continue;
+        auto filtered_ase_configuration_setting =
+            getCapabilitiesMatchedAseConfigurationSettings(
+                setting, capability.value(), kLeAudioDirectionSink);
+        if (filtered_ase_configuration_setting.has_value()) {
+          matched_ase_configuration_settings.push_back(
+              filtered_ase_configuration_setting.value());
+        }
       }
     }
   }
 
-  // Matching with requirements
+  // Combine filter every source capability
+  if (in_remoteSourceAudioCapabilities.has_value()) {
+    // Matching each setting with any remote capabilities
+    for (auto& setting : ase_configuration_settings) {
+      for (auto& capability : in_remoteSourceAudioCapabilities.value()) {
+        if (!capability.has_value()) continue;
+        auto filtered_ase_configuration_setting =
+            getCapabilitiesMatchedAseConfigurationSettings(
+                setting, capability.value(), kLeAudioDirectionSource);
+        if (filtered_ase_configuration_setting.has_value()) {
+          // Put into the same list
+          // possibly duplicated, filtered by requirement later
+          matched_ase_configuration_settings.push_back(
+              filtered_ase_configuration_setting.value());
+        }
+      }
+    }
+  }
+
+  if (matched_ase_configuration_settings.empty()) {
+    LOG(WARNING) << __func__ << ": No setting matched the capability";
+    return ndk::ScopedAStatus::ok();
+  }
+  // Each requirement will match with a valid setting
   std::vector<IBluetoothAudioProvider::LeAudioAseConfigurationSetting> result;
-  for (auto& setting : capability_matched_ase_configuration_settings) {
-    for (auto& requirement : in_requirements) {
+  for (auto& requirement : in_requirements) {
+    LOG(INFO) << __func__ << ": Trying to match for the requirement "
+              << requirement.toString();
+    bool is_matched = false;
+
+    for (auto& setting : matched_ase_configuration_settings) {
       auto filtered_ase_configuration_setting =
           getRequirementMatchedAseConfigurationSettings(setting, requirement);
       if (filtered_ase_configuration_setting.has_value()) {
         result.push_back(filtered_ase_configuration_setting.value());
+        LOG(INFO) << __func__ << ": Result = "
+                  << filtered_ase_configuration_setting.value().toString();
+        // Found a matched setting, ignore other settings
+        is_matched = true;
+        break;
       }
     }
+    if (!is_matched) {
+      // If cannot satisfy this requirement, return an empty result
+      LOG(WARNING) << __func__ << ": Cannot match the requirement "
+                   << requirement.toString();
+      result.clear();
+      break;
+    }
   }
 
   *_aidl_return = result;
@@ -537,41 +635,45 @@
     LeAudioAseQosConfiguration setting_qos,
     AseQosDirectionRequirement requirement_qos) {
   if (setting_qos.retransmissionNum !=
-      requirement_qos.preferredRetransmissionNum)
+      requirement_qos.preferredRetransmissionNum) {
     return false;
-  if (setting_qos.maxTransportLatencyMs > requirement_qos.maxTransportLatencyMs)
+  }
+  if (setting_qos.maxTransportLatencyMs >
+      requirement_qos.maxTransportLatencyMs) {
     return false;
+  }
   // Ignore other parameters, as they are not populated in the setting_qos
   return true;
 }
 
-ndk::ScopedAStatus LeAudioOffloadAudioProvider::getLeAudioAseQosConfiguration(
-    const IBluetoothAudioProvider::LeAudioAseQosConfigurationRequirement&
-        in_qosRequirement,
-    IBluetoothAudioProvider::LeAudioAseQosConfigurationPair* _aidl_return) {
-  IBluetoothAudioProvider::LeAudioAseQosConfigurationPair result;
-  // Get all configuration settings
-  std::vector<IBluetoothAudioProvider::LeAudioAseConfigurationSetting>
-      ase_configuration_settings =
-          BluetoothAudioCodecs::GetLeAudioAseConfigurationSettings();
+bool isValidQosRequirement(AseQosDirectionRequirement qosRequirement) {
+  return ((qosRequirement.maxTransportLatencyMs > 0) &&
+          (qosRequirement.presentationDelayMaxUs > 0) &&
+          (qosRequirement.presentationDelayMaxUs >=
+           qosRequirement.presentationDelayMinUs));
+}
 
-  // Direction QoS matching
-  // Only handle one direction input case
-  uint8_t direction = 0;
+std::optional<LeAudioAseQosConfiguration>
+LeAudioOffloadAudioProvider::getDirectionQosConfiguration(
+    uint8_t direction,
+    const IBluetoothAudioProvider::LeAudioAseQosConfigurationRequirement&
+        qosRequirement,
+    std::vector<LeAudioAseConfigurationSetting>& ase_configuration_settings) {
   std::optional<AseQosDirectionRequirement> direction_qos_requirement =
       std::nullopt;
-  if (in_qosRequirement.sinkAseQosRequirement.has_value()) {
-    direction_qos_requirement = in_qosRequirement.sinkAseQosRequirement.value();
-    direction = kLeAudioDirectionSink;
-  } else if (in_qosRequirement.sourceAseQosRequirement.has_value()) {
-    direction_qos_requirement =
-        in_qosRequirement.sourceAseQosRequirement.value();
-    direction = kLeAudioDirectionSource;
+
+  // Get the correct direction
+  if (direction == kLeAudioDirectionSink) {
+    direction_qos_requirement = qosRequirement.sinkAseQosRequirement.value();
+  } else {
+    direction_qos_requirement = qosRequirement.sourceAseQosRequirement.value();
   }
 
   for (auto& setting : ase_configuration_settings) {
     // Context matching
-    if (setting.audioContext != in_qosRequirement.audioContext) continue;
+    if ((setting.audioContext.bitmask & qosRequirement.audioContext.bitmask) !=
+        qosRequirement.audioContext.bitmask)
+      continue;
 
     // Match configuration flags
     // Currently configuration flags are not populated, ignore.
@@ -592,10 +694,7 @@
       if (!cfg.has_value()) continue;
       // If no requirement, return the first QoS
       if (!direction_qos_requirement.has_value()) {
-        result.sinkQosConfiguration = cfg.value().qosConfiguration;
-        result.sourceQosConfiguration = cfg.value().qosConfiguration;
-        *_aidl_return = result;
-        return ndk::ScopedAStatus::ok();
+        return cfg.value().qosConfiguration;
       }
 
       // If has requirement, return the first matched QoS
@@ -607,17 +706,41 @@
               direction_qos_requirement.value().aseConfiguration) &&
           isMatchedQosRequirement(cfg.value().qosConfiguration.value(),
                                   direction_qos_requirement.value())) {
-        if (direction == kLeAudioDirectionSink)
-          result.sinkQosConfiguration = cfg.value().qosConfiguration;
-        else
-          result.sourceQosConfiguration = cfg.value().qosConfiguration;
-        *_aidl_return = result;
-        return ndk::ScopedAStatus::ok();
+        return cfg.value().qosConfiguration;
       }
     }
   }
 
-  // No match, return empty QoS
+  return std::nullopt;
+}
+
+ndk::ScopedAStatus LeAudioOffloadAudioProvider::getLeAudioAseQosConfiguration(
+    const IBluetoothAudioProvider::LeAudioAseQosConfigurationRequirement&
+        in_qosRequirement,
+    IBluetoothAudioProvider::LeAudioAseQosConfigurationPair* _aidl_return) {
+  IBluetoothAudioProvider::LeAudioAseQosConfigurationPair result;
+
+  // Get all configuration settings
+  std::vector<IBluetoothAudioProvider::LeAudioAseConfigurationSetting>
+      ase_configuration_settings =
+          BluetoothAudioCodecs::GetLeAudioAseConfigurationSettings();
+
+  // Direction QoS matching
+  // Only handle one direction input case
+  if (in_qosRequirement.sinkAseQosRequirement.has_value()) {
+    if (!isValidQosRequirement(in_qosRequirement.sinkAseQosRequirement.value()))
+      return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    result.sinkQosConfiguration = getDirectionQosConfiguration(
+        kLeAudioDirectionSink, in_qosRequirement, ase_configuration_settings);
+  }
+  if (in_qosRequirement.sourceAseQosRequirement.has_value()) {
+    if (!isValidQosRequirement(
+            in_qosRequirement.sourceAseQosRequirement.value()))
+      return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    result.sourceQosConfiguration = getDirectionQosConfiguration(
+        kLeAudioDirectionSource, in_qosRequirement, ase_configuration_settings);
+  }
+
   *_aidl_return = result;
   return ndk::ScopedAStatus::ok();
 };
@@ -649,9 +772,13 @@
       BluetoothAudioCodecs::GetLeAudioOffloadCodecInfo(
           SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
   broadcast_settings.clear();
+
+  // Default value for unmapped fields
   CodecSpecificConfigurationLtv::AudioChannelAllocation default_allocation;
   default_allocation.bitmask =
       CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_CENTER;
+  CodecSpecificConfigurationLtv::CodecFrameBlocksPerSDU default_frame;
+  default_frame.value = 2;
 
   for (auto& codec_info : db_codec_info) {
     if (codec_info.transport.getTag() != CodecInfo::Transport::leAudio)
@@ -669,15 +796,20 @@
     octets.value = transport.bitdepth[0];
 
     bis_cfg.codecConfiguration = {
-        sampling_freq_map[transport.samplingFrequencyHz[0]], octets,
-        frame_duration_map[transport.frameDurationUs[0]], default_allocation};
+        sampling_freq_map[transport.samplingFrequencyHz[0]],
+        octets,
+        frame_duration_map[transport.frameDurationUs[0]],
+        default_allocation,
+        default_frame,
+    };
 
     // Add information to structure
     IBluetoothAudioProvider::LeAudioSubgroupBisConfiguration sub_bis_cfg;
-    sub_bis_cfg.numBis = 1;
+    sub_bis_cfg.numBis = 2;
     sub_bis_cfg.bisConfiguration = bis_cfg;
     IBluetoothAudioProvider::LeAudioBroadcastSubgroupConfiguration sub_cfg;
-    sub_cfg.bisConfigurations = {sub_bis_cfg};
+    // Populate the same sub config
+    sub_cfg.bisConfigurations = {sub_bis_cfg, sub_bis_cfg};
     setting.subgroupsConfigurations = {sub_cfg};
 
     broadcast_settings.push_back(setting);
@@ -721,6 +853,36 @@
   return filtered_setting;
 }
 
+bool LeAudioOffloadAudioProvider::isSubgroupConfigurationMatchedContext(
+    AudioContext setting_context,
+    LeAudioBroadcastSubgroupConfiguration configuration) {
+  // Find any valid context metadata in the bisConfigurations
+  // assuming the bis configuration in the same bis subgroup
+  // will have the same context metadata
+  std::optional<AudioContext> config_context = std::nullopt;
+
+  for (auto& p : configuration.bisConfigurations)
+    if (p.bisConfiguration.metadata.has_value()) {
+      bool is_context_found = false;
+      for (auto& metadata : p.bisConfiguration.metadata.value()) {
+        if (!metadata.has_value()) continue;
+        if (metadata.value().getTag() ==
+            MetadataLtv::Tag::preferredAudioContexts) {
+          config_context = metadata.value()
+                               .get<MetadataLtv::Tag::preferredAudioContexts>()
+                               .values;
+          is_context_found = true;
+          break;
+        }
+      }
+      if (is_context_found) break;
+    }
+
+  // Not found context metadata in any of the bis configuration, assume matched
+  if (!config_context.has_value()) return true;
+  return (setting_context.bitmask & config_context.value().bitmask);
+}
+
 ndk::ScopedAStatus
 LeAudioOffloadAudioProvider::getLeAudioBroadcastConfiguration(
     const std::optional<std::vector<
@@ -729,23 +891,28 @@
     const IBluetoothAudioProvider::LeAudioBroadcastConfigurationRequirement&
         in_requirement,
     LeAudioBroadcastConfigurationSetting* _aidl_return) {
-  getBroadcastSettings();
-  _aidl_return = nullptr;
+  if (in_requirement.subgroupConfigurationRequirements.empty()) {
+    LOG(WARNING) << __func__ << ": Empty requirement";
+    return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+  }
 
-  // Match and filter capability
+  // Broadcast setting are from provider info
+  // We will allow empty capability input, match all settings with requirements.
+  getBroadcastSettings();
   std::vector<LeAudioBroadcastConfigurationSetting> filtered_settings;
   if (!in_remoteSinkAudioCapabilities.has_value()) {
-    LOG(WARNING) << __func__ << ": Empty capability";
-    return ndk::ScopedAStatus::ok();
-  }
-  for (auto& setting : broadcast_settings) {
-    for (auto& capability : in_remoteSinkAudioCapabilities.value()) {
-      if (!capability.has_value()) continue;
-      auto filtered_setting =
-          getCapabilitiesMatchedBroadcastConfigurationSettings(
-              setting, capability.value());
-      if (filtered_setting.has_value())
-        filtered_settings.push_back(filtered_setting.value());
+    LOG(INFO) << __func__ << ": Empty capability, get all broadcast settings";
+    filtered_settings = broadcast_settings;
+  } else {
+    for (auto& setting : broadcast_settings) {
+      for (auto& capability : in_remoteSinkAudioCapabilities.value()) {
+        if (!capability.has_value()) continue;
+        auto filtered_setting =
+            getCapabilitiesMatchedBroadcastConfigurationSettings(
+                setting, capability.value());
+        if (filtered_setting.has_value())
+          filtered_settings.push_back(filtered_setting.value());
+      }
     }
   }
 
@@ -754,36 +921,52 @@
     return ndk::ScopedAStatus::ok();
   }
 
-  // Match and return the first matched requirement
   if (in_requirement.subgroupConfigurationRequirements.empty()) {
     LOG(INFO) << __func__ << ": Empty requirement";
     *_aidl_return = filtered_settings[0];
     return ndk::ScopedAStatus::ok();
   }
 
+  // For each subgroup config requirement, find a suitable subgroup config.
+  // Gather these suitable subgroup config in an array.
+  // If the setting can satisfy all requirement, we can return the setting
+  // with the filtered array.
   for (auto& setting : filtered_settings) {
-    // Further filter out bis configuration
-    LeAudioBroadcastConfigurationSetting filtered_setting(setting);
-    filtered_setting.subgroupsConfigurations.clear();
-    for (auto& sub_cfg : setting.subgroupsConfigurations) {
-      bool isMatched = false;
-      for (auto& sub_req : in_requirement.subgroupConfigurationRequirements) {
+    LeAudioBroadcastConfigurationSetting matched_setting(setting);
+    matched_setting.subgroupsConfigurations.clear();
+    auto total_num_bis = 0;
+
+    bool matched_all_requirement = true;
+
+    for (auto& sub_req : in_requirement.subgroupConfigurationRequirements) {
+      bool is_matched = false;
+      for (auto& sub_cfg : setting.subgroupsConfigurations) {
+        // Match the context
+        if (!isSubgroupConfigurationMatchedContext(sub_req.audioContext,
+                                                   sub_cfg))
+          continue;
         // Matching number of BIS
         if (sub_req.bisNumPerSubgroup != sub_cfg.bisConfigurations.size())
           continue;
-        // Currently will ignore quality and context hint.
-        isMatched = true;
+        // Currently will ignore quality matching.
+        matched_setting.subgroupsConfigurations.push_back(sub_cfg);
+        total_num_bis += sub_cfg.bisConfigurations.size();
+        is_matched = true;
         break;
       }
-      if (isMatched)
-        filtered_setting.subgroupsConfigurations.push_back(sub_cfg);
+      // There is an unmatched requirement, this setting cannot be used
+      if (!is_matched) {
+        matched_all_requirement = false;
+        break;
+      }
     }
-    // Return the first match
-    if (!filtered_setting.subgroupsConfigurations.empty()) {
-      LOG(INFO) << __func__ << ": Matched requirement";
-      *_aidl_return = filtered_setting;
-      return ndk::ScopedAStatus::ok();
-    }
+
+    if (!matched_all_requirement) continue;
+
+    matched_setting.numBis = total_num_bis;
+    // Return the filtered setting if all requirement satified
+    *_aidl_return = matched_setting;
+    return ndk::ScopedAStatus::ok();
   }
 
   LOG(WARNING) << __func__ << ": Cannot match any requirement";
diff --git a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h
index 2785e7f..06cd405 100644
--- a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h
+++ b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h
@@ -96,8 +96,8 @@
 
   // Private matching function definitions
   bool isMatchedValidCodec(CodecId cfg_codec, CodecId req_codec);
-  bool isCapabilitiesMatchedContext(
-      AudioContext setting_context,
+  bool filterCapabilitiesMatchedContext(
+      AudioContext& setting_context,
       const IBluetoothAudioProvider::LeAudioDeviceCapabilities& capabilities);
   bool isMatchedSamplingFreq(
       CodecSpecificConfigurationLtv::SamplingFrequency& cfg_freq,
@@ -134,11 +134,10 @@
       std::vector<std::optional<AseDirectionConfiguration>>&
           valid_direction_configurations);
   void filterRequirementAseDirectionConfiguration(
-      std::vector<std::optional<AseDirectionConfiguration>>&
+      std::optional<std::vector<std::optional<AseDirectionConfiguration>>>&
           direction_configurations,
-      const std::optional<std::vector<std::optional<AseDirectionRequirement>>>&
-          requirements,
-      std::vector<std::optional<AseDirectionConfiguration>>&
+      const std::vector<std::optional<AseDirectionRequirement>>& requirements,
+      std::optional<std::vector<std::optional<AseDirectionConfiguration>>>&
           valid_direction_configurations);
   std::optional<LeAudioAseConfigurationSetting>
   getCapabilitiesMatchedAseConfigurationSettings(
@@ -157,6 +156,14 @@
       LeAudioBroadcastConfigurationSetting& setting,
       const IBluetoothAudioProvider::LeAudioDeviceCapabilities& capabilities);
   void getBroadcastSettings();
+  std::optional<LeAudioAseQosConfiguration> getDirectionQosConfiguration(
+      uint8_t direction,
+      const IBluetoothAudioProvider::LeAudioAseQosConfigurationRequirement&
+          qosRequirement,
+      std::vector<LeAudioAseConfigurationSetting>& ase_configuration_settings);
+  bool isSubgroupConfigurationMatchedContext(
+      AudioContext requirement_context,
+      LeAudioBroadcastSubgroupConfiguration configuration);
 };
 
 class LeAudioOffloadOutputAudioProvider : public LeAudioOffloadAudioProvider {
diff --git a/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp b/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
index 789e8a1..ec63831 100644
--- a/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
+++ b/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
@@ -58,6 +58,7 @@
 using aidl::android::hardware::bluetooth::audio::CodecSpecificCapabilitiesLtv;
 using aidl::android::hardware::bluetooth::audio::CodecSpecificConfigurationLtv;
 using aidl::android::hardware::bluetooth::audio::CodecType;
+using aidl::android::hardware::bluetooth::audio::ConfigurationFlags;
 using aidl::android::hardware::bluetooth::audio::HfpConfiguration;
 using aidl::android::hardware::bluetooth::audio::IBluetoothAudioPort;
 using aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider;
@@ -68,6 +69,7 @@
 using aidl::android::hardware::bluetooth::audio::LdacCapabilities;
 using aidl::android::hardware::bluetooth::audio::LdacConfiguration;
 using aidl::android::hardware::bluetooth::audio::LeAudioAseConfiguration;
+using aidl::android::hardware::bluetooth::audio::LeAudioBisConfiguration;
 using aidl::android::hardware::bluetooth::audio::LeAudioBroadcastConfiguration;
 using aidl::android::hardware::bluetooth::audio::
     LeAudioCodecCapabilitiesSetting;
@@ -105,12 +107,24 @@
     LeAudioAseConfigurationSetting::AseDirectionConfiguration;
 using AseQosDirectionRequirement = IBluetoothAudioProvider::
     LeAudioAseQosConfigurationRequirement::AseQosDirectionRequirement;
+using LeAudioAseQosConfigurationRequirement =
+    IBluetoothAudioProvider::LeAudioAseQosConfigurationRequirement;
 using LeAudioAseQosConfiguration =
     IBluetoothAudioProvider::LeAudioAseQosConfiguration;
 using LeAudioDeviceCapabilities =
     IBluetoothAudioProvider::LeAudioDeviceCapabilities;
 using LeAudioConfigurationRequirement =
     IBluetoothAudioProvider::LeAudioConfigurationRequirement;
+using LeAudioBroadcastConfigurationRequirement =
+    IBluetoothAudioProvider::LeAudioBroadcastConfigurationRequirement;
+using LeAudioBroadcastSubgroupConfiguration =
+    IBluetoothAudioProvider::LeAudioBroadcastSubgroupConfiguration;
+using LeAudioBroadcastSubgroupConfigurationRequirement =
+    IBluetoothAudioProvider::LeAudioBroadcastSubgroupConfigurationRequirement;
+using LeAudioBroadcastConfigurationSetting =
+    IBluetoothAudioProvider::LeAudioBroadcastConfigurationSetting;
+using LeAudioSubgroupBisConfiguration =
+    IBluetoothAudioProvider::LeAudioSubgroupBisConfiguration;
 
 // Constants
 
@@ -1944,6 +1958,7 @@
         BluetoothAudioHalVersion::VERSION_AIDL_V4) {
       GTEST_SKIP();
     }
+    GetProviderInfoHelper(SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH);
     OpenProviderHelper(SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH);
     // Can open or empty capability
     ASSERT_TRUE(temp_provider_capabilities_.empty() ||
@@ -2227,6 +2242,37 @@
     BluetoothAudioProviderFactoryAidl::TearDown();
   }
 
+  bool IsMultidirectionalCapabilitiesEnabled() {
+    if (!temp_provider_info_.has_value()) return false;
+
+    return temp_provider_info_.value().supportsMultidirectionalCapabilities;
+  }
+
+  bool IsAsymmetricConfigurationAllowed() {
+    if (!temp_provider_info_.has_value()) return false;
+    if (temp_provider_info_.value().codecInfos.empty()) return false;
+
+    for (auto& codec_info : temp_provider_info_.value().codecInfos) {
+      if (codec_info.transport.getTag() != CodecInfo::Transport::leAudio) {
+        return false;
+      }
+
+      auto flags =
+          codec_info.transport.get<CodecInfo::Transport::leAudio>().flags;
+
+      if (!flags) {
+        continue;
+      }
+
+      if (flags->bitmask &
+          ConfigurationFlags::ALLOW_ASYMMETRIC_CONFIGURATIONS) {
+        return true;
+      }
+    }
+
+    return false;
+  }
+
   bool IsOffloadOutputSupported() {
     for (auto& capability : temp_provider_capabilities_) {
       if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
@@ -2283,27 +2329,31 @@
     return media_audio_context;
   }
 
-  LeAudioDeviceCapabilities GetDefaultRemoteCapability() {
+  LeAudioDeviceCapabilities GetDefaultRemoteSinkCapability() {
     // Create a capability
     LeAudioDeviceCapabilities capability;
 
     capability.codecId = CodecId::Core::LC3;
 
     auto pref_context_metadata = MetadataLtv::PreferredAudioContexts();
-    pref_context_metadata.values = GetAudioContext(AudioContext::MEDIA);
+    pref_context_metadata.values =
+        GetAudioContext(AudioContext::MEDIA | AudioContext::CONVERSATIONAL |
+                        AudioContext::GAME);
     capability.metadata = {pref_context_metadata};
 
     auto sampling_rate =
         CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies();
     sampling_rate.bitmask =
+        CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ16000 |
         CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ8000;
     auto frame_duration =
         CodecSpecificCapabilitiesLtv::SupportedFrameDurations();
     frame_duration.bitmask =
-        CodecSpecificCapabilitiesLtv::SupportedFrameDurations::US7500;
+        CodecSpecificCapabilitiesLtv::SupportedFrameDurations::US7500 |
+        CodecSpecificCapabilitiesLtv::SupportedFrameDurations::US10000;
     auto octets = CodecSpecificCapabilitiesLtv::SupportedOctetsPerCodecFrame();
     octets.min = 0;
-    octets.max = 60;
+    octets.max = 120;
     auto frames = CodecSpecificCapabilitiesLtv::SupportedMaxCodecFramesPerSDU();
     frames.value = 2;
     capability.codecSpecificCapabilities = {sampling_rate, frame_duration,
@@ -2311,29 +2361,394 @@
     return capability;
   }
 
-  LeAudioConfigurationRequirement GetDefaultRequirement(
-      bool is_source_requriement) {
+  LeAudioDeviceCapabilities GetDefaultRemoteSourceCapability() {
+    // Create a capability
+    LeAudioDeviceCapabilities capability;
+
+    capability.codecId = CodecId::Core::LC3;
+
+    auto pref_context_metadata = MetadataLtv::PreferredAudioContexts();
+    pref_context_metadata.values =
+        GetAudioContext(AudioContext::LIVE_AUDIO |
+                        AudioContext::CONVERSATIONAL | AudioContext::GAME);
+    capability.metadata = {pref_context_metadata};
+
+    auto sampling_rate =
+        CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies();
+    sampling_rate.bitmask =
+        CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ16000 |
+        CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ8000;
+    auto frame_duration =
+        CodecSpecificCapabilitiesLtv::SupportedFrameDurations();
+    frame_duration.bitmask =
+        CodecSpecificCapabilitiesLtv::SupportedFrameDurations::US7500 |
+        CodecSpecificCapabilitiesLtv::SupportedFrameDurations::US10000;
+    auto octets = CodecSpecificCapabilitiesLtv::SupportedOctetsPerCodecFrame();
+    octets.min = 0;
+    octets.max = 120;
+    auto frames = CodecSpecificCapabilitiesLtv::SupportedMaxCodecFramesPerSDU();
+    frames.value = 2;
+    capability.codecSpecificCapabilities = {sampling_rate, frame_duration,
+                                            octets, frames};
+    return capability;
+  }
+
+  std::optional<CodecSpecificConfigurationLtv> GetConfigurationLtv(
+      const std::vector<CodecSpecificConfigurationLtv>& configurationLtvs,
+      CodecSpecificConfigurationLtv::Tag tag) {
+    for (const auto ltv : configurationLtvs) {
+      if (ltv.getTag() == tag) {
+        return ltv;
+      }
+    }
+    return std::nullopt;
+  }
+
+  bool IsAseRequirementSatisfiedWithUnknownChannelCount(
+      const std::vector<std::optional<AseDirectionRequirement>>&
+          ase_requirements,
+      const std::vector<std::optional<AseDirectionConfiguration>>&
+          ase_configurations) {
+    /* This is mandatory  to match sample freq, allocation however, when in the
+     * device group there is only one device which supports left and right
+     * allocation, and channel count is hidden from the BT stack, the BT stack
+     * will send single requirement but it can receive two configurations if the
+     * channel count is 1.
+     */
+
+    int num_of_ase_requirements = 0;
+    for (const auto& ase_req : ase_requirements) {
+      auto required_allocation_ltv = GetConfigurationLtv(
+          ase_req->aseConfiguration.codecConfiguration,
+          CodecSpecificConfigurationLtv::Tag::audioChannelAllocation);
+      if (required_allocation_ltv == std::nullopt) {
+        continue;
+      }
+      int required_allocation =
+          required_allocation_ltv
+              ->get<
+                  CodecSpecificConfigurationLtv::Tag::audioChannelAllocation>()
+              .bitmask;
+      num_of_ase_requirements += std::bitset<32>(required_allocation).count();
+    }
+
+    int num_of_satisfied_ase_requirements = 0;
+    for (const auto& ase_req : ase_requirements) {
+      if (!ase_req) {
+        continue;
+      }
+      auto required_sample_freq_ltv = GetConfigurationLtv(
+          ase_req->aseConfiguration.codecConfiguration,
+          CodecSpecificConfigurationLtv::Tag::samplingFrequency);
+      auto required_allocation_ltv = GetConfigurationLtv(
+          ase_req->aseConfiguration.codecConfiguration,
+          CodecSpecificConfigurationLtv::Tag::audioChannelAllocation);
+
+      /* Allocation and sample freq shall be always in the requirement */
+      if (!required_sample_freq_ltv || !required_allocation_ltv) {
+        return false;
+      }
+
+      int required_allocation =
+          required_allocation_ltv
+              ->get<
+                  CodecSpecificConfigurationLtv::Tag::audioChannelAllocation>()
+              .bitmask;
+
+      for (const auto& ase_conf : ase_configurations) {
+        if (!ase_conf) {
+          continue;
+        }
+        auto config_sample_freq_ltv = GetConfigurationLtv(
+            ase_conf->aseConfiguration.codecConfiguration,
+            CodecSpecificConfigurationLtv::Tag::samplingFrequency);
+        auto config_allocation_ltv = GetConfigurationLtv(
+            ase_conf->aseConfiguration.codecConfiguration,
+            CodecSpecificConfigurationLtv::Tag::audioChannelAllocation);
+        if (config_sample_freq_ltv == std::nullopt ||
+            config_allocation_ltv == std::nullopt) {
+          return false;
+        }
+
+        int configured_allocation = config_allocation_ltv
+                                        ->get<CodecSpecificConfigurationLtv::
+                                                  Tag::audioChannelAllocation>()
+                                        .bitmask;
+
+        if (config_sample_freq_ltv == required_sample_freq_ltv &&
+            (required_allocation & configured_allocation)) {
+          num_of_satisfied_ase_requirements +=
+              std::bitset<32>(configured_allocation).count();
+        }
+      }
+    }
+
+    return (num_of_satisfied_ase_requirements == num_of_ase_requirements);
+  }
+
+  bool IsAseRequirementSatisfied(
+      const std::vector<std::optional<AseDirectionRequirement>>&
+          ase_requirements,
+      const std::vector<std::optional<AseDirectionConfiguration>>&
+          ase_configurations) {
+    // This is mandatory  to match sample freq, allocation
+    int num_of_satisfied_ase_requirements = 0;
+
+    int required_allocations = 0;
+    for (const auto& ase_req : ase_requirements) {
+      auto required_allocation_ltv = GetConfigurationLtv(
+          ase_req->aseConfiguration.codecConfiguration,
+          CodecSpecificConfigurationLtv::Tag::audioChannelAllocation);
+      if (required_allocation_ltv == std::nullopt) {
+        continue;
+      }
+
+      int allocations =
+          required_allocation_ltv
+              ->get<
+                  CodecSpecificConfigurationLtv::Tag::audioChannelAllocation>()
+              .bitmask;
+      required_allocations += std::bitset<32>(allocations).count();
+    }
+
+    if (ase_requirements.size() != required_allocations) {
+      /* If more than one allication is requested in the requirement, then use
+       * different verifier */
+      return IsAseRequirementSatisfiedWithUnknownChannelCount(
+          ase_requirements, ase_configurations);
+    }
+
+    for (const auto& ase_req : ase_requirements) {
+      if (!ase_req) {
+        continue;
+      }
+      auto required_sample_freq_ltv = GetConfigurationLtv(
+          ase_req->aseConfiguration.codecConfiguration,
+          CodecSpecificConfigurationLtv::Tag::samplingFrequency);
+      auto required_allocation_ltv = GetConfigurationLtv(
+          ase_req->aseConfiguration.codecConfiguration,
+          CodecSpecificConfigurationLtv::Tag::audioChannelAllocation);
+
+      /* Allocation and sample freq shall be always in the requirement */
+      if (!required_sample_freq_ltv || !required_allocation_ltv) {
+        return false;
+      }
+
+      for (const auto& ase_conf : ase_configurations) {
+        if (!ase_conf) {
+          continue;
+        }
+        auto config_sample_freq_ltv = GetConfigurationLtv(
+            ase_conf->aseConfiguration.codecConfiguration,
+            CodecSpecificConfigurationLtv::Tag::samplingFrequency);
+        auto config_allocation_ltv = GetConfigurationLtv(
+            ase_conf->aseConfiguration.codecConfiguration,
+            CodecSpecificConfigurationLtv::Tag::audioChannelAllocation);
+        if (config_sample_freq_ltv == std::nullopt ||
+            config_allocation_ltv == std::nullopt) {
+          return false;
+        }
+
+        if (config_sample_freq_ltv == required_sample_freq_ltv &&
+            config_allocation_ltv == required_allocation_ltv) {
+          num_of_satisfied_ase_requirements++;
+          break;
+        }
+      }
+    }
+
+    return (num_of_satisfied_ase_requirements == ase_requirements.size());
+  }
+
+  void VerifyIfRequirementsSatisfied(
+      const std::vector<LeAudioConfigurationRequirement>& requirements,
+      const std::vector<LeAudioAseConfigurationSetting>& configurations) {
+    if (requirements.empty() && configurations.empty()) {
+      return;
+    }
+
+    /* It might happen that vendor lib will provide same configuration for
+     * multiple contexts and it should be accepted
+     */
+
+    int num_of_requirements = 0;
+    for (const auto& req : requirements) {
+      num_of_requirements += std::bitset<32>(req.audioContext.bitmask).count();
+    }
+
+    int num_of_configurations = 0;
+    for (const auto& conf : configurations) {
+      num_of_configurations +=
+          std::bitset<32>(conf.audioContext.bitmask).count();
+    }
+
+    ASSERT_EQ(num_of_requirements, num_of_configurations);
+
+    int num_of_satisfied_requirements = 0;
+    for (const auto& req : requirements) {
+      for (const auto& conf : configurations) {
+        if ((req.audioContext.bitmask & conf.audioContext.bitmask) !=
+            req.audioContext.bitmask) {
+          continue;
+        }
+
+        if (req.sinkAseRequirement && req.sourceAseRequirement) {
+          if (!conf.sinkAseConfiguration || !conf.sourceAseConfiguration) {
+            continue;
+          }
+
+          if (!IsAseRequirementSatisfied(*req.sinkAseRequirement,
+                                         *conf.sinkAseConfiguration) ||
+              !IsAseRequirementSatisfied(*req.sourceAseRequirement,
+                                         *conf.sourceAseConfiguration)) {
+            continue;
+          }
+          num_of_satisfied_requirements +=
+              std::bitset<32>(req.audioContext.bitmask).count();
+
+          break;
+        } else if (req.sinkAseRequirement) {
+          if (!IsAseRequirementSatisfied(*req.sinkAseRequirement,
+                                         *conf.sinkAseConfiguration)) {
+            continue;
+          }
+          num_of_satisfied_requirements +=
+              std::bitset<32>(req.audioContext.bitmask).count();
+          break;
+        } else if (req.sourceAseRequirement) {
+          if (!IsAseRequirementSatisfied(*req.sourceAseRequirement,
+                                         *conf.sourceAseConfiguration)) {
+            continue;
+          }
+          num_of_satisfied_requirements +=
+              std::bitset<32>(req.audioContext.bitmask).count();
+          break;
+        }
+      }
+    }
+    ASSERT_EQ(num_of_satisfied_requirements, num_of_requirements);
+  }
+
+  LeAudioConfigurationRequirement GetUnicastDefaultRequirement(
+      int32_t context_bits, bool is_sink_requirement,
+      bool is_source_requriement,
+      CodecSpecificConfigurationLtv::SamplingFrequency freq =
+          CodecSpecificConfigurationLtv::SamplingFrequency::HZ16000) {
     // Create a requirements
     LeAudioConfigurationRequirement requirement;
-    requirement.audioContext = GetAudioContext(AudioContext::MEDIA);
+    requirement.audioContext = GetAudioContext(context_bits);
+
+    auto allocation = CodecSpecificConfigurationLtv::AudioChannelAllocation();
+    allocation.bitmask =
+        CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_LEFT |
+        CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_RIGHT;
 
     auto direction_ase_requriement = AseDirectionRequirement();
     direction_ase_requriement.aseConfiguration.codecId = CodecId::Core::LC3;
     direction_ase_requriement.aseConfiguration.targetLatency =
         LeAudioAseConfiguration::TargetLatency::BALANCED_LATENCY_RELIABILITY;
 
-    // Mismatch sampling frequency
     direction_ase_requriement.aseConfiguration.codecConfiguration = {
-        CodecSpecificConfigurationLtv::SamplingFrequency::HZ11025,
-        CodecSpecificConfigurationLtv::FrameDuration::US7500,
+        freq, CodecSpecificConfigurationLtv::FrameDuration::US10000, allocation
+
     };
+    if (is_sink_requirement)
+      requirement.sinkAseRequirement = {direction_ase_requriement};
+
     if (is_source_requriement)
       requirement.sourceAseRequirement = {direction_ase_requriement};
-    else
-      requirement.sinkAseRequirement = {direction_ase_requriement};
+
     return requirement;
   }
 
+  LeAudioConfigurationRequirement GetUnicastGameRequirement(bool asymmetric) {
+    // Create a requirements
+    LeAudioConfigurationRequirement requirement;
+    requirement.audioContext = GetAudioContext(AudioContext::GAME);
+
+    auto allocation = CodecSpecificConfigurationLtv::AudioChannelAllocation();
+    allocation.bitmask =
+        CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_LEFT |
+        CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_RIGHT;
+
+    auto sink_ase_requriement = AseDirectionRequirement();
+    sink_ase_requriement.aseConfiguration.codecId = CodecId::Core::LC3;
+    sink_ase_requriement.aseConfiguration.targetLatency =
+        LeAudioAseConfiguration::TargetLatency::BALANCED_LATENCY_RELIABILITY;
+
+    sink_ase_requriement.aseConfiguration.codecConfiguration = {
+        CodecSpecificConfigurationLtv::SamplingFrequency::HZ16000,
+        CodecSpecificConfigurationLtv::FrameDuration::US10000, allocation};
+
+    auto source_ase_requriement = AseDirectionRequirement();
+    source_ase_requriement.aseConfiguration.codecId = CodecId::Core::LC3;
+    source_ase_requriement.aseConfiguration.targetLatency =
+        LeAudioAseConfiguration::TargetLatency::BALANCED_LATENCY_RELIABILITY;
+
+    if (asymmetric) {
+      source_ase_requriement.aseConfiguration.codecConfiguration = {
+          CodecSpecificConfigurationLtv::SamplingFrequency::HZ8000,
+          CodecSpecificConfigurationLtv::FrameDuration::US10000, allocation};
+    } else {
+      source_ase_requriement.aseConfiguration.codecConfiguration = {
+          CodecSpecificConfigurationLtv::SamplingFrequency::HZ16000,
+          CodecSpecificConfigurationLtv::FrameDuration::US10000, allocation};
+    }
+
+    requirement.sinkAseRequirement = {sink_ase_requriement};
+    requirement.sourceAseRequirement = {source_ase_requriement};
+
+    return requirement;
+  }
+
+  LeAudioAseQosConfigurationRequirement GetQosRequirements(
+      bool is_sink_requirement, bool is_source_requriement, bool valid = true) {
+    LeAudioAseQosConfigurationRequirement qosRequirement;
+
+    auto allocation = CodecSpecificConfigurationLtv::AudioChannelAllocation();
+    allocation.bitmask =
+        CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_LEFT |
+        CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_RIGHT;
+
+    AseQosDirectionRequirement directionalRequirement = {
+        .framing = IBluetoothAudioProvider::Framing::UNFRAMED,
+        .preferredRetransmissionNum = 2,
+        .maxTransportLatencyMs = 10,
+        .presentationDelayMinUs = 40000,
+        .presentationDelayMaxUs = 40000,
+        .aseConfiguration =
+            {
+                .targetLatency = LeAudioAseConfiguration::TargetLatency::
+                    BALANCED_LATENCY_RELIABILITY,
+                .codecId = CodecId::Core::LC3,
+                .codecConfiguration =
+                    {CodecSpecificConfigurationLtv::SamplingFrequency::HZ16000,
+                     CodecSpecificConfigurationLtv::FrameDuration::US10000,
+                     allocation},
+            },
+    };
+
+    if (!valid) {
+      // clear some required values;
+      directionalRequirement.maxTransportLatencyMs = 0;
+      directionalRequirement.presentationDelayMaxUs = 0;
+    }
+
+    qosRequirement.sinkAseQosRequirement = directionalRequirement;
+    if (is_source_requriement && is_sink_requirement) {
+      qosRequirement.sourceAseQosRequirement = directionalRequirement;
+      qosRequirement.sinkAseQosRequirement = directionalRequirement;
+    } else if (is_source_requriement) {
+      qosRequirement.sourceAseQosRequirement = directionalRequirement;
+      qosRequirement.sinkAseQosRequirement = std::nullopt;
+    } else if (is_sink_requirement) {
+      qosRequirement.sourceAseQosRequirement = std::nullopt;
+      qosRequirement.sinkAseQosRequirement = directionalRequirement;
+    }
+
+    return qosRequirement;
+  }
+
   std::vector<Lc3Configuration> GetUnicastLc3SupportedList(bool decoding,
                                                            bool supported) {
     std::vector<Lc3Configuration> le_audio_codec_configs;
@@ -2459,6 +2874,11 @@
       AudioContext::NOTIFICATIONS, AudioContext::RINGTONE_ALERTS,
       AudioContext::ALERTS,        AudioContext::EMERGENCY_ALARM,
   };
+
+  AudioContext bidirectional_contexts = {
+      .bitmask = AudioContext::CONVERSATIONAL | AudioContext::GAME |
+                 AudioContext::VOICE_ASSISTANTS | AudioContext::LIVE_AUDIO,
+  };
 };
 
 /**
@@ -2510,6 +2930,40 @@
       BluetoothAudioHalVersion::VERSION_AIDL_V4) {
     GTEST_SKIP();
   }
+
+  if (IsMultidirectionalCapabilitiesEnabled()) {
+    GTEST_SKIP();
+  }
+
+  std::vector<std::optional<LeAudioDeviceCapabilities>> empty_capability;
+  std::vector<LeAudioConfigurationRequirement> empty_requirement;
+  std::vector<LeAudioAseConfigurationSetting> configurations;
+
+  // Check empty capability for source direction
+  auto aidl_retval = audio_provider_->getLeAudioAseConfiguration(
+      std::nullopt, empty_capability, empty_requirement, &configurations);
+
+  ASSERT_FALSE(aidl_retval.isOk());
+
+  // Check empty capability for sink direction
+  aidl_retval = audio_provider_->getLeAudioAseConfiguration(
+      empty_capability, std::nullopt, empty_requirement, &configurations);
+
+  ASSERT_TRUE(aidl_retval.isOk());
+  ASSERT_TRUE(configurations.empty());
+}
+
+TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
+       GetEmptyAseConfigurationEmptyCapability_Multidirectiona) {
+  if (GetProviderFactoryInterfaceVersion() <
+      BluetoothAudioHalVersion::VERSION_AIDL_V4) {
+    GTEST_SKIP();
+  }
+
+  if (!IsMultidirectionalCapabilitiesEnabled()) {
+    GTEST_SKIP();
+  }
+
   std::vector<std::optional<LeAudioDeviceCapabilities>> empty_capability;
   std::vector<LeAudioConfigurationRequirement> empty_requirement;
   std::vector<LeAudioAseConfigurationSetting> configurations;
@@ -2535,50 +2989,388 @@
       BluetoothAudioHalVersion::VERSION_AIDL_V4) {
     GTEST_SKIP();
   }
-  std::vector<std::optional<LeAudioDeviceCapabilities>> capabilities = {
-      GetDefaultRemoteCapability()};
+  std::vector<std::optional<LeAudioDeviceCapabilities>> sink_capabilities = {
+      GetDefaultRemoteSinkCapability()};
+  std::vector<std::optional<LeAudioDeviceCapabilities>> source_capabilities = {
+      GetDefaultRemoteSourceCapability()};
+
+  auto not_supported_sampling_rate_by_remote =
+      CodecSpecificConfigurationLtv::SamplingFrequency::HZ11025;
 
   // Check empty capability for source direction
   std::vector<LeAudioAseConfigurationSetting> configurations;
   std::vector<LeAudioConfigurationRequirement> source_requirements = {
-      GetDefaultRequirement(true)};
+      GetUnicastDefaultRequirement(AudioContext::LIVE_AUDIO, false /*sink */,
+                                   true /* source */,
+                                   not_supported_sampling_rate_by_remote)};
   auto aidl_retval = audio_provider_->getLeAudioAseConfiguration(
-      std::nullopt, capabilities, source_requirements, &configurations);
+      std::nullopt, source_capabilities, source_requirements, &configurations);
 
   ASSERT_TRUE(aidl_retval.isOk());
   ASSERT_TRUE(configurations.empty());
 
   // Check empty capability for sink direction
   std::vector<LeAudioConfigurationRequirement> sink_requirements = {
-      GetDefaultRequirement(false)};
+      GetUnicastDefaultRequirement(AudioContext::MEDIA, true /*sink */,
+                                   false /* source */,
+                                   not_supported_sampling_rate_by_remote)};
   aidl_retval = audio_provider_->getLeAudioAseConfiguration(
-      capabilities, std::nullopt, source_requirements, &configurations);
+      sink_capabilities, std::nullopt, sink_requirements, &configurations);
 
   ASSERT_TRUE(aidl_retval.isOk());
   ASSERT_TRUE(configurations.empty());
 }
 
+TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl, GetAseConfiguration) {
+  if (GetProviderFactoryInterfaceVersion() <
+      BluetoothAudioHalVersion::VERSION_AIDL_V4) {
+    GTEST_SKIP();
+  }
+
+  if (IsMultidirectionalCapabilitiesEnabled()) {
+    GTEST_SKIP();
+  }
+
+  std::vector<std::optional<LeAudioDeviceCapabilities>> sink_capabilities = {
+      GetDefaultRemoteSinkCapability()};
+  std::vector<std::optional<LeAudioDeviceCapabilities>> source_capabilities = {
+      GetDefaultRemoteSourceCapability()};
+
+  // Should not ask for Source on ENCODING session if Multidiretional not
+  // supported
+  std::vector<LeAudioAseConfigurationSetting> configurations;
+  std::vector<LeAudioConfigurationRequirement> source_requirements = {
+      GetUnicastDefaultRequirement(AudioContext::LIVE_AUDIO, false /* sink */,
+                                   true /* source */)};
+  auto aidl_retval = audio_provider_->getLeAudioAseConfiguration(
+      std::nullopt, source_capabilities, source_requirements, &configurations);
+
+  ASSERT_FALSE(aidl_retval.isOk());
+  ASSERT_TRUE(configurations.empty());
+
+  // Check capability for remote sink direction
+  std::vector<LeAudioConfigurationRequirement> sink_requirements = {
+      GetUnicastDefaultRequirement(AudioContext::MEDIA, true /* sink */,
+                                   false /* source */)};
+  aidl_retval = audio_provider_->getLeAudioAseConfiguration(
+      sink_capabilities, std::nullopt, sink_requirements, &configurations);
+
+  ASSERT_TRUE(aidl_retval.isOk());
+  ASSERT_FALSE(configurations.empty());
+  VerifyIfRequirementsSatisfied(sink_requirements, configurations);
+
+  // Check multiple capability for remote sink direction
+  std::vector<LeAudioConfigurationRequirement> multi_sink_requirements = {
+      GetUnicastDefaultRequirement(AudioContext::MEDIA, true /* sink */,
+                                   false /* source */),
+      GetUnicastDefaultRequirement(AudioContext::CONVERSATIONAL,
+                                   true /* sink */, false /* source */)};
+  aidl_retval = audio_provider_->getLeAudioAseConfiguration(
+      sink_capabilities, std::nullopt, multi_sink_requirements,
+      &configurations);
+
+  ASSERT_TRUE(aidl_retval.isOk());
+  ASSERT_FALSE(configurations.empty());
+  VerifyIfRequirementsSatisfied(multi_sink_requirements, configurations);
+
+  // Check multiple context types in a single requirement.
+  std::vector<LeAudioConfigurationRequirement> multi_context_sink_requirements =
+      {GetUnicastDefaultRequirement(
+          AudioContext::MEDIA | AudioContext::SOUND_EFFECTS, true /* sink */,
+          false /* source */)};
+  aidl_retval = audio_provider_->getLeAudioAseConfiguration(
+      sink_capabilities, std::nullopt, multi_context_sink_requirements,
+      &configurations);
+
+  ASSERT_TRUE(aidl_retval.isOk());
+  ASSERT_FALSE(configurations.empty());
+  VerifyIfRequirementsSatisfied(multi_sink_requirements, configurations);
+}
+
+TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
+       GetAseConfiguration_Multidirectional) {
+  if (GetProviderFactoryInterfaceVersion() <
+      BluetoothAudioHalVersion::VERSION_AIDL_V4) {
+    GTEST_SKIP();
+  }
+
+  if (!IsMultidirectionalCapabilitiesEnabled()) {
+    GTEST_SKIP();
+  }
+
+  std::vector<std::optional<LeAudioDeviceCapabilities>> sink_capabilities = {
+      GetDefaultRemoteSinkCapability()};
+  std::vector<std::optional<LeAudioDeviceCapabilities>> source_capabilities = {
+      GetDefaultRemoteSourceCapability()};
+
+  // Verify source configuration is received
+  std::vector<LeAudioAseConfigurationSetting> configurations;
+  std::vector<LeAudioConfigurationRequirement> source_requirements = {
+      GetUnicastDefaultRequirement(AudioContext::LIVE_AUDIO, false /* sink */,
+                                   true /* source */)};
+  auto aidl_retval = audio_provider_->getLeAudioAseConfiguration(
+      std::nullopt, source_capabilities, source_requirements, &configurations);
+
+  ASSERT_TRUE(aidl_retval.isOk());
+  ASSERT_FALSE(configurations.empty());
+  VerifyIfRequirementsSatisfied(source_requirements, configurations);
+
+  // Verify sink configuration is received
+  std::vector<LeAudioConfigurationRequirement> sink_requirements = {
+      GetUnicastDefaultRequirement(AudioContext::MEDIA, true /* sink */,
+                                   false /* source */)};
+  aidl_retval = audio_provider_->getLeAudioAseConfiguration(
+      sink_capabilities, std::nullopt, sink_requirements, &configurations);
+
+  ASSERT_TRUE(aidl_retval.isOk());
+  ASSERT_FALSE(configurations.empty());
+  VerifyIfRequirementsSatisfied(sink_requirements, configurations);
+
+  std::vector<LeAudioConfigurationRequirement> combined_requirements = {
+      GetUnicastDefaultRequirement(AudioContext::LIVE_AUDIO, false /* sink */,
+                                   true /* source */),
+      GetUnicastDefaultRequirement(AudioContext::CONVERSATIONAL,
+                                   true /* sink */, true /* source */),
+      GetUnicastDefaultRequirement(AudioContext::MEDIA, true /* sink */,
+                                   false /* source */)};
+
+  aidl_retval = audio_provider_->getLeAudioAseConfiguration(
+      sink_capabilities, source_capabilities, combined_requirements,
+      &configurations);
+
+  ASSERT_TRUE(aidl_retval.isOk());
+  ASSERT_FALSE(configurations.empty());
+  VerifyIfRequirementsSatisfied(combined_requirements, configurations);
+}
+
+TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
+       GetAsymmetricAseConfiguration_Multidirectional) {
+  if (GetProviderFactoryInterfaceVersion() <
+      BluetoothAudioHalVersion::VERSION_AIDL_V4) {
+    GTEST_SKIP();
+  }
+
+  if (!IsMultidirectionalCapabilitiesEnabled()) {
+    GTEST_SKIP();
+  }
+
+  if (!IsAsymmetricConfigurationAllowed()) {
+    GTEST_SKIP();
+  }
+
+  std::vector<LeAudioAseConfigurationSetting> configurations;
+  std::vector<std::optional<LeAudioDeviceCapabilities>> sink_capabilities = {
+      GetDefaultRemoteSinkCapability()};
+  std::vector<std::optional<LeAudioDeviceCapabilities>> source_capabilities = {
+      GetDefaultRemoteSourceCapability()};
+
+  std::vector<LeAudioConfigurationRequirement> asymmetric_requirements = {
+      GetUnicastGameRequirement(true /* Asymmetric */)};
+
+  auto aidl_retval = audio_provider_->getLeAudioAseConfiguration(
+      sink_capabilities, source_capabilities, asymmetric_requirements,
+      &configurations);
+
+  ASSERT_TRUE(aidl_retval.isOk());
+  ASSERT_FALSE(configurations.empty());
+  VerifyIfRequirementsSatisfied(asymmetric_requirements, configurations);
+}
+
+TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
+       GetQoSConfiguration_Multidirectional) {
+  if (GetProviderFactoryInterfaceVersion() <
+      BluetoothAudioHalVersion::VERSION_AIDL_V4) {
+    GTEST_SKIP();
+  }
+
+  if (!IsMultidirectionalCapabilitiesEnabled()) {
+    GTEST_SKIP();
+  }
+
+  auto allocation = CodecSpecificConfigurationLtv::AudioChannelAllocation();
+  allocation.bitmask =
+      CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_LEFT |
+      CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_RIGHT;
+
+  LeAudioAseQosConfigurationRequirement requirement =
+      GetQosRequirements(true, true);
+
+  std::vector<IBluetoothAudioProvider::LeAudioAseQosConfiguration>
+      QoSConfigurations;
+  bool is_supported = false;
+  for (auto bitmask : all_context_bitmasks) {
+    requirement.audioContext = GetAudioContext(bitmask);
+    bool is_bidirectional = bidirectional_contexts.bitmask & bitmask;
+
+    if (is_bidirectional) {
+      requirement.sourceAseQosRequirement = requirement.sinkAseQosRequirement;
+    } else {
+      requirement.sourceAseQosRequirement = std::nullopt;
+    }
+
+    IBluetoothAudioProvider::LeAudioAseQosConfigurationPair result;
+    auto aidl_retval =
+        audio_provider_->getLeAudioAseQosConfiguration(requirement, &result);
+    if (!aidl_retval.isOk()) {
+      // If not OK, then it could be not supported, as it is an optional
+      // feature
+      ASSERT_EQ(aidl_retval.getExceptionCode(), EX_UNSUPPORTED_OPERATION);
+    }
+
+    is_supported = true;
+    if (result.sinkQosConfiguration.has_value()) {
+      if (is_bidirectional) {
+        ASSERT_TRUE(result.sourceQosConfiguration.has_value());
+      } else {
+        ASSERT_FALSE(result.sourceQosConfiguration.has_value());
+      }
+      QoSConfigurations.push_back(result.sinkQosConfiguration.value());
+    }
+  }
+  if (is_supported) {
+    // QoS Configurations should not be empty, as we searched for all contexts
+    ASSERT_FALSE(QoSConfigurations.empty());
+  }
+}
+
+TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
+       GetQoSConfiguration_InvalidRequirements) {
+  if (GetProviderFactoryInterfaceVersion() <
+      BluetoothAudioHalVersion::VERSION_AIDL_V4) {
+    GTEST_SKIP();
+  }
+  auto allocation = CodecSpecificConfigurationLtv::AudioChannelAllocation();
+  allocation.bitmask =
+      CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_LEFT |
+      CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_RIGHT;
+
+  LeAudioAseQosConfigurationRequirement invalid_requirement =
+      GetQosRequirements(true /* sink */, false /* source */,
+                         false /* valid */);
+
+  std::vector<IBluetoothAudioProvider::LeAudioAseQosConfiguration>
+      QoSConfigurations;
+  for (auto bitmask : all_context_bitmasks) {
+    invalid_requirement.audioContext = GetAudioContext(bitmask);
+    IBluetoothAudioProvider::LeAudioAseQosConfigurationPair result;
+    auto aidl_retval = audio_provider_->getLeAudioAseQosConfiguration(
+        invalid_requirement, &result);
+    ASSERT_FALSE(aidl_retval.isOk());
+  }
+}
+
 TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl, GetQoSConfiguration) {
   if (GetProviderFactoryInterfaceVersion() <
       BluetoothAudioHalVersion::VERSION_AIDL_V4) {
     GTEST_SKIP();
   }
+  auto allocation = CodecSpecificConfigurationLtv::AudioChannelAllocation();
+  allocation.bitmask =
+      CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_LEFT |
+      CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_RIGHT;
+
   IBluetoothAudioProvider::LeAudioAseQosConfigurationRequirement requirement;
+  requirement = GetQosRequirements(true /* sink */, false /* source */);
+
   std::vector<IBluetoothAudioProvider::LeAudioAseQosConfiguration>
       QoSConfigurations;
+  bool is_supported = false;
   for (auto bitmask : all_context_bitmasks) {
     requirement.audioContext = GetAudioContext(bitmask);
     IBluetoothAudioProvider::LeAudioAseQosConfigurationPair result;
     auto aidl_retval =
         audio_provider_->getLeAudioAseQosConfiguration(requirement, &result);
-    ASSERT_TRUE(aidl_retval.isOk());
-    if (result.sinkQosConfiguration.has_value())
-      QoSConfigurations.push_back(result.sinkQosConfiguration.value());
-    if (result.sourceQosConfiguration.has_value())
-      QoSConfigurations.push_back(result.sourceQosConfiguration.value());
+    if (!aidl_retval.isOk()) {
+      // If not OK, then it could be not supported, as it is an optional
+      // feature
+      ASSERT_EQ(aidl_retval.getExceptionCode(), EX_UNSUPPORTED_OPERATION);
+    } else {
+      is_supported = true;
+      if (result.sinkQosConfiguration.has_value()) {
+        QoSConfigurations.push_back(result.sinkQosConfiguration.value());
+      }
+    }
   }
-  // QoS Configurations should not be empty, as we searched for all contexts
-  ASSERT_FALSE(QoSConfigurations.empty());
+
+  if (is_supported) {
+    // QoS Configurations should not be empty, as we searched for all contexts
+    ASSERT_FALSE(QoSConfigurations.empty());
+  }
+}
+
+TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
+       GetDataPathConfiguration_Multidirectional) {
+  IBluetoothAudioProvider::StreamConfig sink_requirement;
+  IBluetoothAudioProvider::StreamConfig source_requirement;
+  std::vector<IBluetoothAudioProvider::LeAudioDataPathConfiguration>
+      DataPathConfigurations;
+
+  if (!IsMultidirectionalCapabilitiesEnabled()) {
+    GTEST_SKIP();
+  }
+
+  bool is_supported = false;
+  auto allocation = CodecSpecificConfigurationLtv::AudioChannelAllocation();
+  allocation.bitmask =
+      CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_LEFT |
+      CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_RIGHT;
+
+  auto streamMap = LeAudioConfiguration::StreamMap();
+
+  // Use some mandatory configuration
+  streamMap.streamHandle = 0x0001;
+  streamMap.audioChannelAllocation = 0x03;
+  streamMap.aseConfiguration = {
+      .targetLatency =
+          LeAudioAseConfiguration::TargetLatency::BALANCED_LATENCY_RELIABILITY,
+      .codecId = CodecId::Core::LC3,
+      .codecConfiguration =
+          {CodecSpecificConfigurationLtv::SamplingFrequency::HZ16000,
+           CodecSpecificConfigurationLtv::FrameDuration::US10000, allocation},
+  };
+
+  // Bidirectional
+  sink_requirement.streamMap = {streamMap};
+  source_requirement.streamMap = {streamMap};
+
+  for (auto bitmask : all_context_bitmasks) {
+    sink_requirement.audioContext = GetAudioContext(bitmask);
+    source_requirement.audioContext = sink_requirement.audioContext;
+
+    IBluetoothAudioProvider::LeAudioDataPathConfigurationPair result;
+    ::ndk::ScopedAStatus aidl_retval;
+
+    bool is_bidirectional = bidirectional_contexts.bitmask & bitmask;
+    if (is_bidirectional) {
+      aidl_retval = audio_provider_->getLeAudioAseDatapathConfiguration(
+          sink_requirement, source_requirement, &result);
+    } else {
+      aidl_retval = audio_provider_->getLeAudioAseDatapathConfiguration(
+          sink_requirement, std::nullopt, &result);
+    }
+
+    if (!aidl_retval.isOk()) {
+      // If not OK, then it could be not supported, as it is an optional
+      // feature
+      ASSERT_EQ(aidl_retval.getExceptionCode(), EX_UNSUPPORTED_OPERATION);
+    } else {
+      is_supported = true;
+      if (result.outputConfig.has_value()) {
+        if (is_bidirectional) {
+          ASSERT_TRUE(result.inputConfig.has_value());
+        } else {
+          ASSERT_TRUE(!result.inputConfig.has_value());
+        }
+        DataPathConfigurations.push_back(result.outputConfig.value());
+      }
+    }
+  }
+
+  if (is_supported) {
+    // Datapath Configurations should not be empty, as we searched for all
+    // contexts
+    ASSERT_FALSE(DataPathConfigurations.empty());
+  }
 }
 
 TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
@@ -2588,26 +3380,45 @@
     GTEST_SKIP();
   }
   IBluetoothAudioProvider::StreamConfig sink_requirement;
-  IBluetoothAudioProvider::StreamConfig source_requirement;
   std::vector<IBluetoothAudioProvider::LeAudioDataPathConfiguration>
       DataPathConfigurations;
   bool is_supported = false;
+  auto allocation = CodecSpecificConfigurationLtv::AudioChannelAllocation();
+  allocation.bitmask =
+      CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_LEFT |
+      CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_RIGHT;
+
+  auto streamMap = LeAudioConfiguration::StreamMap();
+
+  // Use some mandatory configuration
+  streamMap.streamHandle = 0x0001;
+  streamMap.audioChannelAllocation = 0x03;
+  streamMap.aseConfiguration = {
+      .targetLatency =
+          LeAudioAseConfiguration::TargetLatency::BALANCED_LATENCY_RELIABILITY,
+      .codecId = CodecId::Core::LC3,
+      .codecConfiguration =
+          {CodecSpecificConfigurationLtv::SamplingFrequency::HZ16000,
+           CodecSpecificConfigurationLtv::FrameDuration::US10000, allocation},
+  };
+
+  sink_requirement.streamMap = {streamMap};
 
   for (auto bitmask : all_context_bitmasks) {
     sink_requirement.audioContext = GetAudioContext(bitmask);
-    source_requirement.audioContext = GetAudioContext(bitmask);
     IBluetoothAudioProvider::LeAudioDataPathConfigurationPair result;
     auto aidl_retval = audio_provider_->getLeAudioAseDatapathConfiguration(
-        sink_requirement, source_requirement, &result);
+        sink_requirement, std::nullopt, &result);
+
     if (!aidl_retval.isOk()) {
-      // If not OK, then it could be not supported, as it is an optional feature
+      // If not OK, then it could be not supported, as it is an optional
+      // feature
       ASSERT_EQ(aidl_retval.getExceptionCode(), EX_UNSUPPORTED_OPERATION);
     } else {
       is_supported = true;
-      if (result.inputConfig.has_value())
-        DataPathConfigurations.push_back(result.inputConfig.value());
-      if (result.inputConfig.has_value())
-        DataPathConfigurations.push_back(result.inputConfig.value());
+      if (result.outputConfig.has_value()) {
+        DataPathConfigurations.push_back(result.outputConfig.value());
+      }
     }
   }
 
@@ -2654,10 +3465,9 @@
  * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
  * stopped with Unicast hardware encoding config
  *
- * Disabled since offload codec checking is not ready
  */
 TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
-       DISABLED_StartAndEndLeAudioOutputSessionWithInvalidAudioConfiguration) {
+       StartAndEndLeAudioOutputSessionWithInvalidAudioConfiguration) {
   if (!IsOffloadOutputSupported()) {
     GTEST_SKIP();
   }
@@ -2677,8 +3487,8 @@
         audio_port_, AudioConfiguration(le_audio_config), latency_modes,
         &mq_desc);
 
-    // AIDL call should fail on invalid codec
-    ASSERT_FALSE(aidl_retval.isOk());
+    // It is OK to start session with invalid configuration
+    ASSERT_TRUE(aidl_retval.isOk());
     EXPECT_TRUE(audio_provider_->endSession().isOk());
   }
 }
@@ -2757,8 +3567,8 @@
           audio_port_, AudioConfiguration(le_audio_config), latency_modes,
           &mq_desc);
 
-      // AIDL call should fail on invalid codec
-      ASSERT_FALSE(aidl_retval.isOk());
+      // It is OK to start session with invalid configuration
+      ASSERT_TRUE(aidl_retval.isOk());
       EXPECT_TRUE(audio_provider_->endSession().isOk());
     }
   }
@@ -2878,10 +3688,9 @@
  * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH can be started and
  * stopped with Unicast hardware encoding config
  *
- * Disabled since offload codec checking is not ready
  */
 TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
-       DISABLED_StartAndEndLeAudioInputSessionWithInvalidAudioConfiguration) {
+       StartAndEndLeAudioInputSessionWithInvalidAudioConfiguration) {
   if (!IsOffloadInputSupported()) {
     GTEST_SKIP();
   }
@@ -2902,12 +3711,229 @@
         audio_port_, AudioConfiguration(le_audio_config), latency_modes,
         &mq_desc);
 
-    // AIDL call should fail on invalid codec
-    ASSERT_FALSE(aidl_retval.isOk());
+    // It is OK to start with invalid configuration as it might be unknown on
+    // start
+    ASSERT_TRUE(aidl_retval.isOk());
     EXPECT_TRUE(audio_provider_->endSession().isOk());
   }
 }
 
+TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
+       GetEmptyAseConfigurationEmptyCapability) {
+  if (GetProviderFactoryInterfaceVersion() <
+      BluetoothAudioHalVersion::VERSION_AIDL_V4) {
+    GTEST_SKIP();
+  }
+
+  if (IsMultidirectionalCapabilitiesEnabled()) {
+    GTEST_SKIP();
+  }
+
+  std::vector<std::optional<LeAudioDeviceCapabilities>> empty_capability;
+  std::vector<LeAudioConfigurationRequirement> empty_requirement;
+  std::vector<LeAudioAseConfigurationSetting> configurations;
+
+  // Check success for source direction (Input == DecodingSession == remote
+  // source)
+  auto aidl_retval = audio_provider_->getLeAudioAseConfiguration(
+      std::nullopt, empty_capability, empty_requirement, &configurations);
+
+  ASSERT_TRUE(aidl_retval.isOk());
+  ASSERT_TRUE(configurations.empty());
+
+  // Check failure for sink direction
+  aidl_retval = audio_provider_->getLeAudioAseConfiguration(
+      empty_capability, std::nullopt, empty_requirement, &configurations);
+
+  ASSERT_FALSE(aidl_retval.isOk());
+}
+
+TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
+       GetEmptyAseConfigurationEmptyCapability_Multidirectional) {
+  if (GetProviderFactoryInterfaceVersion() <
+      BluetoothAudioHalVersion::VERSION_AIDL_V4) {
+    GTEST_SKIP();
+  }
+
+  if (!IsMultidirectionalCapabilitiesEnabled()) {
+    GTEST_SKIP();
+  }
+
+  std::vector<std::optional<LeAudioDeviceCapabilities>> empty_capability;
+  std::vector<LeAudioConfigurationRequirement> empty_requirement;
+  std::vector<LeAudioAseConfigurationSetting> configurations;
+
+  // Check empty capability for source direction
+  auto aidl_retval = audio_provider_->getLeAudioAseConfiguration(
+      std::nullopt, empty_capability, empty_requirement, &configurations);
+
+  ASSERT_TRUE(aidl_retval.isOk());
+  ASSERT_TRUE(configurations.empty());
+
+  // Check empty capability for sink direction
+  aidl_retval = audio_provider_->getLeAudioAseConfiguration(
+      empty_capability, std::nullopt, empty_requirement, &configurations);
+
+  ASSERT_TRUE(aidl_retval.isOk());
+  ASSERT_TRUE(configurations.empty());
+}
+
+TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl, GetAseConfiguration) {
+  if (GetProviderFactoryInterfaceVersion() <
+      BluetoothAudioHalVersion::VERSION_AIDL_V4) {
+    GTEST_SKIP();
+  }
+
+  if (IsMultidirectionalCapabilitiesEnabled()) {
+    GTEST_SKIP();
+  }
+
+  std::vector<std::optional<LeAudioDeviceCapabilities>> sink_capabilities = {
+      GetDefaultRemoteSinkCapability()};
+  std::vector<std::optional<LeAudioDeviceCapabilities>> source_capabilities = {
+      GetDefaultRemoteSourceCapability()};
+
+  // Check source configuration is received
+  std::vector<LeAudioAseConfigurationSetting> configurations;
+  std::vector<LeAudioConfigurationRequirement> source_requirements = {
+      GetUnicastDefaultRequirement(AudioContext::LIVE_AUDIO, false /* sink */,
+                                   true /* source */)};
+  auto aidl_retval = audio_provider_->getLeAudioAseConfiguration(
+      std::nullopt, source_capabilities, source_requirements, &configurations);
+
+  ASSERT_TRUE(aidl_retval.isOk());
+  ASSERT_FALSE(configurations.empty());
+
+  // Check error result when requesting sink on DECODING session
+  std::vector<LeAudioConfigurationRequirement> sink_requirements = {
+      GetUnicastDefaultRequirement(AudioContext::MEDIA, true /* sink */,
+                                   false /* source */)};
+  aidl_retval = audio_provider_->getLeAudioAseConfiguration(
+      sink_capabilities, std::nullopt, sink_requirements, &configurations);
+
+  ASSERT_FALSE(aidl_retval.isOk());
+}
+
+TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
+       GetAseConfiguration_Multidirectional) {
+  if (GetProviderFactoryInterfaceVersion() <
+      BluetoothAudioHalVersion::VERSION_AIDL_V4) {
+    GTEST_SKIP();
+  }
+
+  if (!IsMultidirectionalCapabilitiesEnabled()) {
+    GTEST_SKIP();
+  }
+
+  std::vector<std::optional<LeAudioDeviceCapabilities>> sink_capabilities = {
+      GetDefaultRemoteSinkCapability()};
+  std::vector<std::optional<LeAudioDeviceCapabilities>> source_capabilities = {
+      GetDefaultRemoteSourceCapability()};
+
+  // Check source configuration is received
+  std::vector<LeAudioAseConfigurationSetting> configurations;
+  std::vector<LeAudioConfigurationRequirement> source_requirements = {
+      GetUnicastDefaultRequirement(AudioContext::LIVE_AUDIO, false /* sink */,
+                                   true /* source */)};
+  auto aidl_retval = audio_provider_->getLeAudioAseConfiguration(
+      std::nullopt, source_capabilities, source_requirements, &configurations);
+
+  ASSERT_TRUE(aidl_retval.isOk());
+  ASSERT_FALSE(configurations.empty());
+  VerifyIfRequirementsSatisfied(source_requirements, configurations);
+
+  // Check empty capability for sink direction
+  std::vector<LeAudioConfigurationRequirement> sink_requirements = {
+      GetUnicastDefaultRequirement(AudioContext::MEDIA, true /* sink */,
+                                   false /* source */)};
+  aidl_retval = audio_provider_->getLeAudioAseConfiguration(
+      sink_capabilities, std::nullopt, sink_requirements, &configurations);
+
+  ASSERT_TRUE(aidl_retval.isOk());
+  ASSERT_FALSE(configurations.empty());
+  VerifyIfRequirementsSatisfied(sink_requirements, configurations);
+
+  std::vector<LeAudioConfigurationRequirement> combined_requirements = {
+      GetUnicastDefaultRequirement(AudioContext::LIVE_AUDIO, false /* sink */,
+                                   true /* source */),
+      GetUnicastDefaultRequirement(AudioContext::CONVERSATIONAL,
+                                   true /* sink */, true /* source */),
+      GetUnicastDefaultRequirement(AudioContext::MEDIA, true /* sink */,
+                                   false /* source */)};
+
+  aidl_retval = audio_provider_->getLeAudioAseConfiguration(
+      sink_capabilities, source_capabilities, combined_requirements,
+      &configurations);
+
+  ASSERT_TRUE(aidl_retval.isOk());
+  ASSERT_FALSE(configurations.empty());
+  VerifyIfRequirementsSatisfied(combined_requirements, configurations);
+}
+
+TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
+       GetQoSConfiguration_InvalidRequirements) {
+  if (GetProviderFactoryInterfaceVersion() <
+      BluetoothAudioHalVersion::VERSION_AIDL_V4) {
+    GTEST_SKIP();
+  }
+  auto allocation = CodecSpecificConfigurationLtv::AudioChannelAllocation();
+  allocation.bitmask =
+      CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_LEFT |
+      CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_RIGHT;
+
+  LeAudioAseQosConfigurationRequirement invalid_requirement =
+      GetQosRequirements(false /* sink */, true /* source */,
+                         false /* valid */);
+
+  std::vector<IBluetoothAudioProvider::LeAudioAseQosConfiguration>
+      QoSConfigurations;
+  for (auto bitmask : all_context_bitmasks) {
+    invalid_requirement.audioContext = GetAudioContext(bitmask);
+    IBluetoothAudioProvider::LeAudioAseQosConfigurationPair result;
+    auto aidl_retval = audio_provider_->getLeAudioAseQosConfiguration(
+        invalid_requirement, &result);
+    ASSERT_FALSE(aidl_retval.isOk());
+  }
+}
+
+TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl, GetQoSConfiguration) {
+  if (GetProviderFactoryInterfaceVersion() <
+      BluetoothAudioHalVersion::VERSION_AIDL_V4) {
+    GTEST_SKIP();
+  }
+  auto allocation = CodecSpecificConfigurationLtv::AudioChannelAllocation();
+  allocation.bitmask =
+      CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_LEFT |
+      CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_RIGHT;
+
+  IBluetoothAudioProvider::LeAudioAseQosConfigurationRequirement requirement;
+  requirement = GetQosRequirements(false /* sink */, true /* source */);
+
+  std::vector<IBluetoothAudioProvider::LeAudioAseQosConfiguration>
+      QoSConfigurations;
+  bool is_supported = false;
+  for (auto bitmask : all_context_bitmasks) {
+    requirement.audioContext = GetAudioContext(bitmask);
+    IBluetoothAudioProvider::LeAudioAseQosConfigurationPair result;
+    auto aidl_retval =
+        audio_provider_->getLeAudioAseQosConfiguration(requirement, &result);
+    if (!aidl_retval.isOk()) {
+      // If not OK, then it could be not supported, as it is an optional
+      // feature
+      ASSERT_EQ(aidl_retval.getExceptionCode(), EX_UNSUPPORTED_OPERATION);
+    } else {
+      is_supported = true;
+      if (result.sourceQosConfiguration.has_value()) {
+        QoSConfigurations.push_back(result.sourceQosConfiguration.value());
+      }
+    }
+  }
+
+  if (is_supported) {
+    // QoS Configurations should not be empty, as we searched for all contexts
+    ASSERT_FALSE(QoSConfigurations.empty());
+  }
+}
 /**
  * openProvider LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH
  */
@@ -3057,6 +4083,146 @@
     return le_audio_codec_configs;
   }
 
+  AudioContext GetAudioContext(int32_t bitmask) {
+    AudioContext media_audio_context;
+    media_audio_context.bitmask = bitmask;
+    return media_audio_context;
+  }
+
+  std::optional<CodecSpecificConfigurationLtv> GetConfigurationLtv(
+      const std::vector<CodecSpecificConfigurationLtv>& configurationLtvs,
+      CodecSpecificConfigurationLtv::Tag tag) {
+    for (const auto ltv : configurationLtvs) {
+      if (ltv.getTag() == tag) {
+        return ltv;
+      }
+    }
+    return std::nullopt;
+  }
+
+  std::optional<CodecSpecificConfigurationLtv::SamplingFrequency>
+  GetBisSampleFreq(const LeAudioBisConfiguration& bis_conf) {
+    auto sample_freq_ltv = GetConfigurationLtv(
+        bis_conf.codecConfiguration,
+        CodecSpecificConfigurationLtv::Tag::samplingFrequency);
+    if (!sample_freq_ltv) {
+      return std::nullopt;
+    }
+    return (*sample_freq_ltv)
+        .get<CodecSpecificConfigurationLtv::samplingFrequency>();
+  }
+
+  std::vector<CodecSpecificConfigurationLtv::SamplingFrequency>
+  GetSubgroupSampleFreqs(
+      const LeAudioBroadcastSubgroupConfiguration& subgroup_conf) {
+    std::vector<CodecSpecificConfigurationLtv::SamplingFrequency> result = {};
+
+    for (const auto& bis_conf : subgroup_conf.bisConfigurations) {
+      auto sample_freq = GetBisSampleFreq(bis_conf.bisConfiguration);
+      if (sample_freq) {
+        result.push_back(*sample_freq);
+      }
+    }
+    return result;
+  }
+
+  void VerifyBroadcastConfiguration(
+      const LeAudioBroadcastConfigurationRequirement& requirements,
+      const LeAudioBroadcastConfigurationSetting& configuration,
+      std::vector<CodecSpecificConfigurationLtv::SamplingFrequency>
+          expectedSampleFreqs = {}) {
+    std::vector<CodecSpecificConfigurationLtv::SamplingFrequency> sampleFreqs =
+        {};
+
+    int number_of_requested_bises = 0;
+    for (const auto& subgroup_req :
+         requirements.subgroupConfigurationRequirements) {
+      number_of_requested_bises += subgroup_req.bisNumPerSubgroup;
+    }
+
+    if (!expectedSampleFreqs.empty()) {
+      for (const auto& subgroup_conf : configuration.subgroupsConfigurations) {
+        auto result = GetSubgroupSampleFreqs(subgroup_conf);
+        sampleFreqs.insert(sampleFreqs.end(), result.begin(), result.end());
+      }
+    }
+
+    ASSERT_EQ(number_of_requested_bises, configuration.numBis);
+    ASSERT_EQ(requirements.subgroupConfigurationRequirements.size(),
+              configuration.subgroupsConfigurations.size());
+
+    if (expectedSampleFreqs.empty()) {
+      return;
+    }
+
+    std::sort(sampleFreqs.begin(), sampleFreqs.end());
+    std::sort(expectedSampleFreqs.begin(), expectedSampleFreqs.end());
+
+    ASSERT_EQ(sampleFreqs, expectedSampleFreqs);
+  }
+
+  LeAudioDeviceCapabilities GetDefaultBroadcastSinkCapability() {
+    // Create a capability
+    LeAudioDeviceCapabilities capability;
+
+    capability.codecId = CodecId::Core::LC3;
+
+    auto pref_context_metadata = MetadataLtv::PreferredAudioContexts();
+    pref_context_metadata.values =
+        GetAudioContext(AudioContext::MEDIA | AudioContext::CONVERSATIONAL |
+                        AudioContext::GAME);
+    capability.metadata = {pref_context_metadata};
+
+    auto sampling_rate =
+        CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies();
+    sampling_rate.bitmask =
+        CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ48000 |
+        CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ16000;
+    auto frame_duration =
+        CodecSpecificCapabilitiesLtv::SupportedFrameDurations();
+    frame_duration.bitmask =
+        CodecSpecificCapabilitiesLtv::SupportedFrameDurations::US7500 |
+        CodecSpecificCapabilitiesLtv::SupportedFrameDurations::US10000;
+    auto octets = CodecSpecificCapabilitiesLtv::SupportedOctetsPerCodecFrame();
+    octets.min = 0;
+    octets.max = 120;
+    auto frames = CodecSpecificCapabilitiesLtv::SupportedMaxCodecFramesPerSDU();
+    frames.value = 2;
+    capability.codecSpecificCapabilities = {sampling_rate, frame_duration,
+                                            octets, frames};
+    return capability;
+  }
+
+  LeAudioBroadcastConfigurationRequirement GetBroadcastRequirement(
+      bool standard_quality, bool high_quality) {
+    LeAudioBroadcastConfigurationRequirement requirement;
+
+    AudioContext media_audio_context;
+    media_audio_context.bitmask = AudioContext::MEDIA;
+
+    LeAudioBroadcastSubgroupConfigurationRequirement
+        standard_quality_requirement = {
+            .audioContext = media_audio_context,
+            .quality = IBluetoothAudioProvider::BroadcastQuality::STANDARD,
+            .bisNumPerSubgroup = 2};
+
+    LeAudioBroadcastSubgroupConfigurationRequirement high_quality_requirement =
+        {.audioContext = media_audio_context,
+         .quality = IBluetoothAudioProvider::BroadcastQuality::HIGH,
+         .bisNumPerSubgroup = 2};
+
+    if (standard_quality) {
+      requirement.subgroupConfigurationRequirements.push_back(
+          standard_quality_requirement);
+    }
+
+    if (high_quality) {
+      requirement.subgroupConfigurationRequirements.push_back(
+          high_quality_requirement);
+    }
+    return requirement;
+  }
+
   std::vector<Lc3Configuration> GetBroadcastLc3SupportedList(bool supported) {
     std::vector<Lc3Configuration> le_audio_codec_configs;
     if (!supported) {
@@ -3163,18 +4329,93 @@
       BluetoothAudioHalVersion::VERSION_AIDL_V4) {
     GTEST_SKIP();
   }
+
+  if (!IsBroadcastOffloadSupported()) {
+    GTEST_SKIP();
+  }
+
   std::vector<std::optional<LeAudioDeviceCapabilities>> empty_capability;
   IBluetoothAudioProvider::LeAudioBroadcastConfigurationRequirement
       empty_requirement;
 
-  IBluetoothAudioProvider::LeAudioBroadcastConfigurationSetting* configuration =
-      new IBluetoothAudioProvider::LeAudioBroadcastConfigurationSetting();
+  IBluetoothAudioProvider::LeAudioBroadcastConfigurationSetting configuration;
 
   // Check empty capability for source direction
   auto aidl_retval = audio_provider_->getLeAudioBroadcastConfiguration(
-      empty_capability, empty_requirement, configuration);
+      empty_capability, empty_requirement, &configuration);
+
+  ASSERT_FALSE(aidl_retval.isOk());
+}
+
+TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
+       GetBroadcastConfigurationEmptyCapability) {
+  if (GetProviderFactoryInterfaceVersion() <
+      BluetoothAudioHalVersion::VERSION_AIDL_V4) {
+    GTEST_SKIP();
+  }
+
+  if (!IsBroadcastOffloadSupported()) {
+    GTEST_SKIP();
+  }
+
+  std::vector<std::optional<LeAudioDeviceCapabilities>> empty_capability;
+  IBluetoothAudioProvider::LeAudioBroadcastConfigurationSetting configuration;
+
+  IBluetoothAudioProvider::LeAudioBroadcastConfigurationRequirement
+      one_subgroup_requirement =
+          GetBroadcastRequirement(true /* standard*/, false /* high */);
+
+  // Check empty capability for source direction
+  auto aidl_retval = audio_provider_->getLeAudioBroadcastConfiguration(
+      empty_capability, one_subgroup_requirement, &configuration);
 
   ASSERT_TRUE(aidl_retval.isOk());
+  ASSERT_NE(configuration.numBis, 0);
+  ASSERT_FALSE(configuration.subgroupsConfigurations.empty());
+  VerifyBroadcastConfiguration(one_subgroup_requirement, configuration);
+
+  IBluetoothAudioProvider::LeAudioBroadcastConfigurationRequirement
+      two_subgroup_requirement =
+          GetBroadcastRequirement(true /* standard*/, true /* high */);
+
+  // Check empty capability for source direction
+  aidl_retval = audio_provider_->getLeAudioBroadcastConfiguration(
+      empty_capability, two_subgroup_requirement, &configuration);
+
+  ASSERT_TRUE(aidl_retval.isOk());
+  ASSERT_NE(configuration.numBis, 0);
+  ASSERT_FALSE(configuration.subgroupsConfigurations.empty());
+  VerifyBroadcastConfiguration(two_subgroup_requirement, configuration);
+}
+
+TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
+       GetBroadcastConfigurationNonEmptyCapability) {
+  if (GetProviderFactoryInterfaceVersion() <
+      BluetoothAudioHalVersion::VERSION_AIDL_V4) {
+    GTEST_SKIP();
+  }
+
+  if (!IsBroadcastOffloadSupported()) {
+    GTEST_SKIP();
+  }
+
+  std::vector<std::optional<LeAudioDeviceCapabilities>> capability = {
+      GetDefaultBroadcastSinkCapability()};
+
+  IBluetoothAudioProvider::LeAudioBroadcastConfigurationRequirement
+      requirement =
+          GetBroadcastRequirement(true /* standard*/, true /* high */);
+
+  IBluetoothAudioProvider::LeAudioBroadcastConfigurationSetting configuration;
+
+  // Check empty capability for source direction
+  auto aidl_retval = audio_provider_->getLeAudioBroadcastConfiguration(
+      capability, requirement, &configuration);
+
+  ASSERT_TRUE(aidl_retval.isOk());
+  ASSERT_NE(configuration.numBis, 0);
+  ASSERT_FALSE(configuration.subgroupsConfigurations.empty());
+  VerifyBroadcastConfiguration(requirement, configuration);
 }
 
 /**
@@ -3185,7 +4426,7 @@
 TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
        StartAndEndLeAudioBroadcastSessionWithPossibleBroadcastConfig) {
   if (!IsBroadcastOffloadSupported()) {
-    return;
+    GTEST_SKIP();
   }
 
   auto lc3_codec_configs = GetBroadcastLc3SupportedList(true /* supported */);
@@ -3224,7 +4465,7 @@
     BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
     DISABLED_StartAndEndLeAudioBroadcastSessionWithInvalidAudioConfiguration) {
   if (!IsBroadcastOffloadSupported()) {
-    return;
+    GTEST_SKIP();
   }
 
   auto lc3_codec_configs = GetBroadcastLc3SupportedList(false /* supported */);
diff --git a/bluetooth/audio/flags/btaudiohal.aconfig b/bluetooth/audio/flags/btaudiohal.aconfig
index 4c1500a..13e2116 100644
--- a/bluetooth/audio/flags/btaudiohal.aconfig
+++ b/bluetooth/audio/flags/btaudiohal.aconfig
@@ -7,3 +7,10 @@
     description: "Flag for DSA Over LEA"
     bug: "270987427"
 }
+
+flag {
+    name: "leaudio_report_broadcast_ac_to_hal"
+    namespace: "pixel_bluetooth"
+    description: "Flag for reporting lea broadcast audio config to HAL"
+    bug: "321168976"
+}
\ No newline at end of file
diff --git a/bluetooth/audio/utils/Android.bp b/bluetooth/audio/utils/Android.bp
index c0817f5..1661362 100644
--- a/bluetooth/audio/utils/Android.bp
+++ b/bluetooth/audio/utils/Android.bp
@@ -42,6 +42,7 @@
         "aidl_session/BluetoothAudioSession.cpp",
         "aidl_session/HidlToAidlMiddleware.cpp",
         "aidl_session/BluetoothLeAudioCodecsProvider.cpp",
+        "aidl_session/BluetoothHfpCodecsProvider.cpp",
         "aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.cpp",
     ],
     export_include_dirs: ["aidl_session/"],
@@ -50,6 +51,7 @@
         "libxsdc-utils",
     ],
     defaults: [
+        "aconfig_lib_cc_static_link.defaults",
         "latest_android_hardware_bluetooth_audio_ndk_shared",
     ],
     shared_libs: [
@@ -68,9 +70,13 @@
     static_libs: [
         "btaudiohal_flags_c_lib",
     ],
-    generated_sources: ["le_audio_codec_capabilities"],
+    generated_sources: [
+        "le_audio_codec_capabilities",
+        "hfp_codec_capabilities",
+    ],
     generated_headers: [
         "le_audio_codec_capabilities",
+        "hfp_codec_capabilities",
         "AIDLLeAudioSetConfigSchemas_h",
     ],
     required: [
@@ -78,11 +84,15 @@
         "aidl_audio_set_configurations_json",
         "aidl_audio_set_scenarios_bfbs",
         "aidl_audio_set_scenarios_json",
+        "hfp_codec_capabilities_xml",
     ],
 }
 
 cc_test {
     name: "BluetoothLeAudioCodecsProviderTest",
+    defaults: [
+        "latest_android_hardware_bluetooth_audio_ndk_shared",
+    ],
     srcs: [
         "aidl_session/BluetoothLeAudioCodecsProvider.cpp",
         "aidl_session/BluetoothLeAudioCodecsProviderTest.cpp",
@@ -93,7 +103,6 @@
     shared_libs: [
         "libbase",
         "libbinder_ndk",
-        "android.hardware.bluetooth.audio-V4-ndk",
         "libxml2",
     ],
     test_suites: [
@@ -106,6 +115,35 @@
     generated_headers: ["le_audio_codec_capabilities"],
 }
 
+cc_test {
+    name: "BluetoothHfpCodecsProviderTest",
+    defaults: [
+        "latest_android_hardware_audio_common_ndk_static",
+        "latest_android_hardware_bluetooth_audio_ndk_static",
+        "latest_android_media_audio_common_types_ndk_static",
+    ],
+    srcs: [
+        "aidl_session/BluetoothHfpCodecsProvider.cpp",
+        "aidl_session/BluetoothHfpCodecsProviderTest.cpp",
+    ],
+    header_libs: [
+        "libxsdc-utils",
+    ],
+    shared_libs: [
+        "libbase",
+        "libbinder_ndk",
+        "libxml2",
+    ],
+    test_suites: [
+        "general-tests",
+    ],
+    test_options: {
+        unit_test: false,
+    },
+    generated_sources: ["hfp_codec_capabilities"],
+    generated_headers: ["hfp_codec_capabilities"],
+}
+
 xsd_config {
     name: "le_audio_codec_capabilities",
     srcs: ["le_audio_codec_capabilities/le_audio_codec_capabilities.xsd"],
@@ -114,6 +152,14 @@
     root_elements: ["leAudioOffloadSetting"],
 }
 
+xsd_config {
+    name: "hfp_codec_capabilities",
+    srcs: ["hfp_codec_capabilities/hfp_codec_capabilities.xsd"],
+    package_name: "aidl.android.hardware.bluetooth.audio.hfp.setting",
+    api_dir: "hfp_codec_capabilities/schema",
+    root_elements: ["hfpOffloadSetting"],
+}
+
 genrule {
     name: "AIDLLeAudioSetConfigSchemas_h",
     tools: [
@@ -177,6 +223,14 @@
 }
 
 prebuilt_etc {
+    name: "hfp_codec_capabilities_xml",
+    src: "hfp_codec_capabilities/hfp_codec_capabilities.xml",
+    filename: "hfp_codec_capabilities.xml",
+    sub_dir: "aidl/hfp",
+    vendor: true,
+}
+
+prebuilt_etc {
     name: "aidl_audio_set_configurations_bfbs",
     src: ":AIDLLeAudioSetConfigsSchema_bfbs",
     filename: "aidl_audio_set_configurations.bfbs",
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp
index d37825a..c25b102 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp
@@ -32,6 +32,7 @@
 #include <aidl/android/hardware/bluetooth/audio/SbcChannelMode.h>
 #include <android-base/logging.h>
 
+#include "BluetoothHfpCodecsProvider.h"
 #include "BluetoothLeAudioAseConfigurationSettingProvider.h"
 #include "BluetoothLeAudioCodecsProvider.h"
 
@@ -100,6 +101,7 @@
 std::vector<LeAudioCodecCapabilitiesSetting> kDefaultOffloadLeAudioCapabilities;
 std::unordered_map<SessionType, std::vector<CodecInfo>>
     kDefaultOffloadLeAudioCodecInfoMap;
+std::vector<CodecInfo> kDefaultOffloadHfpCodecInfo;
 
 template <class T>
 bool BluetoothAudioCodecs::ContainedInVector(
@@ -439,6 +441,17 @@
   return codec_info_map_iter->second;
 }
 
+std::vector<CodecInfo> BluetoothAudioCodecs::GetHfpOffloadCodecInfo() {
+  if (kDefaultOffloadHfpCodecInfo.empty()) {
+    auto hfp_offload_setting =
+        BluetoothHfpCodecsProvider::ParseFromHfpOffloadSettingFile();
+    // Load file into list
+    kDefaultOffloadHfpCodecInfo =
+        BluetoothHfpCodecsProvider::GetHfpAudioCodecInfo(hfp_offload_setting);
+  }
+  return kDefaultOffloadHfpCodecInfo;
+}
+
 std::vector<LeAudioAseConfigurationSetting>
 BluetoothAudioCodecs::GetLeAudioAseConfigurationSettings() {
   return AudioSetConfigurationProviderJson::
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h
index 057b9a7..0a1f708 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h
@@ -57,6 +57,8 @@
   static std::vector<LeAudioAseConfigurationSetting>
   GetLeAudioAseConfigurationSettings();
 
+  static std::vector<CodecInfo> GetHfpOffloadCodecInfo();
+
  private:
   template <typename T>
   struct identity {
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
index 67ba93c..d0f2a26 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
@@ -121,18 +121,41 @@
 
 void BluetoothAudioSession::ReportAudioConfigChanged(
     const AudioConfiguration& audio_config) {
-  if (session_type_ !=
-          SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
-      session_type_ !=
-          SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
-    return;
-  }
-
   std::lock_guard<std::recursive_mutex> guard(mutex_);
-  if (audio_config.getTag() != AudioConfiguration::leAudioConfig) {
-    LOG(ERROR) << __func__ << " invalid audio config type for SessionType ="
-               << toString(session_type_);
-    return;
+  if (com::android::btaudio::hal::flags::leaudio_report_broadcast_ac_to_hal()) {
+    if (session_type_ ==
+            SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
+        session_type_ ==
+            SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
+      if (audio_config.getTag() != AudioConfiguration::leAudioConfig) {
+        LOG(ERROR) << __func__ << " invalid audio config type for SessionType ="
+                  << toString(session_type_);
+        return;
+      }
+    } else if (session_type_ ==
+            SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
+      if (audio_config.getTag() != AudioConfiguration::leAudioBroadcastConfig) {
+        LOG(ERROR) << __func__ << " invalid audio config type for SessionType ="
+                  << toString(session_type_);
+        return;
+      }
+    } else {
+      LOG(ERROR) << __func__ << " invalid SessionType ="
+                 << toString(session_type_);
+      return;
+    }
+  } else {
+    if (session_type_ !=
+            SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
+        session_type_ !=
+            SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
+      return;
+    }
+    if (audio_config.getTag() != AudioConfiguration::leAudioConfig) {
+      LOG(ERROR) << __func__ << " invalid audio config type for SessionType ="
+                 << toString(session_type_);
+      return;
+    }
   }
 
   audio_config_ = std::make_unique<AudioConfiguration>(audio_config);
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothHfpCodecsProvider.cpp b/bluetooth/audio/utils/aidl_session/BluetoothHfpCodecsProvider.cpp
new file mode 100644
index 0000000..d61ec5a
--- /dev/null
+++ b/bluetooth/audio/utils/aidl_session/BluetoothHfpCodecsProvider.cpp
@@ -0,0 +1,115 @@
+/*
+ * 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 "BluetoothHfpCodecsProvider.h"
+
+#include <unordered_map>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+
+using hfp::setting::CodecType;
+using hfp::setting::PathConfiguration;
+
+static const char* kHfpCodecCapabilitiesFile =
+    "/vendor/etc/aidl/hfp/hfp_codec_capabilities.xml";
+
+std::optional<HfpOffloadSetting>
+BluetoothHfpCodecsProvider::ParseFromHfpOffloadSettingFile() {
+  auto hfp_offload_setting =
+      hfp::setting::readHfpOffloadSetting(kHfpCodecCapabilitiesFile);
+  if (!hfp_offload_setting.has_value()) {
+    LOG(ERROR) << __func__ << ": Failed to read " << kHfpCodecCapabilitiesFile;
+  }
+  return hfp_offload_setting;
+}
+
+std::vector<CodecInfo> BluetoothHfpCodecsProvider::GetHfpAudioCodecInfo(
+    const std::optional<HfpOffloadSetting>& hfp_offload_setting) {
+  std::vector<CodecInfo> result;
+  if (!hfp_offload_setting.has_value()) return result;
+
+  // Convert path configuration into map
+  // Currently transport configuration is unused
+  if (!hfp_offload_setting.value().hasPathConfiguration() ||
+      hfp_offload_setting.value().getPathConfiguration().empty()) {
+    LOG(WARNING) << __func__ << ": path configurations is empty";
+    return result;
+  }
+  auto path_configurations = hfp_offload_setting.value().getPathConfiguration();
+  std::unordered_map<std::string, PathConfiguration> path_config_map;
+  for (const auto& path_cfg : path_configurations)
+    if (path_cfg.hasName() && path_cfg.hasDataPath())
+      path_config_map.insert(make_pair(path_cfg.getName(), path_cfg));
+
+  for (const auto& cfg : hfp_offload_setting.value().getConfiguration()) {
+    auto input_path_cfg = path_config_map.find(cfg.getInputPathConfiguration());
+    auto output_path_cfg =
+        path_config_map.find(cfg.getOutputPathConfiguration());
+    if (input_path_cfg == path_config_map.end()) {
+      LOG(WARNING) << __func__ << ": Input path configuration not found: "
+                   << cfg.getInputPathConfiguration();
+      continue;
+    }
+
+    if (output_path_cfg == path_config_map.end()) {
+      LOG(WARNING) << __func__ << ": Output path configuration not found: "
+                   << cfg.getOutputPathConfiguration();
+      continue;
+    }
+
+    CodecInfo codec_info;
+
+    switch (cfg.getCodec()) {
+      case CodecType::LC3:
+        codec_info.id = CodecId::Core::LC3;
+        break;
+      case CodecType::MSBC:
+        codec_info.id = CodecId::Core::MSBC;
+        break;
+      case CodecType::CVSD:
+        codec_info.id = CodecId::Core::CVSD;
+        break;
+      default:
+        LOG(WARNING) << __func__ << ": Unknown codec from " << cfg.getName();
+        codec_info.id = CodecId::Vendor();
+        break;
+    }
+    codec_info.name = cfg.getName();
+
+    codec_info.transport =
+        CodecInfo::Transport::make<CodecInfo::Transport::Tag::hfp>();
+
+    auto& transport =
+        codec_info.transport.get<CodecInfo::Transport::Tag::hfp>();
+    transport.useControllerCodec = cfg.getUseControllerCodec();
+    transport.inputDataPath = input_path_cfg->second.getDataPath();
+    transport.outputDataPath = output_path_cfg->second.getDataPath();
+
+    result.push_back(codec_info);
+  }
+  LOG(INFO) << __func__ << ": Has " << result.size() << " codec info";
+  return result;
+}
+
+}  // namespace audio
+}  // namespace bluetooth
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothHfpCodecsProvider.h b/bluetooth/audio/utils/aidl_session/BluetoothHfpCodecsProvider.h
new file mode 100644
index 0000000..642ee02
--- /dev/null
+++ b/bluetooth/audio/utils/aidl_session/BluetoothHfpCodecsProvider.h
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <android-base/logging.h>
+
+#include <vector>
+
+#include "aidl/android/hardware/bluetooth/audio/CodecInfo.h"
+#include "aidl_android_hardware_bluetooth_audio_hfp_setting.h"
+#include "aidl_android_hardware_bluetooth_audio_hfp_setting_enums.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+
+using hfp::setting::HfpOffloadSetting;
+
+class BluetoothHfpCodecsProvider {
+ public:
+  static std::optional<HfpOffloadSetting> ParseFromHfpOffloadSettingFile();
+
+  static std::vector<CodecInfo> GetHfpAudioCodecInfo(
+      const std::optional<HfpOffloadSetting>& hfp_offload_setting);
+};
+}  // namespace audio
+}  // namespace bluetooth
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothHfpCodecsProviderTest.cpp b/bluetooth/audio/utils/aidl_session/BluetoothHfpCodecsProviderTest.cpp
new file mode 100644
index 0000000..b08c3eb
--- /dev/null
+++ b/bluetooth/audio/utils/aidl_session/BluetoothHfpCodecsProviderTest.cpp
@@ -0,0 +1,153 @@
+/*
+ * 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 <gtest/gtest.h>
+
+#include <optional>
+#include <tuple>
+
+#include "BluetoothHfpCodecsProvider.h"
+#include "gtest/gtest.h"
+
+using aidl::android::hardware::bluetooth::audio::BluetoothHfpCodecsProvider;
+using aidl::android::hardware::bluetooth::audio::CodecInfo;
+using aidl::android::hardware::bluetooth::audio::hfp::setting::CodecType;
+using aidl::android::hardware::bluetooth::audio::hfp::setting::Configuration;
+using aidl::android::hardware::bluetooth::audio::hfp::setting::
+    HfpOffloadSetting;
+using aidl::android::hardware::bluetooth::audio::hfp::setting::
+    PathConfiguration;
+using aidl::android::hardware::bluetooth::audio::hfp::setting::
+    TransportConfiguration;
+
+typedef std::tuple<std::vector<PathConfiguration>,
+                   std::vector<TransportConfiguration>,
+                   std::vector<Configuration>>
+    HfpOffloadSettingTuple;
+
+// Define valid components for each list
+// PathConfiguration
+static const PathConfiguration kValidPathConfigurationCVSD("CVSD_IO", 16000,
+                                                           CodecType::CVSD, 16,
+                                                           2, 0, 1, 0);
+static const PathConfiguration kInvalidPathConfigurationNULL(std::nullopt,
+                                                             16000,
+                                                             CodecType::CVSD,
+                                                             16, 2, 0, 1, 0);
+static const PathConfiguration kInvalidPathConfigurationNoPath(
+    "CVSD_NULL", 16000, CodecType::CVSD, 16, 2, 0, std::nullopt, 0);
+
+// Configuration
+static const Configuration kValidConfigurationCVSD("CVSD", CodecType::CVSD,
+                                                   65535, 7, 0, true, "CVSD_IO",
+                                                   "CVSD_IO", std::nullopt,
+                                                   std::nullopt);
+static const Configuration kInvalidConfigurationCVSDNoPath(
+    "CVSD", CodecType::CVSD, 65535, 7, 0, true, "CVSD_NULL", "CVSD_NULL",
+    std::nullopt, std::nullopt);
+static const Configuration kInvalidConfigurationCVSDNotFound(
+    "CVSD", CodecType::CVSD, 65535, 7, 0, true, "CVSD_N", "CVSD_N",
+    std::nullopt, std::nullopt);
+
+class BluetoothHfpCodecsProviderTest : public ::testing::Test {
+ public:
+  static std::vector<HfpOffloadSettingTuple> CreateTestCases(
+      const std::vector<std::vector<PathConfiguration>> path_configs_list,
+      const std::vector<std::vector<TransportConfiguration>>
+          transport_configs_list,
+      const std::vector<std::vector<Configuration>> configs_list) {
+    std::vector<HfpOffloadSettingTuple> test_cases;
+    for (const auto& path_configs : path_configs_list) {
+      for (const auto& transport_configs : transport_configs_list) {
+        for (const auto& configs : configs_list)
+          test_cases.push_back(
+              CreateTestCase(path_configs, transport_configs, configs));
+      }
+    }
+    return test_cases;
+  }
+
+ protected:
+  std::vector<CodecInfo> RunTestCase(HfpOffloadSettingTuple test_case) {
+    auto& [path_configuration_list, transport_configuration_list,
+           configuration_list] = test_case;
+    HfpOffloadSetting hfp_offload_setting(path_configuration_list,
+                                          transport_configuration_list,
+                                          configuration_list);
+    auto capabilities =
+        BluetoothHfpCodecsProvider::GetHfpAudioCodecInfo(hfp_offload_setting);
+    return capabilities;
+  }
+
+ private:
+  static inline HfpOffloadSettingTuple CreateTestCase(
+      const std::vector<PathConfiguration> path_config_list,
+      const std::vector<TransportConfiguration> transport_config_list,
+      const std::vector<Configuration> config_list) {
+    return std::make_tuple(path_config_list, transport_config_list,
+                           config_list);
+  }
+};
+
+class GetHfpCodecInfoTest : public BluetoothHfpCodecsProviderTest {
+ public:
+  static std::vector<std::vector<PathConfiguration>>
+  GetInvalidPathConfigurationLists() {
+    std::vector<std::vector<PathConfiguration>> result;
+    result.push_back({kInvalidPathConfigurationNULL});
+    result.push_back({kInvalidPathConfigurationNoPath});
+    result.push_back({});
+    return result;
+  }
+
+  static std::vector<std::vector<Configuration>>
+  GetInvalidConfigurationLists() {
+    std::vector<std::vector<Configuration>> result;
+    result.push_back({kInvalidConfigurationCVSDNotFound});
+    result.push_back({kInvalidConfigurationCVSDNoPath});
+    result.push_back({});
+    return result;
+  }
+};
+
+TEST_F(GetHfpCodecInfoTest, InvalidPathConfiguration) {
+  auto test_cases = BluetoothHfpCodecsProviderTest::CreateTestCases(
+      GetHfpCodecInfoTest::GetInvalidPathConfigurationLists(), {{}},
+      {{kValidConfigurationCVSD}});
+  for (auto& test_case : test_cases) {
+    auto hfp_codec_capabilities = RunTestCase(test_case);
+    ASSERT_TRUE(hfp_codec_capabilities.empty());
+  }
+}
+
+TEST_F(GetHfpCodecInfoTest, InvalidConfigurationName) {
+  auto test_cases = BluetoothHfpCodecsProviderTest::CreateTestCases(
+      GetHfpCodecInfoTest::GetInvalidPathConfigurationLists(), {{}},
+      {GetHfpCodecInfoTest::GetInvalidConfigurationLists()});
+  for (auto& test_case : test_cases) {
+    auto hfp_codec_capabilities = RunTestCase(test_case);
+    ASSERT_TRUE(hfp_codec_capabilities.empty());
+  }
+}
+
+TEST_F(GetHfpCodecInfoTest, ValidConfiguration) {
+  auto test_cases = BluetoothHfpCodecsProviderTest::CreateTestCases(
+      {{kValidPathConfigurationCVSD}}, {{}}, {{kValidConfigurationCVSD}});
+  for (auto& test_case : test_cases) {
+    auto hfp_codec_capabilities = RunTestCase(test_case);
+    ASSERT_FALSE(hfp_codec_capabilities.empty());
+  }
+}
diff --git a/bluetooth/audio/utils/hfp_codec_capabilities/hfp_codec_capabilities.xml b/bluetooth/audio/utils/hfp_codec_capabilities/hfp_codec_capabilities.xml
new file mode 100644
index 0000000..c94843f
--- /dev/null
+++ b/bluetooth/audio/utils/hfp_codec_capabilities/hfp_codec_capabilities.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!---
+  This is an example to configure HFP hardware offload supported capability settings
+  There are 3 list in this file. Add element into each list as needed.
+
+  pathConfiguration: input / output path configuration
+  transportConfiguration: transmit / receive configuration
+
+  configuration:
+    For each configuration, there are attributes:
+      - name
+      - codec
+      - useControllerCodec
+      - maxLatencyMs
+      - packetTypes
+      - retransmissionEffort
+      - input and output path configuration (reference by name)
+      - transmit and receive configuration (reference by name)
+-->
+<hfpOffloadSetting>
+
+  <pathConfiguration name="CVSD_IO" bandwidth="16000" codec="CVSD" codedDataSize="16" pcmDataFormat="2" pcmPayloadMsbPosition="0" dataPath="1" transportUnitSize="0" />
+  <pathConfiguration name="MSBC_IO" bandwidth="32000" codec="MSBC" codedDataSize="16" pcmDataFormat="2" pcmPayloadMsbPosition="0" dataPath="1" transportUnitSize="0" />
+  <pathConfiguration name="LC3_IO" bandwidth="64000" codec="MSBC" codedDataSize="16" pcmDataFormat="2" pcmPayloadMsbPosition="0" dataPath="1" transportUnitSize="0" />
+
+  <transportConfiguration name="CVSD_TXRX" bandwidth="8000" codec="CVSD" codedFrameSize="60" />
+  <transportConfiguration name="MSBC_TXRX" bandwidth="8000" codec="MSBC" codedFrameSize="60" />
+  <transportConfiguration name="LC3_TXRX" bandwidth="8000" codec="LC3" codedFrameSize="60" />
+
+  <configuration name="CVSD_D1_controller" codec="CVSD" maxLatencyMs="65535" packetTypes="7" retransmissionEffort="0" useControllerCodec="true" inputPathConfiguration="CVSD_IO" outputPathConfiguration="CVSD_IO" inputTransportConfiguration="CVSD_TXRX" outTransportConfiguration="CVSD_TXRX" />
+  <configuration name="CVSD_S3_controller" codec="CVSD" maxLatencyMs="10" packetTypes="959" retransmissionEffort="1" useControllerCodec="true" inputPathConfiguration="CVSD_IO" outputPathConfiguration="CVSD_IO" inputTransportConfiguration="CVSD_TXRX" outTransportConfiguration="CVSD_TXRX" />
+  <configuration name="CVSD_S4_controller" codec="CVSD" maxLatencyMs="12" packetTypes="959" retransmissionEffort="2" useControllerCodec="true" inputPathConfiguration="CVSD_IO" outputPathConfiguration="CVSD_IO" inputTransportConfiguration="CVSD_TXRX" outTransportConfiguration="CVSD_TXRX" />
+
+  <configuration name="MSBC_T1_controller" codec="MSBC" maxLatencyMs="8" packetTypes="968" retransmissionEffort="2" useControllerCodec="true" inputPathConfiguration="MSBC_IO" outputPathConfiguration="MSBC_IO" inputTransportConfiguration="MSBC_TXRX" outTransportConfiguration="MSBC_TXRX" />
+  <configuration name="MSBC_T2_controller" codec="MSBC" maxLatencyMs="13" packetTypes="904" retransmissionEffort="2" useControllerCodec="true" inputPathConfiguration="MSBC_IO" outputPathConfiguration="MSBC_IO" inputTransportConfiguration="MSBC_TXRX" outTransportConfiguration="MSBC_TXRX" />
+
+  <configuration name="LC3_T1_controller" codec="LC3" maxLatencyMs="8" packetTypes="968" retransmissionEffort="2" useControllerCodec="true" inputPathConfiguration="LC3_IO" outputPathConfiguration="LC3_IO" inputTransportConfiguration="LC3_TXRX" outTransportConfiguration="LC3_TXRX" />
+  <configuration name="LC3_T2_controller" codec="LC3" maxLatencyMs="13" packetTypes="896" retransmissionEffort="2" useControllerCodec="true" inputPathConfiguration="LC3_IO" outputPathConfiguration="LC3_IO" inputTransportConfiguration="LC3_TXRX" outTransportConfiguration="LC3_TXRX" />
+
+</hfpOffloadSetting>
diff --git a/bluetooth/audio/utils/hfp_codec_capabilities/hfp_codec_capabilities.xsd b/bluetooth/audio/utils/hfp_codec_capabilities/hfp_codec_capabilities.xsd
new file mode 100644
index 0000000..c4787b9
--- /dev/null
+++ b/bluetooth/audio/utils/hfp_codec_capabilities/hfp_codec_capabilities.xsd
@@ -0,0 +1,51 @@
+<!-- HFP Offload Codec Capability Schema -->
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+  <xs:element name="hfpOffloadSetting">
+    <xs:complexType>
+      <xs:element ref="pathConfiguration" minOccurs="1" maxOccurs="unbounded"/>
+      <xs:element ref="transportConfiguration" minOccurs="1" maxOccurs="unbounded"/>
+      <xs:element ref="configuration" minOccurs="1" maxOccurs="unbounded"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="pathConfiguration">
+    <xs:complexType>
+      <xs:attribute name="name" type="xs:string"/>
+      <xs:attribute name="bandwidth" type="xs:unsignedInt"/>
+      <xs:attribute name="codec" type="codecType"/>
+      <xs:attribute name="codedDataSize" type="xs:unsignedShort"/>
+      <xs:attribute name="pcmDataFormat" type="xs:unsignedByte"/>
+      <xs:attribute name="pcmPayloadMsbPosition" type="xs:unsignedByte"/>
+      <xs:attribute name="dataPath" type="xs:unsignedByte"/>
+      <xs:attribute name="transportUnitSize" type="xs:unsignedByte"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="transportConfiguration">
+    <xs:complexType>
+      <xs:attribute name="name" type="xs:string"/>
+      <xs:attribute name="bandwidth" type="xs:unsignedInt"/>
+      <xs:attribute name="codec" type="codecType"/>
+      <xs:attribute name="codedFrameSize" type="xs:unsignedShort"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="configuration">
+    <xs:complexType>
+      <xs:attribute name="name" type="xs:string"/>
+      <xs:attribute name="codec" type="codecType"/>
+      <xs:attribute name="maxLatencyMs" type="xs:unsignedShort"/>
+      <xs:attribute name="packetTypes" type="xs:unsignedShort"/>
+      <xs:attribute name="retransmissionEffort" type="xs:unsignedByte"/>
+      <xs:attribute name="useControllerCodec" type="xs:boolean"/>
+      <xs:attribute name="inputPathConfiguration" type="xs:string"/>
+      <xs:attribute name="outputPathConfiguration" type="xs:string"/>
+      <xs:attribute name="inputTransportConfiguration" type="xs:string"/>
+      <xs:attribute name="outputTransportConfiguration" type="xs:string"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:simpleType name="codecType">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="LC3"/>
+      <xs:enumeration value="CVSD"/>
+      <xs:enumeration value="MSBC"/>
+    </xs:restriction>
+  </xs:simpleType>
+</xs:schema>
diff --git a/bluetooth/audio/utils/hfp_codec_capabilities/schema/current.txt b/bluetooth/audio/utils/hfp_codec_capabilities/schema/current.txt
new file mode 100644
index 0000000..4b49929
--- /dev/null
+++ b/bluetooth/audio/utils/hfp_codec_capabilities/schema/current.txt
@@ -0,0 +1,82 @@
+// Signature format: 2.0
+package aidl.android.hardware.bluetooth.audio.hfp.setting {
+
+  public enum CodecType {
+    method public String getRawName();
+    enum_constant public static final aidl.android.hardware.bluetooth.audio.hfp.setting.CodecType CVSD;
+    enum_constant public static final aidl.android.hardware.bluetooth.audio.hfp.setting.CodecType LC3;
+    enum_constant public static final aidl.android.hardware.bluetooth.audio.hfp.setting.CodecType MSBC;
+  }
+
+  public class Configuration {
+    ctor public Configuration();
+    method public aidl.android.hardware.bluetooth.audio.hfp.setting.CodecType getCodec();
+    method public String getInputPathConfiguration();
+    method public String getInputTransportConfiguration();
+    method public int getMaxLatencyMs();
+    method public String getName();
+    method public String getOutputPathConfiguration();
+    method public String getOutputTransportConfiguration();
+    method public int getPacketTypes();
+    method public short getRetransmissionEffort();
+    method public boolean getUseControllerCodec();
+    method public void setCodec(aidl.android.hardware.bluetooth.audio.hfp.setting.CodecType);
+    method public void setInputPathConfiguration(String);
+    method public void setInputTransportConfiguration(String);
+    method public void setMaxLatencyMs(int);
+    method public void setName(String);
+    method public void setOutputPathConfiguration(String);
+    method public void setOutputTransportConfiguration(String);
+    method public void setPacketTypes(int);
+    method public void setRetransmissionEffort(short);
+    method public void setUseControllerCodec(boolean);
+  }
+
+  public class HfpOffloadSetting {
+    ctor public HfpOffloadSetting();
+    method public java.util.List<aidl.android.hardware.bluetooth.audio.hfp.setting.Configuration> getConfiguration();
+    method public java.util.List<aidl.android.hardware.bluetooth.audio.hfp.setting.PathConfiguration> getPathConfiguration();
+    method public java.util.List<aidl.android.hardware.bluetooth.audio.hfp.setting.TransportConfiguration> getTransportConfiguration();
+  }
+
+  public class PathConfiguration {
+    ctor public PathConfiguration();
+    method public long getBandwidth();
+    method public aidl.android.hardware.bluetooth.audio.hfp.setting.CodecType getCodec();
+    method public int getCodedDataSize();
+    method public short getDataPath();
+    method public String getName();
+    method public short getPcmDataFormat();
+    method public short getPcmPayloadMsbPosition();
+    method public short getTransportUnitSize();
+    method public void setBandwidth(long);
+    method public void setCodec(aidl.android.hardware.bluetooth.audio.hfp.setting.CodecType);
+    method public void setCodedDataSize(int);
+    method public void setDataPath(short);
+    method public void setName(String);
+    method public void setPcmDataFormat(short);
+    method public void setPcmPayloadMsbPosition(short);
+    method public void setTransportUnitSize(short);
+  }
+
+  public class TransportConfiguration {
+    ctor public TransportConfiguration();
+    method public long getBandwidth();
+    method public aidl.android.hardware.bluetooth.audio.hfp.setting.CodecType getCodec();
+    method public int getCodedFrameSize();
+    method public String getName();
+    method public void setBandwidth(long);
+    method public void setCodec(aidl.android.hardware.bluetooth.audio.hfp.setting.CodecType);
+    method public void setCodedFrameSize(int);
+    method public void setName(String);
+  }
+
+  public class XmlParser {
+    ctor public XmlParser();
+    method public static aidl.android.hardware.bluetooth.audio.hfp.setting.HfpOffloadSetting readHfpOffloadSetting(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public static String readText(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public static void skip(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+  }
+
+}
+
diff --git a/bluetooth/audio/utils/hfp_codec_capabilities/schema/last_current.txt b/bluetooth/audio/utils/hfp_codec_capabilities/schema/last_current.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/bluetooth/audio/utils/hfp_codec_capabilities/schema/last_current.txt
@@ -0,0 +1 @@
+
diff --git a/bluetooth/audio/utils/hfp_codec_capabilities/schema/last_removed.txt b/bluetooth/audio/utils/hfp_codec_capabilities/schema/last_removed.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/bluetooth/audio/utils/hfp_codec_capabilities/schema/last_removed.txt
@@ -0,0 +1 @@
+
diff --git a/bluetooth/audio/utils/hfp_codec_capabilities/schema/removed.txt b/bluetooth/audio/utils/hfp_codec_capabilities/schema/removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/bluetooth/audio/utils/hfp_codec_capabilities/schema/removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/bluetooth/finder/aidl/vts/VtsHalBluetoothFinderTargetTest.cpp b/bluetooth/finder/aidl/vts/VtsHalBluetoothFinderTargetTest.cpp
index fee9e242..be07a7d 100644
--- a/bluetooth/finder/aidl/vts/VtsHalBluetoothFinderTargetTest.cpp
+++ b/bluetooth/finder/aidl/vts/VtsHalBluetoothFinderTargetTest.cpp
@@ -18,7 +18,6 @@
 #include <aidl/Vintf.h>
 #include <aidl/android/hardware/bluetooth/finder/IBluetoothFinder.h>
 #include <android-base/logging.h>
-#include <android-base/properties.h>
 #include <android/binder_manager.h>
 #include <android/binder_process.h>
 #include <binder/IServiceManager.h>
@@ -72,12 +71,6 @@
   return bluetooth_finder->getPoweredOffFinderMode(status);
 }
 
-TEST_P(BluetoothFinderTest, PropertyIsSet) {
-  ASSERT_EQ(
-      android::base::GetProperty("ro.bluetooth.finder.supported", "false"),
-      "true");
-}
-
 TEST_P(BluetoothFinderTest, SendEidsSingle) {
   ScopedAStatus status = sendEids(1);
   ASSERT_TRUE(status.isOk());
diff --git a/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp b/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
index 6e3ddc9..90ec32c 100644
--- a/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
+++ b/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
@@ -32,6 +32,7 @@
 #include <torch_provider_cb.h>
 #include <com_android_internal_camera_flags.h>
 #include <list>
+#include <nativebase/nativebase.h>
 
 using ::aidl::android::hardware::camera::common::CameraDeviceStatus;
 using ::aidl::android::hardware::camera::common::CameraResourceCost;
@@ -1668,9 +1669,9 @@
                                     BufferStatus::OK, NativeHandle(), NativeHandle()};
             } else {
                 allocateGraphicBuffer(previewStream.width, previewStream.height,
-                                      android_convertGralloc1To0Usage(
+                                      ANDROID_NATIVE_UNSIGNED_CAST(android_convertGralloc1To0Usage(
                                               static_cast<uint64_t>(halStream.producerUsage),
-                                              static_cast<uint64_t>(halStream.consumerUsage)),
+                                              static_cast<uint64_t>(halStream.consumerUsage))),
                                       halStream.overrideFormat, &buffer_handle);
                 graphicBuffers.push_back(buffer_handle);
                 outputBuffers[k] = {
@@ -1889,9 +1890,9 @@
                                         NativeHandle(), NativeHandle()};
                 } else {
                     allocateGraphicBuffer(previewStream.width, previewStream.height,
-                                          android_convertGralloc1To0Usage(
+                                          ANDROID_NATIVE_UNSIGNED_CAST(android_convertGralloc1To0Usage(
                                                   static_cast<uint64_t>(halStream.producerUsage),
-                                                  static_cast<uint64_t>(halStream.consumerUsage)),
+                                                  static_cast<uint64_t>(halStream.consumerUsage))),
                                           halStream.overrideFormat, &buffer_handle);
                     graphicBuffers.push_back(buffer_handle);
                     outputBuffers[k] = {
@@ -2057,9 +2058,9 @@
                                             NativeHandle(), BufferStatus::OK,
                                             NativeHandle(), NativeHandle()};
                     } else {
-                        auto usage = android_convertGralloc1To0Usage(
+                        auto usage = ANDROID_NATIVE_UNSIGNED_CAST(android_convertGralloc1To0Usage(
                                 static_cast<uint64_t>(halStream.producerUsage),
-                                static_cast<uint64_t>(halStream.consumerUsage));
+                                static_cast<uint64_t>(halStream.consumerUsage)));
                         allocateGraphicBuffer(previewStream.width, previewStream.height, usage,
                                               halStream.overrideFormat, &buffer_handle);
 
@@ -2278,9 +2279,9 @@
                                 NativeHandle(),   NativeHandle()};
             } else {
                 allocateGraphicBuffer(previewStream.width, previewStream.height,
-                                      android_convertGralloc1To0Usage(
+                                      ANDROID_NATIVE_UNSIGNED_CAST(android_convertGralloc1To0Usage(
                                               static_cast<uint64_t>(halStreams[0].producerUsage),
-                                              static_cast<uint64_t>(halStreams[0].consumerUsage)),
+                                              static_cast<uint64_t>(halStreams[0].consumerUsage))),
                                       halStreams[0].overrideFormat, &buffers[i]);
                 outputBuffer = {halStreams[0].id, bufferId + i,   ::android::makeToAidl(buffers[i]),
                                 BufferStatus::OK, NativeHandle(), NativeHandle()};
@@ -2378,9 +2379,9 @@
             bufferId = 0;
         } else {
             allocateGraphicBuffer(previewStream.width, previewStream.height,
-                                  android_convertGralloc1To0Usage(
+                                  ANDROID_NATIVE_UNSIGNED_CAST(android_convertGralloc1To0Usage(
                                           static_cast<uint64_t>(halStreams[0].producerUsage),
-                                          static_cast<uint64_t>(halStreams[0].consumerUsage)),
+                                          static_cast<uint64_t>(halStreams[0].consumerUsage))),
                                   halStreams[0].overrideFormat, &buffer_handle);
         }
 
@@ -2501,9 +2502,9 @@
             } else {
                 // jpeg buffer (w,h) = (blobLen, 1)
                 allocateGraphicBuffer(jpegBufferSize, /*height*/ 1,
-                                      android_convertGralloc1To0Usage(
+                                      ANDROID_NATIVE_UNSIGNED_CAST(android_convertGralloc1To0Usage(
                                               static_cast<uint64_t>(halStream.producerUsage),
-                                              static_cast<uint64_t>(halStream.consumerUsage)),
+                                              static_cast<uint64_t>(halStream.consumerUsage))),
                                       halStream.overrideFormat, &buffers[i]);
                 outputBuffer = {halStream.id,     bufferId + i,   ::android::makeToAidl(buffers[i]),
                                 BufferStatus::OK, NativeHandle(), NativeHandle()};
@@ -2727,9 +2728,9 @@
                             BufferStatus::OK, NativeHandle(), NativeHandle()};
         } else {
             allocateGraphicBuffer(previewStream.width, previewStream.height,
-                                  android_convertGralloc1To0Usage(
+                                  ANDROID_NATIVE_UNSIGNED_CAST(android_convertGralloc1To0Usage(
                                           static_cast<uint64_t>(halStreams[0].producerUsage),
-                                          static_cast<uint64_t>(halStreams[0].consumerUsage)),
+                                          static_cast<uint64_t>(halStreams[0].consumerUsage))),
                                   halStreams[0].overrideFormat, &buffer_handle);
             outputBuffer = {halStreams[0].id, bufferId,       ::android::makeToAidl(buffer_handle),
                             BufferStatus::OK, NativeHandle(), NativeHandle()};
diff --git a/camera/provider/aidl/vts/camera_aidl_test.cpp b/camera/provider/aidl/vts/camera_aidl_test.cpp
index aef50d4..1673ab0 100644
--- a/camera/provider/aidl/vts/camera_aidl_test.cpp
+++ b/camera/provider/aidl/vts/camera_aidl_test.cpp
@@ -41,6 +41,7 @@
 #include <regex>
 #include <typeinfo>
 #include "utils/Errors.h"
+#include <nativebase/nativebase.h>
 
 using ::aidl::android::hardware::camera::common::CameraDeviceStatus;
 using ::aidl::android::hardware::camera::common::TorchModeStatus;
@@ -2337,8 +2338,8 @@
                     /* We don't look at halStreamConfig.streams[0].consumerUsage
                      * since that is 0 for output streams
                      */
-                    android_convertGralloc1To0Usage(
-                            static_cast<uint64_t>(halStreams[0].producerUsage), bufferUsage),
+                    ANDROID_NATIVE_UNSIGNED_CAST(android_convertGralloc1To0Usage(
+                            static_cast<uint64_t>(halStreams[0].producerUsage), bufferUsage)),
                     halStreams[0].overrideFormat, &handle);
 
             outputBuffer = {halStreams[0].id, bufferId,       ::android::makeToAidl(handle),
@@ -2865,9 +2866,9 @@
                                   /* We don't look at halStreamConfig.streams[0].consumerUsage
                                    * since that is 0 for output streams
                                    */
-                                  android_convertGralloc1To0Usage(
+                                  ANDROID_NATIVE_UNSIGNED_CAST(android_convertGralloc1To0Usage(
                                           static_cast<uint64_t>(halStreams[0].producerUsage),
-                                          GRALLOC1_CONSUMER_USAGE_HWCOMPOSER),
+                                          GRALLOC1_CONSUMER_USAGE_HWCOMPOSER)),
                                   halStreams[0].overrideFormat, &buffer_handle);
             outputBuffer = {halStreams[0].id, bufferId,       ::android::makeToAidl(buffer_handle),
                             BufferStatus::OK, NativeHandle(), NativeHandle()};
@@ -3848,9 +3849,9 @@
                                         NativeHandle(), BufferStatus::OK,
                                         NativeHandle(), NativeHandle()};
                 } else {
-                    auto usage = android_convertGralloc1To0Usage(
+                    auto usage = ANDROID_NATIVE_UNSIGNED_CAST(android_convertGralloc1To0Usage(
                             static_cast<uint64_t>(halStream.producerUsage),
-                            static_cast<uint64_t>(halStream.consumerUsage));
+                            static_cast<uint64_t>(halStream.consumerUsage)));
                     allocateGraphicBuffer(previewStream.width, previewStream.height, usage,
                                             halStream.overrideFormat, &buffer_handle);
 
@@ -4006,9 +4007,9 @@
                                 NativeHandle(),   NativeHandle()};
             } else {
                 allocateGraphicBuffer(previewStream.width, previewStream.height,
-                                      android_convertGralloc1To0Usage(
+                                      ANDROID_NATIVE_UNSIGNED_CAST(android_convertGralloc1To0Usage(
                                               static_cast<uint64_t>(halStreams[0].producerUsage),
-                                              static_cast<uint64_t>(halStreams[0].consumerUsage)),
+                                              static_cast<uint64_t>(halStreams[0].consumerUsage))),
                                       halStreams[0].overrideFormat, &buffers[i]);
                 outputBuffer = {halStreams[0].id, bufferId + i,   ::android::makeToAidl(buffers[i]),
                                 BufferStatus::OK, NativeHandle(), NativeHandle()};
diff --git a/camera/provider/aidl/vts/device_cb.cpp b/camera/provider/aidl/vts/device_cb.cpp
index 2c11d3f..8a8b925 100644
--- a/camera/provider/aidl/vts/device_cb.cpp
+++ b/camera/provider/aidl/vts/device_cb.cpp
@@ -20,6 +20,7 @@
 #include <aidlcommonsupport/NativeHandle.h>
 #include <grallocusage/GrallocUsageConversion.h>
 #include <cinttypes>
+#include <nativebase/nativebase.h>
 
 using ::aidl::android::hardware::camera::device::BufferStatus;
 using ::aidl::android::hardware::camera::device::ErrorMsg;
@@ -143,8 +144,8 @@
 
             CameraAidlTest::allocateGraphicBuffer(
                     w, h,
-                    android_convertGralloc1To0Usage(static_cast<uint64_t>(halStream.producerUsage),
-                                                    static_cast<uint64_t>(halStream.consumerUsage)),
+                    ANDROID_NATIVE_UNSIGNED_CAST(android_convertGralloc1To0Usage(static_cast<uint64_t>(halStream.producerUsage),
+                                                    static_cast<uint64_t>(halStream.consumerUsage))),
                     halStream.overrideFormat, &handle);
 
             StreamBuffer streamBuffer = StreamBuffer();
diff --git a/common/aidl/Android.bp b/common/aidl/Android.bp
index 1457b8a..1f5742d 100644
--- a/common/aidl/Android.bp
+++ b/common/aidl/Android.bp
@@ -11,11 +11,8 @@
     name: "android.hardware.common",
     host_supported: true,
     vendor_available: true,
-    vndk: {
-        enabled: true,
-        support_system_process: true,
-    },
-    vndk_use_version: "2",
+    product_available: true,
+    double_loadable: true,
     srcs: [
         "android/hardware/common/*.aidl",
     ],
diff --git a/common/fmq/aidl/Android.bp b/common/fmq/aidl/Android.bp
index 6c37213..9c1b45d 100644
--- a/common/fmq/aidl/Android.bp
+++ b/common/fmq/aidl/Android.bp
@@ -11,10 +11,8 @@
     name: "android.hardware.common.fmq",
     host_supported: true,
     vendor_available: true,
-    vndk: {
-        enabled: true,
-        support_system_process: true,
-    },
+    product_available: true,
+    double_loadable: true,
     srcs: [
         "android/hardware/common/fmq/*.aidl",
     ],
diff --git a/common/support/Android.bp b/common/support/Android.bp
index 12ab1f7..56700fa 100644
--- a/common/support/Android.bp
+++ b/common/support/Android.bp
@@ -10,6 +10,7 @@
 cc_library_static {
     name: "libaidlcommonsupport",
     vendor_available: true,
+    product_available: true,
     host_supported: true,
     target: {
         darwin: {
diff --git a/compatibility_matrices/Android.bp b/compatibility_matrices/Android.bp
index 2b69442..ad42015 100644
--- a/compatibility_matrices/Android.bp
+++ b/compatibility_matrices/Android.bp
@@ -88,8 +88,29 @@
     stem: "compatibility_matrix.202504.xml",
     srcs: ["compatibility_matrix.202504.xml"],
     kernel_configs: [
-        "kernel_config_w_6.1",
-        "kernel_config_w_6.6",
+        "kernel_config_w_6.next",
     ],
 
 }
+
+// Phony target that installs all system compatibility matrix files
+SYSTEM_MATRIX_DEPS = [
+    "framework_compatibility_matrix.5.xml",
+    "framework_compatibility_matrix.6.xml",
+    "framework_compatibility_matrix.7.xml",
+    "framework_compatibility_matrix.8.xml",
+    "framework_compatibility_matrix.202404.xml",
+    "framework_compatibility_matrix.device.xml",
+]
+
+phony {
+    name: "system_compatibility_matrix.xml",
+    required: SYSTEM_MATRIX_DEPS,
+    product_variables: {
+        release_aidl_use_unfrozen: {
+            required: [
+                "framework_compatibility_matrix.202504.xml",
+            ],
+        },
+    },
+}
diff --git a/compatibility_matrices/Android.mk b/compatibility_matrices/Android.mk
index ab57b8c..338c075 100644
--- a/compatibility_matrices/Android.mk
+++ b/compatibility_matrices/Android.mk
@@ -119,15 +119,6 @@
 my_framework_matrix_deps += \
     $(my_system_matrix_deps)
 
-# Phony target that installs all system compatibility matrix files
-include $(CLEAR_VARS)
-LOCAL_MODULE := system_compatibility_matrix.xml
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../NOTICE
-LOCAL_REQUIRED_MODULES := $(my_system_matrix_deps)
-include $(BUILD_PHONY_PACKAGE)
-
 # Phony target that installs all framework compatibility matrix files (system + product)
 include $(CLEAR_VARS)
 LOCAL_MODULE := framework_compatibility_matrix.xml
diff --git a/compatibility_matrices/compatibility_matrix.202404.xml b/compatibility_matrices/compatibility_matrix.202404.xml
index cf7de22..9ea476a 100644
--- a/compatibility_matrices/compatibility_matrix.202404.xml
+++ b/compatibility_matrices/compatibility_matrix.202404.xml
@@ -529,6 +529,7 @@
             <name>ISharedSecret</name>
             <instance>default</instance>
             <instance>strongbox</instance>
+            <regex-instance>.*</regex-instance>
         </interface>
     </hal>
     <hal format="aidl">
diff --git a/configstore/1.0/Android.bp b/configstore/1.0/Android.bp
index 51fc44c..ef781d2 100644
--- a/configstore/1.0/Android.bp
+++ b/configstore/1.0/Android.bp
@@ -12,9 +12,6 @@
 hidl_interface {
     name: "android.hardware.configstore@1.0",
     root: "android.hardware",
-    vndk: {
-        enabled: true,
-    },
     srcs: [
         "types.hal",
         "ISurfaceFlingerConfigs.hal",
diff --git a/configstore/1.1/Android.bp b/configstore/1.1/Android.bp
index ec745dd..c8c3f5e 100644
--- a/configstore/1.1/Android.bp
+++ b/configstore/1.1/Android.bp
@@ -12,9 +12,6 @@
 hidl_interface {
     name: "android.hardware.configstore@1.1",
     root: "android.hardware",
-    vndk: {
-        enabled: true,
-    },
     srcs: [
         "types.hal",
         "ISurfaceFlingerConfigs.hal",
diff --git a/configstore/utils/Android.bp b/configstore/utils/Android.bp
index 7ed3f68..b62f1bc 100644
--- a/configstore/utils/Android.bp
+++ b/configstore/utils/Android.bp
@@ -26,13 +26,10 @@
 cc_library_shared {
     name: "android.hardware.configstore-utils",
     vendor_available: true,
-    vndk: {
-        enabled: true,
-    },
     double_loadable: true,
     defaults: ["hidl_defaults"],
 
-    srcs: [ "ConfigStoreUtils.cpp" ],
+    srcs: ["ConfigStoreUtils.cpp"],
 
     export_include_dirs: ["include"],
 
@@ -40,12 +37,12 @@
         "android.hardware.configstore@1.0",
         "android.hardware.configstore@1.1",
         "libbase",
-        "libhidlbase"
+        "libhidlbase",
     ],
     export_shared_lib_headers: [
         "android.hardware.configstore@1.0",
         "android.hardware.configstore@1.1",
         "libbase",
-        "libhidlbase"
+        "libhidlbase",
     ],
 }
diff --git a/confirmationui/aidl/android/hardware/confirmationui/IConfirmationResultCallback.aidl b/confirmationui/aidl/android/hardware/confirmationui/IConfirmationResultCallback.aidl
index 92328a8..dcce7ef 100644
--- a/confirmationui/aidl/android/hardware/confirmationui/IConfirmationResultCallback.aidl
+++ b/confirmationui/aidl/android/hardware/confirmationui/IConfirmationResultCallback.aidl
@@ -38,15 +38,15 @@
      * prevented the TUI from being shut down gracefully.
      *
      * @param formattedMessage holds the prompt text and extra data.
-     *                         The message is CBOR (RFC 7049) encoded and has the following format:
-     *                         CBOR_MAP{ "prompt", <promptText>, "extra", <extraData> }
-     *                         The message is a CBOR encoded map (type 5) with the keys
-     *                         "prompt" and "extra". The keys are encoded as CBOR text string
-     *                         (type 3). The value <promptText> is encoded as CBOR text string
-     *                         (type 3), and the value <extraData> is encoded as CBOR byte string
-     *                         (type 2). The map must have exactly one key value pair for each of
-     *                         the keys "prompt" and "extra". Other keys are not allowed.
-     *                         The value of "prompt" is given by the proptText argument to
+     *                         The message is CBOR (RFC 7049) encoded and has the exact format
+     *                         given by the following CDDL:
+     *
+     *                         formattedMessage = {
+     *                             "prompt" : tstr,
+     *                             "extra" : bstr,
+     *                         }
+     *
+     *                         The value of "prompt" is given by the promptText argument to
      *                         IConfirmationUI::promptUserConfirmation and must not be modified
      *                         by the implementation.
      *                         The value of "extra" is given by the extraData argument to
@@ -59,8 +59,7 @@
      *                          the "", concatenated with the formatted message as returned in the
      *                          formattedMessage argument. The HMAC is keyed with a 256-bit secret
      *                          which is shared with Keymaster. In test mode the test key MUST be
-     *                          used (see TestModeCommands.aidl and
-     * IConfirmationUI::TEST_KEY_BYTE).
+     *                          used (see TestModeCommands.aidl and IConfirmationUI::TEST_KEY_BYTE)
      */
     void result(in int error, in byte[] formattedMessage, in byte[] confirmationToken);
 }
diff --git a/confirmationui/aidl/vts/functional/VtsHalConfirmationUITargetTest.cpp b/confirmationui/aidl/vts/functional/VtsHalConfirmationUITargetTest.cpp
index 61dae8b..7ffd146 100644
--- a/confirmationui/aidl/vts/functional/VtsHalConfirmationUITargetTest.cpp
+++ b/confirmationui/aidl/vts/functional/VtsHalConfirmationUITargetTest.cpp
@@ -192,6 +192,12 @@
   public:
     void TearDown() override { confirmator_->abort(); }
     void SetUp() override {
+        // Wake up the device in-case screen is off. b/332827323
+        int ret = system("input keyevent KEYCODE_WAKEUP");
+        if (ret != 0) {
+            ALOGE("Failed to run keyevent KEYCODE_WAKEUP command");
+        }
+        usleep(100000);  // wait for 100ms to wake up the screen.
         std::string name = GetParam();
         ASSERT_TRUE(AServiceManager_isDeclared(name.c_str())) << name;
         ndk::SpAIBinder binder(AServiceManager_waitForService(name.c_str()));
diff --git a/confirmationui/support/Android.bp b/confirmationui/support/Android.bp
index 1200115..67cc04b 100644
--- a/confirmationui/support/Android.bp
+++ b/confirmationui/support/Android.bp
@@ -27,9 +27,6 @@
     name: "android.hardware.confirmationui-support-lib",
     vendor_available: true,
     host_supported: true,
-    vndk: {
-        enabled: true,
-    },
     srcs: [
         "src/cbor.cpp",
         "src/confirmationui_utils.cpp",
diff --git a/contexthub/OWNERS b/contexthub/OWNERS
index ee25833..f35961a 100644
--- a/contexthub/OWNERS
+++ b/contexthub/OWNERS
@@ -1,3 +1,2 @@
 # Bug component: 156070
-arthuri@google.com
 bduddie@google.com
diff --git a/dumpstate/OWNERS b/dumpstate/OWNERS
index 4c9173e..b0ef9da 100644
--- a/dumpstate/OWNERS
+++ b/dumpstate/OWNERS
@@ -1,3 +1,3 @@
-# Bug component: 298624585
+# Bug component: 153446
 
 include platform/frameworks/native:/cmds/dumpstate/OWNERS
diff --git a/gatekeeper/aidl/software/Android.bp b/gatekeeper/aidl/software/Android.bp
new file mode 100644
index 0000000..d244461
--- /dev/null
+++ b/gatekeeper/aidl/software/Android.bp
@@ -0,0 +1,71 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_binary {
+    name: "android.hardware.gatekeeper-service.nonsecure",
+    cflags: [
+        "-fvisibility=hidden",
+        "-Wall",
+        "-Werror",
+    ],
+    installable: false, // installed in APEX
+    relative_install_path: "hw",
+    shared_libs: [
+        "android.hardware.gatekeeper-V1-ndk",
+        "android.hardware.security.sharedsecret-V1-ndk",
+        "lib_android_keymaster_keymint_utils",
+        "libbase",
+        "libbinder_ndk",
+        "libcrypto",
+        "libcutils",
+        "libgatekeeper",
+        "libhardware",
+        "libkeymaster_portable",
+        "liblog",
+        "libutils",
+    ],
+    srcs: [
+        "GateKeeper.cpp",
+        "SharedSecret.cpp",
+        "service.cpp",
+    ],
+    static_libs: ["libscrypt_static"],
+    vendor: true,
+}
+
+prebuilt_etc {
+    name: "gatekeeper_nonsecure_vintf",
+    srcs: [
+        "android.hardware.gatekeeper-service.nonsecure.xml",
+        "android.hardware.security.sharedsecret-gatekeeper.xml",
+    ],
+    sub_dir: "vintf",
+    installable: false,
+}
+
+prebuilt_etc {
+    name: "android.hardware.gatekeeper-service.nonsecure.rc",
+    src: "android.hardware.gatekeeper-service.nonsecure.rc",
+    installable: false,
+}
+
+apex {
+    name: "com.android.hardware.gatekeeper.nonsecure",
+    binaries: ["android.hardware.gatekeeper-service.nonsecure"],
+    certificate: ":com.google.cf.apex.certificate",
+    file_contexts: "file_contexts",
+    key: "com.google.cf.apex.key",
+    manifest: "manifest.json",
+    prebuilts: [
+        "gatekeeper_nonsecure_vintf",
+        "android.hardware.gatekeeper-service.nonsecure.rc",
+    ],
+    updatable: false,
+    vendor: true,
+}
diff --git a/gatekeeper/aidl/software/GateKeeper.cpp b/gatekeeper/aidl/software/GateKeeper.cpp
new file mode 100644
index 0000000..1fc3682
--- /dev/null
+++ b/gatekeeper/aidl/software/GateKeeper.cpp
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+#define LOG_TAG "android.hardware.gatekeeper-service.nonsecure"
+
+#include <endian.h>
+
+#include <android-base/logging.h>
+
+#include "GateKeeper.h"
+
+using ::gatekeeper::EnrollRequest;
+using ::gatekeeper::EnrollResponse;
+using ::gatekeeper::ERROR_NONE;
+using ::gatekeeper::ERROR_RETRY;
+using ::gatekeeper::SizedBuffer;
+using ::gatekeeper::VerifyRequest;
+using ::gatekeeper::VerifyResponse;
+
+namespace aidl::android::hardware::gatekeeper {
+
+SizedBuffer vec2sized_buffer(const std::vector<uint8_t>& vec) {
+    if (vec.size() == 0 || vec.size() > std::numeric_limits<uint32_t>::max()) {
+        return {};
+    }
+    auto unused = new uint8_t[vec.size()];
+    std::copy(vec.begin(), vec.end(), unused);
+    return {unused, static_cast<uint32_t>(vec.size())};
+}
+
+void sizedBuffer2AidlHWToken(SizedBuffer& buffer,
+                             android::hardware::security::keymint::HardwareAuthToken* aidlToken) {
+    const hw_auth_token_t* authToken =
+            reinterpret_cast<const hw_auth_token_t*>(buffer.Data<uint8_t>());
+    aidlToken->challenge = authToken->challenge;
+    aidlToken->userId = authToken->user_id;
+    aidlToken->authenticatorId = authToken->authenticator_id;
+    // these are in network order: translate to host
+    aidlToken->authenticatorType =
+            static_cast<android::hardware::security::keymint::HardwareAuthenticatorType>(
+                    be32toh(authToken->authenticator_type));
+    aidlToken->timestamp.milliSeconds = be64toh(authToken->timestamp);
+    aidlToken->mac.insert(aidlToken->mac.begin(), std::begin(authToken->hmac),
+                          std::end(authToken->hmac));
+}
+
+SoftGateKeeperDevice::SoftGateKeeperDevice(::gatekeeper::SoftGateKeeper& impl) : impl_(impl) {}
+
+::ndk::ScopedAStatus SoftGateKeeperDevice::enroll(int32_t uid,
+                                                  const std::vector<uint8_t>& currentPasswordHandle,
+                                                  const std::vector<uint8_t>& currentPassword,
+                                                  const std::vector<uint8_t>& desiredPassword,
+                                                  GatekeeperEnrollResponse* rsp) {
+    if (desiredPassword.size() == 0) {
+        LOG(ERROR) << "Desired password size is 0";
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificError(ERROR_GENERAL_FAILURE));
+    }
+
+    if (currentPasswordHandle.size() > 0) {
+        if (currentPasswordHandle.size() != sizeof(::gatekeeper::password_handle_t)) {
+            LOG(ERROR) << "Password handle has wrong length";
+            return ndk::ScopedAStatus(AStatus_fromServiceSpecificError(ERROR_GENERAL_FAILURE));
+        }
+    }
+
+    EnrollRequest request(uid, vec2sized_buffer(currentPasswordHandle),
+                          vec2sized_buffer(desiredPassword), vec2sized_buffer(currentPassword));
+    EnrollResponse response;
+    impl_.Enroll(request, &response);
+    if (response.error == ERROR_RETRY) {
+        LOG(ERROR) << "Enroll response has a retry error";
+        *rsp = {ERROR_RETRY_TIMEOUT, static_cast<int32_t>(response.retry_timeout), 0, {}};
+        return ndk::ScopedAStatus::ok();
+    } else if (response.error != ERROR_NONE) {
+        LOG(ERROR) << "Enroll response has an error: " << response.error;
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificError(ERROR_GENERAL_FAILURE));
+    } else {
+        const ::gatekeeper::password_handle_t* password_handle =
+                response.enrolled_password_handle.Data<::gatekeeper::password_handle_t>();
+        *rsp = {STATUS_OK,
+                0,
+                static_cast<int64_t>(password_handle->user_id),
+                {response.enrolled_password_handle.Data<uint8_t>(),
+                 (response.enrolled_password_handle.Data<uint8_t>() +
+                  response.enrolled_password_handle.size())}};
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus SoftGateKeeperDevice::verify(
+        int32_t uid, int64_t challenge, const std::vector<uint8_t>& enrolledPasswordHandle,
+        const std::vector<uint8_t>& providedPassword, GatekeeperVerifyResponse* rsp) {
+    if (enrolledPasswordHandle.size() == 0) {
+        LOG(ERROR) << "Enrolled password size is 0";
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificError(ERROR_GENERAL_FAILURE));
+    }
+
+    if (enrolledPasswordHandle.size() > 0) {
+        if (enrolledPasswordHandle.size() != sizeof(::gatekeeper::password_handle_t)) {
+            LOG(ERROR) << "Password handle has wrong length";
+            return ndk::ScopedAStatus(AStatus_fromServiceSpecificError(ERROR_GENERAL_FAILURE));
+        }
+    }
+
+    VerifyRequest request(uid, challenge, vec2sized_buffer(enrolledPasswordHandle),
+                          vec2sized_buffer(providedPassword));
+    VerifyResponse response;
+    impl_.Verify(request, &response);
+
+    if (response.error == ERROR_RETRY) {
+        LOG(ERROR) << "Verify request response gave retry error";
+        *rsp = {ERROR_RETRY_TIMEOUT, static_cast<int32_t>(response.retry_timeout), {}};
+        return ndk::ScopedAStatus::ok();
+    } else if (response.error != ERROR_NONE) {
+        LOG(ERROR) << "Verify request response gave error: " << response.error;
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificError(ERROR_GENERAL_FAILURE));
+    } else {
+        // On Success, return GatekeeperVerifyResponse with Success Status, timeout{0} and
+        // valid HardwareAuthToken.
+        *rsp = {response.request_reenroll ? STATUS_REENROLL : STATUS_OK, 0, {}};
+        // Convert the hw_auth_token_t to HardwareAuthToken in the response.
+        sizedBuffer2AidlHWToken(response.auth_token, &rsp->hardwareAuthToken);
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus SoftGateKeeperDevice::deleteUser(int32_t /*uid*/) {
+    LOG(ERROR) << "deleteUser is unimplemented";
+    return ndk::ScopedAStatus(AStatus_fromServiceSpecificError(ERROR_NOT_IMPLEMENTED));
+}
+
+::ndk::ScopedAStatus SoftGateKeeperDevice::deleteAllUsers() {
+    LOG(ERROR) << "deleteAllUsers is unimplemented";
+    return ndk::ScopedAStatus(AStatus_fromServiceSpecificError(ERROR_NOT_IMPLEMENTED));
+}
+
+}  // namespace aidl::android::hardware::gatekeeper
diff --git a/gatekeeper/aidl/software/GateKeeper.h b/gatekeeper/aidl/software/GateKeeper.h
new file mode 100644
index 0000000..1327fad
--- /dev/null
+++ b/gatekeeper/aidl/software/GateKeeper.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include <aidl/android/hardware/gatekeeper/BnGatekeeper.h>
+#include <gatekeeper/gatekeeper_messages.h>
+
+#include "SoftGateKeeper.h"
+
+namespace aidl::android::hardware::gatekeeper {
+
+class SoftGateKeeperDevice : public BnGatekeeper {
+  public:
+    SoftGateKeeperDevice(::gatekeeper::SoftGateKeeper&);
+    /**
+     * Enrolls password_payload, which should be derived from a user selected pin
+     * or password, with the authentication factor private key used only for
+     * enrolling authentication factor data.
+     *
+     * Returns: 0 on success or an error code less than 0 on error.
+     * On error, enrolled_password_handle will not be allocated.
+     */
+    ::ndk::ScopedAStatus enroll(int32_t uid, const std::vector<uint8_t>& currentPasswordHandle,
+                                const std::vector<uint8_t>& currentPassword,
+                                const std::vector<uint8_t>& desiredPassword,
+                                GatekeeperEnrollResponse* _aidl_return) override;
+    /**
+     * Verifies provided_password matches enrolled_password_handle.
+     *
+     * Implementations of this module may retain the result of this call
+     * to attest to the recency of authentication.
+     *
+     * On success, writes the address of a verification token to auth_token,
+     * usable to attest password verification to other trusted services. Clients
+     * may pass NULL for this value.
+     *
+     * Returns: 0 on success or an error code less than 0 on error
+     * On error, verification token will not be allocated
+     */
+    ::ndk::ScopedAStatus verify(int32_t uid, int64_t challenge,
+                                const std::vector<uint8_t>& enrolledPasswordHandle,
+                                const std::vector<uint8_t>& providedPassword,
+                                GatekeeperVerifyResponse* _aidl_return) override;
+
+    ::ndk::ScopedAStatus deleteAllUsers() override;
+
+    ::ndk::ScopedAStatus deleteUser(int32_t uid) override;
+
+  private:
+    ::gatekeeper::SoftGateKeeper& impl_;
+};
+
+}  // namespace aidl::android::hardware::gatekeeper
diff --git a/gatekeeper/aidl/software/SharedSecret.cpp b/gatekeeper/aidl/software/SharedSecret.cpp
new file mode 100644
index 0000000..f693700
--- /dev/null
+++ b/gatekeeper/aidl/software/SharedSecret.cpp
@@ -0,0 +1,131 @@
+/*
+ * Copyright 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 "SharedSecret.h"
+
+#include <algorithm>
+#include <cstring>
+#include <mutex>
+#include <vector>
+
+#include <openssl/rand.h>
+
+#include <KeyMintUtils.h>
+#include <aidl/android/hardware/security/sharedsecret/BnSharedSecret.h>
+#include <aidl/android/hardware/security/sharedsecret/SharedSecretParameters.h>
+#include <android-base/logging.h>
+#include <keymaster/android_keymaster_messages.h>
+#include <keymaster/android_keymaster_utils.h>
+#include <keymaster/km_openssl/ckdf.h>
+#include <keymaster/km_openssl/hmac.h>
+
+namespace aidl::android::hardware::security::sharedsecret {
+
+::ndk::ScopedAStatus SoftSharedSecret::getSharedSecretParameters(
+        SharedSecretParameters* out_params) {
+    std::lock_guard lock(mutex_);
+    if (seed_.empty()) {
+        seed_.resize(32, 0);
+    }
+    out_params->seed = seed_;
+    if (nonce_.empty()) {
+        nonce_.resize(32, 0);
+        RAND_bytes(nonce_.data(), 32);
+    }
+    out_params->nonce = nonce_;
+    LOG(INFO) << "Presented shared secret parameters with seed size " << out_params->seed.size()
+              << " and nonce size " << out_params->nonce.size();
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus SoftSharedSecret::computeSharedSecret(
+        const std::vector<SharedSecretParameters>& params, std::vector<uint8_t>* sharing_check) {
+    std::lock_guard lock(mutex_);
+    LOG(INFO) << "Computing shared secret";
+    // Reimplemented based on SoftKeymasterEnforcement, which does not expose
+    // enough functionality to satisfy the GateKeeper interface
+    keymaster::KeymasterKeyBlob key_agreement_key;
+    if (key_agreement_key.Reset(32) == nullptr) {
+        LOG(ERROR) << "key agreement key memory allocation failed";
+        return keymint::km_utils::kmError2ScopedAStatus(KM_ERROR_MEMORY_ALLOCATION_FAILED);
+    }
+    // Matching:
+    // - kFakeAgreementKey in system/keymaster/km_openssl/soft_keymaster_enforcement.cpp
+    // - Keys::kak in hardware/interfaces/security/keymint/aidl/default/ta/soft.rs
+    std::memset(key_agreement_key.writable_data(), 0, 32);
+    keymaster::KeymasterBlob label((uint8_t*)KEY_AGREEMENT_LABEL, strlen(KEY_AGREEMENT_LABEL));
+    if (label.data == nullptr) {
+        LOG(ERROR) << "label memory allocation failed";
+        return keymint::km_utils::kmError2ScopedAStatus(KM_ERROR_MEMORY_ALLOCATION_FAILED);
+    }
+
+    static_assert(sizeof(keymaster_blob_t) == sizeof(keymaster::KeymasterBlob));
+
+    bool found_mine = false;
+    std::vector<keymaster::KeymasterBlob> context_blobs;
+    for (const auto& param : params) {
+        auto& seed_blob = context_blobs.emplace_back();
+        if (seed_blob.Reset(param.seed.size()) == nullptr) {
+            LOG(ERROR) << "seed memory allocation failed";
+            return keymint::km_utils::kmError2ScopedAStatus(KM_ERROR_MEMORY_ALLOCATION_FAILED);
+        }
+        std::copy(param.seed.begin(), param.seed.end(), seed_blob.writable_data());
+        auto& nonce_blob = context_blobs.emplace_back();
+        if (nonce_blob.Reset(param.nonce.size()) == nullptr) {
+            LOG(ERROR) << "Nonce memory allocation failed";
+            return keymint::km_utils::kmError2ScopedAStatus(KM_ERROR_MEMORY_ALLOCATION_FAILED);
+        }
+        std::copy(param.nonce.begin(), param.nonce.end(), nonce_blob.writable_data());
+        if (param.seed == seed_ && param.nonce == nonce_) {
+            found_mine = true;
+        }
+    }
+    if (!found_mine) {
+        LOG(ERROR) << "Did not receive my own shared secret parameter back";
+        return keymint::km_utils::kmError2ScopedAStatus(KM_ERROR_INVALID_ARGUMENT);
+    }
+    auto context_blobs_ptr = reinterpret_cast<keymaster_blob_t*>(context_blobs.data());
+    if (hmac_key_.Reset(32) == nullptr) {
+        LOG(ERROR) << "hmac key allocation failed";
+        return keymint::km_utils::kmError2ScopedAStatus(KM_ERROR_MEMORY_ALLOCATION_FAILED);
+    }
+    auto error = keymaster::ckdf(key_agreement_key, label, context_blobs_ptr, context_blobs.size(),
+                                 &hmac_key_);
+    if (error != KM_ERROR_OK) {
+        LOG(ERROR) << "CKDF failed";
+        return keymint::km_utils::kmError2ScopedAStatus(error);
+    }
+
+    keymaster::HmacSha256 hmac_impl;
+    if (!hmac_impl.Init(hmac_key_.key_material, hmac_key_.key_material_size)) {
+        LOG(ERROR) << "hmac initialization failed";
+        return ::ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+    }
+    sharing_check->clear();
+    sharing_check->resize(32, 0);
+    if (!hmac_impl.Sign((const uint8_t*)KEY_CHECK_LABEL, strlen(KEY_CHECK_LABEL),
+                        sharing_check->data(), sharing_check->size())) {
+        return ::ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+    }
+    return ::ndk::ScopedAStatus::ok();
+}
+
+keymaster::KeymasterKeyBlob SoftSharedSecret::HmacKey() const {
+    std::lock_guard lock(mutex_);
+    return hmac_key_;
+}
+
+}  // namespace aidl::android::hardware::security::sharedsecret
diff --git a/gatekeeper/aidl/software/SharedSecret.h b/gatekeeper/aidl/software/SharedSecret.h
new file mode 100644
index 0000000..1b804e7
--- /dev/null
+++ b/gatekeeper/aidl/software/SharedSecret.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2020, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <cstdint>
+#include <mutex>
+
+#include <aidl/android/hardware/security/sharedsecret/BnSharedSecret.h>
+#include <aidl/android/hardware/security/sharedsecret/SharedSecretParameters.h>
+#include <keymaster/km_openssl/soft_keymaster_enforcement.h>
+
+namespace aidl::android::hardware::security::sharedsecret {
+
+class SoftSharedSecret : public BnSharedSecret {
+  public:
+    ::ndk::ScopedAStatus getSharedSecretParameters(SharedSecretParameters* params) override;
+    ::ndk::ScopedAStatus computeSharedSecret(const std::vector<SharedSecretParameters>& params,
+                                             std::vector<uint8_t>* sharingCheck) override;
+
+    keymaster::KeymasterKeyBlob HmacKey() const;
+
+  private:
+    mutable std::mutex mutex_;
+    std::vector<std::uint8_t> seed_;
+    std::vector<std::uint8_t> nonce_;
+    keymaster::KeymasterKeyBlob hmac_key_;
+};
+
+}  // namespace aidl::android::hardware::security::sharedsecret
diff --git a/gatekeeper/aidl/software/SoftGateKeeper.h b/gatekeeper/aidl/software/SoftGateKeeper.h
new file mode 100644
index 0000000..305d997
--- /dev/null
+++ b/gatekeeper/aidl/software/SoftGateKeeper.h
@@ -0,0 +1,189 @@
+/*
+ * Copyright 2015 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.
+ *
+ */
+
+#ifndef SOFT_GATEKEEPER_H_
+#define SOFT_GATEKEEPER_H_
+
+extern "C" {
+#include <openssl/rand.h>
+#include <openssl/sha.h>
+
+#include <crypto_scrypt.h>
+}
+
+#include <memory>
+#include <unordered_map>
+
+#include <android-base/logging.h>
+#include <android-base/memory.h>
+#include <gatekeeper/gatekeeper.h>
+#include <keymaster/km_openssl/hmac.h>
+
+#include "SharedSecret.h"
+
+namespace gatekeeper {
+
+struct fast_hash_t {
+    uint64_t salt;
+    uint8_t digest[SHA256_DIGEST_LENGTH];
+};
+
+class SoftGateKeeper : public GateKeeper {
+  public:
+    static const uint32_t SIGNATURE_LENGTH_BYTES = 32;
+
+    // scrypt params
+    static const uint64_t N = 16384;
+    static const uint32_t r = 8;
+    static const uint32_t p = 1;
+
+    static const int MAX_UINT_32_CHARS = 11;
+
+    SoftGateKeeper(const ::aidl::android::hardware::security::sharedsecret::SoftSharedSecret&
+                           shared_secret)
+        : shared_secret_(shared_secret) {
+        key_.reset(new uint8_t[SIGNATURE_LENGTH_BYTES]);
+        memset(key_.get(), 0, SIGNATURE_LENGTH_BYTES);
+    }
+
+    virtual ~SoftGateKeeper() {}
+
+    virtual bool GetAuthTokenKey(const uint8_t** auth_token_key, uint32_t* length) const {
+        if (auth_token_key == NULL || length == NULL) return false;
+        if (hmac_key_.key_material == nullptr) {
+            hmac_key_ = shared_secret_.HmacKey();
+        }
+        *auth_token_key = hmac_key_.key_material;
+        *length = hmac_key_.key_material_size;
+        return true;
+    }
+
+    virtual void GetPasswordKey(const uint8_t** password_key, uint32_t* length) {
+        if (password_key == NULL || length == NULL) return;
+        *password_key = key_.get();
+        *length = SIGNATURE_LENGTH_BYTES;
+    }
+
+    virtual void ComputePasswordSignature(uint8_t* signature, uint32_t signature_length,
+                                          const uint8_t*, uint32_t, const uint8_t* password,
+                                          uint32_t password_length, salt_t salt) const {
+        if (signature == NULL) return;
+        crypto_scrypt(password, password_length, reinterpret_cast<uint8_t*>(&salt), sizeof(salt), N,
+                      r, p, signature, signature_length);
+    }
+
+    virtual void GetRandom(void* random, uint32_t requested_length) const {
+        if (random == NULL) return;
+        RAND_pseudo_bytes((uint8_t*)random, requested_length);
+    }
+
+    virtual void ComputeSignature(uint8_t* signature, uint32_t signature_length, const uint8_t* key,
+                                  uint32_t key_length, const uint8_t* message,
+                                  const uint32_t message_length) const {
+        if (signature == NULL) return;
+        keymaster::HmacSha256 hmac_calculator;
+        if (!hmac_calculator.Init(key, key_length)) {
+            LOG(ERROR) << "ComputeSignature: Failed to initialize hmac calculator";
+            return;
+        }
+        if (!hmac_calculator.Sign(message, message_length, signature, signature_length)) {
+            LOG(ERROR) << "ComputeSignature: failed to create hmac";
+        }
+    }
+
+    virtual uint64_t GetMillisecondsSinceBoot() const {
+        struct timespec time;
+        int res = clock_gettime(CLOCK_BOOTTIME, &time);
+        if (res < 0) return 0;
+        return (time.tv_sec * 1000) + (time.tv_nsec / 1000 / 1000);
+    }
+
+    virtual bool IsHardwareBacked() const { return false; }
+
+    virtual bool GetFailureRecord(uint32_t uid, secure_id_t user_id, failure_record_t* record,
+                                  bool /* secure */) {
+        failure_record_t* stored = &failure_map_[uid];
+        if (user_id != stored->secure_user_id) {
+            stored->secure_user_id = user_id;
+            stored->last_checked_timestamp = 0;
+            stored->failure_counter = 0;
+        }
+        memcpy(record, stored, sizeof(*record));
+        return true;
+    }
+
+    virtual bool ClearFailureRecord(uint32_t uid, secure_id_t user_id, bool /* secure */) {
+        failure_record_t* stored = &failure_map_[uid];
+        stored->secure_user_id = user_id;
+        stored->last_checked_timestamp = 0;
+        stored->failure_counter = 0;
+        return true;
+    }
+
+    virtual bool WriteFailureRecord(uint32_t uid, failure_record_t* record, bool /* secure */) {
+        failure_map_[uid] = *record;
+        return true;
+    }
+
+    fast_hash_t ComputeFastHash(const SizedBuffer& password, uint64_t salt) {
+        fast_hash_t fast_hash;
+        size_t digest_size = password.size() + sizeof(salt);
+        std::unique_ptr<uint8_t[]> digest(new uint8_t[digest_size]);
+        memcpy(digest.get(), &salt, sizeof(salt));
+        memcpy(digest.get() + sizeof(salt), password.Data<uint8_t>(), password.size());
+
+        SHA256(digest.get(), digest_size, (uint8_t*)&fast_hash.digest);
+
+        fast_hash.salt = salt;
+        return fast_hash;
+    }
+
+    bool VerifyFast(const fast_hash_t& fast_hash, const SizedBuffer& password) {
+        fast_hash_t computed = ComputeFastHash(password, fast_hash.salt);
+        return memcmp(computed.digest, fast_hash.digest, SHA256_DIGEST_LENGTH) == 0;
+    }
+
+    bool DoVerify(const password_handle_t* expected_handle, const SizedBuffer& password) {
+        uint64_t user_id = android::base::get_unaligned<secure_id_t>(&expected_handle->user_id);
+        FastHashMap::const_iterator it = fast_hash_map_.find(user_id);
+        if (it != fast_hash_map_.end() && VerifyFast(it->second, password)) {
+            return true;
+        } else {
+            if (GateKeeper::DoVerify(expected_handle, password)) {
+                uint64_t salt;
+                GetRandom(&salt, sizeof(salt));
+                fast_hash_map_[user_id] = ComputeFastHash(password, salt);
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+  private:
+    typedef std::unordered_map<uint32_t, failure_record_t> FailureRecordMap;
+    typedef std::unordered_map<uint64_t, fast_hash_t> FastHashMap;
+
+    const ::aidl::android::hardware::security::sharedsecret::SoftSharedSecret& shared_secret_;
+    std::unique_ptr<uint8_t[]> key_;
+    FailureRecordMap failure_map_;
+    FastHashMap fast_hash_map_;
+    mutable ::keymaster::KeymasterKeyBlob hmac_key_;
+};
+}  // namespace gatekeeper
+
+#endif  // SOFT_GATEKEEPER_H_
diff --git a/gatekeeper/aidl/software/android.hardware.gatekeeper-service.nonsecure.rc b/gatekeeper/aidl/software/android.hardware.gatekeeper-service.nonsecure.rc
new file mode 100644
index 0000000..d361730
--- /dev/null
+++ b/gatekeeper/aidl/software/android.hardware.gatekeeper-service.nonsecure.rc
@@ -0,0 +1,4 @@
+service vendor.gatekeeper_nonsecure /apex/com.android.hardware.gatekeeper/bin/hw/android.hardware.gatekeeper-service.nonsecure
+    class early_hal
+    user system
+    group system
diff --git a/gatekeeper/aidl/software/android.hardware.gatekeeper-service.nonsecure.xml b/gatekeeper/aidl/software/android.hardware.gatekeeper-service.nonsecure.xml
new file mode 100644
index 0000000..c35421e
--- /dev/null
+++ b/gatekeeper/aidl/software/android.hardware.gatekeeper-service.nonsecure.xml
@@ -0,0 +1,10 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.gatekeeper</name>
+        <version>1</version>
+        <interface>
+            <name>IGatekeeper</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+</manifest>
diff --git a/gatekeeper/aidl/software/android.hardware.security.sharedsecret-gatekeeper.xml b/gatekeeper/aidl/software/android.hardware.security.sharedsecret-gatekeeper.xml
new file mode 100644
index 0000000..5d94985
--- /dev/null
+++ b/gatekeeper/aidl/software/android.hardware.security.sharedsecret-gatekeeper.xml
@@ -0,0 +1,6 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.security.sharedsecret</name>
+        <fqname>ISharedSecret/gatekeeper</fqname>
+    </hal>
+</manifest>
diff --git a/gatekeeper/aidl/software/file_contexts b/gatekeeper/aidl/software/file_contexts
new file mode 100644
index 0000000..23a62ea
--- /dev/null
+++ b/gatekeeper/aidl/software/file_contexts
@@ -0,0 +1,3 @@
+(/.*)?                                                          u:object_r:vendor_file:s0
+/etc(/.*)?                                                      u:object_r:vendor_configs_file:s0
+/bin/hw/android\.hardware\.gatekeeper-service\.nonsecure        u:object_r:hal_gatekeeper_remote_exec:s0
diff --git a/gatekeeper/aidl/software/manifest.json b/gatekeeper/aidl/software/manifest.json
new file mode 100644
index 0000000..d0def36
--- /dev/null
+++ b/gatekeeper/aidl/software/manifest.json
@@ -0,0 +1,5 @@
+{
+    "name": "com.android.hardware.gatekeeper",
+    "version": 1,
+    "vendorBootstrap": true
+}
diff --git a/gatekeeper/aidl/software/service.cpp b/gatekeeper/aidl/software/service.cpp
new file mode 100644
index 0000000..beef8c4
--- /dev/null
+++ b/gatekeeper/aidl/software/service.cpp
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+#define LOG_TAG "android.hardware.gatekeeper-service.nonsecure"
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <cutils/properties.h>
+
+#include "GateKeeper.h"
+#include "SharedSecret.h"
+#include "SoftGateKeeper.h"
+
+using aidl::android::hardware::gatekeeper::SoftGateKeeperDevice;
+using aidl::android::hardware::security::sharedsecret::SoftSharedSecret;
+
+int main(int, char** argv) {
+    ::android::base::InitLogging(argv, ::android::base::KernelLogger);
+    ABinderProcess_setThreadPoolMaxThreadCount(0);
+
+    auto secret = ndk::SharedRefBase::make<SoftSharedSecret>();
+    std::string secret_instance = SoftSharedSecret::descriptor + std::string("/gatekeeper");
+    auto status = AServiceManager_addService(secret->asBinder().get(), secret_instance.c_str());
+    CHECK_EQ(status, STATUS_OK);
+
+    ::gatekeeper::SoftGateKeeper implementation(*secret);
+    auto gatekeeper = ndk::SharedRefBase::make<SoftGateKeeperDevice>(implementation);
+    const std::string instance = SoftGateKeeperDevice::descriptor + std::string("/default");
+    status = AServiceManager_addService(gatekeeper->asBinder().get(), instance.c_str());
+    CHECK_EQ(status, STATUS_OK);
+
+    ABinderProcess_joinThreadPool();
+    return -1;  // Should never get here.
+}
diff --git a/graphics/allocator/2.0/Android.bp b/graphics/allocator/2.0/Android.bp
index 36158e9..5d3f883 100644
--- a/graphics/allocator/2.0/Android.bp
+++ b/graphics/allocator/2.0/Android.bp
@@ -13,9 +13,6 @@
 hidl_interface {
     name: "android.hardware.graphics.allocator@2.0",
     root: "android.hardware",
-    vndk: {
-        enabled: true,
-    },
     srcs: [
         "IAllocator.hal",
     ],
diff --git a/graphics/allocator/3.0/Android.bp b/graphics/allocator/3.0/Android.bp
index 0100f6f..767a79f 100644
--- a/graphics/allocator/3.0/Android.bp
+++ b/graphics/allocator/3.0/Android.bp
@@ -13,9 +13,6 @@
 hidl_interface {
     name: "android.hardware.graphics.allocator@3.0",
     root: "android.hardware",
-    vndk: {
-        enabled: true,
-    },
     srcs: [
         "IAllocator.hal",
     ],
diff --git a/graphics/allocator/4.0/Android.bp b/graphics/allocator/4.0/Android.bp
index 5d7a4a9..590ecf4 100644
--- a/graphics/allocator/4.0/Android.bp
+++ b/graphics/allocator/4.0/Android.bp
@@ -13,9 +13,6 @@
 hidl_interface {
     name: "android.hardware.graphics.allocator@4.0",
     root: "android.hardware",
-    vndk: {
-        enabled: true,
-    },
     srcs: [
         "IAllocator.hal",
     ],
diff --git a/graphics/allocator/aidl/Android.bp b/graphics/allocator/aidl/Android.bp
index 6e24edc..7bb6b50 100644
--- a/graphics/allocator/aidl/Android.bp
+++ b/graphics/allocator/aidl/Android.bp
@@ -11,11 +11,7 @@
 aidl_interface {
     name: "android.hardware.graphics.allocator",
     vendor_available: true,
-    vndk: {
-        enabled: true,
-        support_system_process: true,
-    },
-    vndk_use_version: "2",
+    double_loadable: true,
     srcs: ["android/hardware/graphics/allocator/*.aidl"],
     imports: [
         "android.hardware.common-V2",
@@ -34,9 +30,6 @@
                 "//apex_available:platform",
                 "com.android.media.swcodec",
             ],
-            vndk: {
-                enabled: true,
-            },
             min_sdk_version: "29",
         },
     },
diff --git a/graphics/bufferqueue/1.0/Android.bp b/graphics/bufferqueue/1.0/Android.bp
index fe46b5e..c7c6453 100644
--- a/graphics/bufferqueue/1.0/Android.bp
+++ b/graphics/bufferqueue/1.0/Android.bp
@@ -13,9 +13,6 @@
 hidl_interface {
     name: "android.hardware.graphics.bufferqueue@1.0",
     root: "android.hardware",
-    vndk: {
-        enabled: true,
-    },
     srcs: [
         "IGraphicBufferProducer.hal",
         "IProducerListener.hal",
diff --git a/graphics/bufferqueue/2.0/Android.bp b/graphics/bufferqueue/2.0/Android.bp
index c2b0985..e9f75c1 100644
--- a/graphics/bufferqueue/2.0/Android.bp
+++ b/graphics/bufferqueue/2.0/Android.bp
@@ -13,9 +13,6 @@
 hidl_interface {
     name: "android.hardware.graphics.bufferqueue@2.0",
     root: "android.hardware",
-    vndk: {
-        enabled: true,
-    },
     srcs: [
         "types.hal",
         "IGraphicBufferProducer.hal",
diff --git a/graphics/common/1.0/Android.bp b/graphics/common/1.0/Android.bp
index 786953b..b876bf3 100644
--- a/graphics/common/1.0/Android.bp
+++ b/graphics/common/1.0/Android.bp
@@ -13,10 +13,6 @@
 hidl_interface {
     name: "android.hardware.graphics.common@1.0",
     root: "android.hardware",
-    vndk: {
-        enabled: true,
-        support_system_process: true,
-    },
     srcs: [
         "types.hal",
     ],
diff --git a/graphics/common/1.1/Android.bp b/graphics/common/1.1/Android.bp
index d857f80..ff6c9b7 100644
--- a/graphics/common/1.1/Android.bp
+++ b/graphics/common/1.1/Android.bp
@@ -13,10 +13,6 @@
 hidl_interface {
     name: "android.hardware.graphics.common@1.1",
     root: "android.hardware",
-    vndk: {
-        enabled: true,
-        support_system_process: true,
-    },
     srcs: [
         "types.hal",
     ],
diff --git a/graphics/common/1.2/Android.bp b/graphics/common/1.2/Android.bp
index 17d0c20..b4663e5 100644
--- a/graphics/common/1.2/Android.bp
+++ b/graphics/common/1.2/Android.bp
@@ -13,10 +13,6 @@
 hidl_interface {
     name: "android.hardware.graphics.common@1.2",
     root: "android.hardware",
-    vndk: {
-        enabled: true,
-        support_system_process: true,
-    },
     srcs: [
         "types.hal",
     ],
diff --git a/graphics/common/aidl/Android.bp b/graphics/common/aidl/Android.bp
index 570f735..4f5c3d9 100644
--- a/graphics/common/aidl/Android.bp
+++ b/graphics/common/aidl/Android.bp
@@ -12,11 +12,7 @@
     name: "android.hardware.graphics.common",
     host_supported: true,
     vendor_available: true,
-    vndk: {
-        enabled: true,
-        support_system_process: true,
-    },
-    vndk_use_version: "5",
+    double_loadable: true,
     srcs: [
         "android/hardware/graphics/common/*.aidl",
     ],
diff --git a/graphics/composer/aidl/Android.bp b/graphics/composer/aidl/Android.bp
index 87ecb16..c4e6878 100644
--- a/graphics/composer/aidl/Android.bp
+++ b/graphics/composer/aidl/Android.bp
@@ -28,12 +28,8 @@
     name: "android.hardware.graphics.composer3",
     host_supported: true,
     vendor_available: true,
-    vndk: {
-        enabled: true,
-        support_system_process: true,
-    },
+    double_loadable: true,
     frozen: true,
-    vndk_use_version: "1",
     srcs: [
         "android/hardware/graphics/composer3/*.aidl",
     ],
@@ -51,9 +47,6 @@
             enabled: false,
         },
         ndk: {
-            vndk: {
-                enabled: true,
-            },
         },
         rust: {
             enabled: true,
diff --git a/graphics/mapper/2.0/Android.bp b/graphics/mapper/2.0/Android.bp
index 81040ab..07ca1cb 100644
--- a/graphics/mapper/2.0/Android.bp
+++ b/graphics/mapper/2.0/Android.bp
@@ -13,10 +13,6 @@
 hidl_interface {
     name: "android.hardware.graphics.mapper@2.0",
     root: "android.hardware",
-    vndk: {
-        enabled: true,
-        support_system_process: true,
-    },
     srcs: [
         "types.hal",
         "IMapper.hal",
diff --git a/graphics/mapper/2.1/Android.bp b/graphics/mapper/2.1/Android.bp
index 1308a6c..f6e089a 100644
--- a/graphics/mapper/2.1/Android.bp
+++ b/graphics/mapper/2.1/Android.bp
@@ -13,10 +13,6 @@
 hidl_interface {
     name: "android.hardware.graphics.mapper@2.1",
     root: "android.hardware",
-    vndk: {
-        enabled: true,
-        support_system_process: true,
-    },
     srcs: [
         "IMapper.hal",
     ],
diff --git a/graphics/mapper/3.0/Android.bp b/graphics/mapper/3.0/Android.bp
index b49806f..0e15af9 100644
--- a/graphics/mapper/3.0/Android.bp
+++ b/graphics/mapper/3.0/Android.bp
@@ -13,10 +13,6 @@
 hidl_interface {
     name: "android.hardware.graphics.mapper@3.0",
     root: "android.hardware",
-    vndk: {
-        enabled: true,
-        support_system_process: true,
-    },
     srcs: [
         "types.hal",
         "IMapper.hal",
diff --git a/graphics/mapper/4.0/Android.bp b/graphics/mapper/4.0/Android.bp
index c07f73c..b2dd7d2 100644
--- a/graphics/mapper/4.0/Android.bp
+++ b/graphics/mapper/4.0/Android.bp
@@ -13,10 +13,6 @@
 hidl_interface {
     name: "android.hardware.graphics.mapper@4.0",
     root: "android.hardware",
-    vndk: {
-        enabled: true,
-        support_system_process: true,
-    },
     srcs: [
         "types.hal",
         "IMapper.hal",
diff --git a/graphics/mapper/stable-c/Android.bp b/graphics/mapper/stable-c/Android.bp
index 40486fd..82306be 100644
--- a/graphics/mapper/stable-c/Android.bp
+++ b/graphics/mapper/stable-c/Android.bp
@@ -59,6 +59,7 @@
     header_abi_checker: {
         enabled: true,
         symbol_file: "imapper.map.txt",
+        ref_dump_dirs: ["abi-dumps"],
     },
 }
 
diff --git a/graphics/mapper/stable-c/README.md b/graphics/mapper/stable-c/README.md
index 0b9b499..919119a 100644
--- a/graphics/mapper/stable-c/README.md
+++ b/graphics/mapper/stable-c/README.md
@@ -22,6 +22,12 @@
 ```
 defines that the IMapper 5.0 library is provided by `/vendor/lib[64]/hw/mapper.minigbm.so`.
 
+ServiceManager should be able to `find` the instance. The instance should be labelled in
+`service_contexts` as follows:
+```
+mapper/minigbm    u:object_r:hal_graphics_mapper_service:s0
+```
+
 This library must export the following `extern "C"` symbols:
 
 ### `ANDROID_HAL_STABLEC_VERSION`
diff --git a/graphics/mapper/stable-c/abi-dumps/arm/source-based/libimapper_stablec_abicheck.so.lsdump b/graphics/mapper/stable-c/abi-dumps/arm/source-based/libimapper_stablec_abicheck.so.lsdump
new file mode 100644
index 0000000..a653228
--- /dev/null
+++ b/graphics/mapper/stable-c/abi-dumps/arm/source-based/libimapper_stablec_abicheck.so.lsdump
@@ -0,0 +1,1053 @@
+{
+ "array_types" :
+ [
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIA0_i",
+   "name" : "int[0]",
+   "referenced_type" : "_ZTIi",
+   "self_type" : "_ZTIA0_i",
+   "source_file" : "system/core/include/cutils/native_handle.h"
+  },
+  {
+   "alignment" : 1,
+   "linker_set_key" : "_ZTIA32_h",
+   "name" : "unsigned char[32]",
+   "referenced_type" : "_ZTIh",
+   "self_type" : "_ZTIA32_h",
+   "size" : 32,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  }
+ ],
+ "builtin_types" :
+ [
+  {
+   "alignment" : 1,
+   "is_integral" : true,
+   "is_unsigned" : true,
+   "linker_set_key" : "_ZTIb",
+   "name" : "bool",
+   "referenced_type" : "_ZTIb",
+   "self_type" : "_ZTIb",
+   "size" : 1
+  },
+  {
+   "alignment" : 1,
+   "is_integral" : true,
+   "is_unsigned" : true,
+   "linker_set_key" : "_ZTIc",
+   "name" : "char",
+   "referenced_type" : "_ZTIc",
+   "self_type" : "_ZTIc",
+   "size" : 1
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIe",
+   "name" : "long double",
+   "referenced_type" : "_ZTIe",
+   "self_type" : "_ZTIe",
+   "size" : 8
+  },
+  {
+   "alignment" : 1,
+   "is_integral" : true,
+   "is_unsigned" : true,
+   "linker_set_key" : "_ZTIh",
+   "name" : "unsigned char",
+   "referenced_type" : "_ZTIh",
+   "self_type" : "_ZTIh",
+   "size" : 1
+  },
+  {
+   "alignment" : 4,
+   "is_integral" : true,
+   "linker_set_key" : "_ZTIi",
+   "name" : "int",
+   "referenced_type" : "_ZTIi",
+   "self_type" : "_ZTIi",
+   "size" : 4
+  },
+  {
+   "alignment" : 4,
+   "is_integral" : true,
+   "is_unsigned" : true,
+   "linker_set_key" : "_ZTIj",
+   "name" : "unsigned int",
+   "referenced_type" : "_ZTIj",
+   "self_type" : "_ZTIj",
+   "size" : 4
+  },
+  {
+   "linker_set_key" : "_ZTIv",
+   "name" : "void",
+   "referenced_type" : "_ZTIv",
+   "self_type" : "_ZTIv"
+  },
+  {
+   "alignment" : 8,
+   "is_integral" : true,
+   "linker_set_key" : "_ZTIx",
+   "name" : "long long",
+   "referenced_type" : "_ZTIx",
+   "self_type" : "_ZTIx",
+   "size" : 8
+  },
+  {
+   "alignment" : 8,
+   "is_integral" : true,
+   "is_unsigned" : true,
+   "linker_set_key" : "_ZTIy",
+   "name" : "unsigned long long",
+   "referenced_type" : "_ZTIy",
+   "self_type" : "_ZTIy",
+   "size" : 8
+  }
+ ],
+ "elf_functions" :
+ [
+  {
+   "name" : "AIMapper_loadIMapper"
+  }
+ ],
+ "elf_objects" : [],
+ "enum_types" :
+ [
+  {
+   "alignment" : 4,
+   "enum_fields" :
+   [
+    {
+     "enum_field_value" : 0,
+     "name" : "AIMAPPER_ERROR_NONE"
+    },
+    {
+     "enum_field_value" : 1,
+     "name" : "AIMAPPER_ERROR_BAD_DESCRIPTOR"
+    },
+    {
+     "enum_field_value" : 2,
+     "name" : "AIMAPPER_ERROR_BAD_BUFFER"
+    },
+    {
+     "enum_field_value" : 3,
+     "name" : "AIMAPPER_ERROR_BAD_VALUE"
+    },
+    {
+     "enum_field_value" : 5,
+     "name" : "AIMAPPER_ERROR_NO_RESOURCES"
+    },
+    {
+     "enum_field_value" : 7,
+     "name" : "AIMAPPER_ERROR_UNSUPPORTED"
+    }
+   ],
+   "linker_set_key" : "_ZTI14AIMapper_Error",
+   "name" : "AIMapper_Error",
+   "referenced_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTI14AIMapper_Error",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h",
+   "underlying_type" : "_ZTIi"
+  },
+  {
+   "alignment" : 4,
+   "enum_fields" :
+   [
+    {
+     "enum_field_value" : 5,
+     "name" : "AIMAPPER_VERSION_5"
+    }
+   ],
+   "linker_set_key" : "_ZTI16AIMapper_Version",
+   "name" : "AIMapper_Version",
+   "referenced_type" : "_ZTI16AIMapper_Version",
+   "self_type" : "_ZTI16AIMapper_Version",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h",
+   "underlying_type" : "_ZTIj"
+  }
+ ],
+ "function_types" :
+ [
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPFvPvEPFvS0_21AIMapper_MetadataTypePKvjES0_E",
+   "name" : "AIMapper_Error (void (*)(void *), void (*)(void *, AIMapper_MetadataType, const void *, unsigned int), void *)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPFvPvE"
+    },
+    {
+     "referenced_type" : "_ZTIPFvPv21AIMapper_MetadataTypePKvjE"
+    },
+    {
+     "referenced_type" : "_ZTIPv"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPFvPvEPFvS0_21AIMapper_MetadataTypePKvjES0_E",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPFvPvEPFvS0_21AIMapper_MetadataTypePKvjES0_E",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handle21AIMapper_MetadataTypePKvjE",
+   "name" : "AIMapper_Error (const native_handle *, AIMapper_MetadataType, const void *, unsigned int)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTI21AIMapper_MetadataType"
+    },
+    {
+     "referenced_type" : "_ZTIPKv"
+    },
+    {
+     "referenced_type" : "_ZTIj"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handle21AIMapper_MetadataTypePKvjE",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handle21AIMapper_MetadataTypePKvjE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handleE",
+   "name" : "AIMapper_Error (const native_handle *)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handleE",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handleE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handlePFvPv21AIMapper_MetadataTypePKvjES3_E",
+   "name" : "AIMapper_Error (const native_handle *, void (*)(void *, AIMapper_MetadataType, const void *, unsigned int), void *)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTIPFvPv21AIMapper_MetadataTypePKvjE"
+    },
+    {
+     "referenced_type" : "_ZTIPv"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePFvPv21AIMapper_MetadataTypePKvjES3_E",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePFvPv21AIMapper_MetadataTypePKvjES3_E",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handlePPvPyE",
+   "name" : "AIMapper_Error (const native_handle *, void **, unsigned long long *)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTIPPv"
+    },
+    {
+     "referenced_type" : "_ZTIPy"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePPvPyE",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePPvPyE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handlePS2_E",
+   "name" : "AIMapper_Error (const native_handle *, const native_handle **)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTIPPK13native_handle"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePS2_E",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePS2_E",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handlePiE",
+   "name" : "AIMapper_Error (const native_handle *, int *)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTIPi"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePiE",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePiE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handlePjS3_E",
+   "name" : "AIMapper_Error (const native_handle *, unsigned int *, unsigned int *)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTIPj"
+    },
+    {
+     "referenced_type" : "_ZTIPj"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePjS3_E",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePjS3_E",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handlexPKvjE",
+   "name" : "AIMapper_Error (const native_handle *, long long, const void *, unsigned int)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTIx"
+    },
+    {
+     "referenced_type" : "_ZTIPKv"
+    },
+    {
+     "referenced_type" : "_ZTIj"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlexPKvjE",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handlexPKvjE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handley5ARectiPPvE",
+   "name" : "AIMapper_Error (const native_handle *, unsigned long long, ARect, int, void **)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTIy"
+    },
+    {
+     "referenced_type" : "_ZTI5ARect"
+    },
+    {
+     "referenced_type" : "_ZTIi"
+    },
+    {
+     "referenced_type" : "_ZTIPPv"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handley5ARectiPPvE",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handley5ARectiPPvE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPPK32AIMapper_MetadataTypeDescriptionPjE",
+   "name" : "AIMapper_Error (const AIMapper_MetadataTypeDescription **, unsigned int *)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPPK32AIMapper_MetadataTypeDescription"
+    },
+    {
+     "referenced_type" : "_ZTIPj"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPPK32AIMapper_MetadataTypeDescriptionPjE",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPPK32AIMapper_MetadataTypeDescriptionPjE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIFiPK13native_handle21AIMapper_MetadataTypePvjE",
+   "name" : "int (const native_handle *, AIMapper_MetadataType, void *, unsigned int)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTI21AIMapper_MetadataType"
+    },
+    {
+     "referenced_type" : "_ZTIPv"
+    },
+    {
+     "referenced_type" : "_ZTIj"
+    }
+   ],
+   "referenced_type" : "_ZTIFiPK13native_handle21AIMapper_MetadataTypePvjE",
+   "return_type" : "_ZTIi",
+   "self_type" : "_ZTIFiPK13native_handle21AIMapper_MetadataTypePvjE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIFiPK13native_handlexPvjE",
+   "name" : "int (const native_handle *, long long, void *, unsigned int)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTIx"
+    },
+    {
+     "referenced_type" : "_ZTIPv"
+    },
+    {
+     "referenced_type" : "_ZTIj"
+    }
+   ],
+   "referenced_type" : "_ZTIFiPK13native_handlexPvjE",
+   "return_type" : "_ZTIi",
+   "self_type" : "_ZTIFiPK13native_handlexPvjE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIFvPv21AIMapper_MetadataTypePKvjE",
+   "name" : "void (void *, AIMapper_MetadataType, const void *, unsigned int)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPv"
+    },
+    {
+     "referenced_type" : "_ZTI21AIMapper_MetadataType"
+    },
+    {
+     "referenced_type" : "_ZTIPKv"
+    },
+    {
+     "referenced_type" : "_ZTIj"
+    }
+   ],
+   "referenced_type" : "_ZTIFvPv21AIMapper_MetadataTypePKvjE",
+   "return_type" : "_ZTIv",
+   "self_type" : "_ZTIFvPv21AIMapper_MetadataTypePKvjE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIFvPvE",
+   "name" : "void (void *)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPv"
+    }
+   ],
+   "referenced_type" : "_ZTIFvPvE",
+   "return_type" : "_ZTIv",
+   "self_type" : "_ZTIFvPvE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  }
+ ],
+ "functions" :
+ [
+  {
+   "function_name" : "AIMapper_loadIMapper",
+   "linker_set_key" : "AIMapper_loadIMapper",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPP8AIMapper"
+    }
+   ],
+   "return_type" : "_ZTI14AIMapper_Error",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  }
+ ],
+ "global_vars" : [],
+ "lvalue_reference_types" : [],
+ "pointer_types" :
+ [
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIP8AIMapper",
+   "name" : "AIMapper *",
+   "referenced_type" : "_ZTI8AIMapper",
+   "self_type" : "_ZTIP8AIMapper",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPFvPvEPFvS0_21AIMapper_MetadataTypePKvjES0_E",
+   "name" : "AIMapper_Error (*)(void (*)(void *), void (*)(void *, AIMapper_MetadataType, const void *, unsigned int), void *)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPFvPvEPFvS0_21AIMapper_MetadataTypePKvjES0_E",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPFvPvEPFvS0_21AIMapper_MetadataTypePKvjES0_E",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handle21AIMapper_MetadataTypePKvjE",
+   "name" : "AIMapper_Error (*)(const native_handle *, AIMapper_MetadataType, const void *, unsigned int)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handle21AIMapper_MetadataTypePKvjE",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handle21AIMapper_MetadataTypePKvjE",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handleE",
+   "name" : "AIMapper_Error (*)(const native_handle *)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handleE",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handleE",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handlePFvPv21AIMapper_MetadataTypePKvjES3_E",
+   "name" : "AIMapper_Error (*)(const native_handle *, void (*)(void *, AIMapper_MetadataType, const void *, unsigned int), void *)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePFvPv21AIMapper_MetadataTypePKvjES3_E",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePFvPv21AIMapper_MetadataTypePKvjES3_E",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handlePPvPyE",
+   "name" : "AIMapper_Error (*)(const native_handle *, void **, unsigned long long *)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePPvPyE",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePPvPyE",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handlePS2_E",
+   "name" : "AIMapper_Error (*)(const native_handle *, const native_handle **)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePS2_E",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePS2_E",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handlePiE",
+   "name" : "AIMapper_Error (*)(const native_handle *, int *)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePiE",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePiE",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handlePjS3_E",
+   "name" : "AIMapper_Error (*)(const native_handle *, unsigned int *, unsigned int *)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePjS3_E",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePjS3_E",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handlexPKvjE",
+   "name" : "AIMapper_Error (*)(const native_handle *, long long, const void *, unsigned int)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlexPKvjE",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlexPKvjE",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handley5ARectiPPvE",
+   "name" : "AIMapper_Error (*)(const native_handle *, unsigned long long, ARect, int, void **)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handley5ARectiPPvE",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handley5ARectiPPvE",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPPK32AIMapper_MetadataTypeDescriptionPjE",
+   "name" : "AIMapper_Error (*)(const AIMapper_MetadataTypeDescription **, unsigned int *)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPPK32AIMapper_MetadataTypeDescriptionPjE",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPPK32AIMapper_MetadataTypeDescriptionPjE",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPFiPK13native_handle21AIMapper_MetadataTypePvjE",
+   "name" : "int (*)(const native_handle *, AIMapper_MetadataType, void *, unsigned int)",
+   "referenced_type" : "_ZTIFiPK13native_handle21AIMapper_MetadataTypePvjE",
+   "self_type" : "_ZTIPFiPK13native_handle21AIMapper_MetadataTypePvjE",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPFiPK13native_handlexPvjE",
+   "name" : "int (*)(const native_handle *, long long, void *, unsigned int)",
+   "referenced_type" : "_ZTIFiPK13native_handlexPvjE",
+   "self_type" : "_ZTIPFiPK13native_handlexPvjE",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPFvPv21AIMapper_MetadataTypePKvjE",
+   "name" : "void (*)(void *, AIMapper_MetadataType, const void *, unsigned int)",
+   "referenced_type" : "_ZTIFvPv21AIMapper_MetadataTypePKvjE",
+   "self_type" : "_ZTIPFvPv21AIMapper_MetadataTypePKvjE",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPFvPvE",
+   "name" : "void (*)(void *)",
+   "referenced_type" : "_ZTIFvPvE",
+   "self_type" : "_ZTIPFvPvE",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPK13native_handle",
+   "name" : "const native_handle *",
+   "referenced_type" : "_ZTIK13native_handle",
+   "self_type" : "_ZTIPK13native_handle",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPK32AIMapper_MetadataTypeDescription",
+   "name" : "const AIMapper_MetadataTypeDescription *",
+   "referenced_type" : "_ZTIK32AIMapper_MetadataTypeDescription",
+   "self_type" : "_ZTIPK32AIMapper_MetadataTypeDescription",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPKc",
+   "name" : "const char *",
+   "referenced_type" : "_ZTIKc",
+   "self_type" : "_ZTIPKc",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPKv",
+   "name" : "const void *",
+   "referenced_type" : "_ZTIKv",
+   "self_type" : "_ZTIPKv",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPP8AIMapper",
+   "name" : "AIMapper **",
+   "referenced_type" : "_ZTIP8AIMapper",
+   "self_type" : "_ZTIPP8AIMapper",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPPK13native_handle",
+   "name" : "const native_handle **",
+   "referenced_type" : "_ZTIPK13native_handle",
+   "self_type" : "_ZTIPPK13native_handle",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPPK32AIMapper_MetadataTypeDescription",
+   "name" : "const AIMapper_MetadataTypeDescription **",
+   "referenced_type" : "_ZTIPK32AIMapper_MetadataTypeDescription",
+   "self_type" : "_ZTIPPK32AIMapper_MetadataTypeDescription",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPPv",
+   "name" : "void **",
+   "referenced_type" : "_ZTIPv",
+   "self_type" : "_ZTIPPv",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPi",
+   "name" : "int *",
+   "referenced_type" : "_ZTIi",
+   "self_type" : "_ZTIPi",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPj",
+   "name" : "unsigned int *",
+   "referenced_type" : "_ZTIj",
+   "self_type" : "_ZTIPj",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPv",
+   "name" : "void *",
+   "referenced_type" : "_ZTIv",
+   "self_type" : "_ZTIPv",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPy",
+   "name" : "unsigned long long *",
+   "referenced_type" : "_ZTIy",
+   "self_type" : "_ZTIPy",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  }
+ ],
+ "qualified_types" :
+ [
+  {
+   "alignment" : 4,
+   "is_const" : true,
+   "linker_set_key" : "_ZTIK13native_handle",
+   "name" : "const native_handle",
+   "referenced_type" : "_ZTI13native_handle",
+   "self_type" : "_ZTIK13native_handle",
+   "size" : 12,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "is_const" : true,
+   "linker_set_key" : "_ZTIK32AIMapper_MetadataTypeDescription",
+   "name" : "const AIMapper_MetadataTypeDescription",
+   "referenced_type" : "_ZTI32AIMapper_MetadataTypeDescription",
+   "self_type" : "_ZTIK32AIMapper_MetadataTypeDescription",
+   "size" : 56,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 1,
+   "is_const" : true,
+   "linker_set_key" : "_ZTIKc",
+   "name" : "const char",
+   "referenced_type" : "_ZTIc",
+   "self_type" : "_ZTIKc",
+   "size" : 1,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "is_const" : true,
+   "linker_set_key" : "_ZTIKv",
+   "name" : "const void",
+   "referenced_type" : "_ZTIv",
+   "self_type" : "_ZTIKv",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  }
+ ],
+ "record_types" :
+ [
+  {
+   "alignment" : 4,
+   "fields" :
+   [
+    {
+     "field_name" : "importBuffer",
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePS2_E"
+    },
+    {
+     "field_name" : "freeBuffer",
+     "field_offset" : 32,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handleE"
+    },
+    {
+     "field_name" : "getTransportSize",
+     "field_offset" : 64,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePjS3_E"
+    },
+    {
+     "field_name" : "lock",
+     "field_offset" : 96,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handley5ARectiPPvE"
+    },
+    {
+     "field_name" : "unlock",
+     "field_offset" : 128,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePiE"
+    },
+    {
+     "field_name" : "flushLockedBuffer",
+     "field_offset" : 160,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handleE"
+    },
+    {
+     "field_name" : "rereadLockedBuffer",
+     "field_offset" : 192,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handleE"
+    },
+    {
+     "field_name" : "getMetadata",
+     "field_offset" : 224,
+     "referenced_type" : "_ZTIPFiPK13native_handle21AIMapper_MetadataTypePvjE"
+    },
+    {
+     "field_name" : "getStandardMetadata",
+     "field_offset" : 256,
+     "referenced_type" : "_ZTIPFiPK13native_handlexPvjE"
+    },
+    {
+     "field_name" : "setMetadata",
+     "field_offset" : 288,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handle21AIMapper_MetadataTypePKvjE"
+    },
+    {
+     "field_name" : "setStandardMetadata",
+     "field_offset" : 320,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlexPKvjE"
+    },
+    {
+     "field_name" : "listSupportedMetadataTypes",
+     "field_offset" : 352,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPPK32AIMapper_MetadataTypeDescriptionPjE"
+    },
+    {
+     "field_name" : "dumpBuffer",
+     "field_offset" : 384,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePFvPv21AIMapper_MetadataTypePKvjES3_E"
+    },
+    {
+     "field_name" : "dumpAllBuffers",
+     "field_offset" : 416,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPFvPvEPFvS0_21AIMapper_MetadataTypePKvjES0_E"
+    },
+    {
+     "field_name" : "getReservedRegion",
+     "field_offset" : 448,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePPvPyE"
+    }
+   ],
+   "linker_set_key" : "_ZTI10AIMapperV5",
+   "name" : "AIMapperV5",
+   "referenced_type" : "_ZTI10AIMapperV5",
+   "self_type" : "_ZTI10AIMapperV5",
+   "size" : 60,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "fields" :
+   [
+    {
+     "field_name" : "__clang_max_align_nonce1",
+     "referenced_type" : "_ZTIx"
+    },
+    {
+     "field_name" : "__clang_max_align_nonce2",
+     "field_offset" : 64,
+     "referenced_type" : "_ZTIe"
+    }
+   ],
+   "linker_set_key" : "_ZTI11max_align_t",
+   "name" : "max_align_t",
+   "referenced_type" : "_ZTI11max_align_t",
+   "self_type" : "_ZTI11max_align_t",
+   "size" : 16,
+   "source_file" : "prebuilts/clang-tools/linux-x86/clang-headers/__stddef_max_align_t.h"
+  },
+  {
+   "alignment" : 4,
+   "fields" :
+   [
+    {
+     "field_name" : "version",
+     "referenced_type" : "_ZTIi"
+    },
+    {
+     "field_name" : "numFds",
+     "field_offset" : 32,
+     "referenced_type" : "_ZTIi"
+    },
+    {
+     "field_name" : "numInts",
+     "field_offset" : 64,
+     "referenced_type" : "_ZTIi"
+    },
+    {
+     "field_name" : "data",
+     "field_offset" : 96,
+     "referenced_type" : "_ZTIA0_i"
+    }
+   ],
+   "linker_set_key" : "_ZTI13native_handle",
+   "name" : "native_handle",
+   "referenced_type" : "_ZTI13native_handle",
+   "self_type" : "_ZTI13native_handle",
+   "size" : 12,
+   "source_file" : "system/core/include/cutils/native_handle.h"
+  },
+  {
+   "alignment" : 8,
+   "fields" :
+   [
+    {
+     "field_name" : "name",
+     "referenced_type" : "_ZTIPKc"
+    },
+    {
+     "field_name" : "value",
+     "field_offset" : 64,
+     "referenced_type" : "_ZTIx"
+    }
+   ],
+   "linker_set_key" : "_ZTI21AIMapper_MetadataType",
+   "name" : "AIMapper_MetadataType",
+   "referenced_type" : "_ZTI21AIMapper_MetadataType",
+   "self_type" : "_ZTI21AIMapper_MetadataType",
+   "size" : 16,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "fields" :
+   [
+    {
+     "field_name" : "metadataType",
+     "referenced_type" : "_ZTI21AIMapper_MetadataType"
+    },
+    {
+     "field_name" : "description",
+     "field_offset" : 128,
+     "referenced_type" : "_ZTIPKc"
+    },
+    {
+     "field_name" : "isGettable",
+     "field_offset" : 160,
+     "referenced_type" : "_ZTIb"
+    },
+    {
+     "field_name" : "isSettable",
+     "field_offset" : 168,
+     "referenced_type" : "_ZTIb"
+    },
+    {
+     "field_name" : "reserved",
+     "field_offset" : 176,
+     "referenced_type" : "_ZTIA32_h"
+    }
+   ],
+   "linker_set_key" : "_ZTI32AIMapper_MetadataTypeDescription",
+   "name" : "AIMapper_MetadataTypeDescription",
+   "referenced_type" : "_ZTI32AIMapper_MetadataTypeDescription",
+   "self_type" : "_ZTI32AIMapper_MetadataTypeDescription",
+   "size" : 56,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "fields" :
+   [
+    {
+     "field_name" : "left",
+     "referenced_type" : "_ZTIi"
+    },
+    {
+     "field_name" : "top",
+     "field_offset" : 32,
+     "referenced_type" : "_ZTIi"
+    },
+    {
+     "field_name" : "right",
+     "field_offset" : 64,
+     "referenced_type" : "_ZTIi"
+    },
+    {
+     "field_name" : "bottom",
+     "field_offset" : 96,
+     "referenced_type" : "_ZTIi"
+    }
+   ],
+   "linker_set_key" : "_ZTI5ARect",
+   "name" : "ARect",
+   "referenced_type" : "_ZTI5ARect",
+   "self_type" : "_ZTI5ARect",
+   "size" : 16,
+   "source_file" : "frameworks/native/libs/arect/include/android/rect.h"
+  },
+  {
+   "alignment" : 8,
+   "fields" :
+   [
+    {
+     "field_name" : "version",
+     "referenced_type" : "_ZTI16AIMapper_Version"
+    },
+    {
+     "field_name" : "v5",
+     "field_offset" : 32,
+     "referenced_type" : "_ZTI10AIMapperV5"
+    }
+   ],
+   "linker_set_key" : "_ZTI8AIMapper",
+   "name" : "AIMapper",
+   "referenced_type" : "_ZTI8AIMapper",
+   "self_type" : "_ZTI8AIMapper",
+   "size" : 64,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  }
+ ],
+ "rvalue_reference_types" : []
+}
diff --git a/graphics/mapper/stable-c/abi-dumps/arm64/source-based/libimapper_stablec_abicheck.so.lsdump b/graphics/mapper/stable-c/abi-dumps/arm64/source-based/libimapper_stablec_abicheck.so.lsdump
new file mode 100644
index 0000000..25f0e48
--- /dev/null
+++ b/graphics/mapper/stable-c/abi-dumps/arm64/source-based/libimapper_stablec_abicheck.so.lsdump
@@ -0,0 +1,1062 @@
+{
+ "array_types" :
+ [
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIA0_i",
+   "name" : "int[0]",
+   "referenced_type" : "_ZTIi",
+   "self_type" : "_ZTIA0_i",
+   "source_file" : "system/core/include/cutils/native_handle.h"
+  },
+  {
+   "alignment" : 1,
+   "linker_set_key" : "_ZTIA32_h",
+   "name" : "unsigned char[32]",
+   "referenced_type" : "_ZTIh",
+   "self_type" : "_ZTIA32_h",
+   "size" : 32,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  }
+ ],
+ "builtin_types" :
+ [
+  {
+   "alignment" : 1,
+   "is_integral" : true,
+   "is_unsigned" : true,
+   "linker_set_key" : "_ZTIb",
+   "name" : "bool",
+   "referenced_type" : "_ZTIb",
+   "self_type" : "_ZTIb",
+   "size" : 1
+  },
+  {
+   "alignment" : 1,
+   "is_integral" : true,
+   "is_unsigned" : true,
+   "linker_set_key" : "_ZTIc",
+   "name" : "char",
+   "referenced_type" : "_ZTIc",
+   "self_type" : "_ZTIc",
+   "size" : 1
+  },
+  {
+   "alignment" : 16,
+   "linker_set_key" : "_ZTIe",
+   "name" : "long double",
+   "referenced_type" : "_ZTIe",
+   "self_type" : "_ZTIe",
+   "size" : 16
+  },
+  {
+   "alignment" : 1,
+   "is_integral" : true,
+   "is_unsigned" : true,
+   "linker_set_key" : "_ZTIh",
+   "name" : "unsigned char",
+   "referenced_type" : "_ZTIh",
+   "self_type" : "_ZTIh",
+   "size" : 1
+  },
+  {
+   "alignment" : 4,
+   "is_integral" : true,
+   "linker_set_key" : "_ZTIi",
+   "name" : "int",
+   "referenced_type" : "_ZTIi",
+   "self_type" : "_ZTIi",
+   "size" : 4
+  },
+  {
+   "alignment" : 4,
+   "is_integral" : true,
+   "is_unsigned" : true,
+   "linker_set_key" : "_ZTIj",
+   "name" : "unsigned int",
+   "referenced_type" : "_ZTIj",
+   "self_type" : "_ZTIj",
+   "size" : 4
+  },
+  {
+   "alignment" : 8,
+   "is_integral" : true,
+   "linker_set_key" : "_ZTIl",
+   "name" : "long",
+   "referenced_type" : "_ZTIl",
+   "self_type" : "_ZTIl",
+   "size" : 8
+  },
+  {
+   "alignment" : 8,
+   "is_integral" : true,
+   "is_unsigned" : true,
+   "linker_set_key" : "_ZTIm",
+   "name" : "unsigned long",
+   "referenced_type" : "_ZTIm",
+   "self_type" : "_ZTIm",
+   "size" : 8
+  },
+  {
+   "linker_set_key" : "_ZTIv",
+   "name" : "void",
+   "referenced_type" : "_ZTIv",
+   "self_type" : "_ZTIv"
+  },
+  {
+   "alignment" : 8,
+   "is_integral" : true,
+   "linker_set_key" : "_ZTIx",
+   "name" : "long long",
+   "referenced_type" : "_ZTIx",
+   "self_type" : "_ZTIx",
+   "size" : 8
+  }
+ ],
+ "elf_functions" :
+ [
+  {
+   "name" : "AIMapper_loadIMapper"
+  }
+ ],
+ "elf_objects" : [],
+ "enum_types" :
+ [
+  {
+   "alignment" : 4,
+   "enum_fields" :
+   [
+    {
+     "enum_field_value" : 0,
+     "name" : "AIMAPPER_ERROR_NONE"
+    },
+    {
+     "enum_field_value" : 1,
+     "name" : "AIMAPPER_ERROR_BAD_DESCRIPTOR"
+    },
+    {
+     "enum_field_value" : 2,
+     "name" : "AIMAPPER_ERROR_BAD_BUFFER"
+    },
+    {
+     "enum_field_value" : 3,
+     "name" : "AIMAPPER_ERROR_BAD_VALUE"
+    },
+    {
+     "enum_field_value" : 5,
+     "name" : "AIMAPPER_ERROR_NO_RESOURCES"
+    },
+    {
+     "enum_field_value" : 7,
+     "name" : "AIMAPPER_ERROR_UNSUPPORTED"
+    }
+   ],
+   "linker_set_key" : "_ZTI14AIMapper_Error",
+   "name" : "AIMapper_Error",
+   "referenced_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTI14AIMapper_Error",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h",
+   "underlying_type" : "_ZTIi"
+  },
+  {
+   "alignment" : 4,
+   "enum_fields" :
+   [
+    {
+     "enum_field_value" : 5,
+     "name" : "AIMAPPER_VERSION_5"
+    }
+   ],
+   "linker_set_key" : "_ZTI16AIMapper_Version",
+   "name" : "AIMapper_Version",
+   "referenced_type" : "_ZTI16AIMapper_Version",
+   "self_type" : "_ZTI16AIMapper_Version",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h",
+   "underlying_type" : "_ZTIj"
+  }
+ ],
+ "function_types" :
+ [
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPFvPvEPFvS0_21AIMapper_MetadataTypePKvmES0_E",
+   "name" : "AIMapper_Error (void (*)(void *), void (*)(void *, AIMapper_MetadataType, const void *, unsigned long), void *)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPFvPvE"
+    },
+    {
+     "referenced_type" : "_ZTIPFvPv21AIMapper_MetadataTypePKvmE"
+    },
+    {
+     "referenced_type" : "_ZTIPv"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPFvPvEPFvS0_21AIMapper_MetadataTypePKvmES0_E",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPFvPvEPFvS0_21AIMapper_MetadataTypePKvmES0_E",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handle21AIMapper_MetadataTypePKvmE",
+   "name" : "AIMapper_Error (const native_handle *, AIMapper_MetadataType, const void *, unsigned long)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTI21AIMapper_MetadataType"
+    },
+    {
+     "referenced_type" : "_ZTIPKv"
+    },
+    {
+     "referenced_type" : "_ZTIm"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handle21AIMapper_MetadataTypePKvmE",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handle21AIMapper_MetadataTypePKvmE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handleE",
+   "name" : "AIMapper_Error (const native_handle *)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handleE",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handleE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handlePFvPv21AIMapper_MetadataTypePKvmES3_E",
+   "name" : "AIMapper_Error (const native_handle *, void (*)(void *, AIMapper_MetadataType, const void *, unsigned long), void *)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTIPFvPv21AIMapper_MetadataTypePKvmE"
+    },
+    {
+     "referenced_type" : "_ZTIPv"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePFvPv21AIMapper_MetadataTypePKvmES3_E",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePFvPv21AIMapper_MetadataTypePKvmES3_E",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handlePPvPmE",
+   "name" : "AIMapper_Error (const native_handle *, void **, unsigned long *)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTIPPv"
+    },
+    {
+     "referenced_type" : "_ZTIPm"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePPvPmE",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePPvPmE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handlePS2_E",
+   "name" : "AIMapper_Error (const native_handle *, const native_handle **)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTIPPK13native_handle"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePS2_E",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePS2_E",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handlePiE",
+   "name" : "AIMapper_Error (const native_handle *, int *)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTIPi"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePiE",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePiE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handlePjS3_E",
+   "name" : "AIMapper_Error (const native_handle *, unsigned int *, unsigned int *)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTIPj"
+    },
+    {
+     "referenced_type" : "_ZTIPj"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePjS3_E",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePjS3_E",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handlelPKvmE",
+   "name" : "AIMapper_Error (const native_handle *, long, const void *, unsigned long)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTIl"
+    },
+    {
+     "referenced_type" : "_ZTIPKv"
+    },
+    {
+     "referenced_type" : "_ZTIm"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlelPKvmE",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handlelPKvmE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handlem5ARectiPPvE",
+   "name" : "AIMapper_Error (const native_handle *, unsigned long, ARect, int, void **)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTIm"
+    },
+    {
+     "referenced_type" : "_ZTI5ARect"
+    },
+    {
+     "referenced_type" : "_ZTIi"
+    },
+    {
+     "referenced_type" : "_ZTIPPv"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlem5ARectiPPvE",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handlem5ARectiPPvE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPPK32AIMapper_MetadataTypeDescriptionPmE",
+   "name" : "AIMapper_Error (const AIMapper_MetadataTypeDescription **, unsigned long *)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPPK32AIMapper_MetadataTypeDescription"
+    },
+    {
+     "referenced_type" : "_ZTIPm"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPPK32AIMapper_MetadataTypeDescriptionPmE",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPPK32AIMapper_MetadataTypeDescriptionPmE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIFiPK13native_handle21AIMapper_MetadataTypePvmE",
+   "name" : "int (const native_handle *, AIMapper_MetadataType, void *, unsigned long)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTI21AIMapper_MetadataType"
+    },
+    {
+     "referenced_type" : "_ZTIPv"
+    },
+    {
+     "referenced_type" : "_ZTIm"
+    }
+   ],
+   "referenced_type" : "_ZTIFiPK13native_handle21AIMapper_MetadataTypePvmE",
+   "return_type" : "_ZTIi",
+   "self_type" : "_ZTIFiPK13native_handle21AIMapper_MetadataTypePvmE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIFiPK13native_handlelPvmE",
+   "name" : "int (const native_handle *, long, void *, unsigned long)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTIl"
+    },
+    {
+     "referenced_type" : "_ZTIPv"
+    },
+    {
+     "referenced_type" : "_ZTIm"
+    }
+   ],
+   "referenced_type" : "_ZTIFiPK13native_handlelPvmE",
+   "return_type" : "_ZTIi",
+   "self_type" : "_ZTIFiPK13native_handlelPvmE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIFvPv21AIMapper_MetadataTypePKvmE",
+   "name" : "void (void *, AIMapper_MetadataType, const void *, unsigned long)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPv"
+    },
+    {
+     "referenced_type" : "_ZTI21AIMapper_MetadataType"
+    },
+    {
+     "referenced_type" : "_ZTIPKv"
+    },
+    {
+     "referenced_type" : "_ZTIm"
+    }
+   ],
+   "referenced_type" : "_ZTIFvPv21AIMapper_MetadataTypePKvmE",
+   "return_type" : "_ZTIv",
+   "self_type" : "_ZTIFvPv21AIMapper_MetadataTypePKvmE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIFvPvE",
+   "name" : "void (void *)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPv"
+    }
+   ],
+   "referenced_type" : "_ZTIFvPvE",
+   "return_type" : "_ZTIv",
+   "self_type" : "_ZTIFvPvE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  }
+ ],
+ "functions" :
+ [
+  {
+   "function_name" : "AIMapper_loadIMapper",
+   "linker_set_key" : "AIMapper_loadIMapper",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPP8AIMapper"
+    }
+   ],
+   "return_type" : "_ZTI14AIMapper_Error",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  }
+ ],
+ "global_vars" : [],
+ "lvalue_reference_types" : [],
+ "pointer_types" :
+ [
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIP8AIMapper",
+   "name" : "AIMapper *",
+   "referenced_type" : "_ZTI8AIMapper",
+   "self_type" : "_ZTIP8AIMapper",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPFvPvEPFvS0_21AIMapper_MetadataTypePKvmES0_E",
+   "name" : "AIMapper_Error (*)(void (*)(void *), void (*)(void *, AIMapper_MetadataType, const void *, unsigned long), void *)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPFvPvEPFvS0_21AIMapper_MetadataTypePKvmES0_E",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPFvPvEPFvS0_21AIMapper_MetadataTypePKvmES0_E",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handle21AIMapper_MetadataTypePKvmE",
+   "name" : "AIMapper_Error (*)(const native_handle *, AIMapper_MetadataType, const void *, unsigned long)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handle21AIMapper_MetadataTypePKvmE",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handle21AIMapper_MetadataTypePKvmE",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handleE",
+   "name" : "AIMapper_Error (*)(const native_handle *)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handleE",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handleE",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handlePFvPv21AIMapper_MetadataTypePKvmES3_E",
+   "name" : "AIMapper_Error (*)(const native_handle *, void (*)(void *, AIMapper_MetadataType, const void *, unsigned long), void *)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePFvPv21AIMapper_MetadataTypePKvmES3_E",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePFvPv21AIMapper_MetadataTypePKvmES3_E",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handlePPvPmE",
+   "name" : "AIMapper_Error (*)(const native_handle *, void **, unsigned long *)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePPvPmE",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePPvPmE",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handlePS2_E",
+   "name" : "AIMapper_Error (*)(const native_handle *, const native_handle **)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePS2_E",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePS2_E",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handlePiE",
+   "name" : "AIMapper_Error (*)(const native_handle *, int *)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePiE",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePiE",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handlePjS3_E",
+   "name" : "AIMapper_Error (*)(const native_handle *, unsigned int *, unsigned int *)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePjS3_E",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePjS3_E",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handlelPKvmE",
+   "name" : "AIMapper_Error (*)(const native_handle *, long, const void *, unsigned long)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlelPKvmE",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlelPKvmE",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handlem5ARectiPPvE",
+   "name" : "AIMapper_Error (*)(const native_handle *, unsigned long, ARect, int, void **)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlem5ARectiPPvE",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlem5ARectiPPvE",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPPK32AIMapper_MetadataTypeDescriptionPmE",
+   "name" : "AIMapper_Error (*)(const AIMapper_MetadataTypeDescription **, unsigned long *)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPPK32AIMapper_MetadataTypeDescriptionPmE",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPPK32AIMapper_MetadataTypeDescriptionPmE",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPFiPK13native_handle21AIMapper_MetadataTypePvmE",
+   "name" : "int (*)(const native_handle *, AIMapper_MetadataType, void *, unsigned long)",
+   "referenced_type" : "_ZTIFiPK13native_handle21AIMapper_MetadataTypePvmE",
+   "self_type" : "_ZTIPFiPK13native_handle21AIMapper_MetadataTypePvmE",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPFiPK13native_handlelPvmE",
+   "name" : "int (*)(const native_handle *, long, void *, unsigned long)",
+   "referenced_type" : "_ZTIFiPK13native_handlelPvmE",
+   "self_type" : "_ZTIPFiPK13native_handlelPvmE",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPFvPv21AIMapper_MetadataTypePKvmE",
+   "name" : "void (*)(void *, AIMapper_MetadataType, const void *, unsigned long)",
+   "referenced_type" : "_ZTIFvPv21AIMapper_MetadataTypePKvmE",
+   "self_type" : "_ZTIPFvPv21AIMapper_MetadataTypePKvmE",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPFvPvE",
+   "name" : "void (*)(void *)",
+   "referenced_type" : "_ZTIFvPvE",
+   "self_type" : "_ZTIPFvPvE",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPK13native_handle",
+   "name" : "const native_handle *",
+   "referenced_type" : "_ZTIK13native_handle",
+   "self_type" : "_ZTIPK13native_handle",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPK32AIMapper_MetadataTypeDescription",
+   "name" : "const AIMapper_MetadataTypeDescription *",
+   "referenced_type" : "_ZTIK32AIMapper_MetadataTypeDescription",
+   "self_type" : "_ZTIPK32AIMapper_MetadataTypeDescription",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPKc",
+   "name" : "const char *",
+   "referenced_type" : "_ZTIKc",
+   "self_type" : "_ZTIPKc",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPKv",
+   "name" : "const void *",
+   "referenced_type" : "_ZTIKv",
+   "self_type" : "_ZTIPKv",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPP8AIMapper",
+   "name" : "AIMapper **",
+   "referenced_type" : "_ZTIP8AIMapper",
+   "self_type" : "_ZTIPP8AIMapper",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPPK13native_handle",
+   "name" : "const native_handle **",
+   "referenced_type" : "_ZTIPK13native_handle",
+   "self_type" : "_ZTIPPK13native_handle",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPPK32AIMapper_MetadataTypeDescription",
+   "name" : "const AIMapper_MetadataTypeDescription **",
+   "referenced_type" : "_ZTIPK32AIMapper_MetadataTypeDescription",
+   "self_type" : "_ZTIPPK32AIMapper_MetadataTypeDescription",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPPv",
+   "name" : "void **",
+   "referenced_type" : "_ZTIPv",
+   "self_type" : "_ZTIPPv",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPi",
+   "name" : "int *",
+   "referenced_type" : "_ZTIi",
+   "self_type" : "_ZTIPi",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPj",
+   "name" : "unsigned int *",
+   "referenced_type" : "_ZTIj",
+   "self_type" : "_ZTIPj",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPm",
+   "name" : "unsigned long *",
+   "referenced_type" : "_ZTIm",
+   "self_type" : "_ZTIPm",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPv",
+   "name" : "void *",
+   "referenced_type" : "_ZTIv",
+   "self_type" : "_ZTIPv",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  }
+ ],
+ "qualified_types" :
+ [
+  {
+   "alignment" : 4,
+   "is_const" : true,
+   "linker_set_key" : "_ZTIK13native_handle",
+   "name" : "const native_handle",
+   "referenced_type" : "_ZTI13native_handle",
+   "self_type" : "_ZTIK13native_handle",
+   "size" : 12,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "is_const" : true,
+   "linker_set_key" : "_ZTIK32AIMapper_MetadataTypeDescription",
+   "name" : "const AIMapper_MetadataTypeDescription",
+   "referenced_type" : "_ZTI32AIMapper_MetadataTypeDescription",
+   "self_type" : "_ZTIK32AIMapper_MetadataTypeDescription",
+   "size" : 64,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 1,
+   "is_const" : true,
+   "linker_set_key" : "_ZTIKc",
+   "name" : "const char",
+   "referenced_type" : "_ZTIc",
+   "self_type" : "_ZTIKc",
+   "size" : 1,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "is_const" : true,
+   "linker_set_key" : "_ZTIKv",
+   "name" : "const void",
+   "referenced_type" : "_ZTIv",
+   "self_type" : "_ZTIKv",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  }
+ ],
+ "record_types" :
+ [
+  {
+   "alignment" : 8,
+   "fields" :
+   [
+    {
+     "field_name" : "importBuffer",
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePS2_E"
+    },
+    {
+     "field_name" : "freeBuffer",
+     "field_offset" : 64,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handleE"
+    },
+    {
+     "field_name" : "getTransportSize",
+     "field_offset" : 128,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePjS3_E"
+    },
+    {
+     "field_name" : "lock",
+     "field_offset" : 192,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlem5ARectiPPvE"
+    },
+    {
+     "field_name" : "unlock",
+     "field_offset" : 256,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePiE"
+    },
+    {
+     "field_name" : "flushLockedBuffer",
+     "field_offset" : 320,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handleE"
+    },
+    {
+     "field_name" : "rereadLockedBuffer",
+     "field_offset" : 384,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handleE"
+    },
+    {
+     "field_name" : "getMetadata",
+     "field_offset" : 448,
+     "referenced_type" : "_ZTIPFiPK13native_handle21AIMapper_MetadataTypePvmE"
+    },
+    {
+     "field_name" : "getStandardMetadata",
+     "field_offset" : 512,
+     "referenced_type" : "_ZTIPFiPK13native_handlelPvmE"
+    },
+    {
+     "field_name" : "setMetadata",
+     "field_offset" : 576,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handle21AIMapper_MetadataTypePKvmE"
+    },
+    {
+     "field_name" : "setStandardMetadata",
+     "field_offset" : 640,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlelPKvmE"
+    },
+    {
+     "field_name" : "listSupportedMetadataTypes",
+     "field_offset" : 704,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPPK32AIMapper_MetadataTypeDescriptionPmE"
+    },
+    {
+     "field_name" : "dumpBuffer",
+     "field_offset" : 768,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePFvPv21AIMapper_MetadataTypePKvmES3_E"
+    },
+    {
+     "field_name" : "dumpAllBuffers",
+     "field_offset" : 832,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPFvPvEPFvS0_21AIMapper_MetadataTypePKvmES0_E"
+    },
+    {
+     "field_name" : "getReservedRegion",
+     "field_offset" : 896,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePPvPmE"
+    }
+   ],
+   "linker_set_key" : "_ZTI10AIMapperV5",
+   "name" : "AIMapperV5",
+   "referenced_type" : "_ZTI10AIMapperV5",
+   "self_type" : "_ZTI10AIMapperV5",
+   "size" : 120,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 16,
+   "fields" :
+   [
+    {
+     "field_name" : "__clang_max_align_nonce1",
+     "referenced_type" : "_ZTIx"
+    },
+    {
+     "field_name" : "__clang_max_align_nonce2",
+     "field_offset" : 128,
+     "referenced_type" : "_ZTIe"
+    }
+   ],
+   "linker_set_key" : "_ZTI11max_align_t",
+   "name" : "max_align_t",
+   "referenced_type" : "_ZTI11max_align_t",
+   "self_type" : "_ZTI11max_align_t",
+   "size" : 32,
+   "source_file" : "prebuilts/clang-tools/linux-x86/clang-headers/__stddef_max_align_t.h"
+  },
+  {
+   "alignment" : 4,
+   "fields" :
+   [
+    {
+     "field_name" : "version",
+     "referenced_type" : "_ZTIi"
+    },
+    {
+     "field_name" : "numFds",
+     "field_offset" : 32,
+     "referenced_type" : "_ZTIi"
+    },
+    {
+     "field_name" : "numInts",
+     "field_offset" : 64,
+     "referenced_type" : "_ZTIi"
+    },
+    {
+     "field_name" : "data",
+     "field_offset" : 96,
+     "referenced_type" : "_ZTIA0_i"
+    }
+   ],
+   "linker_set_key" : "_ZTI13native_handle",
+   "name" : "native_handle",
+   "referenced_type" : "_ZTI13native_handle",
+   "self_type" : "_ZTI13native_handle",
+   "size" : 12,
+   "source_file" : "system/core/include/cutils/native_handle.h"
+  },
+  {
+   "alignment" : 8,
+   "fields" :
+   [
+    {
+     "field_name" : "name",
+     "referenced_type" : "_ZTIPKc"
+    },
+    {
+     "field_name" : "value",
+     "field_offset" : 64,
+     "referenced_type" : "_ZTIl"
+    }
+   ],
+   "linker_set_key" : "_ZTI21AIMapper_MetadataType",
+   "name" : "AIMapper_MetadataType",
+   "referenced_type" : "_ZTI21AIMapper_MetadataType",
+   "self_type" : "_ZTI21AIMapper_MetadataType",
+   "size" : 16,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "fields" :
+   [
+    {
+     "field_name" : "metadataType",
+     "referenced_type" : "_ZTI21AIMapper_MetadataType"
+    },
+    {
+     "field_name" : "description",
+     "field_offset" : 128,
+     "referenced_type" : "_ZTIPKc"
+    },
+    {
+     "field_name" : "isGettable",
+     "field_offset" : 192,
+     "referenced_type" : "_ZTIb"
+    },
+    {
+     "field_name" : "isSettable",
+     "field_offset" : 200,
+     "referenced_type" : "_ZTIb"
+    },
+    {
+     "field_name" : "reserved",
+     "field_offset" : 208,
+     "referenced_type" : "_ZTIA32_h"
+    }
+   ],
+   "linker_set_key" : "_ZTI32AIMapper_MetadataTypeDescription",
+   "name" : "AIMapper_MetadataTypeDescription",
+   "referenced_type" : "_ZTI32AIMapper_MetadataTypeDescription",
+   "self_type" : "_ZTI32AIMapper_MetadataTypeDescription",
+   "size" : 64,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "fields" :
+   [
+    {
+     "field_name" : "left",
+     "referenced_type" : "_ZTIi"
+    },
+    {
+     "field_name" : "top",
+     "field_offset" : 32,
+     "referenced_type" : "_ZTIi"
+    },
+    {
+     "field_name" : "right",
+     "field_offset" : 64,
+     "referenced_type" : "_ZTIi"
+    },
+    {
+     "field_name" : "bottom",
+     "field_offset" : 96,
+     "referenced_type" : "_ZTIi"
+    }
+   ],
+   "linker_set_key" : "_ZTI5ARect",
+   "name" : "ARect",
+   "referenced_type" : "_ZTI5ARect",
+   "self_type" : "_ZTI5ARect",
+   "size" : 16,
+   "source_file" : "frameworks/native/libs/arect/include/android/rect.h"
+  },
+  {
+   "alignment" : 16,
+   "fields" :
+   [
+    {
+     "field_name" : "version",
+     "referenced_type" : "_ZTI16AIMapper_Version"
+    },
+    {
+     "field_name" : "v5",
+     "field_offset" : 64,
+     "referenced_type" : "_ZTI10AIMapperV5"
+    }
+   ],
+   "linker_set_key" : "_ZTI8AIMapper",
+   "name" : "AIMapper",
+   "referenced_type" : "_ZTI8AIMapper",
+   "self_type" : "_ZTI8AIMapper",
+   "size" : 128,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  }
+ ],
+ "rvalue_reference_types" : []
+}
diff --git a/graphics/mapper/stable-c/abi-dumps/arm_arm64/source-based/libimapper_stablec_abicheck.so.lsdump b/graphics/mapper/stable-c/abi-dumps/arm_arm64/source-based/libimapper_stablec_abicheck.so.lsdump
new file mode 100644
index 0000000..a653228
--- /dev/null
+++ b/graphics/mapper/stable-c/abi-dumps/arm_arm64/source-based/libimapper_stablec_abicheck.so.lsdump
@@ -0,0 +1,1053 @@
+{
+ "array_types" :
+ [
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIA0_i",
+   "name" : "int[0]",
+   "referenced_type" : "_ZTIi",
+   "self_type" : "_ZTIA0_i",
+   "source_file" : "system/core/include/cutils/native_handle.h"
+  },
+  {
+   "alignment" : 1,
+   "linker_set_key" : "_ZTIA32_h",
+   "name" : "unsigned char[32]",
+   "referenced_type" : "_ZTIh",
+   "self_type" : "_ZTIA32_h",
+   "size" : 32,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  }
+ ],
+ "builtin_types" :
+ [
+  {
+   "alignment" : 1,
+   "is_integral" : true,
+   "is_unsigned" : true,
+   "linker_set_key" : "_ZTIb",
+   "name" : "bool",
+   "referenced_type" : "_ZTIb",
+   "self_type" : "_ZTIb",
+   "size" : 1
+  },
+  {
+   "alignment" : 1,
+   "is_integral" : true,
+   "is_unsigned" : true,
+   "linker_set_key" : "_ZTIc",
+   "name" : "char",
+   "referenced_type" : "_ZTIc",
+   "self_type" : "_ZTIc",
+   "size" : 1
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIe",
+   "name" : "long double",
+   "referenced_type" : "_ZTIe",
+   "self_type" : "_ZTIe",
+   "size" : 8
+  },
+  {
+   "alignment" : 1,
+   "is_integral" : true,
+   "is_unsigned" : true,
+   "linker_set_key" : "_ZTIh",
+   "name" : "unsigned char",
+   "referenced_type" : "_ZTIh",
+   "self_type" : "_ZTIh",
+   "size" : 1
+  },
+  {
+   "alignment" : 4,
+   "is_integral" : true,
+   "linker_set_key" : "_ZTIi",
+   "name" : "int",
+   "referenced_type" : "_ZTIi",
+   "self_type" : "_ZTIi",
+   "size" : 4
+  },
+  {
+   "alignment" : 4,
+   "is_integral" : true,
+   "is_unsigned" : true,
+   "linker_set_key" : "_ZTIj",
+   "name" : "unsigned int",
+   "referenced_type" : "_ZTIj",
+   "self_type" : "_ZTIj",
+   "size" : 4
+  },
+  {
+   "linker_set_key" : "_ZTIv",
+   "name" : "void",
+   "referenced_type" : "_ZTIv",
+   "self_type" : "_ZTIv"
+  },
+  {
+   "alignment" : 8,
+   "is_integral" : true,
+   "linker_set_key" : "_ZTIx",
+   "name" : "long long",
+   "referenced_type" : "_ZTIx",
+   "self_type" : "_ZTIx",
+   "size" : 8
+  },
+  {
+   "alignment" : 8,
+   "is_integral" : true,
+   "is_unsigned" : true,
+   "linker_set_key" : "_ZTIy",
+   "name" : "unsigned long long",
+   "referenced_type" : "_ZTIy",
+   "self_type" : "_ZTIy",
+   "size" : 8
+  }
+ ],
+ "elf_functions" :
+ [
+  {
+   "name" : "AIMapper_loadIMapper"
+  }
+ ],
+ "elf_objects" : [],
+ "enum_types" :
+ [
+  {
+   "alignment" : 4,
+   "enum_fields" :
+   [
+    {
+     "enum_field_value" : 0,
+     "name" : "AIMAPPER_ERROR_NONE"
+    },
+    {
+     "enum_field_value" : 1,
+     "name" : "AIMAPPER_ERROR_BAD_DESCRIPTOR"
+    },
+    {
+     "enum_field_value" : 2,
+     "name" : "AIMAPPER_ERROR_BAD_BUFFER"
+    },
+    {
+     "enum_field_value" : 3,
+     "name" : "AIMAPPER_ERROR_BAD_VALUE"
+    },
+    {
+     "enum_field_value" : 5,
+     "name" : "AIMAPPER_ERROR_NO_RESOURCES"
+    },
+    {
+     "enum_field_value" : 7,
+     "name" : "AIMAPPER_ERROR_UNSUPPORTED"
+    }
+   ],
+   "linker_set_key" : "_ZTI14AIMapper_Error",
+   "name" : "AIMapper_Error",
+   "referenced_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTI14AIMapper_Error",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h",
+   "underlying_type" : "_ZTIi"
+  },
+  {
+   "alignment" : 4,
+   "enum_fields" :
+   [
+    {
+     "enum_field_value" : 5,
+     "name" : "AIMAPPER_VERSION_5"
+    }
+   ],
+   "linker_set_key" : "_ZTI16AIMapper_Version",
+   "name" : "AIMapper_Version",
+   "referenced_type" : "_ZTI16AIMapper_Version",
+   "self_type" : "_ZTI16AIMapper_Version",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h",
+   "underlying_type" : "_ZTIj"
+  }
+ ],
+ "function_types" :
+ [
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPFvPvEPFvS0_21AIMapper_MetadataTypePKvjES0_E",
+   "name" : "AIMapper_Error (void (*)(void *), void (*)(void *, AIMapper_MetadataType, const void *, unsigned int), void *)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPFvPvE"
+    },
+    {
+     "referenced_type" : "_ZTIPFvPv21AIMapper_MetadataTypePKvjE"
+    },
+    {
+     "referenced_type" : "_ZTIPv"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPFvPvEPFvS0_21AIMapper_MetadataTypePKvjES0_E",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPFvPvEPFvS0_21AIMapper_MetadataTypePKvjES0_E",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handle21AIMapper_MetadataTypePKvjE",
+   "name" : "AIMapper_Error (const native_handle *, AIMapper_MetadataType, const void *, unsigned int)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTI21AIMapper_MetadataType"
+    },
+    {
+     "referenced_type" : "_ZTIPKv"
+    },
+    {
+     "referenced_type" : "_ZTIj"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handle21AIMapper_MetadataTypePKvjE",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handle21AIMapper_MetadataTypePKvjE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handleE",
+   "name" : "AIMapper_Error (const native_handle *)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handleE",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handleE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handlePFvPv21AIMapper_MetadataTypePKvjES3_E",
+   "name" : "AIMapper_Error (const native_handle *, void (*)(void *, AIMapper_MetadataType, const void *, unsigned int), void *)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTIPFvPv21AIMapper_MetadataTypePKvjE"
+    },
+    {
+     "referenced_type" : "_ZTIPv"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePFvPv21AIMapper_MetadataTypePKvjES3_E",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePFvPv21AIMapper_MetadataTypePKvjES3_E",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handlePPvPyE",
+   "name" : "AIMapper_Error (const native_handle *, void **, unsigned long long *)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTIPPv"
+    },
+    {
+     "referenced_type" : "_ZTIPy"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePPvPyE",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePPvPyE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handlePS2_E",
+   "name" : "AIMapper_Error (const native_handle *, const native_handle **)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTIPPK13native_handle"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePS2_E",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePS2_E",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handlePiE",
+   "name" : "AIMapper_Error (const native_handle *, int *)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTIPi"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePiE",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePiE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handlePjS3_E",
+   "name" : "AIMapper_Error (const native_handle *, unsigned int *, unsigned int *)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTIPj"
+    },
+    {
+     "referenced_type" : "_ZTIPj"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePjS3_E",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePjS3_E",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handlexPKvjE",
+   "name" : "AIMapper_Error (const native_handle *, long long, const void *, unsigned int)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTIx"
+    },
+    {
+     "referenced_type" : "_ZTIPKv"
+    },
+    {
+     "referenced_type" : "_ZTIj"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlexPKvjE",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handlexPKvjE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handley5ARectiPPvE",
+   "name" : "AIMapper_Error (const native_handle *, unsigned long long, ARect, int, void **)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTIy"
+    },
+    {
+     "referenced_type" : "_ZTI5ARect"
+    },
+    {
+     "referenced_type" : "_ZTIi"
+    },
+    {
+     "referenced_type" : "_ZTIPPv"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handley5ARectiPPvE",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handley5ARectiPPvE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPPK32AIMapper_MetadataTypeDescriptionPjE",
+   "name" : "AIMapper_Error (const AIMapper_MetadataTypeDescription **, unsigned int *)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPPK32AIMapper_MetadataTypeDescription"
+    },
+    {
+     "referenced_type" : "_ZTIPj"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPPK32AIMapper_MetadataTypeDescriptionPjE",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPPK32AIMapper_MetadataTypeDescriptionPjE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIFiPK13native_handle21AIMapper_MetadataTypePvjE",
+   "name" : "int (const native_handle *, AIMapper_MetadataType, void *, unsigned int)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTI21AIMapper_MetadataType"
+    },
+    {
+     "referenced_type" : "_ZTIPv"
+    },
+    {
+     "referenced_type" : "_ZTIj"
+    }
+   ],
+   "referenced_type" : "_ZTIFiPK13native_handle21AIMapper_MetadataTypePvjE",
+   "return_type" : "_ZTIi",
+   "self_type" : "_ZTIFiPK13native_handle21AIMapper_MetadataTypePvjE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIFiPK13native_handlexPvjE",
+   "name" : "int (const native_handle *, long long, void *, unsigned int)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTIx"
+    },
+    {
+     "referenced_type" : "_ZTIPv"
+    },
+    {
+     "referenced_type" : "_ZTIj"
+    }
+   ],
+   "referenced_type" : "_ZTIFiPK13native_handlexPvjE",
+   "return_type" : "_ZTIi",
+   "self_type" : "_ZTIFiPK13native_handlexPvjE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIFvPv21AIMapper_MetadataTypePKvjE",
+   "name" : "void (void *, AIMapper_MetadataType, const void *, unsigned int)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPv"
+    },
+    {
+     "referenced_type" : "_ZTI21AIMapper_MetadataType"
+    },
+    {
+     "referenced_type" : "_ZTIPKv"
+    },
+    {
+     "referenced_type" : "_ZTIj"
+    }
+   ],
+   "referenced_type" : "_ZTIFvPv21AIMapper_MetadataTypePKvjE",
+   "return_type" : "_ZTIv",
+   "self_type" : "_ZTIFvPv21AIMapper_MetadataTypePKvjE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIFvPvE",
+   "name" : "void (void *)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPv"
+    }
+   ],
+   "referenced_type" : "_ZTIFvPvE",
+   "return_type" : "_ZTIv",
+   "self_type" : "_ZTIFvPvE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  }
+ ],
+ "functions" :
+ [
+  {
+   "function_name" : "AIMapper_loadIMapper",
+   "linker_set_key" : "AIMapper_loadIMapper",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPP8AIMapper"
+    }
+   ],
+   "return_type" : "_ZTI14AIMapper_Error",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  }
+ ],
+ "global_vars" : [],
+ "lvalue_reference_types" : [],
+ "pointer_types" :
+ [
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIP8AIMapper",
+   "name" : "AIMapper *",
+   "referenced_type" : "_ZTI8AIMapper",
+   "self_type" : "_ZTIP8AIMapper",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPFvPvEPFvS0_21AIMapper_MetadataTypePKvjES0_E",
+   "name" : "AIMapper_Error (*)(void (*)(void *), void (*)(void *, AIMapper_MetadataType, const void *, unsigned int), void *)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPFvPvEPFvS0_21AIMapper_MetadataTypePKvjES0_E",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPFvPvEPFvS0_21AIMapper_MetadataTypePKvjES0_E",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handle21AIMapper_MetadataTypePKvjE",
+   "name" : "AIMapper_Error (*)(const native_handle *, AIMapper_MetadataType, const void *, unsigned int)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handle21AIMapper_MetadataTypePKvjE",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handle21AIMapper_MetadataTypePKvjE",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handleE",
+   "name" : "AIMapper_Error (*)(const native_handle *)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handleE",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handleE",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handlePFvPv21AIMapper_MetadataTypePKvjES3_E",
+   "name" : "AIMapper_Error (*)(const native_handle *, void (*)(void *, AIMapper_MetadataType, const void *, unsigned int), void *)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePFvPv21AIMapper_MetadataTypePKvjES3_E",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePFvPv21AIMapper_MetadataTypePKvjES3_E",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handlePPvPyE",
+   "name" : "AIMapper_Error (*)(const native_handle *, void **, unsigned long long *)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePPvPyE",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePPvPyE",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handlePS2_E",
+   "name" : "AIMapper_Error (*)(const native_handle *, const native_handle **)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePS2_E",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePS2_E",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handlePiE",
+   "name" : "AIMapper_Error (*)(const native_handle *, int *)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePiE",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePiE",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handlePjS3_E",
+   "name" : "AIMapper_Error (*)(const native_handle *, unsigned int *, unsigned int *)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePjS3_E",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePjS3_E",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handlexPKvjE",
+   "name" : "AIMapper_Error (*)(const native_handle *, long long, const void *, unsigned int)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlexPKvjE",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlexPKvjE",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handley5ARectiPPvE",
+   "name" : "AIMapper_Error (*)(const native_handle *, unsigned long long, ARect, int, void **)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handley5ARectiPPvE",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handley5ARectiPPvE",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPPK32AIMapper_MetadataTypeDescriptionPjE",
+   "name" : "AIMapper_Error (*)(const AIMapper_MetadataTypeDescription **, unsigned int *)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPPK32AIMapper_MetadataTypeDescriptionPjE",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPPK32AIMapper_MetadataTypeDescriptionPjE",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPFiPK13native_handle21AIMapper_MetadataTypePvjE",
+   "name" : "int (*)(const native_handle *, AIMapper_MetadataType, void *, unsigned int)",
+   "referenced_type" : "_ZTIFiPK13native_handle21AIMapper_MetadataTypePvjE",
+   "self_type" : "_ZTIPFiPK13native_handle21AIMapper_MetadataTypePvjE",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPFiPK13native_handlexPvjE",
+   "name" : "int (*)(const native_handle *, long long, void *, unsigned int)",
+   "referenced_type" : "_ZTIFiPK13native_handlexPvjE",
+   "self_type" : "_ZTIPFiPK13native_handlexPvjE",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPFvPv21AIMapper_MetadataTypePKvjE",
+   "name" : "void (*)(void *, AIMapper_MetadataType, const void *, unsigned int)",
+   "referenced_type" : "_ZTIFvPv21AIMapper_MetadataTypePKvjE",
+   "self_type" : "_ZTIPFvPv21AIMapper_MetadataTypePKvjE",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPFvPvE",
+   "name" : "void (*)(void *)",
+   "referenced_type" : "_ZTIFvPvE",
+   "self_type" : "_ZTIPFvPvE",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPK13native_handle",
+   "name" : "const native_handle *",
+   "referenced_type" : "_ZTIK13native_handle",
+   "self_type" : "_ZTIPK13native_handle",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPK32AIMapper_MetadataTypeDescription",
+   "name" : "const AIMapper_MetadataTypeDescription *",
+   "referenced_type" : "_ZTIK32AIMapper_MetadataTypeDescription",
+   "self_type" : "_ZTIPK32AIMapper_MetadataTypeDescription",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPKc",
+   "name" : "const char *",
+   "referenced_type" : "_ZTIKc",
+   "self_type" : "_ZTIPKc",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPKv",
+   "name" : "const void *",
+   "referenced_type" : "_ZTIKv",
+   "self_type" : "_ZTIPKv",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPP8AIMapper",
+   "name" : "AIMapper **",
+   "referenced_type" : "_ZTIP8AIMapper",
+   "self_type" : "_ZTIPP8AIMapper",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPPK13native_handle",
+   "name" : "const native_handle **",
+   "referenced_type" : "_ZTIPK13native_handle",
+   "self_type" : "_ZTIPPK13native_handle",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPPK32AIMapper_MetadataTypeDescription",
+   "name" : "const AIMapper_MetadataTypeDescription **",
+   "referenced_type" : "_ZTIPK32AIMapper_MetadataTypeDescription",
+   "self_type" : "_ZTIPPK32AIMapper_MetadataTypeDescription",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPPv",
+   "name" : "void **",
+   "referenced_type" : "_ZTIPv",
+   "self_type" : "_ZTIPPv",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPi",
+   "name" : "int *",
+   "referenced_type" : "_ZTIi",
+   "self_type" : "_ZTIPi",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPj",
+   "name" : "unsigned int *",
+   "referenced_type" : "_ZTIj",
+   "self_type" : "_ZTIPj",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPv",
+   "name" : "void *",
+   "referenced_type" : "_ZTIv",
+   "self_type" : "_ZTIPv",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPy",
+   "name" : "unsigned long long *",
+   "referenced_type" : "_ZTIy",
+   "self_type" : "_ZTIPy",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  }
+ ],
+ "qualified_types" :
+ [
+  {
+   "alignment" : 4,
+   "is_const" : true,
+   "linker_set_key" : "_ZTIK13native_handle",
+   "name" : "const native_handle",
+   "referenced_type" : "_ZTI13native_handle",
+   "self_type" : "_ZTIK13native_handle",
+   "size" : 12,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "is_const" : true,
+   "linker_set_key" : "_ZTIK32AIMapper_MetadataTypeDescription",
+   "name" : "const AIMapper_MetadataTypeDescription",
+   "referenced_type" : "_ZTI32AIMapper_MetadataTypeDescription",
+   "self_type" : "_ZTIK32AIMapper_MetadataTypeDescription",
+   "size" : 56,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 1,
+   "is_const" : true,
+   "linker_set_key" : "_ZTIKc",
+   "name" : "const char",
+   "referenced_type" : "_ZTIc",
+   "self_type" : "_ZTIKc",
+   "size" : 1,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "is_const" : true,
+   "linker_set_key" : "_ZTIKv",
+   "name" : "const void",
+   "referenced_type" : "_ZTIv",
+   "self_type" : "_ZTIKv",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  }
+ ],
+ "record_types" :
+ [
+  {
+   "alignment" : 4,
+   "fields" :
+   [
+    {
+     "field_name" : "importBuffer",
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePS2_E"
+    },
+    {
+     "field_name" : "freeBuffer",
+     "field_offset" : 32,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handleE"
+    },
+    {
+     "field_name" : "getTransportSize",
+     "field_offset" : 64,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePjS3_E"
+    },
+    {
+     "field_name" : "lock",
+     "field_offset" : 96,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handley5ARectiPPvE"
+    },
+    {
+     "field_name" : "unlock",
+     "field_offset" : 128,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePiE"
+    },
+    {
+     "field_name" : "flushLockedBuffer",
+     "field_offset" : 160,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handleE"
+    },
+    {
+     "field_name" : "rereadLockedBuffer",
+     "field_offset" : 192,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handleE"
+    },
+    {
+     "field_name" : "getMetadata",
+     "field_offset" : 224,
+     "referenced_type" : "_ZTIPFiPK13native_handle21AIMapper_MetadataTypePvjE"
+    },
+    {
+     "field_name" : "getStandardMetadata",
+     "field_offset" : 256,
+     "referenced_type" : "_ZTIPFiPK13native_handlexPvjE"
+    },
+    {
+     "field_name" : "setMetadata",
+     "field_offset" : 288,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handle21AIMapper_MetadataTypePKvjE"
+    },
+    {
+     "field_name" : "setStandardMetadata",
+     "field_offset" : 320,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlexPKvjE"
+    },
+    {
+     "field_name" : "listSupportedMetadataTypes",
+     "field_offset" : 352,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPPK32AIMapper_MetadataTypeDescriptionPjE"
+    },
+    {
+     "field_name" : "dumpBuffer",
+     "field_offset" : 384,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePFvPv21AIMapper_MetadataTypePKvjES3_E"
+    },
+    {
+     "field_name" : "dumpAllBuffers",
+     "field_offset" : 416,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPFvPvEPFvS0_21AIMapper_MetadataTypePKvjES0_E"
+    },
+    {
+     "field_name" : "getReservedRegion",
+     "field_offset" : 448,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePPvPyE"
+    }
+   ],
+   "linker_set_key" : "_ZTI10AIMapperV5",
+   "name" : "AIMapperV5",
+   "referenced_type" : "_ZTI10AIMapperV5",
+   "self_type" : "_ZTI10AIMapperV5",
+   "size" : 60,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "fields" :
+   [
+    {
+     "field_name" : "__clang_max_align_nonce1",
+     "referenced_type" : "_ZTIx"
+    },
+    {
+     "field_name" : "__clang_max_align_nonce2",
+     "field_offset" : 64,
+     "referenced_type" : "_ZTIe"
+    }
+   ],
+   "linker_set_key" : "_ZTI11max_align_t",
+   "name" : "max_align_t",
+   "referenced_type" : "_ZTI11max_align_t",
+   "self_type" : "_ZTI11max_align_t",
+   "size" : 16,
+   "source_file" : "prebuilts/clang-tools/linux-x86/clang-headers/__stddef_max_align_t.h"
+  },
+  {
+   "alignment" : 4,
+   "fields" :
+   [
+    {
+     "field_name" : "version",
+     "referenced_type" : "_ZTIi"
+    },
+    {
+     "field_name" : "numFds",
+     "field_offset" : 32,
+     "referenced_type" : "_ZTIi"
+    },
+    {
+     "field_name" : "numInts",
+     "field_offset" : 64,
+     "referenced_type" : "_ZTIi"
+    },
+    {
+     "field_name" : "data",
+     "field_offset" : 96,
+     "referenced_type" : "_ZTIA0_i"
+    }
+   ],
+   "linker_set_key" : "_ZTI13native_handle",
+   "name" : "native_handle",
+   "referenced_type" : "_ZTI13native_handle",
+   "self_type" : "_ZTI13native_handle",
+   "size" : 12,
+   "source_file" : "system/core/include/cutils/native_handle.h"
+  },
+  {
+   "alignment" : 8,
+   "fields" :
+   [
+    {
+     "field_name" : "name",
+     "referenced_type" : "_ZTIPKc"
+    },
+    {
+     "field_name" : "value",
+     "field_offset" : 64,
+     "referenced_type" : "_ZTIx"
+    }
+   ],
+   "linker_set_key" : "_ZTI21AIMapper_MetadataType",
+   "name" : "AIMapper_MetadataType",
+   "referenced_type" : "_ZTI21AIMapper_MetadataType",
+   "self_type" : "_ZTI21AIMapper_MetadataType",
+   "size" : 16,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "fields" :
+   [
+    {
+     "field_name" : "metadataType",
+     "referenced_type" : "_ZTI21AIMapper_MetadataType"
+    },
+    {
+     "field_name" : "description",
+     "field_offset" : 128,
+     "referenced_type" : "_ZTIPKc"
+    },
+    {
+     "field_name" : "isGettable",
+     "field_offset" : 160,
+     "referenced_type" : "_ZTIb"
+    },
+    {
+     "field_name" : "isSettable",
+     "field_offset" : 168,
+     "referenced_type" : "_ZTIb"
+    },
+    {
+     "field_name" : "reserved",
+     "field_offset" : 176,
+     "referenced_type" : "_ZTIA32_h"
+    }
+   ],
+   "linker_set_key" : "_ZTI32AIMapper_MetadataTypeDescription",
+   "name" : "AIMapper_MetadataTypeDescription",
+   "referenced_type" : "_ZTI32AIMapper_MetadataTypeDescription",
+   "self_type" : "_ZTI32AIMapper_MetadataTypeDescription",
+   "size" : 56,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "fields" :
+   [
+    {
+     "field_name" : "left",
+     "referenced_type" : "_ZTIi"
+    },
+    {
+     "field_name" : "top",
+     "field_offset" : 32,
+     "referenced_type" : "_ZTIi"
+    },
+    {
+     "field_name" : "right",
+     "field_offset" : 64,
+     "referenced_type" : "_ZTIi"
+    },
+    {
+     "field_name" : "bottom",
+     "field_offset" : 96,
+     "referenced_type" : "_ZTIi"
+    }
+   ],
+   "linker_set_key" : "_ZTI5ARect",
+   "name" : "ARect",
+   "referenced_type" : "_ZTI5ARect",
+   "self_type" : "_ZTI5ARect",
+   "size" : 16,
+   "source_file" : "frameworks/native/libs/arect/include/android/rect.h"
+  },
+  {
+   "alignment" : 8,
+   "fields" :
+   [
+    {
+     "field_name" : "version",
+     "referenced_type" : "_ZTI16AIMapper_Version"
+    },
+    {
+     "field_name" : "v5",
+     "field_offset" : 32,
+     "referenced_type" : "_ZTI10AIMapperV5"
+    }
+   ],
+   "linker_set_key" : "_ZTI8AIMapper",
+   "name" : "AIMapper",
+   "referenced_type" : "_ZTI8AIMapper",
+   "self_type" : "_ZTI8AIMapper",
+   "size" : 64,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  }
+ ],
+ "rvalue_reference_types" : []
+}
diff --git a/graphics/mapper/stable-c/abi-dumps/x86/source-based/libimapper_stablec_abicheck.so.lsdump b/graphics/mapper/stable-c/abi-dumps/x86/source-based/libimapper_stablec_abicheck.so.lsdump
new file mode 100644
index 0000000..3eca8c3
--- /dev/null
+++ b/graphics/mapper/stable-c/abi-dumps/x86/source-based/libimapper_stablec_abicheck.so.lsdump
@@ -0,0 +1,1052 @@
+{
+ "array_types" :
+ [
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIA0_i",
+   "name" : "int[0]",
+   "referenced_type" : "_ZTIi",
+   "self_type" : "_ZTIA0_i",
+   "source_file" : "system/core/include/cutils/native_handle.h"
+  },
+  {
+   "alignment" : 1,
+   "linker_set_key" : "_ZTIA32_h",
+   "name" : "unsigned char[32]",
+   "referenced_type" : "_ZTIh",
+   "self_type" : "_ZTIA32_h",
+   "size" : 32,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  }
+ ],
+ "builtin_types" :
+ [
+  {
+   "alignment" : 1,
+   "is_integral" : true,
+   "is_unsigned" : true,
+   "linker_set_key" : "_ZTIb",
+   "name" : "bool",
+   "referenced_type" : "_ZTIb",
+   "self_type" : "_ZTIb",
+   "size" : 1
+  },
+  {
+   "alignment" : 1,
+   "is_integral" : true,
+   "linker_set_key" : "_ZTIc",
+   "name" : "char",
+   "referenced_type" : "_ZTIc",
+   "self_type" : "_ZTIc",
+   "size" : 1
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIe",
+   "name" : "long double",
+   "referenced_type" : "_ZTIe",
+   "self_type" : "_ZTIe",
+   "size" : 8
+  },
+  {
+   "alignment" : 1,
+   "is_integral" : true,
+   "is_unsigned" : true,
+   "linker_set_key" : "_ZTIh",
+   "name" : "unsigned char",
+   "referenced_type" : "_ZTIh",
+   "self_type" : "_ZTIh",
+   "size" : 1
+  },
+  {
+   "alignment" : 4,
+   "is_integral" : true,
+   "linker_set_key" : "_ZTIi",
+   "name" : "int",
+   "referenced_type" : "_ZTIi",
+   "self_type" : "_ZTIi",
+   "size" : 4
+  },
+  {
+   "alignment" : 4,
+   "is_integral" : true,
+   "is_unsigned" : true,
+   "linker_set_key" : "_ZTIj",
+   "name" : "unsigned int",
+   "referenced_type" : "_ZTIj",
+   "self_type" : "_ZTIj",
+   "size" : 4
+  },
+  {
+   "linker_set_key" : "_ZTIv",
+   "name" : "void",
+   "referenced_type" : "_ZTIv",
+   "self_type" : "_ZTIv"
+  },
+  {
+   "alignment" : 4,
+   "is_integral" : true,
+   "linker_set_key" : "_ZTIx",
+   "name" : "long long",
+   "referenced_type" : "_ZTIx",
+   "self_type" : "_ZTIx",
+   "size" : 8
+  },
+  {
+   "alignment" : 4,
+   "is_integral" : true,
+   "is_unsigned" : true,
+   "linker_set_key" : "_ZTIy",
+   "name" : "unsigned long long",
+   "referenced_type" : "_ZTIy",
+   "self_type" : "_ZTIy",
+   "size" : 8
+  }
+ ],
+ "elf_functions" :
+ [
+  {
+   "name" : "AIMapper_loadIMapper"
+  }
+ ],
+ "elf_objects" : [],
+ "enum_types" :
+ [
+  {
+   "alignment" : 4,
+   "enum_fields" :
+   [
+    {
+     "enum_field_value" : 0,
+     "name" : "AIMAPPER_ERROR_NONE"
+    },
+    {
+     "enum_field_value" : 1,
+     "name" : "AIMAPPER_ERROR_BAD_DESCRIPTOR"
+    },
+    {
+     "enum_field_value" : 2,
+     "name" : "AIMAPPER_ERROR_BAD_BUFFER"
+    },
+    {
+     "enum_field_value" : 3,
+     "name" : "AIMAPPER_ERROR_BAD_VALUE"
+    },
+    {
+     "enum_field_value" : 5,
+     "name" : "AIMAPPER_ERROR_NO_RESOURCES"
+    },
+    {
+     "enum_field_value" : 7,
+     "name" : "AIMAPPER_ERROR_UNSUPPORTED"
+    }
+   ],
+   "linker_set_key" : "_ZTI14AIMapper_Error",
+   "name" : "AIMapper_Error",
+   "referenced_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTI14AIMapper_Error",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h",
+   "underlying_type" : "_ZTIi"
+  },
+  {
+   "alignment" : 4,
+   "enum_fields" :
+   [
+    {
+     "enum_field_value" : 5,
+     "name" : "AIMAPPER_VERSION_5"
+    }
+   ],
+   "linker_set_key" : "_ZTI16AIMapper_Version",
+   "name" : "AIMapper_Version",
+   "referenced_type" : "_ZTI16AIMapper_Version",
+   "self_type" : "_ZTI16AIMapper_Version",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h",
+   "underlying_type" : "_ZTIj"
+  }
+ ],
+ "function_types" :
+ [
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPFvPvEPFvS0_21AIMapper_MetadataTypePKvjES0_E",
+   "name" : "AIMapper_Error (void (*)(void *), void (*)(void *, AIMapper_MetadataType, const void *, unsigned int), void *)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPFvPvE"
+    },
+    {
+     "referenced_type" : "_ZTIPFvPv21AIMapper_MetadataTypePKvjE"
+    },
+    {
+     "referenced_type" : "_ZTIPv"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPFvPvEPFvS0_21AIMapper_MetadataTypePKvjES0_E",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPFvPvEPFvS0_21AIMapper_MetadataTypePKvjES0_E",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handle21AIMapper_MetadataTypePKvjE",
+   "name" : "AIMapper_Error (const native_handle *, AIMapper_MetadataType, const void *, unsigned int)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTI21AIMapper_MetadataType"
+    },
+    {
+     "referenced_type" : "_ZTIPKv"
+    },
+    {
+     "referenced_type" : "_ZTIj"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handle21AIMapper_MetadataTypePKvjE",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handle21AIMapper_MetadataTypePKvjE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handleE",
+   "name" : "AIMapper_Error (const native_handle *)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handleE",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handleE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handlePFvPv21AIMapper_MetadataTypePKvjES3_E",
+   "name" : "AIMapper_Error (const native_handle *, void (*)(void *, AIMapper_MetadataType, const void *, unsigned int), void *)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTIPFvPv21AIMapper_MetadataTypePKvjE"
+    },
+    {
+     "referenced_type" : "_ZTIPv"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePFvPv21AIMapper_MetadataTypePKvjES3_E",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePFvPv21AIMapper_MetadataTypePKvjES3_E",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handlePPvPyE",
+   "name" : "AIMapper_Error (const native_handle *, void **, unsigned long long *)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTIPPv"
+    },
+    {
+     "referenced_type" : "_ZTIPy"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePPvPyE",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePPvPyE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handlePS2_E",
+   "name" : "AIMapper_Error (const native_handle *, const native_handle **)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTIPPK13native_handle"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePS2_E",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePS2_E",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handlePiE",
+   "name" : "AIMapper_Error (const native_handle *, int *)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTIPi"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePiE",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePiE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handlePjS3_E",
+   "name" : "AIMapper_Error (const native_handle *, unsigned int *, unsigned int *)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTIPj"
+    },
+    {
+     "referenced_type" : "_ZTIPj"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePjS3_E",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePjS3_E",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handlexPKvjE",
+   "name" : "AIMapper_Error (const native_handle *, long long, const void *, unsigned int)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTIx"
+    },
+    {
+     "referenced_type" : "_ZTIPKv"
+    },
+    {
+     "referenced_type" : "_ZTIj"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlexPKvjE",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handlexPKvjE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handley5ARectiPPvE",
+   "name" : "AIMapper_Error (const native_handle *, unsigned long long, ARect, int, void **)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTIy"
+    },
+    {
+     "referenced_type" : "_ZTI5ARect"
+    },
+    {
+     "referenced_type" : "_ZTIi"
+    },
+    {
+     "referenced_type" : "_ZTIPPv"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handley5ARectiPPvE",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handley5ARectiPPvE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPPK32AIMapper_MetadataTypeDescriptionPjE",
+   "name" : "AIMapper_Error (const AIMapper_MetadataTypeDescription **, unsigned int *)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPPK32AIMapper_MetadataTypeDescription"
+    },
+    {
+     "referenced_type" : "_ZTIPj"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPPK32AIMapper_MetadataTypeDescriptionPjE",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPPK32AIMapper_MetadataTypeDescriptionPjE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIFiPK13native_handle21AIMapper_MetadataTypePvjE",
+   "name" : "int (const native_handle *, AIMapper_MetadataType, void *, unsigned int)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTI21AIMapper_MetadataType"
+    },
+    {
+     "referenced_type" : "_ZTIPv"
+    },
+    {
+     "referenced_type" : "_ZTIj"
+    }
+   ],
+   "referenced_type" : "_ZTIFiPK13native_handle21AIMapper_MetadataTypePvjE",
+   "return_type" : "_ZTIi",
+   "self_type" : "_ZTIFiPK13native_handle21AIMapper_MetadataTypePvjE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIFiPK13native_handlexPvjE",
+   "name" : "int (const native_handle *, long long, void *, unsigned int)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTIx"
+    },
+    {
+     "referenced_type" : "_ZTIPv"
+    },
+    {
+     "referenced_type" : "_ZTIj"
+    }
+   ],
+   "referenced_type" : "_ZTIFiPK13native_handlexPvjE",
+   "return_type" : "_ZTIi",
+   "self_type" : "_ZTIFiPK13native_handlexPvjE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIFvPv21AIMapper_MetadataTypePKvjE",
+   "name" : "void (void *, AIMapper_MetadataType, const void *, unsigned int)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPv"
+    },
+    {
+     "referenced_type" : "_ZTI21AIMapper_MetadataType"
+    },
+    {
+     "referenced_type" : "_ZTIPKv"
+    },
+    {
+     "referenced_type" : "_ZTIj"
+    }
+   ],
+   "referenced_type" : "_ZTIFvPv21AIMapper_MetadataTypePKvjE",
+   "return_type" : "_ZTIv",
+   "self_type" : "_ZTIFvPv21AIMapper_MetadataTypePKvjE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIFvPvE",
+   "name" : "void (void *)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPv"
+    }
+   ],
+   "referenced_type" : "_ZTIFvPvE",
+   "return_type" : "_ZTIv",
+   "self_type" : "_ZTIFvPvE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  }
+ ],
+ "functions" :
+ [
+  {
+   "function_name" : "AIMapper_loadIMapper",
+   "linker_set_key" : "AIMapper_loadIMapper",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPP8AIMapper"
+    }
+   ],
+   "return_type" : "_ZTI14AIMapper_Error",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  }
+ ],
+ "global_vars" : [],
+ "lvalue_reference_types" : [],
+ "pointer_types" :
+ [
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIP8AIMapper",
+   "name" : "AIMapper *",
+   "referenced_type" : "_ZTI8AIMapper",
+   "self_type" : "_ZTIP8AIMapper",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPFvPvEPFvS0_21AIMapper_MetadataTypePKvjES0_E",
+   "name" : "AIMapper_Error (*)(void (*)(void *), void (*)(void *, AIMapper_MetadataType, const void *, unsigned int), void *)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPFvPvEPFvS0_21AIMapper_MetadataTypePKvjES0_E",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPFvPvEPFvS0_21AIMapper_MetadataTypePKvjES0_E",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handle21AIMapper_MetadataTypePKvjE",
+   "name" : "AIMapper_Error (*)(const native_handle *, AIMapper_MetadataType, const void *, unsigned int)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handle21AIMapper_MetadataTypePKvjE",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handle21AIMapper_MetadataTypePKvjE",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handleE",
+   "name" : "AIMapper_Error (*)(const native_handle *)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handleE",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handleE",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handlePFvPv21AIMapper_MetadataTypePKvjES3_E",
+   "name" : "AIMapper_Error (*)(const native_handle *, void (*)(void *, AIMapper_MetadataType, const void *, unsigned int), void *)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePFvPv21AIMapper_MetadataTypePKvjES3_E",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePFvPv21AIMapper_MetadataTypePKvjES3_E",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handlePPvPyE",
+   "name" : "AIMapper_Error (*)(const native_handle *, void **, unsigned long long *)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePPvPyE",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePPvPyE",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handlePS2_E",
+   "name" : "AIMapper_Error (*)(const native_handle *, const native_handle **)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePS2_E",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePS2_E",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handlePiE",
+   "name" : "AIMapper_Error (*)(const native_handle *, int *)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePiE",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePiE",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handlePjS3_E",
+   "name" : "AIMapper_Error (*)(const native_handle *, unsigned int *, unsigned int *)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePjS3_E",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePjS3_E",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handlexPKvjE",
+   "name" : "AIMapper_Error (*)(const native_handle *, long long, const void *, unsigned int)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlexPKvjE",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlexPKvjE",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handley5ARectiPPvE",
+   "name" : "AIMapper_Error (*)(const native_handle *, unsigned long long, ARect, int, void **)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handley5ARectiPPvE",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handley5ARectiPPvE",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPPK32AIMapper_MetadataTypeDescriptionPjE",
+   "name" : "AIMapper_Error (*)(const AIMapper_MetadataTypeDescription **, unsigned int *)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPPK32AIMapper_MetadataTypeDescriptionPjE",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPPK32AIMapper_MetadataTypeDescriptionPjE",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPFiPK13native_handle21AIMapper_MetadataTypePvjE",
+   "name" : "int (*)(const native_handle *, AIMapper_MetadataType, void *, unsigned int)",
+   "referenced_type" : "_ZTIFiPK13native_handle21AIMapper_MetadataTypePvjE",
+   "self_type" : "_ZTIPFiPK13native_handle21AIMapper_MetadataTypePvjE",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPFiPK13native_handlexPvjE",
+   "name" : "int (*)(const native_handle *, long long, void *, unsigned int)",
+   "referenced_type" : "_ZTIFiPK13native_handlexPvjE",
+   "self_type" : "_ZTIPFiPK13native_handlexPvjE",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPFvPv21AIMapper_MetadataTypePKvjE",
+   "name" : "void (*)(void *, AIMapper_MetadataType, const void *, unsigned int)",
+   "referenced_type" : "_ZTIFvPv21AIMapper_MetadataTypePKvjE",
+   "self_type" : "_ZTIPFvPv21AIMapper_MetadataTypePKvjE",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPFvPvE",
+   "name" : "void (*)(void *)",
+   "referenced_type" : "_ZTIFvPvE",
+   "self_type" : "_ZTIPFvPvE",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPK13native_handle",
+   "name" : "const native_handle *",
+   "referenced_type" : "_ZTIK13native_handle",
+   "self_type" : "_ZTIPK13native_handle",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPK32AIMapper_MetadataTypeDescription",
+   "name" : "const AIMapper_MetadataTypeDescription *",
+   "referenced_type" : "_ZTIK32AIMapper_MetadataTypeDescription",
+   "self_type" : "_ZTIPK32AIMapper_MetadataTypeDescription",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPKc",
+   "name" : "const char *",
+   "referenced_type" : "_ZTIKc",
+   "self_type" : "_ZTIPKc",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPKv",
+   "name" : "const void *",
+   "referenced_type" : "_ZTIKv",
+   "self_type" : "_ZTIPKv",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPP8AIMapper",
+   "name" : "AIMapper **",
+   "referenced_type" : "_ZTIP8AIMapper",
+   "self_type" : "_ZTIPP8AIMapper",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPPK13native_handle",
+   "name" : "const native_handle **",
+   "referenced_type" : "_ZTIPK13native_handle",
+   "self_type" : "_ZTIPPK13native_handle",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPPK32AIMapper_MetadataTypeDescription",
+   "name" : "const AIMapper_MetadataTypeDescription **",
+   "referenced_type" : "_ZTIPK32AIMapper_MetadataTypeDescription",
+   "self_type" : "_ZTIPPK32AIMapper_MetadataTypeDescription",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPPv",
+   "name" : "void **",
+   "referenced_type" : "_ZTIPv",
+   "self_type" : "_ZTIPPv",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPi",
+   "name" : "int *",
+   "referenced_type" : "_ZTIi",
+   "self_type" : "_ZTIPi",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPj",
+   "name" : "unsigned int *",
+   "referenced_type" : "_ZTIj",
+   "self_type" : "_ZTIPj",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPv",
+   "name" : "void *",
+   "referenced_type" : "_ZTIv",
+   "self_type" : "_ZTIPv",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPy",
+   "name" : "unsigned long long *",
+   "referenced_type" : "_ZTIy",
+   "self_type" : "_ZTIPy",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  }
+ ],
+ "qualified_types" :
+ [
+  {
+   "alignment" : 4,
+   "is_const" : true,
+   "linker_set_key" : "_ZTIK13native_handle",
+   "name" : "const native_handle",
+   "referenced_type" : "_ZTI13native_handle",
+   "self_type" : "_ZTIK13native_handle",
+   "size" : 12,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "is_const" : true,
+   "linker_set_key" : "_ZTIK32AIMapper_MetadataTypeDescription",
+   "name" : "const AIMapper_MetadataTypeDescription",
+   "referenced_type" : "_ZTI32AIMapper_MetadataTypeDescription",
+   "self_type" : "_ZTIK32AIMapper_MetadataTypeDescription",
+   "size" : 52,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 1,
+   "is_const" : true,
+   "linker_set_key" : "_ZTIKc",
+   "name" : "const char",
+   "referenced_type" : "_ZTIc",
+   "self_type" : "_ZTIKc",
+   "size" : 1,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "is_const" : true,
+   "linker_set_key" : "_ZTIKv",
+   "name" : "const void",
+   "referenced_type" : "_ZTIv",
+   "self_type" : "_ZTIKv",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  }
+ ],
+ "record_types" :
+ [
+  {
+   "alignment" : 4,
+   "fields" :
+   [
+    {
+     "field_name" : "importBuffer",
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePS2_E"
+    },
+    {
+     "field_name" : "freeBuffer",
+     "field_offset" : 32,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handleE"
+    },
+    {
+     "field_name" : "getTransportSize",
+     "field_offset" : 64,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePjS3_E"
+    },
+    {
+     "field_name" : "lock",
+     "field_offset" : 96,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handley5ARectiPPvE"
+    },
+    {
+     "field_name" : "unlock",
+     "field_offset" : 128,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePiE"
+    },
+    {
+     "field_name" : "flushLockedBuffer",
+     "field_offset" : 160,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handleE"
+    },
+    {
+     "field_name" : "rereadLockedBuffer",
+     "field_offset" : 192,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handleE"
+    },
+    {
+     "field_name" : "getMetadata",
+     "field_offset" : 224,
+     "referenced_type" : "_ZTIPFiPK13native_handle21AIMapper_MetadataTypePvjE"
+    },
+    {
+     "field_name" : "getStandardMetadata",
+     "field_offset" : 256,
+     "referenced_type" : "_ZTIPFiPK13native_handlexPvjE"
+    },
+    {
+     "field_name" : "setMetadata",
+     "field_offset" : 288,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handle21AIMapper_MetadataTypePKvjE"
+    },
+    {
+     "field_name" : "setStandardMetadata",
+     "field_offset" : 320,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlexPKvjE"
+    },
+    {
+     "field_name" : "listSupportedMetadataTypes",
+     "field_offset" : 352,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPPK32AIMapper_MetadataTypeDescriptionPjE"
+    },
+    {
+     "field_name" : "dumpBuffer",
+     "field_offset" : 384,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePFvPv21AIMapper_MetadataTypePKvjES3_E"
+    },
+    {
+     "field_name" : "dumpAllBuffers",
+     "field_offset" : 416,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPFvPvEPFvS0_21AIMapper_MetadataTypePKvjES0_E"
+    },
+    {
+     "field_name" : "getReservedRegion",
+     "field_offset" : 448,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePPvPyE"
+    }
+   ],
+   "linker_set_key" : "_ZTI10AIMapperV5",
+   "name" : "AIMapperV5",
+   "referenced_type" : "_ZTI10AIMapperV5",
+   "self_type" : "_ZTI10AIMapperV5",
+   "size" : 60,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "fields" :
+   [
+    {
+     "field_name" : "__clang_max_align_nonce1",
+     "referenced_type" : "_ZTIx"
+    },
+    {
+     "field_name" : "__clang_max_align_nonce2",
+     "field_offset" : 64,
+     "referenced_type" : "_ZTIe"
+    }
+   ],
+   "linker_set_key" : "_ZTI11max_align_t",
+   "name" : "max_align_t",
+   "referenced_type" : "_ZTI11max_align_t",
+   "self_type" : "_ZTI11max_align_t",
+   "size" : 16,
+   "source_file" : "prebuilts/clang-tools/linux-x86/clang-headers/__stddef_max_align_t.h"
+  },
+  {
+   "alignment" : 4,
+   "fields" :
+   [
+    {
+     "field_name" : "version",
+     "referenced_type" : "_ZTIi"
+    },
+    {
+     "field_name" : "numFds",
+     "field_offset" : 32,
+     "referenced_type" : "_ZTIi"
+    },
+    {
+     "field_name" : "numInts",
+     "field_offset" : 64,
+     "referenced_type" : "_ZTIi"
+    },
+    {
+     "field_name" : "data",
+     "field_offset" : 96,
+     "referenced_type" : "_ZTIA0_i"
+    }
+   ],
+   "linker_set_key" : "_ZTI13native_handle",
+   "name" : "native_handle",
+   "referenced_type" : "_ZTI13native_handle",
+   "self_type" : "_ZTI13native_handle",
+   "size" : 12,
+   "source_file" : "system/core/include/cutils/native_handle.h"
+  },
+  {
+   "alignment" : 4,
+   "fields" :
+   [
+    {
+     "field_name" : "name",
+     "referenced_type" : "_ZTIPKc"
+    },
+    {
+     "field_name" : "value",
+     "field_offset" : 32,
+     "referenced_type" : "_ZTIx"
+    }
+   ],
+   "linker_set_key" : "_ZTI21AIMapper_MetadataType",
+   "name" : "AIMapper_MetadataType",
+   "referenced_type" : "_ZTI21AIMapper_MetadataType",
+   "self_type" : "_ZTI21AIMapper_MetadataType",
+   "size" : 12,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "fields" :
+   [
+    {
+     "field_name" : "metadataType",
+     "referenced_type" : "_ZTI21AIMapper_MetadataType"
+    },
+    {
+     "field_name" : "description",
+     "field_offset" : 96,
+     "referenced_type" : "_ZTIPKc"
+    },
+    {
+     "field_name" : "isGettable",
+     "field_offset" : 128,
+     "referenced_type" : "_ZTIb"
+    },
+    {
+     "field_name" : "isSettable",
+     "field_offset" : 136,
+     "referenced_type" : "_ZTIb"
+    },
+    {
+     "field_name" : "reserved",
+     "field_offset" : 144,
+     "referenced_type" : "_ZTIA32_h"
+    }
+   ],
+   "linker_set_key" : "_ZTI32AIMapper_MetadataTypeDescription",
+   "name" : "AIMapper_MetadataTypeDescription",
+   "referenced_type" : "_ZTI32AIMapper_MetadataTypeDescription",
+   "self_type" : "_ZTI32AIMapper_MetadataTypeDescription",
+   "size" : 52,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "fields" :
+   [
+    {
+     "field_name" : "left",
+     "referenced_type" : "_ZTIi"
+    },
+    {
+     "field_name" : "top",
+     "field_offset" : 32,
+     "referenced_type" : "_ZTIi"
+    },
+    {
+     "field_name" : "right",
+     "field_offset" : 64,
+     "referenced_type" : "_ZTIi"
+    },
+    {
+     "field_name" : "bottom",
+     "field_offset" : 96,
+     "referenced_type" : "_ZTIi"
+    }
+   ],
+   "linker_set_key" : "_ZTI5ARect",
+   "name" : "ARect",
+   "referenced_type" : "_ZTI5ARect",
+   "self_type" : "_ZTI5ARect",
+   "size" : 16,
+   "source_file" : "frameworks/native/libs/arect/include/android/rect.h"
+  },
+  {
+   "alignment" : 8,
+   "fields" :
+   [
+    {
+     "field_name" : "version",
+     "referenced_type" : "_ZTI16AIMapper_Version"
+    },
+    {
+     "field_name" : "v5",
+     "field_offset" : 32,
+     "referenced_type" : "_ZTI10AIMapperV5"
+    }
+   ],
+   "linker_set_key" : "_ZTI8AIMapper",
+   "name" : "AIMapper",
+   "referenced_type" : "_ZTI8AIMapper",
+   "self_type" : "_ZTI8AIMapper",
+   "size" : 64,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  }
+ ],
+ "rvalue_reference_types" : []
+}
diff --git a/graphics/mapper/stable-c/abi-dumps/x86_64/source-based/libimapper_stablec_abicheck.so.lsdump b/graphics/mapper/stable-c/abi-dumps/x86_64/source-based/libimapper_stablec_abicheck.so.lsdump
new file mode 100644
index 0000000..c42e20a
--- /dev/null
+++ b/graphics/mapper/stable-c/abi-dumps/x86_64/source-based/libimapper_stablec_abicheck.so.lsdump
@@ -0,0 +1,1061 @@
+{
+ "array_types" :
+ [
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIA0_i",
+   "name" : "int[0]",
+   "referenced_type" : "_ZTIi",
+   "self_type" : "_ZTIA0_i",
+   "source_file" : "system/core/include/cutils/native_handle.h"
+  },
+  {
+   "alignment" : 1,
+   "linker_set_key" : "_ZTIA32_h",
+   "name" : "unsigned char[32]",
+   "referenced_type" : "_ZTIh",
+   "self_type" : "_ZTIA32_h",
+   "size" : 32,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  }
+ ],
+ "builtin_types" :
+ [
+  {
+   "alignment" : 1,
+   "is_integral" : true,
+   "is_unsigned" : true,
+   "linker_set_key" : "_ZTIb",
+   "name" : "bool",
+   "referenced_type" : "_ZTIb",
+   "self_type" : "_ZTIb",
+   "size" : 1
+  },
+  {
+   "alignment" : 1,
+   "is_integral" : true,
+   "linker_set_key" : "_ZTIc",
+   "name" : "char",
+   "referenced_type" : "_ZTIc",
+   "self_type" : "_ZTIc",
+   "size" : 1
+  },
+  {
+   "alignment" : 16,
+   "linker_set_key" : "_ZTIg",
+   "name" : "long double",
+   "referenced_type" : "_ZTIg",
+   "self_type" : "_ZTIg",
+   "size" : 16
+  },
+  {
+   "alignment" : 1,
+   "is_integral" : true,
+   "is_unsigned" : true,
+   "linker_set_key" : "_ZTIh",
+   "name" : "unsigned char",
+   "referenced_type" : "_ZTIh",
+   "self_type" : "_ZTIh",
+   "size" : 1
+  },
+  {
+   "alignment" : 4,
+   "is_integral" : true,
+   "linker_set_key" : "_ZTIi",
+   "name" : "int",
+   "referenced_type" : "_ZTIi",
+   "self_type" : "_ZTIi",
+   "size" : 4
+  },
+  {
+   "alignment" : 4,
+   "is_integral" : true,
+   "is_unsigned" : true,
+   "linker_set_key" : "_ZTIj",
+   "name" : "unsigned int",
+   "referenced_type" : "_ZTIj",
+   "self_type" : "_ZTIj",
+   "size" : 4
+  },
+  {
+   "alignment" : 8,
+   "is_integral" : true,
+   "linker_set_key" : "_ZTIl",
+   "name" : "long",
+   "referenced_type" : "_ZTIl",
+   "self_type" : "_ZTIl",
+   "size" : 8
+  },
+  {
+   "alignment" : 8,
+   "is_integral" : true,
+   "is_unsigned" : true,
+   "linker_set_key" : "_ZTIm",
+   "name" : "unsigned long",
+   "referenced_type" : "_ZTIm",
+   "self_type" : "_ZTIm",
+   "size" : 8
+  },
+  {
+   "linker_set_key" : "_ZTIv",
+   "name" : "void",
+   "referenced_type" : "_ZTIv",
+   "self_type" : "_ZTIv"
+  },
+  {
+   "alignment" : 8,
+   "is_integral" : true,
+   "linker_set_key" : "_ZTIx",
+   "name" : "long long",
+   "referenced_type" : "_ZTIx",
+   "self_type" : "_ZTIx",
+   "size" : 8
+  }
+ ],
+ "elf_functions" :
+ [
+  {
+   "name" : "AIMapper_loadIMapper"
+  }
+ ],
+ "elf_objects" : [],
+ "enum_types" :
+ [
+  {
+   "alignment" : 4,
+   "enum_fields" :
+   [
+    {
+     "enum_field_value" : 0,
+     "name" : "AIMAPPER_ERROR_NONE"
+    },
+    {
+     "enum_field_value" : 1,
+     "name" : "AIMAPPER_ERROR_BAD_DESCRIPTOR"
+    },
+    {
+     "enum_field_value" : 2,
+     "name" : "AIMAPPER_ERROR_BAD_BUFFER"
+    },
+    {
+     "enum_field_value" : 3,
+     "name" : "AIMAPPER_ERROR_BAD_VALUE"
+    },
+    {
+     "enum_field_value" : 5,
+     "name" : "AIMAPPER_ERROR_NO_RESOURCES"
+    },
+    {
+     "enum_field_value" : 7,
+     "name" : "AIMAPPER_ERROR_UNSUPPORTED"
+    }
+   ],
+   "linker_set_key" : "_ZTI14AIMapper_Error",
+   "name" : "AIMapper_Error",
+   "referenced_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTI14AIMapper_Error",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h",
+   "underlying_type" : "_ZTIi"
+  },
+  {
+   "alignment" : 4,
+   "enum_fields" :
+   [
+    {
+     "enum_field_value" : 5,
+     "name" : "AIMAPPER_VERSION_5"
+    }
+   ],
+   "linker_set_key" : "_ZTI16AIMapper_Version",
+   "name" : "AIMapper_Version",
+   "referenced_type" : "_ZTI16AIMapper_Version",
+   "self_type" : "_ZTI16AIMapper_Version",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h",
+   "underlying_type" : "_ZTIj"
+  }
+ ],
+ "function_types" :
+ [
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPFvPvEPFvS0_21AIMapper_MetadataTypePKvmES0_E",
+   "name" : "AIMapper_Error (void (*)(void *), void (*)(void *, AIMapper_MetadataType, const void *, unsigned long), void *)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPFvPvE"
+    },
+    {
+     "referenced_type" : "_ZTIPFvPv21AIMapper_MetadataTypePKvmE"
+    },
+    {
+     "referenced_type" : "_ZTIPv"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPFvPvEPFvS0_21AIMapper_MetadataTypePKvmES0_E",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPFvPvEPFvS0_21AIMapper_MetadataTypePKvmES0_E",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handle21AIMapper_MetadataTypePKvmE",
+   "name" : "AIMapper_Error (const native_handle *, AIMapper_MetadataType, const void *, unsigned long)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTI21AIMapper_MetadataType"
+    },
+    {
+     "referenced_type" : "_ZTIPKv"
+    },
+    {
+     "referenced_type" : "_ZTIm"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handle21AIMapper_MetadataTypePKvmE",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handle21AIMapper_MetadataTypePKvmE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handleE",
+   "name" : "AIMapper_Error (const native_handle *)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handleE",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handleE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handlePFvPv21AIMapper_MetadataTypePKvmES3_E",
+   "name" : "AIMapper_Error (const native_handle *, void (*)(void *, AIMapper_MetadataType, const void *, unsigned long), void *)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTIPFvPv21AIMapper_MetadataTypePKvmE"
+    },
+    {
+     "referenced_type" : "_ZTIPv"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePFvPv21AIMapper_MetadataTypePKvmES3_E",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePFvPv21AIMapper_MetadataTypePKvmES3_E",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handlePPvPmE",
+   "name" : "AIMapper_Error (const native_handle *, void **, unsigned long *)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTIPPv"
+    },
+    {
+     "referenced_type" : "_ZTIPm"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePPvPmE",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePPvPmE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handlePS2_E",
+   "name" : "AIMapper_Error (const native_handle *, const native_handle **)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTIPPK13native_handle"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePS2_E",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePS2_E",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handlePiE",
+   "name" : "AIMapper_Error (const native_handle *, int *)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTIPi"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePiE",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePiE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handlePjS3_E",
+   "name" : "AIMapper_Error (const native_handle *, unsigned int *, unsigned int *)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTIPj"
+    },
+    {
+     "referenced_type" : "_ZTIPj"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePjS3_E",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePjS3_E",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handlelPKvmE",
+   "name" : "AIMapper_Error (const native_handle *, long, const void *, unsigned long)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTIl"
+    },
+    {
+     "referenced_type" : "_ZTIPKv"
+    },
+    {
+     "referenced_type" : "_ZTIm"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlelPKvmE",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handlelPKvmE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handlem5ARectiPPvE",
+   "name" : "AIMapper_Error (const native_handle *, unsigned long, ARect, int, void **)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTIm"
+    },
+    {
+     "referenced_type" : "_ZTI5ARect"
+    },
+    {
+     "referenced_type" : "_ZTIi"
+    },
+    {
+     "referenced_type" : "_ZTIPPv"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlem5ARectiPPvE",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handlem5ARectiPPvE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPPK32AIMapper_MetadataTypeDescriptionPmE",
+   "name" : "AIMapper_Error (const AIMapper_MetadataTypeDescription **, unsigned long *)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPPK32AIMapper_MetadataTypeDescription"
+    },
+    {
+     "referenced_type" : "_ZTIPm"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPPK32AIMapper_MetadataTypeDescriptionPmE",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPPK32AIMapper_MetadataTypeDescriptionPmE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIFiPK13native_handle21AIMapper_MetadataTypePvmE",
+   "name" : "int (const native_handle *, AIMapper_MetadataType, void *, unsigned long)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTI21AIMapper_MetadataType"
+    },
+    {
+     "referenced_type" : "_ZTIPv"
+    },
+    {
+     "referenced_type" : "_ZTIm"
+    }
+   ],
+   "referenced_type" : "_ZTIFiPK13native_handle21AIMapper_MetadataTypePvmE",
+   "return_type" : "_ZTIi",
+   "self_type" : "_ZTIFiPK13native_handle21AIMapper_MetadataTypePvmE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIFiPK13native_handlelPvmE",
+   "name" : "int (const native_handle *, long, void *, unsigned long)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTIl"
+    },
+    {
+     "referenced_type" : "_ZTIPv"
+    },
+    {
+     "referenced_type" : "_ZTIm"
+    }
+   ],
+   "referenced_type" : "_ZTIFiPK13native_handlelPvmE",
+   "return_type" : "_ZTIi",
+   "self_type" : "_ZTIFiPK13native_handlelPvmE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIFvPv21AIMapper_MetadataTypePKvmE",
+   "name" : "void (void *, AIMapper_MetadataType, const void *, unsigned long)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPv"
+    },
+    {
+     "referenced_type" : "_ZTI21AIMapper_MetadataType"
+    },
+    {
+     "referenced_type" : "_ZTIPKv"
+    },
+    {
+     "referenced_type" : "_ZTIm"
+    }
+   ],
+   "referenced_type" : "_ZTIFvPv21AIMapper_MetadataTypePKvmE",
+   "return_type" : "_ZTIv",
+   "self_type" : "_ZTIFvPv21AIMapper_MetadataTypePKvmE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIFvPvE",
+   "name" : "void (void *)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPv"
+    }
+   ],
+   "referenced_type" : "_ZTIFvPvE",
+   "return_type" : "_ZTIv",
+   "self_type" : "_ZTIFvPvE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  }
+ ],
+ "functions" :
+ [
+  {
+   "function_name" : "AIMapper_loadIMapper",
+   "linker_set_key" : "AIMapper_loadIMapper",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPP8AIMapper"
+    }
+   ],
+   "return_type" : "_ZTI14AIMapper_Error",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  }
+ ],
+ "global_vars" : [],
+ "lvalue_reference_types" : [],
+ "pointer_types" :
+ [
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIP8AIMapper",
+   "name" : "AIMapper *",
+   "referenced_type" : "_ZTI8AIMapper",
+   "self_type" : "_ZTIP8AIMapper",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPFvPvEPFvS0_21AIMapper_MetadataTypePKvmES0_E",
+   "name" : "AIMapper_Error (*)(void (*)(void *), void (*)(void *, AIMapper_MetadataType, const void *, unsigned long), void *)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPFvPvEPFvS0_21AIMapper_MetadataTypePKvmES0_E",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPFvPvEPFvS0_21AIMapper_MetadataTypePKvmES0_E",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handle21AIMapper_MetadataTypePKvmE",
+   "name" : "AIMapper_Error (*)(const native_handle *, AIMapper_MetadataType, const void *, unsigned long)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handle21AIMapper_MetadataTypePKvmE",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handle21AIMapper_MetadataTypePKvmE",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handleE",
+   "name" : "AIMapper_Error (*)(const native_handle *)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handleE",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handleE",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handlePFvPv21AIMapper_MetadataTypePKvmES3_E",
+   "name" : "AIMapper_Error (*)(const native_handle *, void (*)(void *, AIMapper_MetadataType, const void *, unsigned long), void *)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePFvPv21AIMapper_MetadataTypePKvmES3_E",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePFvPv21AIMapper_MetadataTypePKvmES3_E",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handlePPvPmE",
+   "name" : "AIMapper_Error (*)(const native_handle *, void **, unsigned long *)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePPvPmE",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePPvPmE",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handlePS2_E",
+   "name" : "AIMapper_Error (*)(const native_handle *, const native_handle **)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePS2_E",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePS2_E",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handlePiE",
+   "name" : "AIMapper_Error (*)(const native_handle *, int *)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePiE",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePiE",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handlePjS3_E",
+   "name" : "AIMapper_Error (*)(const native_handle *, unsigned int *, unsigned int *)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePjS3_E",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePjS3_E",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handlelPKvmE",
+   "name" : "AIMapper_Error (*)(const native_handle *, long, const void *, unsigned long)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlelPKvmE",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlelPKvmE",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handlem5ARectiPPvE",
+   "name" : "AIMapper_Error (*)(const native_handle *, unsigned long, ARect, int, void **)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlem5ARectiPPvE",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlem5ARectiPPvE",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPPK32AIMapper_MetadataTypeDescriptionPmE",
+   "name" : "AIMapper_Error (*)(const AIMapper_MetadataTypeDescription **, unsigned long *)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPPK32AIMapper_MetadataTypeDescriptionPmE",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPPK32AIMapper_MetadataTypeDescriptionPmE",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPFiPK13native_handle21AIMapper_MetadataTypePvmE",
+   "name" : "int (*)(const native_handle *, AIMapper_MetadataType, void *, unsigned long)",
+   "referenced_type" : "_ZTIFiPK13native_handle21AIMapper_MetadataTypePvmE",
+   "self_type" : "_ZTIPFiPK13native_handle21AIMapper_MetadataTypePvmE",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPFiPK13native_handlelPvmE",
+   "name" : "int (*)(const native_handle *, long, void *, unsigned long)",
+   "referenced_type" : "_ZTIFiPK13native_handlelPvmE",
+   "self_type" : "_ZTIPFiPK13native_handlelPvmE",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPFvPv21AIMapper_MetadataTypePKvmE",
+   "name" : "void (*)(void *, AIMapper_MetadataType, const void *, unsigned long)",
+   "referenced_type" : "_ZTIFvPv21AIMapper_MetadataTypePKvmE",
+   "self_type" : "_ZTIPFvPv21AIMapper_MetadataTypePKvmE",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPFvPvE",
+   "name" : "void (*)(void *)",
+   "referenced_type" : "_ZTIFvPvE",
+   "self_type" : "_ZTIPFvPvE",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPK13native_handle",
+   "name" : "const native_handle *",
+   "referenced_type" : "_ZTIK13native_handle",
+   "self_type" : "_ZTIPK13native_handle",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPK32AIMapper_MetadataTypeDescription",
+   "name" : "const AIMapper_MetadataTypeDescription *",
+   "referenced_type" : "_ZTIK32AIMapper_MetadataTypeDescription",
+   "self_type" : "_ZTIPK32AIMapper_MetadataTypeDescription",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPKc",
+   "name" : "const char *",
+   "referenced_type" : "_ZTIKc",
+   "self_type" : "_ZTIPKc",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPKv",
+   "name" : "const void *",
+   "referenced_type" : "_ZTIKv",
+   "self_type" : "_ZTIPKv",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPP8AIMapper",
+   "name" : "AIMapper **",
+   "referenced_type" : "_ZTIP8AIMapper",
+   "self_type" : "_ZTIPP8AIMapper",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPPK13native_handle",
+   "name" : "const native_handle **",
+   "referenced_type" : "_ZTIPK13native_handle",
+   "self_type" : "_ZTIPPK13native_handle",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPPK32AIMapper_MetadataTypeDescription",
+   "name" : "const AIMapper_MetadataTypeDescription **",
+   "referenced_type" : "_ZTIPK32AIMapper_MetadataTypeDescription",
+   "self_type" : "_ZTIPPK32AIMapper_MetadataTypeDescription",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPPv",
+   "name" : "void **",
+   "referenced_type" : "_ZTIPv",
+   "self_type" : "_ZTIPPv",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPi",
+   "name" : "int *",
+   "referenced_type" : "_ZTIi",
+   "self_type" : "_ZTIPi",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPj",
+   "name" : "unsigned int *",
+   "referenced_type" : "_ZTIj",
+   "self_type" : "_ZTIPj",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPm",
+   "name" : "unsigned long *",
+   "referenced_type" : "_ZTIm",
+   "self_type" : "_ZTIPm",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "linker_set_key" : "_ZTIPv",
+   "name" : "void *",
+   "referenced_type" : "_ZTIv",
+   "self_type" : "_ZTIPv",
+   "size" : 8,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  }
+ ],
+ "qualified_types" :
+ [
+  {
+   "alignment" : 4,
+   "is_const" : true,
+   "linker_set_key" : "_ZTIK13native_handle",
+   "name" : "const native_handle",
+   "referenced_type" : "_ZTI13native_handle",
+   "self_type" : "_ZTIK13native_handle",
+   "size" : 12,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "is_const" : true,
+   "linker_set_key" : "_ZTIK32AIMapper_MetadataTypeDescription",
+   "name" : "const AIMapper_MetadataTypeDescription",
+   "referenced_type" : "_ZTI32AIMapper_MetadataTypeDescription",
+   "self_type" : "_ZTIK32AIMapper_MetadataTypeDescription",
+   "size" : 64,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 1,
+   "is_const" : true,
+   "linker_set_key" : "_ZTIKc",
+   "name" : "const char",
+   "referenced_type" : "_ZTIc",
+   "self_type" : "_ZTIKc",
+   "size" : 1,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "is_const" : true,
+   "linker_set_key" : "_ZTIKv",
+   "name" : "const void",
+   "referenced_type" : "_ZTIv",
+   "self_type" : "_ZTIKv",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  }
+ ],
+ "record_types" :
+ [
+  {
+   "alignment" : 8,
+   "fields" :
+   [
+    {
+     "field_name" : "importBuffer",
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePS2_E"
+    },
+    {
+     "field_name" : "freeBuffer",
+     "field_offset" : 64,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handleE"
+    },
+    {
+     "field_name" : "getTransportSize",
+     "field_offset" : 128,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePjS3_E"
+    },
+    {
+     "field_name" : "lock",
+     "field_offset" : 192,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlem5ARectiPPvE"
+    },
+    {
+     "field_name" : "unlock",
+     "field_offset" : 256,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePiE"
+    },
+    {
+     "field_name" : "flushLockedBuffer",
+     "field_offset" : 320,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handleE"
+    },
+    {
+     "field_name" : "rereadLockedBuffer",
+     "field_offset" : 384,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handleE"
+    },
+    {
+     "field_name" : "getMetadata",
+     "field_offset" : 448,
+     "referenced_type" : "_ZTIPFiPK13native_handle21AIMapper_MetadataTypePvmE"
+    },
+    {
+     "field_name" : "getStandardMetadata",
+     "field_offset" : 512,
+     "referenced_type" : "_ZTIPFiPK13native_handlelPvmE"
+    },
+    {
+     "field_name" : "setMetadata",
+     "field_offset" : 576,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handle21AIMapper_MetadataTypePKvmE"
+    },
+    {
+     "field_name" : "setStandardMetadata",
+     "field_offset" : 640,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlelPKvmE"
+    },
+    {
+     "field_name" : "listSupportedMetadataTypes",
+     "field_offset" : 704,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPPK32AIMapper_MetadataTypeDescriptionPmE"
+    },
+    {
+     "field_name" : "dumpBuffer",
+     "field_offset" : 768,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePFvPv21AIMapper_MetadataTypePKvmES3_E"
+    },
+    {
+     "field_name" : "dumpAllBuffers",
+     "field_offset" : 832,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPFvPvEPFvS0_21AIMapper_MetadataTypePKvmES0_E"
+    },
+    {
+     "field_name" : "getReservedRegion",
+     "field_offset" : 896,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePPvPmE"
+    }
+   ],
+   "linker_set_key" : "_ZTI10AIMapperV5",
+   "name" : "AIMapperV5",
+   "referenced_type" : "_ZTI10AIMapperV5",
+   "self_type" : "_ZTI10AIMapperV5",
+   "size" : 120,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 16,
+   "fields" :
+   [
+    {
+     "field_name" : "__clang_max_align_nonce1",
+     "referenced_type" : "_ZTIx"
+    },
+    {
+     "field_name" : "__clang_max_align_nonce2",
+     "field_offset" : 128,
+     "referenced_type" : "_ZTIg"
+    }
+   ],
+   "linker_set_key" : "_ZTI11max_align_t",
+   "name" : "max_align_t",
+   "referenced_type" : "_ZTI11max_align_t",
+   "self_type" : "_ZTI11max_align_t",
+   "size" : 32,
+   "source_file" : "prebuilts/clang-tools/linux-x86/clang-headers/__stddef_max_align_t.h"
+  },
+  {
+   "alignment" : 4,
+   "fields" :
+   [
+    {
+     "field_name" : "version",
+     "referenced_type" : "_ZTIi"
+    },
+    {
+     "field_name" : "numFds",
+     "field_offset" : 32,
+     "referenced_type" : "_ZTIi"
+    },
+    {
+     "field_name" : "numInts",
+     "field_offset" : 64,
+     "referenced_type" : "_ZTIi"
+    },
+    {
+     "field_name" : "data",
+     "field_offset" : 96,
+     "referenced_type" : "_ZTIA0_i"
+    }
+   ],
+   "linker_set_key" : "_ZTI13native_handle",
+   "name" : "native_handle",
+   "referenced_type" : "_ZTI13native_handle",
+   "self_type" : "_ZTI13native_handle",
+   "size" : 12,
+   "source_file" : "system/core/include/cutils/native_handle.h"
+  },
+  {
+   "alignment" : 8,
+   "fields" :
+   [
+    {
+     "field_name" : "name",
+     "referenced_type" : "_ZTIPKc"
+    },
+    {
+     "field_name" : "value",
+     "field_offset" : 64,
+     "referenced_type" : "_ZTIl"
+    }
+   ],
+   "linker_set_key" : "_ZTI21AIMapper_MetadataType",
+   "name" : "AIMapper_MetadataType",
+   "referenced_type" : "_ZTI21AIMapper_MetadataType",
+   "self_type" : "_ZTI21AIMapper_MetadataType",
+   "size" : 16,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "fields" :
+   [
+    {
+     "field_name" : "metadataType",
+     "referenced_type" : "_ZTI21AIMapper_MetadataType"
+    },
+    {
+     "field_name" : "description",
+     "field_offset" : 128,
+     "referenced_type" : "_ZTIPKc"
+    },
+    {
+     "field_name" : "isGettable",
+     "field_offset" : 192,
+     "referenced_type" : "_ZTIb"
+    },
+    {
+     "field_name" : "isSettable",
+     "field_offset" : 200,
+     "referenced_type" : "_ZTIb"
+    },
+    {
+     "field_name" : "reserved",
+     "field_offset" : 208,
+     "referenced_type" : "_ZTIA32_h"
+    }
+   ],
+   "linker_set_key" : "_ZTI32AIMapper_MetadataTypeDescription",
+   "name" : "AIMapper_MetadataTypeDescription",
+   "referenced_type" : "_ZTI32AIMapper_MetadataTypeDescription",
+   "self_type" : "_ZTI32AIMapper_MetadataTypeDescription",
+   "size" : 64,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "fields" :
+   [
+    {
+     "field_name" : "left",
+     "referenced_type" : "_ZTIi"
+    },
+    {
+     "field_name" : "top",
+     "field_offset" : 32,
+     "referenced_type" : "_ZTIi"
+    },
+    {
+     "field_name" : "right",
+     "field_offset" : 64,
+     "referenced_type" : "_ZTIi"
+    },
+    {
+     "field_name" : "bottom",
+     "field_offset" : 96,
+     "referenced_type" : "_ZTIi"
+    }
+   ],
+   "linker_set_key" : "_ZTI5ARect",
+   "name" : "ARect",
+   "referenced_type" : "_ZTI5ARect",
+   "self_type" : "_ZTI5ARect",
+   "size" : 16,
+   "source_file" : "frameworks/native/libs/arect/include/android/rect.h"
+  },
+  {
+   "alignment" : 16,
+   "fields" :
+   [
+    {
+     "field_name" : "version",
+     "referenced_type" : "_ZTI16AIMapper_Version"
+    },
+    {
+     "field_name" : "v5",
+     "field_offset" : 64,
+     "referenced_type" : "_ZTI10AIMapperV5"
+    }
+   ],
+   "linker_set_key" : "_ZTI8AIMapper",
+   "name" : "AIMapper",
+   "referenced_type" : "_ZTI8AIMapper",
+   "self_type" : "_ZTI8AIMapper",
+   "size" : 128,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  }
+ ],
+ "rvalue_reference_types" : []
+}
diff --git a/graphics/mapper/stable-c/abi-dumps/x86_x86_64/source-based/libimapper_stablec_abicheck.so.lsdump b/graphics/mapper/stable-c/abi-dumps/x86_x86_64/source-based/libimapper_stablec_abicheck.so.lsdump
new file mode 100644
index 0000000..3eca8c3
--- /dev/null
+++ b/graphics/mapper/stable-c/abi-dumps/x86_x86_64/source-based/libimapper_stablec_abicheck.so.lsdump
@@ -0,0 +1,1052 @@
+{
+ "array_types" :
+ [
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIA0_i",
+   "name" : "int[0]",
+   "referenced_type" : "_ZTIi",
+   "self_type" : "_ZTIA0_i",
+   "source_file" : "system/core/include/cutils/native_handle.h"
+  },
+  {
+   "alignment" : 1,
+   "linker_set_key" : "_ZTIA32_h",
+   "name" : "unsigned char[32]",
+   "referenced_type" : "_ZTIh",
+   "self_type" : "_ZTIA32_h",
+   "size" : 32,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  }
+ ],
+ "builtin_types" :
+ [
+  {
+   "alignment" : 1,
+   "is_integral" : true,
+   "is_unsigned" : true,
+   "linker_set_key" : "_ZTIb",
+   "name" : "bool",
+   "referenced_type" : "_ZTIb",
+   "self_type" : "_ZTIb",
+   "size" : 1
+  },
+  {
+   "alignment" : 1,
+   "is_integral" : true,
+   "linker_set_key" : "_ZTIc",
+   "name" : "char",
+   "referenced_type" : "_ZTIc",
+   "self_type" : "_ZTIc",
+   "size" : 1
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIe",
+   "name" : "long double",
+   "referenced_type" : "_ZTIe",
+   "self_type" : "_ZTIe",
+   "size" : 8
+  },
+  {
+   "alignment" : 1,
+   "is_integral" : true,
+   "is_unsigned" : true,
+   "linker_set_key" : "_ZTIh",
+   "name" : "unsigned char",
+   "referenced_type" : "_ZTIh",
+   "self_type" : "_ZTIh",
+   "size" : 1
+  },
+  {
+   "alignment" : 4,
+   "is_integral" : true,
+   "linker_set_key" : "_ZTIi",
+   "name" : "int",
+   "referenced_type" : "_ZTIi",
+   "self_type" : "_ZTIi",
+   "size" : 4
+  },
+  {
+   "alignment" : 4,
+   "is_integral" : true,
+   "is_unsigned" : true,
+   "linker_set_key" : "_ZTIj",
+   "name" : "unsigned int",
+   "referenced_type" : "_ZTIj",
+   "self_type" : "_ZTIj",
+   "size" : 4
+  },
+  {
+   "linker_set_key" : "_ZTIv",
+   "name" : "void",
+   "referenced_type" : "_ZTIv",
+   "self_type" : "_ZTIv"
+  },
+  {
+   "alignment" : 4,
+   "is_integral" : true,
+   "linker_set_key" : "_ZTIx",
+   "name" : "long long",
+   "referenced_type" : "_ZTIx",
+   "self_type" : "_ZTIx",
+   "size" : 8
+  },
+  {
+   "alignment" : 4,
+   "is_integral" : true,
+   "is_unsigned" : true,
+   "linker_set_key" : "_ZTIy",
+   "name" : "unsigned long long",
+   "referenced_type" : "_ZTIy",
+   "self_type" : "_ZTIy",
+   "size" : 8
+  }
+ ],
+ "elf_functions" :
+ [
+  {
+   "name" : "AIMapper_loadIMapper"
+  }
+ ],
+ "elf_objects" : [],
+ "enum_types" :
+ [
+  {
+   "alignment" : 4,
+   "enum_fields" :
+   [
+    {
+     "enum_field_value" : 0,
+     "name" : "AIMAPPER_ERROR_NONE"
+    },
+    {
+     "enum_field_value" : 1,
+     "name" : "AIMAPPER_ERROR_BAD_DESCRIPTOR"
+    },
+    {
+     "enum_field_value" : 2,
+     "name" : "AIMAPPER_ERROR_BAD_BUFFER"
+    },
+    {
+     "enum_field_value" : 3,
+     "name" : "AIMAPPER_ERROR_BAD_VALUE"
+    },
+    {
+     "enum_field_value" : 5,
+     "name" : "AIMAPPER_ERROR_NO_RESOURCES"
+    },
+    {
+     "enum_field_value" : 7,
+     "name" : "AIMAPPER_ERROR_UNSUPPORTED"
+    }
+   ],
+   "linker_set_key" : "_ZTI14AIMapper_Error",
+   "name" : "AIMapper_Error",
+   "referenced_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTI14AIMapper_Error",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h",
+   "underlying_type" : "_ZTIi"
+  },
+  {
+   "alignment" : 4,
+   "enum_fields" :
+   [
+    {
+     "enum_field_value" : 5,
+     "name" : "AIMAPPER_VERSION_5"
+    }
+   ],
+   "linker_set_key" : "_ZTI16AIMapper_Version",
+   "name" : "AIMapper_Version",
+   "referenced_type" : "_ZTI16AIMapper_Version",
+   "self_type" : "_ZTI16AIMapper_Version",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h",
+   "underlying_type" : "_ZTIj"
+  }
+ ],
+ "function_types" :
+ [
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPFvPvEPFvS0_21AIMapper_MetadataTypePKvjES0_E",
+   "name" : "AIMapper_Error (void (*)(void *), void (*)(void *, AIMapper_MetadataType, const void *, unsigned int), void *)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPFvPvE"
+    },
+    {
+     "referenced_type" : "_ZTIPFvPv21AIMapper_MetadataTypePKvjE"
+    },
+    {
+     "referenced_type" : "_ZTIPv"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPFvPvEPFvS0_21AIMapper_MetadataTypePKvjES0_E",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPFvPvEPFvS0_21AIMapper_MetadataTypePKvjES0_E",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handle21AIMapper_MetadataTypePKvjE",
+   "name" : "AIMapper_Error (const native_handle *, AIMapper_MetadataType, const void *, unsigned int)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTI21AIMapper_MetadataType"
+    },
+    {
+     "referenced_type" : "_ZTIPKv"
+    },
+    {
+     "referenced_type" : "_ZTIj"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handle21AIMapper_MetadataTypePKvjE",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handle21AIMapper_MetadataTypePKvjE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handleE",
+   "name" : "AIMapper_Error (const native_handle *)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handleE",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handleE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handlePFvPv21AIMapper_MetadataTypePKvjES3_E",
+   "name" : "AIMapper_Error (const native_handle *, void (*)(void *, AIMapper_MetadataType, const void *, unsigned int), void *)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTIPFvPv21AIMapper_MetadataTypePKvjE"
+    },
+    {
+     "referenced_type" : "_ZTIPv"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePFvPv21AIMapper_MetadataTypePKvjES3_E",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePFvPv21AIMapper_MetadataTypePKvjES3_E",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handlePPvPyE",
+   "name" : "AIMapper_Error (const native_handle *, void **, unsigned long long *)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTIPPv"
+    },
+    {
+     "referenced_type" : "_ZTIPy"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePPvPyE",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePPvPyE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handlePS2_E",
+   "name" : "AIMapper_Error (const native_handle *, const native_handle **)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTIPPK13native_handle"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePS2_E",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePS2_E",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handlePiE",
+   "name" : "AIMapper_Error (const native_handle *, int *)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTIPi"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePiE",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePiE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handlePjS3_E",
+   "name" : "AIMapper_Error (const native_handle *, unsigned int *, unsigned int *)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTIPj"
+    },
+    {
+     "referenced_type" : "_ZTIPj"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePjS3_E",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePjS3_E",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handlexPKvjE",
+   "name" : "AIMapper_Error (const native_handle *, long long, const void *, unsigned int)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTIx"
+    },
+    {
+     "referenced_type" : "_ZTIPKv"
+    },
+    {
+     "referenced_type" : "_ZTIj"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlexPKvjE",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handlexPKvjE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPK13native_handley5ARectiPPvE",
+   "name" : "AIMapper_Error (const native_handle *, unsigned long long, ARect, int, void **)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTIy"
+    },
+    {
+     "referenced_type" : "_ZTI5ARect"
+    },
+    {
+     "referenced_type" : "_ZTIi"
+    },
+    {
+     "referenced_type" : "_ZTIPPv"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handley5ARectiPPvE",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPK13native_handley5ARectiPPvE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIF14AIMapper_ErrorPPK32AIMapper_MetadataTypeDescriptionPjE",
+   "name" : "AIMapper_Error (const AIMapper_MetadataTypeDescription **, unsigned int *)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPPK32AIMapper_MetadataTypeDescription"
+    },
+    {
+     "referenced_type" : "_ZTIPj"
+    }
+   ],
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPPK32AIMapper_MetadataTypeDescriptionPjE",
+   "return_type" : "_ZTI14AIMapper_Error",
+   "self_type" : "_ZTIF14AIMapper_ErrorPPK32AIMapper_MetadataTypeDescriptionPjE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIFiPK13native_handle21AIMapper_MetadataTypePvjE",
+   "name" : "int (const native_handle *, AIMapper_MetadataType, void *, unsigned int)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTI21AIMapper_MetadataType"
+    },
+    {
+     "referenced_type" : "_ZTIPv"
+    },
+    {
+     "referenced_type" : "_ZTIj"
+    }
+   ],
+   "referenced_type" : "_ZTIFiPK13native_handle21AIMapper_MetadataTypePvjE",
+   "return_type" : "_ZTIi",
+   "self_type" : "_ZTIFiPK13native_handle21AIMapper_MetadataTypePvjE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIFiPK13native_handlexPvjE",
+   "name" : "int (const native_handle *, long long, void *, unsigned int)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPK13native_handle"
+    },
+    {
+     "referenced_type" : "_ZTIx"
+    },
+    {
+     "referenced_type" : "_ZTIPv"
+    },
+    {
+     "referenced_type" : "_ZTIj"
+    }
+   ],
+   "referenced_type" : "_ZTIFiPK13native_handlexPvjE",
+   "return_type" : "_ZTIi",
+   "self_type" : "_ZTIFiPK13native_handlexPvjE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIFvPv21AIMapper_MetadataTypePKvjE",
+   "name" : "void (void *, AIMapper_MetadataType, const void *, unsigned int)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPv"
+    },
+    {
+     "referenced_type" : "_ZTI21AIMapper_MetadataType"
+    },
+    {
+     "referenced_type" : "_ZTIPKv"
+    },
+    {
+     "referenced_type" : "_ZTIj"
+    }
+   ],
+   "referenced_type" : "_ZTIFvPv21AIMapper_MetadataTypePKvjE",
+   "return_type" : "_ZTIv",
+   "self_type" : "_ZTIFvPv21AIMapper_MetadataTypePKvjE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIFvPvE",
+   "name" : "void (void *)",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPv"
+    }
+   ],
+   "referenced_type" : "_ZTIFvPvE",
+   "return_type" : "_ZTIv",
+   "self_type" : "_ZTIFvPvE",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  }
+ ],
+ "functions" :
+ [
+  {
+   "function_name" : "AIMapper_loadIMapper",
+   "linker_set_key" : "AIMapper_loadIMapper",
+   "parameters" :
+   [
+    {
+     "referenced_type" : "_ZTIPP8AIMapper"
+    }
+   ],
+   "return_type" : "_ZTI14AIMapper_Error",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  }
+ ],
+ "global_vars" : [],
+ "lvalue_reference_types" : [],
+ "pointer_types" :
+ [
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIP8AIMapper",
+   "name" : "AIMapper *",
+   "referenced_type" : "_ZTI8AIMapper",
+   "self_type" : "_ZTIP8AIMapper",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPFvPvEPFvS0_21AIMapper_MetadataTypePKvjES0_E",
+   "name" : "AIMapper_Error (*)(void (*)(void *), void (*)(void *, AIMapper_MetadataType, const void *, unsigned int), void *)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPFvPvEPFvS0_21AIMapper_MetadataTypePKvjES0_E",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPFvPvEPFvS0_21AIMapper_MetadataTypePKvjES0_E",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handle21AIMapper_MetadataTypePKvjE",
+   "name" : "AIMapper_Error (*)(const native_handle *, AIMapper_MetadataType, const void *, unsigned int)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handle21AIMapper_MetadataTypePKvjE",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handle21AIMapper_MetadataTypePKvjE",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handleE",
+   "name" : "AIMapper_Error (*)(const native_handle *)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handleE",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handleE",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handlePFvPv21AIMapper_MetadataTypePKvjES3_E",
+   "name" : "AIMapper_Error (*)(const native_handle *, void (*)(void *, AIMapper_MetadataType, const void *, unsigned int), void *)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePFvPv21AIMapper_MetadataTypePKvjES3_E",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePFvPv21AIMapper_MetadataTypePKvjES3_E",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handlePPvPyE",
+   "name" : "AIMapper_Error (*)(const native_handle *, void **, unsigned long long *)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePPvPyE",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePPvPyE",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handlePS2_E",
+   "name" : "AIMapper_Error (*)(const native_handle *, const native_handle **)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePS2_E",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePS2_E",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handlePiE",
+   "name" : "AIMapper_Error (*)(const native_handle *, int *)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePiE",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePiE",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handlePjS3_E",
+   "name" : "AIMapper_Error (*)(const native_handle *, unsigned int *, unsigned int *)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlePjS3_E",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePjS3_E",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handlexPKvjE",
+   "name" : "AIMapper_Error (*)(const native_handle *, long long, const void *, unsigned int)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handlexPKvjE",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlexPKvjE",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPK13native_handley5ARectiPPvE",
+   "name" : "AIMapper_Error (*)(const native_handle *, unsigned long long, ARect, int, void **)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPK13native_handley5ARectiPPvE",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPK13native_handley5ARectiPPvE",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPF14AIMapper_ErrorPPK32AIMapper_MetadataTypeDescriptionPjE",
+   "name" : "AIMapper_Error (*)(const AIMapper_MetadataTypeDescription **, unsigned int *)",
+   "referenced_type" : "_ZTIF14AIMapper_ErrorPPK32AIMapper_MetadataTypeDescriptionPjE",
+   "self_type" : "_ZTIPF14AIMapper_ErrorPPK32AIMapper_MetadataTypeDescriptionPjE",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPFiPK13native_handle21AIMapper_MetadataTypePvjE",
+   "name" : "int (*)(const native_handle *, AIMapper_MetadataType, void *, unsigned int)",
+   "referenced_type" : "_ZTIFiPK13native_handle21AIMapper_MetadataTypePvjE",
+   "self_type" : "_ZTIPFiPK13native_handle21AIMapper_MetadataTypePvjE",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPFiPK13native_handlexPvjE",
+   "name" : "int (*)(const native_handle *, long long, void *, unsigned int)",
+   "referenced_type" : "_ZTIFiPK13native_handlexPvjE",
+   "self_type" : "_ZTIPFiPK13native_handlexPvjE",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPFvPv21AIMapper_MetadataTypePKvjE",
+   "name" : "void (*)(void *, AIMapper_MetadataType, const void *, unsigned int)",
+   "referenced_type" : "_ZTIFvPv21AIMapper_MetadataTypePKvjE",
+   "self_type" : "_ZTIPFvPv21AIMapper_MetadataTypePKvjE",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPFvPvE",
+   "name" : "void (*)(void *)",
+   "referenced_type" : "_ZTIFvPvE",
+   "self_type" : "_ZTIPFvPvE",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPK13native_handle",
+   "name" : "const native_handle *",
+   "referenced_type" : "_ZTIK13native_handle",
+   "self_type" : "_ZTIPK13native_handle",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPK32AIMapper_MetadataTypeDescription",
+   "name" : "const AIMapper_MetadataTypeDescription *",
+   "referenced_type" : "_ZTIK32AIMapper_MetadataTypeDescription",
+   "self_type" : "_ZTIPK32AIMapper_MetadataTypeDescription",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPKc",
+   "name" : "const char *",
+   "referenced_type" : "_ZTIKc",
+   "self_type" : "_ZTIPKc",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPKv",
+   "name" : "const void *",
+   "referenced_type" : "_ZTIKv",
+   "self_type" : "_ZTIPKv",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPP8AIMapper",
+   "name" : "AIMapper **",
+   "referenced_type" : "_ZTIP8AIMapper",
+   "self_type" : "_ZTIPP8AIMapper",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPPK13native_handle",
+   "name" : "const native_handle **",
+   "referenced_type" : "_ZTIPK13native_handle",
+   "self_type" : "_ZTIPPK13native_handle",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPPK32AIMapper_MetadataTypeDescription",
+   "name" : "const AIMapper_MetadataTypeDescription **",
+   "referenced_type" : "_ZTIPK32AIMapper_MetadataTypeDescription",
+   "self_type" : "_ZTIPPK32AIMapper_MetadataTypeDescription",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPPv",
+   "name" : "void **",
+   "referenced_type" : "_ZTIPv",
+   "self_type" : "_ZTIPPv",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPi",
+   "name" : "int *",
+   "referenced_type" : "_ZTIi",
+   "self_type" : "_ZTIPi",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPj",
+   "name" : "unsigned int *",
+   "referenced_type" : "_ZTIj",
+   "self_type" : "_ZTIPj",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPv",
+   "name" : "void *",
+   "referenced_type" : "_ZTIv",
+   "self_type" : "_ZTIPv",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "linker_set_key" : "_ZTIPy",
+   "name" : "unsigned long long *",
+   "referenced_type" : "_ZTIy",
+   "self_type" : "_ZTIPy",
+   "size" : 4,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  }
+ ],
+ "qualified_types" :
+ [
+  {
+   "alignment" : 4,
+   "is_const" : true,
+   "linker_set_key" : "_ZTIK13native_handle",
+   "name" : "const native_handle",
+   "referenced_type" : "_ZTI13native_handle",
+   "self_type" : "_ZTIK13native_handle",
+   "size" : 12,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "is_const" : true,
+   "linker_set_key" : "_ZTIK32AIMapper_MetadataTypeDescription",
+   "name" : "const AIMapper_MetadataTypeDescription",
+   "referenced_type" : "_ZTI32AIMapper_MetadataTypeDescription",
+   "self_type" : "_ZTIK32AIMapper_MetadataTypeDescription",
+   "size" : 52,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 1,
+   "is_const" : true,
+   "linker_set_key" : "_ZTIKc",
+   "name" : "const char",
+   "referenced_type" : "_ZTIc",
+   "self_type" : "_ZTIKc",
+   "size" : 1,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "is_const" : true,
+   "linker_set_key" : "_ZTIKv",
+   "name" : "const void",
+   "referenced_type" : "_ZTIv",
+   "self_type" : "_ZTIKv",
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  }
+ ],
+ "record_types" :
+ [
+  {
+   "alignment" : 4,
+   "fields" :
+   [
+    {
+     "field_name" : "importBuffer",
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePS2_E"
+    },
+    {
+     "field_name" : "freeBuffer",
+     "field_offset" : 32,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handleE"
+    },
+    {
+     "field_name" : "getTransportSize",
+     "field_offset" : 64,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePjS3_E"
+    },
+    {
+     "field_name" : "lock",
+     "field_offset" : 96,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handley5ARectiPPvE"
+    },
+    {
+     "field_name" : "unlock",
+     "field_offset" : 128,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePiE"
+    },
+    {
+     "field_name" : "flushLockedBuffer",
+     "field_offset" : 160,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handleE"
+    },
+    {
+     "field_name" : "rereadLockedBuffer",
+     "field_offset" : 192,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handleE"
+    },
+    {
+     "field_name" : "getMetadata",
+     "field_offset" : 224,
+     "referenced_type" : "_ZTIPFiPK13native_handle21AIMapper_MetadataTypePvjE"
+    },
+    {
+     "field_name" : "getStandardMetadata",
+     "field_offset" : 256,
+     "referenced_type" : "_ZTIPFiPK13native_handlexPvjE"
+    },
+    {
+     "field_name" : "setMetadata",
+     "field_offset" : 288,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handle21AIMapper_MetadataTypePKvjE"
+    },
+    {
+     "field_name" : "setStandardMetadata",
+     "field_offset" : 320,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlexPKvjE"
+    },
+    {
+     "field_name" : "listSupportedMetadataTypes",
+     "field_offset" : 352,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPPK32AIMapper_MetadataTypeDescriptionPjE"
+    },
+    {
+     "field_name" : "dumpBuffer",
+     "field_offset" : 384,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePFvPv21AIMapper_MetadataTypePKvjES3_E"
+    },
+    {
+     "field_name" : "dumpAllBuffers",
+     "field_offset" : 416,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPFvPvEPFvS0_21AIMapper_MetadataTypePKvjES0_E"
+    },
+    {
+     "field_name" : "getReservedRegion",
+     "field_offset" : 448,
+     "referenced_type" : "_ZTIPF14AIMapper_ErrorPK13native_handlePPvPyE"
+    }
+   ],
+   "linker_set_key" : "_ZTI10AIMapperV5",
+   "name" : "AIMapperV5",
+   "referenced_type" : "_ZTI10AIMapperV5",
+   "self_type" : "_ZTI10AIMapperV5",
+   "size" : 60,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 8,
+   "fields" :
+   [
+    {
+     "field_name" : "__clang_max_align_nonce1",
+     "referenced_type" : "_ZTIx"
+    },
+    {
+     "field_name" : "__clang_max_align_nonce2",
+     "field_offset" : 64,
+     "referenced_type" : "_ZTIe"
+    }
+   ],
+   "linker_set_key" : "_ZTI11max_align_t",
+   "name" : "max_align_t",
+   "referenced_type" : "_ZTI11max_align_t",
+   "self_type" : "_ZTI11max_align_t",
+   "size" : 16,
+   "source_file" : "prebuilts/clang-tools/linux-x86/clang-headers/__stddef_max_align_t.h"
+  },
+  {
+   "alignment" : 4,
+   "fields" :
+   [
+    {
+     "field_name" : "version",
+     "referenced_type" : "_ZTIi"
+    },
+    {
+     "field_name" : "numFds",
+     "field_offset" : 32,
+     "referenced_type" : "_ZTIi"
+    },
+    {
+     "field_name" : "numInts",
+     "field_offset" : 64,
+     "referenced_type" : "_ZTIi"
+    },
+    {
+     "field_name" : "data",
+     "field_offset" : 96,
+     "referenced_type" : "_ZTIA0_i"
+    }
+   ],
+   "linker_set_key" : "_ZTI13native_handle",
+   "name" : "native_handle",
+   "referenced_type" : "_ZTI13native_handle",
+   "self_type" : "_ZTI13native_handle",
+   "size" : 12,
+   "source_file" : "system/core/include/cutils/native_handle.h"
+  },
+  {
+   "alignment" : 4,
+   "fields" :
+   [
+    {
+     "field_name" : "name",
+     "referenced_type" : "_ZTIPKc"
+    },
+    {
+     "field_name" : "value",
+     "field_offset" : 32,
+     "referenced_type" : "_ZTIx"
+    }
+   ],
+   "linker_set_key" : "_ZTI21AIMapper_MetadataType",
+   "name" : "AIMapper_MetadataType",
+   "referenced_type" : "_ZTI21AIMapper_MetadataType",
+   "self_type" : "_ZTI21AIMapper_MetadataType",
+   "size" : 12,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "fields" :
+   [
+    {
+     "field_name" : "metadataType",
+     "referenced_type" : "_ZTI21AIMapper_MetadataType"
+    },
+    {
+     "field_name" : "description",
+     "field_offset" : 96,
+     "referenced_type" : "_ZTIPKc"
+    },
+    {
+     "field_name" : "isGettable",
+     "field_offset" : 128,
+     "referenced_type" : "_ZTIb"
+    },
+    {
+     "field_name" : "isSettable",
+     "field_offset" : 136,
+     "referenced_type" : "_ZTIb"
+    },
+    {
+     "field_name" : "reserved",
+     "field_offset" : 144,
+     "referenced_type" : "_ZTIA32_h"
+    }
+   ],
+   "linker_set_key" : "_ZTI32AIMapper_MetadataTypeDescription",
+   "name" : "AIMapper_MetadataTypeDescription",
+   "referenced_type" : "_ZTI32AIMapper_MetadataTypeDescription",
+   "self_type" : "_ZTI32AIMapper_MetadataTypeDescription",
+   "size" : 52,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  },
+  {
+   "alignment" : 4,
+   "fields" :
+   [
+    {
+     "field_name" : "left",
+     "referenced_type" : "_ZTIi"
+    },
+    {
+     "field_name" : "top",
+     "field_offset" : 32,
+     "referenced_type" : "_ZTIi"
+    },
+    {
+     "field_name" : "right",
+     "field_offset" : 64,
+     "referenced_type" : "_ZTIi"
+    },
+    {
+     "field_name" : "bottom",
+     "field_offset" : 96,
+     "referenced_type" : "_ZTIi"
+    }
+   ],
+   "linker_set_key" : "_ZTI5ARect",
+   "name" : "ARect",
+   "referenced_type" : "_ZTI5ARect",
+   "self_type" : "_ZTI5ARect",
+   "size" : 16,
+   "source_file" : "frameworks/native/libs/arect/include/android/rect.h"
+  },
+  {
+   "alignment" : 8,
+   "fields" :
+   [
+    {
+     "field_name" : "version",
+     "referenced_type" : "_ZTI16AIMapper_Version"
+    },
+    {
+     "field_name" : "v5",
+     "field_offset" : 32,
+     "referenced_type" : "_ZTI10AIMapperV5"
+    }
+   ],
+   "linker_set_key" : "_ZTI8AIMapper",
+   "name" : "AIMapper",
+   "referenced_type" : "_ZTI8AIMapper",
+   "self_type" : "_ZTI8AIMapper",
+   "size" : 64,
+   "source_file" : "hardware/interfaces/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h"
+  }
+ ],
+ "rvalue_reference_types" : []
+}
diff --git a/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h b/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h
index 75e436d..23de7b9 100644
--- a/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h
+++ b/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h
@@ -87,7 +87,7 @@
  *
  * Vendor-provided metadata should be prefixed with a "vendor.mycompanyname.*" namespace. It is
  * recommended that the metadata follows the pattern of StandardMetadaType.aidl. That is, an
- * aidl-defined enum with @VendorStability on it and the naming then matching that type such
+ * aidl-defined enum with @VintfStability on it and the naming then matching that type such
  * as "vendor.mycompanyname.graphics.common.MetadataType" with the value field then set to the
  * aidl's enum value.
  *
diff --git a/health/aidl/vts/functional/VtsHalHealthTargetTest.cpp b/health/aidl/vts/functional/VtsHalHealthTargetTest.cpp
index 9360789..45a1e40 100644
--- a/health/aidl/vts/functional/VtsHalHealthTargetTest.cpp
+++ b/health/aidl/vts/functional/VtsHalHealthTargetTest.cpp
@@ -312,7 +312,8 @@
     return true;
 }
 
-/*
+/* @VsrTest = 3.2.015
+ *
  * Tests the values returned by getBatteryHealthData() from interface IHealth.
  */
 TEST_P(HealthAidl, getBatteryHealthData) {
diff --git a/identity/aidl/default/Android.bp b/identity/aidl/default/Android.bp
index 7bc3c8d..a1045c3 100644
--- a/identity/aidl/default/Android.bp
+++ b/identity/aidl/default/Android.bp
@@ -36,7 +36,7 @@
     ],
     static_libs: [
         "libbase",
-        "libcppbor_external",
+        "libcppbor",
         "libcppcose_rkp",
         "libutils",
         "libsoft_attestation_cert",
@@ -102,7 +102,7 @@
     ],
     static_libs: [
         "libbase",
-        "libcppbor_external",
+        "libcppbor",
         "libcppcose_rkp",
         "libutils",
         "libsoft_attestation_cert",
@@ -146,7 +146,7 @@
     ],
     static_libs: [
         "libbase",
-        "libcppbor_external",
+        "libcppbor",
         "libcppcose_rkp",
         "libutils",
         "libsoft_attestation_cert",
diff --git a/identity/aidl/vts/Android.bp b/identity/aidl/vts/Android.bp
index 6f7ab54..8ff2382 100644
--- a/identity/aidl/vts/Android.bp
+++ b/identity/aidl/vts/Android.bp
@@ -42,7 +42,7 @@
         "android.hardware.security.rkp-V3-cpp",
         "android.hardware.security.rkp-V3-ndk",
         "android.hardware.security.secureclock-V1-ndk",
-        "libcppbor_external",
+        "libcppbor",
         "libcppcose_rkp",
         "libkeymaster_portable",
         "libkeymint_vts_test_utils",
diff --git a/identity/support/Android.bp b/identity/support/Android.bp
index d62d055..cc0a684 100644
--- a/identity/support/Android.bp
+++ b/identity/support/Android.bp
@@ -36,7 +36,7 @@
         "libpuresoftkeymasterdevice",
     ],
     static_libs: [
-        "libcppbor_external",
+        "libcppbor",
     ],
 }
 
@@ -70,7 +70,7 @@
     ],
     static_libs: [
         "android.hardware.identity-support-lib",
-        "libcppbor_external",
+        "libcppbor",
         "libgmock",
     ],
     test_suites: ["general-tests"],
diff --git a/media/1.0/Android.bp b/media/1.0/Android.bp
index 22a6d59..d5ef95a 100644
--- a/media/1.0/Android.bp
+++ b/media/1.0/Android.bp
@@ -12,9 +12,6 @@
 hidl_interface {
     name: "android.hardware.media@1.0",
     root: "android.hardware",
-    vndk: {
-        enabled: true,
-    },
     srcs: [
         "types.hal",
     ],
diff --git a/media/1.0/xml/Android.bp b/media/1.0/xml/Android.bp
new file mode 100644
index 0000000..5b5a95c
--- /dev/null
+++ b/media/1.0/xml/Android.bp
@@ -0,0 +1,26 @@
+// 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 {
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+///////////////////////////////////////
+// media_profiles_V1_0.dtd
+
+prebuilt_etc {
+    name: "media_profiles_V1_0.dtd",
+    src: "media_profiles.dtd",
+    filename: "media_profiles_V1_0.dtd",
+}
diff --git a/media/1.0/xml/Android.mk b/media/1.0/xml/Android.mk
deleted file mode 100644
index a795288..0000000
--- a/media/1.0/xml/Android.mk
+++ /dev/null
@@ -1,16 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-#######################################
-# media_profiles_V1_0.dtd
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := media_profiles_V1_0.dtd
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../../NOTICE
-LOCAL_SRC_FILES := media_profiles.dtd
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)
-
-include $(BUILD_PREBUILT)
diff --git a/media/bufferpool/2.0/Android.bp b/media/bufferpool/2.0/Android.bp
index fd6f08b..470a11f 100644
--- a/media/bufferpool/2.0/Android.bp
+++ b/media/bufferpool/2.0/Android.bp
@@ -13,9 +13,6 @@
 hidl_interface {
     name: "android.hardware.media.bufferpool@2.0",
     root: "android.hardware",
-    vndk: {
-        enabled: true,
-    },
     srcs: [
         "types.hal",
         "IAccessor.hal",
diff --git a/media/bufferpool/aidl/default/BufferPool.cpp b/media/bufferpool/aidl/default/BufferPool.cpp
index ed4574f..57716db 100644
--- a/media/bufferpool/aidl/default/BufferPool.cpp
+++ b/media/bufferpool/aidl/default/BufferPool.cpp
@@ -102,11 +102,11 @@
         if (it->isInvalidated(bufferId)) {
             uint32_t msgId = 0;
             if (it->mNeedsAck) {
-                msgId = ++mInvalidationId;
-                if (msgId == 0) {
-                    // wrap happens
-                    msgId = ++mInvalidationId;
+                if (mInvalidationId == UINT_MAX) {
+                    // wrap happens;
+                    mInvalidationId = 0;
                 }
+                msgId = ++mInvalidationId;
             }
             channel.postInvalidation(msgId, it->mFrom, it->mTo);
             it = mPendings.erase(it);
@@ -125,11 +125,11 @@
         const std::shared_ptr<Accessor> &impl) {
         uint32_t msgId = 0;
     if (needsAck) {
-        msgId = ++mInvalidationId;
-        if (msgId == 0) {
-            // wrap happens
-            msgId = ++mInvalidationId;
+        if (mInvalidationId == UINT_MAX) {
+            //wrap happens
+            mInvalidationId = 0;
         }
+        msgId = ++mInvalidationId;
     }
     ALOGV("bufferpool2 invalidation requested and queued");
     if (left == 0) {
diff --git a/media/bufferpool/aidl/default/BufferStatus.cpp b/media/bufferpool/aidl/default/BufferStatus.cpp
index 19caa1e..fecbe3f 100644
--- a/media/bufferpool/aidl/default/BufferStatus.cpp
+++ b/media/bufferpool/aidl/default/BufferStatus.cpp
@@ -26,8 +26,17 @@
 
 using aidl::android::hardware::media::bufferpool2::BufferStatus;
 
+uint32_t wrappedMinus(uint32_t a, uint32_t b) {
+    if (a >= b) {
+        return a - b;
+    } else {
+        return ~(b - a) + 1;
+    }
+}
+
 bool isMessageLater(uint32_t curMsgId, uint32_t prevMsgId) {
-    return curMsgId != prevMsgId && curMsgId - prevMsgId < prevMsgId - curMsgId;
+    return curMsgId != prevMsgId &&
+            wrappedMinus(curMsgId, prevMsgId) < wrappedMinus(prevMsgId, curMsgId);
 }
 
 bool isBufferInRange(BufferId from, BufferId to, BufferId bufferId) {
diff --git a/media/omx/1.0/Android.bp b/media/omx/1.0/Android.bp
index ea63467..cd1b9b6 100644
--- a/media/omx/1.0/Android.bp
+++ b/media/omx/1.0/Android.bp
@@ -12,9 +12,6 @@
 hidl_interface {
     name: "android.hardware.media.omx@1.0",
     root: "android.hardware",
-    vndk: {
-        enabled: true,
-    },
     srcs: [
         "types.hal",
         "IGraphicBufferSource.hal",
diff --git a/memtrack/1.0/Android.bp b/memtrack/1.0/Android.bp
index bf8db3f..1aeec59 100644
--- a/memtrack/1.0/Android.bp
+++ b/memtrack/1.0/Android.bp
@@ -12,9 +12,6 @@
 hidl_interface {
     name: "android.hardware.memtrack@1.0",
     root: "android.hardware",
-    vndk: {
-        enabled: true,
-    },
     srcs: [
         "types.hal",
         "IMemtrack.hal",
diff --git a/memtrack/aidl/Android.bp b/memtrack/aidl/Android.bp
index 0d1c241..4973d1e 100644
--- a/memtrack/aidl/Android.bp
+++ b/memtrack/aidl/Android.bp
@@ -34,9 +34,6 @@
             enabled: false,
         },
         ndk: {
-            vndk: {
-                enabled: true,
-            },
         },
     },
     frozen: true,
diff --git a/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp b/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp
index 8210ff0..2fc9e65 100644
--- a/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp
+++ b/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp
@@ -562,7 +562,18 @@
  */
 TEST_P(NfcHidlTest, OpenAfterOpen) {
   EXPECT_EQ(NfcStatus::OK, nfc_->open(nfc_cb_));
+  // Wait for OPEN_CPLT event
+  auto res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
+  EXPECT_TRUE(res.no_timeout);
+  EXPECT_EQ(NfcEvent::OPEN_CPLT, res.args->last_event_);
+  EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
+
   EXPECT_EQ(NfcStatus::OK, nfc_->open(nfc_cb_));
+  // Wait for OPEN_CPLT event
+  res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
+  EXPECT_TRUE(res.no_timeout);
+  EXPECT_EQ(NfcEvent::OPEN_CPLT, res.args->last_event_);
+  EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
 }
 
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(NfcHidlTest);
diff --git a/nfc/OWNERS b/nfc/OWNERS
index 7867204..f46dccd 100644
--- a/nfc/OWNERS
+++ b/nfc/OWNERS
@@ -1,6 +1,2 @@
 # Bug component: 48448
-alisher@google.com
-georgekgchang@google.com
-jackcwyu@google.com
-
-
+include platform/packages/apps/Nfc:/OWNERS
\ No newline at end of file
diff --git a/nfc/aidl/default/Android.bp b/nfc/aidl/default/Android.bp
deleted file mode 100644
index 0cda51d..0000000
--- a/nfc/aidl/default/Android.bp
+++ /dev/null
@@ -1,33 +0,0 @@
-package {
-    default_team: "trendy_team_fwk_nfc",
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "hardware_interfaces_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["hardware_interfaces_license"],
-}
-
-cc_binary {
-    name: "android.hardware.nfc-service.example",
-    relative_install_path: "hw",
-    init_rc: ["nfc-service-example.rc"],
-    vintf_fragments: ["nfc-service-example.xml"],
-    vendor: true,
-    cflags: [
-        "-Wall",
-        "-Wextra",
-    ],
-    shared_libs: [
-        "libbase",
-        "liblog",
-        "libutils",
-        "libbinder_ndk",
-        "android.hardware.nfc-V1-ndk",
-    ],
-    srcs: [
-        "main.cpp",
-        "Nfc.cpp",
-        "Vendor_hal_api.cpp",
-    ],
-}
diff --git a/nfc/aidl/default/Nfc.cpp b/nfc/aidl/default/Nfc.cpp
deleted file mode 100644
index 4685b59..0000000
--- a/nfc/aidl/default/Nfc.cpp
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "Nfc.h"
-
-#include <android-base/logging.h>
-
-#include "Vendor_hal_api.h"
-
-namespace aidl {
-namespace android {
-namespace hardware {
-namespace nfc {
-
-std::shared_ptr<INfcClientCallback> Nfc::mCallback = nullptr;
-AIBinder_DeathRecipient* clientDeathRecipient = nullptr;
-
-void OnDeath(void* cookie) {
-    if (Nfc::mCallback != nullptr && !AIBinder_isAlive(Nfc::mCallback->asBinder().get())) {
-        LOG(INFO) << __func__ << " Nfc service has died";
-        Nfc* nfc = static_cast<Nfc*>(cookie);
-        nfc->close(NfcCloseType::DISABLE);
-    }
-}
-
-::ndk::ScopedAStatus Nfc::open(const std::shared_ptr<INfcClientCallback>& clientCallback) {
-    LOG(INFO) << "open";
-    if (clientCallback == nullptr) {
-        LOG(INFO) << "Nfc::open null callback";
-        return ndk::ScopedAStatus::fromServiceSpecificError(
-                static_cast<int32_t>(NfcStatus::FAILED));
-    }
-    Nfc::mCallback = clientCallback;
-
-    clientDeathRecipient = AIBinder_DeathRecipient_new(OnDeath);
-    auto linkRet = AIBinder_linkToDeath(clientCallback->asBinder().get(), clientDeathRecipient,
-                                        this /* cookie */);
-    if (linkRet != STATUS_OK) {
-        LOG(ERROR) << __func__ << ": linkToDeath failed: " << linkRet;
-        // Just ignore the error.
-    }
-
-    int ret = Vendor_hal_open(eventCallback, dataCallback);
-    return ret == 0 ? ndk::ScopedAStatus::ok()
-                    : ndk::ScopedAStatus::fromServiceSpecificError(
-                              static_cast<int32_t>(NfcStatus::FAILED));
-}
-
-::ndk::ScopedAStatus Nfc::close(NfcCloseType type) {
-    LOG(INFO) << "close";
-    if (Nfc::mCallback == nullptr) {
-        LOG(ERROR) << __func__ << "mCallback null";
-        return ndk::ScopedAStatus::fromServiceSpecificError(
-                static_cast<int32_t>(NfcStatus::FAILED));
-    }
-    int ret = 0;
-    if (type == NfcCloseType::HOST_SWITCHED_OFF) {
-        ret = Vendor_hal_close_off();
-    } else {
-        ret = Vendor_hal_close();
-    }
-    Nfc::mCallback = nullptr;
-    AIBinder_DeathRecipient_delete(clientDeathRecipient);
-    clientDeathRecipient = nullptr;
-    return ret == 0 ? ndk::ScopedAStatus::ok()
-                    : ndk::ScopedAStatus::fromServiceSpecificError(
-                              static_cast<int32_t>(NfcStatus::FAILED));
-}
-
-::ndk::ScopedAStatus Nfc::coreInitialized() {
-    LOG(INFO) << "coreInitialized";
-    if (Nfc::mCallback == nullptr) {
-        LOG(ERROR) << __func__ << "mCallback null";
-        return ndk::ScopedAStatus::fromServiceSpecificError(
-                static_cast<int32_t>(NfcStatus::FAILED));
-    }
-    int ret = Vendor_hal_core_initialized();
-
-    return ret == 0 ? ndk::ScopedAStatus::ok()
-                    : ndk::ScopedAStatus::fromServiceSpecificError(
-                              static_cast<int32_t>(NfcStatus::FAILED));
-}
-
-::ndk::ScopedAStatus Nfc::factoryReset() {
-    LOG(INFO) << "factoryReset";
-    Vendor_hal_factoryReset();
-    return ndk::ScopedAStatus::ok();
-}
-
-::ndk::ScopedAStatus Nfc::getConfig(NfcConfig* _aidl_return) {
-    LOG(INFO) << "getConfig";
-    NfcConfig nfcVendorConfig;
-    Vendor_hal_getConfig(nfcVendorConfig);
-
-    *_aidl_return = nfcVendorConfig;
-    return ndk::ScopedAStatus::ok();
-}
-
-::ndk::ScopedAStatus Nfc::powerCycle() {
-    LOG(INFO) << "powerCycle";
-    if (Nfc::mCallback == nullptr) {
-        LOG(ERROR) << __func__ << "mCallback null";
-        return ndk::ScopedAStatus::fromServiceSpecificError(
-                static_cast<int32_t>(NfcStatus::FAILED));
-    }
-    return Vendor_hal_power_cycle() ? ndk::ScopedAStatus::fromServiceSpecificError(
-                                              static_cast<int32_t>(NfcStatus::FAILED))
-                                    : ndk::ScopedAStatus::ok();
-}
-
-::ndk::ScopedAStatus Nfc::preDiscover() {
-    LOG(INFO) << "preDiscover";
-    if (Nfc::mCallback == nullptr) {
-        LOG(ERROR) << __func__ << "mCallback null";
-        return ndk::ScopedAStatus::fromServiceSpecificError(
-                static_cast<int32_t>(NfcStatus::FAILED));
-    }
-    return Vendor_hal_pre_discover() ? ndk::ScopedAStatus::fromServiceSpecificError(
-                                               static_cast<int32_t>(NfcStatus::FAILED))
-                                     : ndk::ScopedAStatus::ok();
-}
-
-::ndk::ScopedAStatus Nfc::write(const std::vector<uint8_t>& data, int32_t* _aidl_return) {
-    LOG(INFO) << "write";
-    if (Nfc::mCallback == nullptr) {
-        LOG(ERROR) << __func__ << "mCallback null";
-        return ndk::ScopedAStatus::fromServiceSpecificError(
-                static_cast<int32_t>(NfcStatus::FAILED));
-    }
-    *_aidl_return = Vendor_hal_write(data.size(), &data[0]);
-    return ndk::ScopedAStatus::ok();
-}
-::ndk::ScopedAStatus Nfc::setEnableVerboseLogging(bool enable) {
-    LOG(INFO) << "setVerboseLogging";
-    Vendor_hal_setVerboseLogging(enable);
-    return ndk::ScopedAStatus::ok();
-}
-
-::ndk::ScopedAStatus Nfc::isVerboseLoggingEnabled(bool* _aidl_return) {
-    *_aidl_return = Vendor_hal_getVerboseLogging();
-    return ndk::ScopedAStatus::ok();
-}
-
-}  // namespace nfc
-}  // namespace hardware
-}  // namespace android
-}  // namespace aidl
diff --git a/nfc/aidl/default/Nfc.h b/nfc/aidl/default/Nfc.h
deleted file mode 100644
index 1b14534..0000000
--- a/nfc/aidl/default/Nfc.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <aidl/android/hardware/nfc/BnNfc.h>
-#include <aidl/android/hardware/nfc/INfcClientCallback.h>
-#include <android-base/logging.h>
-namespace aidl {
-namespace android {
-namespace hardware {
-namespace nfc {
-
-using ::aidl::android::hardware::nfc::NfcCloseType;
-using ::aidl::android::hardware::nfc::NfcConfig;
-using ::aidl::android::hardware::nfc::NfcStatus;
-
-// Default implementation that reports no support NFC.
-struct Nfc : public BnNfc {
-  public:
-    Nfc() = default;
-
-    ::ndk::ScopedAStatus open(const std::shared_ptr<INfcClientCallback>& clientCallback) override;
-    ::ndk::ScopedAStatus close(NfcCloseType type) override;
-    ::ndk::ScopedAStatus coreInitialized() override;
-    ::ndk::ScopedAStatus factoryReset() override;
-    ::ndk::ScopedAStatus getConfig(NfcConfig* _aidl_return) override;
-    ::ndk::ScopedAStatus powerCycle() override;
-    ::ndk::ScopedAStatus preDiscover() override;
-    ::ndk::ScopedAStatus write(const std::vector<uint8_t>& data, int32_t* _aidl_return) override;
-    ::ndk::ScopedAStatus setEnableVerboseLogging(bool enable) override;
-    ::ndk::ScopedAStatus isVerboseLoggingEnabled(bool* _aidl_return) override;
-
-    static void eventCallback(uint8_t event, uint8_t status) {
-        if (mCallback != nullptr) {
-            auto ret = mCallback->sendEvent((NfcEvent)event, (NfcStatus)status);
-            if (!ret.isOk()) {
-                LOG(ERROR) << "Failed to send event!";
-            }
-        }
-    }
-
-    static void dataCallback(uint16_t data_len, uint8_t* p_data) {
-        std::vector<uint8_t> data(p_data, p_data + data_len);
-        if (mCallback != nullptr) {
-            auto ret = mCallback->sendData(data);
-            if (!ret.isOk()) {
-                LOG(ERROR) << "Failed to send data!";
-            }
-        }
-    }
-
-    static std::shared_ptr<INfcClientCallback> mCallback;
-};
-
-}  // namespace nfc
-}  // namespace hardware
-}  // namespace android
-}  // namespace aidl
diff --git a/nfc/aidl/default/Vendor_hal_api.cpp b/nfc/aidl/default/Vendor_hal_api.cpp
deleted file mode 100644
index 66a2ebc..0000000
--- a/nfc/aidl/default/Vendor_hal_api.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <android-base/properties.h>
-#include <dlfcn.h>
-#include <errno.h>
-#include <string.h>
-
-#include "Vendor_hal_api.h"
-
-bool logging = false;
-
-int Vendor_hal_open(nfc_stack_callback_t* p_cback, nfc_stack_data_callback_t* p_data_cback) {
-    (void)p_cback;
-    (void)p_data_cback;
-    // nothing to open in this example
-    return -1;
-}
-
-int Vendor_hal_write(uint16_t data_len, const uint8_t* p_data) {
-    (void)data_len;
-    (void)p_data;
-    return -1;
-}
-
-int Vendor_hal_core_initialized() {
-    return -1;
-}
-
-int Vendor_hal_pre_discover() {
-    return -1;
-}
-
-int Vendor_hal_close() {
-    return -1;
-}
-
-int Vendor_hal_close_off() {
-    return -1;
-}
-
-int Vendor_hal_power_cycle() {
-    return -1;
-}
-
-void Vendor_hal_factoryReset() {}
-
-void Vendor_hal_getConfig(NfcConfig& config) {
-    (void)config;
-}
-
-void Vendor_hal_setVerboseLogging(bool enable) {
-    logging = enable;
-}
-
-bool Vendor_hal_getVerboseLogging() {
-    return logging;
-}
diff --git a/nfc/aidl/default/Vendor_hal_api.h b/nfc/aidl/default/Vendor_hal_api.h
deleted file mode 100644
index 595c2dd..0000000
--- a/nfc/aidl/default/Vendor_hal_api.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#pragma once
-
-#include <aidl/android/hardware/nfc/INfc.h>
-#include <aidl/android/hardware/nfc/NfcConfig.h>
-#include <aidl/android/hardware/nfc/NfcEvent.h>
-#include <aidl/android/hardware/nfc/NfcStatus.h>
-#include <aidl/android/hardware/nfc/PresenceCheckAlgorithm.h>
-#include <aidl/android/hardware/nfc/ProtocolDiscoveryConfig.h>
-#include "hardware_nfc.h"
-
-using aidl::android::hardware::nfc::NfcConfig;
-using aidl::android::hardware::nfc::NfcEvent;
-using aidl::android::hardware::nfc::NfcStatus;
-using aidl::android::hardware::nfc::PresenceCheckAlgorithm;
-using aidl::android::hardware::nfc::ProtocolDiscoveryConfig;
-
-int Vendor_hal_open(nfc_stack_callback_t* p_cback, nfc_stack_data_callback_t* p_data_cback);
-int Vendor_hal_write(uint16_t data_len, const uint8_t* p_data);
-
-int Vendor_hal_core_initialized();
-
-int Vendor_hal_pre_discover();
-
-int Vendor_hal_close();
-
-int Vendor_hal_close_off();
-
-int Vendor_hal_power_cycle();
-
-void Vendor_hal_factoryReset();
-
-void Vendor_hal_getConfig(NfcConfig& config);
-
-void Vendor_hal_setVerboseLogging(bool enable);
-
-bool Vendor_hal_getVerboseLogging();
diff --git a/nfc/aidl/default/hardware_nfc.h b/nfc/aidl/default/hardware_nfc.h
deleted file mode 100644
index 0f856c5..0000000
--- a/nfc/aidl/default/hardware_nfc.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#pragma once
-
-typedef uint8_t nfc_event_t;
-typedef uint8_t nfc_status_t;
-
-/*
- * The callback passed in from the NFC stack that the HAL
- * can use to pass events back to the stack.
- */
-typedef void(nfc_stack_callback_t)(nfc_event_t event, nfc_status_t event_status);
-
-/*
- * The callback passed in from the NFC stack that the HAL
- * can use to pass incomming data to the stack.
- */
-typedef void(nfc_stack_data_callback_t)(uint16_t data_len, uint8_t* p_data);
diff --git a/nfc/aidl/default/main.cpp b/nfc/aidl/default/main.cpp
deleted file mode 100644
index 0cc51e7..0000000
--- a/nfc/aidl/default/main.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <android-base/logging.h>
-#include <android/binder_manager.h>
-#include <android/binder_process.h>
-
-#include "Nfc.h"
-using ::aidl::android::hardware::nfc::Nfc;
-
-int main() {
-    LOG(INFO) << "NFC HAL starting up";
-    if (!ABinderProcess_setThreadPoolMaxThreadCount(1)) {
-        LOG(INFO) << "failed to set thread pool max thread count";
-        return 1;
-    }
-    std::shared_ptr<Nfc> nfc_service = ndk::SharedRefBase::make<Nfc>();
-
-    const std::string instance = std::string() + Nfc::descriptor + "/default";
-    binder_status_t status =
-            AServiceManager_addService(nfc_service->asBinder().get(), instance.c_str());
-    CHECK(status == STATUS_OK);
-    ABinderProcess_joinThreadPool();
-    return 0;
-}
diff --git a/nfc/aidl/default/nfc-service-example.rc b/nfc/aidl/default/nfc-service-example.rc
deleted file mode 100644
index 7d7052e..0000000
--- a/nfc/aidl/default/nfc-service-example.rc
+++ /dev/null
@@ -1,4 +0,0 @@
-service nfc_hal_service /vendor/bin/hw/android.hardware.nfc-service.st
-    class hal
-    user nfc
-    group nfc
diff --git a/nfc/aidl/default/nfc-service-example.xml b/nfc/aidl/default/nfc-service-example.xml
deleted file mode 100644
index 70fed20..0000000
--- a/nfc/aidl/default/nfc-service-example.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<manifest version="1.0" type="device">
-    <hal format="aidl">
-        <name>android.hardware.nfc</name>
-        <fqname>INfc/default</fqname>
-    </hal>
-</manifest>
diff --git a/radio/1.5/vts/functional/radio_hidl_hal_api.cpp b/radio/1.5/vts/functional/radio_hidl_hal_api.cpp
index 3d3abe4..e4db40c 100644
--- a/radio/1.5/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.5/vts/functional/radio_hidl_hal_api.cpp
@@ -519,26 +519,38 @@
 TEST_P(RadioHidlTest_v1_5, setSystemSelectionChannels_1_5) {
     serial = GetRandomSerialNumber();
 
-    ::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands bandP900;
-    bandP900.geranBands() = {GeranBands::BAND_P900};
-    ::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands band850;
-    band850.geranBands() = {GeranBands::BAND_850};
-    ::android::hardware::radio::V1_5::RadioAccessSpecifier specifierP900 = {
-            .radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::GERAN,
-            .bands = bandP900,
+    ::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands band3;
+    band3.eutranBands({::android::hardware::radio::V1_5::EutranBands::BAND_3});
+    ::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands band17;
+    band17.eutranBands({::android::hardware::radio::V1_5::EutranBands::BAND_17});
+    ::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands band20;
+    band20.eutranBands({::android::hardware::radio::V1_5::EutranBands::BAND_20});
+    ::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands band40;
+    band40.eutranBands({::android::hardware::radio::V1_5::EutranBands::BAND_40});
+    ::android::hardware::radio::V1_5::RadioAccessSpecifier specifier3 = {
+            .radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::EUTRAN,
+            .bands = band3,
             .channels = {1, 2}};
-    ::android::hardware::radio::V1_5::RadioAccessSpecifier specifier850 = {
-            .radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::GERAN,
-            .bands = band850,
+    ::android::hardware::radio::V1_5::RadioAccessSpecifier specifier17 = {
+            .radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::EUTRAN,
+            .bands = band17,
+            .channels = {1, 2}};
+    ::android::hardware::radio::V1_5::RadioAccessSpecifier specifier20 = {
+            .radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::EUTRAN,
+            .bands = band20,
+            .channels = {128, 129}};
+    ::android::hardware::radio::V1_5::RadioAccessSpecifier specifier40 = {
+            .radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::EUTRAN,
+            .bands = band40,
             .channels = {128, 129}};
 
-    Return<void> res =
-            radio_v1_5->setSystemSelectionChannels_1_5(serial, true, {specifierP900, specifier850});
+    Return<void> res = radio_v1_5->setSystemSelectionChannels_1_5(
+            serial, true, {specifier3, specifier17, specifier20, specifier40});
     ASSERT_OK(res);
     EXPECT_EQ(std::cv_status::no_timeout, wait());
     EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
     EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
-    ALOGI("setSystemSelectionChannels, rspInfo.error = %s\n",
+    ALOGI("setSystemSelectionChannels_1_5, rspInfo.error = %s\n",
           toString(radioRsp_v1_5->rspInfo.error).c_str());
     ASSERT_TRUE(CheckAnyOfErrors(
             radioRsp_v1_5->rspInfo.error,
@@ -547,12 +559,12 @@
     if (radioRsp_v1_5->rspInfo.error == RadioError::NONE) {
         serial = GetRandomSerialNumber();
         Return<void> res = radio_v1_5->setSystemSelectionChannels_1_5(
-                serial, false, {specifierP900, specifier850});
+                serial, false, {specifier3, specifier17, specifier20, specifier40});
         ASSERT_OK(res);
         EXPECT_EQ(std::cv_status::no_timeout, wait());
         EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
         EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
-        ALOGI("setSystemSelectionChannels, rspInfo.error = %s\n",
+        ALOGI("setSystemSelectionChannels_1_5, rspInfo.error = %s\n",
               toString(radioRsp_v1_5->rspInfo.error).c_str());
         EXPECT_EQ(RadioError::NONE, radioRsp_v1_5->rspInfo.error);
     }
@@ -1190,11 +1202,12 @@
 
     // can't camp on nonexistent MCCMNC, so we expect this to fail.
     Return<void> res = radio_v1_5->setNetworkSelectionModeManual_1_5(
-            serial, "123456", android::hardware::radio::V1_5::RadioAccessNetworks::GERAN);
+            serial, "123456", android::hardware::radio::V1_5::RadioAccessNetworks::EUTRAN);
     EXPECT_EQ(std::cv_status::no_timeout, wait());
     EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
     EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
-
+    ALOGI("setNetworkSelectionModeManual_1_5, rspInfo.error = %s\n",
+          toString(radioRsp_v1_5->rspInfo.error).c_str());
     if (cardStatus.base.base.base.cardState == CardState::ABSENT) {
         ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error,
                                      {RadioError::NONE, RadioError::ILLEGAL_SIM_OR_ME,
diff --git a/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl b/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl
index d9eea03..b67e8e0 100644
--- a/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl
+++ b/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl
@@ -747,6 +747,7 @@
 
     /**
      * Response of isCellularIdentifierTransparencyEnabled.
+     * This is an optional API.
      *
      * @param info Response info struct containing response type, serial no. and error.
      * @param isEnabled Indicates whether cellular identifier transparency is enabled or not.
@@ -757,12 +758,14 @@
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:INTERNAL_ERR
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     void isCellularIdentifierTransparencyEnabledResponse(
             in RadioResponseInfo info, boolean isEnabled);
 
     /**
      * Response of setCellularIdentifierTransparencyEnabled.
+     * This is an optional API.
      *
      * @param info Response info struct containing response type, serial no. and error.
      *
@@ -773,11 +776,13 @@
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:INTERNAL_ERR
      *   RadioError:INVALID_STATE
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     void setCellularIdentifierTransparencyEnabledResponse(in RadioResponseInfo info);
 
     /**
      * Response of setSecurityAlgorithmsUpdatedEnabled.
+     * This is an optional API.
      *
      * @param info Response info struct containing response type, serial no. and error.
      *
@@ -788,11 +793,13 @@
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:INTERNAL_ERR
      *   RadioError:INVALID_STATE
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     void setSecurityAlgorithmsUpdatedEnabledResponse(in RadioResponseInfo info);
 
     /**
      * Response of isSecurityAlgorithmsUpdatedEnabled.
+     * This is an optional API.
      *
      * @param info Response info struct containing response type, serial no. and error.
      * @param isEnabled Indicates whether cellular ciphering transparency is enabled or not.
@@ -803,6 +810,7 @@
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:INTERNAL_ERR
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     void isSecurityAlgorithmsUpdatedEnabledResponse(
             in RadioResponseInfo info, in boolean isEnabled);
diff --git a/radio/aidl/vts/radio_network_test.cpp b/radio/aidl/vts/radio_network_test.cpp
index 5cb0158..b214401 100644
--- a/radio/aidl/vts/radio_network_test.cpp
+++ b/radio/aidl/vts/radio_network_test.cpp
@@ -1426,10 +1426,9 @@
 
     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}));
+            {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::INVALID_ARGUMENTS,
+             RadioError::INVALID_STATE, RadioError::NO_MEMORY, RadioError::INTERNAL_ERR,
+             RadioError::SYSTEM_ERR, RadioError::CANCELLED, RadioError::MODEM_ERR}));
 }
 
 /*
@@ -2196,6 +2195,18 @@
 
     serial = GetRandomSerialNumber();
 
+    radio_network->setEmergencyMode(serial, EmergencyMode::EMERGENCY_WWAN);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+    ASSERT_TRUE(CheckAnyOfErrors(
+            radioRsp_network->rspInfo.error,
+            {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED, RadioError::RADIO_NOT_AVAILABLE,
+             RadioError::MODEM_ERR, RadioError::INVALID_ARGUMENTS}));
+
+    serial = GetRandomSerialNumber();
+
     EmergencyNetworkScanTrigger scanRequest;
     scanRequest.accessNetwork = {AccessNetwork::EUTRAN};
     scanRequest.scanType = EmergencyScanType::NO_PREFERENCE;
@@ -2209,6 +2220,19 @@
             radioRsp_network->rspInfo.error,
             {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED, RadioError::RADIO_NOT_AVAILABLE,
              RadioError::MODEM_ERR, RadioError::INVALID_ARGUMENTS}));
+
+    // exit emergency mode for other tests
+    serial = GetRandomSerialNumber();
+
+    radio_network->exitEmergencyMode(serial);
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                 {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED,
+                                  RadioError::RADIO_NOT_AVAILABLE, RadioError::MODEM_ERR}));
 }
 
 /*
@@ -2435,9 +2459,9 @@
     EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
     EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
 
-    ASSERT_TRUE(CheckAnyOfErrors(
-            radioRsp_network->rspInfo.error,
-            {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::MODEM_ERR}));
+    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                 {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
+                                  RadioError::MODEM_ERR, RadioError::REQUEST_NOT_SUPPORTED}));
 }
 
 TEST_P(RadioNetworkTest, setCellularIdentifierTransparencyEnabled) {
@@ -2466,9 +2490,9 @@
     EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
     EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
 
-    ASSERT_TRUE(CheckAnyOfErrors(
-            radioRsp_network->rspInfo.error,
-            {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::MODEM_ERR}));
+    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                 {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
+                                  RadioError::MODEM_ERR, RadioError::REQUEST_NOT_SUPPORTED}));
 
     // Assert the value has changed
     serial = GetRandomSerialNumber();
@@ -2478,9 +2502,9 @@
     EXPECT_EQ(std::cv_status::no_timeout, wait());
     EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
     EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
-    ASSERT_TRUE(CheckAnyOfErrors(
-            radioRsp_network->rspInfo.error,
-            {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::MODEM_ERR}));
+    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                 {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
+                                  RadioError::MODEM_ERR, RadioError::REQUEST_NOT_SUPPORTED}));
     EXPECT_EQ(valueToSet, radioRsp_network->isCellularIdentifierTransparencyEnabled);
 
     // Reset original state
@@ -2519,9 +2543,9 @@
     EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
     EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
 
-    ASSERT_TRUE(CheckAnyOfErrors(
-            radioRsp_network->rspInfo.error,
-            {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::MODEM_ERR}));
+    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                 {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
+                                  RadioError::MODEM_ERR, RadioError::REQUEST_NOT_SUPPORTED}));
 
     // Assert the value has changed
     serial = GetRandomSerialNumber();
@@ -2531,9 +2555,9 @@
     EXPECT_EQ(std::cv_status::no_timeout, wait());
     EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
     EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
-    ASSERT_TRUE(CheckAnyOfErrors(
-            radioRsp_network->rspInfo.error,
-            {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::MODEM_ERR}));
+    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                 {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
+                                  RadioError::MODEM_ERR, RadioError::REQUEST_NOT_SUPPORTED}));
     EXPECT_EQ(valueToSet, radioRsp_network->isSecurityAlgorithmsUpdatedEnabled);
 
     // Reset original state
@@ -2565,7 +2589,7 @@
     EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
     EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
 
-    ASSERT_TRUE(CheckAnyOfErrors(
-            radioRsp_network->rspInfo.error,
-            {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::MODEM_ERR}));
+    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                 {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
+                                  RadioError::MODEM_ERR, RadioError::REQUEST_NOT_SUPPORTED}));
 }
diff --git a/renderscript/1.0/Android.bp b/renderscript/1.0/Android.bp
index 1f2ac15..c699141 100644
--- a/renderscript/1.0/Android.bp
+++ b/renderscript/1.0/Android.bp
@@ -14,10 +14,6 @@
     root: "android.hardware",
     // TODO(b/153609531): remove when no longer needed.
     native_bridge_supported: true,
-    vndk: {
-        enabled: true,
-        support_system_process: true,
-    },
     srcs: [
         "types.hal",
         "IContext.hal",
diff --git a/security/authgraph/default/src/main.rs b/security/authgraph/default/src/main.rs
index 65ced75..0f6e05c 100644
--- a/security/authgraph/default/src/main.rs
+++ b/security/authgraph/default/src/main.rs
@@ -40,7 +40,7 @@
 }
 
 fn main() {
-    if let Err(e) = inner_main() {
+    if let Err(HalServiceError(e)) = inner_main() {
         panic!("HAL service failed: {:?}", e);
     }
 }
diff --git a/security/keymint/aidl/default/Android.bp b/security/keymint/aidl/default/Android.bp
index 953630b..fbb6140 100644
--- a/security/keymint/aidl/default/Android.bp
+++ b/security/keymint/aidl/default/Android.bp
@@ -7,6 +7,13 @@
     default_applicable_licenses: ["hardware_interfaces_license"],
 }
 
+// The following target has an insecure implementation of KeyMint where the
+// trusted application (TA) code runs in-process alongside the HAL service
+// code.
+//
+// A real device is required to run the TA code in a secure environment, as
+// per CDD 9.11 [C-1-1]: "MUST back up the keystore implementation with an
+// isolated execution environment."
 cc_binary {
     name: "android.hardware.security.keymint-service",
     relative_install_path: "hw",
@@ -30,7 +37,7 @@
         "android.hardware.security.secureclock-V1-ndk",
         "libbase",
         "libbinder_ndk",
-        "libcppbor_external",
+        "libcppbor",
         "libcrypto",
         "libkeymaster_portable",
         "libkeymint",
@@ -46,9 +53,123 @@
     ],
 }
 
+// The following target has an insecure implementation of KeyMint where the
+// trusted application (TA) code runs in-process alongside the HAL service
+// code.
+//
+// A real device is required to run the TA code in a secure environment, as
+// per CDD 9.11 [C-1-1]: "MUST back up the keystore implementation with an
+// isolated execution environment."
+rust_binary {
+    name: "android.hardware.security.keymint-service.nonsecure",
+    relative_install_path: "hw",
+    vendor: true,
+    init_rc: ["android.hardware.security.keymint-service.nonsecure.rc"],
+    vintf_fragments: [
+        "android.hardware.security.keymint-service.xml",
+        "android.hardware.security.sharedsecret-service.xml",
+        "android.hardware.security.secureclock-service.xml",
+    ],
+    defaults: [
+        "keymint_use_latest_hal_aidl_rust",
+    ],
+    srcs: [
+        "main.rs",
+    ],
+    rustlibs: [
+        "libandroid_logger",
+        "libbinder_rs",
+        "liblog_rust",
+        "libkmr_hal",
+        "libkmr_hal_nonsecure",
+        "libkmr_ta_nonsecure",
+    ],
+    required: [
+        "android.hardware.hardware_keystore.xml",
+    ],
+}
+
 prebuilt_etc {
     name: "android.hardware.hardware_keystore.xml",
     sub_dir: "permissions",
     vendor: true,
     src: "android.hardware.hardware_keystore.xml",
 }
+
+rust_library {
+    name: "libkmr_hal_nonsecure",
+    crate_name: "kmr_hal_nonsecure",
+    vendor_available: true,
+    lints: "android",
+    rustlibs: [
+        "libbinder_rs",
+        "libhex",
+        "liblibc",
+        "liblog_rust",
+        "libkmr_hal",
+        "libkmr_wire",
+    ],
+    srcs: ["hal/lib.rs"],
+
+}
+
+rust_library {
+    name: "libkmr_ta_nonsecure",
+    crate_name: "kmr_ta_nonsecure",
+    vendor_available: true,
+    host_supported: true,
+    lints: "android",
+    rustlibs: [
+        "libhex",
+        "liblibc",
+        "liblog_rust",
+        "libkmr_common",
+        "libkmr_crypto_boring",
+        "libkmr_ta",
+        "libkmr_wire",
+    ],
+    srcs: ["ta/lib.rs"],
+}
+
+apex {
+    name: "com.android.hardware.keymint.rust_nonsecure",
+    manifest: "manifest.json",
+    file_contexts: "file_contexts",
+    key: "com.google.cf.apex.key",
+    certificate: ":com.android.hardware.certificate",
+    soc_specific: true,
+    updatable: false,
+    binaries: [
+        "android.hardware.security.keymint-service.nonsecure",
+    ],
+    prebuilts: [
+        "keymint_aidl_nonsecure_init_rc",
+        "keymint_aidl_nonsecure_vintf",
+        "android.hardware.hardware_keystore.xml", // permissions
+    ],
+}
+
+prebuilt_etc {
+    name: "keymint_aidl_nonsecure_init_rc",
+    filename_from_src: true,
+    vendor: true,
+    src: ":gen-keymint_aidl_nonsecure_init_rc",
+}
+
+genrule {
+    name: "gen-keymint_aidl_nonsecure_init_rc",
+    srcs: ["android.hardware.security.keymint-service.nonsecure.rc"],
+    out: ["android.hardware.security.keymint-service.nonsecure.apex.rc"],
+    cmd: "sed -E 's%/vendor/bin/%/apex/com.android.hardware.keymint/bin/%' $(in) > $(out)",
+}
+
+prebuilt_etc {
+    name: "keymint_aidl_nonsecure_vintf",
+    sub_dir: "vintf",
+    vendor: true,
+    srcs: [
+        "android.hardware.security.keymint-service.xml",
+        "android.hardware.security.sharedsecret-service.xml",
+        "android.hardware.security.secureclock-service.xml",
+    ],
+}
diff --git a/security/keymint/aidl/default/android.hardware.security.keymint-service.nonsecure.rc b/security/keymint/aidl/default/android.hardware.security.keymint-service.nonsecure.rc
new file mode 100644
index 0000000..c792eae
--- /dev/null
+++ b/security/keymint/aidl/default/android.hardware.security.keymint-service.nonsecure.rc
@@ -0,0 +1,3 @@
+service vendor.keymint-default /vendor/bin/hw/android.hardware.security.keymint-service.nonsecure
+    class early_hal
+    user nobody
diff --git a/security/keymint/aidl/default/file_contexts b/security/keymint/aidl/default/file_contexts
new file mode 100644
index 0000000..dce7e3c
--- /dev/null
+++ b/security/keymint/aidl/default/file_contexts
@@ -0,0 +1,3 @@
+(/.*)?                                                           u:object_r:vendor_file:s0
+/etc(/.*)?                                                       u:object_r:vendor_configs_file:s0
+/bin/hw/android\.hardware\.security\.keymint-service\.nonsecure  u:object_r:hal_keymint_rust_exec:s0
diff --git a/security/keymint/aidl/default/hal/lib.rs b/security/keymint/aidl/default/hal/lib.rs
new file mode 100644
index 0000000..621f077
--- /dev/null
+++ b/security/keymint/aidl/default/hal/lib.rs
@@ -0,0 +1,99 @@
+/*
+ * 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.
+ */
+
+//! KeyMint helper functions that are only suitable for non-secure environments
+//! such as Cuttlefish.
+
+use kmr_hal::env::get_property;
+use log::error;
+
+/// Populate attestation ID information based on properties (where available).
+/// Retrieving the serial number requires SELinux permission.
+pub fn attestation_id_info() -> kmr_wire::AttestationIdInfo {
+    let prop = |name| {
+        get_property(name)
+            .unwrap_or_else(|_| format!("{} unavailable", name))
+            .as_bytes()
+            .to_vec()
+    };
+    kmr_wire::AttestationIdInfo {
+        brand: prop("ro.product.brand"),
+        device: prop("ro.product.device"),
+        product: prop("ro.product.name"),
+        serial: prop("ro.serialno"),
+        manufacturer: prop("ro.product.manufacturer"),
+        model: prop("ro.product.model"),
+        // Currently modem_simulator always returns one fixed value. See `handleGetIMEI` in
+        // device/google/cuttlefish/host/commands/modem_simulator/misc_service.cpp for more details.
+        // TODO(b/263188546): Use device-specific IMEI values when available.
+        imei: b"867400022047199".to_vec(),
+        imei2: b"867400022047199".to_vec(),
+        meid: vec![],
+    }
+}
+
+/// Get boot information based on system properties.
+pub fn get_boot_info() -> kmr_wire::SetBootInfoRequest {
+    // No access to a verified boot key.
+    let verified_boot_key = vec![0; 32];
+    let vbmeta_digest = get_property("ro.boot.vbmeta.digest").unwrap_or_else(|_| "00".repeat(32));
+    let verified_boot_hash = hex::decode(&vbmeta_digest).unwrap_or_else(|_e| {
+        error!("failed to parse hex data in '{}'", vbmeta_digest);
+        vec![0; 32]
+    });
+    let device_boot_locked = match get_property("ro.boot.vbmeta.device_state")
+        .unwrap_or_else(|_| "no-prop".to_string())
+        .as_str()
+    {
+        "locked" => true,
+        "unlocked" => false,
+        v => {
+            error!("Unknown device_state '{}', treating as unlocked", v);
+            false
+        }
+    };
+    let verified_boot_state = match get_property("ro.boot.verifiedbootstate")
+        .unwrap_or_else(|_| "no-prop".to_string())
+        .as_str()
+    {
+        "green" => 0,  // Verified
+        "yellow" => 1, // SelfSigned
+        "orange" => 2, // Unverified,
+        "red" => 3,    // Failed,
+        v => {
+            error!("Unknown boot state '{}', treating as Unverified", v);
+            2
+        }
+    };
+
+    // Attempt to get the boot patchlevel from a system property.  This requires an SELinux
+    // permission, so fall back to re-using the OS patchlevel if this can't be done.
+    let boot_patchlevel_prop = get_property("ro.vendor.boot_security_patch").unwrap_or_else(|e| {
+        error!("Failed to retrieve boot patchlevel: {:?}", e);
+        get_property(kmr_hal::env::OS_PATCHLEVEL_PROPERTY)
+            .unwrap_or_else(|_| "1970-09-19".to_string())
+    });
+    let boot_patchlevel =
+        kmr_hal::env::extract_patchlevel(&boot_patchlevel_prop).unwrap_or(19700919);
+
+    kmr_wire::SetBootInfoRequest {
+        verified_boot_key,
+        device_boot_locked,
+        verified_boot_state,
+        verified_boot_hash,
+        boot_patchlevel,
+    }
+}
diff --git a/security/keymint/aidl/default/main.rs b/security/keymint/aidl/default/main.rs
new file mode 100644
index 0000000..007aded
--- /dev/null
+++ b/security/keymint/aidl/default/main.rs
@@ -0,0 +1,176 @@
+/*
+ * 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.
+ */
+
+//! Default implementation of the KeyMint HAL and related HALs.
+//!
+//! This implementation of the HAL is only intended to allow testing and policy compliance.  A real
+//! implementation **must implement the TA in a secure environment**, as per CDD 9.11 [C-1-1]:
+//! "MUST back up the keystore implementation with an isolated execution environment."
+//!
+//! The additional device-specific components that are required for a real implementation of KeyMint
+//! that is based on the Rust reference implementation are described in system/keymint/README.md.
+
+use kmr_hal::SerializedChannel;
+use kmr_hal_nonsecure::{attestation_id_info, get_boot_info};
+use log::{debug, error, info, warn};
+use std::ops::DerefMut;
+use std::sync::{mpsc, Arc, Mutex};
+
+/// Name of KeyMint binder device instance.
+static SERVICE_INSTANCE: &str = "default";
+
+static KM_SERVICE_NAME: &str = "android.hardware.security.keymint.IKeyMintDevice";
+static RPC_SERVICE_NAME: &str = "android.hardware.security.keymint.IRemotelyProvisionedComponent";
+static CLOCK_SERVICE_NAME: &str = "android.hardware.security.secureclock.ISecureClock";
+static SECRET_SERVICE_NAME: &str = "android.hardware.security.sharedsecret.ISharedSecret";
+
+/// Local error type for failures in the HAL service.
+#[derive(Debug, Clone)]
+struct HalServiceError(String);
+
+impl From<String> for HalServiceError {
+    fn from(s: String) -> Self {
+        Self(s)
+    }
+}
+
+fn main() {
+    if let Err(HalServiceError(e)) = inner_main() {
+        panic!("HAL service failed: {:?}", e);
+    }
+}
+
+fn inner_main() -> Result<(), HalServiceError> {
+    // Initialize Android logging.
+    android_logger::init_once(
+        android_logger::Config::default()
+            .with_tag("keymint-hal-nonsecure")
+            .with_max_level(log::LevelFilter::Info)
+            .with_log_buffer(android_logger::LogId::System),
+    );
+    // Redirect panic messages to logcat.
+    std::panic::set_hook(Box::new(|panic_info| {
+        error!("{}", panic_info);
+    }));
+
+    warn!("Insecure KeyMint HAL service is starting.");
+
+    info!("Starting thread pool now.");
+    binder::ProcessState::start_thread_pool();
+
+    // Create a TA in-process, which acts as a local channel for communication.
+    let channel = Arc::new(Mutex::new(LocalTa::new()));
+
+    // Let the TA know information about the boot environment. In a real device this
+    // is communicated directly from the bootloader to the TA, but here we retrieve
+    // the information from system properties and send from the HAL service.
+    let boot_req = get_boot_info();
+    debug!("boot/HAL->TA: boot info is {:?}", boot_req);
+    kmr_hal::send_boot_info(channel.lock().unwrap().deref_mut(), boot_req)
+        .map_err(|e| HalServiceError(format!("Failed to send boot info: {:?}", e)))?;
+
+    // Let the TA know information about the userspace environment.
+    if let Err(e) = kmr_hal::send_hal_info(channel.lock().unwrap().deref_mut()) {
+        error!("Failed to send HAL info: {:?}", e);
+    }
+
+    // Let the TA know about attestation IDs. (In a real device these would be pre-provisioned into
+    // the TA.)
+    let attest_ids = attestation_id_info();
+    if let Err(e) = kmr_hal::send_attest_ids(channel.lock().unwrap().deref_mut(), attest_ids) {
+        error!("Failed to send attestation ID info: {:?}", e);
+    }
+
+    let secret_service = kmr_hal::sharedsecret::Device::new_as_binder(channel.clone());
+    let service_name = format!("{}/{}", SECRET_SERVICE_NAME, SERVICE_INSTANCE);
+    binder::add_service(&service_name, secret_service.as_binder()).map_err(|e| {
+        HalServiceError(format!(
+            "Failed to register service {} because of {:?}.",
+            service_name, e
+        ))
+    })?;
+
+    let km_service = kmr_hal::keymint::Device::new_as_binder(channel.clone());
+    let service_name = format!("{}/{}", KM_SERVICE_NAME, SERVICE_INSTANCE);
+    binder::add_service(&service_name, km_service.as_binder()).map_err(|e| {
+        HalServiceError(format!(
+            "Failed to register service {} because of {:?}.",
+            service_name, e
+        ))
+    })?;
+
+    let rpc_service = kmr_hal::rpc::Device::new_as_binder(channel.clone());
+    let service_name = format!("{}/{}", RPC_SERVICE_NAME, SERVICE_INSTANCE);
+    binder::add_service(&service_name, rpc_service.as_binder()).map_err(|e| {
+        HalServiceError(format!(
+            "Failed to register service {} because of {:?}.",
+            service_name, e
+        ))
+    })?;
+
+    let clock_service = kmr_hal::secureclock::Device::new_as_binder(channel.clone());
+    let service_name = format!("{}/{}", CLOCK_SERVICE_NAME, SERVICE_INSTANCE);
+    binder::add_service(&service_name, clock_service.as_binder()).map_err(|e| {
+        HalServiceError(format!(
+            "Failed to register service {} because of {:?}.",
+            service_name, e
+        ))
+    })?;
+
+    info!("Successfully registered KeyMint HAL services.");
+    binder::ProcessState::join_thread_pool();
+    info!("KeyMint HAL service is terminating."); // should not reach here
+    Ok(())
+}
+
+/// Implementation of the KeyMint TA that runs locally in-process (and which is therefore
+/// insecure).
+#[derive(Debug)]
+pub struct LocalTa {
+    in_tx: mpsc::Sender<Vec<u8>>,
+    out_rx: mpsc::Receiver<Vec<u8>>,
+}
+
+impl LocalTa {
+    /// Create a new instance.
+    pub fn new() -> Self {
+        // Create a pair of channels to communicate with the TA thread.
+        let (in_tx, in_rx) = mpsc::channel();
+        let (out_tx, out_rx) = mpsc::channel();
+
+        // The TA code expects to run single threaded, so spawn a thread to run it in.
+        std::thread::spawn(move || {
+            let mut ta = kmr_ta_nonsecure::build_ta();
+            loop {
+                let req_data: Vec<u8> = in_rx.recv().expect("failed to receive next req");
+                let rsp_data = ta.process(&req_data);
+                out_tx.send(rsp_data).expect("failed to send out rsp");
+            }
+        });
+        Self { in_tx, out_rx }
+    }
+}
+
+impl SerializedChannel for LocalTa {
+    const MAX_SIZE: usize = usize::MAX;
+
+    fn execute(&mut self, req_data: &[u8]) -> binder::Result<Vec<u8>> {
+        self.in_tx
+            .send(req_data.to_vec())
+            .expect("failed to send in request");
+        Ok(self.out_rx.recv().expect("failed to receive response"))
+    }
+}
diff --git a/security/keymint/aidl/default/manifest.json b/security/keymint/aidl/default/manifest.json
new file mode 100644
index 0000000..289943e
--- /dev/null
+++ b/security/keymint/aidl/default/manifest.json
@@ -0,0 +1,5 @@
+{
+    "name": "com.android.hardware.keymint",
+    "version": 1,
+    "vendorBootstrap": true
+}
diff --git a/security/keymint/aidl/default/ta/attest.rs b/security/keymint/aidl/default/ta/attest.rs
new file mode 100644
index 0000000..1ce2066
--- /dev/null
+++ b/security/keymint/aidl/default/ta/attest.rs
@@ -0,0 +1,425 @@
+//
+// Copyright (C) 2022 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.
+
+//! Attestation keys and certificates.
+//!
+//! Hard-coded keys and certs copied from system/keymaster/context/soft_attestation_cert.cpp
+
+use kmr_common::{
+    crypto::ec, crypto::rsa, crypto::CurveType, crypto::KeyMaterial, wire::keymint,
+    wire::keymint::EcCurve, Error,
+};
+use kmr_ta::device::{RetrieveCertSigningInfo, SigningAlgorithm, SigningKeyType};
+
+/// RSA attestation private key in PKCS#1 format.
+///
+/// Decoded contents (using [der2ascii](https://github.com/google/der-ascii)):
+///
+/// ```
+/// SEQUENCE {
+///   INTEGER { 0 }
+///   INTEGER { `00c08323dc56881bb8302069f5b08561c6eebe7f05e2f5a842048abe8b47be76feaef25cf29b2afa3200141601429989a15fcfc6815eb363583c2fd2f20be4983283dd814b16d7e185417ae54abc296a3a6db5c004083b68c556c1f02339916419864d50b74d40aeca484c77356c895a0c275abfac499d5d7d2362f29c5e02e871` }
+///   INTEGER { 65537 }
+///   INTEGER { `00be860b0b99a802a6fb1a59438a7bb715065b09a36dc6e9cacc6bf3c02c34d7d79e94c6606428d88c7b7f6577c1cdea64074abe8e7286df1f0811dc9728260868de95d32efc96b6d084ff271a5f60defcc703e7a38e6e29ba9a3c5fc2c28076b6a896af1d34d78828ce9bddb1f34f9c9404430781298e201316725bbdbc993a41` }
+///   INTEGER { `00e1c6d927646c0916ec36826d594983740c21f1b074c4a1a59867c669795c85d3dc464c5b929e94bfb34e0dcc5014b10f13341ab7fdd5f60414d2a326cad41cc5` }
+///   INTEGER { `00da485997785cd5630fb0fd8c5254f98e538e18983aae9e6b7e6a5a7b5d343755b9218ebd40320d28387d789f76fa218bcc2d8b68a5f6418fbbeca5179ab3afbd` }
+///   INTEGER { `50fefc32649559616ed6534e154509329d93a3d810dbe5bdb982292cf78bd8badb8020ae8d57f4b71d05386ffe9e9db271ca3477a34999db76f8e5ece9c0d49d` }
+///   INTEGER { `15b74cf27cceff8bb36bf04d9d8346b09a2f70d2f4439b0f26ac7e03f7e9d1f77d4b915fd29b2823f03acb5d5200e0857ff2a803e93eee96d6235ce95442bc21` }
+///   INTEGER { `0090a745da8970b2cd649660324228c5f82856ffd665ba9a85c8d60f1b8bee717ecd2c72eae01dad86ba7654d4cf45adb5f1f2b31d9f8122cfa5f1a5570f9b2d25` }
+/// }
+/// ```
+const RSA_ATTEST_KEY: &str = concat!(
+    "3082025d02010002818100c08323dc56881bb8302069f5b08561c6eebe7f05e2",
+    "f5a842048abe8b47be76feaef25cf29b2afa3200141601429989a15fcfc6815e",
+    "b363583c2fd2f20be4983283dd814b16d7e185417ae54abc296a3a6db5c00408",
+    "3b68c556c1f02339916419864d50b74d40aeca484c77356c895a0c275abfac49",
+    "9d5d7d2362f29c5e02e871020301000102818100be860b0b99a802a6fb1a5943",
+    "8a7bb715065b09a36dc6e9cacc6bf3c02c34d7d79e94c6606428d88c7b7f6577",
+    "c1cdea64074abe8e7286df1f0811dc9728260868de95d32efc96b6d084ff271a",
+    "5f60defcc703e7a38e6e29ba9a3c5fc2c28076b6a896af1d34d78828ce9bddb1",
+    "f34f9c9404430781298e201316725bbdbc993a41024100e1c6d927646c0916ec",
+    "36826d594983740c21f1b074c4a1a59867c669795c85d3dc464c5b929e94bfb3",
+    "4e0dcc5014b10f13341ab7fdd5f60414d2a326cad41cc5024100da485997785c",
+    "d5630fb0fd8c5254f98e538e18983aae9e6b7e6a5a7b5d343755b9218ebd4032",
+    "0d28387d789f76fa218bcc2d8b68a5f6418fbbeca5179ab3afbd024050fefc32",
+    "649559616ed6534e154509329d93a3d810dbe5bdb982292cf78bd8badb8020ae",
+    "8d57f4b71d05386ffe9e9db271ca3477a34999db76f8e5ece9c0d49d024015b7",
+    "4cf27cceff8bb36bf04d9d8346b09a2f70d2f4439b0f26ac7e03f7e9d1f77d4b",
+    "915fd29b2823f03acb5d5200e0857ff2a803e93eee96d6235ce95442bc210241",
+    "0090a745da8970b2cd649660324228c5f82856ffd665ba9a85c8d60f1b8bee71",
+    "7ecd2c72eae01dad86ba7654d4cf45adb5f1f2b31d9f8122cfa5f1a5570f9b2d",
+    "25",
+);
+
+/// Attestation certificate corresponding to [`RSA_ATTEST_KEY`], signed by the key in
+/// [`RSA_ATTEST_ROOT_CERT`].
+///
+/// Decoded contents:
+///
+/// ```
+/// Certificate:
+///     Data:
+///         Version: 3 (0x2)
+///         Serial Number: 4096 (0x1000)
+///     Signature Algorithm: SHA256-RSA
+///         Issuer: C=US, O=Google, Inc., OU=Android, L=Mountain View, ST=California
+///         Validity:
+///             Not Before: 2016-01-04 12:40:53 +0000 UTC
+///             Not After : 2035-12-30 12:40:53 +0000 UTC
+///         Subject: C=US, O=Google, Inc., OU=Android, ST=California, CN=Android Software Attestation Key
+///         Subject Public Key Info:
+///             Public Key Algorithm: rsaEncryption
+///                 Public Key: (1024 bit)
+///                 Modulus:
+///                     c0:83:23:dc:56:88:1b:b8:30:20:69:f5:b0:85:61:
+///                     c6:ee:be:7f:05:e2:f5:a8:42:04:8a:be:8b:47:be:
+///                     76:fe:ae:f2:5c:f2:9b:2a:fa:32:00:14:16:01:42:
+///                     99:89:a1:5f:cf:c6:81:5e:b3:63:58:3c:2f:d2:f2:
+///                     0b:e4:98:32:83:dd:81:4b:16:d7:e1:85:41:7a:e5:
+///                     4a:bc:29:6a:3a:6d:b5:c0:04:08:3b:68:c5:56:c1:
+///                     f0:23:39:91:64:19:86:4d:50:b7:4d:40:ae:ca:48:
+///                     4c:77:35:6c:89:5a:0c:27:5a:bf:ac:49:9d:5d:7d:
+///                     23:62:f2:9c:5e:02:e8:71:
+///                 Exponent: 65537 (0x10001)
+///         X509v3 extensions:
+///             X509v3 Authority Key Identifier:
+///                 keyid:29faf1accc4dd24c96402775b6b0e932e507fe2e
+///             X509v3 Subject Key Identifier:
+///                 keyid:d40c101bf8cd63b9f73952b50e135ca6d7999386
+///             X509v3 Key Usage: critical
+///                 Digital Signature, Certificate Signing
+///             X509v3 Basic Constraints: critical
+///                 CA:true, pathlen:0
+///     Signature Algorithm: SHA256-RSA
+///          9e:2d:48:5f:8c:67:33:dc:1a:85:ad:99:d7:50:23:ea:14:ec:
+///          43:b0:e1:9d:ea:c2:23:46:1e:72:b5:19:dc:60:22:e4:a5:68:
+///          31:6c:0b:55:c4:e6:9c:a2:2d:9f:3a:4f:93:6b:31:8b:16:78:
+///          16:0d:88:cb:d9:8b:cc:80:9d:84:f0:c2:27:e3:6b:38:f1:fd:
+///          d1:e7:17:72:31:59:35:7d:96:f3:c5:7f:ab:9d:8f:96:61:26:
+///          4f:b2:be:81:bb:0d:49:04:22:8a:ce:9f:f7:f5:42:2e:25:44:
+///          fa:21:07:12:5a:83:b5:55:ad:18:82:f8:40:14:9b:9c:20:63:
+///          04:7f:
+/// ```
+const RSA_ATTEST_CERT: &str = concat!(
+    "308202b63082021fa00302010202021000300d06092a864886f70d01010b0500",
+    "3063310b30090603550406130255533113301106035504080c0a43616c69666f",
+    "726e69613116301406035504070c0d4d6f756e7461696e205669657731153013",
+    "060355040a0c0c476f6f676c652c20496e632e3110300e060355040b0c07416e",
+    "64726f6964301e170d3136303130343132343035335a170d3335313233303132",
+    "343035335a3076310b30090603550406130255533113301106035504080c0a43",
+    "616c69666f726e696131153013060355040a0c0c476f6f676c652c20496e632e",
+    "3110300e060355040b0c07416e64726f69643129302706035504030c20416e64",
+    "726f696420536f667477617265204174746573746174696f6e204b657930819f",
+    "300d06092a864886f70d010101050003818d0030818902818100c08323dc5688",
+    "1bb8302069f5b08561c6eebe7f05e2f5a842048abe8b47be76feaef25cf29b2a",
+    "fa3200141601429989a15fcfc6815eb363583c2fd2f20be4983283dd814b16d7",
+    "e185417ae54abc296a3a6db5c004083b68c556c1f02339916419864d50b74d40",
+    "aeca484c77356c895a0c275abfac499d5d7d2362f29c5e02e8710203010001a3",
+    "663064301d0603551d0e04160414d40c101bf8cd63b9f73952b50e135ca6d799",
+    "9386301f0603551d2304183016801429faf1accc4dd24c96402775b6b0e932e5",
+    "07fe2e30120603551d130101ff040830060101ff020100300e0603551d0f0101",
+    "ff040403020284300d06092a864886f70d01010b0500038181009e2d485f8c67",
+    "33dc1a85ad99d75023ea14ec43b0e19deac223461e72b519dc6022e4a568316c",
+    "0b55c4e69ca22d9f3a4f936b318b1678160d88cbd98bcc809d84f0c227e36b38",
+    "f1fdd1e717723159357d96f3c57fab9d8f9661264fb2be81bb0d4904228ace9f",
+    "f7f5422e2544fa2107125a83b555ad1882f840149b9c2063047f",
+);
+
+/// Attestation self-signed root certificate holding the key that signed [`RSA_ATTEST_CERT`].
+///
+/// Decoded contents:
+///
+/// ```
+/// Certificate:
+///     Data:
+///         Version: 3 (0x2)
+///         Serial Number: 18416584322103887884 (0xff94d9dd9f07c80c)
+///     Signature Algorithm: SHA256-RSA
+///         Issuer: C=US, O=Google, Inc., OU=Android, L=Mountain View, ST=California
+///         Validity:
+///             Not Before: 2016-01-04 12:31:08 +0000 UTC
+///             Not After : 2035-12-30 12:31:08 +0000 UTC
+///         Subject: C=US, O=Google, Inc., OU=Android, L=Mountain View, ST=California
+///         Subject Public Key Info:
+///             Public Key Algorithm: rsaEncryption
+///                 Public Key: (1024 bit)
+///                 Modulus:
+///                     a2:6b:ad:eb:6e:2e:44:61:ef:d5:0e:82:e6:b7:94:
+///                     d1:75:23:1f:77:9b:63:91:63:ff:f7:aa:ff:0b:72:
+///                     47:4e:c0:2c:43:ec:33:7c:d7:ac:ed:40:3e:8c:28:
+///                     a0:66:d5:f7:87:0b:33:97:de:0e:b8:4e:13:40:ab:
+///                     af:a5:27:bf:95:69:a0:31:db:06:52:65:f8:44:59:
+///                     57:61:f0:bb:f2:17:4b:b7:41:80:64:c0:28:0e:8f:
+///                     52:77:8e:db:d2:47:b6:45:e9:19:c8:e9:8b:c3:db:
+///                     c2:91:3f:d7:d7:50:c4:1d:35:66:f9:57:e4:97:96:
+///                     0b:09:ac:ce:92:35:85:9b:
+///                 Exponent: 65537 (0x10001)
+///         X509v3 extensions:
+///             X509v3 Authority Key Identifier:
+///                 keyid:29faf1accc4dd24c96402775b6b0e932e507fe2e
+///             X509v3 Subject Key Identifier:
+///                 keyid:29faf1accc4dd24c96402775b6b0e932e507fe2e
+///             X509v3 Key Usage: critical
+///                 Digital Signature, Certificate Signing
+///             X509v3 Basic Constraints: critical
+///                 CA:true
+///     Signature Algorithm: SHA256-RSA
+///          4f:72:f3:36:59:8d:0e:c1:b9:74:5b:31:59:f6:f0:8d:25:49:
+///          30:9e:a3:1c:1c:29:d2:45:2d:20:b9:4d:5f:64:b4:e8:80:c7:
+///          78:7a:9c:39:de:a8:b3:f5:bf:2f:70:5f:47:10:5c:c5:e6:eb:
+///          4d:06:99:61:d2:ae:9a:07:ff:f7:7c:b8:ab:eb:9c:0f:24:07:
+///          5e:b1:7f:ba:79:71:fd:4d:5b:9e:df:14:a9:fe:df:ed:7c:c0:
+///          88:5d:f8:dd:9b:64:32:56:d5:35:9a:e2:13:f9:8f:ce:c1:7c:
+///          dc:ef:a4:aa:b2:55:c3:83:a9:2e:fb:5c:f6:62:f5:27:52:17:
+///          be:63:
+/// ```
+const RSA_ATTEST_ROOT_CERT: &str = concat!(
+    "308202a730820210a003020102020900ff94d9dd9f07c80c300d06092a864886",
+    "f70d01010b05003063310b30090603550406130255533113301106035504080c",
+    "0a43616c69666f726e69613116301406035504070c0d4d6f756e7461696e2056",
+    "69657731153013060355040a0c0c476f6f676c652c20496e632e3110300e0603",
+    "55040b0c07416e64726f6964301e170d3136303130343132333130385a170d33",
+    "35313233303132333130385a3063310b30090603550406130255533113301106",
+    "035504080c0a43616c69666f726e69613116301406035504070c0d4d6f756e74",
+    "61696e205669657731153013060355040a0c0c476f6f676c652c20496e632e31",
+    "10300e060355040b0c07416e64726f696430819f300d06092a864886f70d0101",
+    "01050003818d0030818902818100a26badeb6e2e4461efd50e82e6b794d17523",
+    "1f779b639163fff7aaff0b72474ec02c43ec337cd7aced403e8c28a066d5f787",
+    "0b3397de0eb84e1340abafa527bf9569a031db065265f844595761f0bbf2174b",
+    "b7418064c0280e8f52778edbd247b645e919c8e98bc3dbc2913fd7d750c41d35",
+    "66f957e497960b09acce9235859b0203010001a3633061301d0603551d0e0416",
+    "041429faf1accc4dd24c96402775b6b0e932e507fe2e301f0603551d23041830",
+    "16801429faf1accc4dd24c96402775b6b0e932e507fe2e300f0603551d130101",
+    "ff040530030101ff300e0603551d0f0101ff040403020284300d06092a864886",
+    "f70d01010b0500038181004f72f336598d0ec1b9745b3159f6f08d2549309ea3",
+    "1c1c29d2452d20b94d5f64b4e880c7787a9c39dea8b3f5bf2f705f47105cc5e6",
+    "eb4d069961d2ae9a07fff77cb8abeb9c0f24075eb17fba7971fd4d5b9edf14a9",
+    "fedfed7cc0885df8dd9b643256d5359ae213f98fcec17cdcefa4aab255c383a9",
+    "2efb5cf662f5275217be63",
+);
+
+/// EC attestation private key in `ECPrivateKey` format.
+///
+/// Decoded contents (using [der2ascii](https://github.com/google/der-ascii)):
+///
+/// ```
+/// SEQUENCE {
+///   INTEGER { 1 }
+///   OCTET_STRING { `21e086432a15198459cf363a50fc14c9daadf935f527c2dfd71e4d6dbc42e544` }
+///   [0] {
+///     # secp256r1
+///     OBJECT_IDENTIFIER { 1.2.840.10045.3.1.7 }
+///   }
+///   [1] {
+///     BIT_STRING { `00` `04eb9e79f8426359accb2a914c8986cc70ad90669382a9732613feaccbf821274c2174974a2afea5b94d7f66d4e065106635bc53b7a0a3a671583edb3e11ae1014` }
+///   }
+/// }
+/// ```
+const EC_ATTEST_KEY: &str = concat!(
+    "3077020101042021e086432a15198459cf363a50fc14c9daadf935f527c2dfd7",
+    "1e4d6dbc42e544a00a06082a8648ce3d030107a14403420004eb9e79f8426359",
+    "accb2a914c8986cc70ad90669382a9732613feaccbf821274c2174974a2afea5",
+    "b94d7f66d4e065106635bc53b7a0a3a671583edb3e11ae1014",
+);
+
+/// Attestation certificate corresponding to [`EC_ATTEST_KEY`], signed by the key in
+/// [`EC_ATTEST_ROOT_CERT`].
+///
+/// Decoded contents:
+///
+/// ```
+/// Certificate:
+///     Data:
+///         Version: 3 (0x2)
+///         Serial Number: 4097 (0x1001)
+///     Signature Algorithm: ECDSA-SHA256
+///         Issuer: C=US, O=Google, Inc., OU=Android, L=Mountain View, ST=California, CN=Android Keystore Software Attestation Root
+///         Validity:
+///             Not Before: 2016-01-11 00:46:09 +0000 UTC
+///             Not After : 2026-01-08 00:46:09 +0000 UTC
+///         Subject: C=US, O=Google, Inc., OU=Android, ST=California, CN=Android Keystore Software Attestation Intermediate
+///         Subject Public Key Info:
+///             Public Key Algorithm: id-ecPublicKey
+///                 Public Key: (256 bit)
+///                 pub:
+///                     04:eb:9e:79:f8:42:63:59:ac:cb:2a:91:4c:89:86:
+///                     cc:70:ad:90:66:93:82:a9:73:26:13:fe:ac:cb:f8:
+///                     21:27:4c:21:74:97:4a:2a:fe:a5:b9:4d:7f:66:d4:
+///                     e0:65:10:66:35:bc:53:b7:a0:a3:a6:71:58:3e:db:
+///                     3e:11:ae:10:14:
+///                 ASN1 OID: prime256v1
+///         X509v3 extensions:
+///             X509v3 Authority Key Identifier:
+///                 keyid:c8ade9774c45c3a3cf0d1610e479433a215a30cf
+///             X509v3 Subject Key Identifier:
+///                 keyid:3ffcacd61ab13a9e8120b8d5251cc565bb1e91a9
+///             X509v3 Key Usage: critical
+///                 Digital Signature, Certificate Signing
+///             X509v3 Basic Constraints: critical
+///                 CA:true, pathlen:0
+///     Signature Algorithm: ECDSA-SHA256
+///          30:45:02:20:4b:8a:9b:7b:ee:82:bc:c0:33:87:ae:2f:c0:89:
+///          98:b4:dd:c3:8d:ab:27:2a:45:9f:69:0c:c7:c3:92:d4:0f:8e:
+///          02:21:00:ee:da:01:5d:b6:f4:32:e9:d4:84:3b:62:4c:94:04:
+///          ef:3a:7c:cc:bd:5e:fb:22:bb:e7:fe:b9:77:3f:59:3f:fb:
+/// ```
+const EC_ATTEST_CERT: &str = concat!(
+    "308202783082021ea00302010202021001300a06082a8648ce3d040302308198",
+    "310b30090603550406130255533113301106035504080c0a43616c69666f726e",
+    "69613116301406035504070c0d4d6f756e7461696e2056696577311530130603",
+    "55040a0c0c476f6f676c652c20496e632e3110300e060355040b0c07416e6472",
+    "6f69643133303106035504030c2a416e64726f6964204b657973746f72652053",
+    "6f667477617265204174746573746174696f6e20526f6f74301e170d31363031",
+    "31313030343630395a170d3236303130383030343630395a308188310b300906",
+    "03550406130255533113301106035504080c0a43616c69666f726e6961311530",
+    "13060355040a0c0c476f6f676c652c20496e632e3110300e060355040b0c0741",
+    "6e64726f6964313b303906035504030c32416e64726f6964204b657973746f72",
+    "6520536f667477617265204174746573746174696f6e20496e7465726d656469",
+    "6174653059301306072a8648ce3d020106082a8648ce3d03010703420004eb9e",
+    "79f8426359accb2a914c8986cc70ad90669382a9732613feaccbf821274c2174",
+    "974a2afea5b94d7f66d4e065106635bc53b7a0a3a671583edb3e11ae1014a366",
+    "3064301d0603551d0e041604143ffcacd61ab13a9e8120b8d5251cc565bb1e91",
+    "a9301f0603551d23041830168014c8ade9774c45c3a3cf0d1610e479433a215a",
+    "30cf30120603551d130101ff040830060101ff020100300e0603551d0f0101ff",
+    "040403020284300a06082a8648ce3d040302034800304502204b8a9b7bee82bc",
+    "c03387ae2fc08998b4ddc38dab272a459f690cc7c392d40f8e022100eeda015d",
+    "b6f432e9d4843b624c9404ef3a7cccbd5efb22bbe7feb9773f593ffb",
+);
+
+/// Attestation self-signed root certificate holding the key that signed [`EC_ATTEST_CERT`].
+///
+/// Decoded contents:
+///
+/// ```
+/// Certificate:
+///     Data:
+///         Version: 3 (0x2)
+///         Serial Number: 11674912229752527703 (0xa2059ed10e435b57)
+///     Signature Algorithm: ECDSA-SHA256
+///         Issuer: C=US, O=Google, Inc., OU=Android, L=Mountain View, ST=California, CN=Android Keystore Software Attestation Root
+///         Validity:
+///             Not Before: 2016-01-11 00:43:50 +0000 UTC
+///             Not After : 2036-01-06 00:43:50 +0000 UTC
+///         Subject: C=US, O=Google, Inc., OU=Android, L=Mountain View, ST=California, CN=Android Keystore Software Attestation Root
+///         Subject Public Key Info:
+///             Public Key Algorithm: id-ecPublicKey
+///                 Public Key: (256 bit)
+///                 pub:
+///                     04:ee:5d:5e:c7:e1:c0:db:6d:03:a6:7e:e6:b6:1b:
+///                     ec:4d:6a:5d:6a:68:2e:0f:ff:7f:49:0e:7d:77:1f:
+///                     44:22:6d:bd:b1:af:fa:16:cb:c7:ad:c5:77:d2:56:
+///                     9c:aa:b7:b0:2d:54:01:5d:3e:43:2b:2a:8e:d7:4e:
+///                     ec:48:75:41:a4:
+///                 ASN1 OID: prime256v1
+///         X509v3 extensions:
+///             X509v3 Authority Key Identifier:
+///                 keyid:c8ade9774c45c3a3cf0d1610e479433a215a30cf
+///             X509v3 Subject Key Identifier:
+///                 keyid:c8ade9774c45c3a3cf0d1610e479433a215a30cf
+///             X509v3 Key Usage: critical
+///                 Digital Signature, Certificate Signing
+///             X509v3 Basic Constraints: critical
+///                 CA:true
+///     Signature Algorithm: ECDSA-SHA256
+///          30:44:02:20:35:21:a3:ef:8b:34:46:1e:9c:d5:60:f3:1d:58:
+///          89:20:6a:dc:a3:65:41:f6:0d:9e:ce:8a:19:8c:66:48:60:7b:
+///          02:20:4d:0b:f3:51:d9:30:7c:7d:5b:da:35:34:1d:a8:47:1b:
+///          63:a5:85:65:3c:ad:4f:24:a7:e7:4d:af:41:7d:f1:bf:
+/// ```
+const EC_ATTEST_ROOT_CERT: &str = concat!(
+    "3082028b30820232a003020102020900a2059ed10e435b57300a06082a8648ce",
+    "3d040302308198310b30090603550406130255533113301106035504080c0a43",
+    "616c69666f726e69613116301406035504070c0d4d6f756e7461696e20566965",
+    "7731153013060355040a0c0c476f6f676c652c20496e632e3110300e06035504",
+    "0b0c07416e64726f69643133303106035504030c2a416e64726f6964204b6579",
+    "73746f726520536f667477617265204174746573746174696f6e20526f6f7430",
+    "1e170d3136303131313030343335305a170d3336303130363030343335305a30",
+    "8198310b30090603550406130255533113301106035504080c0a43616c69666f",
+    "726e69613116301406035504070c0d4d6f756e7461696e205669657731153013",
+    "060355040a0c0c476f6f676c652c20496e632e3110300e060355040b0c07416e",
+    "64726f69643133303106035504030c2a416e64726f6964204b657973746f7265",
+    "20536f667477617265204174746573746174696f6e20526f6f74305930130607",
+    "2a8648ce3d020106082a8648ce3d03010703420004ee5d5ec7e1c0db6d03a67e",
+    "e6b61bec4d6a5d6a682e0fff7f490e7d771f44226dbdb1affa16cbc7adc577d2",
+    "569caab7b02d54015d3e432b2a8ed74eec487541a4a3633061301d0603551d0e",
+    "04160414c8ade9774c45c3a3cf0d1610e479433a215a30cf301f0603551d2304",
+    "1830168014c8ade9774c45c3a3cf0d1610e479433a215a30cf300f0603551d13",
+    "0101ff040530030101ff300e0603551d0f0101ff040403020284300a06082a86",
+    "48ce3d040302034700304402203521a3ef8b34461e9cd560f31d5889206adca3",
+    "6541f60d9ece8a198c6648607b02204d0bf351d9307c7d5bda35341da8471b63",
+    "a585653cad4f24a7e74daf417df1bf",
+);
+
+/// Per-algorithm attestation certificate signing information.
+pub struct CertSignAlgoInfo {
+    key: KeyMaterial,
+    chain: Vec<keymint::Certificate>,
+}
+
+/// Certificate signing information for all asymmetric key types.
+pub struct CertSignInfo {
+    rsa_info: CertSignAlgoInfo,
+    ec_info: CertSignAlgoInfo,
+}
+
+impl CertSignInfo {
+    /// Create a new cert signing impl.
+    pub fn new() -> Self {
+        CertSignInfo {
+            rsa_info: CertSignAlgoInfo {
+                key: KeyMaterial::Rsa(rsa::Key(hex::decode(RSA_ATTEST_KEY).unwrap()).into()),
+                chain: vec![
+                    keymint::Certificate {
+                        encoded_certificate: hex::decode(RSA_ATTEST_CERT).unwrap(),
+                    },
+                    keymint::Certificate {
+                        encoded_certificate: hex::decode(RSA_ATTEST_ROOT_CERT).unwrap(),
+                    },
+                ],
+            },
+            ec_info: CertSignAlgoInfo {
+                key: KeyMaterial::Ec(
+                    EcCurve::P256,
+                    CurveType::Nist,
+                    ec::Key::P256(ec::NistKey(hex::decode(EC_ATTEST_KEY).unwrap())).into(),
+                ),
+                chain: vec![
+                    keymint::Certificate {
+                        encoded_certificate: hex::decode(EC_ATTEST_CERT).unwrap(),
+                    },
+                    keymint::Certificate {
+                        encoded_certificate: hex::decode(EC_ATTEST_ROOT_CERT).unwrap(),
+                    },
+                ],
+            },
+        }
+    }
+}
+
+impl RetrieveCertSigningInfo for CertSignInfo {
+    fn signing_key(&self, key_type: SigningKeyType) -> Result<KeyMaterial, Error> {
+        Ok(match key_type.algo_hint {
+            SigningAlgorithm::Rsa => self.rsa_info.key.clone(),
+            SigningAlgorithm::Ec => self.ec_info.key.clone(),
+        })
+    }
+
+    fn cert_chain(&self, key_type: SigningKeyType) -> Result<Vec<keymint::Certificate>, Error> {
+        Ok(match key_type.algo_hint {
+            SigningAlgorithm::Rsa => self.rsa_info.chain.clone(),
+            SigningAlgorithm::Ec => self.ec_info.chain.clone(),
+        })
+    }
+}
diff --git a/security/keymint/aidl/default/ta/clock.rs b/security/keymint/aidl/default/ta/clock.rs
new file mode 100644
index 0000000..03e04ec
--- /dev/null
+++ b/security/keymint/aidl/default/ta/clock.rs
@@ -0,0 +1,44 @@
+//
+// Copyright (C) 2022 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.
+
+//! Monotonic clock implementation.
+
+use kmr_common::crypto;
+
+/// Monotonic clock.
+pub struct StdClock;
+
+impl StdClock {
+    /// Create new clock instance, holding time since construction.
+    pub fn new() -> Self {
+        Self {}
+    }
+}
+
+impl crypto::MonotonicClock for StdClock {
+    fn now(&self) -> crypto::MillisecondsSinceEpoch {
+        let mut time = libc::timespec { tv_sec: 0, tv_nsec: 0 };
+        // Use `CLOCK_BOOTTIME` for consistency with the times used by the Cuttlefish
+        // C++ implementation of Gatekeeper.
+        let rc =
+        // Safety: `time` is a valid structure.
+            unsafe { libc::clock_gettime(libc::CLOCK_BOOTTIME, &mut time as *mut libc::timespec) };
+        if rc < 0 {
+            log::warn!("failed to get time!");
+            return crypto::MillisecondsSinceEpoch(0);
+        }
+        crypto::MillisecondsSinceEpoch(((time.tv_sec * 1000) + (time.tv_nsec / 1000 / 1000)).into())
+    }
+}
diff --git a/security/keymint/aidl/default/ta/lib.rs b/security/keymint/aidl/default/ta/lib.rs
new file mode 100644
index 0000000..f002422
--- /dev/null
+++ b/security/keymint/aidl/default/ta/lib.rs
@@ -0,0 +1,109 @@
+/*
+ * 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.
+ */
+
+//! Local in-process implementation of the KeyMint TA. This is insecure and should
+//! only be used for testing purposes.
+
+// This crate is `std` using, but some of the code uses macros from a `no_std` world.
+extern crate alloc;
+
+use kmr_common::crypto;
+use kmr_crypto_boring::{
+    aes::BoringAes, aes_cmac::BoringAesCmac, des::BoringDes, ec::BoringEc, eq::BoringEq,
+    hmac::BoringHmac, rng::BoringRng, rsa::BoringRsa, sha256::BoringSha256,
+};
+use kmr_ta::device::{
+    BootloaderDone, CsrSigningAlgorithm, Implementation, TrustedPresenceUnsupported,
+};
+use kmr_ta::{HardwareInfo, KeyMintTa, RpcInfo, RpcInfoV3};
+use kmr_wire::keymint::SecurityLevel;
+use kmr_wire::rpc::MINIMUM_SUPPORTED_KEYS_IN_CSR;
+use log::info;
+
+pub mod attest;
+pub mod clock;
+pub mod rpc;
+pub mod soft;
+
+/// Build a set of crypto trait implementations based around BoringSSL and the standard library
+/// clock.
+pub fn boringssl_crypto_impls() -> crypto::Implementation {
+    let rng = BoringRng;
+    let clock = clock::StdClock::new();
+    let rsa = BoringRsa::default();
+    let ec = BoringEc::default();
+    crypto::Implementation {
+        rng: Box::new(rng),
+        clock: Some(Box::new(clock)),
+        compare: Box::new(BoringEq),
+        aes: Box::new(BoringAes),
+        des: Box::new(BoringDes),
+        hmac: Box::new(BoringHmac),
+        rsa: Box::new(rsa),
+        ec: Box::new(ec),
+        ckdf: Box::new(BoringAesCmac),
+        hkdf: Box::new(BoringHmac),
+        sha256: Box::new(BoringSha256),
+    }
+}
+
+/// Build a [`kmr_ta::KeyMintTa`] instance for nonsecure use.
+pub fn build_ta() -> kmr_ta::KeyMintTa {
+    info!("Building NON-SECURE KeyMint Rust TA");
+    let hw_info = HardwareInfo {
+        version_number: 1,
+        security_level: SecurityLevel::TrustedEnvironment,
+        impl_name: "Rust reference implementation",
+        author_name: "Google",
+        unique_id: "NON-SECURE KeyMint TA",
+    };
+    let rpc_sign_algo = CsrSigningAlgorithm::EdDSA;
+    let rpc_info_v3 = RpcInfoV3 {
+        author_name: "Google",
+        unique_id: "NON-SECURE KeyMint TA",
+        fused: false,
+        supported_num_of_keys_in_csr: MINIMUM_SUPPORTED_KEYS_IN_CSR,
+    };
+
+    let sign_info = attest::CertSignInfo::new();
+    let keys: Box<dyn kmr_ta::device::RetrieveKeyMaterial> = Box::new(soft::Keys);
+    let rpc: Box<dyn kmr_ta::device::RetrieveRpcArtifacts> = Box::new(soft::RpcArtifacts::new(
+        soft::Derive::default(),
+        rpc_sign_algo,
+    ));
+    let dev = Implementation {
+        keys,
+        sign_info: Some(Box::new(sign_info)),
+        // HAL populates attestation IDs from properties.
+        attest_ids: None,
+        sdd_mgr: None,
+        // `BOOTLOADER_ONLY` keys not supported.
+        bootloader: Box::new(BootloaderDone),
+        // `STORAGE_KEY` keys not supported.
+        sk_wrapper: None,
+        // `TRUSTED_USER_PRESENCE_REQUIRED` keys not supported
+        tup: Box::new(TrustedPresenceUnsupported),
+        // No support for converting previous implementation's keyblobs.
+        legacy_key: None,
+        rpc,
+    };
+    KeyMintTa::new(
+        hw_info,
+        RpcInfo::V3(rpc_info_v3),
+        boringssl_crypto_impls(),
+        dev,
+    )
+}
diff --git a/security/keymint/aidl/default/ta/rpc.rs b/security/keymint/aidl/default/ta/rpc.rs
new file mode 100644
index 0000000..39da50e
--- /dev/null
+++ b/security/keymint/aidl/default/ta/rpc.rs
@@ -0,0 +1,234 @@
+//
+// Copyright (C) 2022 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.
+
+//! Emulated implementation of device traits for `IRemotelyProvisionedComponent`.
+
+use core::cell::RefCell;
+use kmr_common::crypto::{ec, ec::CoseKeyPurpose, Ec, KeyMaterial};
+use kmr_common::{crypto, explicit, rpc_err, vec_try, Error};
+use kmr_crypto_boring::{ec::BoringEc, hmac::BoringHmac, rng::BoringRng};
+use kmr_ta::device::{
+    CsrSigningAlgorithm, DiceInfo, PubDiceArtifacts, RetrieveRpcArtifacts, RpcV2Req,
+};
+use kmr_wire::coset::{iana, CoseSign1Builder, HeaderBuilder};
+use kmr_wire::keymint::{Digest, EcCurve};
+use kmr_wire::{cbor::value::Value, coset::AsCborValue, rpc, CborError};
+
+/// Trait to encapsulate deterministic derivation of secret data.
+pub trait DeriveBytes {
+    /// Derive `output_len` bytes of data from `context`, deterministically.
+    fn derive_bytes(&self, context: &[u8], output_len: usize) -> Result<Vec<u8>, Error>;
+}
+
+/// Common emulated implementation of RPC artifact retrieval.
+pub struct Artifacts<T: DeriveBytes> {
+    derive: T,
+    sign_algo: CsrSigningAlgorithm,
+    // Invariant once populated: `self.dice_info.signing_algorithm` == `self.sign_algo`
+    dice_info: RefCell<Option<DiceInfo>>,
+    // Invariant once populated: `self.bcc_signing_key` is a variant that matches `self.sign_algo`
+    bcc_signing_key: RefCell<Option<ec::Key>>,
+}
+
+impl<T: DeriveBytes> RetrieveRpcArtifacts for Artifacts<T> {
+    fn derive_bytes_from_hbk(
+        &self,
+        _hkdf: &dyn crypto::Hkdf,
+        context: &[u8],
+        output_len: usize,
+    ) -> Result<Vec<u8>, Error> {
+        self.derive.derive_bytes(context, output_len)
+    }
+
+    fn get_dice_info(&self, _test_mode: rpc::TestMode) -> Result<DiceInfo, Error> {
+        if self.dice_info.borrow().is_none() {
+            let (dice_info, priv_key) = self.generate_dice_artifacts(rpc::TestMode(false))?;
+            *self.dice_info.borrow_mut() = Some(dice_info);
+            *self.bcc_signing_key.borrow_mut() = Some(priv_key);
+        }
+
+        Ok(self
+            .dice_info
+            .borrow()
+            .as_ref()
+            .ok_or_else(|| rpc_err!(Failed, "DICE artifacts are not initialized."))?
+            .clone())
+    }
+
+    fn sign_data(
+        &self,
+        ec: &dyn crypto::Ec,
+        data: &[u8],
+        _rpc_v2: Option<RpcV2Req>,
+    ) -> Result<Vec<u8>, Error> {
+        // DICE artifacts should have been initialized via `get_dice_info()` by the time this
+        // method is called.
+        let private_key = self
+            .bcc_signing_key
+            .borrow()
+            .as_ref()
+            .ok_or_else(|| rpc_err!(Failed, "DICE artifacts are not initialized."))?
+            .clone();
+
+        let mut op = ec.begin_sign(private_key.into(), self.signing_digest())?;
+        op.update(data)?;
+        let sig = op.finish()?;
+        crypto::ec::to_cose_signature(self.signing_curve(), sig)
+    }
+}
+
+impl<T: DeriveBytes> Artifacts<T> {
+    /// Constructor.
+    pub fn new(derive: T, sign_algo: CsrSigningAlgorithm) -> Self {
+        Self {
+            derive,
+            sign_algo,
+            dice_info: RefCell::new(None),
+            bcc_signing_key: RefCell::new(None),
+        }
+    }
+
+    /// Indicate the curve used in signing.
+    fn signing_curve(&self) -> EcCurve {
+        match self.sign_algo {
+            CsrSigningAlgorithm::ES256 => EcCurve::P256,
+            CsrSigningAlgorithm::ES384 => EcCurve::P384,
+            CsrSigningAlgorithm::EdDSA => EcCurve::Curve25519,
+        }
+    }
+
+    /// Indicate the digest used in signing.
+    fn signing_digest(&self) -> Digest {
+        match self.sign_algo {
+            CsrSigningAlgorithm::ES256 => Digest::Sha256,
+            CsrSigningAlgorithm::ES384 => Digest::Sha384,
+            CsrSigningAlgorithm::EdDSA => Digest::None,
+        }
+    }
+
+    /// Indicate the COSE algorithm value associated with signing.
+    fn signing_cose_algo(&self) -> iana::Algorithm {
+        match self.sign_algo {
+            CsrSigningAlgorithm::ES256 => iana::Algorithm::ES256,
+            CsrSigningAlgorithm::ES384 => iana::Algorithm::ES384,
+            CsrSigningAlgorithm::EdDSA => iana::Algorithm::EdDSA,
+        }
+    }
+
+    fn generate_dice_artifacts(
+        &self,
+        _test_mode: rpc::TestMode,
+    ) -> Result<(DiceInfo, ec::Key), Error> {
+        let ec = BoringEc::default();
+
+        let key_material = match self.sign_algo {
+            CsrSigningAlgorithm::EdDSA => {
+                let secret = self.derive_bytes_from_hbk(&BoringHmac, b"Device Key Seed", 32)?;
+                ec::import_raw_ed25519_key(&secret)
+            }
+            // TODO: generate the *same* key after reboot, by use of the TPM.
+            CsrSigningAlgorithm::ES256 => {
+                ec.generate_nist_key(&mut BoringRng, ec::NistCurve::P256, &[])
+            }
+            CsrSigningAlgorithm::ES384 => {
+                ec.generate_nist_key(&mut BoringRng, ec::NistCurve::P384, &[])
+            }
+        }?;
+        let (pub_cose_key, private_key) = match key_material {
+            KeyMaterial::Ec(curve, curve_type, key) => (
+                key.public_cose_key(
+                    &ec,
+                    curve,
+                    curve_type,
+                    CoseKeyPurpose::Sign,
+                    None, /* no key ID */
+                    rpc::TestMode(false),
+                )?,
+                key,
+            ),
+            _ => {
+                return Err(rpc_err!(
+                    Failed,
+                    "expected the Ec variant of KeyMaterial for the cdi leaf key."
+                ))
+            }
+        };
+
+        let cose_key_cbor = pub_cose_key.to_cbor_value().map_err(CborError::from)?;
+        let cose_key_cbor_data = kmr_ta::rkp::serialize_cbor(&cose_key_cbor)?;
+
+        // Construct `DiceChainEntryPayload`
+        let dice_chain_entry_payload = Value::Map(vec_try![
+            // Issuer
+            (
+                Value::Integer(1.into()),
+                Value::Text(String::from("Issuer"))
+            ),
+            // Subject
+            (
+                Value::Integer(2.into()),
+                Value::Text(String::from("Subject"))
+            ),
+            // Subject public key
+            (
+                Value::Integer((-4670552).into()),
+                Value::Bytes(cose_key_cbor_data)
+            ),
+            // Key Usage field contains a CBOR byte string of the bits which correspond
+            // to `keyCertSign` as per RFC 5280 Section 4.2.1.3 (in little-endian byte order)
+            (
+                Value::Integer((-4670553).into()),
+                Value::Bytes(vec_try![0x20]?)
+            ),
+        ]?);
+        let dice_chain_entry_payload_data = kmr_ta::rkp::serialize_cbor(&dice_chain_entry_payload)?;
+
+        // Construct `DiceChainEntry`
+        let protected = HeaderBuilder::new()
+            .algorithm(self.signing_cose_algo())
+            .build();
+        let dice_chain_entry = CoseSign1Builder::new()
+            .protected(protected)
+            .payload(dice_chain_entry_payload_data)
+            .try_create_signature(&[], |input| {
+                let mut op = ec.begin_sign(private_key.clone(), self.signing_digest())?;
+                op.update(input)?;
+                let sig = op.finish()?;
+                crypto::ec::to_cose_signature(self.signing_curve(), sig)
+            })?
+            .build();
+        let dice_chain_entry_cbor = dice_chain_entry.to_cbor_value().map_err(CborError::from)?;
+
+        // Construct `DiceCertChain`
+        let dice_cert_chain = Value::Array(vec_try![cose_key_cbor, dice_chain_entry_cbor]?);
+        let dice_cert_chain_data = kmr_ta::rkp::serialize_cbor(&dice_cert_chain)?;
+
+        // Construct `UdsCerts` as an empty CBOR map
+        let uds_certs_data = kmr_ta::rkp::serialize_cbor(&Value::Map(Vec::new()))?;
+
+        let pub_dice_artifacts = PubDiceArtifacts {
+            dice_cert_chain: dice_cert_chain_data,
+            uds_certs: uds_certs_data,
+        };
+
+        let dice_info = DiceInfo {
+            pub_dice_artifacts,
+            signing_algorithm: self.sign_algo,
+            rpc_v2_test_cdi_priv: None,
+        };
+
+        Ok((dice_info, explicit!(private_key)?))
+    }
+}
diff --git a/security/keymint/aidl/default/ta/soft.rs b/security/keymint/aidl/default/ta/soft.rs
new file mode 100644
index 0000000..5bbe060
--- /dev/null
+++ b/security/keymint/aidl/default/ta/soft.rs
@@ -0,0 +1,67 @@
+//
+// Copyright (C) 2022 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.
+
+//! Software-only trait implementations using fake keys.
+
+use kmr_common::{
+    crypto,
+    crypto::{Hkdf, Rng},
+    Error,
+};
+use kmr_crypto_boring::{hmac::BoringHmac, rng::BoringRng};
+use kmr_ta::device::RetrieveKeyMaterial;
+
+/// Root key retrieval using hard-coded fake keys.
+pub struct Keys;
+
+impl RetrieveKeyMaterial for Keys {
+    fn root_kek(&self, _context: &[u8]) -> Result<crypto::OpaqueOr<crypto::hmac::Key>, Error> {
+        // Matches `MASTER_KEY` in system/keymaster/key_blob_utils/software_keyblobs.cpp
+        Ok(crypto::hmac::Key::new([0; 16].to_vec()).into())
+    }
+    fn kak(&self) -> Result<crypto::OpaqueOr<crypto::aes::Key>, Error> {
+        // Matches `kFakeKeyAgreementKey` in
+        // system/keymaster/km_openssl/soft_keymaster_enforcement.cpp.
+        Ok(crypto::aes::Key::Aes256([0; 32]).into())
+    }
+    fn unique_id_hbk(&self, _ckdf: &dyn crypto::Ckdf) -> Result<crypto::hmac::Key, Error> {
+        // Matches value used in system/keymaster/contexts/pure_soft_keymaster_context.cpp.
+        crypto::hmac::Key::new_from(b"MustBeRandomBits")
+    }
+}
+
+/// Implementation of key derivation using a random fake key.
+pub struct Derive {
+    hbk: Vec<u8>,
+}
+
+impl Default for Derive {
+    fn default() -> Self {
+        // Use random data as an emulation of a hardware-backed key.
+        let mut hbk = vec![0; 32];
+        let mut rng = BoringRng;
+        rng.fill_bytes(&mut hbk);
+        Self { hbk }
+    }
+}
+
+impl crate::rpc::DeriveBytes for Derive {
+    fn derive_bytes(&self, context: &[u8], output_len: usize) -> Result<Vec<u8>, Error> {
+        BoringHmac.hkdf(&[], &self.hbk, context, output_len)
+    }
+}
+
+/// RPC artifact retrieval using software fake key.
+pub type RpcArtifacts = crate::rpc::Artifacts<Derive>;
diff --git a/security/keymint/aidl/vts/functional/Android.bp b/security/keymint/aidl/vts/functional/Android.bp
index 41b161d..7a135e1 100644
--- a/security/keymint/aidl/vts/functional/Android.bp
+++ b/security/keymint/aidl/vts/functional/Android.bp
@@ -45,7 +45,7 @@
         "android.hardware.security.secureclock-V1-ndk",
         "libavb_user",
         "libavb",
-        "libcppbor_external",
+        "libcppbor",
         "libcppcose_rkp",
         "libfs_mgr",
         "libjsoncpp",
diff --git a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
index cc97c13..5106561 100644
--- a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
+++ b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
@@ -16,10 +16,10 @@
 
 #define LOG_TAG "keymint_1_attest_key_test"
 #include <android-base/logging.h>
-#include <android-base/strings.h>
 #include <cutils/log.h>
 #include <cutils/properties.h>
 
+#include <keymint_support/authorization_set.h>
 #include <keymint_support/key_param_output.h>
 #include <keymint_support/openssl_utils.h>
 
@@ -28,72 +28,18 @@
 namespace aidl::android::hardware::security::keymint::test {
 
 namespace {
-string TELEPHONY_CMD_GET_IMEI = "cmd phone get-imei ";
 
 bool IsSelfSigned(const vector<Certificate>& chain) {
     if (chain.size() != 1) return false;
     return ChainSignaturesAreValid(chain);
 }
 
-/*
- * Run a shell command and collect the output of it. If any error, set an empty string as the
- * output.
- */
-string exec_command(string command) {
-    char buffer[128];
-    string result = "";
-
-    FILE* pipe = popen(command.c_str(), "r");
-    if (!pipe) {
-        LOG(ERROR) << "popen failed.";
-        return result;
-    }
-
-    // read till end of process:
-    while (!feof(pipe)) {
-        if (fgets(buffer, 128, pipe) != NULL) {
-            result += buffer;
-        }
-    }
-
-    pclose(pipe);
-    return result;
-}
-
-/*
- * Get IMEI using Telephony service shell command. If any error while executing the command
- * then empty string will be returned as output.
- */
-string get_imei(int slot) {
-    string cmd = TELEPHONY_CMD_GET_IMEI + std::to_string(slot);
-    string output = exec_command(cmd);
-
-    if (output.empty()) {
-        LOG(ERROR) << "Command failed. Cmd: " << cmd;
-        return "";
-    }
-
-    vector<string> out = ::android::base::Tokenize(::android::base::Trim(output), "Device IMEI:");
-
-    if (out.size() != 1) {
-        LOG(ERROR) << "Error in parsing the command output. Cmd: " << cmd;
-        return "";
-    }
-
-    string imei = ::android::base::Trim(out[0]);
-    if (imei.compare("null") == 0) {
-        LOG(WARNING) << "Failed to get IMEI from Telephony service: value is null. Cmd: " << cmd;
-        return "";
-    }
-
-    return imei;
-}
 }  // namespace
 
 class AttestKeyTest : public KeyMintAidlTestBase {
   public:
     void SetUp() override {
-        skipAttestKeyTest();
+        skipAttestKeyTestIfNeeded();
         KeyMintAidlTestBase::SetUp();
     }
 };
@@ -273,7 +219,7 @@
 /*
  * AttestKeyTest.RsaAttestedAttestKeys
  *
- * This test creates an RSA attestation key signed by factory keys, and varifies it can be
+ * This test creates an RSA attestation key signed by factory keys, and verifies it can be
  * used to sign other RSA and EC keys.
  */
 TEST_P(AttestKeyTest, RsaAttestedAttestKeys) {
@@ -305,9 +251,8 @@
                                             .SetDefaultValidity(),
                                     {} /* attestation signing key */, &attest_key.keyBlob,
                                     &attest_key_characteristics, &attest_key_cert_chain);
-    // Strongbox may not support factory provisioned attestation key.
-    if (SecLevel() == SecurityLevel::STRONGBOX) {
-        if (result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) return;
+    if (isRkpOnly() && result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) {
+        GTEST_SKIP() << "RKP-only devices do not have a factory key";
     }
     ASSERT_EQ(ErrorCode::OK, result);
     KeyBlobDeleter attest_deleter(keymint_, attest_key.keyBlob);
@@ -400,30 +345,32 @@
             attest_key_opt = attest_key;
         }
 
-        auto result = GenerateAttestKey(AuthorizationSetBuilder()
-                                                .RsaKey(2048, 65537)
-                                                .AttestKey()
-                                                .AttestationChallenge("foo")
-                                                .AttestationApplicationId("bar")
-                                                .Authorization(TAG_NO_AUTH_REQUIRED)
-                                                .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
-                                                .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
-                                                .SetDefaultValidity(),
-                                        attest_key_opt, &key_blob_list[i],
-                                        &attested_key_characteristics, &cert_chain_list[i]);
-        // Strongbox may not support factory provisioned attestation key.
-        if (SecLevel() == SecurityLevel::STRONGBOX) {
-            if (result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) return;
+        AuthorizationSetBuilder auth_set_builder =
+                AuthorizationSetBuilder()
+                        .RsaKey(2048, 65537)
+                        .AttestKey()
+                        .AttestationApplicationId("bar")
+                        .Authorization(TAG_NO_AUTH_REQUIRED)
+                        .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
+                        .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
+                        .SetDefaultValidity();
+        // In RKP-only systems, the first key cannot be attested due to lack of batch key
+        if (!isRkpOnly() || i > 0) {
+            auth_set_builder.AttestationChallenge("foo");
         }
+        auto result = GenerateAttestKey(auth_set_builder, attest_key_opt, &key_blob_list[i],
+                                        &attested_key_characteristics, &cert_chain_list[i]);
         ASSERT_EQ(ErrorCode::OK, result);
         deleters.push_back(KeyBlobDeleter(keymint_, key_blob_list[i]));
 
-        AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
-        AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
-        ASSERT_GT(cert_chain_list[i].size(), 0);
-        ASSERT_TRUE(verify_attestation_record(AidlVersion(), "foo", "bar", sw_enforced, hw_enforced,
-                                              SecLevel(),
-                                              cert_chain_list[i][0].encodedCertificate));
+        if (!isRkpOnly() || i > 0) {
+            AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
+            AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
+            ASSERT_GT(cert_chain_list[i].size(), 0);
+            ASSERT_TRUE(verify_attestation_record(AidlVersion(), "foo", "bar", sw_enforced,
+                                                  hw_enforced, SecLevel(),
+                                                  cert_chain_list[i][0].encodedCertificate));
+        }
 
         if (i > 0) {
             /*
@@ -439,7 +386,7 @@
         }
 
         EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_list[i]));
-        EXPECT_GT(cert_chain_list[i].size(), i + 1);
+        EXPECT_GT(cert_chain_list[i].size(), i + (isRkpOnly() ? 0 : 1));
         verify_subject_and_serial(cert_chain_list[i][0], serial_int, subject, false);
     }
 }
@@ -475,36 +422,34 @@
             attest_key_opt = attest_key;
         }
 
-        auto result = GenerateAttestKey(AuthorizationSetBuilder()
-                                                .EcdsaKey(EcCurve::P_256)
-                                                .AttestKey()
-                                                .AttestationChallenge("foo")
-                                                .AttestationApplicationId("bar")
-                                                .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
-                                                .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
-                                                .Authorization(TAG_NO_AUTH_REQUIRED)
-                                                .SetDefaultValidity(),
-                                        attest_key_opt, &key_blob_list[i],
-                                        &attested_key_characteristics, &cert_chain_list[i]);
-        // Strongbox may not support factory provisioned attestation key.
-        if (SecLevel() == SecurityLevel::STRONGBOX) {
-            if (result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) return;
+        AuthorizationSetBuilder auth_set_builder =
+                AuthorizationSetBuilder()
+                        .EcdsaKey(EcCurve::P_256)
+                        .AttestKey()
+                        .AttestationApplicationId("bar")
+                        .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
+                        .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
+                        .Authorization(TAG_NO_AUTH_REQUIRED)
+                        .SetDefaultValidity();
+        // In RKP-only systems, the first key cannot be attested due to lack of batch key
+        if (!isRkpOnly() || i > 0) {
+            auth_set_builder.AttestationChallenge("foo");
         }
+        auto result = GenerateAttestKey(auth_set_builder, attest_key_opt, &key_blob_list[i],
+                                        &attested_key_characteristics, &cert_chain_list[i]);
         ASSERT_EQ(ErrorCode::OK, result);
         deleters.push_back(KeyBlobDeleter(keymint_, key_blob_list[i]));
 
-        AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
-        AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
-        ASSERT_GT(cert_chain_list[i].size(), 0);
-        ASSERT_TRUE(verify_attestation_record(AidlVersion(), "foo", "bar", sw_enforced, hw_enforced,
-                                              SecLevel(),
-                                              cert_chain_list[i][0].encodedCertificate));
+        if (!isRkpOnly() || i > 0) {
+            AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
+            AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
+            ASSERT_GT(cert_chain_list[i].size(), 0);
+            ASSERT_TRUE(verify_attestation_record(AidlVersion(), "foo", "bar", sw_enforced,
+                                                  hw_enforced, SecLevel(),
+                                                  cert_chain_list[i][0].encodedCertificate));
+        }
 
         if (i > 0) {
-            /*
-             * The first key is attestated with factory chain, but all the rest of the keys are
-             * not supposed to be returned in attestation certificate chains.
-             */
             EXPECT_FALSE(ChainSignaturesAreValid(cert_chain_list[i]));
 
             // Appending the attest_key chain to the attested_key_chain should yield a valid chain.
@@ -514,7 +459,7 @@
         }
 
         EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_list[i]));
-        EXPECT_GT(cert_chain_list[i].size(), i + 1);
+        EXPECT_GT(cert_chain_list[i].size(), i + (isRkpOnly() ? 0 : 1));
         verify_subject_and_serial(cert_chain_list[i][0], serial_int, subject, false);
     }
 }
@@ -576,45 +521,36 @@
             attest_key.keyBlob = key_blob_list[i - 1];
             attest_key_opt = attest_key;
         }
-        ErrorCode result;
+        AuthorizationSetBuilder auth_set_builder =
+                AuthorizationSetBuilder()
+                        .AttestKey()
+                        .AttestationApplicationId("bar")
+                        .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
+                        .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
+                        .Authorization(TAG_NO_AUTH_REQUIRED)
+                        .SetDefaultValidity();
+        // In RKP-only systems, the first key cannot be attested due to lack of batch key
+        if (!isRkpOnly() || i > 0) {
+            auth_set_builder.AttestationChallenge("foo");
+        }
         if ((i & 0x1) == 1) {
-            result = GenerateAttestKey(AuthorizationSetBuilder()
-                                               .EcdsaKey(EcCurve::P_256)
-                                               .AttestKey()
-                                               .AttestationChallenge("foo")
-                                               .AttestationApplicationId("bar")
-                                               .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
-                                               .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
-                                               .Authorization(TAG_NO_AUTH_REQUIRED)
-                                               .SetDefaultValidity(),
-                                       attest_key_opt, &key_blob_list[i],
-                                       &attested_key_characteristics, &cert_chain_list[i]);
+            auth_set_builder.EcdsaKey(EcCurve::P_256);
         } else {
-            result = GenerateAttestKey(AuthorizationSetBuilder()
-                                               .RsaKey(2048, 65537)
-                                               .AttestKey()
-                                               .AttestationChallenge("foo")
-                                               .AttestationApplicationId("bar")
-                                               .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
-                                               .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
-                                               .Authorization(TAG_NO_AUTH_REQUIRED)
-                                               .SetDefaultValidity(),
-                                       attest_key_opt, &key_blob_list[i],
-                                       &attested_key_characteristics, &cert_chain_list[i]);
+            auth_set_builder.RsaKey(2048, 65537);
         }
-        // Strongbox may not support factory provisioned attestation key.
-        if (SecLevel() == SecurityLevel::STRONGBOX) {
-            if (result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) return;
-        }
+        ErrorCode result = GenerateAttestKey(auth_set_builder, attest_key_opt, &key_blob_list[i],
+                                             &attested_key_characteristics, &cert_chain_list[i]);
         ASSERT_EQ(ErrorCode::OK, result);
         deleters.push_back(KeyBlobDeleter(keymint_, key_blob_list[i]));
 
-        AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
-        AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
-        ASSERT_GT(cert_chain_list[i].size(), 0);
-        ASSERT_TRUE(verify_attestation_record(AidlVersion(), "foo", "bar", sw_enforced, hw_enforced,
-                                              SecLevel(),
-                                              cert_chain_list[i][0].encodedCertificate));
+        if (!isRkpOnly() || i > 0) {
+            AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
+            AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
+            ASSERT_GT(cert_chain_list[i].size(), 0);
+            ASSERT_TRUE(verify_attestation_record(AidlVersion(), "foo", "bar", sw_enforced,
+                                                  hw_enforced, SecLevel(),
+                                                  cert_chain_list[i][0].encodedCertificate));
+        }
 
         if (i > 0) {
             /*
@@ -630,7 +566,7 @@
         }
 
         EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_list[i]));
-        EXPECT_GT(cert_chain_list[i].size(), i + 1);
+        EXPECT_GT(cert_chain_list[i].size(), i + (isRkpOnly() ? 0 : 1));
         verify_subject_and_serial(cert_chain_list[i][0], serial_int, subject, false);
     }
 }
diff --git a/security/keymint/aidl/vts/functional/AuthTest.cpp b/security/keymint/aidl/vts/functional/AuthTest.cpp
index eb5db68..f435513 100644
--- a/security/keymint/aidl/vts/functional/AuthTest.cpp
+++ b/security/keymint/aidl/vts/functional/AuthTest.cpp
@@ -455,18 +455,7 @@
                            .Authorization(TAG_AUTH_TIMEOUT, timeout_secs);
     vector<uint8_t> keyblob;
     vector<KeyCharacteristics> key_characteristics;
-    vector<Certificate> cert_chain;
-    auto result = GenerateKey(builder, std::nullopt, &keyblob, &key_characteristics, &cert_chain);
-    if (SecLevel() == SecurityLevel::STRONGBOX) {
-        if (result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) {
-            result = GenerateKeyWithSelfSignedAttestKey(AuthorizationSetBuilder()
-                                                                .EcdsaKey(EcCurve::P_256)
-                                                                .AttestKey()
-                                                                .SetDefaultValidity(),
-                                                        builder, &keyblob, &key_characteristics,
-                                                        &cert_chain);
-        }
-    }
+    auto result = GenerateKey(builder, &keyblob, &key_characteristics);
     ASSERT_EQ(ErrorCode::OK, result);
 
     // Verify first user to get a HAT that should work.
diff --git a/security/keymint/aidl/vts/functional/BootloaderStateTest.cpp b/security/keymint/aidl/vts/functional/BootloaderStateTest.cpp
index 808ed18..c1f6aee 100644
--- a/security/keymint/aidl/vts/functional/BootloaderStateTest.cpp
+++ b/security/keymint/aidl/vts/functional/BootloaderStateTest.cpp
@@ -54,18 +54,6 @@
                                            .Digest(Digest::NONE)
                                            .SetDefaultValidity();
         auto result = GenerateKey(keyDesc, &key_blob, &key_characteristics);
-        // If factory provisioned attestation key is not supported by Strongbox,
-        // then create a key with self-signed attestation and use it as the
-        // attestation key instead.
-        if (SecLevel() == SecurityLevel::STRONGBOX &&
-            result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) {
-            result = GenerateKeyWithSelfSignedAttestKey(
-                    AuthorizationSetBuilder()
-                            .EcdsaKey(EcCurve::P_256)
-                            .AttestKey()
-                            .SetDefaultValidity(), /* attest key params */
-                    keyDesc, &key_blob, &key_characteristics);
-        }
         ASSERT_EQ(ErrorCode::OK, result);
 
         // Parse attested AVB values.
diff --git a/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp b/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp
index 8e9aded..f669110 100644
--- a/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp
+++ b/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp
@@ -73,20 +73,22 @@
     vector<KeyCharacteristics> key_characteristics;
 
     // Check RSA implementation
-    auto result = GenerateKey(AuthorizationSetBuilder()
-                                      .Authorization(TAG_NO_AUTH_REQUIRED)
-                                      .RsaSigningKey(2048, 65537)
-                                      .Digest(Digest::SHA_2_256)
-                                      .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)
-                                      .Authorization(TAG_INCLUDE_UNIQUE_ID)
-                                      .Authorization(TAG_CREATION_DATETIME, 1619621648000)
-                                      .SetDefaultValidity()
-                                      .AttestationChallenge("challenge")
-                                      .AttestationApplicationId("foo")
-                                      .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION),
-                              &key_blob, &key_characteristics);
+    auto result =
+            GenerateKey(AuthorizationSetBuilder()
+                                .Authorization(TAG_NO_AUTH_REQUIRED)
+                                .RsaSigningKey(2048, 65537)
+                                .Digest(Digest::SHA_2_256)
+                                .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)
+                                .Authorization(TAG_INCLUDE_UNIQUE_ID)
+                                .Authorization(TAG_CREATION_DATETIME, 1619621648000)
+                                .SetDefaultValidity()
+                                .AttestationChallenge("challenge")
+                                .AttestationApplicationId("foo")
+                                .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION),
+                        /*attest_key=*/std::nullopt, &key_blob, &key_characteristics, &cert_chain_);
 
-    ASSERT_TRUE(result == ErrorCode::INVALID_ARGUMENT || result == ErrorCode::UNSUPPORTED_TAG);
+    ASSERT_TRUE(result == ErrorCode::INVALID_ARGUMENT || result == ErrorCode::UNSUPPORTED_TAG)
+            << "Result: " << result;
 }
 
 /*
@@ -104,19 +106,21 @@
     vector<KeyCharacteristics> key_characteristics;
 
     // Check Ecdsa implementation
-    auto result = GenerateKey(AuthorizationSetBuilder()
-                                      .Authorization(TAG_NO_AUTH_REQUIRED)
-                                      .EcdsaSigningKey(EcCurve::P_256)
-                                      .Digest(Digest::SHA_2_256)
-                                      .Authorization(TAG_INCLUDE_UNIQUE_ID)
-                                      .Authorization(TAG_CREATION_DATETIME, 1619621648000)
-                                      .SetDefaultValidity()
-                                      .AttestationChallenge("challenge")
-                                      .AttestationApplicationId("foo")
-                                      .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION),
-                              &key_blob, &key_characteristics);
+    auto result =
+            GenerateKey(AuthorizationSetBuilder()
+                                .Authorization(TAG_NO_AUTH_REQUIRED)
+                                .EcdsaSigningKey(EcCurve::P_256)
+                                .Digest(Digest::SHA_2_256)
+                                .Authorization(TAG_INCLUDE_UNIQUE_ID)
+                                .Authorization(TAG_CREATION_DATETIME, 1619621648000)
+                                .SetDefaultValidity()
+                                .AttestationChallenge("challenge")
+                                .AttestationApplicationId("foo")
+                                .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION),
+                        /*attest_key=*/std::nullopt, &key_blob, &key_characteristics, &cert_chain_);
 
-    ASSERT_TRUE(result == ErrorCode::INVALID_ARGUMENT || result == ErrorCode::UNSUPPORTED_TAG);
+    ASSERT_TRUE(result == ErrorCode::INVALID_ARGUMENT || result == ErrorCode::UNSUPPORTED_TAG)
+            << "Result: " << result;
 }
 
 /*
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index 087f763..cef8120 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -20,8 +20,13 @@
 #include <fstream>
 #include <unordered_set>
 #include <vector>
+#include "aidl/android/hardware/security/keymint/AttestationKey.h"
+#include "aidl/android/hardware/security/keymint/ErrorCode.h"
+#include "keymint_support/authorization_set.h"
+#include "keymint_support/keymint_tags.h"
 
 #include <android-base/logging.h>
+#include <android-base/strings.h>
 #include <android/binder_manager.h>
 #include <android/content/pm/IPackageManagerNative.h>
 #include <cppbor_parse.h>
@@ -245,6 +250,13 @@
     return AidlVersion() >= 3 && property_get_int32("ro.vendor.api_level", 0) > __ANDROID_API_T__;
 }
 
+bool KeyMintAidlTestBase::isRkpOnly() {
+    if (SecLevel() == SecurityLevel::STRONGBOX) {
+        return property_get_bool("remote_provisioning.strongbox.rkp_only", false);
+    }
+    return property_get_bool("remote_provisioning.tee.rkp_only", false);
+}
+
 bool KeyMintAidlTestBase::Curve25519Supported() {
     // Strongbox never supports curve 25519.
     if (SecLevel() == SecurityLevel::STRONGBOX) {
@@ -295,6 +307,40 @@
     }
 }
 
+ErrorCode KeyMintAidlTestBase::GenerateKey(const AuthorizationSet& key_desc) {
+    return GenerateKey(key_desc, &key_blob_, &key_characteristics_);
+}
+
+ErrorCode KeyMintAidlTestBase::GenerateKey(const AuthorizationSet& key_desc,
+                                           vector<uint8_t>* key_blob,
+                                           vector<KeyCharacteristics>* key_characteristics) {
+    std::optional<AttestationKey> attest_key = std::nullopt;
+    vector<Certificate> attest_cert_chain;
+    // If an attestation is requested, but the system is RKP-only, we need to supply an explicit
+    // attestation key. Else the result is a key without an attestation.
+    if (isRkpOnly() && key_desc.Contains(TAG_ATTESTATION_CHALLENGE)) {
+        skipAttestKeyTestIfNeeded();
+        AuthorizationSet attest_key_desc =
+                AuthorizationSetBuilder().EcdsaKey(EcCurve::P_256).AttestKey().SetDefaultValidity();
+        attest_key.emplace();
+        vector<KeyCharacteristics> attest_key_characteristics;
+        auto error = GenerateAttestKey(attest_key_desc, std::nullopt, &attest_key.value().keyBlob,
+                                       &attest_key_characteristics, &attest_cert_chain);
+        EXPECT_EQ(error, ErrorCode::OK);
+        EXPECT_EQ(attest_cert_chain.size(), 1);
+        attest_key.value().issuerSubjectName = make_name_from_str("Android Keystore Key");
+    }
+
+    ErrorCode error =
+            GenerateKey(key_desc, attest_key, key_blob, key_characteristics, &cert_chain_);
+
+    if (error == ErrorCode::OK && attest_cert_chain.size() > 0) {
+        cert_chain_.push_back(attest_cert_chain[0]);
+    }
+
+    return error;
+}
+
 ErrorCode KeyMintAidlTestBase::GenerateKey(const AuthorizationSet& key_desc,
                                            const optional<AttestationKey>& attest_key,
                                            vector<uint8_t>* key_blob,
@@ -335,36 +381,6 @@
     return GetReturnErrorCode(result);
 }
 
-ErrorCode KeyMintAidlTestBase::GenerateKey(const AuthorizationSet& key_desc,
-                                           const optional<AttestationKey>& attest_key) {
-    return GenerateKey(key_desc, attest_key, &key_blob_, &key_characteristics_, &cert_chain_);
-}
-
-ErrorCode KeyMintAidlTestBase::GenerateKeyWithSelfSignedAttestKey(
-        const AuthorizationSet& attest_key_desc, const AuthorizationSet& key_desc,
-        vector<uint8_t>* key_blob, vector<KeyCharacteristics>* key_characteristics,
-        vector<Certificate>* cert_chain) {
-    skipAttestKeyTest();
-    AttestationKey attest_key;
-    vector<Certificate> attest_cert_chain;
-    vector<KeyCharacteristics> attest_key_characteristics;
-    // Generate a key with self signed attestation.
-    auto error = GenerateAttestKey(attest_key_desc, std::nullopt, &attest_key.keyBlob,
-                                   &attest_key_characteristics, &attest_cert_chain);
-    if (error != ErrorCode::OK) {
-        return error;
-    }
-
-    attest_key.issuerSubjectName = make_name_from_str("Android Keystore Key");
-    // Generate a key, by passing the above self signed attestation key as attest key.
-    error = GenerateKey(key_desc, attest_key, key_blob, key_characteristics, cert_chain);
-    if (error == ErrorCode::OK) {
-        // Append the attest_cert_chain to the attested cert_chain to yield a valid cert chain.
-        cert_chain->push_back(attest_cert_chain[0]);
-    }
-    return error;
-}
-
 ErrorCode KeyMintAidlTestBase::ImportKey(const AuthorizationSet& key_desc, KeyFormat format,
                                          const string& key_material, vector<uint8_t>* key_blob,
                                          vector<KeyCharacteristics>* key_characteristics) {
@@ -1573,7 +1589,7 @@
     // with any other key purpose, but the original VTS tests incorrectly did exactly that.
     // This means that a device that launched prior to Android T (API level 33) may
     // accept or even require KeyPurpose::SIGN too.
-    if (property_get_int32("ro.board.first_api_level", 0) < __ANDROID_API_T__) {
+    if (get_vsr_api_level() < __ANDROID_API_T__) {
         AuthorizationSet key_desc_plus_sign = key_desc;
         key_desc_plus_sign.push_back(TAG_PURPOSE, KeyPurpose::SIGN);
 
@@ -1663,7 +1679,7 @@
 
 // Skip a test that involves use of the ATTEST_KEY feature in specific configurations
 // where ATTEST_KEY is not supported (for either StrongBox or TEE).
-void KeyMintAidlTestBase::skipAttestKeyTest(void) const {
+void KeyMintAidlTestBase::skipAttestKeyTestIfNeeded() const {
     if (shouldSkipAttestKeyTest()) {
         GTEST_SKIP() << "Test using ATTEST_KEY is not applicable on waivered device";
     }
@@ -2024,7 +2040,7 @@
         }
     }
 
-    if (KeyMintAidlTestBase::dump_Attestations) std::cout << cert_data.str();
+    if (KeyMintAidlTestBase::dump_Attestations) std::cout << "cert chain:\n" << cert_data.str();
     return AssertionSuccess();
 }
 
@@ -2322,6 +2338,67 @@
     return result;
 }
 
+namespace {
+
+std::string TELEPHONY_CMD_GET_IMEI = "cmd phone get-imei ";
+
+/*
+ * Run a shell command and collect the output of it. If any error, set an empty string as the
+ * output.
+ */
+std::string exec_command(const std::string& command) {
+    char buffer[128];
+    std::string result = "";
+
+    FILE* pipe = popen(command.c_str(), "r");
+    if (!pipe) {
+        LOG(ERROR) << "popen failed.";
+        return result;
+    }
+
+    // read till end of process:
+    while (!feof(pipe)) {
+        if (fgets(buffer, 128, pipe) != NULL) {
+            result += buffer;
+        }
+    }
+
+    pclose(pipe);
+    return result;
+}
+
+}  // namespace
+
+/*
+ * Get IMEI using Telephony service shell command. If any error while executing the command
+ * then empty string will be returned as output.
+ */
+std::string get_imei(int slot) {
+    std::string cmd = TELEPHONY_CMD_GET_IMEI + std::to_string(slot);
+    std::string output = exec_command(cmd);
+
+    if (output.empty()) {
+        LOG(ERROR) << "Command failed. Cmd: " << cmd;
+        return "";
+    }
+
+    vector<std::string> out =
+            ::android::base::Tokenize(::android::base::Trim(output), "Device IMEI:");
+
+    if (out.size() != 1) {
+        LOG(ERROR) << "Error in parsing the command output. Cmd: " << cmd;
+        return "";
+    }
+
+    std::string imei = ::android::base::Trim(out[0]);
+    if (imei.compare("null") == 0) {
+        LOG(WARNING) << "Failed to get IMEI from Telephony service: value is null. Cmd: " << cmd;
+        return "";
+    }
+
+    return imei;
+}
+
 }  // namespace test
 
 }  // namespace aidl::android::hardware::security::keymint
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
index 4ed7698..1bf2d9d 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
@@ -104,35 +104,19 @@
     uint32_t boot_patch_level();
     bool isDeviceIdAttestationRequired();
     bool isSecondImeiIdAttestationRequired();
+    bool isRkpOnly();
 
     bool Curve25519Supported();
 
+    ErrorCode GenerateKey(const AuthorizationSet& key_desc);
+
     ErrorCode GenerateKey(const AuthorizationSet& key_desc, vector<uint8_t>* key_blob,
-                          vector<KeyCharacteristics>* key_characteristics) {
-        return GenerateKey(key_desc, std::nullopt /* attest_key */, key_blob, key_characteristics,
-                           &cert_chain_);
-    }
+                          vector<KeyCharacteristics>* key_characteristics);
+
     ErrorCode GenerateKey(const AuthorizationSet& key_desc,
                           const optional<AttestationKey>& attest_key, vector<uint8_t>* key_blob,
                           vector<KeyCharacteristics>* key_characteristics,
                           vector<Certificate>* cert_chain);
-    ErrorCode GenerateKey(const AuthorizationSet& key_desc,
-                          const optional<AttestationKey>& attest_key = std::nullopt);
-
-    // Generate key for implementations which do not support factory attestation.
-    ErrorCode GenerateKeyWithSelfSignedAttestKey(const AuthorizationSet& attest_key_desc,
-                                                 const AuthorizationSet& key_desc,
-                                                 vector<uint8_t>* key_blob,
-                                                 vector<KeyCharacteristics>* key_characteristics,
-                                                 vector<Certificate>* cert_chain);
-
-    ErrorCode GenerateKeyWithSelfSignedAttestKey(const AuthorizationSet& attest_key_desc,
-                                                 const AuthorizationSet& key_desc,
-                                                 vector<uint8_t>* key_blob,
-                                                 vector<KeyCharacteristics>* key_characteristics) {
-        return GenerateKeyWithSelfSignedAttestKey(attest_key_desc, key_desc, key_blob,
-                                                  key_characteristics, &cert_chain_);
-    }
 
     ErrorCode ImportKey(const AuthorizationSet& key_desc, KeyFormat format,
                         const string& key_material, vector<uint8_t>* key_blob,
@@ -372,7 +356,7 @@
     bool is_strongbox_enabled(void) const;
     bool is_chipset_allowed_km4_strongbox(void) const;
     bool shouldSkipAttestKeyTest(void) const;
-    void skipAttestKeyTest(void) const;
+    void skipAttestKeyTestIfNeeded() const;
 
     void assert_mgf_digests_present_or_not_in_key_characteristics(
             const vector<KeyCharacteristics>& key_characteristics,
@@ -446,6 +430,7 @@
 void device_id_attestation_check_acceptable_error(Tag tag, const ErrorCode& result);
 bool check_feature(const std::string& name);
 std::optional<int32_t> keymint_feature_value(bool strongbox);
+std::string get_imei(int slot);
 
 AuthorizationSet HwEnforcedAuthorizations(const vector<KeyCharacteristics>& key_characteristics);
 AuthorizationSet SwEnforcedAuthorizations(const vector<KeyCharacteristics>& key_characteristics);
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index 9575183..3c49a82 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -22,6 +22,7 @@
 #include <algorithm>
 #include <iostream>
 #include <map>
+#include <set>
 
 #include <openssl/curve25519.h>
 #include <openssl/ec.h>
@@ -37,6 +38,7 @@
 #include <aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.h>
 #include <aidl/android/hardware/security/keymint/KeyFormat.h>
 
+#include <keymint_support/authorization_set.h>
 #include <keymint_support/key_param_output.h>
 #include <keymint_support/openssl_utils.h>
 
@@ -1146,17 +1148,6 @@
                                .SetDefaultValidity();
 
         auto result = GenerateKey(builder, &key_blob, &key_characteristics);
-        // Strongbox may not support factory provisioned attestation key.
-        if (SecLevel() == SecurityLevel::STRONGBOX) {
-            if (result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) {
-                result = GenerateKeyWithSelfSignedAttestKey(
-                        AuthorizationSetBuilder()
-                                .RsaKey(key_size, 65537)
-                                .AttestKey()
-                                .SetDefaultValidity(), /* attest key params */
-                        builder, &key_blob, &key_characteristics);
-            }
-        }
         ASSERT_EQ(ErrorCode::OK, result);
         KeyBlobDeleter deleter(keymint_, key_blob);
         ASSERT_GT(key_blob.size(), 0U);
@@ -1369,17 +1360,6 @@
                            .SetDefaultValidity();
 
     auto result = GenerateKey(builder, &key_blob, &key_characteristics);
-    // Strongbox may not support factory provisioned attestation key.
-    if (SecLevel() == SecurityLevel::STRONGBOX) {
-        if (result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) {
-            result = GenerateKeyWithSelfSignedAttestKey(
-                    AuthorizationSetBuilder()
-                            .RsaKey(key_size, 65537)
-                            .AttestKey()
-                            .SetDefaultValidity(), /* attest key params */
-                    builder, &key_blob, &key_characteristics);
-        }
-    }
     ASSERT_EQ(ErrorCode::OK, result);
     KeyBlobDeleter deleter(keymint_, key_blob);
 
@@ -1490,17 +1470,6 @@
                            .SetDefaultValidity();
 
     auto result = GenerateKey(builder, &key_blob, &key_characteristics);
-    // Strongbox may not support factory provisioned attestation key.
-    if (SecLevel() == SecurityLevel::STRONGBOX) {
-        if (result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) {
-            result = GenerateKeyWithSelfSignedAttestKey(
-                    AuthorizationSetBuilder()
-                            .RsaKey(2048, 65537)
-                            .AttestKey()
-                            .SetDefaultValidity(), /* attest key params */
-                    builder, &key_blob, &key_characteristics);
-        }
-    }
     ASSERT_EQ(ErrorCode::ATTESTATION_APPLICATION_ID_MISSING, result);
 }
 
@@ -1625,17 +1594,6 @@
                                .SetDefaultValidity();
 
         auto result = GenerateKey(builder, &key_blob, &key_characteristics);
-        // Strongbox may not support factory provisioned attestation key.
-        if (SecLevel() == SecurityLevel::STRONGBOX) {
-            if (result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) {
-                result = GenerateKeyWithSelfSignedAttestKey(
-                        AuthorizationSetBuilder()
-                                .RsaKey(key_size, 65537)
-                                .AttestKey()
-                                .SetDefaultValidity(), /* attest key params */
-                        builder, &key_blob, &key_characteristics);
-            }
-        }
         ASSERT_EQ(ErrorCode::OK, result);
         KeyBlobDeleter deleter(keymint_, key_blob);
 
@@ -1877,17 +1835,6 @@
                                .SetDefaultValidity();
 
         auto result = GenerateKey(builder, &key_blob, &key_characteristics);
-        // Strongbox may not support factory provisioned attestation key.
-        if (SecLevel() == SecurityLevel::STRONGBOX) {
-            if (result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) {
-                result = GenerateKeyWithSelfSignedAttestKey(
-                        AuthorizationSetBuilder()
-                                .EcdsaKey(curve)
-                                .AttestKey()
-                                .SetDefaultValidity(), /* attest key params */
-                        builder, &key_blob, &key_characteristics);
-            }
-        }
         ASSERT_EQ(ErrorCode::OK, result);
         KeyBlobDeleter deleter(keymint_, key_blob);
         ASSERT_GT(key_blob.size(), 0U);
@@ -2020,17 +1967,6 @@
             // Tag not required to be supported by all KeyMint implementations.
             continue;
         }
-        // Strongbox may not support factory provisioned attestation key.
-        if (SecLevel() == SecurityLevel::STRONGBOX) {
-            if (result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) {
-                result = GenerateKeyWithSelfSignedAttestKey(
-                        AuthorizationSetBuilder()
-                                .EcdsaKey(EcCurve::P_256)
-                                .AttestKey()
-                                .SetDefaultValidity(), /* attest key params */
-                        builder, &key_blob, &key_characteristics);
-            }
-        }
         ASSERT_EQ(result, ErrorCode::OK);
         KeyBlobDeleter deleter(keymint_, key_blob);
         ASSERT_GT(key_blob.size(), 0U);
@@ -2082,18 +2018,6 @@
         builder.push_back(tag);
 
         auto error = GenerateKey(builder, &key_blob, &key_characteristics);
-        // Strongbox may not support factory provisioned attestation key.
-        if (SecLevel() == SecurityLevel::STRONGBOX) {
-            if (error == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) {
-                error = GenerateKeyWithSelfSignedAttestKey(
-                        AuthorizationSetBuilder()
-                                .EcdsaKey(EcCurve::P_256)
-                                .AttestKey()
-                                .SetDefaultValidity(), /* attest key params */
-                        builder, &key_blob, &key_characteristics);
-            }
-        }
-
         device_id_attestation_check_acceptable_error(tag.tag, error);
     }
 }
@@ -2102,7 +2026,7 @@
  * NewKeyGenerationTest.EcdsaAttestationIdTags
  *
  * Verifies that creation of an attested ECDSA key includes various ID tags in the
- * attestation extension.
+ * attestation extension one by one.
  */
 TEST_P(NewKeyGenerationTest, EcdsaAttestationIdTags) {
     auto challenge = "hello";
@@ -2130,6 +2054,15 @@
     add_attestation_id(&extra_tags, TAG_ATTESTATION_ID_MANUFACTURER, "manufacturer");
     add_attestation_id(&extra_tags, TAG_ATTESTATION_ID_MODEL, "model");
     add_tag_from_prop(&extra_tags, TAG_ATTESTATION_ID_SERIAL, "ro.serialno");
+    string imei = get_imei(0);
+    if (!imei.empty()) {
+        extra_tags.Authorization(TAG_ATTESTATION_ID_IMEI, imei.data(), imei.size());
+    }
+    string second_imei = get_imei(1);
+    if (!second_imei.empty()) {
+        extra_tags.Authorization(TAG_ATTESTATION_ID_SECOND_IMEI, second_imei.data(),
+                                 second_imei.size());
+    }
 
     for (const KeyParameter& tag : extra_tags) {
         SCOPED_TRACE(testing::Message() << "tag-" << tag);
@@ -2138,10 +2071,6 @@
         AuthorizationSetBuilder builder = base_builder;
         builder.push_back(tag);
         auto result = GenerateKey(builder, &key_blob, &key_characteristics);
-        // Strongbox may not support factory provisioned attestation key.
-        if (SecLevel() == SecurityLevel::STRONGBOX) {
-            if (result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) return;
-        }
         if (result == ErrorCode::CANNOT_ATTEST_IDS && !isDeviceIdAttestationRequired()) {
             // ID attestation was optional till api level 32, from api level 33 it is mandatory.
             continue;
@@ -2171,6 +2100,83 @@
 }
 
 /*
+ * NewKeyGenerationTest.EcdsaAttestationIdAllTags
+ *
+ * Verifies that creation of an attested ECDSA key includes various ID tags in the
+ * attestation extension all together.
+ */
+TEST_P(NewKeyGenerationTest, EcdsaAttestationIdAllTags) {
+    auto challenge = "hello";
+    auto app_id = "foo";
+    auto subject = "cert subj 2";
+    vector<uint8_t> subject_der(make_name_from_str(subject));
+    uint64_t serial_int = 0x1010;
+    vector<uint8_t> serial_blob(build_serial_blob(serial_int));
+    AuthorizationSetBuilder builder = AuthorizationSetBuilder()
+                                              .Authorization(TAG_NO_AUTH_REQUIRED)
+                                              .EcdsaSigningKey(EcCurve::P_256)
+                                              .Digest(Digest::NONE)
+                                              .AttestationChallenge(challenge)
+                                              .AttestationApplicationId(app_id)
+                                              .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
+                                              .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
+                                              .SetDefaultValidity();
+
+    // Various ATTESTATION_ID_* tags that map to fields in the attestation extension ASN.1 schema.
+    auto extra_tags = AuthorizationSetBuilder();
+    add_attestation_id(&extra_tags, TAG_ATTESTATION_ID_BRAND, "brand");
+    add_attestation_id(&extra_tags, TAG_ATTESTATION_ID_DEVICE, "device");
+    add_attestation_id(&extra_tags, TAG_ATTESTATION_ID_PRODUCT, "name");
+    add_attestation_id(&extra_tags, TAG_ATTESTATION_ID_MANUFACTURER, "manufacturer");
+    add_attestation_id(&extra_tags, TAG_ATTESTATION_ID_MODEL, "model");
+    add_tag_from_prop(&extra_tags, TAG_ATTESTATION_ID_SERIAL, "ro.serialno");
+    string imei = get_imei(0);
+    if (!imei.empty()) {
+        extra_tags.Authorization(TAG_ATTESTATION_ID_IMEI, imei.data(), imei.size());
+    }
+    string second_imei = get_imei(1);
+    if (!second_imei.empty()) {
+        extra_tags.Authorization(TAG_ATTESTATION_ID_SECOND_IMEI, second_imei.data(),
+                                 second_imei.size());
+    }
+    for (const KeyParameter& tag : extra_tags) {
+        builder.push_back(tag);
+    }
+
+    vector<uint8_t> key_blob;
+    vector<KeyCharacteristics> key_characteristics;
+    auto result = GenerateKey(builder, &key_blob, &key_characteristics);
+    if (result == ErrorCode::CANNOT_ATTEST_IDS && !isDeviceIdAttestationRequired()) {
+        // ID attestation was optional till api level 32, from api level 33 it is mandatory.
+        return;
+    }
+    ASSERT_EQ(result, ErrorCode::OK);
+    KeyBlobDeleter deleter(keymint_, key_blob);
+    ASSERT_GT(key_blob.size(), 0U);
+
+    EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
+    ASSERT_GT(cert_chain_.size(), 0);
+    verify_subject_and_serial(cert_chain_[0], serial_int, subject, /* self_signed = */ false);
+
+    AuthorizationSet hw_enforced = HwEnforcedAuthorizations(key_characteristics);
+    AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics);
+
+    // The attested key characteristics will not contain APPLICATION_ID_* fields (their
+    // spec definitions all have "Must never appear in KeyCharacteristics"), but the
+    // attestation extension should contain them, so make sure the extra tags are added.
+    for (const KeyParameter& tag : extra_tags) {
+        hw_enforced.push_back(tag);
+    }
+
+    // Verifying the attestation record will check for the specific tag because
+    // it's included in the authorizations.
+    EXPECT_TRUE(verify_attestation_record(AidlVersion(), challenge, app_id, sw_enforced,
+                                          hw_enforced, SecLevel(),
+                                          cert_chain_[0].encodedCertificate))
+            << "failed to verify " << bin2hex(cert_chain_[0].encodedCertificate);
+}
+
+/*
  * NewKeyGenerationTest.EcdsaAttestationUniqueId
  *
  * Verifies that creation of an attested ECDSA key with a UNIQUE_ID included.
@@ -2199,16 +2205,6 @@
             builder.Authorization(TAG_RESET_SINCE_ID_ROTATION);
         }
         auto result = GenerateKey(builder);
-        if (SecLevel() == SecurityLevel::STRONGBOX) {
-            if (result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) {
-                result = GenerateKeyWithSelfSignedAttestKey(
-                        AuthorizationSetBuilder()
-                                .EcdsaKey(EcCurve::P_256)
-                                .AttestKey()
-                                .SetDefaultValidity(), /* attest key params */
-                        builder, &key_blob_, &key_characteristics_, &cert_chain_);
-            }
-        }
         ASSERT_EQ(ErrorCode::OK, result);
         ASSERT_GT(key_blob_.size(), 0U);
 
@@ -2309,17 +2305,6 @@
                            .SetDefaultValidity();
 
     auto result = GenerateKey(builder, &key_blob, &key_characteristics);
-    // Strongbox may not support factory provisioned attestation key.
-    if (SecLevel() == SecurityLevel::STRONGBOX) {
-        if (result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) {
-            result = GenerateKeyWithSelfSignedAttestKey(
-                    AuthorizationSetBuilder()
-                            .EcdsaKey(EcCurve::P_256)
-                            .AttestKey()
-                            .SetDefaultValidity(), /* attest key params */
-                    builder, &key_blob, &key_characteristics);
-        }
-    }
     ASSERT_EQ(result, ErrorCode::OK);
     KeyBlobDeleter deleter(keymint_, key_blob);
     ASSERT_GT(key_blob.size(), 0U);
@@ -2404,17 +2389,6 @@
                            .SetDefaultValidity();
 
     auto result = GenerateKey(builder, &key_blob, &key_characteristics);
-    // Strongbox may not support factory provisioned attestation key.
-    if (SecLevel() == SecurityLevel::STRONGBOX) {
-        if (result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) {
-            result = GenerateKeyWithSelfSignedAttestKey(
-                    AuthorizationSetBuilder()
-                            .EcdsaKey(EcCurve::P_256)
-                            .AttestKey()
-                            .SetDefaultValidity(), /* attest key params */
-                    builder, &key_blob, &key_characteristics);
-        }
-    }
     ASSERT_EQ(ErrorCode::ATTESTATION_APPLICATION_ID_MISSING, result);
 }
 
@@ -2482,17 +2456,6 @@
                                .SetDefaultValidity();
 
         auto result = GenerateKey(builder, &key_blob, &key_characteristics);
-        // Strongbox may not support factory provisioned attestation key.
-        if (SecLevel() == SecurityLevel::STRONGBOX) {
-            if (result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) {
-                result = GenerateKeyWithSelfSignedAttestKey(
-                        AuthorizationSetBuilder()
-                                .EcdsaKey(EcCurve::P_256)
-                                .AttestKey()
-                                .SetDefaultValidity(), /* attest key params */
-                        builder, &key_blob, &key_characteristics);
-            }
-        }
         ASSERT_EQ(ErrorCode::OK, result);
         KeyBlobDeleter deleter(keymint_, key_blob);
         ASSERT_GT(key_blob.size(), 0U);
@@ -2718,7 +2681,8 @@
                                                      .AttestationChallenge(challenge)
                                                      .AttestationApplicationId(app_id)
                                                      .Authorization(TAG_MIN_MAC_LENGTH, 128),
-                                             &key_blob, &key_characteristics));
+                                             /*attest_key=*/std::nullopt, &key_blob,
+                                             &key_characteristics, &cert_chain_));
         KeyBlobDeleter deleter(keymint_, key_blob);
 
         ASSERT_GT(key_blob.size(), 0U);
@@ -2907,7 +2871,9 @@
                                                  .EcbMode()
                                                  .Padding(PaddingMode::PKCS7)
                                                  .AttestationChallenge(challenge)
-                                                 .AttestationApplicationId(app_id)));
+                                                 .AttestationApplicationId(app_id),
+                                         /*attest_key=*/std::nullopt, &key_blob_,
+                                         &key_characteristics_, &cert_chain_));
 
     ASSERT_EQ(cert_chain_.size(), 0);
 }
@@ -2928,7 +2894,9 @@
                                                  .Authorization(TAG_NO_AUTH_REQUIRED)
                                                  .Padding(PaddingMode::NONE)
                                                  .AttestationChallenge(challenge)
-                                                 .AttestationApplicationId(app_id)));
+                                                 .AttestationApplicationId(app_id),
+                                         /*attest_key=*/std::nullopt, &key_blob_,
+                                         &key_characteristics_, &cert_chain_));
     ASSERT_EQ(cert_chain_.size(), 0);
 }
 
@@ -3707,6 +3675,42 @@
 }
 
 /*
+ * SigningOperationsTest.HmacMessageDigestUnique
+ *
+ * Verifies that HMAC with different keys gives different results.
+ */
+TEST_P(SigningOperationsTest, HmacMessageDigestUnique) {
+    for (int key_len : {64, 128, 192, 256, 512}) {
+        for (int msg_len = 0; msg_len <= 30; msg_len += 10) {
+            string message = string(msg_len, 'x');
+            for (auto digest : ValidDigests(false /* withNone */, false /* withMD5 */)) {
+                SCOPED_TRACE(testing::Message() << "Digest::" << digest << "::MsgLen::" << msg_len);
+
+                int count = 10;
+                std::set<string> results;
+                for (int ii = 0; ii < count; ii++) {
+                    ASSERT_EQ(ErrorCode::OK,
+                              GenerateKey(AuthorizationSetBuilder()
+                                                  .Authorization(TAG_NO_AUTH_REQUIRED)
+                                                  .HmacKey(key_len)
+                                                  .Digest(digest)
+                                                  .Authorization(TAG_MIN_MAC_LENGTH, 160)))
+                            << "Failed to create HMAC key with digest " << digest;
+                    string signature = MacMessage(message, digest, 160);
+                    EXPECT_EQ(160U / 8U, signature.size())
+                            << "Failed to sign with HMAC key with digest " << digest;
+                    CheckedDeleteKey();
+                    results.insert(signature);
+                }
+                EXPECT_EQ(results.size(), count)
+                        << "HMAC of a message '" << message << "' with " << count
+                        << " fresh keys only gave " << results.size() << " distinct results";
+            }
+        }
+    }
+}
+
+/*
  * SigningOperationsTest.HmacSha256TooLargeMacLength
  *
  * Verifies that HMAC fails in the correct way when asked to generate a MAC larger than the
@@ -5222,6 +5226,149 @@
                                        .Padding(PaddingMode::RSA_OAEP)));
 }
 
+auto wrapped_rsa_key = hex2str(
+        "308206230201000482010060f81b63ae53aa4be2e91b0b7cbdabd108125836139e5b991f3e3c9a98eca6cb7188"
+        "fba1c1232605747ed118975870c886e583a0ff766fc32b789a17029955caaff39a9c6c439be168e24b51046683"
+        "ce16110e0df115ccabbadcbe7ea9118b9589e4cccf240b6f0a506dfee57e19738c3cabb7dbf63b43e1b9ab058b"
+        "41b9480f2797210ef2bfbecb82526ac60ac006ebe0a053e825ad996d0ce8a98dc1ebf6ad889e491e03e9ddcc05"
+        "63f31921b55a54c61aa7f846d814dfe548f2c7939940bc6cf20489733203732df924b2b2a5aa9b54d31e7e42b9"
+        "e6cf107182edd33cb8e41db88167a79a264bbf883e69300ac82aac8de9dca0a13900150111efead81b74040c78"
+        "01d20b1547cfef40de45da30350201013030a1083106020102020103a203020101a30402020800a40531030201"
+        "01a5053103020104a6053103020103bf8377020500048204c126cd1642e83dea941151d872de12b8aaa835446e"
+        "94d2c1ea99c030225c5cad125dabe2341d9aba63e4df7fefc51e8e6f623ffae2aab9927113562b674b3cc2d7fc"
+        "fc34f199151a56ab114e792e6a21bd3b31fbf0d93050b9f90fb8e6cad3a067a4033848c4380184990f19a141d9"
+        "527177fdc13d802c33d222206c36404518285fe7e631aaeb6072c22c351c8c9db06e0b24e11aecef305f6abefb"
+        "4f31111534f7c55da8cf0d33882edbb43765304d1d45545c5207a858ea8d4369393bf1c54624df03da86c0ed47"
+        "b9ce1297149622069d51d2512f656ad0d421e6ff746ce8f79920df6a204c31732414a2f7eb24f8c2950348187a"
+        "4ba20b88a72355a4ec2b383be9f9b5b9ad564aa4c81de47dd95d77a8156ed0901d005a26f523b2a82c2d25d64d"
+        "f7660a6d3a720a6ba1eafe71da9fed0265d37a475193525620e705a543a928827accad93aba90556da859808be"
+        "dc2a8105af252e883892f41679d0600ddefb84415145bc28a2d9b0c60cea1ed3876486950ae0532cc1e953b0b5"
+        "81314c74250550741b24e4221ebb2804428caa2f08356a7de853ccfc5b18c2179147a883fa5763dd54f0d45388"
+        "c72f1bea19675d14014a725e125cdfac98d1701d9562be9d75362ea238b93244f46306cee4d77cbb8cbe7bf22d"
+        "fe677bbb103c00a204e49a0731660a2b23ee73ec7297a17822d4c4468e271029f8f1e8995f1a37cdc38324ead3"
+        "2474e6ee3ff671803d8a98a870324364d408c4d966d3cf0b9bbcbdbdff34a3e9666705362bc78beb96df4b8964"
+        "d141022250f62d1433cba5d1f510859eff688e46ce65dea00f5ebcfe7a79081ef1f0f5584dba14b79bc5a5f309"
+        "a1e48fe2bd9e94fcd9793d9b3632ccc51f18f7453e897e33b729abd2d34be324acbc22dfbf1d089aa93a178f79"
+        "23344140a468ac120b2f0055c284576b968e1d5148c6879b207b6cdb4eb513bccca619ae12ef156a9df03d6d8c"
+        "2c1c2ea7109dbcb61e5a74b36d0a7529f38b9ea742a956376da823251a6126693e2e1dab55b643c4e9783db835"
+        "f64d91069a2de1cda55539da52cadeeba2d3278da9005d89b4de4c5571600823f53d9cab1b55f65a560479d9ee"
+        "edeb361ab80ccedd0a067ddf5de639d115ffb3acf07fbba1cba6daa524b99db0b785273f7b6c15c4237ce1dce8"
+        "1b81622f35f116b638c75f0e0b26ba6bd9c5caee60c8b4f9198052b25e8c101638598946cb02c14db0a21b46c6"
+        "61ea123b2a2b5a51eb059715ce26940c977715a32e288b713013d66d0dae398d546abcd8c80966190b77732a7c"
+        "e2b8fc83e0cd83f69adef2b24b69fba19c546362087c08c8dab941a8573a084be3407d45a318c9a299f69d79f6"
+        "fae0859d6f08ee7708cf6041cccd815c3515f792aefc23a624e8e58bd9c6fe2f8f1ca6dcf04c6fdfa23eb3ff74"
+        "c5e5c7388f9faa32c86b6cd7438774e6cf06cb23a32cddb04c30f7d11e221db306c7937796e70a4dcfb7415c04"
+        "7823b965bedeaea196dc30fe648c52f3c1bcee62b19d4cccdb740ca35c3f3daad998c99dc117fffb7d150d500f"
+        "812b60ebec8b2067b13938250d078768e77f898fcdfc5f3554b6eda9df3b42bef38bb4d67cb63b7ede01e93b4d"
+        "c7768b52aa8ad8fb7fb288a529b84671f1ff9e44bb7c8f05d99806b65eb8e90b530fef3817f9fc4c921d0d46af"
+        "11aee8252407adc6c54589e9f6e6c1e25fc7510cfe499ea20465610410bf575efdbeb5af763920c3b4cdc8401"
+        "2");
+
+auto wrapped_ec_key = hex2str(
+        "308201dd020100048201000bb910602f88b1419ada400c8ab7602cf2fdbb4ef5e36881255fd5f85d49c4110c52"
+        "c75eab5e27a1732c1afa17bfe2cd393dea0a78a77ee08759e984411d1c7f0dbdcb6b77e05556694534be4434d8"
+        "596a7152aec71481522c85f0cc4635df2875d58dc29a78317b2aedd3586055e6e2227616f6a8ac4b9db5a2ad0e"
+        "10f5c4b43374bd6c9f57f79a103e64084414cfab3d3e0b7c2f26eb00a62105b7d1c7f41b7292fd6fce9395f39c"
+        "e0b6da0b5bf0d29d8952b958bd29b47c5ebd20d53ade370f463e35a166c04af71e3d5ce550019d3d20a5544896"
+        "65d169875d0e6a52348b7ec39b674f818e9b60dfa284d7ae4188471d05b9b2d9a5f750f5a00af999c568040c31"
+        "4144bde8ada6279d32e61530270201013022a1083106020102020103a203020103a30402020100a50531030201"
+        "04bf837702050004818a96e0f8be5a263616b506371d3c2ff3a3c2bcffc3ce067b242af66e30d5cd975b9546eb"
+        "32216d4f083f08fde246ab05fd7e930a0f05701067b44840c01a6722e1b2408be5b6acd0b39a0329cb2f357515"
+        "876433b193382c0b18aed9ed244dcbef5d61d98ca480f99a6cf2a00efda22eb8750db1725e30f64770ac6862ac"
+        "44cfd08a2c55812b512a0b92f704105c80b6a23cf339b2b10c677613510b1b");
+
+auto wrapping_key_for_asym_keys = hex2str(
+        "308204bd020100300d06092a864886f70d0101010500048204a7308204a30201000282010100a7f521fe024ebc"
+        "659db8e7a32b41dba27c5d446cb3d064d594b811d4856c3a583d155b0ff9300df3745738c32c4c4cd15adb6090"
+        "72ca870364bb7f3485784fde12e598b486c91950b9c45016bcb73c3842747c871be02dfc5f0e4b96d1ff5c8a09"
+        "7ae77b27e46dc60f1f574d1bb5e97487c1c3f9b493509e07318e1a0f0e9fdae401f4a62a5dd54daa09bf88ef42"
+        "9923f6f6f55d239908f227676d0f0b618238728dc4babd2a1f7d15fa9827346a1a160ab9427461533006fdf34d"
+        "4efec9aeefcea80b3a7d4ee4a4550055f0030700c5d20abcc32ce74d90ffabf83e02a759ce9074809936564f3d"
+        "3039af9c5e8a6afd9aa5459ab35c3eb851f10b3ae88ba91f0203010001028201001885515124451a7c3b6aa366"
+        "cf09ee66ea81335c2b6461544d42125854a258624988b4a2c05ea3aac77174780a1f9997770c502cc6958ae093"
+        "f44bbdff3e716a9a97aa93b099eb783da6cb8a8642ba27fc8bc522748f66275239640fc0d8e749bfd891b3093f"
+        "f046da2e593088bb263a3d17ace4e7d81a0cf83fe3df2a139882bff509523a3f886922200168ddd8fb7b4c9f26"
+        "62ff941c37937cebbbfeba24dd78d5ccd42025cb0276fa5661965f529274520bbb9faf36c501cafb48e5e47ae0"
+        "6980334fa36b6c62e2da733a8c7f01067de17e38d32d4a0721a6d184405bceaebb39ed3838633e6fbe43ac8b23"
+        "337bfe33cdf0b67ac3938ddccc37d775ad150102818100d538885135037730fad28e987d7562c1ef8ca58f95f7"
+        "ed81cb165ca63e15e810552eb9d487c9b9cde563fb29d1de22a60d54a856385719a4028cf386bcdc88e858d963"
+        "6d644cea25e0ee54ad1237983d9a06a66ea2f764eb540a4992ba2291ea96d20dfbd98bf5b313322cda4eb6710d"
+        "020139e085beb8e52a3e69bd05c71c7b02818100c9a7c89b11fcf8d99eb41995b5641472ef972e5aaa1f1446d7"
+        "ea57a9979e8e64f72ef1cde358649b71be7f21dc19dab52814f9a521d8620bd994a9bb621a8182a250066a0728"
+        "f0b16ab93a106ed79bc19cd519e83196157a8c6f82b5144a285b9384415394905fe18863b0988b27e77c969a81"
+        "c34a074e8fef5908fdf3c51ead02818019d5e8c6963ade45640f01523ed96b66fe64b766e7900c0a4f165d9193"
+        "324a55384d1a1d437ad0f5bed6d78720b3ded4ea069903217e844fd833460acc75986d36ded86a57ddedfd3afd"
+        "05eb96aa7fdaeeffe148c49c5f711854cac769a068b7d92088ab3c97f5e485eded7b62503ef0898ea679ab1b0a"
+        "0252950f70e4f35463028181008ff4c027bb8aad17a5cd0a2aaea83854e8a73347340525d38115e0e8c7bd4007"
+        "e1d1d87ad35e69cbf2423cbdae43a2b70a5b16f0849dd53882663758f6aad763ab7d97669f9fe15bb6456ea706"
+        "89d2be3fb87d5b1df2f77859c2cd3b79b58ae3fd0640206b813981667d4c3749b7fdf01a0f48ad622e9f2def7e"
+        "cf0583bd67ad0281805bd8f20cc82cb5e08dc2e7eea977d4180a5ef4c558e01255b8475feb9084475e20328c93"
+        "5a2247a775c941d64372d01abb27c95ee7d4336b6cbce190808b2f7a8d314d785336397dd6edc0c778f563d37e"
+        "0057b13695600b92fececc3edb067f69b374f9b9c343220a8b927deb6104768edc72b87751e0a3fb1585e679c9"
+        "8564");
+
+TEST_P(ImportWrappedKeyTest, RsaKey) {
+    int vsr_api_level = get_vsr_api_level();
+    if (vsr_api_level < __ANDROID_API_V__) {
+        /*
+         * The Keymaster v4 spec introduced `importWrappedKey()` and did not restrict it to
+         * just symmetric keys.  However, the import of asymmetric wrapped keys was not tested
+         * at the time, so we can only be strict about checking this for implementations claiming
+         * support for VSR API level 35 and above.
+         */
+        GTEST_SKIP() << "Applies only to VSR API level 35, this device is: " << vsr_api_level;
+    }
+
+    auto wrapping_key_desc = AuthorizationSetBuilder()
+                                     .RsaEncryptionKey(2048, 65537)
+                                     .Digest(Digest::SHA_2_256)
+                                     .Padding(PaddingMode::RSA_OAEP)
+                                     .Authorization(TAG_PURPOSE, KeyPurpose::WRAP_KEY)
+                                     .SetDefaultValidity();
+
+    ASSERT_EQ(ErrorCode::OK, ImportWrappedKey(wrapped_rsa_key, wrapping_key_for_asym_keys,
+                                              wrapping_key_desc, zero_masking_key,
+                                              AuthorizationSetBuilder()
+                                                      .Digest(Digest::SHA_2_256)
+                                                      .Padding(PaddingMode::RSA_OAEP)));
+
+    string message = "Hello World!";
+    auto params = AuthorizationSetBuilder().Digest(Digest::SHA_2_256).Padding(PaddingMode::RSA_PSS);
+    string signature = SignMessage(message, params);
+    LocalVerifyMessage(message, signature, params);
+}
+
+TEST_P(ImportWrappedKeyTest, EcKey) {
+    int vsr_api_level = get_vsr_api_level();
+    if (vsr_api_level < __ANDROID_API_V__) {
+        /*
+         * The Keymaster v4 spec introduced `importWrappedKey()` and did not restrict it to
+         * just symmetric keys.  However, the import of asymmetric wrapped keys was not tested
+         * at the time, so we can only be strict about checking this for implementations claiming
+         * support for VSR API level 35 and above.
+         */
+        GTEST_SKIP() << "Applies only to VSR API level 35, this device is: " << vsr_api_level;
+    }
+
+    auto wrapping_key_desc = AuthorizationSetBuilder()
+                                     .RsaEncryptionKey(2048, 65537)
+                                     .Digest(Digest::SHA_2_256)
+                                     .Padding(PaddingMode::RSA_OAEP)
+                                     .Authorization(TAG_PURPOSE, KeyPurpose::WRAP_KEY)
+                                     .SetDefaultValidity();
+
+    ASSERT_EQ(ErrorCode::OK, ImportWrappedKey(wrapped_ec_key, wrapping_key_for_asym_keys,
+                                              wrapping_key_desc, zero_masking_key,
+                                              AuthorizationSetBuilder()
+                                                      .Digest(Digest::SHA_2_256)
+                                                      .Padding(PaddingMode::RSA_OAEP)));
+
+    string message = "Hello World!";
+    auto params = AuthorizationSetBuilder().Digest(Digest::SHA_2_256);
+    string signature = SignMessage(message, params);
+    LocalVerifyMessage(message, signature, params);
+}
+
 INSTANTIATE_KEYMINT_AIDL_TEST(ImportWrappedKeyTest);
 
 typedef KeyMintAidlTestBase EncryptionOperationsTest;
@@ -8367,17 +8514,6 @@
                                .Authorization(TAG_ATTESTATION_CHALLENGE, challenge)
                                .SetDefaultValidity();
         ErrorCode result = GenerateKey(builder);
-
-        if (SecLevel() == SecurityLevel::STRONGBOX) {
-            if (result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) {
-                result = GenerateKeyWithSelfSignedAttestKey(
-                        AuthorizationSetBuilder()
-                                .EcdsaKey(EcCurve::P_256)
-                                .AttestKey()
-                                .SetDefaultValidity(), /* attest key params */
-                        builder, &key_blob_, &key_characteristics_, &cert_chain_);
-            }
-        }
         ASSERT_EQ(ErrorCode::OK, result) << "Failed to generate key";
         ASSERT_GT(cert_chain_.size(), 0);
         X509_Ptr kmKeyCert(parse_cert_blob(cert_chain_[0].encodedCertificate));
@@ -8668,11 +8804,6 @@
     KeyBlobDeleter ecdsa_deleter(keymint_, ecdsaKeyData.blob);
 
     for (const auto& keyData : {aesKeyData, hmacKeyData, rsaKeyData, ecdsaKeyData}) {
-        // Strongbox may not support factory attestation. Key creation might fail with
-        // ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED
-        if (SecLevel() == SecurityLevel::STRONGBOX && keyData.blob.size() == 0U) {
-            continue;
-        }
         ASSERT_GT(keyData.blob.size(), 0U);
         AuthorizationSet crypto_params = SecLevelAuthorizations(keyData.characteristics);
         EXPECT_TRUE(crypto_params.Contains(TAG_EARLY_BOOT_ONLY)) << crypto_params;
@@ -8872,13 +9003,6 @@
 using aidl::android::hardware::security::keymint::test::KeyMintAidlTestBase;
 
 int main(int argc, char** argv) {
-    std::cout << "Testing ";
-    auto halInstances = KeyMintAidlTestBase::build_params();
-    std::cout << "HAL instances:\n";
-    for (auto& entry : halInstances) {
-        std::cout << "    " << entry << '\n';
-    }
-
     ::testing::InitGoogleTest(&argc, argv);
     for (int i = 1; i < argc; ++i) {
         if (argv[i][0] == '-') {
diff --git a/security/keymint/aidl/vts/performance/Android.bp b/security/keymint/aidl/vts/performance/Android.bp
index 7e3a3e5..6179c99 100644
--- a/security/keymint/aidl/vts/performance/Android.bp
+++ b/security/keymint/aidl/vts/performance/Android.bp
@@ -41,7 +41,7 @@
     ],
     static_libs: [
         "android.hardware.security.secureclock-V1-ndk",
-        "libcppbor_external",
+        "libcppbor",
         "libchrome",
     ],
 }
diff --git a/security/keymint/support/Android.bp b/security/keymint/support/Android.bp
index 1a8695b..5c9efef 100644
--- a/security/keymint/support/Android.bp
+++ b/security/keymint/support/Android.bp
@@ -72,7 +72,7 @@
     shared_libs: [
         "libbase",
         "libbinder_ndk",
-        "libcppbor_external",
+        "libcppbor",
         "libcppcose_rkp",
         "libcrypto",
         "libkeymaster_portable",
@@ -94,7 +94,7 @@
     ],
     shared_libs: [
         "libbase",
-        "libcppbor_external",
+        "libcppbor",
         "libcppcose_rkp",
         "libcrypto",
         "libjsoncpp",
diff --git a/security/keymint/support/fuzzer/Android.bp b/security/keymint/support/fuzzer/Android.bp
new file mode 100644
index 0000000..1b1a580
--- /dev/null
+++ b/security/keymint/support/fuzzer/Android.bp
@@ -0,0 +1,69 @@
+/*
+ * 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 {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+    default_team: "trendy_team_android_hardware_backed_security",
+}
+
+cc_defaults {
+    name: "keymint_fuzzer_defaults",
+    static_libs: [
+        "libhidlbase",
+        "libkeymint_support",
+    ],
+    shared_libs: [
+        "libbase",
+        "libcrypto",
+        "libutils",
+        "libhardware",
+        "libbinder_ndk",
+        "liblog",
+    ],
+    defaults: [
+        "keymint_use_latest_hal_aidl_ndk_shared",
+    ],
+    include_dirs: [
+        "hardware/interfaces/security/keymint/support/include",
+        "frameworks/native/libs/binder/ndk/include_platform",
+    ],
+}
+
+cc_fuzz {
+    name: "keymint_attestation_fuzzer",
+    srcs: [
+        "keymint_attestation_fuzzer.cpp",
+    ],
+    defaults: [
+        "keymint_fuzzer_defaults",
+    ],
+}
+
+cc_fuzz {
+    name: "keymint_authSet_fuzzer",
+    srcs: [
+        "keymint_authSet_fuzzer.cpp",
+    ],
+    defaults: [
+        "keymint_fuzzer_defaults",
+    ],
+}
diff --git a/security/keymint/support/fuzzer/README.md b/security/keymint/support/fuzzer/README.md
new file mode 100644
index 0000000..d41af08
--- /dev/null
+++ b/security/keymint/support/fuzzer/README.md
@@ -0,0 +1,79 @@
+# Fuzzers for libkeymint_support
+
+## Plugin Design Considerations
+The fuzzer plugins for libkeymint_support are designed based on the understanding of the source code and try to achieve the following:
+
+#### Maximize code coverage
+The configuration parameters are not hardcoded, but instead selected based on incoming data. This ensures more code paths are reached by the fuzzers.
+
+#### Maximize utilization of input data
+The plugins feed the entire input data to the module. This ensures that the plugins tolerate any kind of input (empty, huge, malformed, etc) and dont `exit()` on any input and thereby increasing the chance of identifying vulnerabilities.
+
+## Table of contents
++ [keymint_attestation_fuzzer](#KeyMintAttestation)
++ [keymint_authSet_fuzzer](#KeyMintAuthSet)
+
+# <a name="KeyMintAttestation"></a> Fuzzer for KeyMintAttestation
+KeyMintAttestation supports the following parameters:
+1. PaddingMode(parameter name: "padding")
+2. Digest(parameter name: "digest")
+3. Index(parameter name: "idx")
+4. Timestamp(parameter name: "timestamp")
+5. AuthSet(parameter name: "authSet")
+6. IssuerSubjectName(parameter name: "issuerSubjectName")
+7. AttestationChallenge(parameter name: "challenge")
+8. AttestationApplicationId(parameter name: "id")
+9. EcCurve(parameter name: "ecCurve")
+10. BlockMode(parameter name: "blockmode")
+11. minMacLength(parameter name: "minMacLength")
+12. macLength(parameter name: "macLength")
+
+| Parameter| Valid Values| Configured Value|
+|------------- |--------------| -------------------- |
+|`padding`| `PaddingMode` |Value obtained from FuzzedDataProvider|
+|`digest`| `Digest` |Value obtained from FuzzedDataProvider|
+|`idx`| `size_t` |Value obtained from FuzzedDataProvider|
+|`timestamp`| `uint64_t` |Value obtained from FuzzedDataProvider|
+|`authSet`| `uint32_t` |Value obtained from FuzzedDataProvider|
+|`issuerSubjectName`| `uint8_t` |Value obtained from FuzzedDataProvider|
+|`AttestationChallenge`| `string` |Value obtained from FuzzedDataProvider|
+|`AttestationApplicationId`| `string` |Value obtained from FuzzedDataProvider|
+|`blockmode`| `BlockMode` |Value obtained from FuzzedDataProvider|
+|`minMacLength`| `uint32_t` |Value obtained from FuzzedDataProvider|
+|`macLength`| `uint32_t` |Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+$ mm -j$(nproc) keymint_attestation_fuzzer
+```
+2. Run on device
+```
+$ adb sync data
+$ adb shell /data/fuzz/arm64/keymint_attestation_fuzzer/keymint_attestation_fuzzer
+```
+
+# <a name="KeyMintAuthSet"></a> Fuzzer for KeyMintAuthSet
+KeyMintAuthSet supports the following parameters:
+1. AuthorizationSet(parameter name: "authSet")
+2. AuthorizationSet(parameter name: "params")
+3. KeyParameters(parameter name: "numKeyParam")
+4. Tag(parameter name: "tag")
+
+| Parameter| Valid Values| Configured Value|
+|------------- |--------------| -------------------- |
+|`authSet`| `AuthorizationSet` |Value obtained from FuzzedDataProvider|
+|`params`| `AuthorizationSet` |Value obtained from FuzzedDataProvider|
+|`numKeyParam`| `size_t` |Value obtained from FuzzedDataProvider|
+|`tag`| `Tag` |Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+$ mm -j$(nproc) keymint_authSet_fuzzer
+```
+2. Run on device
+```
+$ adb sync data
+$ adb shell /data/fuzz/arm64/keymint_authSet_fuzzer/keymint_authSet_fuzzer
+```
diff --git a/security/keymint/support/fuzzer/keymint_attestation_fuzzer.cpp b/security/keymint/support/fuzzer/keymint_attestation_fuzzer.cpp
new file mode 100644
index 0000000..bd781ac
--- /dev/null
+++ b/security/keymint/support/fuzzer/keymint_attestation_fuzzer.cpp
@@ -0,0 +1,165 @@
+/*
+ * 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 <aidl/android/hardware/security/keymint/AttestationKey.h>
+#include <aidl/android/hardware/security/keymint/KeyCreationResult.h>
+#include <android/binder_manager.h>
+#include <keymint_common.h>
+#include <keymint_support/attestation_record.h>
+#include <keymint_support/openssl_utils.h>
+#include <utils/Log.h>
+
+namespace android::hardware::security::keymint_support::fuzzer {
+using namespace android;
+using AStatus = ::ndk::ScopedAStatus;
+std::shared_ptr<IKeyMintDevice> gKeyMint = nullptr;
+
+constexpr size_t kMaxBytes = 256;
+const std::string kServiceName = "android.hardware.security.keymint.IKeyMintDevice/default";
+
+class KeyMintAttestationFuzzer {
+  public:
+    KeyMintAttestationFuzzer(const uint8_t* data, size_t size) : mFdp(data, size){};
+    void process();
+
+  private:
+    KeyCreationResult generateKey(const AuthorizationSet& keyDesc,
+                                  const std::optional<AttestationKey>& attestKey,
+                                  vector<uint8_t>* keyBlob,
+                                  vector<KeyCharacteristics>* keyCharacteristics,
+                                  vector<Certificate>* certChain);
+    X509_Ptr parseCertificateBlob(const vector<uint8_t>& blob);
+    ASN1_OCTET_STRING* getAttestationRecord(const X509* certificate);
+    bool verifyAttestationRecord(const vector<uint8_t>& attestationCert);
+    FuzzedDataProvider mFdp;
+};
+
+KeyCreationResult KeyMintAttestationFuzzer::generateKey(
+        const AuthorizationSet& keyDesc, const std::optional<AttestationKey>& attestKey,
+        vector<uint8_t>* keyBlob, vector<KeyCharacteristics>* keyCharacteristics,
+        vector<Certificate>* certChain) {
+    KeyCreationResult creationResult;
+    AStatus result = gKeyMint->generateKey(keyDesc.vector_data(), attestKey, &creationResult);
+    if (result.isOk() && creationResult.keyBlob.size() > 0) {
+        *keyBlob = std::move(creationResult.keyBlob);
+        *keyCharacteristics = std::move(creationResult.keyCharacteristics);
+        *certChain = std::move(creationResult.certificateChain);
+    }
+    return creationResult;
+}
+
+X509_Ptr KeyMintAttestationFuzzer::parseCertificateBlob(const vector<uint8_t>& blob) {
+    const uint8_t* data = blob.data();
+    return X509_Ptr(d2i_X509(nullptr, &data, blob.size()));
+}
+
+ASN1_OCTET_STRING* KeyMintAttestationFuzzer::getAttestationRecord(const X509* certificate) {
+    ASN1_OBJECT_Ptr oid(OBJ_txt2obj(kAttestionRecordOid, 1 /* dotted string format */));
+    if (!oid.get()) {
+        return nullptr;
+    }
+
+    int32_t location = X509_get_ext_by_OBJ(certificate, oid.get(), -1 /* search from beginning */);
+    if (location == -1) {
+        return nullptr;
+    }
+
+    X509_EXTENSION* attestRecordExt = X509_get_ext(certificate, location);
+    if (!attestRecordExt) {
+        return nullptr;
+    }
+
+    ASN1_OCTET_STRING* attestRecord = X509_EXTENSION_get_data(attestRecordExt);
+    return attestRecord;
+}
+
+bool KeyMintAttestationFuzzer::verifyAttestationRecord(const vector<uint8_t>& attestationCert) {
+    X509_Ptr cert(parseCertificateBlob(attestationCert));
+    if (!cert.get()) {
+        return false;
+    }
+
+    ASN1_OCTET_STRING* attestRecord = getAttestationRecord(cert.get());
+    if (!attestRecord) {
+        return false;
+    }
+
+    AuthorizationSet attestationSwEnforced;
+    AuthorizationSet attestationHwEnforced;
+    SecurityLevel attestationSecurityLevel;
+    SecurityLevel keymintSecurityLevel;
+    vector<uint8_t> attestationChallenge;
+    vector<uint8_t> attestationUniqueId;
+    uint32_t attestationVersion;
+    uint32_t keymintVersion;
+
+    auto error = parse_attestation_record(attestRecord->data, attestRecord->length,
+                                          &attestationVersion, &attestationSecurityLevel,
+                                          &keymintVersion, &keymintSecurityLevel,
+                                          &attestationChallenge, &attestationSwEnforced,
+                                          &attestationHwEnforced, &attestationUniqueId);
+    if (error != ErrorCode::OK) {
+        return false;
+    }
+
+    VerifiedBoot verifiedBootState;
+    vector<uint8_t> verifiedBootKey;
+    vector<uint8_t> verifiedBootHash;
+    bool device_locked;
+
+    error = parse_root_of_trust(attestRecord->data, attestRecord->length, &verifiedBootKey,
+                                &verifiedBootState, &device_locked, &verifiedBootHash);
+    if (error != ErrorCode::OK) {
+        return false;
+    }
+    return true;
+}
+
+void KeyMintAttestationFuzzer::process() {
+    AttestationKey attestKey;
+    vector<Certificate> attestKeyCertChain;
+    vector<KeyCharacteristics> attestKeyCharacteristics;
+    generateKey(createAuthSetForAttestKey(&mFdp), {}, &attestKey.keyBlob, &attestKeyCharacteristics,
+                &attestKeyCertChain);
+
+    vector<Certificate> attestedKeyCertChain;
+    vector<KeyCharacteristics> attestedKeyCharacteristics;
+    vector<uint8_t> attestedKeyBlob;
+    attestKey.issuerSubjectName = mFdp.ConsumeBytes<uint8_t>(kMaxBytes);
+    generateKey(createAuthorizationSet(&mFdp), attestKey, &attestedKeyBlob,
+                &attestedKeyCharacteristics, &attestedKeyCertChain);
+
+    if (attestedKeyCertChain.size() > 0) {
+        size_t leafCert = attestedKeyCertChain.size() - 1;
+        verifyAttestationRecord(attestedKeyCertChain[leafCert].encodedCertificate);
+    }
+}
+
+extern "C" int LLVMFuzzerInitialize(int /* *argc */, char /* ***argv */) {
+    ::ndk::SpAIBinder binder(AServiceManager_waitForService(kServiceName.c_str()));
+    gKeyMint = std::move(IKeyMintDevice::fromBinder(binder));
+    LOG_ALWAYS_FATAL_IF(!gKeyMint, "Failed to get IKeyMintDevice instance.");
+    return 0;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    KeyMintAttestationFuzzer kmAttestationFuzzer(data, size);
+    kmAttestationFuzzer.process();
+    return 0;
+}
+
+}  // namespace android::hardware::security::keymint_support::fuzzer
diff --git a/security/keymint/support/fuzzer/keymint_authSet_fuzzer.cpp b/security/keymint/support/fuzzer/keymint_authSet_fuzzer.cpp
new file mode 100644
index 0000000..fcc3d91
--- /dev/null
+++ b/security/keymint/support/fuzzer/keymint_authSet_fuzzer.cpp
@@ -0,0 +1,175 @@
+/*
+ * 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 <keymint_common.h>
+#include <fstream>
+
+namespace android::hardware::security::keymint_support::fuzzer {
+
+constexpr size_t kMinAction = 0;
+constexpr size_t kMaxAction = 10;
+constexpr size_t kMinKeyParameter = 1;
+constexpr size_t kMaxKeyParameter = 10;
+
+constexpr Tag kTagArray[] = {Tag::INVALID,
+                             Tag::PURPOSE,
+                             Tag::ALGORITHM,
+                             Tag::KEY_SIZE,
+                             Tag::BLOCK_MODE,
+                             Tag::DIGEST,
+                             Tag::PADDING,
+                             Tag::CALLER_NONCE,
+                             Tag::MIN_MAC_LENGTH,
+                             Tag::EC_CURVE,
+                             Tag::RSA_PUBLIC_EXPONENT,
+                             Tag::INCLUDE_UNIQUE_ID,
+                             Tag::RSA_OAEP_MGF_DIGEST,
+                             Tag::BOOTLOADER_ONLY,
+                             Tag::ROLLBACK_RESISTANCE,
+                             Tag::HARDWARE_TYPE,
+                             Tag::EARLY_BOOT_ONLY,
+                             Tag::ACTIVE_DATETIME,
+                             Tag::ORIGINATION_EXPIRE_DATETIME,
+                             Tag::USAGE_EXPIRE_DATETIME,
+                             Tag::MIN_SECONDS_BETWEEN_OPS,
+                             Tag::MAX_USES_PER_BOOT,
+                             Tag::USAGE_COUNT_LIMIT,
+                             Tag::USER_ID,
+                             Tag::USER_SECURE_ID,
+                             Tag::NO_AUTH_REQUIRED,
+                             Tag::USER_AUTH_TYPE,
+                             Tag::AUTH_TIMEOUT,
+                             Tag::ALLOW_WHILE_ON_BODY,
+                             Tag::TRUSTED_USER_PRESENCE_REQUIRED,
+                             Tag::TRUSTED_CONFIRMATION_REQUIRED,
+                             Tag::UNLOCKED_DEVICE_REQUIRED,
+                             Tag::APPLICATION_ID,
+                             Tag::APPLICATION_DATA,
+                             Tag::CREATION_DATETIME,
+                             Tag::ORIGIN,
+                             Tag::ROOT_OF_TRUST,
+                             Tag::OS_VERSION,
+                             Tag::OS_PATCHLEVEL,
+                             Tag::UNIQUE_ID,
+                             Tag::ATTESTATION_CHALLENGE,
+                             Tag::ATTESTATION_APPLICATION_ID,
+                             Tag::ATTESTATION_ID_BRAND,
+                             Tag::ATTESTATION_ID_DEVICE,
+                             Tag::ATTESTATION_ID_PRODUCT,
+                             Tag::ATTESTATION_ID_SERIAL,
+                             Tag::ATTESTATION_ID_IMEI,
+                             Tag::ATTESTATION_ID_MEID,
+                             Tag::ATTESTATION_ID_MANUFACTURER,
+                             Tag::ATTESTATION_ID_MODEL,
+                             Tag::VENDOR_PATCHLEVEL,
+                             Tag::BOOT_PATCHLEVEL,
+                             Tag::DEVICE_UNIQUE_ATTESTATION,
+                             Tag::IDENTITY_CREDENTIAL_KEY,
+                             Tag::STORAGE_KEY,
+                             Tag::ASSOCIATED_DATA,
+                             Tag::NONCE,
+                             Tag::MAC_LENGTH,
+                             Tag::RESET_SINCE_ID_ROTATION,
+                             Tag::CONFIRMATION_TOKEN,
+                             Tag::CERTIFICATE_SERIAL,
+                             Tag::CERTIFICATE_SUBJECT,
+                             Tag::CERTIFICATE_NOT_BEFORE,
+                             Tag::CERTIFICATE_NOT_AFTER,
+                             Tag::MAX_BOOT_LEVEL};
+
+class KeyMintAuthSetFuzzer {
+  public:
+    KeyMintAuthSetFuzzer(const uint8_t* data, size_t size) : mFdp(data, size){};
+    void process();
+
+  private:
+    FuzzedDataProvider mFdp;
+};
+
+void KeyMintAuthSetFuzzer::process() {
+    AuthorizationSet authSet = createAuthorizationSet(&mFdp);
+    while (mFdp.remaining_bytes()) {
+        auto invokeAuthSetAPI = mFdp.PickValueInArray<const std::function<void()>>({
+                [&]() { authSet.Sort(); },
+                [&]() { authSet.Deduplicate(); },
+                [&]() { authSet.Union(createAuthorizationSet(&mFdp)); },
+                [&]() { authSet.Subtract(createAuthorizationSet(&mFdp)); },
+                [&]() {  // invoke push_back()
+                    AuthorizationSetBuilder builder = AuthorizationSetBuilder();
+                    for (const KeyParameter& tag : authSet) {
+                        builder.push_back(tag);
+                    }
+                    AuthorizationSet params = createAuthorizationSet(&mFdp);
+                    authSet.push_back(params);
+                },
+                [&]() {  // invoke copy constructor
+                    auto params = AuthorizationSetBuilder().Authorizations(authSet);
+                    authSet = params;
+                },
+                [&]() {  // invoke move constructor
+                    auto params = AuthorizationSetBuilder().Authorizations(authSet);
+                    authSet = std::move(params);
+                },
+                [&]() {  // invoke Constructor from vector<KeyParameter>
+                    vector<KeyParameter> keyParam;
+                    size_t numKeyParam =
+                            mFdp.ConsumeIntegralInRange<size_t>(kMinKeyParameter, kMaxKeyParameter);
+                    keyParam.resize(numKeyParam);
+                    for (size_t idx = 0; idx < numKeyParam - 1; ++idx) {
+                        keyParam[idx].tag = mFdp.PickValueInArray(kTagArray);
+                    }
+                    if (mFdp.ConsumeBool()) {
+                        AuthorizationSet auths(keyParam);
+                        auths.push_back(AuthorizationSet(keyParam));
+                    } else {  // invoke operator=
+                        AuthorizationSet auths = keyParam;
+                    }
+                },
+                [&]() {  // invoke 'Contains()'
+                    Tag tag = Tag::INVALID;
+                    if (authSet.size() > 0) {
+                        tag = authSet[mFdp.ConsumeIntegralInRange<size_t>(0, authSet.size() - 1)]
+                                      .tag;
+                    }
+                    authSet.Contains(mFdp.ConsumeBool() ? tag : mFdp.PickValueInArray(kTagArray));
+                },
+                [&]() {  // invoke 'GetTagCount()'
+                    Tag tag = Tag::INVALID;
+                    if (authSet.size() > 0) {
+                        tag = authSet[mFdp.ConsumeIntegralInRange<size_t>(0, authSet.size() - 1)]
+                                      .tag;
+                    }
+                    authSet.GetTagCount(mFdp.ConsumeBool() ? tag
+                                                           : mFdp.PickValueInArray(kTagArray));
+                },
+                [&]() {  // invoke 'erase()'
+                    if (authSet.size() > 0) {
+                        authSet.erase(mFdp.ConsumeIntegralInRange<size_t>(0, authSet.size() - 1));
+                    }
+                },
+        });
+        invokeAuthSetAPI();
+    }
+    authSet.Clear();
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    KeyMintAuthSetFuzzer kmAuthSetFuzzer(data, size);
+    kmAuthSetFuzzer.process();
+    return 0;
+}
+
+}  // namespace android::hardware::security::keymint_support::fuzzer
diff --git a/security/keymint/support/fuzzer/keymint_common.h b/security/keymint/support/fuzzer/keymint_common.h
new file mode 100644
index 0000000..5c30e38
--- /dev/null
+++ b/security/keymint/support/fuzzer/keymint_common.h
@@ -0,0 +1,260 @@
+/*
+ * 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.
+ *
+ */
+#ifndef __KEYMINT_COMMON_H__
+#define __KEYMINT_COMMON_H__
+
+#include <aidl/android/hardware/security/keymint/BlockMode.h>
+#include <aidl/android/hardware/security/keymint/Digest.h>
+#include <aidl/android/hardware/security/keymint/EcCurve.h>
+#include <aidl/android/hardware/security/keymint/PaddingMode.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <keymint_support/authorization_set.h>
+
+namespace android::hardware::security::keymint_support::fuzzer {
+
+using namespace aidl::android::hardware::security::keymint;
+
+constexpr uint32_t kStringSize = 64;
+constexpr uint32_t k3DesKeySize = 168;
+constexpr uint32_t kSymmKeySize = 256;
+constexpr uint32_t kRsaKeySize = 2048;
+constexpr uint32_t kPublicExponent = 65537;
+
+constexpr EcCurve kCurve[] = {EcCurve::P_224, EcCurve::P_256, EcCurve::P_384, EcCurve::P_521,
+                              EcCurve::CURVE_25519};
+
+constexpr PaddingMode kPaddingMode[] = {
+        PaddingMode::NONE,
+        PaddingMode::RSA_OAEP,
+        PaddingMode::RSA_PSS,
+        PaddingMode::RSA_PKCS1_1_5_ENCRYPT,
+        PaddingMode::RSA_PKCS1_1_5_SIGN,
+        PaddingMode::PKCS7,
+};
+
+constexpr Digest kDigest[] = {
+        Digest::NONE,      Digest::MD5,       Digest::SHA1,      Digest::SHA_2_224,
+        Digest::SHA_2_256, Digest::SHA_2_384, Digest::SHA_2_512,
+};
+
+constexpr BlockMode kBlockMode[] = {
+        BlockMode::ECB,
+        BlockMode::CBC,
+        BlockMode::CTR,
+        BlockMode::GCM,
+};
+
+enum AttestAuthSet : uint32_t {
+    RSA_ATTEST_KEY = 0u,
+    ECDSA_ATTEST_KEY,
+};
+
+enum AuthSet : uint32_t {
+    RSA_KEY = 0u,
+    RSA_SIGNING_KEY,
+    RSA_ENCRYPTION_KEY,
+    ECDSA_SIGNING_CURVE,
+    AES_ENCRYPTION_KEY,
+    TRIPLE_DES,
+    HMAC,
+    NO_DIGEST,
+    ECB_MODE,
+    GSM_MODE_MIN_MAC,
+    GSM_MODE_MAC,
+    BLOCK_MODE,
+};
+
+AuthorizationSet createAuthSetForAttestKey(FuzzedDataProvider* dataProvider) {
+    uint32_t attestAuthSet = dataProvider->ConsumeBool() ? AttestAuthSet::RSA_ATTEST_KEY
+                                                         : AttestAuthSet::ECDSA_ATTEST_KEY;
+    uint64_t timestamp = dataProvider->ConsumeIntegral<uint64_t>();
+    Digest digest = dataProvider->PickValueInArray(kDigest);
+    PaddingMode padding = dataProvider->PickValueInArray(kPaddingMode);
+    std::string challenge = dataProvider->ConsumeRandomLengthString(kStringSize);
+    std::string id = dataProvider->ConsumeRandomLengthString(kStringSize);
+    switch (attestAuthSet) {
+        case RSA_ATTEST_KEY: {
+            return AuthorizationSetBuilder()
+                    .Authorization(TAG_NO_AUTH_REQUIRED)
+                    .RsaKey(kRsaKeySize, kPublicExponent)
+                    .Digest(digest)
+                    .Padding(padding)
+                    .AttestKey()
+                    .AttestationChallenge(challenge)
+                    .AttestationApplicationId(id)
+                    .SetDefaultValidity()
+                    .Authorization(TAG_CREATION_DATETIME, timestamp)
+                    .Authorization(TAG_INCLUDE_UNIQUE_ID)
+                    .Authorization(TAG_PURPOSE, KeyPurpose::ATTEST_KEY);
+        } break;
+        case ECDSA_ATTEST_KEY: {
+            EcCurve ecCurve = dataProvider->PickValueInArray(kCurve);
+            return AuthorizationSetBuilder()
+                    .Authorization(TAG_NO_AUTH_REQUIRED)
+                    .EcdsaKey(ecCurve)
+                    .AttestKey()
+                    .Digest(digest)
+                    .AttestationChallenge(challenge)
+                    .AttestationApplicationId(id)
+                    .SetDefaultValidity()
+                    .Authorization(TAG_CREATION_DATETIME, timestamp)
+                    .Authorization(TAG_INCLUDE_UNIQUE_ID)
+                    .Authorization(TAG_PURPOSE, KeyPurpose::ATTEST_KEY);
+        } break;
+        default:
+            break;
+    };
+    return AuthorizationSetBuilder();
+}
+
+AuthorizationSet createAuthorizationSet(FuzzedDataProvider* dataProvider) {
+    uint32_t authSet =
+            dataProvider->ConsumeIntegralInRange<uint32_t>(AuthSet::RSA_KEY, AuthSet::BLOCK_MODE);
+    uint64_t timestamp = dataProvider->ConsumeIntegral<uint64_t>();
+    Digest digest = dataProvider->PickValueInArray(kDigest);
+    PaddingMode padding = dataProvider->PickValueInArray(kPaddingMode);
+    std::string challenge = dataProvider->ConsumeRandomLengthString(kStringSize);
+    std::string id = dataProvider->ConsumeRandomLengthString(kStringSize);
+    switch (authSet) {
+        case RSA_KEY: {
+            return AuthorizationSetBuilder()
+                    .Authorization(TAG_NO_AUTH_REQUIRED)
+                    .RsaKey(kRsaKeySize, kPublicExponent)
+                    .Digest(digest)
+                    .Padding(padding)
+                    .AttestKey()
+                    .AttestationChallenge(challenge)
+                    .AttestationApplicationId(id)
+                    .SetDefaultValidity()
+                    .Authorization(TAG_CREATION_DATETIME, timestamp)
+                    .Authorization(TAG_INCLUDE_UNIQUE_ID);
+        } break;
+        case RSA_SIGNING_KEY: {
+            return AuthorizationSetBuilder()
+                    .Authorization(TAG_NO_AUTH_REQUIRED)
+                    .RsaSigningKey(kRsaKeySize, kPublicExponent)
+                    .Digest(digest)
+                    .Padding(padding)
+                    .AttestationChallenge(challenge)
+                    .AttestationApplicationId(id)
+                    .SetDefaultValidity()
+                    .Authorization(TAG_CREATION_DATETIME, timestamp)
+                    .Authorization(TAG_INCLUDE_UNIQUE_ID);
+        } break;
+        case RSA_ENCRYPTION_KEY: {
+            return AuthorizationSetBuilder()
+                    .Authorization(TAG_NO_AUTH_REQUIRED)
+                    .RsaEncryptionKey(kRsaKeySize, kPublicExponent)
+                    .Digest(digest)
+                    .Padding(padding)
+                    .AttestationChallenge(challenge)
+                    .AttestationApplicationId(id)
+                    .SetDefaultValidity()
+                    .Authorization(TAG_CREATION_DATETIME, timestamp)
+                    .Authorization(TAG_INCLUDE_UNIQUE_ID);
+        } break;
+        case ECDSA_SIGNING_CURVE: {
+            EcCurve ecCurve = dataProvider->PickValueInArray(kCurve);
+            return AuthorizationSetBuilder()
+                    .Authorization(TAG_NO_AUTH_REQUIRED)
+                    .EcdsaSigningKey(ecCurve)
+                    .Digest(digest)
+                    .AttestationChallenge(challenge)
+                    .AttestationApplicationId(id)
+                    .SetDefaultValidity()
+                    .Authorization(TAG_CREATION_DATETIME, timestamp)
+                    .Authorization(TAG_INCLUDE_UNIQUE_ID);
+        } break;
+        case AES_ENCRYPTION_KEY: {
+            BlockMode blockmode = dataProvider->PickValueInArray(kBlockMode);
+            return AuthorizationSetBuilder()
+                    .Authorization(TAG_NO_AUTH_REQUIRED)
+                    .AesEncryptionKey(kSymmKeySize)
+                    .BlockMode(blockmode)
+                    .Digest(digest)
+                    .Padding(padding);
+        } break;
+        case TRIPLE_DES: {
+            BlockMode blockmode = dataProvider->PickValueInArray(kBlockMode);
+            return AuthorizationSetBuilder()
+                    .Authorization(TAG_NO_AUTH_REQUIRED)
+                    .TripleDesEncryptionKey(k3DesKeySize)
+                    .BlockMode(blockmode)
+                    .Digest(digest)
+                    .Padding(padding)
+                    .EcbMode()
+                    .SetDefaultValidity();
+        } break;
+        case HMAC: {
+            return AuthorizationSetBuilder()
+                    .Authorization(TAG_NO_AUTH_REQUIRED)
+                    .HmacKey(kSymmKeySize)
+                    .Digest(digest)
+                    .Padding(padding);
+        } break;
+        case NO_DIGEST: {
+            return AuthorizationSetBuilder()
+                    .Authorization(TAG_NO_AUTH_REQUIRED)
+                    .AesEncryptionKey(kSymmKeySize)
+                    .NoDigestOrPadding()
+                    .Digest(digest)
+                    .Padding(padding);
+        } break;
+        case ECB_MODE: {
+            return AuthorizationSetBuilder()
+                    .Authorization(TAG_NO_AUTH_REQUIRED)
+                    .AesEncryptionKey(kSymmKeySize)
+                    .EcbMode()
+                    .Digest(digest)
+                    .Padding(padding);
+        } break;
+        case GSM_MODE_MIN_MAC: {
+            uint32_t minMacLength = dataProvider->ConsumeIntegral<uint32_t>();
+            return AuthorizationSetBuilder()
+                    .Authorization(TAG_NO_AUTH_REQUIRED)
+                    .AesEncryptionKey(kSymmKeySize)
+                    .GcmModeMinMacLen(minMacLength)
+                    .Digest(digest)
+                    .Padding(padding);
+        } break;
+        case GSM_MODE_MAC: {
+            uint32_t macLength = dataProvider->ConsumeIntegral<uint32_t>();
+            return AuthorizationSetBuilder()
+                    .Authorization(TAG_NO_AUTH_REQUIRED)
+                    .AesEncryptionKey(kSymmKeySize)
+                    .GcmModeMacLen(macLength)
+                    .Digest(digest)
+                    .Padding(padding);
+        } break;
+        case BLOCK_MODE: {
+            BlockMode blockmode = dataProvider->PickValueInArray(kBlockMode);
+            return AuthorizationSetBuilder()
+                    .Authorization(TAG_NO_AUTH_REQUIRED)
+                    .AesEncryptionKey(kSymmKeySize)
+                    .BlockMode(blockmode)
+                    .Digest(digest)
+                    .Padding(padding);
+        } break;
+        default:
+            break;
+    };
+    return AuthorizationSetBuilder();
+}
+
+}  // namespace android::hardware::security::keymint_support::fuzzer
+
+#endif  // __KEYMINT_COMMON_H__
diff --git a/security/keymint/support/include/remote_prov/remote_prov_utils.h b/security/keymint/support/include/remote_prov/remote_prov_utils.h
index b8c69eb..1d7db6a 100644
--- a/security/keymint/support/include/remote_prov/remote_prov_utils.h
+++ b/security/keymint/support/include/remote_prov/remote_prov_utils.h
@@ -183,4 +183,7 @@
         const cppbor::Array& keysToSign, const std::vector<uint8_t>& csr,
         IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge);
 
+/** Checks whether the CSR has a proper DICE chain. */
+ErrMsgOr<bool> isCsrWithProperDiceChain(const std::vector<uint8_t>& csr);
+
 }  // namespace aidl::android::hardware::security::keymint::remote_prov
diff --git a/security/keymint/support/remote_prov_utils.cpp b/security/keymint/support/remote_prov_utils.cpp
index a830041..b74fd59 100644
--- a/security/keymint/support/remote_prov_utils.cpp
+++ b/security/keymint/support/remote_prov_utils.cpp
@@ -1081,4 +1081,40 @@
     return verifyCsr(keysToSign, csr, provisionable, challenge, /*isFactory=*/false);
 }
 
+ErrMsgOr<bool> isCsrWithProperDiceChain(const std::vector<uint8_t>& csr) {
+    auto [parsedRequest, _, csrErrMsg] = cppbor::parse(csr);
+    if (!parsedRequest) {
+        return csrErrMsg;
+    }
+    if (!parsedRequest->asArray()) {
+        return "AuthenticatedRequest is not a CBOR array.";
+    }
+    if (parsedRequest->asArray()->size() != 4U) {
+        return "AuthenticatedRequest must contain version, UDS certificates, DICE chain, and "
+               "signed data. However, the parsed AuthenticatedRequest has " +
+               std::to_string(parsedRequest->asArray()->size()) + " entries.";
+    }
+
+    auto version = parsedRequest->asArray()->get(0)->asUint();
+    auto diceCertChain = parsedRequest->asArray()->get(2)->asArray();
+
+    if (!version || version->value() != 1U) {
+        return "AuthenticatedRequest version must be an unsigned integer and must be equal to 1.";
+    }
+    if (!diceCertChain) {
+        return "AuthenticatedRequest DiceCertChain must be an Array.";
+    }
+
+    // DICE chain is [ pubkey, + DiceChainEntry ].
+    auto diceChainKind = getDiceChainKind();
+    if (!diceChainKind) {
+        return diceChainKind.message();
+    }
+
+    auto encodedDiceChain = diceCertChain->encode();
+    auto chain = hwtrust::DiceChain::Verify(encodedDiceChain, *diceChainKind);
+    if (!chain.ok()) return chain.error().message();
+    return chain->IsProper();
+}
+
 }  // namespace aidl::android::hardware::security::keymint::remote_prov
diff --git a/security/rkp/README.md b/security/rkp/README.md
index 2d00b83..67cf72e 100644
--- a/security/rkp/README.md
+++ b/security/rkp/README.md
@@ -201,7 +201,7 @@
 
 It is important to distinquish the RKP VM from other components, such as KeyMint. An
 [RKP VM marker](https://pigweed.googlesource.com/open-dice/+/HEAD/docs/android.md#configuration-descriptor)
-(key `-70006) is used for this purpose. The existence or absence of this marker is used to
+(key `-70006`) is used for this purpose. The existence or absence of this marker is used to
 identify the type of component decribed by a given DICE chain.
 
 The following describes which certificate types may be request based on the RKP VM marker:
diff --git a/security/rkp/aidl/android/hardware/security/keymint/DeviceInfo.aidl b/security/rkp/aidl/android/hardware/security/keymint/DeviceInfo.aidl
index f668536..98cf023 100644
--- a/security/rkp/aidl/android/hardware/security/keymint/DeviceInfo.aidl
+++ b/security/rkp/aidl/android/hardware/security/keymint/DeviceInfo.aidl
@@ -28,8 +28,9 @@
 parcelable DeviceInfo {
     /**
      * DeviceInfo is a CBOR Map structure described by the following CDDL. DeviceInfo must be
-     * canonicalized according to the specification in RFC 7049. The ordering presented here is
-     * non-canonical to group similar entries semantically.
+     * ordered according to the Length-First Map Key Ordering specified in RFC 8949,
+     * Section 4.2.3. Please note that the ordering presented here groups similar entries
+     * semantically, and not in the correct order per RFC 8949, Section 4.2.3.
      *
      * The DeviceInfo has changed across versions 1, 2, and 3 of the HAL. All versions of the
      * DeviceInfo CDDL are described in the DeviceInfoV*.cddl files. Please refer to the CDDL
diff --git a/security/rkp/aidl/vts/functional/Android.bp b/security/rkp/aidl/vts/functional/Android.bp
index 9c2b6e1..2cce8db 100644
--- a/security/rkp/aidl/vts/functional/Android.bp
+++ b/security/rkp/aidl/vts/functional/Android.bp
@@ -32,7 +32,7 @@
         "libcrypto",
     ],
     static_libs: [
-        "libcppbor_external",
+        "libcppbor",
         "libgmock_ndk",
         "libkeymint_vts_test_utils",
     ],
diff --git a/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp b/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
index 68b966c..2dbc73f 100644
--- a/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
+++ b/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
@@ -55,8 +55,12 @@
 
 constexpr uint8_t MIN_CHALLENGE_SIZE = 0;
 constexpr uint8_t MAX_CHALLENGE_SIZE = 64;
+const string DEFAULT_INSTANCE_NAME =
+        "android.hardware.security.keymint.IRemotelyProvisionedComponent/default";
 const string RKP_VM_INSTANCE_NAME =
         "android.hardware.security.keymint.IRemotelyProvisionedComponent/avf";
+const string KEYMINT_STRONGBOX_INSTANCE_NAME =
+        "android.hardware.security.keymint.IKeyMintDevice/strongbox";
 
 #define INSTANTIATE_REM_PROV_AIDL_TEST(name)                                         \
     GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(name);                             \
@@ -184,9 +188,15 @@
         }
         ASSERT_NE(provisionable_, nullptr);
         auto status = provisionable_->getHardwareInfo(&rpcHardwareInfo);
-        if (GetParam() == RKP_VM_INSTANCE_NAME &&
-            status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
-            GTEST_SKIP() << "The RKP VM is not supported on this system.";
+        if (GetParam() == RKP_VM_INSTANCE_NAME) {
+            if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
+                GTEST_SKIP() << "The RKP VM is not supported on this system.";
+            }
+            int apiLevel = get_vsr_api_level();
+            if (apiLevel < __ANDROID_API_V__) {
+                GTEST_SKIP() << "The RKP VM is supported only on V+ devices. Vendor API level: "
+                             << apiLevel;
+            }
         }
         ASSERT_TRUE(status.isOk());
     }
@@ -230,6 +240,37 @@
     }
 }
 
+/**
+ * Verify that the default implementation supports DICE if there is a StrongBox KeyMint instance
+ * on the device.
+ */
+// @VsrTest = 3.10-015
+TEST(NonParameterizedTests, requireDiceOnDefaultInstanceIfStrongboxPresent) {
+    int vsr_api_level = get_vsr_api_level();
+    if (vsr_api_level < 35) {
+        GTEST_SKIP() << "Applies only to VSR API level 35 or newer, this device is: "
+                     << vsr_api_level;
+    }
+
+    if (!AServiceManager_isDeclared(KEYMINT_STRONGBOX_INSTANCE_NAME.c_str())) {
+        GTEST_SKIP() << "Strongbox is not present on this device.";
+    }
+
+    ::ndk::SpAIBinder binder(AServiceManager_waitForService(DEFAULT_INSTANCE_NAME.c_str()));
+    std::shared_ptr<IRemotelyProvisionedComponent> rpc =
+            IRemotelyProvisionedComponent::fromBinder(binder);
+    ASSERT_NE(rpc, nullptr);
+
+    bytevec challenge = randomBytes(64);
+    bytevec csr;
+    auto status = rpc->generateCertificateRequestV2({} /* keysToSign */, challenge, &csr);
+    EXPECT_TRUE(status.isOk()) << status.getDescription();
+
+    auto result = isCsrWithProperDiceChain(csr);
+    ASSERT_TRUE(result) << result.message();
+    ASSERT_TRUE(*result);
+}
+
 using GetHardwareInfoTests = VtsRemotelyProvisionedComponentTests;
 
 INSTANTIATE_REM_PROV_AIDL_TEST(GetHardwareInfoTests);
diff --git a/security/secretkeeper/aidl/vts/Android.bp b/security/secretkeeper/aidl/vts/Android.bp
index b9ce5ce..be07a7b 100644
--- a/security/secretkeeper/aidl/vts/Android.bp
+++ b/security/secretkeeper/aidl/vts/Android.bp
@@ -27,6 +27,7 @@
         "libciborium",
         "libcoset",
         "libdiced_open_dice",
+        "libhex",
         "liblog_rust",
         "libsecretkeeper_client",
     ],
diff --git a/security/secretkeeper/aidl/vts/dice_sample.rs b/security/secretkeeper/aidl/vts/dice_sample.rs
index 97b4789..4ef396a 100644
--- a/security/secretkeeper/aidl/vts/dice_sample.rs
+++ b/security/secretkeeper/aidl/vts/dice_sample.rs
@@ -28,10 +28,11 @@
 use coset::{
     iana, Algorithm, AsCborValue, CborSerializable, CoseKey, KeyOperation, KeyType, Label,
 };
+pub use diced_open_dice::CDI_SIZE;
 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,
+    DiceMode, InputValues, OwnedDiceArtifacts, HASH_SIZE, HIDDEN_SIZE,
 };
 use log::error;
 use secretkeeper_client::dice::OwnedDiceArtifactsWithExplicitKey;
@@ -110,12 +111,36 @@
 /// The `security_version` is included in the Android certificate as well as each subcomponent
 /// of AVB certificate.
 pub fn make_explicit_owned_dice(security_version: u64) -> OwnedDiceArtifactsWithExplicitKey {
-    let dice = make_sample_bcc_and_cdis(security_version);
+    make_explicit_owned_dice_for_uds(security_version, UDS)
+}
+
+/// Makes a DICE chain (BCC) from the sample input for the given UDS.
+pub fn make_explicit_owned_dice_for_uds(
+    security_version: u64,
+    uds: &[u8; CDI_SIZE],
+) -> OwnedDiceArtifactsWithExplicitKey {
+    let dice = make_sample_bcc_and_cdis(security_version, uds, Subcomponents::Minimal);
     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();
+/// Makes an XXL DICE chain.
+pub fn make_large_explicit_owned_dice(security_version: u64) -> OwnedDiceArtifactsWithExplicitKey {
+    let dice = make_sample_bcc_and_cdis(security_version, UDS, Subcomponents::CompOs);
+    OwnedDiceArtifactsWithExplicitKey::from_owned_artifacts(dice).unwrap()
+}
+
+/// Indicate which subcomponent DICE information to include.
+enum Subcomponents {
+    Minimal,
+    CompOs,
+}
+
+fn make_sample_bcc_and_cdis(
+    security_version: u64,
+    uds: &[u8; CDI_SIZE],
+    subcomponents: Subcomponents,
+) -> 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();
@@ -136,18 +161,16 @@
         DiceMode::kDiceModeNormal,
         HIDDEN_ABL,
     );
-    let (cdi_values, cert) = retry_dice_main_flow(UDS, UDS, &input_values).unwrap();
+    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_desc = cbor!({
-        COMPONENT_NAME => "AVB",
-        COMPONENT_VERSION => 1,
-        COMPONENT_RESETTABLE => null,
-        SUBCOMPONENT_DESCRIPTORS => [
+    let subcomponents = match subcomponents {
+        Subcomponents::CompOs => compos_subcomponent_descriptors(),
+        Subcomponents::Minimal => cbor!([
             {
                 SUBCOMPONENT_NAME => "sub_1",
                 SUBCOMPONENT_SECURITY_VERSION => security_version,
@@ -160,7 +183,14 @@
                 SUBCOMPONENT_CODE_HASH => b"xoxo",
                 SUBCOMPONENT_AUTHORITY_HASH => b"oxox",
             }
-        ]
+        ])
+        .unwrap(),
+    };
+    let config_desc = cbor!({
+        COMPONENT_NAME => "AVB",
+        COMPONENT_VERSION => 1,
+        COMPONENT_RESETTABLE => null,
+        SUBCOMPONENT_DESCRIPTORS => subcomponents,
     })
     .unwrap()
     .to_vec()
@@ -206,3 +236,177 @@
     )
     .unwrap()
 }
+
+fn compos_subcomponent_descriptors() -> Value {
+    // Subcomponent descriptors taken from a CompOS chain.
+    cbor!([
+        {
+            SUBCOMPONENT_NAME => "apk:com.android.compos.payload",
+            SUBCOMPONENT_SECURITY_VERSION => 34,
+            SUBCOMPONENT_CODE_HASH => hex::decode("9f9a7ca6367a602ee8aeb83c783ae37d1028e4e7fe7492c53ca6b0ac3a5a4918").unwrap(),
+            SUBCOMPONENT_AUTHORITY_HASH => hex::decode("5216ccb62004c4534f35c780ad7c582f4ee528371e27d4151f0553325de9ccbe6b34ec4233f5f640703581053abfea303977272d17958704d89b7711292a4569").unwrap(),
+        },
+        {
+            SUBCOMPONENT_NAME => "apk:com.android.security.fsverity_metadata.system",
+            SUBCOMPONENT_SECURITY_VERSION => 34,
+            SUBCOMPONENT_CODE_HASH => hex::decode("c5f0a71179daa76d5897e391ea882a2f22911b5c2c81794ed6bcd2366dfc6474").unwrap(),
+            SUBCOMPONENT_AUTHORITY_HASH => hex::decode("5216ccb62004c4534f35c780ad7c582f4ee528371e27d4151f0553325de9ccbe6b34ec4233f5f640703581053abfea303977272d17958704d89b7711292a4569").unwrap(),
+        },
+        {
+            SUBCOMPONENT_NAME => "apk:com.android.security.fsverity_metadata.system_ext",
+            SUBCOMPONENT_SECURITY_VERSION => 34,
+            SUBCOMPONENT_CODE_HASH => hex::decode("d043740bc1b45ef8eecb093714321f458f1df17e4d76652a02f3b6c038da8305").unwrap(),
+            SUBCOMPONENT_AUTHORITY_HASH => hex::decode("5216ccb62004c4534f35c780ad7c582f4ee528371e27d4151f0553325de9ccbe6b34ec4233f5f640703581053abfea303977272d17958704d89b7711292a4569").unwrap(),
+        },
+        {
+            SUBCOMPONENT_NAME => "apex:com.android.adbd",
+            SUBCOMPONENT_SECURITY_VERSION => 990090000,
+            SUBCOMPONENT_CODE_HASH => hex::decode("fa4d9b37ff0b534c02865357cce0e2fb5e39a00da00880b438de9a8dd13e79f7").unwrap(),
+            SUBCOMPONENT_AUTHORITY_HASH => hex::decode("4df2b359bfe246a1301166dfa9d9a74ae7c11eebe2b6edc360fcc7630974533c4ac28b216af7af3c8c88de2869d0f7b043872eaf75964e311c10bc1beb1cb89c").unwrap(),
+        },
+        {
+            SUBCOMPONENT_NAME => "apex:com.android.adservices",
+            SUBCOMPONENT_SECURITY_VERSION => 990090000,
+            SUBCOMPONENT_CODE_HASH => hex::decode("debbb6f029c92dcb23b8589b751e945855bdff2cb903fed1e8f9f3ee4740bc00").unwrap(),
+            SUBCOMPONENT_AUTHORITY_HASH => hex::decode("2f85397ad0e9c7e7afa3add6c18d18a1a2b9501d2dc51f481ae57fa789f381228ca905459e871b5bfcb300e5a101260ffb6bf58a920e6b7dfc17941ab7a565c4").unwrap(),
+        },
+        {
+            SUBCOMPONENT_NAME => "apex:com.android.appsearch",
+            SUBCOMPONENT_SECURITY_VERSION => 990090000,
+            SUBCOMPONENT_CODE_HASH => hex::decode("44dd279b861339cfcf92d55b7d4aa1cc21a856a8b0a0bf1bfe66574fdd681194").unwrap(),
+            SUBCOMPONENT_AUTHORITY_HASH => hex::decode("e326a8d1cf4a3b18b45c530e153bd310b9bff04949e37a8886b526dc546e2baf403c3384fef01c18341b3e5de0566c294c8373aa8f7b92e07dd9c938a96f7e35").unwrap(),
+        },
+        {
+            SUBCOMPONENT_NAME => "apex:com.android.art",
+            SUBCOMPONENT_SECURITY_VERSION => 990090000,
+            SUBCOMPONENT_CODE_HASH => hex::decode("e4a8eae20cee7fd98dd202b32321a5feaae73cf125b880763d810edbf6b394dd").unwrap(),
+            SUBCOMPONENT_AUTHORITY_HASH => hex::decode("ed255ae9ea98826f3f3a966849f0aaaf356d140c766a869048016e0ba10141af039fec5c53658ddebdad9c2339587c5ef5487bde89237ca79802238d91aebba8").unwrap(),
+        },
+        {
+            SUBCOMPONENT_NAME => "apex:com.android.btservices",
+            SUBCOMPONENT_SECURITY_VERSION => 990090000,
+            SUBCOMPONENT_CODE_HASH => hex::decode("d7aa86dfdf92e662d2210cd2b3ad4e4522c917e9e287268363aa90e20f9ae16c").unwrap(),
+            SUBCOMPONENT_AUTHORITY_HASH => hex::decode("a0d577d4a56cfad09aaa7abcd2355cd78872df85672f2faf9ac2fdf15c06147394e704c7473f28bed737803581a3d097275cc26d8095a4a896ee76167f9ee40e").unwrap(),
+        },
+        {
+            SUBCOMPONENT_NAME => "apex:com.android.compos",
+            SUBCOMPONENT_SECURITY_VERSION => 2,
+            SUBCOMPONENT_CODE_HASH => hex::decode("64c4b31c7de83ecb31632aff1fb6433741b5f870b1d9f258673787715b83e785").unwrap(),
+            SUBCOMPONENT_AUTHORITY_HASH => hex::decode("3e2691174d210a6479c586ef655ee5af1ee53ff960f6291d7b695237d56f73027c5cb30a6d6df07848a0c0b65b6d697e31ed98ba0711a0cb39002c4186b4ad95").unwrap(),
+        },
+        {
+            SUBCOMPONENT_NAME => "apex:com.android.configinfrastructure",
+            SUBCOMPONENT_SECURITY_VERSION => 990090000,
+            SUBCOMPONENT_CODE_HASH => hex::decode("69d589bcd38decdee64f5bdd359af461e95a5f9c9cf7e6c767db25f0ab81b5e7").unwrap(),
+            SUBCOMPONENT_AUTHORITY_HASH => hex::decode("13cde315955806bb1f9ec00714166255148e6baa43f3473bcbe5082bc35d3525605470a6c7ac208337dd79d2250e4adcd4f89f09036f2cbbb553f387c622be07").unwrap(),
+        },
+        {
+            SUBCOMPONENT_NAME => "apex:com.android.conscrypt",
+            SUBCOMPONENT_SECURITY_VERSION => 990090000,
+            SUBCOMPONENT_CODE_HASH => hex::decode("a91183cc1c12e2d0c9f2b0cd9c97c4592246035c2b07f080d9921fa57ed42900").unwrap(),
+            SUBCOMPONENT_AUTHORITY_HASH => hex::decode("4d76d909dd77ee0f8299880b27215a327dda261fb4504125d730fc4f78b105b0947c4103b4bcf49ea9a44d6d04e3c4d385d9ca02a2ef43b8850fca0d91b11e57").unwrap(),
+        },
+        {
+            SUBCOMPONENT_NAME => "apex:com.android.devicelock",
+            SUBCOMPONENT_SECURITY_VERSION => 1,
+            SUBCOMPONENT_CODE_HASH => hex::decode("85f7bdd116f9c2069f5bfb0039ec1ea165ccaaa517f340440b8eb8f58d044fa8").unwrap(),
+            SUBCOMPONENT_AUTHORITY_HASH => hex::decode("2949543df13e57c5dfa49aa3ade0c450514432a7e2710bbb1fd4b768e158bbadf17be6f1446be7d321960e13f2f10f648d2ee551ec41475169e629ed71f2cc5f").unwrap(),
+        },
+        {
+            SUBCOMPONENT_NAME => "apex:com.android.healthfitness",
+            SUBCOMPONENT_SECURITY_VERSION => 990090000,
+            SUBCOMPONENT_CODE_HASH => hex::decode("ad38a1e8186cb62ac75e47592496582ef7ab26b3f0dd405340cee2fe8d73dc47").unwrap(),
+            SUBCOMPONENT_AUTHORITY_HASH => hex::decode("2273e8a7113a103d2b7461c9ae8149ba4cfabe5edeb48b1703c4b4f2fab1a4e9c5a66bf75a9f2063f27df6390d310f1091e9511ad2e41baae822fde1fb022f4f").unwrap(),
+        },
+        {
+            SUBCOMPONENT_NAME => "apex:com.android.i18n",
+            SUBCOMPONENT_SECURITY_VERSION => 1,
+            SUBCOMPONENT_CODE_HASH => hex::decode("2107e7972afeb70f6653643aebf5e0198c5bf13d71b4c792960f78344bf7e439").unwrap(),
+            SUBCOMPONENT_AUTHORITY_HASH => hex::decode("668ac67e4b8a00bf5863ee175db92aefa64138eccbc86a7f528d6fdabec3443e781f4f4c5c3db123994d45696e13e07aa207da25bc70709dcaba3a740b679f7b").unwrap(),
+        },
+        {
+            SUBCOMPONENT_NAME => "apex:com.android.ipsec",
+            SUBCOMPONENT_SECURITY_VERSION => 990090000,
+            SUBCOMPONENT_CODE_HASH => hex::decode("dfc3ff28eaf429535b651bdb675fbc6d6a7e2834919c02ce56bc20f736562c2c").unwrap(),
+            SUBCOMPONENT_AUTHORITY_HASH => hex::decode("8ae0b721d55d3d3f80a1bce694dd85fbbbbba990b0479864c694a47912d4f42a60ca328f76b462a6624b89d1d8b1212fe06fc7749e2c2b0cccd9d86f1058dee2").unwrap(),
+        },
+        {
+            SUBCOMPONENT_NAME => "apex:com.android.media",
+            SUBCOMPONENT_SECURITY_VERSION => 990090000,
+            SUBCOMPONENT_CODE_HASH => hex::decode("cb1288d098962dbe0d069e78512138e6031d4f1bb4052fea30866f0d8226c541").unwrap(),
+            SUBCOMPONENT_AUTHORITY_HASH => hex::decode("7a374d48802077d032daa41fb60123e470808d4bae5d7fd87e6f6e6039fee67cf9cb37b960edb5014247ffc57f4673a0d6a52a07e477c9c7d570594ce0a867af").unwrap(),
+        },
+        {
+            SUBCOMPONENT_NAME => "apex:com.android.mediaprovider",
+            SUBCOMPONENT_SECURITY_VERSION => 990090000,
+            SUBCOMPONENT_CODE_HASH => hex::decode("bf343bfbe145a81974f05244b523b47d5ecc606c534a65723bb5b7a5f40ab4e1").unwrap(),
+            SUBCOMPONENT_AUTHORITY_HASH => hex::decode("272c2cbde4cdd914978246bf6150e30db54f603ee5602a1a48e0b31aa9569a533ff9eedab10bcb852c988d1d46f09de28fc2f0596b070adc38fed9edc12270d8").unwrap(),
+        },
+        {
+            SUBCOMPONENT_NAME => "apex:com.android.nfcservices",
+            SUBCOMPONENT_SECURITY_VERSION => 990090000,
+            SUBCOMPONENT_CODE_HASH => hex::decode("ff0caa7f86efd179fda394b387e2ef875272d7035138ca1309229fe80dc3dd3a").unwrap(),
+            SUBCOMPONENT_AUTHORITY_HASH => hex::decode("26af902c55fa92240fa15f060849e29803775249b5d53a02f7c4a57b039c0be6570809c2d81d63d6d6a923bc58ace14b05d64dcf0f9fdce0f99e6ef18ea292b4").unwrap(),
+        },
+        {
+            SUBCOMPONENT_NAME => "apex:com.android.ondevicepersonalization",
+            SUBCOMPONENT_SECURITY_VERSION => 990090000,
+            SUBCOMPONENT_CODE_HASH => hex::decode("9a339ac3a29bf2852dde9318575799c23c144515cca129eed5055a589d8da33d").unwrap(),
+            SUBCOMPONENT_AUTHORITY_HASH => hex::decode("96c20dbd0a57864a6aa055ebc5611da744c969d37838e7c75712c3f6f37bdbf9eda0dfc240d8f545f9b6fb500edd6d8ca5f48a70acde9a7121e545187df8705d").unwrap(),
+        },
+        {
+            SUBCOMPONENT_NAME => "apex:com.android.os.statsd",
+            SUBCOMPONENT_SECURITY_VERSION => 990090000,
+            SUBCOMPONENT_CODE_HASH => hex::decode("523e068e66be46eb3789d82aecfba7f58287a9cbc4bcf3c45fd32291db3da048").unwrap(),
+            SUBCOMPONENT_AUTHORITY_HASH => hex::decode("431db3773485c432e706fc8040373a373f0dac5a96ba0150ac813d80c00f351496dfe789c6c88dd673aaf642a64c0e09754fb0bb2c12bb12b62968427f9d3f87").unwrap(),
+        },
+        {
+            SUBCOMPONENT_NAME => "apex:com.android.permission",
+            SUBCOMPONENT_SECURITY_VERSION => 990090000,
+            SUBCOMPONENT_CODE_HASH => hex::decode("2f3de015ab80900579db7935d425ee228ea597ac07ef47b8e7e6366a91d93be9").unwrap(),
+            SUBCOMPONENT_AUTHORITY_HASH => hex::decode("0bcf05c42dcff0d2f5dc151369681179b0489749b27c5d2dff9ce69c990e7f299fd9782be1d46698101758f39bf18804e1043e3bd8e3da6c3554a6cccc34a891").unwrap(),
+        },
+        {
+            SUBCOMPONENT_NAME => "apex:com.android.rkpd",
+            SUBCOMPONENT_SECURITY_VERSION => 990090000,
+            SUBCOMPONENT_CODE_HASH => hex::decode("acb4c10a0f01065b787cf8349e7f371d91dda352d51a25e08fca229375de2ef1").unwrap(),
+            SUBCOMPONENT_AUTHORITY_HASH => hex::decode("56854df8c24c9670413396120c89bf18d5f6e2d5ade48b14a102be3bb29751fad1da3b754588da27f33ec5187258a8ec806a323ecf3e99cf8f051499e8cc8b5b").unwrap(),
+        },
+        {
+            SUBCOMPONENT_NAME => "apex:com.android.scheduling",
+            SUBCOMPONENT_SECURITY_VERSION => 990090000,
+            SUBCOMPONENT_CODE_HASH => hex::decode("b802e45078bbff1648ef97c38743005983d25ba47261b9e9fb7c758defec920e").unwrap(),
+            SUBCOMPONENT_AUTHORITY_HASH => hex::decode("d8e3c0f8501b639074c003fd1a45424756a91a79f326e2b50a66f39c9ced5bc0cd0811f6055b5f2c8330a845f95bd26d6f6d3962e3436f65fdfda3343f26cb69").unwrap(),
+        },
+        {
+            SUBCOMPONENT_NAME => "apex:com.android.sdkext",
+            SUBCOMPONENT_SECURITY_VERSION => 990090000,
+            SUBCOMPONENT_CODE_HASH => hex::decode("fb2a3d5437766135838d7ce078870a403ae6929937d58ec8b40182057587af21").unwrap(),
+            SUBCOMPONENT_AUTHORITY_HASH => hex::decode("6bdc69078b58bc524648ce606c8050ffd6a88a8e169c23cbce7a6cfc444cde58a2a9a77968e3f1454a0eaeb0ad00bb846e5447473b0730bbd28e0b71189af808").unwrap(),
+        },
+        {
+            SUBCOMPONENT_NAME => "apex:com.android.tethering",
+            SUBCOMPONENT_SECURITY_VERSION => 990090000,
+            SUBCOMPONENT_CODE_HASH => hex::decode("d352cfd92179ec854ae30c9ce54562b1a31f01738524ba11ceae10db6207c995").unwrap(),
+            SUBCOMPONENT_AUTHORITY_HASH => hex::decode("1af6fe33f7035ea7a4353a02ed40fd7b72f2668b58794d2bbccce8b61aa9878eb817cdcc813e1eab1a2f287c2f15e8b2bb620cf024e55210a659f27c3064bd7f").unwrap(),
+        },
+        {
+            SUBCOMPONENT_NAME => "apex:com.android.uwb",
+            SUBCOMPONENT_SECURITY_VERSION => 990090000,
+            SUBCOMPONENT_CODE_HASH => hex::decode("bfc970bc51670ade054b5fcafa6ed9fb90f0aa14168ea5a97d20d5b236ffac00").unwrap(),
+            SUBCOMPONENT_AUTHORITY_HASH => hex::decode("993f35bbdbad1db72f17382058b10020bb1c932cef8f540c240cb26e867ea03bab4ade22f41823a8be3ea5e82306f47368e294e153328ba38ad35b3aafabdf84").unwrap(),
+        },
+        {
+            SUBCOMPONENT_NAME => "apex:com.android.virt",
+            SUBCOMPONENT_SECURITY_VERSION => 2,
+            SUBCOMPONENT_CODE_HASH => hex::decode("efff05a5354236dc3efca323bf25d0488f7c8212a393349f9a7d329f7db88e73").unwrap(),
+            SUBCOMPONENT_AUTHORITY_HASH => hex::decode("a279d6d530ae0cea2b2f2c1d3dee1e5b59dbdac861e137995eaf44b1a57c5cfb02b7892f00e7fe647756fd2cfef66e74350b517c4d79463c6e6a6f96eb01693b").unwrap(),
+        },
+        {
+            SUBCOMPONENT_NAME => "apex:com.android.wifi",
+            SUBCOMPONENT_SECURITY_VERSION => 990090000,
+            SUBCOMPONENT_CODE_HASH => hex::decode("2d6db7bcfb436ff9a8f22788e4666071d18e03063422d5b58e378530d304e0af").unwrap(),
+            SUBCOMPONENT_AUTHORITY_HASH => hex::decode("29b3ef73b51aff982b3136c944add0ee40a12eba762ca69ae9646c4f08fd8145e593c8b1fe4208e52f87e0735134c573612ec0566ebbf5ab08b2054a5954b599").unwrap(),
+        },
+    ]).unwrap()
+}
diff --git a/security/secretkeeper/aidl/vts/secretkeeper_test_client.rs b/security/secretkeeper/aidl/vts/secretkeeper_test_client.rs
index 7c00aa9..595dc7a 100644
--- a/security/secretkeeper/aidl/vts/secretkeeper_test_client.rs
+++ b/security/secretkeeper/aidl/vts/secretkeeper_test_client.rs
@@ -36,7 +36,7 @@
 use secretkeeper_test::{
     AUTHORITY_HASH, MODE, CONFIG_DESC, SECURITY_VERSION, SUBCOMPONENT_AUTHORITY_HASH,
     SUBCOMPONENT_DESCRIPTORS, SUBCOMPONENT_SECURITY_VERSION,
-    dice_sample::make_explicit_owned_dice
+    dice_sample::{make_explicit_owned_dice_for_uds, make_explicit_owned_dice, make_large_explicit_owned_dice, CDI_SIZE}
 };
 use std::fs;
 use std::path::Path;
@@ -289,9 +289,22 @@
     }
 }
 
-// Assert that the error is EntryNotFound
+// Assert that the error is `EntryNotFound`.
 fn assert_entry_not_found(res: Result<Secret, Error>) {
-    assert!(matches!(res.unwrap_err(), Error::SecretkeeperError(SecretkeeperError::EntryNotFound)))
+    assert_result_matches(res, SecretkeeperError::EntryNotFound)
+}
+
+// Assert that the error is `DicePolicyError`.
+fn assert_dice_policy_error(res: Result<Secret, Error>) {
+    assert_result_matches(res, SecretkeeperError::DicePolicyError)
+}
+
+fn assert_result_matches(res: Result<Secret, Error>, want: SecretkeeperError) {
+    match res {
+        Err(Error::SecretkeeperError(e)) if e == want => {}
+        Err(got) => panic!("unexpected error {got:?}, expected {want:?}"),
+        Ok(_) => panic!("unexpected success instead of {want:?}"),
+    }
 }
 
 /// Construct a sealing policy on the dice chain. This method uses the following set of
@@ -445,6 +458,42 @@
     assert_entry_not_found(sk_client.get(&ID_NOT_STORED));
 }
 
+/// A secret stored in one session should be accessible from a different session
+/// as long as the client has the same identity.
+#[rdroidtest(get_instances())]
+fn secretkeeper_get_secret_across_sessions_with_same_identity(instance: String) {
+    // Store a secret with one session.  Note that we need to hang on to the
+    // test client because it auto-deletes entries on drop.
+    let mut sk_client1 = SkClient::new(&instance).unwrap();
+    sk_client1.store(&ID_EXAMPLE, &SECRET_EXAMPLE).unwrap();
+    assert_eq!(sk_client1.get(&ID_EXAMPLE).unwrap(), SECRET_EXAMPLE);
+
+    // Retrieve the secret using a different session (that has the same identity).
+    let mut sk_client2 = SkClient::new(&instance).unwrap();
+    assert_eq!(sk_client2.get(&ID_EXAMPLE).unwrap(), SECRET_EXAMPLE);
+}
+
+/// A secret stored in one session should not be accessible from a different session
+/// if the client has a different identity.
+#[rdroidtest(get_instances())]
+fn secretkeeper_no_secret_across_sessions_with_different_identity(instance: String) {
+    // Store a secret with one session.  Note that we need to hang on to the
+    // test client because it auto-deletes entries on drop.
+    let mut sk_client1 = SkClient::new(&instance).unwrap();
+    sk_client1.store(&ID_EXAMPLE, &SECRET_EXAMPLE).unwrap();
+    assert_eq!(sk_client1.get(&ID_EXAMPLE).unwrap(), SECRET_EXAMPLE);
+
+    // Fail to retrieve the secret using a different session that has a different identity.
+    pub const ALT_UDS: &[u8; CDI_SIZE] = &[
+        0x66, 0x4f, 0xab, 0xa9, 0xa5, 0xad, 0x0f, 0x5e, 0x15, 0xc3, 0x12, 0xf7, 0x77, 0x45, 0xfa,
+        0x56, 0x18, 0x6a, 0xa6, 0x34, 0xb6, 0x7c, 0x82, 0x7b, 0x89, 0x4c, 0xc5, 0x52, 0xd3, 0x27,
+        0x36, 0x8e,
+    ];
+    let alt_identity = make_explicit_owned_dice_for_uds(5, ALT_UDS);
+    let mut sk_client2 = SkClient::with_identity(&instance, alt_identity).unwrap();
+    assert_dice_policy_error(sk_client2.get(&ID_EXAMPLE));
+}
+
 #[rdroidtest(get_instances())]
 fn secretkeeper_store_delete_ids(instance: String) {
     let mut sk_client = SkClient::new(&instance).unwrap();
@@ -522,6 +571,69 @@
     assert_entry_not_found(sk_client.get(&ID_NOT_STORED));
 }
 
+// This tests creates lots of sessions one after another, to confirm that the Secretkeeper
+// instance doesn't have unbounded internal state. (Instead, it should drop older sessions
+// and the clients using those sessions would need to re-establish a new session.)
+#[rdroidtest(get_instances())]
+fn secretkeeper_many_sessions_serial(instance: String) {
+    const SESSION_COUNT: usize = 32;
+    let mut sk_clients = Vec::new();
+    for idx in 0..SESSION_COUNT {
+        let identity = make_large_explicit_owned_dice(5);
+        let mut sk_client = SkClient::with_identity(&instance, identity)
+            .expect(&format!("failed to establish session {idx}"));
+        sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE).unwrap();
+        sk_clients.push(sk_client);
+    }
+}
+
+// This tests creates lots of sessions in parallel.  Some of these session are expected
+// to fail, but the Secretkeeper TA should survive the experience.
+#[rdroidtest(get_instances())]
+fn secretkeeper_many_sessions_parallel(instance: String) {
+    const SESSION_COUNT: usize = 32;
+
+    let mut handles = Vec::<std::thread::JoinHandle<()>>::new();
+    for idx in 0..SESSION_COUNT {
+        let instance = instance.clone();
+        handles.push(std::thread::spawn(move || {
+            // In each thread, create a session and use it.  This may (legitimately) fail at any
+            // moment.
+            let _result = use_sk_may_fail(instance, idx);
+        }));
+    }
+
+    // Wait for all activity to quiesce.
+    for handle in handles {
+        let _result = handle.join();
+    }
+
+    // Now that all the parallel activity is done, should still be able to interact with
+    // Secretkeeper.
+    let mut sk_client = SkClient::new(&instance).unwrap();
+    sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE).unwrap();
+    assert_eq!(sk_client.get(&ID_EXAMPLE).unwrap(), SECRET_EXAMPLE);
+
+    // Remove any IDs that might have been stored in the test.
+    for idx in 0..SESSION_COUNT {
+        let mut id = ID_EXAMPLE.clone();
+        id.0[0] = idx as u8;
+        sk_client.delete(&[&id]);
+    }
+}
+
+fn use_sk_may_fail(instance: String, idx: usize) -> Result<(), Error> {
+    let identity = make_large_explicit_owned_dice(5);
+    let mut sk_client = SkClient::with_identity(&instance, identity)?;
+    let mut id = ID_EXAMPLE.clone();
+    id.0[0] = idx as u8;
+
+    sk_client.store(&id, &SECRET_EXAMPLE)?;
+    let result = sk_client.get(&id)?;
+    assert_eq!(result, SECRET_EXAMPLE);
+    Ok(())
+}
+
 // This test checks that Secretkeeper uses the expected [`RequestSeqNum`] as aad while
 // decrypting requests and the responses are encrypted with correct [`ResponseSeqNum`] for the
 // first few messages.
@@ -634,10 +746,7 @@
     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).unwrap();
-    assert!(matches!(
-        sk_client_downgraded.get(&ID_EXAMPLE).unwrap_err(),
-        Error::SecretkeeperError(SecretkeeperError::DicePolicyError)
-    ));
+    assert_dice_policy_error(sk_client_downgraded.get(&ID_EXAMPLE));
 
     // Now get the secret with the later version, and upgrade the sealing policy along the way.
     let sealing_policy =
@@ -648,10 +757,7 @@
     );
 
     // The original version of the client should no longer be able to retrieve the secret.
-    assert!(matches!(
-        sk_client_original.get(&ID_EXAMPLE).unwrap_err(),
-        Error::SecretkeeperError(SecretkeeperError::DicePolicyError)
-    ));
+    assert_dice_policy_error(sk_client_original.get(&ID_EXAMPLE));
 }
 
 // This test checks that the identity of Secretkeeper (in context of AuthGraph key exchange) is
diff --git a/security/sharedsecret/aidl/android/hardware/security/sharedsecret/ISharedSecret.aidl b/security/sharedsecret/aidl/android/hardware/security/sharedsecret/ISharedSecret.aidl
index eca8d87..b0dd284 100644
--- a/security/sharedsecret/aidl/android/hardware/security/sharedsecret/ISharedSecret.aidl
+++ b/security/sharedsecret/aidl/android/hardware/security/sharedsecret/ISharedSecret.aidl
@@ -81,14 +81,9 @@
      *           defined in the standard.  The counter is prefixed and length L appended, as shown
      *           in the construction on page 12 of the standard.  The label string is UTF-8 encoded.
      *
-     *     ``K'' is a pre-established shared secret, set up during factory reset.  The mechanism for
-     *           establishing this shared secret is implementation-defined.Any method of securely
-     *           establishing K that ensures that an attacker cannot obtain or derive its value is
-     *           acceptable.
-     *
-     *           CRITICAL SECURITY REQUIREMENT: All keys created by a IKeymintDevice instance must
-     *           be cryptographically bound to the value of K, such that establishing a new K
-     *           permanently destroys them.
+     *     ``K'' is a pre-established shared secret.  The mechanism for establishing this shared
+     *           secret is implementation-defined.  Any method of securely establishing K that
+     *           ensures that an attacker cannot obtain or derive its value is acceptable.
      *
      *     ``||'' represents concatenation.
      *
diff --git a/sensors/OWNERS b/sensors/OWNERS
index e7ebd3e..5017a9a 100644
--- a/sensors/OWNERS
+++ b/sensors/OWNERS
@@ -1,5 +1,3 @@
 # Bug component: 62965
 
-arthuri@google.com
 bduddie@google.com
-stange@google.com
diff --git a/soundtrigger/2.0/Android.bp b/soundtrigger/2.0/Android.bp
index 996105c..828b9ec 100644
--- a/soundtrigger/2.0/Android.bp
+++ b/soundtrigger/2.0/Android.bp
@@ -12,9 +12,6 @@
 hidl_interface {
     name: "android.hardware.soundtrigger@2.0",
     root: "android.hardware",
-    vndk: {
-        enabled: true,
-    },
     srcs: [
         "types.hal",
         "ISoundTriggerHw.hal",
diff --git a/soundtrigger/2.0/default/Android.bp b/soundtrigger/2.0/default/Android.bp
index 8236e30..2cbf041 100644
--- a/soundtrigger/2.0/default/Android.bp
+++ b/soundtrigger/2.0/default/Android.bp
@@ -26,9 +26,6 @@
     name: "android.hardware.soundtrigger@2.0-core",
     defaults: ["hidl_defaults"],
     vendor_available: true,
-    vndk: {
-        enabled: true,
-    },
     srcs: [
         "SoundTriggerHalImpl.cpp",
     ],
diff --git a/staging/security/OWNERS b/staging/security/OWNERS
new file mode 100644
index 0000000..ba4df18
--- /dev/null
+++ b/staging/security/OWNERS
@@ -0,0 +1,8 @@
+armellel@google.com
+arve@android.com
+swillden@google.com
+paulcrowley@google.com
+hasinitg@google.com
+cukie@google.com
+westoncarvalho@google.com
+oarbildo@google.com
diff --git a/staging/security/see/hwcrypto/aidl/Android.bp b/staging/security/see/hwcrypto/aidl/Android.bp
new file mode 100644
index 0000000..3e7ee9e
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/Android.bp
@@ -0,0 +1,29 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+aidl_interface {
+    name: "android.hardware.security.see",
+    unstable: false,
+    host_supported: true,
+    srcs: [
+        "android/hardware/security/see/hwcrypto/*.aidl",
+        "android/hardware/security/see/hwcrypto/types/*.aidl",
+    ],
+    backend: {
+        java: {
+            enabled: false,
+        },
+        cpp: {
+            enabled: false,
+        },
+        rust: {
+            enabled: true,
+        },
+    },
+}
diff --git a/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/CryptoOperation.aidl b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/CryptoOperation.aidl
new file mode 100644
index 0000000..0a7e7a2
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/CryptoOperation.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright 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.security.see.hwcrypto;
+union CryptoOperation {
+  android.hardware.security.see.hwcrypto.MemoryBufferParameter setMemoryBuffer;
+  android.hardware.security.see.hwcrypto.OperationParameters setOperationParameters;
+  android.hardware.security.see.hwcrypto.PatternParameters setPattern;
+  android.hardware.security.see.hwcrypto.types.OperationData copyData;
+  android.hardware.security.see.hwcrypto.types.OperationData aadInput;
+  android.hardware.security.see.hwcrypto.types.OperationData dataInput;
+  android.hardware.security.see.hwcrypto.types.OperationData dataOutput;
+  @nullable android.hardware.security.see.hwcrypto.types.Void finish;
+  @nullable android.hardware.security.see.hwcrypto.types.Void destroyContext;
+}
diff --git a/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/CryptoOperationErrorAdditionalInfo.aidl b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/CryptoOperationErrorAdditionalInfo.aidl
new file mode 100644
index 0000000..05780e1
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/CryptoOperationErrorAdditionalInfo.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright 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.security.see.hwcrypto;
+parcelable CryptoOperationErrorAdditionalInfo {
+  long failingCommandIndex;
+}
diff --git a/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/CryptoOperationResult.aidl b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/CryptoOperationResult.aidl
new file mode 100644
index 0000000..1088e27
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/CryptoOperationResult.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright 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.security.see.hwcrypto;
+parcelable CryptoOperationResult {
+  @nullable android.hardware.security.see.hwcrypto.ICryptoOperationContext context;
+}
diff --git a/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/CryptoOperationSet.aidl b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/CryptoOperationSet.aidl
new file mode 100644
index 0000000..f3b9b43
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/CryptoOperationSet.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright 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.security.see.hwcrypto;
+parcelable CryptoOperationSet {
+  @nullable android.hardware.security.see.hwcrypto.ICryptoOperationContext context;
+  android.hardware.security.see.hwcrypto.CryptoOperation[] operations;
+}
diff --git a/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/ICryptoOperationContext.aidl b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/ICryptoOperationContext.aidl
new file mode 100644
index 0000000..472215f
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/ICryptoOperationContext.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright 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.security.see.hwcrypto;
+interface ICryptoOperationContext {
+}
diff --git a/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/IHwCryptoKey.aidl b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/IHwCryptoKey.aidl
new file mode 100644
index 0000000..7efcdd6
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/IHwCryptoKey.aidl
@@ -0,0 +1,71 @@
+/*
+ * Copyright 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 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.security.see.hwcrypto;
+interface IHwCryptoKey {
+  android.hardware.security.see.hwcrypto.IHwCryptoKey.DiceCurrentBoundKeyResult deriveCurrentDicePolicyBoundKey(in android.hardware.security.see.hwcrypto.IHwCryptoKey.DiceBoundDerivationKey derivationKey);
+  android.hardware.security.see.hwcrypto.IHwCryptoKey.DiceBoundKeyResult deriveDicePolicyBoundKey(in android.hardware.security.see.hwcrypto.IHwCryptoKey.DiceBoundDerivationKey derivationKey, in byte[] dicePolicyForKeyVersion);
+  android.hardware.security.see.hwcrypto.IHwCryptoKey.DerivedKey deriveKey(in android.hardware.security.see.hwcrypto.IHwCryptoKey.DerivedKeyParameters parameters);
+  enum DeviceKeyId {
+    DEVICE_BOUND_KEY,
+    BATCH_KEY,
+  }
+  union DiceBoundDerivationKey {
+    android.hardware.security.see.hwcrypto.IOpaqueKey opaqueKey;
+    android.hardware.security.see.hwcrypto.IHwCryptoKey.DeviceKeyId keyId;
+  }
+  parcelable DiceCurrentBoundKeyResult {
+    android.hardware.security.see.hwcrypto.IOpaqueKey diceBoundKey;
+    byte[] dicePolicyForKeyVersion;
+  }
+  parcelable DiceBoundKeyResult {
+    android.hardware.security.see.hwcrypto.IOpaqueKey diceBoundKey;
+    boolean dicePolicyWasCurrent;
+  }
+  parcelable ClearKeyPolicy {
+    int keySizeBytes;
+  }
+  union DerivedKeyPolicy {
+    android.hardware.security.see.hwcrypto.KeyPolicy opaqueKey;
+    android.hardware.security.see.hwcrypto.IHwCryptoKey.ClearKeyPolicy clearKey;
+  }
+  parcelable DerivedKeyParameters {
+    android.hardware.security.see.hwcrypto.IOpaqueKey derivationKey;
+    android.hardware.security.see.hwcrypto.IHwCryptoKey.DerivedKeyPolicy keyPolicy;
+    byte[] context;
+  }
+  union DerivedKey {
+    byte[] explicitKey = {};
+    android.hardware.security.see.hwcrypto.IOpaqueKey opaque;
+  }
+}
diff --git a/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/IHwCryptoOperations.aidl b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/IHwCryptoOperations.aidl
new file mode 100644
index 0000000..5c26cc2
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/IHwCryptoOperations.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright 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.security.see.hwcrypto;
+interface IHwCryptoOperations {
+  android.hardware.security.see.hwcrypto.CryptoOperationResult[] processCommandList(inout android.hardware.security.see.hwcrypto.CryptoOperationSet[] operations, out android.hardware.security.see.hwcrypto.CryptoOperationErrorAdditionalInfo additionalErrorInfo);
+}
diff --git a/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/IOpaqueKey.aidl b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/IOpaqueKey.aidl
new file mode 100644
index 0000000..9cbf272
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/IOpaqueKey.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 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.security.see.hwcrypto;
+interface IOpaqueKey {
+  byte[] exportWrappedKey(in android.hardware.security.see.hwcrypto.IOpaqueKey wrappingKey);
+  android.hardware.security.see.hwcrypto.KeyPolicy getKeyPolicy();
+  byte[] getPublicKey();
+}
diff --git a/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/KeyPolicy.aidl b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/KeyPolicy.aidl
new file mode 100644
index 0000000..0e3896e
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/KeyPolicy.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 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.security.see.hwcrypto;
+parcelable KeyPolicy {
+  android.hardware.security.see.hwcrypto.types.KeyUse usage;
+  android.hardware.security.see.hwcrypto.types.KeyLifetime keyLifetime = android.hardware.security.see.hwcrypto.types.KeyLifetime.EPHEMERAL;
+  android.hardware.security.see.hwcrypto.types.KeyPermissions[] keyPermissions;
+  boolean keyManagementKey;
+  android.hardware.security.see.hwcrypto.types.KeyType keyType = android.hardware.security.see.hwcrypto.types.KeyType.AES_256_GCM;
+}
diff --git a/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/MemoryBufferParameter.aidl b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/MemoryBufferParameter.aidl
new file mode 100644
index 0000000..d88d5c8
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/MemoryBufferParameter.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 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.security.see.hwcrypto;
+parcelable MemoryBufferParameter {
+  android.hardware.security.see.hwcrypto.MemoryBufferParameter.MemoryBuffer bufferHandle;
+  int sizeBytes;
+  union MemoryBuffer {
+    ParcelFileDescriptor input;
+    ParcelFileDescriptor output;
+  }
+}
diff --git a/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/OperationParameters.aidl b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/OperationParameters.aidl
new file mode 100644
index 0000000..017e51c
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/OperationParameters.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright 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.security.see.hwcrypto;
+union OperationParameters {
+  android.hardware.security.see.hwcrypto.types.SymmetricAuthOperationParameters symmetricAuthCrypto;
+  android.hardware.security.see.hwcrypto.types.SymmetricOperationParameters symmetricCrypto;
+}
diff --git a/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/PatternParameters.aidl b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/PatternParameters.aidl
new file mode 100644
index 0000000..0fd1ee7
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/PatternParameters.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright 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.security.see.hwcrypto;
+parcelable PatternParameters {
+  long numberBlocksProcess;
+  long numberBlocksCopy;
+}
diff --git a/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/AesCipherMode.aidl b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/AesCipherMode.aidl
new file mode 100644
index 0000000..e7501ff
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/AesCipherMode.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright 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.security.see.hwcrypto.types;
+union AesCipherMode {
+  android.hardware.security.see.hwcrypto.types.CipherModeParameters cbc;
+  android.hardware.security.see.hwcrypto.types.CipherModeParameters ctr;
+}
diff --git a/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/AesGcmMode.aidl b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/AesGcmMode.aidl
new file mode 100644
index 0000000..4084abb
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/AesGcmMode.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 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.security.see.hwcrypto.types;
+union AesGcmMode {
+  android.hardware.security.see.hwcrypto.types.AesGcmMode.AesGcmModeParameters gcmTag16;
+  parcelable AesGcmModeParameters {
+    byte[12] nonce;
+  }
+}
diff --git a/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/CipherModeParameters.aidl b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/CipherModeParameters.aidl
new file mode 100644
index 0000000..7a77521
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/CipherModeParameters.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright 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.security.see.hwcrypto.types;
+parcelable CipherModeParameters {
+  byte[16] nonce;
+}
diff --git a/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/HalErrorCode.aidl b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/HalErrorCode.aidl
new file mode 100644
index 0000000..cd8b3c6
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/HalErrorCode.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright 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.security.see.hwcrypto.types;
+parcelable HalErrorCode {
+  const int NO_ERROR = 0;
+  const int GENERIC_ERROR = (-1) /* -1 */;
+  const int BAD_STATE = (-2) /* -2 */;
+  const int UNSUPPORTED = (-3) /* -3 */;
+  const int SERIALIZATION_ERROR = (-4) /* -4 */;
+  const int ALLOCATION_ERROR = (-5) /* -5 */;
+  const int INVALID_KEY = (-6) /* -6 */;
+  const int BAD_PARAMETER = (-7) /* -7 */;
+}
diff --git a/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/KeyLifetime.aidl b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/KeyLifetime.aidl
new file mode 100644
index 0000000..db5964c
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/KeyLifetime.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 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.security.see.hwcrypto.types;
+@Backing(type="byte")
+enum KeyLifetime {
+  EPHEMERAL,
+  HARDWARE,
+  PORTABLE,
+}
diff --git a/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/KeyPermissions.aidl b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/KeyPermissions.aidl
new file mode 100644
index 0000000..ea3a173
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/KeyPermissions.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 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.security.see.hwcrypto.types;
+enum KeyPermissions {
+  ALLOW_EPHEMERAL_KEY_WRAPPING,
+  ALLOW_HARDWARE_KEY_WRAPPING,
+  ALLOW_PORTABLE_KEY_WRAPPING,
+}
diff --git a/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/KeyType.aidl b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/KeyType.aidl
new file mode 100644
index 0000000..59b83c4
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/KeyType.aidl
@@ -0,0 +1,55 @@
+/*
+ * Copyright 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.security.see.hwcrypto.types;
+enum KeyType {
+  AES_128_CBC_NO_PADDING,
+  AES_128_CBC_PKCS7_PADDING,
+  AES_128_CTR,
+  AES_128_GCM,
+  AES_128_CMAC,
+  AES_256_CBC_NO_PADDING,
+  AES_256_CBC_PKCS7_PADDING,
+  AES_256_CTR,
+  AES_256_GCM,
+  AES_256_CMAC,
+  HMAC_SHA256,
+  HMAC_SHA512,
+  RSA2048_PSS_SHA256,
+  RSA2048_PKCS1_5_SHA256,
+  ECC_NIST_P256_SIGN_NO_PADDING,
+  ECC_NIST_P256_SIGN_SHA256,
+  ECC_NIST_P521_SIGN_NO_PADDING,
+  ECC_NIST_P521_SIGN_SHA512,
+  ECC_ED25519_SIGN,
+}
diff --git a/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/KeyUse.aidl b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/KeyUse.aidl
new file mode 100644
index 0000000..e888bdf
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/KeyUse.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 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.security.see.hwcrypto.types;
+@Backing(type="int")
+enum KeyUse {
+  ENCRYPT = 1,
+  DECRYPT = 2,
+  ENCRYPT_DECRYPT = (ENCRYPT | DECRYPT) /* 3 */,
+  SIGN = 4,
+  DERIVE = 8,
+  WRAP = 16,
+}
diff --git a/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/MemoryBufferReference.aidl b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/MemoryBufferReference.aidl
new file mode 100644
index 0000000..eaa8dd7
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/MemoryBufferReference.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright 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.security.see.hwcrypto.types;
+parcelable MemoryBufferReference {
+  int startOffset;
+  int sizeBytes;
+}
diff --git a/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/OperationData.aidl b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/OperationData.aidl
new file mode 100644
index 0000000..aad3ac1
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/OperationData.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright 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.security.see.hwcrypto.types;
+union OperationData {
+  android.hardware.security.see.hwcrypto.types.MemoryBufferReference memoryBufferReference;
+  byte[] dataBuffer;
+}
diff --git a/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/OperationType.aidl b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/OperationType.aidl
new file mode 100644
index 0000000..ca8b3eb
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/OperationType.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright 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.security.see.hwcrypto.types;
+enum OperationType {
+  READ,
+  WRITE,
+}
diff --git a/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/SymmetricAuthCryptoParameters.aidl b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/SymmetricAuthCryptoParameters.aidl
new file mode 100644
index 0000000..d3d1763
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/SymmetricAuthCryptoParameters.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright 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.security.see.hwcrypto.types;
+union SymmetricAuthCryptoParameters {
+  android.hardware.security.see.hwcrypto.types.AesGcmMode aes;
+}
diff --git a/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/SymmetricAuthOperationParameters.aidl b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/SymmetricAuthOperationParameters.aidl
new file mode 100644
index 0000000..8a8ef09
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/SymmetricAuthOperationParameters.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 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.security.see.hwcrypto.types;
+parcelable SymmetricAuthOperationParameters {
+  android.hardware.security.see.hwcrypto.IOpaqueKey key;
+  android.hardware.security.see.hwcrypto.types.SymmetricOperation direction;
+  android.hardware.security.see.hwcrypto.types.SymmetricAuthCryptoParameters parameters;
+}
diff --git a/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/SymmetricCryptoParameters.aidl b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/SymmetricCryptoParameters.aidl
new file mode 100644
index 0000000..cc93094
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/SymmetricCryptoParameters.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright 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.security.see.hwcrypto.types;
+union SymmetricCryptoParameters {
+  android.hardware.security.see.hwcrypto.types.AesCipherMode aes;
+}
diff --git a/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/SymmetricOperation.aidl b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/SymmetricOperation.aidl
new file mode 100644
index 0000000..1a17525
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/SymmetricOperation.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright 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.security.see.hwcrypto.types;
+enum SymmetricOperation {
+  ENCRYPT,
+  DECRYPT,
+}
diff --git a/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/SymmetricOperationParameters.aidl b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/SymmetricOperationParameters.aidl
new file mode 100644
index 0000000..769833b
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/SymmetricOperationParameters.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 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.security.see.hwcrypto.types;
+parcelable SymmetricOperationParameters {
+  android.hardware.security.see.hwcrypto.IOpaqueKey key;
+  android.hardware.security.see.hwcrypto.types.SymmetricOperation direction;
+  android.hardware.security.see.hwcrypto.types.SymmetricCryptoParameters parameters;
+}
diff --git a/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/Void.aidl b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/Void.aidl
new file mode 100644
index 0000000..b37848b
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/aidl_api/android.hardware.security.see/current/android/hardware/security/see/hwcrypto/types/Void.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright 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.security.see.hwcrypto.types;
+parcelable Void {
+}
diff --git a/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/CryptoOperation.aidl b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/CryptoOperation.aidl
new file mode 100644
index 0000000..2fdbc78
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/CryptoOperation.aidl
@@ -0,0 +1,88 @@
+/*
+ * Copyright 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.security.see.hwcrypto;
+
+import android.hardware.security.see.hwcrypto.MemoryBufferParameter;
+import android.hardware.security.see.hwcrypto.OperationParameters;
+import android.hardware.security.see.hwcrypto.PatternParameters;
+import android.hardware.security.see.hwcrypto.types.OperationData;
+import android.hardware.security.see.hwcrypto.types.Void;
+
+/*
+ * Type that describes the different operations that can be performed along with its required
+ * parameters. It will be used to construct a vector of operation that are executed sequentially.
+ */
+union CryptoOperation {
+    /*
+     * Sets a memory buffer to operate on. References to positions of this memory buffer can be used
+     * when setting the parameters for <code>UpdateAad</code>, <code>UpdateData</code>,
+     * <code>Finish</code> and <code>CopyData</code>.
+     */
+    MemoryBufferParameter setMemoryBuffer;
+
+    /*
+     * Sets the parameters for the current operation, for more info on specific parameters see
+     * <code>OperationParameters</code>.
+     */
+    OperationParameters setOperationParameters;
+
+    /*
+     * Sets the pattern for a decrypt type operation. A pattern is used to describe that the Input
+     * data provided is not completely encrypted, but that it has some blocks encrypted followed by
+     * some blocks in the clear. Currently it shall only be supported for cbcs mode as defined on
+     * IEC 23001-7:2016.
+     */
+    PatternParameters setPattern;
+
+    /*
+     * Copies data from input to output.
+     */
+    OperationData copyData;
+
+    /*
+     * Adds additional authenticated data. This type is only valid after a
+     * <code>SetOperationParameters</code> of type <code>SymmetricAuthOperationParameters</code>.
+     */
+    OperationData aadInput;
+
+    /*
+     * Adds data to the operation for processing. This type is only valid after a
+     * <code>SetOperationParameters</code> and it will trigger the operation, so output buffers
+     * need to be set first.
+     */
+    OperationData dataInput;
+
+    /*
+     * Adds output buffers to store results form the operation. This type is only valid after a
+     * <code>SetOperationParameters</code> and it needs to be done before calling
+     * <code>DataInput</code>
+     */
+    OperationData dataOutput;
+
+    /*
+     * Finalizes a cryptographic operation in flight. Because operations are initiated with a call
+     * to <code>SetOperationParameters</code>, a <code>finish</code> element is only valid after a
+     * <code>SetOperationParameters</code> element.
+     */
+    @nullable Void finish;
+
+    /*
+     * Specifies that we do not want to continue using this context anymore. The result of this
+     * call is that all resources are freed after finishing operating on the set of commands and no
+     * context is returned to the caller.
+     */
+    @nullable Void destroyContext;
+}
diff --git a/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/CryptoOperationErrorAdditionalInfo.aidl b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/CryptoOperationErrorAdditionalInfo.aidl
new file mode 100644
index 0000000..f3ac8ea
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/CryptoOperationErrorAdditionalInfo.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright 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.security.see.hwcrypto;
+
+/*
+ * Type that provides more information about failures when processing a list of commands.
+ */
+parcelable CryptoOperationErrorAdditionalInfo {
+    /*
+     * Index indicating the first step of <code>CryptoOperationSet::operations</code> that failed
+     * when executing a set of commands. No more commands would have been executed after this.
+     */
+    long failingCommandIndex;
+}
diff --git a/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/CryptoOperationResult.aidl b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/CryptoOperationResult.aidl
new file mode 100644
index 0000000..07c2983
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/CryptoOperationResult.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright 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.security.see.hwcrypto;
+
+import android.hardware.security.see.hwcrypto.ICryptoOperationContext;
+
+/*
+ * Type that describes the result of a set of crypto operations.
+ */
+parcelable CryptoOperationResult {
+    /*
+     * Token that can be passed on a CryptoOperationSet to issue more operations on the same context
+     * on future calls.
+     */
+    @nullable ICryptoOperationContext context;
+}
diff --git a/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/CryptoOperationSet.aidl b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/CryptoOperationSet.aidl
new file mode 100644
index 0000000..9aff1e8
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/CryptoOperationSet.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright 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.security.see.hwcrypto;
+
+import android.hardware.security.see.hwcrypto.CryptoOperation;
+import android.hardware.security.see.hwcrypto.ICryptoOperationContext;
+
+/*
+ * Type that describes a set of crypto operations to execute
+ */
+parcelable CryptoOperationSet {
+    /*
+     * Token to be used to issue the operations. If NULL, a new context will be created and
+     * returned.
+     */
+    @nullable ICryptoOperationContext context;
+
+    /*
+     * Set of operations to execute.
+     */
+    CryptoOperation[] operations;
+}
diff --git a/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/ICryptoOperationContext.aidl b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/ICryptoOperationContext.aidl
new file mode 100644
index 0000000..68d0c03
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/ICryptoOperationContext.aidl
@@ -0,0 +1,25 @@
+/*
+ * Copyright 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.security.see.hwcrypto;
+
+/*
+ * Token that can be used to execute more commands when passed as an input on a
+ * <code>CryptoOperationSet::context</code> parcelable. It represents an operation being executed
+ * and is valid until a <code>CryptoOperation::Finish</code> is issued using the token. The
+ * operation in progress context includes any memory buffer previously mapped by a
+ * <code>CryptoOperation::SetMemoryBuffer</code> call.
+ */
+interface ICryptoOperationContext {}
diff --git a/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/IHwCryptoKey.aidl b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/IHwCryptoKey.aidl
new file mode 100644
index 0000000..939014a
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/IHwCryptoKey.aidl
@@ -0,0 +1,186 @@
+/*
+ * Copyright 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.
+ */
+package android.hardware.security.see.hwcrypto;
+
+import android.hardware.security.see.hwcrypto.IOpaqueKey;
+import android.hardware.security.see.hwcrypto.KeyPolicy;
+
+/*
+ * Higher level interface to access and generate keys.
+ */
+interface IHwCryptoKey {
+    /*
+     * Identifier for the requested device provided key. The currently supported identifiers are:
+     *
+     * DEVICE_BOUND_KEY:
+     *      This is a key unique to the device.
+     * BATCH_KEY:
+     *      This is a shared by a set of devices.
+     */
+    enum DeviceKeyId {
+        DEVICE_BOUND_KEY,
+        BATCH_KEY,
+    }
+    union DiceBoundDerivationKey {
+        /*
+         * Opaque to be used to derive the DICE bound key.
+         */
+        IOpaqueKey opaqueKey;
+
+        /*
+         * Device provided key to be used to derive the DICE bound key.
+         */
+        DeviceKeyId keyId;
+    }
+
+    parcelable DiceCurrentBoundKeyResult {
+        /*
+         * Key cryptographically bound to a DICE policy.
+         */
+        IOpaqueKey diceBoundKey;
+
+        /*
+         * Current dice policy which was used to generate the returned key. This policy is
+         * opaque from this service perspective (it will be sent to an Authentication Manager
+         * Service to be verified). It follows the structure defined on DicePolicy.cddl, located
+         * under hardware/interfaces/security/authgraph/aidl/android/hardware/security/authgraph/
+         * with the caveat that it could be encrypted if the client does not have enough permissions
+         * to see the device dice policy information.
+         */
+        byte[] dicePolicyForKeyVersion;
+    }
+
+    parcelable DiceBoundKeyResult {
+        /*
+         * Key cryptographically bound to a DICE policy.
+         */
+        IOpaqueKey diceBoundKey;
+
+        /*
+         * Indicates if the diceBoundKey returned was created using a current DICE policy. The
+         * caller can use this to detect if an old policy was provided and rotate its keys if so
+         * desired. Old, valid policies remain usable, but care needs to be taken to not continue to
+         * use a potentially compromised key.
+         */
+        boolean dicePolicyWasCurrent;
+    }
+
+    parcelable ClearKeyPolicy {
+        /*
+         * Indicates the desired key size. It will be used to calculate how many bytes of key
+         * material should be returned.
+         */
+        int keySizeBytes;
+    }
+
+    union DerivedKeyPolicy {
+        /*
+         * Policy for the newly derived opaque key. Defines how the key can be used and its type.
+         */
+        KeyPolicy opaqueKey;
+
+        /*
+         * If used we will derive a clear key and pass it back as an array of bytes on
+         * <code>HwCryptoKeyMaterial::explicitKey</code>.
+         */
+        ClearKeyPolicy clearKey;
+    }
+
+    parcelable DerivedKeyParameters {
+        /*
+         * Key to be used to derive the new key using HKDF.
+         */
+        IOpaqueKey derivationKey;
+
+        /*
+         * Policy for the newly derived key. Depending on its type, either a clear or opaque key
+         * will be derived.
+         */
+        DerivedKeyPolicy keyPolicy;
+
+        /*
+         * An arbitrary set of bytes incorporated into the key derivation. May have
+         * an implementation-specific maximum length, but it is guaranteed to accept
+         * at least 32 bytes.
+         */
+        byte[] context;
+    }
+
+    union DerivedKey {
+        /*
+         * Derived key in clear format.
+         */
+        byte[] explicitKey = {};
+
+        /*
+         * Derived key as a key token to be used only through the HWCrypto service.
+         */
+        IOpaqueKey opaque;
+    }
+
+    /*
+     * deriveCurrentDicePolicyBoundKey() - Derives a versioned key tied to the caller's current DICE
+     *                              policy. It will return this current policy back to the caller
+     *                              along with the generated key.
+     *
+     * @derivationKey:
+     *     Key to be used to derive the new key using HKDF.
+     *
+     * Return:
+     *      Ok(DiceCurrentBoundKeyResult) on success, service specific error based on
+     *      <code>HalErrorCode</code> otherwise.
+     */
+    DiceCurrentBoundKeyResult deriveCurrentDicePolicyBoundKey(
+            in DiceBoundDerivationKey derivationKey);
+
+    /*
+     * deriveDicePolicyBoundKey() - Derive a versioned key by checking the provided DICE policy
+     *                              against the caller and then using it as a context for deriving
+     *                              the returned key.
+     *
+     * @derivationKey:
+     *     Key to be used to derive the new key using HKDF.
+     *
+     * @dicePolicyForKeyVersion:
+     *     Policy used to derive keys tied to specific versions. Using this parameter
+     *     the caller can tie a derived key to a minimum version of itself, so in the future only
+     *     itself or a more recent version can derive the same key. This parameter is opaque to the
+     *     caller and it could be encrypted in the case the client doesn't have permission to know
+     *     the dice chain.
+     *     When implementing this function, this parameter shall be one of the components fed
+     *     to the KDF context and it needs to be checked against the caller DICE certificate before
+     *     being used.
+     *
+     * Return:
+     *      Ok(DiceBoundKeyResult) on success, service specific error based on
+     *      <code>HalErrorCode</code> otherwise.
+     */
+    DiceBoundKeyResult deriveDicePolicyBoundKey(
+            in DiceBoundDerivationKey derivationKey, in byte[] dicePolicyForKeyVersion);
+
+    /*
+     * deriveKey() - Derive a new key based on the given key, policy and context.
+     *
+     * @parameters:
+     *      Parameters used for the key derivation. See <code>DerivedKeyParameters</code> on this
+     *      file for more information.
+     *
+     * Return:
+     *      Ok(HwCryptoKeyMaterial) on success, service specific error based on
+     *      <code>HalErrorCode</code> otherwise.
+     */
+    DerivedKey deriveKey(in DerivedKeyParameters parameters);
+}
diff --git a/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/IHwCryptoOperations.aidl b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/IHwCryptoOperations.aidl
new file mode 100644
index 0000000..4d394ed
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/IHwCryptoOperations.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright 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.security.see.hwcrypto;
+
+import android.hardware.security.see.hwcrypto.CryptoOperationErrorAdditionalInfo;
+import android.hardware.security.see.hwcrypto.CryptoOperationResult;
+import android.hardware.security.see.hwcrypto.CryptoOperationSet;
+
+/*
+ * Interface used that provides cryptographic services, including the generation and use of
+ * cryptographic keys. Interactions with this interface are done through a command-base API,
+ * which allow callers to execute a large set of operations on a single call.
+ */
+interface IHwCryptoOperations {
+    /*
+     * processCommandList() - Executes a list of cryptographic commands in order
+     *
+     * @operations:
+     *      Parameter containing 1 or more set of commands to execute. Additionally, each set can
+     *      also contain a context on which the commands will be executed.
+     * @additionalErrorInfo:
+     *      Structure containing additional info when errors are encountered. Only valid if the
+     *      function failed its execution.
+     * Return:
+     *      CryptoOperationResult[] on success, which can contain a context to continue executing
+     *      each of the provided operations sets, service specific error based on
+     *      <code>HalErrorCode</code> otherwise.
+     */
+    CryptoOperationResult[] processCommandList(inout CryptoOperationSet[] operations,
+            out CryptoOperationErrorAdditionalInfo additionalErrorInfo);
+}
diff --git a/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/IOpaqueKey.aidl b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/IOpaqueKey.aidl
new file mode 100644
index 0000000..0d0f613
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/IOpaqueKey.aidl
@@ -0,0 +1,55 @@
+/*
+ * Copyright 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.security.see.hwcrypto;
+
+import android.hardware.security.see.hwcrypto.KeyPolicy;
+import android.hardware.security.see.hwcrypto.types.OperationType;
+
+interface IOpaqueKey {
+    /*
+     * exportWrappedKey() - Exports this key as a wrapped (encrypted) blob.
+     *
+     * @wrapping_key:
+     *     wrapping key. It needs to be an opaque key and its policy needs to indicate that it can
+     *     be used for key wrapping.
+     *
+     * Return:
+     *      Wrapped key blob as a byte array on success. Format of the blob is opaque to the service
+     *      but has to match the command accepted by
+     *      <code>IHwCryptoKeyGeneration::importWrappedKey</code>, service specific error based on
+     *      <code>HalErrorCode</code> otherwise.
+     */
+    byte[] exportWrappedKey(in IOpaqueKey wrappingKey);
+
+    /*
+     * getKeyPolicy() - Returns the key policy.
+     *
+     * Return:
+     *      A <code>KeyPolicy</code> on success, service specific error based on
+     *      <code>HalErrorCode</code> otherwise.
+     */
+    KeyPolicy getKeyPolicy();
+
+    /*
+     * getPublicKey() - Returns the public key portion of this OpaqueKey. This operation is only
+     *                  valid for asymmetric keys
+     *
+     * Return:
+     *      public key as a byte array on success, service specific error based on
+     *      <code>HalErrorCode</code> otherwise. Format used for the returned public key is COSE.
+     */
+    byte[] getPublicKey();
+}
diff --git a/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/KeyPolicy.aidl b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/KeyPolicy.aidl
new file mode 100644
index 0000000..9266bfa
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/KeyPolicy.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright 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.security.see.hwcrypto;
+
+import android.hardware.security.see.hwcrypto.types.KeyLifetime;
+import android.hardware.security.see.hwcrypto.types.KeyPermissions;
+import android.hardware.security.see.hwcrypto.types.KeyType;
+import android.hardware.security.see.hwcrypto.types.KeyUse;
+
+/*
+ * Parcelable that specified how a key can be used.
+ */
+parcelable KeyPolicy {
+    /*
+     * Enum specifying the operations the key can perform (encryption, decryption, etc.).
+     */
+    KeyUse usage;
+
+    /*
+     * Enum that describes the key lifetime characteristics. See the docstring on
+     * <code>KeyLifetime</code> for more details.
+     */
+    KeyLifetime keyLifetime = KeyLifetime.EPHEMERAL;
+
+    /*
+     * Additional permissions of the key (e.g. key types allowed to wrap the key, boot binding,
+     * etc.). See the docstring on <code>KeyPermissions</code> for more details.
+     */
+    KeyPermissions[] keyPermissions;
+
+    /*
+     * Key can be used to wrap or derive other keys.
+     */
+    boolean keyManagementKey;
+
+    /*
+     * Enum that specifies the key type.
+     */
+    KeyType keyType = KeyType.AES_256_GCM;
+}
diff --git a/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/MemoryBufferParameter.aidl b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/MemoryBufferParameter.aidl
new file mode 100644
index 0000000..c5a6a5c
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/MemoryBufferParameter.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright 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.security.see.hwcrypto;
+
+/*
+ * Parcelable representing a memory buffer.
+ */
+parcelable MemoryBufferParameter {
+    union MemoryBuffer {
+        ParcelFileDescriptor input;
+        ParcelFileDescriptor output;
+    }
+
+    /*
+     * Handle used to access this memory area.
+     */
+    MemoryBuffer bufferHandle;
+
+    /*
+     * Total size of the memory buffer.
+     */
+    int sizeBytes;
+}
diff --git a/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/OperationParameters.aidl b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/OperationParameters.aidl
new file mode 100644
index 0000000..9e2fc6c
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/OperationParameters.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright 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.security.see.hwcrypto;
+
+import android.hardware.security.see.hwcrypto.types.SymmetricAuthOperationParameters;
+import android.hardware.security.see.hwcrypto.types.SymmetricOperationParameters;
+
+/*
+ * Type that describes the parameters for the different operations that can be performed.
+ */
+union OperationParameters {
+    /*
+     * Parameters for authenticated symmetric cryptography (AES GCM).
+     */
+    SymmetricAuthOperationParameters symmetricAuthCrypto;
+
+    /*
+     * Parameters for non-authenticated symmetric cryptography (AES/TDES).
+     */
+    SymmetricOperationParameters symmetricCrypto;
+}
diff --git a/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/PatternParameters.aidl b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/PatternParameters.aidl
new file mode 100644
index 0000000..3f62abe
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/PatternParameters.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright 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.security.see.hwcrypto;
+
+/*
+ * Parcelable that specifies a pattern to process data.
+ */
+parcelable PatternParameters {
+    /*
+     * Number of blocks that will be processed. The size of the block matches the size of the
+     * cipher used (e.g. for AES this parameter indicates the number of 16 bytes blocks to be
+     * processed).
+     */
+    long numberBlocksProcess;
+
+    /*
+     * Number of blocks that will be copied. The size of the block matches the size of the cipher
+     * used to process the encrypted areas (e.g. for AES this parameter indicates the number of 16
+     * bytes blocks to be copied).
+     */
+    long numberBlocksCopy;
+}
diff --git a/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/AesCipherMode.aidl b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/AesCipherMode.aidl
new file mode 100644
index 0000000..ac31557
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/AesCipherMode.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright 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.security.see.hwcrypto.types;
+
+import android.hardware.security.see.hwcrypto.types.CipherModeParameters;
+import android.hardware.security.see.hwcrypto.types.Void;
+
+/*
+ * Type used for the parameters needed to run a non-authenticated AES operation.
+ */
+union AesCipherMode {
+    /*
+     * Cipher Block Chaining mode. Padding will either be none or PKCS#7 depending on the key policy
+     * padding parameter. It contains the nonce for the operation.
+     */
+    CipherModeParameters cbc;
+
+    /*
+     * Counter mode. Type contains the nonce for the operation.
+     */
+    CipherModeParameters ctr;
+}
diff --git a/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/AesGcmMode.aidl b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/AesGcmMode.aidl
new file mode 100644
index 0000000..4025553
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/AesGcmMode.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright 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.security.see.hwcrypto.types;
+
+/*
+ * Type used for the parameters needed to run an authenticated AES operation (GCM).
+ */
+union AesGcmMode {
+    parcelable AesGcmModeParameters {
+        /*
+         * Galois Counter Mode nonce. Only 12-bytes nonce are supported.
+         */
+        byte[12] nonce;
+    }
+
+    /*
+     * Galois Counter Mode with an authentication Tag that has a length of 16 bytes.
+     */
+    AesGcmModeParameters gcmTag16;
+}
diff --git a/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/CipherModeParameters.aidl b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/CipherModeParameters.aidl
new file mode 100644
index 0000000..bfa5daa
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/CipherModeParameters.aidl
@@ -0,0 +1,24 @@
+
+/*
+ * Copyright 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.security.see.hwcrypto.types;
+
+/*
+ * Type encapsulating nonce used on non-authenticated AES symmetric encryption.
+ */
+parcelable CipherModeParameters {
+    byte[16] nonce;
+}
diff --git a/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/HalErrorCode.aidl b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/HalErrorCode.aidl
new file mode 100644
index 0000000..e8e8539
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/HalErrorCode.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright 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.security.see.hwcrypto.types;
+
+/*
+ * Service error codes. Will be returned as service specific errors.
+ */
+parcelable HalErrorCode {
+    /* Success */
+    const int NO_ERROR = 0;
+
+    /* Generic error */
+    const int GENERIC_ERROR = -1;
+
+    /* Desired operation cannot be performed because of the server current state */
+    const int BAD_STATE = -2;
+
+    /* Operation or parameters are not supported by the server */
+    const int UNSUPPORTED = -3;
+
+    /* Error encountered when parsing parameters */
+    const int SERIALIZATION_ERROR = -4;
+
+    /* Server ran out of memory when performing operation */
+    const int ALLOCATION_ERROR = -5;
+
+    /* Provided key is not compatible with the operation */
+    const int INVALID_KEY = -6;
+
+    /* Bad parameter supplied for the desired operation */
+    const int BAD_PARAMETER = -7;
+}
diff --git a/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/KeyLifetime.aidl b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/KeyLifetime.aidl
new file mode 100644
index 0000000..9958a0b
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/KeyLifetime.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 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.security.see.hwcrypto.types;
+
+/*
+ * Enum that gives more information about the lifetime characteristics of the key. They are
+ * represented as a bitmask to allow us to internally combine them on a single property to describe
+ * a set of allowed lifetimes.
+ */
+@Backing(type="byte")
+enum KeyLifetime {
+    /*
+     * Hardware keys with limited validity (until key is erased or power cycle occurs).
+     */
+    EPHEMERAL,
+
+    /*
+     * Key only lives or was derived from a key that only lives in hardware. This key cannot be
+     * retrieved in the clear.
+     */
+    HARDWARE,
+
+    /*
+     * Key could have been at some point of its lifetime in the clear on a software component.
+     */
+    PORTABLE,
+
+}
diff --git a/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/KeyPermissions.aidl b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/KeyPermissions.aidl
new file mode 100644
index 0000000..a1e4f21
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/KeyPermissions.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright 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.security.see.hwcrypto.types;
+
+/*
+ * Additional characteristics and permissions of the key.
+ */
+enum KeyPermissions {
+    /*
+     * Key can be wrapped by an ephemeral key.
+     */
+    ALLOW_EPHEMERAL_KEY_WRAPPING,
+
+    /*
+     * Key can be wrapped by a hardware key. Notice that ephemeral keys cannot be wrapped by
+     * hardware keys.
+     */
+    ALLOW_HARDWARE_KEY_WRAPPING,
+
+    /*
+     * Key can be wrapped by a portable key. Notice that neither ephemeral keys nor hardware keys
+     * can be wrapped by portable keys.
+     */
+    ALLOW_PORTABLE_KEY_WRAPPING,
+}
diff --git a/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/KeyType.aidl b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/KeyType.aidl
new file mode 100644
index 0000000..3cf4670
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/KeyType.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 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.security.see.hwcrypto.types;
+
+/*
+ * Enum describing all supported key types. Key types are strongly bound to the algorithm to
+ * prevent reusing the same key on different algorithms (e.g. using the same key for 2 different AES
+ * 128 Cipher modes).
+ */
+enum KeyType {
+    AES_128_CBC_NO_PADDING,
+    AES_128_CBC_PKCS7_PADDING,
+    AES_128_CTR,
+    AES_128_GCM,
+    AES_128_CMAC,
+    AES_256_CBC_NO_PADDING,
+    AES_256_CBC_PKCS7_PADDING,
+    AES_256_CTR,
+    AES_256_GCM,
+    AES_256_CMAC,
+    HMAC_SHA256,
+    HMAC_SHA512,
+    RSA2048_PSS_SHA256,
+    RSA2048_PKCS1_5_SHA256,
+    ECC_NIST_P256_SIGN_NO_PADDING,
+    ECC_NIST_P256_SIGN_SHA256,
+    ECC_NIST_P521_SIGN_NO_PADDING,
+    ECC_NIST_P521_SIGN_SHA512,
+    ECC_ED25519_SIGN,
+}
diff --git a/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/KeyUse.aidl b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/KeyUse.aidl
new file mode 100644
index 0000000..76bfd62
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/KeyUse.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright 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.security.see.hwcrypto.types;
+
+/*
+ * Enum describing the allowed operations that can be performed with the given key.
+ */
+@Backing(type="int")
+enum KeyUse {
+    ENCRYPT = 1,
+    DECRYPT = 2,
+    ENCRYPT_DECRYPT = ENCRYPT | DECRYPT,
+    SIGN = 4,
+    DERIVE = 8,
+    WRAP = 16,
+}
diff --git a/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/MemoryBufferReference.aidl b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/MemoryBufferReference.aidl
new file mode 100644
index 0000000..5b90d9c
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/MemoryBufferReference.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright 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.security.see.hwcrypto.types;
+
+/*
+ * Structure representing a section of a memory buffer.
+ */
+parcelable MemoryBufferReference {
+    /*
+     * Start of the memory buffer section measured from the start of the memory buffer set for this
+     * operation.
+     */
+    int startOffset;
+
+    /*
+     * Total size of the memory buffer section.
+     */
+    int sizeBytes;
+}
diff --git a/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/OperationData.aidl b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/OperationData.aidl
new file mode 100644
index 0000000..642d05e
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/OperationData.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright 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.security.see.hwcrypto.types;
+
+import android.hardware.security.see.hwcrypto.types.MemoryBufferReference;
+
+/*
+ * Union holding buffers to be used by the cryptographic operation.
+ */
+union OperationData {
+    /*
+     * Reference (offset, size) to the active operations' MemoryBuffer.
+     */
+    MemoryBufferReference memoryBufferReference;
+
+    /*
+     * Vector of data to use for the operation.
+     */
+    byte[] dataBuffer;
+}
diff --git a/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/OperationType.aidl b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/OperationType.aidl
new file mode 100644
index 0000000..76878a3
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/OperationType.aidl
@@ -0,0 +1,24 @@
+/*
+ * Copyright 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.security.see.hwcrypto.types;
+
+/*
+ * Enum describing the different types of operations allowed on a buffer.
+ */
+enum OperationType {
+    READ,
+    WRITE,
+}
diff --git a/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/SymmetricAuthCryptoParameters.aidl b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/SymmetricAuthCryptoParameters.aidl
new file mode 100644
index 0000000..278e48d
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/SymmetricAuthCryptoParameters.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright 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.security.see.hwcrypto.types;
+
+import android.hardware.security.see.hwcrypto.types.AesGcmMode;
+
+/*
+ * Data needed to perform authenticated symmetric cryptographic operations.
+ */
+union SymmetricAuthCryptoParameters {
+    /*
+     * AES (Advanced Encryption Standard) GCM parameters.
+     */
+    AesGcmMode aes;
+}
diff --git a/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/SymmetricAuthOperationParameters.aidl b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/SymmetricAuthOperationParameters.aidl
new file mode 100644
index 0000000..46568c3
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/SymmetricAuthOperationParameters.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 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.security.see.hwcrypto.types;
+
+import android.hardware.security.see.hwcrypto.IOpaqueKey;
+import android.hardware.security.see.hwcrypto.types.SymmetricAuthCryptoParameters;
+import android.hardware.security.see.hwcrypto.types.SymmetricOperation;
+
+/*
+ * Parameters needed to perform an authenticated symmetric cryptographic operation. Currently only
+ * AES-GCM is supported.
+ */
+parcelable SymmetricAuthOperationParameters {
+    /*
+     * Key to be used on the operation.
+     */
+    IOpaqueKey key;
+
+    /*
+     * Encryption or Decryption.
+     */
+    SymmetricOperation direction;
+
+    /*
+     * Parameters that specify the desired authenticated cryptographic operation.
+     */
+    SymmetricAuthCryptoParameters parameters;
+}
diff --git a/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/SymmetricCryptoParameters.aidl b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/SymmetricCryptoParameters.aidl
new file mode 100644
index 0000000..2350242
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/SymmetricCryptoParameters.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright 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.security.see.hwcrypto.types;
+
+import android.hardware.security.see.hwcrypto.types.AesCipherMode;
+
+/*
+ * Data needed to perform non-authenticated symmetric cryptographic operations.
+ */
+union SymmetricCryptoParameters {
+    /*
+     * AES (Advanced Encryption Standard) parameters.
+     */
+    AesCipherMode aes;
+}
diff --git a/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/SymmetricOperation.aidl b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/SymmetricOperation.aidl
new file mode 100644
index 0000000..2717472
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/SymmetricOperation.aidl
@@ -0,0 +1,21 @@
+/*
+ * Copyright 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.security.see.hwcrypto.types;
+
+/*
+ * Enum describing the type of symmetric operation desired.
+ */
+enum SymmetricOperation { ENCRYPT, DECRYPT }
diff --git a/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/SymmetricOperationParameters.aidl b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/SymmetricOperationParameters.aidl
new file mode 100644
index 0000000..1d1554d
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/SymmetricOperationParameters.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 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.security.see.hwcrypto.types;
+
+import android.hardware.security.see.hwcrypto.IOpaqueKey;
+import android.hardware.security.see.hwcrypto.types.SymmetricCryptoParameters;
+import android.hardware.security.see.hwcrypto.types.SymmetricOperation;
+
+/*
+ * Parameters needed to perform a non-authenticated symmetric cryptographic operation.
+ */
+parcelable SymmetricOperationParameters {
+    /*
+     * Key to be used on the operation.
+     */
+    IOpaqueKey key;
+
+    /*
+     * Encryption or Decryption.
+     */
+    SymmetricOperation direction;
+
+    /*
+     * Parameters that specify the desired non-authenticated symmetric cryptographic operation.
+     */
+    SymmetricCryptoParameters parameters;
+}
diff --git a/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/Void.aidl b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/Void.aidl
new file mode 100644
index 0000000..f9f608d
--- /dev/null
+++ b/staging/security/see/hwcrypto/aidl/android/hardware/security/see/hwcrypto/types/Void.aidl
@@ -0,0 +1,18 @@
+/*
+ * Copyright 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.security.see.hwcrypto.types;
+
+parcelable Void {}
diff --git a/tests/msgq/1.0/default/mq_test_service.cpp b/tests/msgq/1.0/default/mq_test_service.cpp
index 72ffe41..66ad12f 100644
--- a/tests/msgq/1.0/default/mq_test_service.cpp
+++ b/tests/msgq/1.0/default/mq_test_service.cpp
@@ -21,13 +21,15 @@
 #include <android/binder_manager.h>
 #include <android/binder_process.h>
 #include <android/hardware/tests/msgq/1.0/ITestMsgQ.h>
+#include <hidl/ServiceManagement.h>
 
 using aidl::android::fmq::test::TestAidlMsgQ;
 
 #include <hidl/LegacySupport.h>
 
-using android::hardware::tests::msgq::V1_0::ITestMsgQ;
 using android::hardware::defaultPassthroughServiceImplementation;
+using android::hardware::isHidlSupported;
+using android::hardware::tests::msgq::V1_0::ITestMsgQ;
 
 int main() {
     android::hardware::details::setTrebleTestingOverride(true);
@@ -39,8 +41,10 @@
     LOG(INFO) << "instance: " << instance;
     CHECK(AServiceManager_addService(store->asBinder().get(), instance.c_str()) == STATUS_OK);
 
-    // Register HIDL service
-    CHECK(defaultPassthroughServiceImplementation<ITestMsgQ>() == android::OK);
+    if (isHidlSupported()) {
+        // Register HIDL service
+        CHECK(defaultPassthroughServiceImplementation<ITestMsgQ>() == android::OK);
+    }
     ABinderProcess_joinThreadPool();
 
     return EXIT_FAILURE;  // should not reach
diff --git a/threadnetwork/aidl/default/main.cpp b/threadnetwork/aidl/default/main.cpp
index 8419041..6514184 100644
--- a/threadnetwork/aidl/default/main.cpp
+++ b/threadnetwork/aidl/default/main.cpp
@@ -18,7 +18,11 @@
 #include <android-base/logging.h>
 #include <android/binder_manager.h>
 #include <android/binder_process.h>
+#include <netinet/in.h>
+#include <net/if.h>
 #include <utils/Log.h>
+#include <cutils/properties.h>
+#include <sys/stat.h>
 
 #include "service.hpp"
 #include "thread_chip.hpp"
@@ -26,24 +30,53 @@
 using aidl::android::hardware::threadnetwork::IThreadChip;
 using aidl::android::hardware::threadnetwork::ThreadChip;
 
+#define THREADNETWORK_COPROCESSOR_SIMULATION_PATH "/apex/com.android.hardware.threadnetwork/bin/ot-rcp"
+
+namespace {
+void addThreadChip(int id, const char* url) {
+    binder_status_t status;
+    const std::string serviceName(std::string() + IThreadChip::descriptor + "/chip" +
+            std::to_string(id));
+
+    ALOGI("ServiceName: %s, Url: %s", serviceName.c_str(), url);
+
+    auto threadChip = ndk::SharedRefBase::make<ThreadChip>(url);
+
+    CHECK_NE(threadChip, nullptr);
+
+    status = AServiceManager_addService(threadChip->asBinder().get(), serviceName.c_str());
+    CHECK_EQ(status, STATUS_OK);
+}
+
+void addSimulatedThreadChip() {
+    char local_interface[PROP_VALUE_MAX];
+
+    CHECK_GT(property_get("persist.vendor.otsim.local_interface",
+                local_interface, "eth1"), 0);
+
+    int node_id = property_get_int32("ro.boot.openthread_node_id", 0);
+    CHECK_GT(node_id,0);
+
+    std::string url = std::string("spinel+hdlc+forkpty://" \
+            THREADNETWORK_COPROCESSOR_SIMULATION_PATH "?forkpty-arg=-L") \
+                      + local_interface + "&forkpty-arg=" + std::to_string(node_id);
+    addThreadChip(0, url.c_str());
+}
+}
+
 int main(int argc, char* argv[]) {
-    CHECK_GT(argc, 1);
-    std::vector<std::shared_ptr<ThreadChip>> threadChips;
     aidl::android::hardware::threadnetwork::Service service;
 
-    for (int id = 0; id < argc - 1; id++) {
-        binder_status_t status;
-        const std::string serviceName(std::string() + IThreadChip::descriptor + "/chip" +
-                                      std::to_string(id));
-        auto threadChip = ndk::SharedRefBase::make<ThreadChip>(argv[id + 1]);
+    if (argc > 1) {
+        for (int id = 0; id < argc - 1; id++) {
+            addThreadChip(id, argv[id + 1]);
+        }
+    } else {
+        struct stat sb;
 
-        CHECK_NE(threadChip, nullptr);
-
-        status = AServiceManager_addService(threadChip->asBinder().get(), serviceName.c_str());
-        CHECK_EQ(status, STATUS_OK);
-
-        ALOGI("ServiceName: %s, Url: %s", serviceName.c_str(), argv[id + 1]);
-        threadChips.push_back(std::move(threadChip));
+        CHECK_EQ(stat(THREADNETWORK_COPROCESSOR_SIMULATION_PATH, &sb), 0);
+        CHECK(sb.st_mode & S_IXUSR);
+        addSimulatedThreadChip();
     }
 
     ALOGI("Thread Network HAL is running");
diff --git a/threadnetwork/aidl/default/socket_interface.cpp b/threadnetwork/aidl/default/socket_interface.cpp
index f874209..0544502 100644
--- a/threadnetwork/aidl/default/socket_interface.cpp
+++ b/threadnetwork/aidl/default/socket_interface.cpp
@@ -23,6 +23,7 @@
 #include "socket_interface.hpp"
 
 #include <errno.h>
+#include <linux/limits.h>
 #include <openthread/logging.h>
 #include <sys/inotify.h>
 #include <sys/socket.h>
@@ -42,6 +43,8 @@
 namespace hardware {
 namespace threadnetwork {
 
+const char SocketInterface::kLogModuleName[] = "SocketIntface";
+
 SocketInterface::SocketInterface(const ot::Url::Url& aRadioUrl)
     : mReceiveFrameCallback(nullptr),
       mReceiveFrameContext(nullptr),
@@ -157,7 +160,7 @@
     } else if (rval < 0) {
         DieNow(OT_EXIT_ERROR_ERRNO);
     } else {
-        otLogCritPlat("Socket connection is closed by remote.");
+        LogCrit("Socket connection is closed by remote.");
         exit(OT_EXIT_FAILURE);
     }
 }
@@ -192,7 +195,7 @@
         mReceiveFrameCallback(mReceiveFrameContext);
     } else {
         mReceiveFrameBuffer->DiscardFrame();
-        otLogWarnPlat("Process socket frame failed: %s", otThreadErrorToString(aError));
+        LogWarn("Process socket frame failed: %s", otThreadErrorToString(aError));
     }
 
 exit:
@@ -204,16 +207,16 @@
     sockaddr_un serverAddress;
 
     VerifyOrExit(sizeof(serverAddress.sun_path) > strlen(aRadioUrl.GetPath()),
-                 otLogCritPlat("Invalid file path length"));
+                 LogCrit("Invalid file path length"));
     strncpy(serverAddress.sun_path, aRadioUrl.GetPath(), sizeof(serverAddress.sun_path));
     serverAddress.sun_family = AF_UNIX;
 
     fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
-    VerifyOrExit(fd != -1, otLogCritPlat("open(): errno=%s", strerror(errno)));
+    VerifyOrExit(fd != -1, LogCrit("open(): errno=%s", strerror(errno)));
 
     if (connect(fd, reinterpret_cast<struct sockaddr*>(&serverAddress), sizeof(serverAddress)) ==
         -1) {
-        otLogCritPlat("connect(): errno=%s", strerror(errno));
+        LogCrit("connect(): errno=%s", strerror(errno));
         close(fd);
         fd = -1;
     }
@@ -225,9 +228,9 @@
 void SocketInterface::CloseFile(void) {
     VerifyOrExit(mSockFd != -1);
 
-    VerifyOrExit(0 == close(mSockFd), otLogCritPlat("close(): errno=%s", strerror(errno)));
+    VerifyOrExit(0 == close(mSockFd), LogCrit("close(): errno=%s", strerror(errno)));
     VerifyOrExit(wait(nullptr) != -1 || errno == ECHILD,
-                 otLogCritPlat("wait(): errno=%s", strerror(errno)));
+                 LogCrit("wait(): errno=%s", strerror(errno)));
 
     mSockFd = -1;
 
@@ -254,7 +257,7 @@
     wd = inotify_add_watch(inotifyFd, folderPath.c_str(), IN_CREATE);
     VerifyOrDie(wd != -1, OT_EXIT_ERROR_ERRNO);
 
-    otLogInfoPlat("Waiting for socket file %s be created...", aPath);
+    LogInfo("Waiting for socket file %s be created...", aPath);
 
     while (true) {
         fd_set fds;
@@ -271,7 +274,7 @@
         }
 
         if (FD_ISSET(inotifyFd, &fds)) {
-            char buffer[sizeof(struct inotify_event)];
+            char buffer[sizeof(struct inotify_event) + NAME_MAX + 1];
             ssize_t bytesRead = read(inotifyFd, buffer, sizeof(buffer));
 
             VerifyOrDie(bytesRead >= 0, OT_EXIT_ERROR_ERRNO);
@@ -286,7 +289,7 @@
     close(inotifyFd);
 
 exit:
-    otLogInfoPlat("Socket file: %s is created", aPath);
+    LogInfo("Socket file: %s is created", aPath);
     return;
 }
 
diff --git a/threadnetwork/aidl/default/socket_interface.hpp b/threadnetwork/aidl/default/socket_interface.hpp
index f88e926..6f3be7f 100644
--- a/threadnetwork/aidl/default/socket_interface.hpp
+++ b/threadnetwork/aidl/default/socket_interface.hpp
@@ -22,6 +22,7 @@
 
 #include "lib/spinel/spinel_interface.hpp"
 #include "lib/url/url.hpp"
+#include "logger.hpp"
 
 namespace aidl {
 namespace android {
@@ -32,8 +33,11 @@
  * Defines a Socket interface to the Radio Co-processor (RCP)
  *
  */
-class SocketInterface : public ot::Spinel::SpinelInterface {
+class SocketInterface : public ot::Spinel::SpinelInterface,
+                        public ot::Posix::Logger<SocketInterface> {
   public:
+    static const char kLogModuleName[];  ///< Module name used for logging.
+
     /**
      * Initializes the object.
      *
diff --git a/threadnetwork/aidl/default/thread_chip.cpp b/threadnetwork/aidl/default/thread_chip.cpp
index d1e1d4c..e312728 100644
--- a/threadnetwork/aidl/default/thread_chip.cpp
+++ b/threadnetwork/aidl/default/thread_chip.cpp
@@ -32,11 +32,9 @@
 namespace hardware {
 namespace threadnetwork {
 
-ThreadChip::ThreadChip(char* url) : mUrl(), mRxFrameBuffer(), mCallback(nullptr) {
+ThreadChip::ThreadChip(const char* url) : mUrl(url), mRxFrameBuffer(), mCallback(nullptr) {
     const char* interfaceName;
 
-    CHECK_EQ(mUrl.Init(url), 0);
-
     interfaceName = mUrl.GetProtocol();
     CHECK_NE(interfaceName, nullptr);
 
diff --git a/threadnetwork/aidl/default/thread_chip.hpp b/threadnetwork/aidl/default/thread_chip.hpp
index 30046ef..d07d049 100644
--- a/threadnetwork/aidl/default/thread_chip.hpp
+++ b/threadnetwork/aidl/default/thread_chip.hpp
@@ -20,8 +20,8 @@
 #include <aidl/android/hardware/threadnetwork/IThreadChipCallback.h>
 
 #include "lib/spinel/spinel_interface.hpp"
-#include "lib/url/url.hpp"
 #include "mainloop.hpp"
+#include "radio_url.hpp"
 
 #include <android/binder_auto_utils.h>
 #include <android/binder_ibinder.h>
@@ -34,7 +34,7 @@
 
 class ThreadChip : public BnThreadChip, ot::Posix::Mainloop::Source {
   public:
-    ThreadChip(char* url);
+    ThreadChip(const char* url);
     ~ThreadChip() {}
 
     ndk::ScopedAStatus open(const std::shared_ptr<IThreadChipCallback>& in_callback) override;
@@ -55,7 +55,7 @@
     ndk::ScopedAStatus initChip(const std::shared_ptr<IThreadChipCallback>& in_callback);
     ndk::ScopedAStatus deinitChip();
 
-    ot::Url::Url mUrl;
+    ot::Posix::RadioUrl mUrl;
     std::shared_ptr<ot::Spinel::SpinelInterface> mSpinelInterface;
     ot::Spinel::SpinelInterface::RxFrameBuffer mRxFrameBuffer;
     std::shared_ptr<IThreadChipCallback> mCallback;
diff --git a/threadnetwork/aidl/default/threadnetwork-service.rc b/threadnetwork/aidl/default/threadnetwork-service.rc
index 3b889eb..a2ac0f7 100644
--- a/threadnetwork/aidl/default/threadnetwork-service.rc
+++ b/threadnetwork/aidl/default/threadnetwork-service.rc
@@ -1,3 +1,3 @@
-service vendor.threadnetwork_hal /apex/com.android.hardware.threadnetwork/bin/hw/android.hardware.threadnetwork-service spinel+hdlc+forkpty:///apex/com.android.hardware.threadnetwork/bin/ot-rcp?forkpty-arg=1
+service vendor.threadnetwork_hal /apex/com.android.hardware.threadnetwork/bin/hw/android.hardware.threadnetwork-service
     class hal
     user thread_network
diff --git a/threadnetwork/aidl/default/utils.cpp b/threadnetwork/aidl/default/utils.cpp
index 1cb42ec..3552b3a 100644
--- a/threadnetwork/aidl/default/utils.cpp
+++ b/threadnetwork/aidl/default/utils.cpp
@@ -20,6 +20,20 @@
 #include <openthread/platform/alarm-milli.h>
 #include <utils/Log.h>
 
+void otLogPlatArgs(otLogLevel aLogLevel, const char* aPlatModuleName, const char* aFormat,
+                   va_list aArgs) {
+    OT_UNUSED_VARIABLE(aPlatModuleName);
+    static const android_LogPriority kLogPriorities[] = {ANDROID_LOG_SILENT, ANDROID_LOG_FATAL,
+                                                         ANDROID_LOG_WARN,   ANDROID_LOG_INFO,
+                                                         ANDROID_LOG_INFO,   ANDROID_LOG_DEBUG};
+
+    if (aLogLevel >= sizeof(kLogPriorities) / sizeof(android_LogPriority)) {
+        return;
+    }
+
+    __android_log_vprint(kLogPriorities[aLogLevel], LOG_TAG, aFormat, aArgs);
+}
+
 void otLogCritPlat(const char* format, ...) {
     va_list args;
 
@@ -28,38 +42,6 @@
     va_end(args);
 }
 
-void otLogWarnPlat(const char* format, ...) {
-    va_list args;
-
-    va_start(args, format);
-    __android_log_vprint(ANDROID_LOG_WARN, LOG_TAG, format, args);
-    va_end(args);
-}
-
-void otLogNotePlat(const char* format, ...) {
-    va_list args;
-
-    va_start(args, format);
-    __android_log_vprint(ANDROID_LOG_INFO, LOG_TAG, format, args);
-    va_end(args);
-}
-
-void otLogInfoPlat(const char* format, ...) {
-    va_list args;
-
-    va_start(args, format);
-    __android_log_vprint(ANDROID_LOG_INFO, LOG_TAG, format, args);
-    va_end(args);
-}
-
-void otLogDebgPlat(const char* format, ...) {
-    va_list args;
-
-    va_start(args, format);
-    __android_log_vprint(ANDROID_LOG_DEBUG, LOG_TAG, format, args);
-    va_end(args);
-}
-
 void otDumpDebgPlat(const char* aText, const void* aData, uint16_t aDataLength) {
     constexpr uint16_t kBufSize = 512;
     char buf[kBufSize];
diff --git a/threadnetwork/aidl/vts/Android.bp b/threadnetwork/aidl/vts/Android.bp
index 864e885..931081b 100644
--- a/threadnetwork/aidl/vts/Android.bp
+++ b/threadnetwork/aidl/vts/Android.bp
@@ -31,6 +31,7 @@
     static_libs: [
         "android.hardware.threadnetwork-V1-ndk",
     ],
+    test_config: "VtsHalThreadNetworkTargetTest.xml",
     test_suites: [
         "general-tests",
         "vts",
diff --git a/threadnetwork/aidl/vts/VtsHalThreadNetworkTargetTest.xml b/threadnetwork/aidl/vts/VtsHalThreadNetworkTargetTest.xml
new file mode 100644
index 0000000..0525876
--- /dev/null
+++ b/threadnetwork/aidl/vts/VtsHalThreadNetworkTargetTest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<configuration description="Runs VtsHalThreadNetworkTargetTest.">
+    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+        <option name="run-command" value="cmd thread_network force-stop-ot-daemon enabled" />
+        <option name="run-command" value="cmd bluetooth_manager enable" />
+        <option name="teardown-command" value="cmd thread_network force-stop-ot-daemon disabled" />
+    </target_preparer>
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="VtsHalThreadNetworkTargetTest->/data/local/tmp/VtsHalThreadNetworkTargetTest" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="VtsHalThreadNetworkTargetTest" />
+    </test>
+</configuration>
diff --git a/tv/Android.mk b/tv/Android.mk
deleted file mode 100644
index d78614a..0000000
--- a/tv/Android.mk
+++ /dev/null
@@ -1,2 +0,0 @@
-$(eval $(call declare-1p-copy-files,hardware/interfaces/tv,tuner_vts_config_1_0.xml))
-$(eval $(call declare-1p-copy-files,hardware/interfaces/tv,tuner_vts_config_1_1.xml))
diff --git a/tv/hdmi/cec/aidl/default/HdmiCecMock.cpp b/tv/hdmi/cec/aidl/default/HdmiCecMock.cpp
index 8a3c6f0..4dbd339 100644
--- a/tv/hdmi/cec/aidl/default/HdmiCecMock.cpp
+++ b/tv/hdmi/cec/aidl/default/HdmiCecMock.cpp
@@ -35,8 +35,7 @@
 void HdmiCecMock::serviceDied(void* cookie) {
     ALOGE("HdmiCecMock died");
     auto hdmiCecMock = static_cast<HdmiCecMock*>(cookie);
-    hdmiCecMock->mCecThreadRun = false;
-    pthread_join(hdmiCecMock->mThreadId, NULL);
+    hdmiCecMock->closeCallback();
 }
 
 ScopedAStatus HdmiCecMock::addLogicalAddress(CecLogicalAddress addr, Result* _aidl_return) {
@@ -86,10 +85,10 @@
 }
 
 ScopedAStatus HdmiCecMock::setCallback(const std::shared_ptr<IHdmiCecCallback>& callback) {
-    // If callback is null, mCallback is also set to null so we do not call the old callback.
-    mCallback = callback;
+    closeCallback();
 
     if (callback != nullptr) {
+        mCallback = callback;
         mDeathRecipient =
                 ndk::ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient_new(serviceDied));
         AIBinder_linkToDeath(callback->asBinder().get(), mDeathRecipient.get(), this /* cookie */);
@@ -104,8 +103,8 @@
 
 ScopedAStatus HdmiCecMock::setLanguage(const std::string& language) {
     if (language.size() != 3) {
-        LOG(ERROR) << "Wrong language code: expected 3 letters, but it was " << language.size()
-                   << ".";
+        ALOGE("[halimp_aidl] Wrong language code: expected 3 letters, but it was %zu",
+              language.size());
         return ScopedAStatus::ok();
     }
     // TODO Validate if language is a valid language code
@@ -169,7 +168,7 @@
     // Open the output pipe for writing outgoing cec message
     mOutputFile = open(CEC_MSG_OUT_FIFO, O_WRONLY | O_CLOEXEC);
     if (mOutputFile < 0) {
-        ALOGD("[halimp_aidl] file open failed for writing");
+        ALOGE("[halimp_aidl] file open failed for writing");
         return -1;
     }
 
@@ -258,17 +257,24 @@
 }
 
 HdmiCecMock::HdmiCecMock() {
-    ALOGE("[halimp_aidl] Opening a virtual CEC HAL for testing and virtual machine.");
+    ALOGD("[halimp_aidl] Opening a virtual CEC HAL for testing and virtual machine.");
     mCallback = nullptr;
     mDeathRecipient = ndk::ScopedAIBinder_DeathRecipient(nullptr);
 }
 
+void HdmiCecMock::closeCallback() {
+    if (mCallback != nullptr) {
+        ALOGD("[halimp_aidl] HdmiCecMock close the current callback.");
+        mCallback = nullptr;
+        mDeathRecipient = ndk::ScopedAIBinder_DeathRecipient(nullptr);
+        mCecThreadRun = false;
+        pthread_join(mThreadId, NULL);
+    }
+}
+
 HdmiCecMock::~HdmiCecMock() {
-    ALOGE("[halimp_aidl] HdmiCecMock shutting down.");
-    mCallback = nullptr;
-    mDeathRecipient = ndk::ScopedAIBinder_DeathRecipient(nullptr);
-    mCecThreadRun = false;
-    pthread_join(mThreadId, NULL);
+    ALOGD("[halimp_aidl] HdmiCecMock shutting down.");
+    closeCallback();
 }
 
 }  // namespace implementation
diff --git a/tv/hdmi/cec/aidl/default/HdmiCecMock.h b/tv/hdmi/cec/aidl/default/HdmiCecMock.h
index e78b1cf..ef392bb 100644
--- a/tv/hdmi/cec/aidl/default/HdmiCecMock.h
+++ b/tv/hdmi/cec/aidl/default/HdmiCecMock.h
@@ -55,6 +55,7 @@
     ::ndk::ScopedAStatus enableCec(bool value) override;
     ::ndk::ScopedAStatus enableSystemCecControl(bool value) override;
     void printCecMsgBuf(const char* msg_buf, int len);
+    void closeCallback();
 
   private:
     static void* __threadLoop(void* data);
@@ -62,9 +63,8 @@
     int readMessageFromFifo(unsigned char* buf, int msgCount);
     int sendMessageToFifo(const CecMessage& message);
     void handleCecMessage(unsigned char* msgBuf, int length);
-
-  private:
     static void serviceDied(void* cookie);
+
     std::shared_ptr<IHdmiCecCallback> mCallback;
 
     // Variables for the virtual cec hal impl
diff --git a/tv/tuner/aidl/vts/functional/FrontendTests.cpp b/tv/tuner/aidl/vts/functional/FrontendTests.cpp
index b7b0185..85d0496 100644
--- a/tv/tuner/aidl/vts/functional/FrontendTests.cpp
+++ b/tv/tuner/aidl/vts/functional/FrontendTests.cpp
@@ -353,8 +353,7 @@
                 break;
             }
             case FrontendStatusType::UEC: {
-                ASSERT_TRUE(realStatuses[i].get<FrontendStatus::Tag::uec>() ==
-                            expectStatuses[i].get<FrontendStatus::Tag::uec>());
+                ASSERT_TRUE(realStatuses[i].get<FrontendStatus::Tag::uec>() >= 0);
                 break;
             }
             case FrontendStatusType::T2_SYSTEM_ID: {
diff --git a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.h b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.h
index 8ad6ee0..6cabb3d 100644
--- a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.h
+++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.h
@@ -17,6 +17,7 @@
 #pragma once
 
 #include <android/binder_manager.h>
+#include <cutils/properties.h>
 
 #include "DemuxTests.h"
 #include "DescramblerTests.h"
@@ -29,6 +30,13 @@
 namespace {
 
 bool initConfiguration() {
+    std::array<char, PROPERTY_VALUE_MAX> variant;
+    property_get("ro.vendor.vts_tuner_configuration_variant", variant.data(), "");
+    string configFilePath = "/vendor/etc/tuner_vts_config_aidl_V1";
+    if (variant.size() != 0) {
+        configFilePath = configFilePath + "."  + variant.data();
+    }
+    configFilePath = configFilePath + ".xml";
     TunerTestingConfigAidlReader1_0::setConfigFilePath(configFilePath);
     if (!TunerTestingConfigAidlReader1_0::checkConfigFileExists()) {
         return false;
diff --git a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h
index ff94639..29d2f18 100644
--- a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h
+++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h
@@ -52,8 +52,6 @@
 const int32_t FMQ_SIZE_4M = 0x400000;
 const int32_t FMQ_SIZE_16M = 0x1000000;
 
-const string configFilePath = "/vendor/etc/tuner_vts_config_aidl_V1.xml";
-
 #define FILTER_MAIN_TYPE_BIT_COUNT 5
 #define STATUS_CHECK_INTERVAL_MS 100L
 
diff --git a/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h b/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h
index 5ffb38f..45d8ee6 100644
--- a/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h
+++ b/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h
@@ -273,16 +273,10 @@
             vector<FrontendStatusType> types;
             vector<FrontendStatus> statuses;
 
-            types.push_back(FrontendStatusType::DEMOD_LOCK);
             types.push_back(FrontendStatusType::UEC);
-            types.push_back(FrontendStatusType::IS_MISO);
 
             FrontendStatus status;
-            status.set<FrontendStatus::Tag::isDemodLocked>(true);
-            statuses.push_back(status);
-            status.set<FrontendStatus::Tag::uec>(4);
-            statuses.push_back(status);
-            status.set<FrontendStatus::Tag::isMiso>(true);
+            status.set<FrontendStatus::Tag::uec>(0);
             statuses.push_back(status);
 
             auto frontends = *hardwareConfig.getFirstFrontends();
diff --git a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvTypes.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvTypes.aidl
index d02cf4d..bb543f2 100644
--- a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvTypes.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvTypes.aidl
@@ -46,4 +46,5 @@
   NB_OF_ELEVATION_MEASUREMENTS = 0xE5,
   ENABLE_DIAGNOSTICS = 0xE8,
   DIAGRAMS_FRAME_REPORTS_FIELDS = 0xE9,
+  ANTENNA_MODE = 0xEA,
 }
diff --git a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvTypes.aidl b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvTypes.aidl
index 65bb1c9..b8b4490 100644
--- a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvTypes.aidl
+++ b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvTypes.aidl
@@ -87,4 +87,12 @@
      * b3 - b7: RFU
      */
     DIAGRAMS_FRAME_REPORTS_FIELDS = 0xE9,
+
+    /**
+     * 1 byte data
+     * 0x0: Omni mode - the ranging antenna is used for both Tx and Rx.
+     * 0x1: Directional mode - the patch antenna is used for both Tx and Rx.
+     * 0x2 - 0xFF: RFU
+     */
+    ANTENNA_MODE = 0xEA,
 }
diff --git a/uwb/aidl/default/src/uwb_chip.rs b/uwb/aidl/default/src/uwb_chip.rs
index d1c3c67..956cf6c 100644
--- a/uwb/aidl/default/src/uwb_chip.rs
+++ b/uwb/aidl/default/src/uwb_chip.rs
@@ -71,7 +71,7 @@
             let packet_vec: Vec<UciControlPacketHal> = packet.into();
             for hal_packet in packet_vec.into_iter() {
                 serial
-                    .write(&hal_packet.to_vec())
+                    .write(&hal_packet.encode_to_vec().unwrap())
                     .map(|written| written as i32)
                     .map_err(|_| binder::StatusCode::UNKNOWN_ERROR)?;
             }
@@ -180,6 +180,8 @@
             let mut reader = AsyncFd::new(reader).unwrap();
 
             loop {
+                const MESSAGE_TYPE_MASK: u8 = 0b11100000;
+                const DATA_MESSAGE_TYPE: u8 = 0b000;
                 const UWB_HEADER_SIZE: usize = 4;
                 let mut buffer = vec![0; UWB_HEADER_SIZE];
 
@@ -224,12 +226,22 @@
                 // Read the remaining header bytes, if truncated.
                 read_exact(reader.get_mut(), &mut buffer[read_len..]).unwrap();
 
-                let length = buffer[3] as usize + UWB_HEADER_SIZE;
+                let common_header = buffer[0];
+                let mt = (common_header & MESSAGE_TYPE_MASK) >> 5;
+                let payload_length = if mt == DATA_MESSAGE_TYPE {
+                    let payload_length_fields: [u8; 2] = buffer[2..=3].try_into().unwrap();
+                    u16::from_le_bytes(payload_length_fields) as usize
+                } else {
+                    buffer[3] as usize
+                };
+
+                let length = payload_length + UWB_HEADER_SIZE;
                 buffer.resize(length, 0);
 
                 // Read the payload bytes.
                 read_exact(reader.get_mut(), &mut buffer[UWB_HEADER_SIZE..]).unwrap();
 
+                log::debug!(" <-- {:?}", buffer);
                 client_callbacks.onUciMessage(&buffer).unwrap();
             }
         });
@@ -284,10 +296,13 @@
         log::debug!("sendUciMessage");
 
         if let State::Opened { ref mut serial, .. } = &mut *self.state.lock().await {
-            serial
-                .write(data)
-                .map(|written| written as i32)
-                .map_err(|_| binder::StatusCode::UNKNOWN_ERROR.into())
+            log::debug!(" --> {:?}", data);
+            let result = serial
+                .write_all(data)
+                .map(|_| data.len() as i32)
+                .map_err(|_| binder::StatusCode::UNKNOWN_ERROR.into());
+            log::debug!(" status: {:?}", result);
+            result
         } else {
             Err(binder::ExceptionCode::ILLEGAL_STATE.into())
         }
diff --git a/uwb/aidl/vts/VtsHalUwbTargetTest.cpp b/uwb/aidl/vts/VtsHalUwbTargetTest.cpp
index 3b0b606..548cae0 100644
--- a/uwb/aidl/vts/VtsHalUwbTargetTest.cpp
+++ b/uwb/aidl/vts/VtsHalUwbTargetTest.cpp
@@ -39,6 +39,8 @@
 
 namespace {
 constexpr static int kCallbackTimeoutMs = 250;
+// this timeout should be same as AOSP stack timeout (HAL_OPEN_TIMEOUT_MS)
+constexpr static int kOpenCallbackTimeoutMs = 20000;
 }  // namespace
 
 class UwbClientCallback : public BnUwbClientCallback {
@@ -105,7 +107,7 @@
                         open_cb_promise.set_value();
                     }
                 });
-        std::chrono::milliseconds timeout{kCallbackTimeoutMs};
+        std::chrono::milliseconds timeout{kOpenCallbackTimeoutMs};
         const auto iuwb_chip = getAnyChip();
         EXPECT_TRUE(iuwb_chip->open(callback).isOk());
         EXPECT_EQ(open_cb_future.wait_for(timeout), std::future_status::ready);
@@ -137,7 +139,7 @@
                     open_cb_promise.set_value();
                 }
             });
-    std::chrono::milliseconds timeout{kCallbackTimeoutMs};
+    std::chrono::milliseconds timeout{kOpenCallbackTimeoutMs};
     const auto iuwb_chip = getAnyChip();
     EXPECT_TRUE(iuwb_chip->open(callback).isOk());
     EXPECT_EQ(open_cb_future.wait_for(timeout), std::future_status::ready);
@@ -158,12 +160,13 @@
                     close_cb_promise.set_value();
                 }
             });
-    std::chrono::milliseconds timeout{kCallbackTimeoutMs};
+    std::chrono::milliseconds open_timeout{kOpenCallbackTimeoutMs};
+    std::chrono::milliseconds close_timeout{kCallbackTimeoutMs};
     const auto iuwb_chip = getAnyChip();
     EXPECT_TRUE(iuwb_chip->open(callback).isOk());
-    EXPECT_EQ(open_cb_future.wait_for(timeout), std::future_status::ready);
+    EXPECT_EQ(open_cb_future.wait_for(open_timeout), std::future_status::ready);
     EXPECT_TRUE(iuwb_chip->close().isOk());
-    EXPECT_EQ(close_cb_future.wait_for(timeout), std::future_status::ready);
+    EXPECT_EQ(close_cb_future.wait_for(close_timeout), std::future_status::ready);
 }
 
 TEST_P(UwbAidl, ChipCoreInit) {
diff --git a/wifi/aidl/default/wifi_legacy_hal.cpp b/wifi/aidl/default/wifi_legacy_hal.cpp
index 55d6f59..cf86120 100644
--- a/wifi/aidl/default/wifi_legacy_hal.cpp
+++ b/wifi/aidl/default/wifi_legacy_hal.cpp
@@ -1867,9 +1867,8 @@
     return {capabs, status};
 }
 
-wifi_error WifiLegacyHal::twtSessionSetup(
-        const std::string& ifaceName, uint32_t cmdId, const wifi_twt_request& request,
-        const on_twt_failure& on_twt_failure_user_callback,
+wifi_error WifiLegacyHal::twtRegisterEvents(
+        const std::string& ifaceName, const on_twt_failure& on_twt_failure_user_callback,
         const on_twt_session_create& on_twt_session_create_user_callback,
         const on_twt_session_update& on_twt_session_update_user_callback,
         const on_twt_session_teardown& on_twt_session_teardown_user_callback,
@@ -1921,13 +1920,18 @@
         on_twt_session_resume_user_callback(id, session_id);
     };
 
-    return global_func_table_.wifi_twt_session_setup(
-            cmdId, getIfaceHandle(ifaceName), request,
+    return global_func_table_.wifi_twt_register_events(
+            getIfaceHandle(ifaceName),
             {onAsyncTwtError, onAsyncTwtSessionCreate, onAsyncTwtSessionUpdate,
              onAsyncTwtSessionTeardown, onAsyncTwtSessionStats, onAsyncTwtSessionSuspend,
              onAsyncTwtSessionResume});
 }
 
+wifi_error WifiLegacyHal::twtSessionSetup(const std::string& ifaceName, uint32_t cmdId,
+                                          const wifi_twt_request& request) {
+    return global_func_table_.wifi_twt_session_setup(cmdId, getIfaceHandle(ifaceName), request);
+}
+
 wifi_error WifiLegacyHal::twtSessionUpdate(const std::string& ifaceName, uint32_t cmdId,
                                            uint32_t sessionId, const wifi_twt_request& request) {
     return global_func_table_.wifi_twt_session_update(cmdId, getIfaceHandle(ifaceName), sessionId,
diff --git a/wifi/aidl/default/wifi_legacy_hal.h b/wifi/aidl/default/wifi_legacy_hal.h
index 121d1b5..3fd567b 100644
--- a/wifi/aidl/default/wifi_legacy_hal.h
+++ b/wifi/aidl/default/wifi_legacy_hal.h
@@ -780,15 +780,16 @@
 
     // TWT functions
     std::pair<wifi_twt_capabilities, wifi_error> twtGetCapabilities(const std::string& ifaceName);
+    wifi_error twtRegisterEvents(
+            const std::string& ifaceName, const on_twt_failure& on_twt_failure_user_callback,
+            const on_twt_session_create& on_twt_session_create_user_callback,
+            const on_twt_session_update& on_twt_session_update_user_callback,
+            const on_twt_session_teardown& on_twt_session_teardown_user_callback,
+            const on_twt_session_stats& on_twt_session_stats_user_callback,
+            const on_twt_session_suspend& on_twt_session_suspend_user_callback,
+            const on_twt_session_resume& on_twt_session_resume_user_callback);
     wifi_error twtSessionSetup(const std::string& ifaceName, uint32_t cmdId,
-                               const wifi_twt_request& request,
-                               const on_twt_failure& on_twt_failure_user_callback,
-                               const on_twt_session_create& on_twt_session_create_user_callback,
-                               const on_twt_session_update& on_twt_session_update_user_callback,
-                               const on_twt_session_teardown& on_twt_session_teardown_user_callback,
-                               const on_twt_session_stats& on_twt_session_stats_user_callback,
-                               const on_twt_session_suspend& on_twt_session_suspend_user_callback,
-                               const on_twt_session_resume& on_twt_session_resume_user_callback);
+                               const wifi_twt_request& request);
     wifi_error twtSessionUpdate(const std::string& ifaceName, uint32_t cmdId, uint32_t sessionId,
                                 const wifi_twt_request& request);
     wifi_error twtSessionSuspend(const std::string& ifaceName, uint32_t cmdId, uint32_t sessionId);
@@ -797,7 +798,7 @@
     wifi_error twtSessionGetStats(const std::string& ifaceName, uint32_t cmdId, uint32_t sessionId);
 
     // Note: Following TWT functions are deprecated
-    // Deprecated
+    // Deprecated by twtRegisterEvegnts
     wifi_error twtRegisterHandler(const std::string& iface_name,
                                   const TwtCallbackHandlers& handler);
     // Deprecated by twtGetCapabilities
diff --git a/wifi/aidl/default/wifi_legacy_hal_stubs.cpp b/wifi/aidl/default/wifi_legacy_hal_stubs.cpp
index 73ea088..878abf0 100644
--- a/wifi/aidl/default/wifi_legacy_hal_stubs.cpp
+++ b/wifi/aidl/default/wifi_legacy_hal_stubs.cpp
@@ -182,6 +182,7 @@
     populateStubFor(&hal_fn->wifi_get_rtt_capabilities_v3);
     populateStubFor(&hal_fn->wifi_rtt_range_request_v3);
     populateStubFor(&hal_fn->wifi_twt_get_capabilities);
+    populateStubFor(&hal_fn->wifi_twt_register_events);
     populateStubFor(&hal_fn->wifi_twt_session_setup);
     populateStubFor(&hal_fn->wifi_twt_session_update);
     populateStubFor(&hal_fn->wifi_twt_session_suspend);
diff --git a/wifi/aidl/default/wifi_sta_iface.cpp b/wifi/aidl/default/wifi_sta_iface.cpp
index aee183d..85e373c 100644
--- a/wifi/aidl/default/wifi_sta_iface.cpp
+++ b/wifi/aidl/default/wifi_sta_iface.cpp
@@ -31,7 +31,11 @@
 WifiStaIface::WifiStaIface(const std::string& ifname,
                            const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
                            const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util)
-    : ifname_(ifname), legacy_hal_(legacy_hal), iface_util_(iface_util), is_valid_(true) {
+    : ifname_(ifname),
+      legacy_hal_(legacy_hal),
+      iface_util_(iface_util),
+      is_valid_(true),
+      is_twt_registered_(false) {
     // Turn on DFS channel usage for STA iface.
     legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->setDfsFlag(ifname_, true);
     if (legacy_status != legacy_hal::WIFI_SUCCESS) {
@@ -266,11 +270,150 @@
     return {ifname_, ndk::ScopedAStatus::ok()};
 }
 
+ndk::ScopedAStatus WifiStaIface::registerTwtEventCallbackInternal() {
+    std::weak_ptr<WifiStaIface> weak_ptr_this = weak_ptr_this_;
+
+    // onTwtFailure callback
+    const auto& on_twt_failure = [weak_ptr_this](legacy_hal::wifi_request_id id,
+                                                 legacy_hal::wifi_twt_error_code error_code) {
+        const auto shared_ptr_this = weak_ptr_this.lock();
+        IWifiStaIfaceEventCallback::TwtErrorCode aidl_error_code =
+                aidl_struct_util::convertLegacyHalTwtErrorCodeToAidl(error_code);
+        if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+            LOG(ERROR) << "Callback invoked on an invalid object";
+            return;
+        }
+        for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+            if (!callback->onTwtFailure(id, aidl_error_code).isOk()) {
+                LOG(ERROR) << "Failed to invoke onTwtFailure callback";
+            }
+        }
+    };
+    // onTwtSessionCreate callback
+    const auto& on_twt_session_create = [weak_ptr_this](legacy_hal::wifi_request_id id,
+                                                        legacy_hal::wifi_twt_session twt_session) {
+        const auto shared_ptr_this = weak_ptr_this.lock();
+        TwtSession aidl_twt_session;
+        if (!aidl_struct_util::convertLegacyHalTwtSessionToAidl(twt_session, &aidl_twt_session)) {
+            LOG(ERROR) << "convertLegacyHalTwtSessionToAidl failed";
+            return;
+        }
+
+        if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+            LOG(ERROR) << "Callback invoked on an invalid object";
+            return;
+        }
+        for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+            if (!callback->onTwtSessionCreate(id, aidl_twt_session).isOk()) {
+                LOG(ERROR) << "Failed to invoke onTwtSessionCreate callback";
+            }
+        }
+    };
+    // onTwtSessionUpdate callback
+    const auto& on_twt_session_update = [weak_ptr_this](legacy_hal::wifi_request_id id,
+                                                        legacy_hal::wifi_twt_session twt_session) {
+        const auto shared_ptr_this = weak_ptr_this.lock();
+        TwtSession aidl_twt_session;
+        if (!aidl_struct_util::convertLegacyHalTwtSessionToAidl(twt_session, &aidl_twt_session)) {
+            LOG(ERROR) << "convertLegacyHalTwtSessionToAidl failed";
+            return;
+        }
+
+        if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+            LOG(ERROR) << "Callback invoked on an invalid object";
+            return;
+        }
+        for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+            if (!callback->onTwtSessionUpdate(id, aidl_twt_session).isOk()) {
+                LOG(ERROR) << "Failed to invoke onTwtSessionUpdate callback";
+            }
+        }
+    };
+    // onTwtSessionTeardown callback
+    const auto& on_twt_session_teardown =
+            [weak_ptr_this](legacy_hal::wifi_request_id id, int session_id,
+                            legacy_hal::wifi_twt_teardown_reason_code reason_code) {
+                const auto shared_ptr_this = weak_ptr_this.lock();
+                IWifiStaIfaceEventCallback::TwtTeardownReasonCode aidl_reason_code =
+                        aidl_struct_util::convertLegacyHalTwtReasonCodeToAidl(reason_code);
+                if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+                    LOG(ERROR) << "Callback invoked on an invalid object";
+                    return;
+                }
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->onTwtSessionTeardown(id, session_id, aidl_reason_code).isOk()) {
+                        LOG(ERROR) << "Failed to invoke onTwtSessionTeardown callback";
+                    }
+                }
+            };
+    // onTwtSessionStats callback
+    const auto& on_twt_session_stats = [weak_ptr_this](legacy_hal::wifi_request_id id,
+                                                       int session_id,
+                                                       legacy_hal::wifi_twt_session_stats stats) {
+        const auto shared_ptr_this = weak_ptr_this.lock();
+        TwtSessionStats aidl_session_stats;
+        if (!aidl_struct_util::convertLegacyHalTwtSessionStatsToAidl(stats, &aidl_session_stats)) {
+            LOG(ERROR) << "convertLegacyHalTwtSessionStatsToAidl failed";
+            return;
+        }
+        if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+            LOG(ERROR) << "Callback invoked on an invalid object";
+            return;
+        }
+        for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+            if (!callback->onTwtSessionStats(id, session_id, aidl_session_stats).isOk()) {
+                LOG(ERROR) << "Failed to invoke onTwtSessionStats callback";
+            }
+        }
+    };
+    // onTwtSessionSuspend callback
+    const auto& on_twt_session_suspend = [weak_ptr_this](legacy_hal::wifi_request_id id,
+                                                         int session_id) {
+        const auto shared_ptr_this = weak_ptr_this.lock();
+        if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+            LOG(ERROR) << "Callback invoked on an invalid object";
+            return;
+        }
+        for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+            if (!callback->onTwtSessionSuspend(id, session_id).isOk()) {
+                LOG(ERROR) << "Failed to invoke onTwtSessionSuspend callback";
+            }
+        }
+    };
+    // onTwtSessionResume callback
+    const auto& on_twt_session_resume = [weak_ptr_this](legacy_hal::wifi_request_id id,
+                                                        int session_id) {
+        const auto shared_ptr_this = weak_ptr_this.lock();
+        if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+            LOG(ERROR) << "Callback invoked on an invalid object";
+            return;
+        }
+        for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+            if (!callback->onTwtSessionResume(id, session_id).isOk()) {
+                LOG(ERROR) << "Failed to invoke onTwtSessionResume callback";
+            }
+        }
+    };
+
+    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->twtRegisterEvents(
+            ifname_, on_twt_failure, on_twt_session_create, on_twt_session_update,
+            on_twt_session_teardown, on_twt_session_stats, on_twt_session_suspend,
+            on_twt_session_resume);
+
+    if (legacy_status == legacy_hal::WIFI_ERROR_NOT_SUPPORTED) {
+        LOG(INFO) << "twtRegisterEvents is not supported" << legacy_status;
+    } else if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+        LOG(ERROR) << "twtRegisterEvents failed - %d" << legacy_status;
+    }
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
 ndk::ScopedAStatus WifiStaIface::registerEventCallbackInternal(
         const std::shared_ptr<IWifiStaIfaceEventCallback>& callback) {
     if (!event_cb_handler_.addCallback(callback)) {
         return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
     }
+    is_twt_registered_ = registerTwtEventCallbackInternal().isOk();
     return ndk::ScopedAStatus::ok();
 }
 
@@ -617,138 +760,16 @@
 
 ndk::ScopedAStatus WifiStaIface::twtSessionSetupInternal(int32_t cmdId,
                                                          const TwtRequest& aidlTwtRequest) {
+    if (!is_twt_registered_) {
+        LOG(INFO) << "twtSessionSetup is not supported as twtRegisterEvents failed";
+        return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
+    }
     legacy_hal::wifi_twt_request legacyHalTwtRequest;
     if (!aidl_struct_util::convertAidlTwtRequestToLegacy(aidlTwtRequest, &legacyHalTwtRequest)) {
         return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
     }
-    std::weak_ptr<WifiStaIface> weak_ptr_this = weak_ptr_this_;
-
-    // onTwtFailure callback
-    const auto& on_twt_failure = [weak_ptr_this](legacy_hal::wifi_request_id id,
-                                                 legacy_hal::wifi_twt_error_code error_code) {
-        const auto shared_ptr_this = weak_ptr_this.lock();
-        IWifiStaIfaceEventCallback::TwtErrorCode aidl_error_code =
-                aidl_struct_util::convertLegacyHalTwtErrorCodeToAidl(error_code);
-        if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-            LOG(ERROR) << "Callback invoked on an invalid object";
-            return;
-        }
-        for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-            if (!callback->onTwtFailure(id, aidl_error_code).isOk()) {
-                LOG(ERROR) << "Failed to invoke onTwtFailure callback";
-            }
-        }
-    };
-    // onTwtSessionCreate callback
-    const auto& on_twt_session_create = [weak_ptr_this](legacy_hal::wifi_request_id id,
-                                                        legacy_hal::wifi_twt_session twt_session) {
-        const auto shared_ptr_this = weak_ptr_this.lock();
-        TwtSession aidl_twt_session;
-        if (!aidl_struct_util::convertLegacyHalTwtSessionToAidl(twt_session, &aidl_twt_session)) {
-            LOG(ERROR) << "convertLegacyHalTwtSessionToAidl failed";
-            return;
-        }
-
-        if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-            LOG(ERROR) << "Callback invoked on an invalid object";
-            return;
-        }
-        for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-            if (!callback->onTwtSessionCreate(id, aidl_twt_session).isOk()) {
-                LOG(ERROR) << "Failed to invoke onTwtSessionCreate callback";
-            }
-        }
-    };
-    // onTwtSessionUpdate callback
-    const auto& on_twt_session_update = [weak_ptr_this](legacy_hal::wifi_request_id id,
-                                                        legacy_hal::wifi_twt_session twt_session) {
-        const auto shared_ptr_this = weak_ptr_this.lock();
-        TwtSession aidl_twt_session;
-        if (!aidl_struct_util::convertLegacyHalTwtSessionToAidl(twt_session, &aidl_twt_session)) {
-            LOG(ERROR) << "convertLegacyHalTwtSessionToAidl failed";
-            return;
-        }
-
-        if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-            LOG(ERROR) << "Callback invoked on an invalid object";
-            return;
-        }
-        for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-            if (!callback->onTwtSessionUpdate(id, aidl_twt_session).isOk()) {
-                LOG(ERROR) << "Failed to invoke onTwtSessionUpdate callback";
-            }
-        }
-    };
-    // onTwtSessionTeardown callback
-    const auto& on_twt_session_teardown =
-            [weak_ptr_this](legacy_hal::wifi_request_id id, int session_id,
-                            legacy_hal::wifi_twt_teardown_reason_code reason_code) {
-                const auto shared_ptr_this = weak_ptr_this.lock();
-                IWifiStaIfaceEventCallback::TwtTeardownReasonCode aidl_reason_code =
-                        aidl_struct_util::convertLegacyHalTwtReasonCodeToAidl(reason_code);
-                if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-                    LOG(ERROR) << "Callback invoked on an invalid object";
-                    return;
-                }
-                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-                    if (!callback->onTwtSessionTeardown(id, session_id, aidl_reason_code).isOk()) {
-                        LOG(ERROR) << "Failed to invoke onTwtSessionTeardown callback";
-                    }
-                }
-            };
-    // onTwtSessionStats callback
-    const auto& on_twt_session_stats = [weak_ptr_this](legacy_hal::wifi_request_id id,
-                                                       int session_id,
-                                                       legacy_hal::wifi_twt_session_stats stats) {
-        const auto shared_ptr_this = weak_ptr_this.lock();
-        TwtSessionStats aidl_session_stats;
-        if (!aidl_struct_util::convertLegacyHalTwtSessionStatsToAidl(stats, &aidl_session_stats)) {
-            LOG(ERROR) << "convertLegacyHalTwtSessionStatsToAidl failed";
-            return;
-        }
-        if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-            LOG(ERROR) << "Callback invoked on an invalid object";
-            return;
-        }
-        for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-            if (!callback->onTwtSessionStats(id, session_id, aidl_session_stats).isOk()) {
-                LOG(ERROR) << "Failed to invoke onTwtSessionStats callback";
-            }
-        }
-    };
-    // onTwtSessionSuspend callback
-    const auto& on_twt_session_suspend = [weak_ptr_this](legacy_hal::wifi_request_id id,
-                                                         int session_id) {
-        const auto shared_ptr_this = weak_ptr_this.lock();
-        if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-            LOG(ERROR) << "Callback invoked on an invalid object";
-            return;
-        }
-        for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-            if (!callback->onTwtSessionSuspend(id, session_id).isOk()) {
-                LOG(ERROR) << "Failed to invoke onTwtSessionSuspend callback";
-            }
-        }
-    };
-    // onTwtSessionResume callback
-    const auto& on_twt_session_resume = [weak_ptr_this](legacy_hal::wifi_request_id id,
-                                                        int session_id) {
-        const auto shared_ptr_this = weak_ptr_this.lock();
-        if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-            LOG(ERROR) << "Callback invoked on an invalid object";
-            return;
-        }
-        for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-            if (!callback->onTwtSessionResume(id, session_id).isOk()) {
-                LOG(ERROR) << "Failed to invoke onTwtSessionResume callback";
-            }
-        }
-    };
-
-    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->twtSessionSetup(
-            ifname_, cmdId, legacyHalTwtRequest, on_twt_failure, on_twt_session_create,
-            on_twt_session_update, on_twt_session_teardown, on_twt_session_stats,
-            on_twt_session_suspend, on_twt_session_resume);
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->twtSessionSetup(ifname_, cmdId, legacyHalTwtRequest);
     return createWifiStatusFromLegacyError(legacy_status);
 }
 
diff --git a/wifi/aidl/default/wifi_sta_iface.h b/wifi/aidl/default/wifi_sta_iface.h
index eb8f745..5713928 100644
--- a/wifi/aidl/default/wifi_sta_iface.h
+++ b/wifi/aidl/default/wifi_sta_iface.h
@@ -103,6 +103,7 @@
   private:
     // Corresponding worker functions for the AIDL methods.
     std::pair<std::string, ndk::ScopedAStatus> getNameInternal();
+    ndk::ScopedAStatus registerTwtEventCallbackInternal();
     ndk::ScopedAStatus registerEventCallbackInternal(
             const std::shared_ptr<IWifiStaIfaceEventCallback>& callback);
     std::pair<int32_t, ndk::ScopedAStatus> getFeatureSetInternal();
@@ -157,6 +158,7 @@
     std::weak_ptr<WifiStaIface> weak_ptr_this_;
     bool is_valid_;
     aidl_callback_util::AidlCallbackHandler<IWifiStaIfaceEventCallback> event_cb_handler_;
+    bool is_twt_registered_;
 
     DISALLOW_COPY_AND_ASSIGN(WifiStaIface);
 };
diff --git a/wifi/legacy_headers/Android.bp b/wifi/legacy_headers/Android.bp
new file mode 100644
index 0000000..725d42c
--- /dev/null
+++ b/wifi/legacy_headers/Android.bp
@@ -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.
+
+cc_library_headers {
+    name: "wifi_legacy_headers",
+    vendor_available: true,
+    export_include_dirs: ["include"],
+
+    header_libs: ["libcutils_headers"],
+    export_header_lib_headers: ["libcutils_headers"],
+}
+
+cc_library_shared {
+    name: "wifi_legacy",
+    vendor_available: true,
+
+    header_libs: [
+        "wifi_legacy_headers",
+    ],
+    export_header_lib_headers: ["wifi_legacy_headers"],
+
+    export_include_dirs: ["include"],
+
+    cflags: [
+        "-DQEMU_HARDWARE",
+        "-Wall",
+        "-Werror",
+    ],
+}
diff --git a/wifi/legacy_headers/include/hardware_legacy/gscan.h b/wifi/legacy_headers/include/hardware_legacy/gscan.h
new file mode 100644
index 0000000..d5d8b9c
--- /dev/null
+++ b/wifi/legacy_headers/include/hardware_legacy/gscan.h
@@ -0,0 +1,430 @@
+#include "wifi_hal.h"
+
+#ifndef __WIFI_HAL_GSCAN_H__
+#define __WIFI_HAL_GSCAN_H__
+
+// Define static_assert() unless already defined by compiler.
+#ifndef __has_feature
+    #define __has_feature(__x) 0
+#endif
+#if !(__has_feature(cxx_static_assert)) && !defined(static_assert)
+        #define static_assert(__b, __m) \
+                extern int compile_time_assert_failed[ ( __b ) ? 1 : -1 ]  \
+                                                                   __attribute__( ( unused ) );
+#endif
+
+/* AP Scans */
+
+typedef enum {
+    WIFI_BAND_UNSPECIFIED,
+    WIFI_BAND_BG = 1,                       // 2.4 GHz
+    WIFI_BAND_A = 2,                        // 5 GHz without DFS
+    WIFI_BAND_A_DFS = 4,                    // 5 GHz DFS only
+    WIFI_BAND_A_WITH_DFS = 6,               // 5 GHz with DFS
+    WIFI_BAND_ABG = 3,                      // 2.4 GHz + 5 GHz; no DFS
+    WIFI_BAND_ABG_WITH_DFS = 7,             // 2.4 GHz + 5 GHz with DFS
+} wifi_band;
+
+#define MAX_CHANNELS                16
+#define MAX_BUCKETS                 16
+#define MAX_HOTLIST_APS             128
+#define MAX_SIGNIFICANT_CHANGE_APS  64
+#define MAX_EPNO_NETWORKS           64
+#define MAX_HOTLIST_SSID            8
+#define MAX_AP_CACHE_PER_SCAN       32
+
+wifi_error wifi_get_valid_channels(wifi_interface_handle handle,
+        int band, int max_channels, wifi_channel *channels, int *num_channels);
+
+typedef struct {
+    int max_scan_cache_size;                 // total space allocated for scan (in bytes)
+    int max_scan_buckets;                    // maximum number of channel buckets
+    int max_ap_cache_per_scan;               // maximum number of APs that can be stored per scan
+    int max_rssi_sample_size;                // number of RSSI samples used for averaging RSSI
+    int max_scan_reporting_threshold;        // max possible report_threshold as described
+                                             // in wifi_scan_cmd_params
+    int max_hotlist_bssids;                  // maximum number of entries for hotlist BSSIDs
+    int max_hotlist_ssids;                   // maximum number of entries for hotlist SSIDs
+    int max_significant_wifi_change_aps;     // maximum number of entries for
+                                             // significant wifi change APs
+    int max_bssid_history_entries;           // number of BSSID/RSSI entries that device can hold
+    int max_number_epno_networks;            // max number of epno entries
+    int max_number_epno_networks_by_ssid;    // max number of epno entries if ssid is specified,
+                                             // that is, epno entries for which an exact match is
+                                             // required, or entries corresponding to hidden ssids
+    int max_number_of_white_listed_ssid;     // max number of white listed SSIDs, M target is 2 to 4
+} wifi_gscan_capabilities;
+
+wifi_error wifi_get_gscan_capabilities(wifi_interface_handle handle,
+        wifi_gscan_capabilities *capabilities);
+
+typedef enum {
+    WIFI_SCAN_RESULTS_AVAILABLE,   // reported when REPORT_EVENTS_EACH_SCAN is set and a scan
+                                   // completes. WIFI_SCAN_THRESHOLD_NUM_SCANS or
+                                   // WIFI_SCAN_THRESHOLD_PERCENT can be reported instead if the
+                                   // reason for the event is available; however, at most one of
+                                   // these events should be reported per scan. If there are
+                                   // multiple buckets that were scanned this period and one has the
+                                   // EACH_SCAN flag set then this event should be prefered.
+    WIFI_SCAN_THRESHOLD_NUM_SCANS, // can be reported when REPORT_EVENTS_EACH_SCAN is not set and
+                                   // report_threshold_num_scans is reached.
+    WIFI_SCAN_THRESHOLD_PERCENT,   // can be reported when REPORT_EVENTS_EACH_SCAN is not set and
+                                   // report_threshold_percent is reached.
+    WIFI_SCAN_FAILED,              // reported when currently executing gscans have failed.
+                                   // start_gscan will need to be called again in order to continue
+                                   // scanning. This is intended to indicate abnormal scan
+                                   // terminations (not those as a result of stop_gscan).
+} wifi_scan_event;
+
+
+/* Format of information elements found in the beacon */
+typedef struct {
+    byte id;                            // element identifier
+    byte len;                           // number of bytes to follow
+    byte data[];
+} wifi_information_element;
+
+typedef struct {
+    wifi_timestamp ts;                  // time since boot (in microsecond) when the result was
+                                        // retrieved
+    char ssid[32+1];                    // null terminated
+    mac_addr bssid;
+    wifi_channel channel;               // channel frequency in MHz
+    wifi_rssi rssi;                     // in db
+    wifi_timespan rtt;                  // in nanoseconds
+    wifi_timespan rtt_sd;               // standard deviation in rtt
+    unsigned short beacon_period;       // period advertised in the beacon
+    unsigned short capability;          // capabilities advertised in the beacon
+    unsigned int ie_length;             // size of the ie_data blob
+    char         ie_data[1];            // blob of all the information elements found in the
+                                        // beacon; this data should be a packed list of
+                                        // wifi_information_element objects, one after the other.
+    // other fields
+} wifi_scan_result;
+
+static_assert(MAX_BUCKETS <= 8 * sizeof(unsigned),
+        "The buckets_scanned bitset is represented by an unsigned int and cannot support this many "
+        "buckets on this platform.");
+typedef struct {
+    /* reported when each probe response is received, if report_events
+     * enabled in wifi_scan_cmd_params. buckets_scanned is a bitset of the
+     * buckets that are currently being scanned. See the buckets_scanned field
+     * in the wifi_cached_scan_results struct for more details.
+     */
+    void (*on_full_scan_result) (wifi_request_id id, wifi_scan_result *result,
+                                 unsigned buckets_scanned);
+
+    /* indicates progress of scanning statemachine */
+    void (*on_scan_event) (wifi_request_id id, wifi_scan_event event);
+
+} wifi_scan_result_handler;
+
+typedef struct {
+    wifi_channel channel;               // frequency
+    int dwellTimeMs;                    // dwell time hint
+    int passive;                        // 0 => active, 1 => passive scan; ignored for DFS
+    /* Add channel class */
+} wifi_scan_channel_spec;
+
+#define REPORT_EVENTS_EACH_SCAN        (1 << 0)
+#define REPORT_EVENTS_FULL_RESULTS     (1 << 1)
+#define REPORT_EVENTS_NO_BATCH         (1 << 2)
+
+typedef struct {
+    int bucket;                         // bucket index, 0 based
+    wifi_band band;                     // when UNSPECIFIED, use channel list
+    int period;                         // desired period, in millisecond; if this is too
+                                        // low, the firmware should choose to generate results as
+                                        // fast as it can instead of failing the command.
+                                        // for exponential backoff bucket this is the min_period
+    /* report_events semantics -
+     *  This is a bit field; which defines following bits -
+     *  REPORT_EVENTS_EACH_SCAN    => report a scan completion event after scan. If this is not set
+     *                                 then scan completion events should be reported if
+     *                                 report_threshold_percent or report_threshold_num_scans is
+     *                                 reached.
+     *  REPORT_EVENTS_FULL_RESULTS => forward scan results (beacons/probe responses + IEs)
+     *                                 in real time to HAL, in addition to completion events
+     *                                 Note: To keep backward compatibility, fire completion
+     *                                 events regardless of REPORT_EVENTS_EACH_SCAN.
+     *  REPORT_EVENTS_NO_BATCH     => controls if scans for this bucket should be placed in the
+     *                                 history buffer
+     */
+    byte report_events;
+    int max_period; // if max_period is non zero or different than period, then this bucket is
+                    // an exponential backoff bucket and the scan period will grow exponentially
+                    // as per formula: actual_period(N) = period * (base ^ (N/step_count))
+                    // to a maximum period of max_period
+    int base;       // for exponential back off bucket: multiplier: new_period=old_period*base
+    int step_count; // for exponential back off bucket, number of scans to perform for a given
+                    // period
+
+    int num_channels;
+    // channels to scan; these may include DFS channels
+    // Note that a given channel may appear in multiple buckets
+    wifi_scan_channel_spec channels[MAX_CHANNELS];
+} wifi_scan_bucket_spec;
+
+typedef struct {
+    int base_period;                    // base timer period in ms
+    int max_ap_per_scan;                // number of access points to store in each scan entry in
+                                        // the BSSID/RSSI history buffer (keep the highest RSSI
+                                        // access points)
+    int report_threshold_percent;       // in %, when scan buffer is this much full, wake up apps
+                                        // processor
+    int report_threshold_num_scans;     // in number of scans, wake up AP after these many scans
+    int num_buckets;
+    wifi_scan_bucket_spec buckets[MAX_BUCKETS];
+} wifi_scan_cmd_params;
+
+/*
+ * Start periodic GSCAN
+ * When this is called all requested buckets should be scanned, starting the beginning of the cycle
+ *
+ * For example:
+ * If there are two buckets specified
+ *  - Bucket 1: period=10s
+ *  - Bucket 2: period=20s
+ *  - Bucket 3: period=30s
+ * Then the following scans should occur
+ *  - t=0  buckets 1, 2, and 3 are scanned
+ *  - t=10 bucket 1 is scanned
+ *  - t=20 bucket 1 and 2 are scanned
+ *  - t=30 bucket 1 and 3 are scanned
+ *  - t=40 bucket 1 and 2 are scanned
+ *  - t=50 bucket 1 is scanned
+ *  - t=60 buckets 1, 2, and 3 are scanned
+ *  - and the patter repeats
+ *
+ * If any scan does not occur or is incomplete (error, interrupted, etc) then a cached scan result
+ * should still be recorded with the WIFI_SCAN_FLAG_INTERRUPTED flag set.
+ */
+wifi_error wifi_start_gscan(wifi_request_id id, wifi_interface_handle iface,
+        wifi_scan_cmd_params params, wifi_scan_result_handler handler);
+
+/* Stop periodic GSCAN */
+wifi_error wifi_stop_gscan(wifi_request_id id, wifi_interface_handle iface);
+
+typedef enum {
+    WIFI_SCAN_FLAG_INTERRUPTED = 1      // Indicates that scan results are not complete because
+                                        // probes were not sent on some channels
+} wifi_scan_flags;
+
+/* Get the GSCAN cached scan results */
+typedef struct {
+    int scan_id;                                     // a unique identifier for the scan unit
+    int flags;                                       // a bitmask with additional
+                                                     // information about scan.
+    unsigned buckets_scanned;                        // a bitset of the buckets that were scanned.
+                                                     // for example a value of 13 (0b1101) would
+                                                     // indicate that buckets 0, 2 and 3 were
+                                                     // scanned to produce this list of results.
+                                                     // should be set to 0 if this information is
+                                                     // not available.
+    int num_results;                                 // number of bssids retrieved by the scan
+    wifi_scan_result results[MAX_AP_CACHE_PER_SCAN]; // scan results - one for each bssid
+} wifi_cached_scan_results;
+
+wifi_error wifi_get_cached_gscan_results(wifi_interface_handle iface, byte flush,
+        int max, wifi_cached_scan_results *results, int *num);
+
+/* BSSID Hotlist */
+typedef struct {
+    void (*on_hotlist_ap_found)(wifi_request_id id,
+            unsigned num_results, wifi_scan_result *results);
+    void (*on_hotlist_ap_lost)(wifi_request_id id,
+            unsigned num_results, wifi_scan_result *results);
+} wifi_hotlist_ap_found_handler;
+
+typedef struct {
+    mac_addr  bssid;                    // AP BSSID
+    wifi_rssi low;                      // low threshold
+    wifi_rssi high;                     // high threshold
+} ap_threshold_param;
+
+typedef struct {
+    int lost_ap_sample_size;
+    int num_bssid;                                 // number of hotlist APs
+    ap_threshold_param ap[MAX_HOTLIST_APS];     // hotlist APs
+} wifi_bssid_hotlist_params;
+
+/* Set the BSSID Hotlist */
+wifi_error wifi_set_bssid_hotlist(wifi_request_id id, wifi_interface_handle iface,
+        wifi_bssid_hotlist_params params, wifi_hotlist_ap_found_handler handler);
+
+/* Clear the BSSID Hotlist */
+wifi_error wifi_reset_bssid_hotlist(wifi_request_id id, wifi_interface_handle iface);
+
+/* SSID Hotlist */
+typedef struct {
+    void (*on_hotlist_ssid_found)(wifi_request_id id,
+            unsigned num_results, wifi_scan_result *results);
+    void (*on_hotlist_ssid_lost)(wifi_request_id id,
+            unsigned num_results, wifi_scan_result *results);
+} wifi_hotlist_ssid_handler;
+
+typedef struct {
+    char  ssid[32+1];                   // SSID
+    wifi_band band;                     // band for this set of threshold params
+    wifi_rssi low;                      // low threshold
+    wifi_rssi high;                     // high threshold
+} ssid_threshold_param;
+
+typedef struct {
+    int lost_ssid_sample_size;
+    int num_ssid;                                   // number of hotlist SSIDs
+    ssid_threshold_param ssid[MAX_HOTLIST_SSID];    // hotlist SSIDs
+} wifi_ssid_hotlist_params;
+
+/* Significant wifi change */
+typedef struct {
+    mac_addr bssid;                     // BSSID
+    wifi_channel channel;               // channel frequency in MHz
+    int num_rssi;                       // number of rssi samples
+    wifi_rssi rssi[];                   // RSSI history in db
+} wifi_significant_change_result;
+
+typedef struct {
+    void (*on_significant_change)(wifi_request_id id,
+            unsigned num_results, wifi_significant_change_result **results);
+} wifi_significant_change_handler;
+
+// The sample size parameters in the wifi_significant_change_params structure
+// represent the number of occurence of a g-scan where the BSSID was seen and RSSI was
+// collected for that BSSID, or, the BSSID was expected to be seen and didn't.
+// for instance: lost_ap_sample_size : number of time a g-scan was performed on the
+// channel the BSSID was seen last, and the BSSID was not seen during those g-scans
+typedef struct {
+    int rssi_sample_size;               // number of samples for averaging RSSI
+    int lost_ap_sample_size;            // number of samples to confirm AP loss
+    int min_breaching;                  // number of APs breaching threshold
+    int num_bssid;                         // max 64
+    ap_threshold_param ap[MAX_SIGNIFICANT_CHANGE_APS];
+} wifi_significant_change_params;
+
+/* Set the Signifcant AP change list */
+wifi_error wifi_set_significant_change_handler(wifi_request_id id, wifi_interface_handle iface,
+        wifi_significant_change_params params, wifi_significant_change_handler handler);
+
+/* Clear the Signifcant AP change list */
+wifi_error wifi_reset_significant_change_handler(wifi_request_id id, wifi_interface_handle iface);
+
+/* Random MAC OUI for PNO */
+wifi_error wifi_set_scanning_mac_oui(wifi_interface_handle handle, oui scan_oui);
+
+
+// Enhanced PNO:
+// Enhanced PNO feature is expected to be enabled all of the time (e.g. screen lit) and may thus
+// require firmware to store a large number of networks, covering the whole list of known networks.
+// Therefore, it is acceptable for firmware to store a crc24, crc32 or other short hash of the SSID,
+// such that a low but non-zero probability of collision exist. With that scheme it should be
+// possible for firmware to keep an entry as small as 4 bytes for each pno network.
+// For instance, a firmware pn0 entry can be implemented in the form of:
+//          PNO ENTRY = crc24(3 bytes) | flags>>3 (5 bits) | auth flags(3 bits)
+//
+// No scans should be automatically performed by the chip. Instead all scan results from gscan
+// should be scored and the wifi_epno_handler on_network_found callback should be called with
+// the scan results.
+//
+// A PNO network shall be reported once, that is, once a network is reported by firmware
+// its entry shall be marked as "done" until framework calls wifi_set_epno_list again.
+// Calling wifi_set_epno_list shall reset the "done" status of pno networks in firmware.
+//
+// A network should only be considered found if its RSSI is above the minimum RSSI for its
+// frequency range (min5GHz_rssi and min24GHz_rssi for 5GHz and 2.4GHz networks respectively).
+// When disconnected the list of scan results should be returned if any network is found.
+// When connected the scan results shall be reported only if the score of any network in the scan
+// is greater than that of the currently connected BSSID.
+//
+// The FW should calculate the score of all the candidates (including currently connected one)
+//   with following equation:
+//     RSSI score = (RSSI + 85) * 4;
+//     If RSSI score > initial_score_max , RSSI score = initial_score_max;
+//     final score = RSSI score
+//         + current_connection_bonus (if currently connected BSSID)
+//         + same_network_bonus (if network has SAME_NETWORK flag)
+//         + secure_bonus (if the network is not open)
+//         + band5GHz_bonus (if BSSID is on 5G)
+//     If there is a BSSID’s score > current BSSID’s score, then report the cached scan results
+//         at the end of the scan (excluding the ones on blacklist) to the upper layer.
+// Additionally, all BSSIDs that are in the BSSID blacklist should be ignored by Enhanced PNO
+
+// Whether directed scan needs to be performed (for hidden SSIDs)
+#define WIFI_PNO_FLAG_DIRECTED_SCAN (1 << 0)
+// Whether PNO event shall be triggered if the network is found on A band
+#define WIFI_PNO_FLAG_A_BAND (1 << 1)
+// Whether PNO event shall be triggered if the network is found on G band
+#define WIFI_PNO_FLAG_G_BAND (1 << 2)
+// Whether strict matching is required
+// If required then the firmware must store the network's SSID and not just a hash
+#define WIFI_PNO_FLAG_STRICT_MATCH (1 << 3)
+// If this SSID should be considered the same network as the currently connected one for scoring
+#define WIFI_PNO_FLAG_SAME_NETWORK (1 << 4)
+
+// Code for matching the beacon AUTH IE - additional codes TBD
+#define WIFI_PNO_AUTH_CODE_OPEN  (1 << 0) // open
+#define WIFI_PNO_AUTH_CODE_PSK   (1 << 1) // WPA_PSK or WPA2PSK
+#define WIFI_PNO_AUTH_CODE_EAPOL (1 << 2) // any EAPOL
+
+typedef struct {
+    char ssid[32+1];     // null terminated
+    byte flags;          // WIFI_PNO_FLAG_XXX
+    byte auth_bit_field; // auth bit field for matching WPA IE
+} wifi_epno_network;
+
+/* ePNO Parameters */
+typedef struct {
+    int min5GHz_rssi;               // minimum 5GHz RSSI for a BSSID to be considered
+    int min24GHz_rssi;              // minimum 2.4GHz RSSI for a BSSID to be considered
+    int initial_score_max;          // the maximum score that a network can have before bonuses
+    int current_connection_bonus;   // only report when there is a network's score this much higher
+                                    // than the current connection.
+    int same_network_bonus;         // score bonus for all networks with the same network flag
+    int secure_bonus;               // score bonus for networks that are not open
+    int band5GHz_bonus;             // 5GHz RSSI score bonus (applied to all 5GHz networks)
+    int num_networks;               // number of wifi_epno_network objects
+    wifi_epno_network networks[MAX_EPNO_NETWORKS];   // PNO networks
+} wifi_epno_params;
+
+typedef struct {
+    // on results
+    void (*on_network_found)(wifi_request_id id,
+            unsigned num_results, wifi_scan_result *results);
+} wifi_epno_handler;
+
+
+/* Set the ePNO list - enable ePNO with the given parameters */
+wifi_error wifi_set_epno_list(wifi_request_id id, wifi_interface_handle iface,
+        const wifi_epno_params *epno_params, wifi_epno_handler handler);
+
+/* Reset the ePNO list - no ePNO networks should be matched after this */
+wifi_error wifi_reset_epno_list(wifi_request_id id, wifi_interface_handle iface);
+
+
+typedef struct {
+    int  id;                            // identifier of this network block, report this in event
+    char realm[256];                    // null terminated UTF8 encoded realm, 0 if unspecified
+    int64_t roamingConsortiumIds[16];   // roaming consortium ids to match, 0s if unspecified
+    byte plmn[3];                       // mcc/mnc combination as per rules, 0s if unspecified
+} wifi_passpoint_network;
+
+typedef struct {
+    void (*on_passpoint_network_found)(
+            wifi_request_id id,
+            int net_id,                        // network block identifier for the matched network
+            wifi_scan_result *result,          // scan result, with channel and beacon information
+            int anqp_len,                      // length of ANQP blob
+            byte *anqp                         // ANQP data, in the information_element format
+            );
+} wifi_passpoint_event_handler;
+
+/* Sets a list for passpoint networks for PNO purposes; it should be matched
+ * against any passpoint networks (designated by Interworking element) found
+ * during regular PNO scan. */
+wifi_error wifi_set_passpoint_list(wifi_request_id id, wifi_interface_handle iface, int num,
+        wifi_passpoint_network *networks, wifi_passpoint_event_handler handler);
+
+/* Reset passpoint network list - no Passpoint networks should be matched after this */
+wifi_error wifi_reset_passpoint_list(wifi_request_id id, wifi_interface_handle iface);
+
+#endif
diff --git a/wifi/legacy_headers/include/hardware_legacy/link_layer_stats.h b/wifi/legacy_headers/include/hardware_legacy/link_layer_stats.h
new file mode 100644
index 0000000..f4e16c6
--- /dev/null
+++ b/wifi/legacy_headers/include/hardware_legacy/link_layer_stats.h
@@ -0,0 +1,342 @@
+#include "wifi_hal.h"

+

+#ifndef __WIFI_HAL_STATS_H

+#define __WIFI_HAL_STATS_H

+

+#ifdef __cplusplus

+extern "C"

+{

+#endif /* __cplusplus */

+

+#define STATS_MAJOR_VERSION      1

+#define STATS_MINOR_VERSION      0

+#define STATS_MICRO_VERSION      0

+

+typedef enum {

+    WIFI_DISCONNECTED = 0,

+    WIFI_AUTHENTICATING = 1,

+    WIFI_ASSOCIATING = 2,

+    WIFI_ASSOCIATED = 3,

+    WIFI_EAPOL_STARTED = 4,   // if done by firmware/driver

+    WIFI_EAPOL_COMPLETED = 5, // if done by firmware/driver

+} wifi_connection_state;

+

+typedef enum {

+    WIFI_ROAMING_IDLE = 0,

+    WIFI_ROAMING_ACTIVE = 1,

+} wifi_roam_state;

+

+typedef enum {

+    WIFI_INTERFACE_STA = 0,

+    WIFI_INTERFACE_SOFTAP = 1,

+    WIFI_INTERFACE_IBSS = 2,

+    WIFI_INTERFACE_P2P_CLIENT = 3,

+    WIFI_INTERFACE_P2P_GO = 4,

+    WIFI_INTERFACE_NAN = 5,

+    WIFI_INTERFACE_MESH = 6,

+    WIFI_INTERFACE_TDLS = 7,

+    WIFI_INTERFACE_UNKNOWN = -1

+ } wifi_interface_mode;

+

+#define WIFI_CAPABILITY_QOS          0x00000001     // set for QOS association

+#define WIFI_CAPABILITY_PROTECTED    0x00000002     // set for protected association (802.11 beacon frame control protected bit set)

+#define WIFI_CAPABILITY_INTERWORKING 0x00000004     // set if 802.11 Extended Capabilities element interworking bit is set

+#define WIFI_CAPABILITY_HS20         0x00000008     // set for HS20 association

+#define WIFI_CAPABILITY_SSID_UTF8    0x00000010     // set is 802.11 Extended Capabilities element UTF-8 SSID bit is set

+#define WIFI_CAPABILITY_COUNTRY      0x00000020     // set is 802.11 Country Element is present

+

+typedef struct {

+   wifi_interface_mode mode;          // interface mode

+   u8 mac_addr[6];                    // interface mac address (self)

+   wifi_connection_state state;       // connection state (valid for STA, CLI only)

+   wifi_roam_state roaming;           // roaming state

+   u32 capabilities;                  // WIFI_CAPABILITY_XXX (self)

+   u8 ssid[33];                       // null terminated SSID

+   u8 bssid[6];                       // bssid

+   u8 ap_country_str[3];              // country string advertised by AP

+   u8 country_str[3];                 // country string for this association

+   u8 time_slicing_duty_cycle_percent;// if this iface is being served using time slicing on a radio with one or more ifaces (i.e MCC), then the duty cycle assigned to this iface in %.

+                                      // If not using time slicing (i.e SCC or DBS), set to 100.

+} wifi_interface_link_layer_info;

+

+/* channel information */

+typedef struct {

+   wifi_channel_width width;   // channel width (20, 40, 80, 80+80, 160, 320)

+   wifi_channel center_freq;   // primary 20 MHz channel

+   wifi_channel center_freq0;  // center frequency (MHz) first segment

+   wifi_channel center_freq1;  // center frequency (MHz) second segment

+} wifi_channel_info;

+

+/* wifi rate */

+typedef struct {

+   u32 preamble   :3;   // 0: OFDM, 1:CCK, 2:HT 3:VHT 4:HE 5:EHT 6..7 reserved

+   u32 nss        :2;   // 0:1x1, 1:2x2, 3:3x3, 4:4x4

+   u32 bw         :3;   // 0:20MHz, 1:40Mhz, 2:80Mhz, 3:160Mhz 4:320Mhz

+   u32 rateMcsIdx :8;   // OFDM/CCK rate code would be as per ieee std in the units of 0.5mbps

+                        // HT/VHT/HE/EHT it would be mcs index

+   u32 reserved  :16;   // reserved

+   u32 bitrate;         // units of 100 Kbps

+} wifi_rate;

+

+/* channel statistics */

+typedef struct {

+   wifi_channel_info channel;  // channel

+   u32 on_time;                // msecs the radio is awake (32 bits number accruing over time)

+   u32 cca_busy_time;          // msecs the CCA register is busy (32 bits number accruing over time)

+} wifi_channel_stat;

+

+// Max number of tx power levels. The actual number vary per device and is specified by |num_tx_levels|

+#define RADIO_STAT_MAX_TX_LEVELS 256

+

+/* radio statistics */

+typedef struct {

+   wifi_radio radio;                      // wifi radio (if multiple radio supported)

+   u32 on_time;                           // msecs the radio is awake (32 bits number accruing over time)

+   u32 tx_time;                           // msecs the radio is transmitting (32 bits number accruing over time)

+   u32 num_tx_levels;                     // number of radio transmit power levels

+   u32 *tx_time_per_levels;               // pointer to an array of radio transmit per power levels in

+                                          // msecs accured over time

+   u32 rx_time;                           // msecs the radio is in active receive (32 bits number accruing over time)

+   u32 on_time_scan;                      // msecs the radio is awake due to all scan (32 bits number accruing over time)

+   u32 on_time_nbd;                       // msecs the radio is awake due to NAN (32 bits number accruing over time)

+   u32 on_time_gscan;                     // msecs the radio is awake due to G?scan (32 bits number accruing over time)

+   u32 on_time_roam_scan;                 // msecs the radio is awake due to roam?scan (32 bits number accruing over time)

+   u32 on_time_pno_scan;                  // msecs the radio is awake due to PNO scan (32 bits number accruing over time)

+   u32 on_time_hs20;                      // msecs the radio is awake due to HS2.0 scans and GAS exchange (32 bits number accruing over time)

+   u32 num_channels;                      // number of channels

+   wifi_channel_stat channels[];          // channel statistics

+} wifi_radio_stat;

+

+/**

+ * Packet statistics reporting by firmware is performed on MPDU basi (i.e. counters increase by 1 for each MPDU)

+ * As well, "data packet" in associated comments, shall be interpreted as 802.11 data packet,

+ * that is, 802.11 frame control subtype == 2 and excluding management and control frames.

+ *

+ * As an example, in the case of transmission of an MSDU fragmented in 16 MPDUs which are transmitted

+ * OTA in a 16 units long a-mpdu, for which a block ack is received with 5 bits set:

+ *          tx_mpdu : shall increase by 5

+ *          retries : shall increase by 16

+ *          tx_ampdu : shall increase by 1

+ * data packet counters shall not increase regardless of the number of BAR potentially sent by device for this a-mpdu

+ * data packet counters shall not increase regardless of the number of BA received by device for this a-mpdu

+ *

+ * For each subsequent retransmission of the 11 remaining non ACK'ed mpdus

+ * (regardless of the fact that they are transmitted in a-mpdu or not)

+ *          retries : shall increase by 1

+ *

+ * If no subsequent BA or ACK are received from AP, until packet lifetime expires for those 11 packet that were not ACK'ed

+ *          mpdu_lost : shall increase by 11

+ */

+

+/* per rate statistics */

+typedef struct {

+   wifi_rate rate;     // rate information

+   u32 tx_mpdu;        // number of successfully transmitted data pkts (ACK rcvd)

+   u32 rx_mpdu;        // number of received data pkts

+   u32 mpdu_lost;      // number of data packet losses (no ACK)

+   u32 retries;        // total number of data pkt retries

+   u32 retries_short;  // number of short data pkt retries

+   u32 retries_long;   // number of long data pkt retries

+} wifi_rate_stat;

+

+/* access categories */

+typedef enum {

+   WIFI_AC_VO  = 0,

+   WIFI_AC_VI  = 1,

+   WIFI_AC_BE  = 2,

+   WIFI_AC_BK  = 3,

+   WIFI_AC_MAX = 4,

+} wifi_traffic_ac;

+

+/* wifi peer type */

+typedef enum

+{

+   WIFI_PEER_STA,

+   WIFI_PEER_AP,

+   WIFI_PEER_P2P_GO,

+   WIFI_PEER_P2P_CLIENT,

+   WIFI_PEER_NAN,

+   WIFI_PEER_TDLS,

+   WIFI_PEER_INVALID,

+} wifi_peer_type;

+

+/* per peer statistics */

+typedef struct bssload_info {

+    u16 sta_count;    // station count

+    u16 chan_util;    // channel utilization

+    u8 PAD[4];

+} bssload_info_t;

+

+typedef struct {

+   wifi_peer_type type;           // peer type (AP, TDLS, GO etc.)

+   u8 peer_mac_address[6];        // mac address

+   u32 capabilities;              // peer WIFI_CAPABILITY_XXX

+   bssload_info_t bssload;        // STA count and CU

+   u32 num_rate;                  // number of rates

+   wifi_rate_stat rate_stats[];   // per rate statistics, number of entries  = num_rate

+} wifi_peer_info;

+

+/* Per access category statistics */

+typedef struct {

+   wifi_traffic_ac ac;             // access category (VI, VO, BE, BK)

+   u32 tx_mpdu;                    // number of successfully transmitted unicast data pkts (ACK rcvd)

+   u32 rx_mpdu;                    // number of received unicast data packets

+   u32 tx_mcast;                   // number of succesfully transmitted multicast data packets

+                                   // STA case: implies ACK received from AP for the unicast packet in which mcast pkt was sent

+   u32 rx_mcast;                   // number of received multicast data packets

+   u32 rx_ampdu;                   // number of received unicast a-mpdus; support of this counter is optional

+   u32 tx_ampdu;                   // number of transmitted unicast a-mpdus; support of this counter is optional

+   u32 mpdu_lost;                  // number of data pkt losses (no ACK)

+   u32 retries;                    // total number of data pkt retries

+   u32 retries_short;              // number of short data pkt retries

+   u32 retries_long;               // number of long data pkt retries

+   u32 contention_time_min;        // data pkt min contention time (usecs)

+   u32 contention_time_max;        // data pkt max contention time (usecs)

+   u32 contention_time_avg;        // data pkt avg contention time (usecs)

+   u32 contention_num_samples;     // num of data pkts used for contention statistics

+} wifi_wmm_ac_stat;

+

+/* interface statistics */

+typedef struct {

+   wifi_interface_handle iface;          // wifi interface

+   wifi_interface_link_layer_info info;  // current state of the interface

+   u32 beacon_rx;                        // access point beacon received count from connected AP

+   u64 average_tsf_offset;               // average beacon offset encountered (beacon_TSF - TBTT)

+                                         // The average_tsf_offset field is used so as to calculate the

+                                         // typical beacon contention time on the channel as well may be

+                                         // used to debug beacon synchronization and related power consumption issue

+   u32 leaky_ap_detected;                // indicate that this AP typically leaks packets beyond the driver guard time.

+   u32 leaky_ap_avg_num_frames_leaked;  // average number of frame leaked by AP after frame with PM bit set was ACK'ed by AP

+   u32 leaky_ap_guard_time;              // guard time currently in force (when implementing IEEE power management based on

+                                         // frame control PM bit), How long driver waits before shutting down the radio and

+                                         // after receiving an ACK for a data frame with PM bit set)

+   u32 mgmt_rx;                          // access point mgmt frames received count from connected AP (including Beacon)

+   u32 mgmt_action_rx;                   // action frames received count

+   u32 mgmt_action_tx;                   // action frames transmit count

+   wifi_rssi rssi_mgmt;                  // access Point Beacon and Management frames RSSI (averaged)

+   wifi_rssi rssi_data;                  // access Point Data Frames RSSI (averaged) from connected AP

+   wifi_rssi rssi_ack;                   // access Point ACK RSSI (averaged) from connected AP

+   wifi_wmm_ac_stat ac[WIFI_AC_MAX];     // per ac data packet statistics

+   u32 num_peers;                        // number of peers

+   wifi_peer_info peer_info[];           // per peer statistics

+} wifi_iface_stat;

+

+/* Various states for the link */

+typedef enum {

+  // Chip does not support reporting the state of the link.

+  WIFI_LINK_STATE_UNKNOWN = 0,

+  // Link has not been in use since last report. It is placed in power save. All

+  // management, control and data frames for the MLO connection are carried over

+  // other links. In this state the link will not listen to beacons even in DTIM

+  // period and does not perform any GTK/IGTK/BIGTK updates but remains

+  // associated.

+  WIFI_LINK_STATE_NOT_IN_USE = 1,

+  // Link is in use. In presence of traffic, it is set to be power active. When

+  // the traffic stops, the link will go into power save mode and will listen

+  // for beacons every DTIM period.

+  WIFI_LINK_STATE_IN_USE = 2,

+} wifi_link_state;

+

+/* Per link statistics */

+typedef struct {

+  u8 link_id;       // Identifier for the link.

+  wifi_link_state state; // State for the link.

+  wifi_radio radio; // Radio on which link stats are sampled.

+  u32 frequency;    // Frequency on which link is operating.

+  u32 beacon_rx;    // Beacon received count from connected AP on the link.

+  u64 average_tsf_offset;  // Average beacon offset encountered (beacon_TSF -

+                           // TBTT). The average_tsf_offset field is used so as

+                           // to calculate the typical beacon contention time on

+                           // the channel as well may be used to debug beacon

+                           // synchronization and related power consumption

+                           // issue.

+  u32 leaky_ap_detected;   // Indicate that this AP on the link typically leaks

+                           // packets beyond the driver guard time.

+  u32 leaky_ap_avg_num_frames_leaked;  // Average number of frame leaked by AP

+                                       // in the link after frame with PM bit

+                                       // set was ACK'ed by AP.

+  u32 leaky_ap_guard_time;  // Guard time currently in force (when implementing

+                            // IEEE power management based on frame control PM

+                            // bit), How long driver waits before shutting down

+                            // the radio and after receiving an ACK for a data

+                            // frame with PM bit set).

+  u32 mgmt_rx;  // Management frames received count from connected AP on the

+                // link (including Beacon).

+  u32 mgmt_action_rx;  // Action frames received count on the link.

+  u32 mgmt_action_tx;  // Action frames transmit count on the link.

+  wifi_rssi rssi_mgmt; // Access Point Beacon and Management frames RSSI

+                       // (averaged) on the link.

+  wifi_rssi rssi_data; // Access Point Data Frames RSSI (averaged) from

+                       // connected AP on the link.

+  wifi_rssi rssi_ack;  // Access Point ACK RSSI (averaged) from connected AP on

+                       // the links.

+  wifi_wmm_ac_stat ac[WIFI_AC_MAX];    // Per AC data packet statistics for the

+                                       // link.

+  u8 time_slicing_duty_cycle_percent;  // If this link is being served using

+                                       // time slicing on a radio with one or

+                                       // more links, then the duty cycle

+                                       // assigned to this link in %.

+  u32 num_peers;                       // Number of peers.

+  wifi_peer_info peer_info[];          // Peer statistics for the link.

+} wifi_link_stat;

+

+/* Multi link stats for interface  */

+typedef struct {

+  wifi_interface_handle iface;          // Wifi interface.

+  wifi_interface_link_layer_info info;  // Current state of the interface.

+  int num_links;                        // Number of links.

+  wifi_link_stat links[];               // Stats per link.

+} wifi_iface_ml_stat;

+/* configuration params */

+typedef struct {

+   u32 mpdu_size_threshold;             // threshold to classify the pkts as short or long

+                                        // packet size < mpdu_size_threshold => short

+   u32 aggressive_statistics_gathering; // set for field debug mode. Driver should collect all statistics regardless of performance impact.

+} wifi_link_layer_params;

+

+/* API to trigger the link layer statistics collection.

+   Unless his API is invoked - link layer statistics will not be collected.

+   Radio statistics (once started) do not stop or get reset unless wifi_clear_link_stats is invoked

+   Interface statistics (once started) reset and start afresh after each connection */

+wifi_error wifi_set_link_stats(wifi_interface_handle iface, wifi_link_layer_params params);

+

+/* Callbacks for reporting link layer stats. Only one of the callbacks needs to

+ * be called. */

+typedef struct {

+   /* Legacy: Single iface/link stats. */

+   void (*on_link_stats_results)(wifi_request_id id,

+                                 wifi_iface_stat *iface_stat, int num_radios,

+                                 wifi_radio_stat *radio_stat);

+   /* Multi link stats. */

+   void (*on_multi_link_stats_results)(wifi_request_id id,

+                                       wifi_iface_ml_stat *iface_ml_stat,

+                                       int num_radios,

+                                       wifi_radio_stat *radio_stat);

+} wifi_stats_result_handler;

+

+/* api to collect the link layer statistics for a given iface and all the radio stats */

+wifi_error wifi_get_link_stats(wifi_request_id id,

+        wifi_interface_handle iface, wifi_stats_result_handler handler);

+

+/* wifi statistics bitmap  */

+#define WIFI_STATS_RADIO              0x00000001      // all radio statistics

+#define WIFI_STATS_RADIO_CCA          0x00000002      // cca_busy_time (within radio statistics)

+#define WIFI_STATS_RADIO_CHANNELS     0x00000004      // all channel statistics (within radio statistics)

+#define WIFI_STATS_RADIO_SCAN         0x00000008      // all scan statistics (within radio statistics)

+#define WIFI_STATS_IFACE              0x00000010      // all interface statistics

+#define WIFI_STATS_IFACE_TXRATE       0x00000020      // all tx rate statistics (within interface statistics)

+#define WIFI_STATS_IFACE_AC           0x00000040      // all ac statistics (within interface statistics)

+#define WIFI_STATS_IFACE_CONTENTION   0x00000080      // all contention (min, max, avg) statistics (within ac statisctics)

+

+/* clear api to reset statistics, stats_clear_rsp_mask identifies what stats have been cleared

+   stop_req = 1 will imply whether to stop the statistics collection.

+   stop_rsp = 1 will imply that stop_req was honored and statistics collection was stopped.

+ */

+wifi_error wifi_clear_link_stats(wifi_interface_handle iface,

+      u32 stats_clear_req_mask, u32 *stats_clear_rsp_mask, u8 stop_req, u8 *stop_rsp);

+

+#ifdef __cplusplus

+}

+#endif /* __cplusplus */

+

+#endif /*__WIFI_HAL_STATS_ */

diff --git a/wifi/legacy_headers/include/hardware_legacy/roam.h b/wifi/legacy_headers/include/hardware_legacy/roam.h
new file mode 100644
index 0000000..dbfd54b
--- /dev/null
+++ b/wifi/legacy_headers/include/hardware_legacy/roam.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#ifndef __WIFI_HAL_ROAM_H__
+#define __WIFI_HAL_ROAM_H__
+
+#include "wifi_hal.h"
+
+#define MAX_BLACKLIST_BSSID         16
+#define MAX_WHITELIST_SSID          8
+#define MAX_SSID_LENGTH             32
+
+typedef struct {
+    u32 max_blacklist_size;
+    u32 max_whitelist_size;
+} wifi_roaming_capabilities;
+
+typedef enum {
+    ROAMING_DISABLE,
+    ROAMING_ENABLE,
+    ROAMING_AGGRESSIVE
+} fw_roaming_state_t;
+
+typedef struct {
+    u32 length;
+    char ssid_str[MAX_SSID_LENGTH];
+} ssid_t;
+
+typedef struct {
+    u32 num_blacklist_bssid;                       // Number of bssids valid in blacklist_bssid[].
+    mac_addr blacklist_bssid[MAX_BLACKLIST_BSSID]; // List of bssids which should not be considered
+                                                   // for romaing by firmware/driver.
+    u32 num_whitelist_ssid;                        // Number of ssids valid in whitelist_ssid[].
+    ssid_t whitelist_ssid[MAX_WHITELIST_SSID];     // List of ssids to which firmware/driver can
+                                                   // consider to roam to.
+} wifi_roaming_config;
+
+/* Get the chipset roaming capabilities. */
+wifi_error wifi_get_roaming_capabilities(wifi_interface_handle handle,
+                                         wifi_roaming_capabilities *caps);
+/* Enable/disable firmware roaming */
+wifi_error wifi_enable_firmware_roaming(wifi_interface_handle handle,
+                                        fw_roaming_state_t state);
+
+/* Pass down the blacklist BSSID and whitelist SSID to firmware. */
+wifi_error wifi_configure_roaming(wifi_interface_handle handle,
+                                  wifi_roaming_config *roaming_config);
+
+#endif /* __WIFI_HAL_ROAM_H__ */
diff --git a/wifi/legacy_headers/include/hardware_legacy/rtt.h b/wifi/legacy_headers/include/hardware_legacy/rtt.h
new file mode 100644
index 0000000..426abe0
--- /dev/null
+++ b/wifi/legacy_headers/include/hardware_legacy/rtt.h
@@ -0,0 +1,415 @@
+
+#include "wifi_hal.h"
+#include "gscan.h"
+
+#ifndef __WIFI_HAL_RTT_H__
+#define __WIFI_HAL_RTT_H__
+
+/* Ranging status */
+typedef enum {
+    RTT_STATUS_SUCCESS       = 0,
+    RTT_STATUS_FAILURE       = 1,           // general failure status
+    RTT_STATUS_FAIL_NO_RSP   = 2,           // target STA does not respond to request
+    RTT_STATUS_FAIL_REJECTED = 3,           // request rejected. Applies to 2-sided RTT only
+    RTT_STATUS_FAIL_NOT_SCHEDULED_YET  = 4,
+    RTT_STATUS_FAIL_TM_TIMEOUT         = 5, // timing measurement times out
+    RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL = 6, // Target on different channel, cannot range
+    RTT_STATUS_FAIL_NO_CAPABILITY  = 7,     // ranging not supported
+    RTT_STATUS_ABORTED             = 8,     // request aborted for unknown reason
+    RTT_STATUS_FAIL_INVALID_TS     = 9,     // Invalid T1-T4 timestamp
+    RTT_STATUS_FAIL_PROTOCOL       = 10,    // 11mc protocol failed
+    RTT_STATUS_FAIL_SCHEDULE       = 11,    // request could not be scheduled
+    RTT_STATUS_FAIL_BUSY_TRY_LATER = 12,    // responder cannot collaborate at time of request
+    RTT_STATUS_INVALID_REQ         = 13,    // bad request args
+    RTT_STATUS_NO_WIFI             = 14,    // WiFi not enabled
+    RTT_STATUS_FAIL_FTM_PARAM_OVERRIDE = 15, // Responder overrides param info, cannot range with new params
+    RTT_STATUS_NAN_RANGING_PROTOCOL_FAILURE =16, //Negotiation failure
+    RTT_STATUS_NAN_RANGING_CONCURRENCY_NOT_SUPPORTED=17, //concurrency not supported (NDP+RTT)
+} wifi_rtt_status;
+
+/* RTT peer type */
+typedef enum {
+    RTT_PEER_AP         = 0x1,
+    RTT_PEER_STA        = 0x2,
+    RTT_PEER_P2P_GO     = 0x3,
+    RTT_PEER_P2P_CLIENT = 0x4,
+    RTT_PEER_NAN        = 0x5
+} rtt_peer_type;
+
+/* RTT Measurement Bandwidth */
+typedef enum {
+    WIFI_RTT_BW_UNSPECIFIED = 0x00,
+    WIFI_RTT_BW_5           = 0x01,
+    WIFI_RTT_BW_10          = 0x02,
+    WIFI_RTT_BW_20          = 0x04,
+    WIFI_RTT_BW_40          = 0x08,
+    WIFI_RTT_BW_80          = 0x10,
+    WIFI_RTT_BW_160         = 0x20,
+    WIFI_RTT_BW_320         = 0x40
+} wifi_rtt_bw;
+
+/* RTT Measurement Preamble */
+typedef enum {
+    WIFI_RTT_PREAMBLE_INVALID = 0x0,
+    WIFI_RTT_PREAMBLE_LEGACY  = 0x1,
+    WIFI_RTT_PREAMBLE_HT      = 0x2,
+    WIFI_RTT_PREAMBLE_VHT     = 0x4,
+    WIFI_RTT_PREAMBLE_HE      = 0x8,
+    WIFI_RTT_PREAMBLE_EHT     = 0x10,
+} wifi_rtt_preamble ;
+
+/* RTT Type */
+typedef enum {
+    RTT_TYPE_1_SIDED          = 0x1,
+    /* Deprecated. Use RTT_TYPE_2_SIDED_11MC instead. */
+    RTT_TYPE_2_SIDED          = 0x2,
+    RTT_TYPE_2_SIDED_11MC     = RTT_TYPE_2_SIDED,
+    RTT_TYPE_2_SIDED_11AZ_NTB = 0x3,
+
+} wifi_rtt_type;
+
+/* RTT configuration */
+typedef struct {
+    mac_addr addr;                 // peer device mac address
+    wifi_rtt_type type;            // 1-sided or 2-sided RTT (11mc and 11az)
+    rtt_peer_type peer;            // optional - peer device hint (STA, P2P, AP)
+    wifi_channel_info channel;     // Required for STA-AP mode, optional for P2P, NBD etc.
+    unsigned burst_period;         // Time interval between bursts (units: 100 ms).
+                                   // Applies to 1-sided and 2-sided RTT multi-burst requests.
+                                   // Range: 0-31, 0: no preference by initiator (2-sided RTT)
+                                   // Note: Applicable for 11mc only.
+    unsigned num_burst;            // Total number of RTT bursts to be executed. It will be
+                                   // specified in the same way as the parameter "Number of
+                                   // Burst Exponent" found in the FTM frame format. It
+                                   // applies to both: 1-sided RTT and 2-sided RTT. Valid
+                                   // values are 0 to 15 as defined in 802.11mc std.
+                                   // 0 means single shot
+                                   // The implication of this parameter on the maximum
+                                   // number of RTT results is the following:
+                                   // for 1-sided RTT: max num of RTT results = (2^num_burst)*(num_frames_per_burst)
+                                   // for 2-sided RTT: max num of RTT results = (2^num_burst)*(num_frames_per_burst - 1)
+                                   // Note: Applicable for 11mc only.
+    unsigned num_frames_per_burst; // num of frames per burst.
+                                   // Minimum value = 1, Maximum value = 31
+                                   // For 2-sided this equals the number of FTM frames
+                                   // to be attempted in a single burst. This also
+                                   // equals the number of FTM frames that the
+                                   // initiator will request that the responder send
+                                   // in a single frame.
+                                   // Note: Applicable for 11mc only.
+    unsigned num_retries_per_rtt_frame; // number of retries for a failed RTT frame. Applies
+                                        // to 1-sided RTT only. Minimum value = 0, Maximum value = 3
+
+    //following fields are only valid for 2-side RTT
+    unsigned num_retries_per_ftmr; // Maximum number of retries that the initiator can
+                                   // retry an FTMR frame.
+                                   // Minimum value = 0, Maximum value = 3
+    byte LCI_request;              // 1: request LCI, 0: do not request LCI
+    byte LCR_request;              // 1: request LCR, 0: do not request LCR
+    unsigned burst_duration;       // Applies to 1-sided and 2-sided 11mc RTT. Valid values will
+                                   // be 2-11 and 15 as specified by the 802.11mc std for
+                                   // the FTM parameter burst duration. In a multi-burst
+                                   // request, if responder overrides with larger value,
+                                   // the initiator will return failure. In a single-burst
+                                   // request if responder overrides with larger value,
+                                   // the initiator will sent TMR_STOP to terminate RTT
+                                   // at the end of the burst_duration it requested.
+    wifi_rtt_preamble preamble;    // RTT preamble to be used in the RTT frames
+    wifi_rtt_bw bw;                // RTT BW to be used in the RTT frames
+} wifi_rtt_config;
+
+/* RTT configuration v3 (11az support)*/
+typedef struct {
+    wifi_rtt_config rtt_config;
+    u64 ntb_min_measurement_time; // 11az Non-Trigger-based (non-TB) minimum measurement time in
+                                  // units of 100 microseconds
+    u64 ntb_max_measurement_time; // 11az Non-Trigger-based (non-TB) maximum measurement time in
+                                  // units of 10 milliseconds
+} wifi_rtt_config_v3;
+
+/* RTT results */
+typedef struct {
+    mac_addr addr;                // device mac address
+    unsigned burst_num;           // burst number in a multi-burst request. Note: Applicable to
+                                  // 1-sided RTT and 2-sided IEEE 802.11mc only.
+    unsigned measurement_number;  // Total RTT measurement frames attempted
+    unsigned success_number;      // Total successful RTT measurement frames
+    byte  number_per_burst_peer;  // Maximum number of "FTM frames per burst" supported by
+                                  // the responder STA. Applies to 2-sided RTT only.
+                                  // If reponder overrides with larger value:
+                                  // - for single-burst request initiator will truncate the
+                                  // larger value and send a TMR_STOP after receiving as
+                                  // many frames as originally requested.
+                                  // - for multi-burst request, initiator will return
+                                  // failure right away.
+    wifi_rtt_status status;       // ranging status
+    byte retry_after_duration;    // When status == RTT_STATUS_FAIL_BUSY_TRY_LATER,
+                                  // this will be the time provided by the responder as to
+                                  // when the request can be tried again. Applies to 2-sided
+                                  // RTT only. In sec, 1-31sec.
+    wifi_rtt_type type;           // RTT type
+    wifi_rssi rssi;               // average rssi in 0.5 dB steps e.g. 143 implies -71.5 dB
+    wifi_rssi rssi_spread;        // rssi spread in 0.5 dB steps e.g. 5 implies 2.5 dB spread (optional)
+    wifi_rate tx_rate;            // 1-sided RTT: TX rate of RTT frame.
+                                  // 2-sided RTT: TX rate of initiator's Ack in response to FTM frame.
+    wifi_rate rx_rate;            // 1-sided RTT: TX rate of Ack from other side.
+                                  // 2-sided RTT: TX rate of FTM frame coming from responder.
+    wifi_timespan rtt;            // round trip time in picoseconds
+    wifi_timespan rtt_sd;         // rtt standard deviation in picoseconds
+    wifi_timespan rtt_spread;     // difference between max and min rtt times recorded in picoseconds
+                                  // Note: Only applicable for IEEE 802.11mc
+    int distance_mm;              // distance in mm (optional)
+    int distance_sd_mm;           // standard deviation in mm (optional)
+    int distance_spread_mm;       // difference between max and min distance recorded in mm (optional)
+    wifi_timestamp ts;            // time of the measurement (in microseconds since boot)
+    int burst_duration;           // in ms, actual time taken by the FW to finish one burst
+                                  // measurement. Applies to 1-sided and 2-sided RTT.
+    int negotiated_burst_num;     // Number of bursts allowed by the responder. Applies
+                                  // to 2-sided 11mc RTT only.
+    wifi_information_element *LCI; // for 11mc and 11az only
+    wifi_information_element *LCR; // for 11mc and 11az only
+} wifi_rtt_result;
+
+/* RTT results version 2 */
+typedef struct {
+    wifi_rtt_result rtt_result;   // Legacy wifi rtt result structure
+    wifi_channel frequency;       // primary channel frequency (MHz) used for ranging measurements
+                                  // If frequency is unknown, this will be set to |UNSPECIFIED(-1)|
+    wifi_rtt_bw packet_bw;        // RTT packet bandwidth is an average BW of the BWs of RTT frames.
+                                  // Cap the average close to a specific valid RttBw.
+} wifi_rtt_result_v2;
+
+/* RTT results v3 (11az support)*/
+typedef struct {
+  wifi_rtt_result_v2 rtt_result;
+  byte i2r_tx_ltf_repetition_count;// Multiple transmissions of HE-LTF symbols in an HE (I2R)
+                                   // Ranging NDP. An HE-LTF repetition value of 1 indicates no
+                                   // repetitions.
+  byte r2i_tx_ltf_repetition_count;// Multiple transmissions of HE-LTF symbols in an HE (R2I)
+                                   // Ranging NDP. An HE-LTF repetition value of 1 indicates no
+                                   // repetitions.
+  u64 ntb_min_measurement_time;    // Minimum non-trigger based (non-TB) dynamic measurement time
+                                   // in units of 100 microseconds assigned by the 11az responder.
+  u64 ntb_max_measurement_time;    // Maximum non-trigger based (non-TB) dynamic measurement
+                                   // time in units of 10 milliseconds assigned by the 11az
+                                   // responder.
+  byte num_tx_sts;                 // Number of transmit space-time streams used.
+  byte num_rx_sts;                 // Number of receive space-time streams used.
+} wifi_rtt_result_v3;
+
+
+/* RTT result callbacks */
+typedef struct {
+    /*
+     * This callback is deprecated on Android 14 and onwards. Newer implementations should support
+     * on_rtt_results_v2 callback.
+     */
+    void (*on_rtt_results) (wifi_request_id id,
+                            unsigned num_results,
+                            wifi_rtt_result *rtt_result[]);
+
+    /*
+     * Called when vendor implementation supports sending RTT results version 2.
+     *
+     * Note: This callback is deprecated on Android 15 onwards. Newer implementation should support
+     * on_rtt_results_v3.
+     */
+    void (*on_rtt_results_v2) (wifi_request_id id,
+                               unsigned num_results,
+                               wifi_rtt_result_v2 *rtt_result_v2[]);
+} wifi_rtt_event_handler;
+
+/* API to request RTT measurement */
+wifi_error wifi_rtt_range_request(wifi_request_id id, wifi_interface_handle iface,
+        unsigned num_rtt_config, wifi_rtt_config rtt_config[], wifi_rtt_event_handler handler);
+
+/* RTT result v3 callback (11az support) */
+typedef struct {
+    /*
+     * Called when vendor implementation supports sending RTT results version 3 (Added support for
+     * 11az ranging)
+     */
+    void (*on_rtt_results_v3) (wifi_request_id id,
+                               unsigned num_results,
+                               wifi_rtt_result_v3 *rtt_result_v3[]);
+} wifi_rtt_event_handler_v3;
+
+
+/* v3 API to request RTT measurement(11az support).  */
+wifi_error wifi_rtt_range_request_v3(wifi_request_id id,
+                                     wifi_interface_handle iface,
+                                     unsigned num_rtt_config,
+                                     wifi_rtt_config_v3 rtt_config_v3[],
+                                     wifi_rtt_event_handler_v3 handler);
+
+/* API to cancel RTT measurements */
+wifi_error wifi_rtt_range_cancel(wifi_request_id id,  wifi_interface_handle iface,
+        unsigned num_devices, mac_addr addr[]);
+
+/* NBD ranging channel map */
+typedef struct {
+    wifi_channel availablity[32]; // specifies the channel map for each of the 16 TU windows
+    // frequency of 0 => unspecified; which means firmware is
+    // free to do whatever it wants in this window.
+} wifi_channel_map;
+
+/* API to start publishing the channel map on responder device in a NBD cluster.
+   Responder device will take this request and schedule broadcasting the channel map
+   in a NBD ranging attribute in a SDF. DE will automatically remove the ranging
+   attribute from the OTA queue after number of DW specified by num_dw
+   where Each DW is 512 TUs apart */
+wifi_error wifi_rtt_channel_map_set(wifi_request_id id,
+        wifi_interface_handle iface, wifi_channel_map *params, unsigned num_dw);
+
+/* API to clear the channel map on the responder device in a NBD cluster.
+   Responder device will cancel future ranging channel request, starting from “next”
+   DW interval and will also stop broadcasting NBD ranging attribute in SDF */
+wifi_error wifi_rtt_channel_map_clear(wifi_request_id id,  wifi_interface_handle iface);
+
+// Preamble definition for bit mask used in wifi_rtt_capabilities
+#define PREAMBLE_LEGACY 0x1
+#define PREAMBLE_HT     0x2
+#define PREAMBLE_VHT    0x4
+#define PREAMBLE_HE     0x8
+#define PREAMBLE_EHT    0x10
+
+// BW definition for bit mask used in wifi_rtt_capabilities
+#define BW_5_SUPPORT   0x1
+#define BW_10_SUPPORT  0x2
+#define BW_20_SUPPORT  0x4
+#define BW_40_SUPPORT  0x8
+#define BW_80_SUPPORT  0x10
+#define BW_160_SUPPORT 0x20
+#define BW_320_SUPPORT 0x40
+
+/* RTT Capabilities */
+typedef struct {
+    byte rtt_one_sided_supported;  // if 1-sided rtt data collection is supported
+    byte rtt_ftm_supported;        // if ftm rtt data collection is supported
+    byte lci_support;              // if initiator supports LCI request. Applies to 2-sided RTT
+                                   // (applies to both 11mc and 11az).
+    byte lcr_support;              // if initiator supports LCR request. Applies to 2-sided RTT
+                                   // (applies to both 11mc and 11az).
+    byte preamble_support;         // bit mask indicates what preamble is supported by 11mc
+                                   // initiator
+    byte bw_support;               // bit mask indicates what BW is supported by 11mc initiator
+    byte responder_supported;      // if 11mc responder mode is supported
+    byte mc_version;               // draft 11mc spec version supported by chip. For instance,
+                                   // version 4.0 should be 40 and version 4.3 should be 43 etc.
+} wifi_rtt_capabilities;
+
+
+/*  RTT capabilities of the device */
+wifi_error wifi_get_rtt_capabilities(wifi_interface_handle iface,
+                                     wifi_rtt_capabilities *capabilities);
+
+/* RTT Capabilities v3 (11az support) */
+typedef struct {
+    wifi_rtt_capabilities rtt_capab;
+    byte az_preamble_support;       // bit mask indicates what preamble is supported by the 11az
+                                    // initiator
+    byte az_bw_support;             // bit mask indicates what BW is supported by 11az initiator
+    byte ntb_initiator_supported;   // if 11az non-TB initiator is supported
+    byte ntb_responder_supported;   // if 11az non-TB responder is supported
+} wifi_rtt_capabilities_v3;
+
+/*  RTT capabilities v3 of the device (11az support) */
+wifi_error wifi_get_rtt_capabilities_v3(wifi_interface_handle iface,
+                                        wifi_rtt_capabilities_v3 *capabilities);
+
+/* debugging definitions */
+enum {
+    RTT_DEBUG_DISABLE,
+    RTT_DEBUG_LOG,
+    RTT_DEBUG_PROTO,
+    RTT_DEBUG_BURST,
+    RTT_DEBUG_ACCURACY,
+    RTT_DEBUG_LOGDETAIL
+};  //rtt debug type
+
+enum {
+    RTT_DEBUG_FORMAT_TXT,
+    RTT_DEBUG_FORMAT_BINARY
+}; //rtt debug format
+
+typedef struct rtt_debug {
+    unsigned version;
+    unsigned len; // total length of after len field
+    unsigned type;  // rtt debug type
+    unsigned format; //rtt debug format
+    char dbuf[0]; // debug content
+} rtt_debug_t;
+
+/* set configuration for debug */
+wifi_error wifi_rtt_debug_cfg(wifi_interface_handle h, unsigned rtt_dbg_type, char *cfgbuf, unsigned cfg_buf_size);
+/* get the debug information */
+wifi_error wifi_rtt_debug_get(wifi_interface_handle h, rtt_debug_t **debugbuf);
+/* free the debug buffer */
+wifi_error wifi_rtt_debug_free(wifi_interface_handle h, rtt_debug_t *debugbuf);
+
+/* API for setting LCI/LCR information to be provided to a requestor */
+typedef enum {
+    WIFI_MOTION_NOT_EXPECTED = 0, // Not expected to change location
+    WIFI_MOTION_EXPECTED = 1,     // Expected to change location
+    WIFI_MOTION_UNKNOWN  = 2,     // Movement pattern unknown
+} wifi_motion_pattern;
+
+typedef struct {
+    long latitude;              // latitude in degrees * 2^25 , 2's complement
+    long longitude;             // latitude in degrees * 2^25 , 2's complement
+    int  altitude;              // Altitude in units of 1/256 m
+    byte latitude_unc;          // As defined in Section 2.3.2 of IETF RFC 6225
+    byte longitude_unc;         // As defined in Section 2.3.2 of IETF RFC 6225
+    byte altitude_unc;          // As defined in Section 2.4.5 from IETF RFC 6225:
+
+    //Following element for configuring the Z subelement
+    wifi_motion_pattern motion_pattern;
+    int  floor;                 // floor in units of 1/16th of floor. 0x80000000 if unknown.
+    int  height_above_floor;    // in units of 1/64 m
+    int  height_unc;            // in units of 1/64 m. 0 if unknown
+} wifi_lci_information;
+
+typedef struct {
+    char country_code[2];       // country code
+    int  length;                // length of the info field
+    char civic_info[256];       // Civic info to be copied in FTM frame
+} wifi_lcr_information;
+
+// API to configure the LCI. Used in RTT Responder mode only
+wifi_error wifi_set_lci(wifi_request_id id, wifi_interface_handle iface,
+                        wifi_lci_information *lci);
+
+// API to configure the LCR. Used in RTT Responder mode only.
+wifi_error wifi_set_lcr(wifi_request_id id, wifi_interface_handle iface,
+                        wifi_lcr_information *lcr);
+
+/**
+ * RTT Responder information
+ */
+typedef struct {
+    wifi_channel_info channel;
+    wifi_rtt_preamble preamble;
+} wifi_rtt_responder;
+
+/**
+ * Get RTT responder information e.g. WiFi channel to enable responder on.
+ */
+wifi_error wifi_rtt_get_responder_info(wifi_interface_handle iface,
+                                       wifi_rtt_responder *responder_info);
+
+/**
+ * Enable RTT responder mode.
+ * channel_hint - hint of the channel information where RTT responder should be enabled on.
+ * max_duration_seconds - timeout of responder mode.
+ * channel_used - channel used for RTT responder, NULL if responder is not enabled.
+ */
+wifi_error wifi_enable_responder(wifi_request_id id, wifi_interface_handle iface,
+                                 wifi_channel_info channel_hint, unsigned max_duration_seconds,
+                                 wifi_rtt_responder *responder_info);
+
+/**
+ * Disable RTT responder mode.
+ */
+wifi_error wifi_disable_responder(wifi_request_id id, wifi_interface_handle iface);
+
+#endif
diff --git a/wifi/legacy_headers/include/hardware_legacy/tdls.h b/wifi/legacy_headers/include/hardware_legacy/tdls.h
new file mode 100644
index 0000000..9ac225a
--- /dev/null
+++ b/wifi/legacy_headers/include/hardware_legacy/tdls.h
@@ -0,0 +1,85 @@
+
+#include "wifi_hal.h"
+
+#ifndef _TDLS_H_
+#define _TDLS_H_
+
+typedef enum {
+    WIFI_TDLS_DISABLED = 1,                 /* TDLS is not enabled, default status for all STAs */
+    WIFI_TDLS_ENABLED,                      /* TDLS is enabled, but not yet tried */
+    WIFI_TDLS_ESTABLISHED,                  /* Direct link is established */
+    WIFI_TDLS_ESTABLISHED_OFF_CHANNEL,      /* Direct link is established using MCC */
+    WIFI_TDLS_DROPPED,                      /* Direct link was established,
+                                             * but is temporarily dropped now */
+    WIFI_TDLS_FAILED                        /* TDLS permanent failed. Inform error to upper layer
+                                             * and go back to WIFI_TDLS_DISABLED */
+} wifi_tdls_state;
+
+typedef enum {
+    WIFI_TDLS_SUCCESS,                              /* Success */
+    WIFI_TDLS_UNSPECIFIED           = -1,           /* Unspecified reason */
+    WIFI_TDLS_NOT_SUPPORTED         = -2,           /* Remote side doesn't support TDLS */
+    WIFI_TDLS_UNSUPPORTED_BAND      = -3,           /* Remote side doesn't support this band */
+    WIFI_TDLS_NOT_BENEFICIAL        = -4,           /* Going to AP is better than going direct */
+    WIFI_TDLS_DROPPED_BY_REMOTE     = -5            /* Remote side doesn't want it anymore */
+} wifi_tdls_reason;
+
+typedef struct {
+    int channel;                        /* channel hint, in channel number (NOT frequency ) */
+    int global_operating_class;         /* operating class to use */
+    int max_latency_ms;                 /* max latency that can be tolerated by apps */
+    int min_bandwidth_kbps;             /* bandwidth required by apps, in kilo bits per second */
+} wifi_tdls_params;
+
+typedef struct {
+    int channel;
+    int global_operating_class;
+    wifi_tdls_state state;
+    wifi_tdls_reason reason;
+} wifi_tdls_status;
+
+typedef struct {
+    int max_concurrent_tdls_session_num;      /* Maximum TDLS session number can be supported by the
+                                              * Firmware and hardware*/
+    int is_global_tdls_supported;            /* 1 -- support,  0 -- not support */
+    int is_per_mac_tdls_supported;           /* 1 -- support,  0 -- not support */
+    int is_off_channel_tdls_supported;       /* 1 -- support,  0 -- not support */
+} wifi_tdls_capabilities;
+
+typedef struct {
+    /* on_tdls_state_changed - reports state of TDLS link to framework
+     * Report this event when the state of TDLS link changes */
+    void (*on_tdls_state_changed)(mac_addr addr, wifi_tdls_status status);
+} wifi_tdls_handler;
+
+
+/* wifi_enable_tdls - enables TDLS-auto mode for a specific route
+ *
+ * params specifies hints, which provide more information about
+ * why TDLS is being sought. The firmware should do its best to
+ * honor the hints before downgrading regular AP link
+ * If upper layer has no specific values, this should be NULL
+ *
+ * handler is used to inform the upper layer about the status change and the corresponding reason
+ */
+wifi_error wifi_enable_tdls(wifi_interface_handle iface, mac_addr addr,
+        wifi_tdls_params *params, wifi_tdls_handler handler);
+
+/* wifi_disable_tdls - disables TDLS-auto mode for a specific route
+ *
+ * This terminates any existing TDLS with addr device, and frees the
+ * device resources to make TDLS connections on new routes.
+ *
+ * DON'T fire any more events on 'handler' specified in earlier call to
+ * wifi_enable_tdls after this action.
+ */
+wifi_error wifi_disable_tdls(wifi_interface_handle iface, mac_addr addr);
+
+/* wifi_get_tdls_status - allows getting the status of TDLS for a specific route */
+wifi_error wifi_get_tdls_status(wifi_interface_handle iface, mac_addr addr,
+        wifi_tdls_status *status);
+
+/* return the current HW + Firmware combination's TDLS capabilities */
+wifi_error wifi_get_tdls_capabilities(wifi_interface_handle iface,
+        wifi_tdls_capabilities *capabilities);
+#endif
diff --git a/wifi/legacy_headers/include/hardware_legacy/wifi_cached_scan_results.h b/wifi/legacy_headers/include/hardware_legacy/wifi_cached_scan_results.h
new file mode 100644
index 0000000..a2a23fe
--- /dev/null
+++ b/wifi/legacy_headers/include/hardware_legacy/wifi_cached_scan_results.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+#ifndef __WIFI_CACHED_SCAN_RESULTS_H__
+#define __WIFI_CACHED_SCAN_RESULTS_H__
+
+#include "wifi_hal.h"
+
+#define WIFI_CACHED_SCAN_RESULT_FLAGS_NONE                         (0)
+/* Element ID 61 (HT Operation) is present (see HT 7.3.2) */
+#define WIFI_CACHED_SCAN_RESULT_FLAGS_HT_OPS_PRESENT               (1 << 0)
+/* Element ID 192 (VHT Operation) is present (see VHT 8.4.2)  */
+#define WIFI_CACHED_SCAN_RESULT_FLAGS_VHT_OPS_PRESENT              (1 << 1)
+/* Element ID 255 + Extension 36 (HE Operation) is present
+ * (see 802.11ax 9.4.2.1)
+ */
+#define WIFI_CACHED_SCAN_RESULT_FLAGS_HE_OPS_PRESENT               (1 << 2)
+/* Element ID 255 + Extension 106 (HE Operation) is present
+ * (see 802.11be D1.5 9.4.2.1)
+ */
+#define WIFI_CACHED_SCAN_RESULT_FLAGS_EHT_OPS_PRESENT              (1 << 3)
+/* Element ID 127 (Extended Capabilities) is present, and bit 70
+ * (Fine Timing Measurement Responder) is set to 1
+ * (see IEEE Std 802.11-2016 9.4.2.27)
+ */
+#define WIFI_CACHED_SCAN_RESULT_FLAGS_IS_FTM_RESPONDER             (1 << 4)
+
+/**
+ * Provides information about a single access point (AP) detected in a scan.
+ */
+typedef struct {
+    /* Number of milliseconds prior to ts in the enclosing
+     * wifi_cached_scan_result_report struct when
+     * the probe response or beacon frame that
+     * was used to populate this structure was received.
+     */
+    u32 age_ms;
+    /* The Capability Information field */
+    u16 capability;
+    /* null terminated */
+    u8 ssid[33];
+    u8 ssid_len;
+    u8 bssid[6];
+    /* A set of flags from WIFI_CACHED_SCAN_RESULT_FLAGS_* */
+    u8 flags;
+    s8  rssi;
+    wifi_channel_spec chanspec;
+}wifi_cached_scan_result;
+
+/*
+ * Data structure sent with events of type WifiCachedScanResult.
+ */
+typedef struct  {
+    /* time since boot (in microsecond) when the result was retrieved */
+    wifi_timestamp ts;
+    /* If 0, indicates that all frequencies in current regulation were
+     * scanned. Otherwise, indicates the number of frequencies scanned, as
+     * specified in scanned_freq_list.
+     */
+    u16 scanned_freq_num;
+    /* Pointer to an array containing scanned_freq_num values comprising the
+     * set of frequencies that were scanned. Frequencies are specified as
+     * channel center frequencies in MHz. May be NULL if scannedFreqListLen is
+     * 0.
+     */
+    const u32 *scanned_freq_list;
+    /* The total number of cached results returned. */
+    u8 result_cnt;
+    /* Pointer to an array containing result_cnt entries. May be NULL if
+     * result_cnt is 0.
+     */
+    const wifi_cached_scan_result *results;
+} wifi_cached_scan_report;
+
+/* callback for reporting cached scan report */
+typedef struct {
+  void (*on_cached_scan_results) (wifi_cached_scan_report *cache_report);
+} wifi_cached_scan_result_handler;
+#endif
diff --git a/wifi/legacy_headers/include/hardware_legacy/wifi_config.h b/wifi/legacy_headers/include/hardware_legacy/wifi_config.h
new file mode 100644
index 0000000..9ddf8b8
--- /dev/null
+++ b/wifi/legacy_headers/include/hardware_legacy/wifi_config.h
@@ -0,0 +1,45 @@
+#include "wifi_hal.h"

+

+#ifndef __WIFI_HAL_CONFIG_H

+#define __WIFI_HAL_CONFIG_H

+

+#ifdef __cplusplus

+extern "C"

+{

+#endif /* __cplusplus */

+

+#define CONFIG_MAJOR_VERSION      1

+#define CONFIG_MINOR_VERSION      0

+#define CONFIG_MICRO_VERSION      0

+

+// whether the wifi chipset wakes at every dtim beacon or a multiple of the dtim period

+// if extended_dtim is set to 3, the STA shall wake up every 3 DTIM beacons

+wifi_error wifi_extended_dtim_config_set(wifi_request_id id,

+        wifi_interface_handle iface, int extended_dtim);

+

+//set the country code to driver

+wifi_error wifi_set_country_code(wifi_interface_handle iface, const char* country_code);

+

+//set the wifi_iface stats averaging factor used to calculate

+// statistics like average the TSF offset or average number of frame leaked

+// For instance, upon beacon reception:

+//    current_avg = ((beacon_TSF - TBTT) * factor + previous_avg * (0x10000 - factor) ) / 0x10000

+// For instance, when evaluating leaky APs:

+//    current_avg = ((num frame received within guard time) * factor + previous_avg * (0x10000 - factor)) / 0x10000

+

+wifi_error wifi_set_beacon_wifi_iface_stats_averaging_factor(wifi_request_id id, wifi_interface_handle iface,

+        u16 factor);

+

+// configure guard time, i.e. when implementing IEEE power management based on

+// frame control PM bit, how long driver waits before shutting down the radio and

+// after receiving an ACK for a data frame with PM bit set

+wifi_error wifi_set_guard_time(wifi_request_id id, wifi_interface_handle iface,

+        u32 guard_time);

+

+#ifdef __cplusplus

+}

+

+#endif /* __cplusplus */

+

+#endif /*__WIFI_HAL_STATS_ */

+

diff --git a/wifi/legacy_headers/include/hardware_legacy/wifi_hal.h b/wifi/legacy_headers/include/hardware_legacy/wifi_hal.h
new file mode 100644
index 0000000..e770777
--- /dev/null
+++ b/wifi/legacy_headers/include/hardware_legacy/wifi_hal.h
@@ -0,0 +1,1428 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#ifndef __WIFI_HAL_H__
+#define __WIFI_HAL_H__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+#include <stdint.h>
+
+#define IFNAMSIZ 16
+#define UNSPECIFIED -1 // wifi HAL common definition for unspecified value
+
+/* typedefs */
+typedef unsigned char byte;
+typedef unsigned char u8;
+typedef signed char s8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+typedef int32_t s32;
+typedef uint64_t u64;
+typedef int64_t s64;
+typedef int wifi_request_id;
+typedef int wifi_channel;                       // indicates channel frequency in MHz
+typedef int wifi_rssi;
+typedef int wifi_radio;
+typedef byte mac_addr[6];
+typedef byte oui[3];
+typedef int64_t wifi_timestamp;                 // In microseconds (us)
+typedef int64_t wifi_timespan;                  // In picoseconds  (ps)
+typedef uint64_t feature_set;
+
+/* forward declarations */
+struct wifi_info;
+struct wifi_interface_info;
+typedef struct wifi_info *wifi_handle;
+typedef struct wifi_interface_info *wifi_interface_handle;
+
+/* WiFi Common definitions */
+/* channel operating width */
+typedef enum {
+    WIFI_CHAN_WIDTH_20    = 0,
+    WIFI_CHAN_WIDTH_40    = 1,
+    WIFI_CHAN_WIDTH_80    = 2,
+    WIFI_CHAN_WIDTH_160   = 3,
+    WIFI_CHAN_WIDTH_80P80 = 4,
+    WIFI_CHAN_WIDTH_5     = 5,
+    WIFI_CHAN_WIDTH_10    = 6,
+    WIFI_CHAN_WIDTH_320   = 7,
+    WIFI_CHAN_WIDTH_INVALID = -1
+} wifi_channel_width;
+
+/* Multi-Link Operation modes */
+typedef enum {
+  WIFI_MLO_MODE_DEFAULT          = 0,
+  WIFI_MLO_MODE_LOW_LATENCY      = 1,
+  WIFI_MLO_MODE_HIGH_THROUGHPUT  = 2,
+  WIFI_MLO_MODE_LOW_POWER        = 3,
+} wifi_mlo_mode;
+
+/* Pre selected Power scenarios to be applied from BDF file */
+typedef enum {
+    WIFI_POWER_SCENARIO_INVALID          = -2,
+    WIFI_POWER_SCENARIO_DEFAULT          = -1,
+    WIFI_POWER_SCENARIO_VOICE_CALL       = 0,
+    WIFI_POWER_SCENARIO_ON_HEAD_CELL_OFF = 1,
+    WIFI_POWER_SCENARIO_ON_HEAD_CELL_ON  = 2,
+    WIFI_POWER_SCENARIO_ON_BODY_CELL_OFF = 3,
+    WIFI_POWER_SCENARIO_ON_BODY_CELL_ON  = 4,
+    WIFI_POWER_SCENARIO_ON_BODY_BT       = 5,
+    WIFI_POWER_SCENARIO_ON_HEAD_HOTSPOT  = 6,
+    WIFI_POWER_SCENARIO_ON_HEAD_HOTSPOT_MMW = 7,
+    WIFI_POWER_SCENARIO_ON_BODY_CELL_ON_BT = 8,
+    WIFI_POWER_SCENARIO_ON_BODY_HOTSPOT = 9,
+    WIFI_POWER_SCENARIO_ON_BODY_HOTSPOT_BT = 10,
+    WIFI_POWER_SCENARIO_ON_BODY_HOTSPOT_MMW = 11,
+    WIFI_POWER_SCENARIO_ON_BODY_HOTSPOT_BT_MMW = 12,
+    WIFI_POWER_SCENARIO_ON_HEAD_CELL_OFF_UNFOLDED = 13,
+    WIFI_POWER_SCENARIO_ON_HEAD_CELL_ON_UNFOLDED = 14,
+    WIFI_POWER_SCENARIO_ON_HEAD_HOTSPOT_UNFOLDED = 15,
+    WIFI_POWER_SCENARIO_ON_HEAD_HOTSPOT_MMW_UNFOLDED = 16,
+    WIFI_POWER_SCENARIO_ON_BODY_CELL_OFF_UNFOLDED = 17,
+    WIFI_POWER_SCENARIO_ON_BODY_BT_UNFOLDED = 18,
+    WIFI_POWER_SCENARIO_ON_BODY_CELL_ON_UNFOLDED = 19,
+    WIFI_POWER_SCENARIO_ON_BODY_CELL_ON_BT_UNFOLDED = 20,
+    WIFI_POWER_SCENARIO_ON_BODY_HOTSPOT_UNFOLDED = 21,
+    WIFI_POWER_SCENARIO_ON_BODY_HOTSPOT_BT_UNFOLDED = 22,
+    WIFI_POWER_SCENARIO_ON_BODY_HOTSPOT_MMW_UNFOLDED = 23,
+    WIFI_POWER_SCENARIO_ON_BODY_HOTSPOT_BT_MMW_UNFOLDED = 24,
+    WIFI_POWER_SCENARIO_ON_BODY_REAR_CAMERA = 25,
+    WIFI_POWER_SCENARIO_ON_BODY_CELL_OFF_UNFOLDED_CAP = 26,
+    WIFI_POWER_SCENARIO_ON_BODY_BT_UNFOLDED_CAP = 27,
+    WIFI_POWER_SCENARIO_ON_BODY_CELL_ON_UNFOLDED_CAP = 28,
+    WIFI_POWER_SCENARIO_ON_BODY_CELL_ON_BT_UNFOLDED_CAP = 29,
+} wifi_power_scenario;
+
+typedef enum {
+  WIFI_LATENCY_MODE_NORMAL    = 0,
+  WIFI_LATENCY_MODE_LOW       = 1,
+} wifi_latency_mode;
+
+/* Wifi Thermal mitigation modes */
+typedef enum {
+  WIFI_MITIGATION_NONE      = 0,
+  WIFI_MITIGATION_LIGHT     = 1,
+  WIFI_MITIGATION_MODERATE  = 2,
+  WIFI_MITIGATION_SEVERE    = 3,
+  WIFI_MITIGATION_CRITICAL  = 4,
+  WIFI_MITIGATION_EMERGENCY = 5,
+} wifi_thermal_mode;
+
+/*
+ * Wifi voice over IP mode
+ * may add new modes later, for example, voice + video over IP mode.
+ */
+typedef enum {
+  WIFI_VOIP_MODE_OFF = 0,
+  WIFI_VOIP_MODE_VOICE  = 1,
+} wifi_voip_mode;
+
+/* List of interface types supported */
+typedef enum {
+  WIFI_INTERFACE_TYPE_STA = 0,
+  WIFI_INTERFACE_TYPE_AP  = 1,
+  WIFI_INTERFACE_TYPE_P2P = 2,
+  WIFI_INTERFACE_TYPE_NAN = 3,
+  WIFI_INTERFACE_TYPE_AP_BRIDGED = 4,
+} wifi_interface_type;
+
+/*
+ * enum wlan_mac_band - Band information corresponding to the WLAN MAC.
+ */
+typedef enum {
+/* WLAN MAC Operates in 2.4 GHz Band */
+    WLAN_MAC_2_4_BAND = 1 << 0,
+/* WLAN MAC Operates in 5 GHz Band */
+    WLAN_MAC_5_0_BAND = 1 << 1,
+/* WLAN MAC Operates in 6 GHz Band */
+    WLAN_MAC_6_0_BAND = 1 << 2,
+/* WLAN MAC Operates in 60 GHz Band */
+    WLAN_MAC_60_0_BAND = 1 << 3,
+} wlan_mac_band;
+
+/* List of chre nan rtt state */
+typedef enum {
+    CHRE_PREEMPTED = 0,
+    CHRE_UNAVAILABLE = 1,
+    CHRE_AVAILABLE = 2,
+} chre_nan_rtt_state;
+
+typedef struct {
+    wifi_channel_width width;
+    int center_frequency0;
+    int center_frequency1;
+    int primary_frequency;
+} wifi_channel_spec;
+
+/*
+ * wifi_usable_channel specifies a channel frequency, bandwidth, and bitmask
+ * of modes allowed on the channel.
+ */
+typedef struct {
+    /* Channel frequency in MHz */
+    wifi_channel freq;
+    /* Channel operating width (20, 40, 80, 160, 320 etc.) */
+    wifi_channel_width width;
+    /* BIT MASK of BIT(WIFI_INTERFACE_*) represented by |wifi_interface_mode|
+     * Bitmask does not represent concurrency.
+     * Examples:
+     * - If a channel is usable only for STA, then only the WIFI_INTERFACE_STA
+     *   bit would be set for that channel.
+     * - If 5GHz SAP is not allowed, then none of the 5GHz channels will have
+     *   WIFI_INTERFACE_SOFTAP bit set.
+     * Note: TDLS bit is set only if there is a STA connection. TDLS bit is set
+     * on non-STA channels only if TDLS off channel is supported.
+     */
+    u32 iface_mode_mask;
+} wifi_usable_channel;
+
+/*
+ * wifi_usable_channel_filter
+ */
+typedef enum {
+  /* Filter Wifi channels that should be avoided due to cellular coex
+   * restrictions. Some Wifi channels can have extreme interference
+   * from/to cellular due to short frequency separation with neighboring
+   * cellular channels or when there is harmonic and intermodulation
+   * interference. Channels which only have some performance degradation
+   * (e.g. power back off is sufficient to deal with coexistence issue)
+   * can be included and should not be filtered out.
+   */
+  WIFI_USABLE_CHANNEL_FILTER_CELLULAR_COEXISTENCE  = 1 << 0,
+  /* Filter channels due to concurrency state.
+   * Examples:
+   * - 5GHz SAP operation may be supported in standalone mode, but if
+   *  there is STA connection on 5GHz DFS channel, none of the 5GHz
+   *  channels are usable for SAP if device does not support DFS SAP mode.
+   * - P2P GO may not be supported on indoor channels in EU during
+   *  standalone mode but if there is a STA connection on indoor channel,
+   *  P2P GO may be supported by some vendors on the same STA channel.
+   */
+  WIFI_USABLE_CHANNEL_FILTER_CONCURRENCY  = 1 << 1,
+  /* This Filter queries Wifi channels and bands that are supported for
+   * NAN3.1 Instant communication mode. This filter should only be applied to NAN interface.
+   * If 5G is supported default discovery channel 149/44 is considered,
+   * If 5G is not supported then channel 6 has to be considered.
+   * Based on regulatory domain if channel 149 and 44 are restricted, channel 6 should
+   * be considered for instant communication channel
+   */
+  WIFI_USABLE_CHANNEL_FILTER_NAN_INSTANT_MODE   = 1 << 2,
+} wifi_usable_channel_filter;
+
+typedef enum {
+    WIFI_SUCCESS = 0,
+    WIFI_ERROR_NONE = 0,
+    WIFI_ERROR_UNKNOWN = -1,
+    WIFI_ERROR_UNINITIALIZED = -2,
+    WIFI_ERROR_NOT_SUPPORTED = -3,
+    WIFI_ERROR_NOT_AVAILABLE = -4,              // Not available right now, but try later
+    WIFI_ERROR_INVALID_ARGS = -5,
+    WIFI_ERROR_INVALID_REQUEST_ID = -6,
+    WIFI_ERROR_TIMED_OUT = -7,
+    WIFI_ERROR_TOO_MANY_REQUESTS = -8,          // Too many instances of this request
+    WIFI_ERROR_OUT_OF_MEMORY = -9,
+    WIFI_ERROR_BUSY = -10,
+} wifi_error;
+
+typedef enum {
+    WIFI_ACCESS_CATEGORY_BEST_EFFORT = 0,
+    WIFI_ACCESS_CATEGORY_BACKGROUND = 1,
+    WIFI_ACCESS_CATEGORY_VIDEO = 2,
+    WIFI_ACCESS_CATEGORY_VOICE = 3
+} wifi_access_category;
+
+/* Channel category mask */
+typedef enum {
+    WIFI_INDOOR_CHANNEL = 1 << 0,
+    WIFI_DFS_CHANNEL    = 1 << 1,
+} wifi_channel_category;
+
+/* Antenna configuration */
+typedef enum {
+  WIFI_ANTENNA_UNSPECIFIED = 0,
+  WIFI_ANTENNA_1X1         = 1,
+  WIFI_ANTENNA_2X2         = 2,
+  WIFI_ANTENNA_3X3         = 3,
+  WIFI_ANTENNA_4X4         = 4,
+} wifi_antenna_configuration;
+
+/* Wifi Radio configuration */
+typedef struct {
+    /* Operating band */
+    wlan_mac_band band;
+    /* Antenna configuration */
+    wifi_antenna_configuration antenna_cfg;
+} wifi_radio_configuration;
+
+/* WiFi Radio Combination  */
+typedef struct {
+    u32 num_radio_configurations;
+    wifi_radio_configuration radio_configurations[];
+} wifi_radio_combination;
+
+/* WiFi Radio combinations matrix */
+/* For Example in case of a chip which has two radios, where one radio is
+ * capable of 2.4GHz 2X2 only and another radio which is capable of either
+ * 5GHz or 6GHz 2X2, number of possible radio combinations in this case
+ * are 5 and possible combinations are
+ *                            {{{2G 2X2}}, //Standalone 2G
+ *                            {{5G 2X2}}, //Standalone 5G
+ *                            {{6G 2X2}}, //Standalone 6G
+ *                            {{2G 2X2}, {5G 2X2}}, //2G+5G DBS
+ *                            {{2G 2X2}, {6G 2X2}}} //2G+6G DBS
+ * Note: Since this chip doesn’t support 5G+6G simultaneous operation
+ * as there is only one radio which can support both, So it can only
+ * do MCC 5G+6G. This table should not get populated with possible MCC
+ * configurations. This is only for simultaneous radio configurations
+ * (such as Standalone, multi band simultaneous or single band simultaneous).
+ */
+typedef struct {
+    u32 num_radio_combinations;
+    /* Each row represents possible radio combinations */
+    wifi_radio_combination radio_combinations[];
+} wifi_radio_combination_matrix;
+
+typedef struct {
+    /**
+     * Maximum number of links supported by the chip for MLO association.
+     */
+    u32 max_mlo_association_link_count;
+    /**
+     * Maximum number of Simultaneous Transmit and Receive (STR) links used
+     * in Multi-Link Operation. The maximum number of STR links used can be
+     * different from the maximum number of radios supported by the chip.
+     *
+     * This is a static configuration of the chip.
+     */
+    u32 max_mlo_str_link_count;
+    /**
+     * Maximum number of concurrent TDLS sessions supported by the chip.
+     *
+     */
+    u32 max_concurrent_tdls_session_count;
+} wifi_chip_capabilities;
+
+#define MAX_IFACE_COMBINATIONS 16
+#define MAX_IFACE_LIMITS 8
+
+/* Wifi interface limit
+ * Example:
+ * 1. To allow STA+STA:
+ *     wifi_iface_limit limit1 = {
+ *         .max_limit = 2,
+ *         .iface_mask = BIT(WIFI_INTERFACE_TYPE_STA)
+ *     };
+ * 2. To allow Single P2P/NAN:
+ *     wifi_iface_limit limit2 = {
+ *         .max_limit = 1,
+ *         .iface_mask = BIT(WIFI_INTERFACE_TYPE_P2P)
+ *                       | BIT(WIFI_INTERFACE_TYPE_NAN)
+ *     };
+ */
+typedef struct {
+    /* Max number of interfaces of same type */
+    u32 max_limit;
+    /* BIT mask of interfaces from wifi_interface_type */
+    u32 iface_mask;
+} wifi_iface_limit;
+
+/* Wifi Interface combination
+ * Example:
+ * 1. To allow STA+SAP:
+ *     wifi_iface_limit limits1[] = {
+ *         {1, BIT(WIFI_INTERFACE_TYPE_STA)},
+ *     };
+ *     wifi_iface_limit limits2[] = {
+ *         {1, BIT(WIFI_INTERFACE_TYPE_AP)},
+ *     };
+ *     wifi_iface_combination comb1 = {
+ *         .max_ifaces = 2,
+ *         .num_iface_limits = 2,
+ *         .iface_limits = {limits1, limits2,},
+ *     };
+ *
+ * 2. To allow STA+P2P/NAN:
+ *     wifi_iface_limit limits3[] = {
+ *         {1, BIT(WIFI_INTERFACE_TYPE_STA)},
+ *         {1, BIT(WIFI_INTERFACE_TYPE_P2P)
+               | BIT(WIFI_INTERFACE_TYPE_NAN)},
+ *     };
+ *     wifi_iface_combination comb2 = {
+ *         .max_ifaces = 2,
+ *         .num_iface_limits = 1,
+ *         .iface_limits = {limits3,},
+ *     };
+ *
+ * 3. To allow STA+STA/AP:
+ *     wifi_iface_limit limits4[] = {
+ *         {2, BIT(WIFI_INTERFACE_TYPE_STA)},
+ *     };
+ *     wifi_iface_limit limits5[] = {
+ *         {1, BIT(WIFI_INTERFACE_TYPE_STA)},
+ *         {1, BIT(WIFI_INTERFACE_TYPE_AP)},
+ *     };
+ *     wifi_iface_combination comb3 = {
+ *         .max_ifaces = 2,
+ *         .num_iface_limits = 2,
+ *         .iface_limits = {limits4, limits5,},
+ *     };
+ *
+ * 4. To allow AP_BRIDGED (AP+AP in bridge mode):
+ *     wifi_iface_limit limits6[] = {
+ *         {1, BIT(WIFI_INTERFACE_TYPE_AP_BRIDGED)},
+ *     };
+ *     wifi_iface_combination comb4 = {
+ *         .max_ifaces = 1,
+ *         .num_iface_limits = 1,
+ *         .iface_limits = {limits6,},
+ *     };
+ */
+typedef struct {
+    /* Maximum number of concurrent interfaces allowed in this combination */
+    u32 max_ifaces;
+    /* Total number of interface limits in a combination */
+    u32 num_iface_limits;
+    /* Interface limits */
+    wifi_iface_limit iface_limits[MAX_IFACE_LIMITS];
+} wifi_iface_combination;
+
+/* Wifi Interface concurrency combination matrix
+ * Example:
+ * 1. To allow 2 port concurrency with limts defined in above comments:
+ *     wifi_iface_concurrency_matrix iface_concurrency_matrix = {
+ *         .num_iface_combinations = 4,
+ *         .iface_combinations = {comb1, comb2, comb3, comb4, }
+ *     };
+ */
+typedef struct {
+    /* Total count of possible iface combinations */
+    u32 num_iface_combinations;
+    /* Interface combinations */
+    wifi_iface_combination iface_combinations[MAX_IFACE_COMBINATIONS];
+} wifi_iface_concurrency_matrix;
+
+/* Wifi OUI data */
+typedef struct {
+    /* OUI : 24-bit organizationally unique identifier to identify the Vendor/OEM */
+    u32 oui;
+    /* Length of the data buffer */
+    u32 data_len;
+    /* Vendor-specific data */
+    const u8 *data;
+} oui_keyed_data;
+
+/* Wifi Vendor data list */
+typedef struct {
+    /* Number of OUI Keyed Data objects */
+    u32 num_oui_keyed_data;
+    /* List of OUI Keyed Data */
+    oui_keyed_data *oui_data;
+} wifi_vendor_data;
+
+/* Initialize/Cleanup */
+
+wifi_error wifi_initialize(wifi_handle *handle);
+
+/**
+ * wifi_wait_for_driver
+ * Function should block until the driver is ready to proceed.
+ * Any errors from this function is considered fatal & will fail the HAL startup sequence.
+ *
+ * on success returns WIFI_SUCCESS
+ * on failure returns WIFI_ERROR_TIMED_OUT
+ */
+wifi_error wifi_wait_for_driver_ready(void);
+
+typedef void (*wifi_cleaned_up_handler) (wifi_handle handle);
+void wifi_cleanup(wifi_handle handle, wifi_cleaned_up_handler handler);
+void wifi_event_loop(wifi_handle handle);
+
+/* Error handling */
+void wifi_get_error_info(wifi_error err, const char **msg); // return a pointer to a static string
+
+/* Feature enums */
+#define WIFI_FEATURE_INFRA              (uint64_t)0x1      // Basic infrastructure mode
+#define WIFI_FEATURE_INFRA_5G           (uint64_t)0x2      // Support for 5 GHz Band
+#define WIFI_FEATURE_HOTSPOT            (uint64_t)0x4      // Support for GAS/ANQP
+#define WIFI_FEATURE_P2P                (uint64_t)0x8      // Wifi-Direct
+#define WIFI_FEATURE_SOFT_AP            (uint64_t)0x10      // Soft AP
+#define WIFI_FEATURE_GSCAN              (uint64_t)0x20      // Google-Scan APIs
+#define WIFI_FEATURE_NAN                (uint64_t)0x40      // Neighbor Awareness Networking
+#define WIFI_FEATURE_D2D_RTT            (uint64_t)0x80      // Device-to-device RTT
+#define WIFI_FEATURE_D2AP_RTT           (uint64_t)0x100      // Device-to-AP RTT
+#define WIFI_FEATURE_BATCH_SCAN         (uint64_t)0x200      // Batched Scan (legacy)
+#define WIFI_FEATURE_PNO                (uint64_t)0x400      // Preferred network offload
+#define WIFI_FEATURE_ADDITIONAL_STA     (uint64_t)0x800      // Support for two STAs
+#define WIFI_FEATURE_TDLS               (uint64_t)0x1000      // Tunnel directed link setup
+#define WIFI_FEATURE_TDLS_OFFCHANNEL    (uint64_t)0x2000      // Support for TDLS off channel
+#define WIFI_FEATURE_EPR                (uint64_t)0x4000      // Enhanced power reporting
+#define WIFI_FEATURE_AP_STA             (uint64_t)0x8000      // Support for AP STA Concurrency
+#define WIFI_FEATURE_LINK_LAYER_STATS   (uint64_t)0x10000     // Link layer stats collection
+#define WIFI_FEATURE_LOGGER             (uint64_t)0x20000     // WiFi Logger
+#define WIFI_FEATURE_HAL_EPNO           (uint64_t)0x40000     // WiFi PNO enhanced
+#define WIFI_FEATURE_RSSI_MONITOR       (uint64_t)0x80000     // RSSI Monitor
+#define WIFI_FEATURE_MKEEP_ALIVE        (uint64_t)0x100000    // WiFi mkeep_alive
+#define WIFI_FEATURE_CONFIG_NDO         (uint64_t)0x200000    // ND offload configure
+#define WIFI_FEATURE_TX_TRANSMIT_POWER  (uint64_t)0x400000    // Capture Tx transmit power levels
+#define WIFI_FEATURE_CONTROL_ROAMING    (uint64_t)0x800000    // Enable/Disable firmware roaming
+#define WIFI_FEATURE_IE_WHITELIST       (uint64_t)0x1000000   // Support Probe IE white listing
+#define WIFI_FEATURE_SCAN_RAND          (uint64_t)0x2000000   // Support MAC & Probe Sequence Number randomization
+#define WIFI_FEATURE_SET_TX_POWER_LIMIT (uint64_t)0x4000000   // Support Tx Power Limit setting
+#define WIFI_FEATURE_USE_BODY_HEAD_SAR  (uint64_t)0x8000000   // Support Using Body/Head Proximity for SAR
+#define WIFI_FEATURE_DYNAMIC_SET_MAC    (uint64_t)0x10000000  // Support changing MAC address without iface reset(down and up)
+#define WIFI_FEATURE_SET_LATENCY_MODE   (uint64_t)0x40000000  // Support Latency mode setting
+#define WIFI_FEATURE_P2P_RAND_MAC       (uint64_t)0x80000000  // Support P2P MAC randomization
+#define WIFI_FEATURE_INFRA_60G          (uint64_t)0x100000000 // Support for 60GHz Band
+#define WIFI_FEATURE_AFC_CHANNEL        (uint64_t)0x200000000 // Support for setting 6GHz AFC channel allowance
+#define WIFI_FEATURE_T2LM_NEGO          (uint64_t)0x400000000 // Support for TID-To-Link mapping negotiation
+#define WIFI_FEATURE_ROAMING_MODE_CONTROL   (uint64_t)0x800000000 // Support for configuring roaming mode
+#define WIFI_FEATURE_SET_VOIP_MODE          (uint64_t)0x1000000000 // Support Voip mode setting
+#define WIFI_FEATURE_CACHED_SCAN_RESULTS    (uint64_t)0x2000000000 // Support cached scan result report
+// Add more features here
+
+#define IS_MASK_SET(mask, flags)        (((flags) & (mask)) == (mask))
+
+#define IS_SUPPORTED_FEATURE(feature, featureSet)       IS_MASK_SET(feature, featureSet)
+
+/* Feature set */
+wifi_error wifi_get_supported_feature_set(wifi_interface_handle handle, feature_set *set);
+
+/*
+ * Each row represents a valid feature combination;
+ * all other combinations are invalid!
+ */
+wifi_error wifi_get_concurrency_matrix(wifi_interface_handle handle, int set_size_max,
+        feature_set set[], int *set_size);
+
+/* multiple interface support */
+
+wifi_error wifi_get_ifaces(wifi_handle handle, int *num_ifaces, wifi_interface_handle **ifaces);
+wifi_error wifi_get_iface_name(wifi_interface_handle iface, char *name, size_t size);
+wifi_interface_handle wifi_get_iface_handle(wifi_handle handle, char *name);
+
+/* STA + STA support - Supported if WIFI_FEATURE_ADDITIONAL_STA is set */
+
+/**
+ * Invoked to indicate that the provided iface is the primary STA iface when there are more
+ * than 1 STA iface concurrently active.
+ *
+ * Note: If the wifi firmware/chip cannot support multiple instances of any offload
+ * (like roaming, APF, rssi threshold, etc), the firmware should ensure that these
+ * offloads are at least enabled for the primary interface. If the new primary interface is
+ * already connected to a network, the firmware must switch all the offloads on
+ * this new interface without disconnecting.
+ */
+wifi_error wifi_multi_sta_set_primary_connection(wifi_handle handle, wifi_interface_handle iface);
+
+/**
+ * When there are 2 or more simultaneous STA connections, this use case hint indicates what
+ * use-case is being enabled by the framework. This use case hint can be used by the firmware
+ * to modify various firmware configurations like:
+ *  - Allowed BSSIDs the firmware can choose for the initial connection/roaming attempts.
+ *  - Duty cycle to choose for the 2 STA connections if the radio is in MCC mode.
+ *  - Whether roaming, APF and other offloads needs to be enabled or not.
+ *
+ * Note:
+ *  - This will be invoked before an active wifi connection is established on the second interface.
+ *  - This use-case hint is implicitly void when the second STA interface is brought down.
+ */
+typedef enum {
+    /**
+     * Usage:
+     * - This will be sent down for make before break use-case.
+     * - Platform is trying to speculatively connect to a second network and evaluate it without
+     *   disrupting the primary connection.
+     *
+     * Requirements for Firmware:
+     * - Do not reduce the number of tx/rx chains of primary connection.
+     * - If using MCC, should set the MCC duty cycle of the primary connection to be higher than
+     *   the secondary connection (maybe 70/30 split).
+     * - Should pick the best BSSID for the secondary STA (disregard the chip mode) independent of
+     *   the primary STA:
+     *     - Don’t optimize for DBS vs MCC/SCC
+     * - Should not impact the primary connection’s bssid selection:
+     *     - Don’t downgrade chains of the existing primary connection.
+     *     - Don’t optimize for DBS vs MCC/SCC.
+     */
+    WIFI_DUAL_STA_TRANSIENT_PREFER_PRIMARY = 0,
+    /**
+     * Usage:
+     * - This will be sent down for any app requested peer to peer connections.
+     * - In this case, both the connections needs to be allocated equal resources.
+     * - For the peer to peer use case, BSSID for the secondary connection will be chosen by the
+     *   framework.
+     *
+     * Requirements for Firmware:
+     * - Can choose MCC or DBS mode depending on the MCC efficiency and HW capability.
+     * - If using MCC, set the MCC duty cycle of the primary connection to be equal to the secondary
+     *   connection.
+     * - Prefer BSSID candidates which will help provide the best "overall" performance for both the
+     *   connections.
+     */
+    WIFI_DUAL_STA_NON_TRANSIENT_UNBIASED = 1
+} wifi_multi_sta_use_case;
+
+wifi_error wifi_multi_sta_set_use_case(wifi_handle handle, wifi_multi_sta_use_case use_case);
+
+/* Configuration events */
+
+typedef struct {
+    void (*on_country_code_changed)(char code[2]);      // We can get this from supplicant too
+
+    // More event handlers
+} wifi_event_handler;
+
+typedef struct {
+    char iface_name[IFNAMSIZ + 1];
+    wifi_channel channel;
+} wifi_iface_info;
+
+typedef struct {
+    u32 wlan_mac_id;
+/* BIT MASK of BIT(WLAN_MAC*) as represented by wlan_mac_band */
+    u32 mac_band;
+/* Represents the connected Wi-Fi interfaces associated with each MAC */
+    int num_iface;
+    wifi_iface_info *iface_info;
+} wifi_mac_info;
+
+typedef struct {
+        void (*on_radio_mode_change)(wifi_request_id id, unsigned num_mac,
+                                     wifi_mac_info *mac_info);
+} wifi_radio_mode_change_handler;
+
+typedef struct {
+        void (*on_rssi_threshold_breached)(wifi_request_id id, u8 *cur_bssid, s8 cur_rssi);
+} wifi_rssi_event_handler;
+
+typedef struct {
+        void (*on_subsystem_restart)(const char* error);
+} wifi_subsystem_restart_handler;
+
+typedef struct {
+        void (*on_chre_nan_rtt_change)(chre_nan_rtt_state state);
+} wifi_chre_handler;
+
+wifi_error wifi_set_iface_event_handler(wifi_request_id id, wifi_interface_handle iface, wifi_event_handler eh);
+wifi_error wifi_reset_iface_event_handler(wifi_request_id id, wifi_interface_handle iface);
+
+wifi_error wifi_set_nodfs_flag(wifi_interface_handle handle, u32 nodfs);
+wifi_error wifi_select_tx_power_scenario(wifi_interface_handle handle, wifi_power_scenario scenario);
+wifi_error wifi_reset_tx_power_scenario(wifi_interface_handle handle);
+wifi_error wifi_set_latency_mode(wifi_interface_handle handle, wifi_latency_mode mode);
+wifi_error wifi_map_dscp_access_category(wifi_handle handle,
+                                         uint32_t start, uint32_t end,
+                                         uint32_t access_category);
+wifi_error wifi_reset_dscp_mapping(wifi_handle handle);
+
+wifi_error wifi_set_subsystem_restart_handler(wifi_handle handle,
+                                              wifi_subsystem_restart_handler handler);
+
+/**
+ *  Wifi HAL Thermal Mitigation API
+ *
+ *  wifi_handle : wifi global handle (note: this is not a interface specific
+ *  command). Mitigation is expected to be applied across all active interfaces
+ *  The implementation and the mitigation action mapping to each mode is chip
+ *  specific. Mitigation will be active until Wifi is turned off or
+ *  WIFI_MITIGATION_NONE mode is sent
+ *
+ *  mode: Thermal mitigation mode
+ *  WIFI_MITIGATION_NONE     : Clear all Wifi thermal mitigation actions
+ *  WIFI_MITIGATION_LIGHT    : Light Throttling where UX is not impacted
+ *  WIFI_MITIGATION_MODERATE : Moderate throttling where UX not largely impacted
+ *  WIFI_MITIGATION_SEVERE   : Severe throttling where UX is largely impacted
+ *  WIFI_MITIGATION_CRITICAL : Platform has done everything to reduce power
+ *  WIFI_MITIGATION_EMERGENCY: Key components in platform are shutting down
+ *
+ *  completion_window
+ *  Deadline (in milliseconds) to complete this request, value 0 implies apply
+ *  immediately. Deadline is basically a relaxed limit and allows vendors to
+ *  apply the mitigation within the window (if it cannot apply immediately)
+ *
+ *  Return
+ *  WIFI_ERROR_NOT_SUPPORTED : Chip does not support thermal mitigation
+ *  WIFI_ERROR_BUSY          : Mitigation is supported, but retry later
+ *  WIFI_ERROR_NONE          : Mitigation request has been accepted
+ */
+wifi_error wifi_set_thermal_mitigation_mode(wifi_handle handle,
+                                            wifi_thermal_mode mode,
+                                            u32 completion_window);
+
+
+typedef struct rx_data_cnt_details_t {
+    int rx_unicast_cnt;     /*Total rx unicast packet which woke up host */
+    int rx_multicast_cnt;   /*Total rx multicast packet which woke up host */
+    int rx_broadcast_cnt;   /*Total rx broadcast packet which woke up host */
+} RX_DATA_WAKE_CNT_DETAILS;
+
+typedef struct rx_wake_pkt_type_classification_t {
+    int icmp_pkt;   /*wake icmp packet count */
+    int icmp6_pkt;  /*wake icmp6 packet count */
+    int icmp6_ra;   /*wake icmp6 RA packet count */
+    int icmp6_na;   /*wake icmp6 NA packet count */
+    int icmp6_ns;   /*wake icmp6 NS packet count */
+    //ToDo: Any more interesting classification to add?
+} RX_WAKE_PKT_TYPE_CLASSFICATION;
+
+typedef struct rx_multicast_cnt_t{
+    int ipv4_rx_multicast_addr_cnt; /*Rx wake packet was ipv4 multicast */
+    int ipv6_rx_multicast_addr_cnt; /*Rx wake packet was ipv6 multicast */
+    int other_rx_multicast_addr_cnt;/*Rx wake packet was non-ipv4 and non-ipv6*/
+} RX_MULTICAST_WAKE_DATA_CNT;
+
+/*
+ * Structure holding all the driver/firmware wake count reasons.
+ *
+ * Buffers for the array fields (cmd_event_wake_cnt/driver_fw_local_wake_cnt)
+ * are allocated and freed by the framework. The size of each allocated
+ * array is indicated by the corresponding |_cnt| field. HAL needs to fill in
+ * the corresponding |_used| field to indicate the number of elements used in
+ * the array.
+ */
+typedef struct wlan_driver_wake_reason_cnt_t {
+    int total_cmd_event_wake;    /* Total count of cmd event wakes */
+    int *cmd_event_wake_cnt;     /* Individual wake count array, each index a reason */
+    int cmd_event_wake_cnt_sz;   /* Max number of cmd event wake reasons */
+    int cmd_event_wake_cnt_used; /* Number of cmd event wake reasons specific to the driver */
+
+    int total_driver_fw_local_wake;    /* Total count of drive/fw wakes, for local reasons */
+    int *driver_fw_local_wake_cnt;     /* Individual wake count array, each index a reason */
+    int driver_fw_local_wake_cnt_sz;   /* Max number of local driver/fw wake reasons */
+    int driver_fw_local_wake_cnt_used; /* Number of local driver/fw wake reasons specific to the driver */
+
+    int total_rx_data_wake;     /* total data rx packets, that woke up host */
+    RX_DATA_WAKE_CNT_DETAILS rx_wake_details;
+    RX_WAKE_PKT_TYPE_CLASSFICATION rx_wake_pkt_classification_info;
+    RX_MULTICAST_WAKE_DATA_CNT rx_multicast_wake_pkt_info;
+} WLAN_DRIVER_WAKE_REASON_CNT;
+
+/* Wi-Fi coex channel avoidance support */
+
+#define WIFI_COEX_NO_POWER_CAP (int32_t)0x7FFFFFF
+
+typedef enum {
+    WIFI_AWARE = 1 << 0,
+    SOFTAP = 1 << 1,
+    WIFI_DIRECT = 1 << 2
+} wifi_coex_restriction;
+
+/**
+ * Representation of a Wi-Fi channel to be avoided for Wi-Fi coex channel avoidance.
+ *
+ * band is represented as an WLAN_MAC* enum value defined in wlan_mac_band.
+ * If power_cap_dbm is WIFI_COEX_NO_POWER_CAP, then no power cap should be applied if the specified
+ * channel is used.
+ */
+typedef struct {
+    wlan_mac_band band;
+    u32 channel;
+    s32 power_cap_dbm;
+} wifi_coex_unsafe_channel;
+
+
+/* include various feature headers */
+
+#include "gscan.h"
+#include "link_layer_stats.h"
+#include "wifi_cached_scan_results.h"
+#include "rtt.h"
+#include "tdls.h"
+#include "wifi_logger.h"
+#include "wifi_config.h"
+#include "wifi_nan.h"
+#include "wifi_offload.h"
+#include "roam.h"
+#include "wifi_twt.h"
+
+//wifi HAL function pointer table
+typedef struct {
+    wifi_error (* wifi_initialize) (wifi_handle *);
+    wifi_error (* wifi_wait_for_driver_ready) (void);
+    void (* wifi_cleanup) (wifi_handle, wifi_cleaned_up_handler);
+    void (*wifi_event_loop)(wifi_handle);
+    void (* wifi_get_error_info) (wifi_error , const char **);
+    wifi_error (* wifi_get_supported_feature_set) (wifi_interface_handle, feature_set *);
+    wifi_error (* wifi_get_concurrency_matrix) (wifi_interface_handle, int, feature_set *, int *);
+    wifi_error (* wifi_set_scanning_mac_oui) (wifi_interface_handle, unsigned char *);
+    wifi_error (* wifi_get_supported_channels)(wifi_handle, int *, wifi_channel *);
+    wifi_error (* wifi_is_epr_supported)(wifi_handle);
+    wifi_error (* wifi_get_ifaces) (wifi_handle , int *, wifi_interface_handle **);
+    wifi_error (* wifi_get_iface_name) (wifi_interface_handle, char *name, size_t);
+    wifi_error (* wifi_set_iface_event_handler) (wifi_request_id,wifi_interface_handle ,
+            wifi_event_handler);
+    wifi_error (* wifi_reset_iface_event_handler) (wifi_request_id, wifi_interface_handle);
+    wifi_error (* wifi_start_gscan) (wifi_request_id, wifi_interface_handle, wifi_scan_cmd_params,
+            wifi_scan_result_handler);
+    wifi_error (* wifi_stop_gscan)(wifi_request_id, wifi_interface_handle);
+    wifi_error (* wifi_get_cached_gscan_results)(wifi_interface_handle, byte, int,
+            wifi_cached_scan_results *, int *);
+    wifi_error (* wifi_set_bssid_hotlist)(wifi_request_id, wifi_interface_handle,
+            wifi_bssid_hotlist_params, wifi_hotlist_ap_found_handler);
+    wifi_error (* wifi_reset_bssid_hotlist)(wifi_request_id, wifi_interface_handle);
+    wifi_error (* wifi_set_significant_change_handler)(wifi_request_id, wifi_interface_handle,
+            wifi_significant_change_params, wifi_significant_change_handler);
+    wifi_error (* wifi_reset_significant_change_handler)(wifi_request_id, wifi_interface_handle);
+    wifi_error (* wifi_get_gscan_capabilities)(wifi_interface_handle, wifi_gscan_capabilities *);
+    wifi_error (* wifi_set_link_stats) (wifi_interface_handle, wifi_link_layer_params);
+    wifi_error (* wifi_get_link_stats) (wifi_request_id,wifi_interface_handle,
+            wifi_stats_result_handler);
+    wifi_error (* wifi_clear_link_stats)(wifi_interface_handle,u32, u32 *, u8, u8 *);
+    wifi_error (* wifi_get_valid_channels)(wifi_interface_handle,int, int, wifi_channel *, int *);
+    wifi_error (* wifi_rtt_range_request)(wifi_request_id, wifi_interface_handle, unsigned,
+            wifi_rtt_config[], wifi_rtt_event_handler);
+    wifi_error (* wifi_rtt_range_request_v3)(wifi_request_id, wifi_interface_handle, unsigned,
+            wifi_rtt_config_v3[], wifi_rtt_event_handler_v3);
+    wifi_error (* wifi_rtt_range_cancel)(wifi_request_id,  wifi_interface_handle, unsigned,
+            mac_addr[]);
+    wifi_error (* wifi_get_rtt_capabilities)(wifi_interface_handle, wifi_rtt_capabilities *);
+    wifi_error (* wifi_get_rtt_capabilities_v3)(wifi_interface_handle, wifi_rtt_capabilities_v3 *);
+    wifi_error (* wifi_rtt_get_responder_info)(wifi_interface_handle iface,
+            wifi_rtt_responder *responder_info);
+    wifi_error (* wifi_enable_responder)(wifi_request_id id, wifi_interface_handle iface,
+            wifi_channel_info channel_hint, unsigned max_duration_seconds,
+            wifi_rtt_responder *responder_info);
+    wifi_error (* wifi_disable_responder)(wifi_request_id id, wifi_interface_handle iface);
+    wifi_error (* wifi_set_nodfs_flag)(wifi_interface_handle, u32);
+    wifi_error (* wifi_start_logging)(wifi_interface_handle, u32, u32, u32, u32, char *);
+    wifi_error (* wifi_set_epno_list)(wifi_request_id, wifi_interface_handle,
+            const wifi_epno_params *, wifi_epno_handler);
+    wifi_error (* wifi_reset_epno_list)(wifi_request_id, wifi_interface_handle);
+    wifi_error (* wifi_set_country_code)(wifi_interface_handle, const char *);
+    wifi_error (* wifi_get_firmware_memory_dump)( wifi_interface_handle iface,
+            wifi_firmware_memory_dump_handler handler);
+    wifi_error (* wifi_set_log_handler)(wifi_request_id id, wifi_interface_handle iface,
+        wifi_ring_buffer_data_handler handler);
+    wifi_error (* wifi_reset_log_handler)(wifi_request_id id, wifi_interface_handle iface);
+    wifi_error (* wifi_set_alert_handler)(wifi_request_id id, wifi_interface_handle iface,
+        wifi_alert_handler handler);
+    wifi_error (* wifi_reset_alert_handler)(wifi_request_id id, wifi_interface_handle iface);
+    wifi_error (* wifi_get_firmware_version)(wifi_interface_handle iface, char *buffer,
+            int buffer_size);
+    wifi_error (* wifi_get_ring_buffers_status)(wifi_interface_handle iface,
+            u32 *num_rings, wifi_ring_buffer_status *status);
+    wifi_error (* wifi_get_logger_supported_feature_set)(wifi_interface_handle iface,
+            unsigned int *support);
+    wifi_error (* wifi_get_ring_data)(wifi_interface_handle iface, char *ring_name);
+    wifi_error (* wifi_enable_tdls)(wifi_interface_handle, mac_addr, wifi_tdls_params *,
+            wifi_tdls_handler);
+    wifi_error (* wifi_disable_tdls)(wifi_interface_handle, mac_addr);
+    wifi_error (*wifi_get_tdls_status) (wifi_interface_handle, mac_addr, wifi_tdls_status *);
+    wifi_error (*wifi_get_tdls_capabilities)(wifi_interface_handle iface,
+            wifi_tdls_capabilities *capabilities);
+    wifi_error (* wifi_get_driver_version)(wifi_interface_handle iface, char *buffer,
+            int buffer_size);
+    wifi_error (* wifi_set_passpoint_list)(wifi_request_id id, wifi_interface_handle iface,
+            int num, wifi_passpoint_network *networks, wifi_passpoint_event_handler handler);
+    wifi_error (* wifi_reset_passpoint_list)(wifi_request_id id, wifi_interface_handle iface);
+    wifi_error (*wifi_set_lci) (wifi_request_id id, wifi_interface_handle iface,
+                                wifi_lci_information *lci);
+    wifi_error (*wifi_set_lcr) (wifi_request_id id, wifi_interface_handle iface,
+                                wifi_lcr_information *lcr);
+    wifi_error (*wifi_start_sending_offloaded_packet)(wifi_request_id id,
+                                wifi_interface_handle iface, u16 ether_type, u8 *ip_packet,
+                                u16 ip_packet_len, u8 *src_mac_addr, u8 *dst_mac_addr,
+                                u32 period_msec);
+    wifi_error (*wifi_stop_sending_offloaded_packet)(wifi_request_id id,
+                                wifi_interface_handle iface);
+    wifi_error (*wifi_start_rssi_monitoring)(wifi_request_id id, wifi_interface_handle
+                        iface, s8 max_rssi, s8 min_rssi, wifi_rssi_event_handler eh);
+    wifi_error (*wifi_stop_rssi_monitoring)(wifi_request_id id, wifi_interface_handle iface);
+    wifi_error (*wifi_get_wake_reason_stats)(wifi_interface_handle iface,
+                                WLAN_DRIVER_WAKE_REASON_CNT *wifi_wake_reason_cnt);
+    wifi_error (*wifi_configure_nd_offload)(wifi_interface_handle iface, u8 enable);
+    wifi_error (*wifi_get_driver_memory_dump)(wifi_interface_handle iface,
+                                wifi_driver_memory_dump_callbacks callbacks);
+    wifi_error (*wifi_start_pkt_fate_monitoring)(wifi_interface_handle iface);
+    wifi_error (*wifi_get_tx_pkt_fates)(wifi_interface_handle handle,
+        wifi_tx_report *tx_report_bufs,
+        size_t n_requested_fates,
+        size_t *n_provided_fates);
+    wifi_error (*wifi_get_rx_pkt_fates)(wifi_interface_handle handle,
+        wifi_rx_report *rx_report_bufs,
+        size_t n_requested_fates,
+        size_t *n_provided_fates);
+
+    /* NAN functions */
+    wifi_error (*wifi_nan_enable_request)(transaction_id id,
+        wifi_interface_handle iface,
+        NanEnableRequest* msg);
+    wifi_error (*wifi_nan_disable_request)(transaction_id id,
+        wifi_interface_handle iface);
+    wifi_error (*wifi_nan_publish_request)(transaction_id id,
+        wifi_interface_handle iface,
+        NanPublishRequest* msg);
+    wifi_error (*wifi_nan_publish_cancel_request)(transaction_id id,
+        wifi_interface_handle iface,
+        NanPublishCancelRequest* msg);
+    wifi_error (*wifi_nan_subscribe_request)(transaction_id id,
+        wifi_interface_handle iface,
+        NanSubscribeRequest* msg);
+    wifi_error (*wifi_nan_subscribe_cancel_request)(transaction_id id,
+        wifi_interface_handle iface,
+        NanSubscribeCancelRequest* msg);
+    wifi_error (*wifi_nan_transmit_followup_request)(transaction_id id,
+        wifi_interface_handle iface,
+        NanTransmitFollowupRequest* msg);
+    wifi_error (*wifi_nan_stats_request)(transaction_id id,
+        wifi_interface_handle iface,
+        NanStatsRequest* msg);
+    wifi_error (*wifi_nan_config_request)(transaction_id id,
+        wifi_interface_handle iface,
+        NanConfigRequest* msg);
+    wifi_error (*wifi_nan_tca_request)(transaction_id id,
+        wifi_interface_handle iface,
+        NanTCARequest* msg);
+    wifi_error (*wifi_nan_beacon_sdf_payload_request)(transaction_id id,
+        wifi_interface_handle iface,
+        NanBeaconSdfPayloadRequest* msg);
+    wifi_error (*wifi_nan_register_handler)(wifi_interface_handle iface,
+        NanCallbackHandler handlers);
+    wifi_error (*wifi_nan_get_version)(wifi_handle handle,
+        NanVersion* version);
+    wifi_error (*wifi_nan_get_capabilities)(transaction_id id,
+        wifi_interface_handle iface);
+    wifi_error (*wifi_nan_data_interface_create)(transaction_id id,
+                                                 wifi_interface_handle iface,
+                                                 char *iface_name);
+    wifi_error (*wifi_nan_data_interface_delete)(transaction_id id,
+                                                 wifi_interface_handle iface,
+                                                 char *iface_name);
+    wifi_error (*wifi_nan_data_request_initiator)(
+        transaction_id id, wifi_interface_handle iface,
+        NanDataPathInitiatorRequest *msg);
+    wifi_error (*wifi_nan_data_indication_response)(
+        transaction_id id, wifi_interface_handle iface,
+        NanDataPathIndicationResponse *msg);
+    wifi_error (*wifi_nan_data_end)(transaction_id id,
+                                    wifi_interface_handle iface,
+                                    NanDataPathEndRequest *msg);
+    wifi_error (*wifi_select_tx_power_scenario)(wifi_interface_handle iface,
+                                                wifi_power_scenario scenario);
+    wifi_error (*wifi_reset_tx_power_scenario)(wifi_interface_handle iface);
+
+    /**
+     * Returns the chipset's hardware filtering capabilities:
+     * @param version pointer to version of the packet filter interpreter
+     *                supported, filled in upon return. 0 indicates no support.
+     * @param max_len pointer to maximum size of the filter bytecode, filled in
+     *                upon return.
+     */
+    wifi_error (*wifi_get_packet_filter_capabilities)(wifi_interface_handle handle,
+                                                      u32 *version, u32 *max_len);
+    /**
+     * Programs the packet filter.
+     * @param program pointer to the program byte-code.
+     * @param len length of the program byte-code.
+     */
+    wifi_error (*wifi_set_packet_filter)(wifi_interface_handle handle,
+                                         const u8 *program, u32 len);
+    wifi_error (*wifi_read_packet_filter)(wifi_interface_handle handle,
+                                          u32 src_offset, u8 *host_dst,
+                                          u32 length);
+    wifi_error (*wifi_get_roaming_capabilities)(wifi_interface_handle handle,
+                                                wifi_roaming_capabilities *caps);
+    wifi_error (*wifi_enable_firmware_roaming)(wifi_interface_handle handle,
+                                               fw_roaming_state_t state);
+    wifi_error (*wifi_configure_roaming)(wifi_interface_handle handle,
+                                         wifi_roaming_config *roaming_config);
+    wifi_error (*wifi_set_radio_mode_change_handler)(wifi_request_id id, wifi_interface_handle
+                        iface, wifi_radio_mode_change_handler eh);
+    wifi_error (*wifi_set_latency_mode)(wifi_interface_handle iface,
+                                        wifi_latency_mode mode);
+    wifi_error (*wifi_set_thermal_mitigation_mode)(wifi_handle handle,
+                                                   wifi_thermal_mode mode,
+                                                   u32 completion_window);
+    wifi_error (*wifi_map_dscp_access_category)(wifi_handle handle,
+                                                u32 start, u32 end,
+                                                u32 access_category);
+    wifi_error (*wifi_reset_dscp_mapping)(wifi_handle handle);
+
+    wifi_error (*wifi_virtual_interface_create)(wifi_handle handle, const char* ifname,
+                                                wifi_interface_type iface_type);
+    wifi_error (*wifi_virtual_interface_delete)(wifi_handle handle, const char* ifname);
+
+    wifi_error (*wifi_set_subsystem_restart_handler)(wifi_handle handle,
+                                                     wifi_subsystem_restart_handler handler);
+
+    /**
+      * Allow vendor HAL to choose interface name when creating
+      * an interface. This can be implemented by chips with their
+      * own interface naming policy.
+      * If not implemented, the default naming will be used.
+      */
+    wifi_error (*wifi_get_supported_iface_name)(wifi_handle handle, u32 iface_type,
+                                                char *name, size_t len);
+
+    /**
+     * Perform early initialization steps that are needed when WIFI
+     * is disabled.
+     * If the function returns failure, it means the vendor HAL is unusable
+     * (for example, if chip hardware is not installed) and no further
+     * functions should be called.
+     */
+    wifi_error (*wifi_early_initialize)(void);
+
+    /**
+     * Get supported feature set which are chip-global, that is
+     * not dependent on any created interface.
+     */
+    wifi_error (*wifi_get_chip_feature_set)(wifi_handle handle, feature_set *set);
+
+    /**
+     * Invoked to indicate that the provided iface is the primary STA iface when there are more
+     * than 1 STA iface concurrently active.
+     */
+    wifi_error (*wifi_multi_sta_set_primary_connection)(wifi_handle handle,
+                                                        wifi_interface_handle iface);
+
+
+    /**
+     * When there are 2 simultaneous STA connections, this use case hint
+     * indicates what STA + STA use-case is being enabled by the framework.
+     */
+    wifi_error (*wifi_multi_sta_set_use_case)(wifi_handle handle,
+                                              wifi_multi_sta_use_case use_case);
+
+    /**
+     * Invoked to indicate that the following list of wifi_coex_unsafe_channel should be avoided
+     * with the specified restrictions.
+     * @param unsafeChannels list of current |wifi_coex_unsafe_channel| to avoid.
+     * @param restrictions bitmask of |wifi_coex_restriction| indicating wifi interfaces to
+     *         restrict from the current unsafe channels.
+     */
+    wifi_error (*wifi_set_coex_unsafe_channels)(wifi_handle handle, u32 num_channels,
+                                                wifi_coex_unsafe_channel *unsafeChannels,
+                                                u32 restrictions);
+
+    /**
+     * Invoked to set voip optimization mode for the provided STA iface
+     */
+    wifi_error (*wifi_set_voip_mode)(wifi_interface_handle iface, wifi_voip_mode mode);
+
+    /**
+     * Get Target Wake Time (TWT) local device capabilities for the station interface.
+     *
+     * @param iface Wifi interface handle
+     * @param capabilities TWT capabilities
+     * @return Synchronous wifi_error
+     */
+    wifi_error (*wifi_twt_get_capabilities)(wifi_interface_handle iface,
+                                            wifi_twt_capabilities* capabilities);
+
+    /**
+     * Register TWT events before sending any TWT request
+     *
+     * @param wifi_interface_handle:
+     * @param events: TWT events callbacks to register
+     * @return Synchronous wifi_error
+     */
+    wifi_error (*wifi_twt_register_events)(wifi_interface_handle iface, wifi_twt_events events);
+
+    /**
+     * Setup a TWT session.
+     *
+     * Supported only if wifi_twt_capabilities.is_twt_requester_supported is set. Results in
+     * asynchronous callback wifi_twt_events.on_twt_session_create on success or
+     * wifi_twt_events.on_twt_failure with error code.
+     *
+     * @param id Identifier for the command. The value 0 is reserved.
+     * @param iface Wifi interface handle
+     * @param request TWT request parameters
+     * @return Synchronous wifi_error
+    */
+    wifi_error (*wifi_twt_session_setup)(wifi_request_id id, wifi_interface_handle iface,
+                                 wifi_twt_request request);
+    /**
+     * Update a TWT session.
+     *
+     * Supported only if wifi_twt_session.is_updatable is set. Reesults in asynchronous callback
+     * wifi_twt_events.on_twt_session_update on success or wifi_twt_events.on_twt_failure with
+     * error code.
+     *
+     * @param id Identifier for the command. The value 0 is reserved.
+     * @param iface Wifi interface handle
+     * @param session_id TWT session identifier
+     * @param request TWT request parameters
+     * @return Synchronous wifi_error
+    */
+    wifi_error (*wifi_twt_session_update)(wifi_request_id id, wifi_interface_handle iface,
+                                  int session_id, wifi_twt_request request);
+    /**
+     * Suspend a TWT session.
+     * Supported only if wifi_twt_session.is_suspendable is set. Results in asynchronous callback
+     * wifi_twt_events.on_twt_session_suspend on success or wifi_twt_events.on_twt_failure with
+     * error code.
+     *
+     * @param id Identifier for the command. The value 0 is reserved.
+     * @param iface Wifi interface handle
+     * @param session_id TWT session identifier
+     * @return Synchronous wifi_error
+    */
+    wifi_error (*wifi_twt_session_suspend)(wifi_request_id id, wifi_interface_handle iface,
+                                   int session_id);
+    /**
+     * Resume a suspended TWT session.
+     *
+     * Supported only if wifi_twt_session.is_suspendable is set. Results in asynchronous callback
+     * wifi_twt_events.on_twt_session_resume on success or wifi_twt_events.on_twt_failure with
+     * error code.
+     *
+     * @param id Identifier for the command. The value 0 is reserved.
+     * @param iface Wifi interface handle
+     * @param session_id TWT session identifier
+     * @return Synchronous wifi_error
+    */
+    wifi_error (*wifi_twt_session_resume)(wifi_request_id id, wifi_interface_handle iface,
+                                  int session_id);
+    /**
+     * Teardown a TWT session.
+     *
+     * Results in asynchronous callback  wifi_twt_events.on_twt_session_teardown on success or
+     * wifi_twt_events.on_twt_failure with error code.
+     *
+     * @param id Identifier for the command. The value 0 is reserved.
+     * @param iface Wifi interface handle
+     * @param session_id TWT session identifier
+     * @return Synchronous wifi_error
+    */
+    wifi_error (*wifi_twt_session_teardown)(wifi_request_id id, wifi_interface_handle iface,
+                                  int session_id);
+
+    /**
+     * Get stats for a TWT session.
+     *
+     * Results in asynchronous callback  wifi_twt_events.on_twt_session_stats on success or
+     * wifi_twt_events.on_twt_failure with error code.
+     *
+     * @param id Identifier for the command. The value 0 is reserved.
+     * @param iface Wifi interface handle
+     * @param session_id TWT session identifier
+     * @return Synchronous wifi_error
+    */
+    wifi_error (*wifi_twt_session_get_stats)(wifi_request_id id, wifi_interface_handle iface,
+                                             int session_id);
+
+    /**@brief twt_register_handler
+     *        Request to register TWT callback before sending any TWT request
+     * @param wifi_interface_handle:
+     * @param TwtCallbackHandler: callback function pointers
+     * @return Synchronous wifi_error
+     *
+     * Note: This function is deprecated by wifi_twt_register_events
+     */
+    wifi_error (*wifi_twt_register_handler)(wifi_interface_handle iface,
+                                            TwtCallbackHandler handler);
+
+    /**@brief twt_get_capability
+     *        Request TWT capability
+     * @param wifi_interface_handle:
+     * @return Synchronous wifi_error and TwtCapabilitySet
+     *
+     * Note: This function is deprecated by wifi_twt_get_capabilities
+     */
+    wifi_error (*wifi_twt_get_capability)(wifi_interface_handle iface,
+                                          TwtCapabilitySet* twt_cap_set);
+
+    /**@brief twt_setup_request
+     *        Request to send TWT setup frame
+     * @param wifi_interface_handle:
+     * @param TwtSetupRequest: detailed parameters of setup request
+     * @return Synchronous wifi_error
+     * @return Asynchronous EventTwtSetupResponse CB return TwtSetupResponse
+     *
+     * Note: This function is deprecated by wifi_twt_session_setup
+     */
+    wifi_error (*wifi_twt_setup_request)(wifi_interface_handle iface,
+                                         TwtSetupRequest* msg);
+
+    /**@brief twt_teardown_request
+     *        Request to send TWT teardown frame
+     * @param wifi_interface_handle:
+     * @param TwtTeardownRequest: detailed parameters of teardown request
+     * @return Synchronous wifi_error
+     * @return Asynchronous EventTwtTeardownCompletion CB return TwtTeardownCompletion
+     * TwtTeardownCompletion may also be received due to other events
+     * like CSA, BTCX, TWT scheduler, MultiConnection, peer-initiated teardown, etc.
+     *
+     * Note: This function is deprecated by wifi_twt_session_teardown
+     */
+    wifi_error (*wifi_twt_teardown_request)(wifi_interface_handle iface,
+                                            TwtTeardownRequest* msg);
+
+    /**@brief twt_info_frame_request
+     *        Request to send TWT info frame
+     * @param wifi_interface_handle:
+     * @param TwtInfoFrameRequest: detailed parameters in info frame
+     * @return Synchronous wifi_error
+     * @return Asynchronous EventTwtInfoFrameReceived CB return TwtInfoFrameReceived
+     * Driver may also receive Peer-initiated TwtInfoFrame
+     *
+     * Note: This function is deprecated by wifi_twt_session_suspend and
+     * wifi_twt_session_resume
+     */
+    wifi_error (*wifi_twt_info_frame_request)(wifi_interface_handle iface,
+                                              TwtInfoFrameRequest* msg);
+
+    /**@brief twt_get_stats
+     *        Request to get TWT stats
+     * @param wifi_interface_handle:
+     * @param config_id: configuration ID of TWT request
+     * @return Synchronous wifi_error and TwtStats
+     *
+     * Note: This function is deprecated by wifi_twt_get_session_stats
+     */
+    wifi_error (*wifi_twt_get_stats)(wifi_interface_handle iface, u8 config_id,
+                                     TwtStats* stats);
+
+    /**@brief twt_clear_stats
+     *        Request to clear TWT stats
+     * @param wifi_interface_handle:
+     * @param config_id: configuration ID of TWT request
+     * @return Synchronous wifi_error
+     *
+     * Note: This function is deprecated.
+     */
+    wifi_error (*wifi_twt_clear_stats)(wifi_interface_handle iface, u8 config_id);
+
+    /**
+     * Invoked to set DTIM configuration when the host is in the suspend mode
+     * @param wifi_interface_handle:
+     * @param multiplier: when STA in the power saving mode, the wake up interval will be set to
+     *              1) multiplier * DTIM period if multiplier > 0.
+     *              2) the device default value if multiplier <=0
+     * Some implementations may apply an additional cap to wake up interval in the case of 1).
+     */
+    wifi_error (*wifi_set_dtim_config)(wifi_interface_handle handle, u32 multiplier);
+
+    /**@brief wifi_get_usable_channels
+     *        Request list of usable channels for the requested bands and modes. Usable
+     *        implies channel is allowed as per regulatory for the current country code
+     *        and not restricted due to other hard limitations (e.g. DFS, Coex) In
+     *        certain modes (e.g. STA+SAP) there could be other hard restrictions
+     *        since MCC operation many not be supported by SAP. This API also allows
+     *        driver to return list of usable channels for each mode uniquely to
+     *        distinguish cases where only a limited set of modes are allowed on
+     *        a given channel e.g. srd channels may be supported for P2P but not
+     *        for SAP or P2P-Client may be allowed on an indoor channel but P2P-GO
+     *        may not be allowed. This API is not interface specific and will be
+     *        used to query capabilities of driver in terms of what modes (STA, SAP,
+     *        P2P_CLI, P2P_GO, NAN, TDLS) can be supported on each of the channels.
+     * @param handle global wifi_handle
+     * @param band_mask BIT MASK of WLAN_MAC* as represented by |wlan_mac_band|
+     * @param iface_mode_mask BIT MASK of BIT(WIFI_INTERFACE_*) represented by
+     *        |wifi_interface_mode|. Bitmask respresents all the modes that the
+     *        caller is interested in (e.g. STA, SAP, WFD-CLI, WFD-GO, TDLS, NAN).
+     *        Note: Bitmask does not represent concurrency matrix. If the caller
+     *        is interested in CLI, GO modes, the iface_mode_mask would be set
+     *        to WIFI_INTERFACE_P2P_CLIENT|WIFI_INTERFACE_P2P_GO.
+     * @param filter_mask BIT MASK of WIFI_USABLE_CHANNEL_FILTER_* represented by
+     *        |wifi_usable_channel_filter|. Indicates if the channel list should
+     *        be filtered based on additional criteria. If filter_mask is not
+     *        specified, driver should return list of usable channels purely
+     *        based on regulatory constraints.
+     * @param max_size maximum number of |wifi_usable_channel|
+     * @param size actual number of |wifi_usable_channel| entries returned by driver
+     * @param channels list of usable channels represented by |wifi_usable_channel|
+     */
+    wifi_error (*wifi_get_usable_channels)(wifi_handle handle, u32 band_mask, u32 iface_mode_mask,
+                                           u32 filter_mask, u32 max_size, u32* size,
+                                           wifi_usable_channel* channels);
+
+    /**
+     * Trigger wifi subsystem restart to reload firmware
+     */
+    wifi_error (*wifi_trigger_subsystem_restart)(wifi_handle handle);
+
+    /**
+     * Invoked to set that the device is operating in an indoor environment.
+     * @param handle global wifi_handle
+     * @param isIndoor: true if the device is operating in an indoor
+     *        environment, false otherwise.
+     * @return Synchronous wifi_error
+     */
+    wifi_error (*wifi_set_indoor_state)(wifi_handle handle, bool isIndoor);
+
+    /**@brief wifi_get_supported_radio_combinations_matrix
+     *        Request all the possible radio combinations this device can offer.
+     * @param handle global wifi_handle
+     * @param max_size maximum size allocated for filling the wifi_radio_combination_matrix
+     * @param wifi_radio_combination_matrix to return all the possible radio
+     *        combinations.
+     * @param size actual size of wifi_radio_combination_matrix returned from
+     *        lower layer
+     *
+     */
+    wifi_error (*wifi_get_supported_radio_combinations_matrix)(
+        wifi_handle handle, u32 max_size, u32 *size,
+        wifi_radio_combination_matrix *radio_combination_matrix);
+
+    /**@brief wifi_nan_rtt_chre_enable_request
+     *        Request to enable CHRE NAN RTT
+     * @param transaction_id: NAN transaction id
+     * @param wifi_interface_handle
+     * @param NanEnableRequest request message
+     * @return Synchronous wifi_error
+     */
+    wifi_error (*wifi_nan_rtt_chre_enable_request)(transaction_id id,
+                                                   wifi_interface_handle iface,
+                                                   NanEnableRequest* msg);
+
+    /**@brief wifi_nan_rtt_chre_disable_request
+     *        Request to disable CHRE NAN RTT
+     * @param transaction_id: NAN transaction id
+     * @param wifi_interface_handle
+     * @return Synchronous wifi_error
+     */
+    wifi_error (*wifi_nan_rtt_chre_disable_request)(transaction_id id, wifi_interface_handle iface);
+
+    /**@brief wifi_chre_register_handler
+     *        register a handler to get the state of CHR
+     * @param wifi_interface_handle
+     * @param wifi_chre_handler: callback function pointer
+     * @return Synchronous wifi_error
+     */
+    wifi_error (*wifi_chre_register_handler)(wifi_interface_handle iface,
+                                             wifi_chre_handler handler);
+
+    /**@brief wifi_enable_tx_power_limits
+     *        Enable WiFi Tx power limis
+     * @param wifi_interface_handle
+     * @param isEnable : If enable TX limit or not
+     * @return Synchronous wifi_error
+     */
+    wifi_error (*wifi_enable_tx_power_limits) (wifi_interface_handle iface,
+                                               bool isEnable);
+
+    /**@brief wifi_get_cached_scan_results
+     *        Retrieve scan results cached in wifi firmware
+     * @param wifi_interface_handle
+     * @param wifi_cached_scan_result_handler : callback function pointer
+     * @return Synchronous wifi_error
+     */
+    wifi_error (*wifi_get_cached_scan_results)(wifi_interface_handle iface,
+                                               wifi_cached_scan_result_handler handler);
+    /**@brief wifi_get_chip_capabilities
+     *        Retrieve capabilities supported by this chip
+     * @param wifi_handle
+     * @return Synchronous wifi_error and chip capabilites
+     */
+    wifi_error (*wifi_get_chip_capabilities)(wifi_handle handle,
+                                             wifi_chip_capabilities *chip_capabilities);
+
+    /**@brief wifi_get_supported_iface_concurrency_matrix
+     *        Request all the possible interface concurrency combinations this
+     *        Wifi Chip can offer.
+     * @param handle global wifi_handle
+     * @param wifi_iface_concurrency_matrix to return all the possible
+     *        interface concurrency combinations.
+     * @return Synchronous wifi_error
+     */
+    wifi_error (*wifi_get_supported_iface_concurrency_matrix)(
+        wifi_handle handle, wifi_iface_concurrency_matrix *matrix);
+
+    /**@brief wifi_enable_sta_channel_for_peer_network
+     *        enable or disable the feature of allowing current STA-connected
+     *        channel for WFA GO, SAP and Wi-Fi Aware when the regulatory allows.
+     * @param handle global wifi_handle
+     * @param channelCategoryEnableFlag bitmask of |wifi_channel_category|.
+     * @return Synchronous wifi_error
+     */
+    wifi_error (*wifi_enable_sta_channel_for_peer_network)(
+        wifi_handle handle, u32 channelCategoryEnableFlag);
+
+    /**@brief wifi_nan_suspend_request
+     * Request that the specified NAN session be suspended.
+     * @param transaction_id: NAN transaction id
+     * @param wifi_interface_handle
+     * @param NanSuspendRequest request message
+     * @return Synchronous wifi_error
+     */
+    wifi_error (*wifi_nan_suspend_request)(transaction_id id, wifi_interface_handle iface,
+                                                   NanSuspendRequest *msg);
+
+    /**@brief wifi_nan_resume_request
+     * Request that the specified NAN session be resumed.
+     * @param transaction_id: NAN transaction id
+     * @param wifi_interface_handle
+     * @param NanResumeRequest request message
+     * @return Synchronous wifi_error
+     */
+    wifi_error (*wifi_nan_resume_request)(transaction_id id, wifi_interface_handle iface,
+                                                   NanResumeRequest *msg);
+
+    wifi_error (*wifi_nan_pairing_request)(
+        transaction_id id, wifi_interface_handle iface,
+        NanPairingRequest *msg);
+    wifi_error (*wifi_nan_pairing_indication_response)(
+    transaction_id id, wifi_interface_handle iface,
+        NanPairingIndicationResponse *msg);
+    wifi_error (*wifi_nan_bootstrapping_request)(
+        transaction_id id, wifi_interface_handle iface,
+        NanBootstrappingRequest *msg);
+    wifi_error (*wifi_nan_bootstrapping_indication_response)(
+        transaction_id id, wifi_interface_handle iface,
+        NanBootstrappingIndicationResponse *msg);
+
+    /**@brief wifi_set_scan_mode
+     *        Notify driver/firmware current is scan only mode to allow lower
+     *        level to optimize power consumption.
+     * @param enable true if current is scan only mode
+     * @return Synchronous wifi_error
+     */
+    wifi_error (*wifi_set_scan_mode)(const char * ifname, bool enable);
+
+    wifi_error (*wifi_nan_pairing_end)(transaction_id id,
+                                    wifi_interface_handle iface,
+                                    NanPairingEndRequest *msg);
+
+    /**@brief wifi_set_mlo_mode
+     * Set Multi-Link Operation mode.
+     * @param handle global wifi_handle
+     * @param mode: MLO mode
+     * @return Synchronous wifi_error
+     */
+    wifi_error (*wifi_set_mlo_mode)(wifi_handle handle, wifi_mlo_mode mode);
+
+    /**@brief wifi_virtual_interface_create_with_vendor_data
+     * Create new virtual interface using vendor data.
+     * @param handle: global wifi_handle
+     * @param ifname: name of interface to be created.
+     * @param iface_type: one of interface types from wifi_interface_type.
+     * @param vendor_data: vendor data to apply on this interface.
+     * @return Synchronous wifi_error
+     */
+    wifi_error (*wifi_virtual_interface_create_with_vendor_data)
+            (wifi_handle handle, const char* ifname,
+             wifi_interface_type iface_type, wifi_vendor_data* vendor_data);
+
+    /*
+     * when adding new functions make sure to add stubs in
+     * wifi_legacy_hal_stubs.cpp::initHalFuncTableWithStubs
+     */
+} wifi_hal_fn;
+
+wifi_error init_wifi_vendor_hal_func_table(wifi_hal_fn *fn);
+typedef wifi_error (*init_wifi_vendor_hal_func_table_t)(wifi_hal_fn *fn);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/wifi/legacy_headers/include/hardware_legacy/wifi_logger.h b/wifi/legacy_headers/include/hardware_legacy/wifi_logger.h
new file mode 100644
index 0000000..0692859
--- /dev/null
+++ b/wifi/legacy_headers/include/hardware_legacy/wifi_logger.h
@@ -0,0 +1,646 @@
+#include "wifi_hal.h"
+
+#ifndef __WIFI_HAL_LOGGER_H
+#define __WIFI_HAL_LOGGER_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+#define LOGGER_MAJOR_VERSION    1
+#define LOGGER_MINOR_VERSION    0
+#define LOGGER_MICRO_VERSION    0
+
+
+
+/**
+ * WiFi logger life cycle is as follow:
+ *
+ * - At initialization time, framework will call wifi_get_ring_buffers_status
+ *   so as to obtain the names and list of supported buffers.
+ * - When WiFi operation start framework will call wifi_start_logging
+ *   so as to trigger log collection.
+ * - Developper UI will provide an option to the user, so as it can set the verbose level
+ *   of individual buffer as reported by wifi_get_ring_buffers_status.
+ * - During wifi operations, driver will periodically report per ring data to framework
+ *   by invoking the on_ring_buffer_data call back.
+ * - when capturing a bug report, framework will indicate to driver that all the data
+ *   has to be uploaded, urgently, by calling wifi_get_ring_data.
+ *
+ * The data uploaded by driver will be stored by framework in separate files, with one stream
+ *   of file per ring.
+ * Framework will store the files in pcapng format, allowing for easy merging and parsing
+ *   with network analyzer tools.
+ */
+
+
+typedef int wifi_ring_buffer_id;
+
+#define PER_PACKET_ENTRY_FLAGS_DIRECTION_TX  1    // 0: TX, 1: RX
+#define PER_PACKET_ENTRY_FLAGS_TX_SUCCESS    2    // whether packet was transmitted or
+                                                  // received/decrypted successfully
+#define PER_PACKET_ENTRY_FLAGS_80211_HEADER  4    // has full 802.11 header, else has 802.3 header
+#define PER_PACKET_ENTRY_FLAGS_PROTECTED     8    // whether packet was encrypted
+
+typedef struct {
+    u8 flags;
+    u8 tid;     // transmit or received tid
+    u16 MCS;    // modulation and bandwidth
+    u8 rssi;    // TX: RSSI of ACK for that packet
+                // RX: RSSI of packet
+    u8 num_retries;                   // number of attempted retries
+    u16 last_transmit_rate;           // last transmit rate in .5 mbps
+    u16 link_layer_transmit_sequence; // transmit/reeive sequence for that MPDU packet
+    u64 firmware_entry_timestamp;     // TX: firmware timestamp (us) when packet is queued within
+                                      // firmware buffer for SDIO/HSIC or into PCIe buffer
+                                      // RX: firmware receive timestamp
+    u64 start_contention_timestamp; // firmware timestamp (us) when packet start contending for the
+                                    // medium for the first time, at head of its AC queue,
+                                    // or as part of an MPDU or A-MPDU. This timestamp is
+                                    // not updated for each retry, only the first transmit attempt.
+    u64 transmit_success_timestamp; // fimrware timestamp (us) when packet is successfully
+                                    // transmitted or aborted because it has exhausted
+                                    // its maximum number of retries.
+    u8 data[0]; // packet data. The length of packet data is determined by the entry_size field of
+                // the wifi_ring_buffer_entry structure. It is expected that first bytes of the
+                // packet, or packet headers only (up to TCP or RTP/UDP headers)
+                // will be copied into the ring
+} __attribute__((packed)) wifi_ring_per_packet_status_entry;
+
+
+/* Below events refer to the wifi_connectivity_event ring and shall be supported */
+#define WIFI_EVENT_ASSOCIATION_REQUESTED    0  // driver receives association command from kernel
+#define WIFI_EVENT_AUTH_COMPLETE            1
+#define WIFI_EVENT_ASSOC_COMPLETE           2
+#define WIFI_EVENT_FW_AUTH_STARTED          3  // fw event indicating auth frames are sent
+#define WIFI_EVENT_FW_ASSOC_STARTED         4  // fw event indicating assoc frames are sent
+#define WIFI_EVENT_FW_RE_ASSOC_STARTED      5  // fw event indicating reassoc frames are sent
+#define WIFI_EVENT_DRIVER_SCAN_REQUESTED    6
+#define WIFI_EVENT_DRIVER_SCAN_RESULT_FOUND 7
+#define WIFI_EVENT_DRIVER_SCAN_COMPLETE     8
+#define WIFI_EVENT_G_SCAN_STARTED           9
+#define WIFI_EVENT_G_SCAN_COMPLETE          10
+#define WIFI_EVENT_DISASSOCIATION_REQUESTED 11
+#define WIFI_EVENT_RE_ASSOCIATION_REQUESTED 12
+#define WIFI_EVENT_ROAM_REQUESTED           13
+#define WIFI_EVENT_BEACON_RECEIVED          14  // received beacon from AP (event enabled
+                                                // only in verbose mode)
+#define WIFI_EVENT_ROAM_SCAN_STARTED        15  // firmware has triggered a roam scan (not g-scan)
+#define WIFI_EVENT_ROAM_SCAN_COMPLETE       16  // firmware has completed a roam scan (not g-scan)
+#define WIFI_EVENT_ROAM_SEARCH_STARTED      17  // firmware has started searching for roam
+                                                // candidates (with reason =xx)
+#define WIFI_EVENT_ROAM_SEARCH_STOPPED      18  // firmware has stopped searching for roam
+                                                // candidates (with reason =xx)
+#define WIFI_EVENT_CHANNEL_SWITCH_ANOUNCEMENT     20 // received channel switch anouncement from AP
+#define WIFI_EVENT_FW_EAPOL_FRAME_TRANSMIT_START  21 // fw start transmit eapol frame, with
+                                                     // EAPOL index 1-4
+#define WIFI_EVENT_FW_EAPOL_FRAME_TRANSMIT_STOP   22 // fw gives up eapol frame, with rate,
+                                                     // success/failure and number retries
+#define WIFI_EVENT_DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED 23 // kernel queue EAPOL for transmission
+                                                            // in driver with EAPOL index 1-4
+#define WIFI_EVENT_FW_EAPOL_FRAME_RECEIVED        24 // with rate, regardless of the fact that
+                                                     // EAPOL frame is accepted or rejected by fw
+#define WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED    26 // with rate, and eapol index, driver has
+                                                     // received EAPOL frame and will queue it up
+                                                     // to wpa_supplicant
+#define WIFI_EVENT_BLOCK_ACK_NEGOTIATION_COMPLETE 27 // with success/failure, parameters
+#define WIFI_EVENT_BT_COEX_BT_SCO_START     28
+#define WIFI_EVENT_BT_COEX_BT_SCO_STOP      29
+#define WIFI_EVENT_BT_COEX_BT_SCAN_START    30  // for paging/scan etc., when BT starts transmiting
+                                                // twice per BT slot
+#define WIFI_EVENT_BT_COEX_BT_SCAN_STOP     31
+#define WIFI_EVENT_BT_COEX_BT_HID_START     32
+#define WIFI_EVENT_BT_COEX_BT_HID_STOP      33
+#define WIFI_EVENT_ROAM_AUTH_STARTED        34  // fw sends auth frame in roaming to next candidate
+#define WIFI_EVENT_ROAM_AUTH_COMPLETE       35  // fw receive auth confirm from ap
+#define WIFI_EVENT_ROAM_ASSOC_STARTED       36  // firmware sends assoc/reassoc frame in
+                                                // roaming to next candidate
+#define WIFI_EVENT_ROAM_ASSOC_COMPLETE      37  // firmware receive assoc/reassoc confirm from ap
+#define WIFI_EVENT_G_SCAN_STOP              38  // firmware sends stop G_SCAN
+#define WIFI_EVENT_G_SCAN_CYCLE_STARTED     39  // firmware indicates G_SCAN scan cycle started
+#define WIFI_EVENT_G_SCAN_CYCLE_COMPLETED   40  // firmware indicates G_SCAN scan cycle completed
+#define WIFI_EVENT_G_SCAN_BUCKET_STARTED    41  // firmware indicates G_SCAN scan start
+                                                // for a particular bucket
+#define WIFI_EVENT_G_SCAN_BUCKET_COMPLETED  42  // firmware indicates G_SCAN scan completed for
+                                                // for a particular bucket
+#define WIFI_EVENT_G_SCAN_RESULTS_AVAILABLE 43  // Event received from firmware about G_SCAN scan
+                                                // results being available
+#define WIFI_EVENT_G_SCAN_CAPABILITIES      44  // Event received from firmware with G_SCAN
+                                                // capabilities
+#define WIFI_EVENT_ROAM_CANDIDATE_FOUND     45  // Event received from firmware when eligible
+                                                // candidate is found
+#define WIFI_EVENT_ROAM_SCAN_CONFIG         46  // Event received from firmware when roam scan
+                                                // configuration gets enabled or disabled
+#define WIFI_EVENT_AUTH_TIMEOUT             47  // firmware/driver timed out authentication
+#define WIFI_EVENT_ASSOC_TIMEOUT            48  // firmware/driver timed out association
+#define WIFI_EVENT_MEM_ALLOC_FAILURE        49  // firmware/driver encountered allocation failure
+#define WIFI_EVENT_DRIVER_PNO_ADD           50  // driver added a PNO network in firmware
+#define WIFI_EVENT_DRIVER_PNO_REMOVE        51  // driver removed a PNO network in firmware
+#define WIFI_EVENT_DRIVER_PNO_NETWORK_FOUND 52  // driver received PNO networks
+                                                // found indication from firmware
+#define WIFI_EVENT_DRIVER_PNO_SCAN_REQUESTED 53  // driver triggered a scan for PNO networks
+#define WIFI_EVENT_DRIVER_PNO_SCAN_RESULT_FOUND 54  // driver received scan results
+                                                    // of PNO networks
+#define WIFI_EVENT_DRIVER_PNO_SCAN_COMPLETE 55  // driver updated scan results from
+                                                // PNO networks to cfg80211
+
+/**
+ * Parameters of wifi logger events are TLVs
+ * Event parameters tags are defined as:
+ */
+#define WIFI_TAG_VENDOR_SPECIFIC    0   // take a byte stream as parameter
+#define WIFI_TAG_BSSID              1   // takes a 6 bytes MAC address as parameter
+#define WIFI_TAG_ADDR               2   // takes a 6 bytes MAC address as parameter
+#define WIFI_TAG_SSID               3   // takes a 32 bytes SSID address as parameter
+#define WIFI_TAG_STATUS             4   // takes an integer as parameter
+#define WIFI_TAG_CHANNEL_SPEC       5   // takes one or more wifi_channel_spec as parameter
+#define WIFI_TAG_WAKE_LOCK_EVENT    6   // takes a wake_lock_event struct as parameter
+#define WIFI_TAG_ADDR1              7   // takes a 6 bytes MAC address as parameter
+#define WIFI_TAG_ADDR2              8   // takes a 6 bytes MAC address as parameter
+#define WIFI_TAG_ADDR3              9   // takes a 6 bytes MAC address as parameter
+#define WIFI_TAG_ADDR4              10  // takes a 6 bytes MAC address as parameter
+#define WIFI_TAG_TSF                11  // take a 64 bits TSF value as parameter
+#define WIFI_TAG_IE                 12  // take one or more specific 802.11 IEs parameter,
+                                        // IEs are in turn indicated in TLV format as per
+                                        // 802.11 spec
+#define WIFI_TAG_INTERFACE          13  // take interface name as parameter
+#define WIFI_TAG_REASON_CODE        14  // take a reason code as per 802.11 as parameter
+#define WIFI_TAG_RATE_MBPS          15  // take a wifi rate in 0.5 mbps
+#define WIFI_TAG_REQUEST_ID         16  // take an integer as parameter
+#define WIFI_TAG_BUCKET_ID          17  // take an integer as parameter
+#define WIFI_TAG_GSCAN_PARAMS       18  // takes a wifi_scan_cmd_params struct as parameter
+#define WIFI_TAG_GSCAN_CAPABILITIES 19  // takes a wifi_gscan_capabilities struct as parameter
+#define WIFI_TAG_SCAN_ID            20  // take an integer as parameter
+#define WIFI_TAG_RSSI               21  // take an integer as parameter
+#define WIFI_TAG_CHANNEL            22  // take an integer as parameter
+#define WIFI_TAG_LINK_ID            23  // take an integer as parameter
+#define WIFI_TAG_LINK_ROLE          24  // take an integer as parameter
+#define WIFI_TAG_LINK_STATE         25  // take an integer as parameter
+#define WIFI_TAG_LINK_TYPE          26  // take an integer as parameter
+#define WIFI_TAG_TSCO               27  // take an integer as parameter
+#define WIFI_TAG_RSCO               28  // take an integer as parameter
+#define WIFI_TAG_EAPOL_MESSAGE_TYPE 29  // take an integer as parameter
+                                        // M1-1, M2-2, M3-3, M4-4
+
+typedef struct {
+    u16 tag;
+    u16 length; // length of value
+    u8 value[0];
+} __attribute__((packed)) tlv_log;
+
+typedef struct {
+    u16 event;
+    tlv_log tlvs[0];   // separate parameter structure per event to be provided and optional data
+                       // the event_data is expected to include an official android part, with some
+                       // parameter as transmit rate, num retries, num scan result found etc...
+                       // as well, event_data can include a vendor proprietary part which is
+                       // understood by the developer only.
+} __attribute__((packed)) wifi_ring_buffer_driver_connectivity_event;
+
+
+/**
+ * Ring buffer name for power events ring. note that power event are extremely frequents
+ * and thus should be stored in their own ring/file so as not to clobber connectivity events.
+ */
+typedef struct {
+    int status;      // 0 taken, 1 released
+    int reason;      // reason why this wake lock is taken
+    char name[0];    // null terminated
+} __attribute__((packed)) wake_lock_event;
+
+typedef struct {
+    u16 event;
+    tlv_log tlvs[0];
+} __attribute__((packed)) wifi_power_event;
+
+
+/**
+ * This structure represent a logger entry within a ring buffer.
+ * Wifi driver are responsible to manage the ring buffer and write the debug
+ * information into those rings.
+ *
+ * In general, the debug entries can be used to store meaningful 802.11 information (SME, MLME,
+ * connection and packet statistics) as well as vendor proprietary data that is specific to a
+ * specific driver or chipset.
+ * Binary entries can be used so as to store packet data or vendor specific information and
+ * will be treated as blobs of data by android.
+ *
+ * A user land process will be started by framework so as to periodically retrieve the
+ * data logged by drivers into their ring buffer, store the data into log files and include
+ * the logs into android bugreports.
+ */
+enum {
+    RING_BUFFER_ENTRY_FLAGS_HAS_BINARY = (1 << (0)),    // set for binary entries
+    RING_BUFFER_ENTRY_FLAGS_HAS_TIMESTAMP = (1 << (1))  // set if 64 bits timestamp is present
+};
+
+enum {
+    ENTRY_TYPE_CONNECT_EVENT = 1,
+    ENTRY_TYPE_PKT,
+    ENTRY_TYPE_WAKE_LOCK,
+    ENTRY_TYPE_POWER_EVENT,
+    ENTRY_TYPE_DATA
+};
+
+typedef struct {
+    u16 entry_size; // the size of payload excluding the header.
+    u8 flags;
+    u8 type;        // entry type
+    u64 timestamp;  // present if has_timestamp bit is set.
+} __attribute__((packed)) wifi_ring_buffer_entry;
+
+#define WIFI_RING_BUFFER_FLAG_HAS_BINARY_ENTRIES 0x00000001   // set if binary entries are present
+#define WIFI_RING_BUFFER_FLAG_HAS_ASCII_ENTRIES  0x00000002   // set if ascii entries are present
+
+
+/* ring buffer params */
+/**
+ * written_bytes and read_bytes implement a producer consumer API
+ *     hence written_bytes >= read_bytes
+ * a modulo arithmetic of the buffer size has to be applied to those counters:
+ * actual offset into ring buffer = written_bytes % ring_buffer_byte_size
+ *
+ */
+typedef struct {
+    u8 name[32];
+    u32 flags;
+    wifi_ring_buffer_id ring_id; // unique integer representing the ring
+    u32 ring_buffer_byte_size;   // total memory size allocated for the buffer
+    u32 verbose_level;           // verbose level for ring buffer
+    u32 written_bytes;           // number of bytes that was written to the buffer by driver,
+                                 // monotonously increasing integer
+    u32 read_bytes;              // number of bytes that was read from the buffer by user land,
+                                 // monotonously increasing integer
+    u32 written_records;         // number of records that was written to the buffer by driver,
+                                 // monotonously increasing integer
+} wifi_ring_buffer_status;
+
+
+/**
+ * Callback for reporting ring data
+ *
+ * The ring buffer data collection is event based:
+ *   - Driver calls on_ring_buffer_data when new records are available, the wifi_ring_buffer_status
+ *     passed up to framework in the call back indicates to framework if more data is available in
+ *     the ring buffer. It is not expected that driver will necessarily always empty the ring
+ *     immediately as data is available, instead driver will report data every X seconds or if
+ *     N bytes are available.
+ *   - In the case where a bug report has to be captured, framework will require driver to upload
+ *     all data immediately. This is indicated to driver when framework calls wifi_get_ringdata.
+ *     When framework calls wifi_get_ring_data, driver will start sending all available data in the
+ *     indicated ring by repeatedly invoking the on_ring_buffer_data callback.
+ *
+ * The callback is called by log handler whenever ring data comes in driver.
+ */
+typedef struct {
+  void (*on_ring_buffer_data) (char *ring_name, char *buffer, int buffer_size,
+        wifi_ring_buffer_status *status);
+} wifi_ring_buffer_data_handler;
+
+/**
+ * API to set the log handler for getting ring data
+ *  - Only a single instance of log handler can be instantiated for each ring buffer.
+ */
+wifi_error wifi_set_log_handler(wifi_request_id id, wifi_interface_handle iface,
+    wifi_ring_buffer_data_handler handler);
+
+/* API to reset the log handler */
+wifi_error wifi_reset_log_handler(wifi_request_id id, wifi_interface_handle iface);
+
+
+/**
+ * Callback for reporting FW dump
+ *
+ * The buffer data collection is event based such as FW health check or FW dump.
+ * The callback is called by alert handler.
+ */
+typedef struct {
+   void (*on_alert) (wifi_request_id id, char *buffer, int buffer_size, int err_code);
+} wifi_alert_handler;
+
+/*
+ * API to set the alert handler for the alert case in Wi-Fi Chip
+ *  - Only a single instance of alert handler can be instantiated.
+ */
+wifi_error wifi_set_alert_handler(wifi_request_id id, wifi_interface_handle iface,
+    wifi_alert_handler handler);
+
+/* API to reset the alert handler */
+wifi_error wifi_reset_alert_handler(wifi_request_id id, wifi_interface_handle iface);
+
+/* API for framework to indicate driver has to upload and drain all data of a given ring */
+wifi_error wifi_get_ring_data(wifi_interface_handle iface, char *ring_name);
+
+
+/**
+ * API to trigger the debug collection.
+ *  Unless his API is invoked - logging is not triggered.
+ *  - Verbose_level 0 corresponds to no collection,
+ *    and it makes log handler stop by no more events from driver.
+ *  - Verbose_level 1 correspond to normal log level, with minimal user impact.
+ *    This is the default value.
+ *  - Verbose_level 2 are enabled when user is lazily trying to reproduce a problem,
+ *    wifi performances and power can be impacted but device should not otherwise be
+ *    significantly impacted.
+ *  - Verbose_level 3+ are used when trying to actively debug a problem.
+ *
+ * ring_name represent the name of the ring for which data collection shall start.
+ *
+ * flags: TBD parameter used to enable/disable specific events on a ring
+ * max_interval: maximum interval in seconds for driver to invoke on_ring_buffer_data,
+ *               ignore if zero
+ * min_data_size: minimum data size in buffer for driver to invoke on_ring_buffer_data,
+ *                ignore if zero
+ */
+wifi_error wifi_start_logging(wifi_interface_handle iface, u32 verbose_level, u32 flags,
+    u32 max_interval_sec, u32 min_data_size, char *ring_name);
+
+/**
+ * API to get the status of all ring buffers supported by driver.
+ *  - Caller is responsible to allocate / free ring buffer status.
+ *  - Maximum no of ring buffer would be 10.
+ */
+wifi_error wifi_get_ring_buffers_status(wifi_interface_handle iface, u32 *num_rings,
+    wifi_ring_buffer_status *status);
+
+/**
+ * Synchronous memory dump by user request.
+ *  - Caller is responsible to store memory dump data into a local,
+ *      e.g., /data/misc/wifi/memdump.bin
+ */
+typedef struct {
+    void (*on_firmware_memory_dump) (char *buffer, int buffer_size);
+} wifi_firmware_memory_dump_handler;
+
+/**
+ * API to collect a firmware memory dump for a given iface by async memdump event.
+ *  - Triggered by Alerthandler, esp. when FW problem or FW health check happens
+ *  - Caller is responsible to store fw dump data into a local,
+ *      e.g., /data/misc/wifi/alertdump-1.bin
+ */
+wifi_error wifi_get_firmware_memory_dump(wifi_interface_handle iface,
+    wifi_firmware_memory_dump_handler handler);
+
+/**
+ * API to collect a firmware version string.
+ *  - Caller is responsible to allocate / free a buffer to retrieve firmware verion info.
+ *  - Max string will be at most 256 bytes.
+ */
+wifi_error wifi_get_firmware_version(wifi_interface_handle iface, char *buffer, int buffer_size);
+
+/**
+ * API to collect a driver version string.
+ *  - Caller is responsible to allocate / free a buffer to retrieve driver verion info.
+ *  - Max string will be at most 256 bytes.
+ */
+wifi_error wifi_get_driver_version(wifi_interface_handle iface, char *buffer, int buffer_size);
+
+
+/* Feature set */
+enum {
+    WIFI_LOGGER_MEMORY_DUMP_SUPPORTED = (1 << (0)),             // Memory dump of FW
+    WIFI_LOGGER_PER_PACKET_TX_RX_STATUS_SUPPORTED = (1 << (1)), // PKT status
+    WIFI_LOGGER_CONNECT_EVENT_SUPPORTED = (1 << (2)),           // Connectivity event
+    WIFI_LOGGER_POWER_EVENT_SUPPORTED = (1 << (3)),             // POWER of Driver
+    WIFI_LOGGER_WAKE_LOCK_SUPPORTED = (1 << (4)),               // WAKE LOCK of Driver
+    WIFI_LOGGER_VERBOSE_SUPPORTED = (1 << (5)),                 // verbose log of FW
+    WIFI_LOGGER_WATCHDOG_TIMER_SUPPORTED = (1 << (6)),          // monitor the health of FW
+    WIFI_LOGGER_DRIVER_DUMP_SUPPORTED = (1 << (7)),             // dumps driver state
+    WIFI_LOGGER_PACKET_FATE_SUPPORTED = (1 << (8)),             // tracks connection packets' fate
+};
+
+/**
+ * API to retrieve the current supportive features.
+ *  - An integer variable is enough to have bit mapping info by caller.
+ */
+wifi_error wifi_get_logger_supported_feature_set(wifi_interface_handle iface,
+    unsigned int *support);
+
+typedef struct {
+    /* Buffer is to be allocated and freed by HAL implementation. */
+    void (*on_driver_memory_dump) (char *buffer, int buffer_size);
+} wifi_driver_memory_dump_callbacks;
+
+/**
+    API to collect driver state.
+
+    Framework will call this API soon before or after (but not
+    concurrently with) wifi_get_firmware_memory_dump(). Capturing
+    firmware and driver dumps is intended to help identify
+    inconsistent state between these components.
+
+    - In response to this call, HAL implementation should make one or
+      more calls to callbacks.on_driver_memory_dump(). Framework will
+      copy data out of the received |buffer|s, and concatenate the
+      contents thereof.
+    - HAL implemention will indicate completion of the driver memory
+      dump by returning from this call.
+*/
+wifi_error wifi_get_driver_memory_dump(
+    wifi_interface_handle iface,
+    wifi_driver_memory_dump_callbacks callbacks);
+
+
+/* packet fate logs */
+
+#define MD5_PREFIX_LEN             4
+#define MAX_FATE_LOG_LEN           32
+#define MAX_FRAME_LEN_ETHERNET     1518
+#define MAX_FRAME_LEN_80211_MGMT   2352  // 802.11-2012 Fig. 8-34
+
+typedef enum {
+    // Sent over air and ACKed.
+    TX_PKT_FATE_ACKED,
+
+    // Sent over air but not ACKed. (Normal for broadcast/multicast.)
+    TX_PKT_FATE_SENT,
+
+    // Queued within firmware, but not yet sent over air.
+    TX_PKT_FATE_FW_QUEUED,
+
+    // Dropped by firmware as invalid. E.g. bad source address, bad checksum,
+    // or invalid for current state.
+    TX_PKT_FATE_FW_DROP_INVALID,
+
+    // Dropped by firmware due to lack of buffer space.
+    TX_PKT_FATE_FW_DROP_NOBUFS,
+
+    // Dropped by firmware for any other reason. Includes frames that
+    // were sent by driver to firmware, but unaccounted for by
+    // firmware.
+    TX_PKT_FATE_FW_DROP_OTHER,
+
+    // Queued within driver, not yet sent to firmware.
+    TX_PKT_FATE_DRV_QUEUED,
+
+    // Dropped by driver as invalid. E.g. bad source address, or
+    // invalid for current state.
+    TX_PKT_FATE_DRV_DROP_INVALID,
+
+    // Dropped by driver due to lack of buffer space.
+    TX_PKT_FATE_DRV_DROP_NOBUFS,
+
+    // Dropped by driver for any other reason.
+    TX_PKT_FATE_DRV_DROP_OTHER,
+} wifi_tx_packet_fate;
+
+typedef enum {
+    // Valid and delivered to network stack (e.g., netif_rx()).
+    RX_PKT_FATE_SUCCESS,
+
+    // Queued within firmware, but not yet sent to driver.
+    RX_PKT_FATE_FW_QUEUED,
+
+    // Dropped by firmware due to host-programmable filters.
+    RX_PKT_FATE_FW_DROP_FILTER,
+
+    // Dropped by firmware as invalid. E.g. bad checksum, decrypt failed,
+    // or invalid for current state.
+    RX_PKT_FATE_FW_DROP_INVALID,
+
+    // Dropped by firmware due to lack of buffer space.
+    RX_PKT_FATE_FW_DROP_NOBUFS,
+
+    // Dropped by firmware for any other reason.
+    RX_PKT_FATE_FW_DROP_OTHER,
+
+    // Queued within driver, not yet delivered to network stack.
+    RX_PKT_FATE_DRV_QUEUED,
+
+    // Dropped by driver due to filter rules.
+    RX_PKT_FATE_DRV_DROP_FILTER,
+
+    // Dropped by driver as invalid. E.g. not permitted in current state.
+    RX_PKT_FATE_DRV_DROP_INVALID,
+
+    // Dropped by driver due to lack of buffer space.
+    RX_PKT_FATE_DRV_DROP_NOBUFS,
+
+    // Dropped by driver for any other reason.
+    RX_PKT_FATE_DRV_DROP_OTHER,
+} wifi_rx_packet_fate;
+
+typedef enum {
+    FRAME_TYPE_UNKNOWN,
+    FRAME_TYPE_ETHERNET_II,
+    FRAME_TYPE_80211_MGMT,
+} frame_type;
+
+typedef struct {
+    // The type of MAC-layer frame that this frame_info holds.
+    // - For data frames, use FRAME_TYPE_ETHERNET_II.
+    // - For management frames, use FRAME_TYPE_80211_MGMT.
+    // - If the type of the frame is unknown, use FRAME_TYPE_UNKNOWN.
+    frame_type payload_type;
+
+    // The number of bytes included in |frame_content|. If the frame
+    // contents are missing (e.g. RX frame dropped in firmware),
+    // |frame_len| should be set to 0.
+    size_t frame_len;
+
+    // Host clock when this frame was received by the driver (either
+    // outbound from the host network stack, or inbound from the
+    // firmware).
+    // - The timestamp should be taken from a clock which includes time
+    //   the host spent suspended (e.g. ktime_get_boottime()).
+    // - If no host timestamp is available (e.g. RX frame was dropped in
+    //   firmware), this field should be set to 0.
+    u32 driver_timestamp_usec;
+
+    // Firmware clock when this frame was received by the firmware
+    // (either outbound from the host, or inbound from a remote
+    // station).
+    // - The timestamp should be taken from a clock which includes time
+    //   firmware spent suspended (if applicable).
+    // - If no firmware timestamp is available (e.g. TX frame was
+    //   dropped by driver), this field should be set to 0.
+    // - Consumers of |frame_info| should _not_ assume any
+    //   synchronization between driver and firmware clocks.
+    u32 firmware_timestamp_usec;
+
+    // Actual frame content.
+    // - Should be provided for TX frames originated by the host.
+    // - Should be provided for RX frames received by the driver.
+    // - Optionally provided for TX frames originated by firmware. (At
+    //   discretion of HAL implementation.)
+    // - Optionally provided for RX frames dropped in firmware. (At
+    //   discretion of HAL implementation.)
+    // - If frame content is not provided, |frame_len| should be set
+    //   to 0.
+    union {
+      char ethernet_ii_bytes[MAX_FRAME_LEN_ETHERNET];
+      char ieee_80211_mgmt_bytes[MAX_FRAME_LEN_80211_MGMT];
+    } frame_content;
+} frame_info;
+
+typedef struct {
+    // Prefix of MD5 hash of |frame_inf.frame_content|. If frame
+    // content is not provided, prefix of MD5 hash over the same data
+    // that would be in frame_content, if frame content were provided.
+    char md5_prefix[MD5_PREFIX_LEN];
+    wifi_tx_packet_fate fate;
+    frame_info frame_inf;
+} wifi_tx_report;
+
+typedef struct {
+    // Prefix of MD5 hash of |frame_inf.frame_content|. If frame
+    // content is not provided, prefix of MD5 hash over the same data
+    // that would be in frame_content, if frame content were provided.
+    char md5_prefix[MD5_PREFIX_LEN];
+    wifi_rx_packet_fate fate;
+    frame_info frame_inf;
+} wifi_rx_report;
+
+/**
+    API to start packet fate monitoring.
+    - Once stared, monitoring should remain active until HAL is unloaded.
+    - When HAL is unloaded, all packet fate buffers should be cleared.
+*/
+wifi_error wifi_start_pkt_fate_monitoring(wifi_interface_handle handle);
+
+/**
+    API to retrieve fates of outbound packets.
+    - HAL implementation should fill |tx_report_bufs| with fates of
+      _first_ min(n_requested_fates, actual packets) frames
+      transmitted for the most recent association. The fate reports
+      should follow the same order as their respective packets.
+    - HAL implementation may choose (but is not required) to include
+      reports for management frames.
+    - Packets reported by firmware, but not recognized by driver,
+      should be included.  However, the ordering of the corresponding
+      reports is at the discretion of HAL implementation.
+    - Framework may call this API multiple times for the same association.
+    - Framework will ensure |n_requested_fates <= MAX_FATE_LOG_LEN|.
+    - Framework will allocate and free the referenced storage.
+*/
+wifi_error wifi_get_tx_pkt_fates(wifi_interface_handle handle,
+        wifi_tx_report *tx_report_bufs,
+        size_t n_requested_fates,
+        size_t *n_provided_fates);
+
+/**
+    API to retrieve fates of inbound packets.
+    - HAL implementation should fill |rx_report_bufs| with fates of
+      _first_ min(n_requested_fates, actual packets) frames
+      received for the most recent association. The fate reports
+      should follow the same order as their respective packets.
+    - HAL implementation may choose (but is not required) to include
+      reports for management frames.
+    - Packets reported by firmware, but not recognized by driver,
+      should be included.  However, the ordering of the corresponding
+      reports is at the discretion of HAL implementation.
+    - Framework may call this API multiple times for the same association.
+    - Framework will ensure |n_requested_fates <= MAX_FATE_LOG_LEN|.
+    - Framework will allocate and free the referenced storage.
+*/
+wifi_error wifi_get_rx_pkt_fates(wifi_interface_handle handle,
+        wifi_rx_report *rx_report_bufs,
+        size_t n_requested_fates,
+        size_t *n_provided_fates);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /*__WIFI_HAL_STATS_ */
diff --git a/wifi/legacy_headers/include/hardware_legacy/wifi_nan.h b/wifi/legacy_headers/include/hardware_legacy/wifi_nan.h
new file mode 100644
index 0000000..55034d1
--- /dev/null
+++ b/wifi/legacy_headers/include/hardware_legacy/wifi_nan.h
@@ -0,0 +1,3500 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#ifndef __NAN_H__
+#define __NAN_H__
+
+#include <net/if.h>
+#include <stdbool.h>
+#include "wifi_hal.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+/*****************************************************************************
+ * Neighbour Aware Network Service Structures and Functions
+ *****************************************************************************/
+
+/*
+  Definitions
+  All multi-byte fields within all NAN protocol stack messages are assumed to be in Little Endian order.
+*/
+
+typedef int NanVersion;
+typedef u16 transaction_id;
+typedef u32 NanDataPathId;
+
+#define NAN_MAC_ADDR_LEN                6
+#define NAN_MAJOR_VERSION               4
+#define NAN_MINOR_VERSION               0
+#define NAN_MICRO_VERSION               0
+#define NAN_MAX_SOCIAL_CHANNELS         3
+
+/* NAN Maximum Lengths */
+#define NAN_MAX_SERVICE_NAME_LEN                255
+#define NAN_MAX_MATCH_FILTER_LEN                255
+#define NAN_MAX_SERVICE_SPECIFIC_INFO_LEN       1024
+#define NAN_MAX_VSA_DATA_LEN                    1024
+#define NAN_MAX_MESH_DATA_LEN                   32
+#define NAN_MAX_INFRA_DATA_LEN                  32
+#define NAN_MAX_CLUSTER_ATTRIBUTE_LEN           255
+#define NAN_MAX_SUBSCRIBE_MAX_ADDRESS           42
+#define NAN_MAX_FAM_CHANNELS                    32
+#define NAN_MAX_POSTDISCOVERY_LEN               5
+#define NAN_MAX_FRAME_DATA_LEN                  504
+#define NAN_DP_MAX_APP_INFO_LEN                 512
+#define NAN_ERROR_STR_LEN                       255
+#define NAN_PMK_INFO_LEN                        32
+#define NAN_MAX_SCID_BUF_LEN                    1024
+#define NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN  2048
+#define NAN_SECURITY_MIN_PASSPHRASE_LEN         8
+#define NAN_SECURITY_MAX_PASSPHRASE_LEN         63
+#define NAN_MAX_CHANNEL_INFO_SUPPORTED          4
+#define NAN_IDENTITY_KEY_LEN                    16
+#define NAN_IDENTITY_TAG_LEN                    8
+#define NAN_IDENTITY_NONCE_LEN                  8
+#define NAN_MAX_MATCH_IDENTITY_LEN             1024
+/*
+  Definition of various NanResponseType
+*/
+typedef enum {
+    NAN_RESPONSE_ENABLED                 = 0,
+    NAN_RESPONSE_DISABLED                = 1,
+    NAN_RESPONSE_PUBLISH                 = 2,
+    NAN_RESPONSE_PUBLISH_CANCEL          = 3,
+    NAN_RESPONSE_TRANSMIT_FOLLOWUP       = 4,
+    NAN_RESPONSE_SUBSCRIBE               = 5,
+    NAN_RESPONSE_SUBSCRIBE_CANCEL        = 6,
+    NAN_RESPONSE_STATS                   = 7,
+    NAN_RESPONSE_CONFIG                  = 8,
+    NAN_RESPONSE_TCA                     = 9,
+    NAN_RESPONSE_ERROR                   = 10,
+    NAN_RESPONSE_BEACON_SDF_PAYLOAD      = 11,
+    NAN_GET_CAPABILITIES                 = 12,
+    NAN_DP_INTERFACE_CREATE              = 13,
+    NAN_DP_INTERFACE_DELETE              = 14,
+    NAN_DP_INITIATOR_RESPONSE            = 15,
+    NAN_DP_RESPONDER_RESPONSE            = 16,
+    NAN_DP_END                           = 17,
+    NAN_PAIRING_INITIATOR_RESPONSE       = 18,
+    NAN_PAIRING_RESPONDER_RESPONSE       = 19,
+    NAN_BOOTSTRAPPING_INITIATOR_RESPONSE = 20,
+    NAN_BOOTSTRAPPING_RESPONDER_RESPONSE = 21,
+    NAN_PAIRING_END                      = 22,
+    NAN_SUSPEND_REQUEST_RESPONSE         = 23,
+    NAN_RESUME_REQUEST_RESPONSE          = 24
+} NanResponseType;
+
+/* NAN Publish Types */
+typedef enum {
+    NAN_PUBLISH_TYPE_UNSOLICITED = 0,
+    NAN_PUBLISH_TYPE_SOLICITED,
+    NAN_PUBLISH_TYPE_UNSOLICITED_SOLICITED
+} NanPublishType;
+
+/* NAN Transmit Priorities */
+typedef enum {
+    NAN_TX_PRIORITY_NORMAL = 0,
+    NAN_TX_PRIORITY_HIGH
+} NanTxPriority;
+
+/* NAN Statistics Request ID Codes */
+typedef enum {
+    NAN_STATS_ID_DE_PUBLISH = 0,
+    NAN_STATS_ID_DE_SUBSCRIBE,
+    NAN_STATS_ID_DE_MAC,
+    NAN_STATS_ID_DE_TIMING_SYNC,
+    NAN_STATS_ID_DE_DW,
+    NAN_STATS_ID_DE
+} NanStatsType;
+
+/* NAN Protocol Event ID Codes */
+typedef enum {
+    NAN_EVENT_ID_DISC_MAC_ADDR = 0,
+    NAN_EVENT_ID_STARTED_CLUSTER,
+    NAN_EVENT_ID_JOINED_CLUSTER
+} NanDiscEngEventType;
+
+/* NAN Data Path type */
+typedef enum {
+    NAN_DATA_PATH_UNICAST_MSG = 0,
+    NAN_DATA_PATH_MULTICAST_MSG
+} NdpType;
+
+/* NAN Ranging Configuration */
+typedef enum {
+    NAN_RANGING_DISABLE = 0,
+    NAN_RANGING_ENABLE
+} NanRangingState;
+
+/* TCA Type */
+typedef enum {
+    NAN_TCA_ID_CLUSTER_SIZE = 0
+} NanTcaType;
+
+/* pairing request type*/
+typedef enum {
+    NAN_PAIRING_SETUP = 0,
+    NAN_PAIRING_VERIFICATION = 1
+} NanPairingRequestType;
+
+/* Nan AKM type */
+typedef enum {
+    SAE = 0,
+    PASN = 1
+} NanAkm;
+
+/* NAN Channel Info */
+typedef struct {
+    u32 channel;
+    u32 bandwidth;
+    u32 nss;
+} NanChannelInfo;
+
+/*
+  Various NAN Protocol Response code
+*/
+typedef enum {
+    /* NAN Protocol Response Codes */
+    NAN_STATUS_SUCCESS = 0,
+    /*  NAN Discovery Engine/Host driver failures */
+    NAN_STATUS_INTERNAL_FAILURE = 1,
+    /*  NAN OTA failures */
+    NAN_STATUS_PROTOCOL_FAILURE = 2,
+    /* if the publish/subscribe id is invalid */
+    NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID = 3,
+    /* If we run out of resources allocated */
+    NAN_STATUS_NO_RESOURCE_AVAILABLE = 4,
+    /* if invalid params are passed */
+    NAN_STATUS_INVALID_PARAM = 5,
+    /*  if the requestor instance id is invalid */
+    NAN_STATUS_INVALID_REQUESTOR_INSTANCE_ID = 6,
+    /*  if the ndp id is invalid */
+    NAN_STATUS_INVALID_NDP_ID = 7,
+    /* if NAN is enabled when wifi is turned off */
+    NAN_STATUS_NAN_NOT_ALLOWED = 8,
+    /* if over the air ack is not received */
+    NAN_STATUS_NO_OTA_ACK = 9,
+    /* If NAN is already enabled and we are try to re-enable the same */
+    NAN_STATUS_ALREADY_ENABLED = 10,
+    /* If followup message internal queue is full */
+    NAN_STATUS_FOLLOWUP_QUEUE_FULL = 11,
+    /* Unsupported concurrency session enabled, NAN disabled notified */
+    NAN_STATUS_UNSUPPORTED_CONCURRENCY_NAN_DISABLED = 12,
+    /*  if the pairing id is invalid */
+    NAN_STATUS_INVALID_PAIRING_ID = 13,
+    /*  if the bootstrapping id is invalid */
+    NAN_STATUS_INVALID_BOOTSTRAPPING_ID = 14,
+    /* If same request is received again */
+    NAN_STATUS_REDUNDANT_REQUEST = 15,
+    /* If current request is not supported */
+    NAN_STATUS_NOT_SUPPORTED = 16,
+    /* If no Wifi Aware connection is active */
+    NAN_STATUS_NO_CONNECTION = 17,
+} NanStatusType;
+
+/* NAN Transmit Types */
+typedef enum {
+    NAN_TX_TYPE_BROADCAST = 0,
+    NAN_TX_TYPE_UNICAST
+} NanTxType;
+
+/* NAN Subscribe Type */
+typedef enum {
+    NAN_SUBSCRIBE_TYPE_PASSIVE = 0,
+    NAN_SUBSCRIBE_TYPE_ACTIVE
+} NanSubscribeType;
+
+/* NAN Service Response Filter Attribute Bit */
+typedef enum {
+    NAN_SRF_ATTR_BLOOM_FILTER = 0,
+    NAN_SRF_ATTR_PARTIAL_MAC_ADDR
+} NanSRFType;
+
+/* NAN Service Response Filter Include Bit */
+typedef enum {
+    NAN_SRF_INCLUDE_DO_NOT_RESPOND = 0,
+    NAN_SRF_INCLUDE_RESPOND
+} NanSRFIncludeType;
+
+/* NAN Match indication type */
+typedef enum {
+    NAN_MATCH_ALG_MATCH_ONCE = 0,
+    NAN_MATCH_ALG_MATCH_CONTINUOUS,
+    NAN_MATCH_ALG_MATCH_NEVER
+} NanMatchAlg;
+
+/* NAN Transmit Window Type */
+typedef enum {
+    NAN_TRANSMIT_IN_DW = 0,
+    NAN_TRANSMIT_IN_FAW
+} NanTransmitWindowType;
+
+/* NAN SRF State in Subscribe */
+typedef enum {
+    NAN_DO_NOT_USE_SRF = 0,
+    NAN_USE_SRF
+} NanSRFState;
+
+/* NAN Include SSI in MatchInd */
+typedef enum {
+    NAN_SSI_NOT_REQUIRED_IN_MATCH_IND = 0,
+    NAN_SSI_REQUIRED_IN_MATCH_IND
+} NanSsiInMatchInd;
+
+/* NAN DP security Configuration */
+typedef enum {
+    NAN_DP_CONFIG_NO_SECURITY = 0,
+    NAN_DP_CONFIG_SECURITY
+} NanDataPathSecurityCfgStatus;
+
+typedef enum {
+    NAN_QOS_NOT_REQUIRED = 0,
+    NAN_QOS_REQUIRED
+} NanQosCfgStatus;
+
+
+/* Data request Responder's response */
+typedef enum {
+    NAN_DP_REQUEST_ACCEPT = 0,
+    NAN_DP_REQUEST_REJECT
+} NanDataPathResponseCode;
+
+/* Pairing request Responder's response */
+typedef enum {
+    NAN_PAIRING_REQUEST_ACCEPT = 0,
+    NAN_PAIRING_REQUEST_REJECT
+} NanPairingResponseCode;
+
+/* Pairing bootstrapping Responder's response */
+typedef enum {
+    NAN_BOOTSTRAPPING_REQUEST_ACCEPT = 0,
+    NAN_BOOTSTRAPPING_REQUEST_REJECT = 1,
+    NAN_BOOTSTRAPPING_REQUEST_COMEBACK = 2
+} NanBootstrappingResponseCode;
+
+/* NAN DP channel config options */
+typedef enum {
+    NAN_DP_CHANNEL_NOT_REQUESTED = 0,
+    NAN_DP_REQUEST_CHANNEL_SETUP,
+    NAN_DP_FORCE_CHANNEL_SETUP
+} NanDataPathChannelCfg;
+
+/* Enable/Disable NAN Ranging Auto response */
+typedef enum {
+    NAN_RANGING_AUTO_RESPONSE_ENABLE = 1,
+    NAN_RANGING_AUTO_RESPONSE_DISABLE
+} NanRangingAutoResponse;
+
+/* Enable/Disable NAN service range report */
+typedef enum {
+    NAN_DISABLE_RANGE_REPORT = 1,
+    NAN_ENABLE_RANGE_REPORT
+} NanRangeReport;
+
+/* NAN Range Response */
+typedef enum {
+    NAN_RANGE_REQUEST_ACCEPT = 1,
+    NAN_RANGE_REQUEST_REJECT,
+    NAN_RANGE_REQUEST_CANCEL
+} NanRangeResponse;
+
+/* NAN Security Key Input Type*/
+typedef enum {
+    NAN_SECURITY_KEY_INPUT_PMK = 1,
+    NAN_SECURITY_KEY_INPUT_PASSPHRASE
+} NanSecurityKeyInputType;
+
+typedef struct {
+    /* pmk length */
+    u32 pmk_len;
+    /*
+       PMK: Info is optional in Discovery phase.
+       PMK info can be passed during
+       the NDP session.
+     */
+    u8 pmk[NAN_PMK_INFO_LEN];
+} NanSecurityPmk;
+
+typedef struct {
+    /* passphrase length */
+    u32 passphrase_len;
+    /*
+       passphrase info is optional in Discovery phase.
+       passphrase info can be passed during
+       the NDP session.
+     */
+    u8 passphrase[NAN_SECURITY_MAX_PASSPHRASE_LEN];
+} NanSecurityPassPhrase;
+
+typedef struct {
+    NanSecurityKeyInputType key_type;
+    union {
+        NanSecurityPmk pmk_info;
+        NanSecurityPassPhrase passphrase_info;
+    } body;
+} NanSecurityKeyInfo;
+
+/* NAN Security Cipher Suites Mask */
+#define NAN_CIPHER_SUITE_SHARED_KEY_NONE               0x00
+#define NAN_CIPHER_SUITE_SHARED_KEY_128_MASK           0x01
+#define NAN_CIPHER_SUITE_SHARED_KEY_256_MASK           0x02
+#define NAN_CIPHER_SUITE_PUBLIC_KEY_2WDH_128_MASK      0x04
+#define NAN_CIPHER_SUITE_PUBLIC_KEY_2WDH_256_MASK      0x08
+#define NAN_CIPHER_SUITE_PUBLIC_KEY_PASN_128_MASK      0x40
+#define NAN_CIPHER_SUITE_PUBLIC_KEY_PASN_256_MASK      0x80
+
+/* NAN ranging indication condition MASKS */
+#define NAN_RANGING_INDICATE_CONTINUOUS_MASK   0x01
+#define NAN_RANGING_INDICATE_INGRESS_MET_MASK  0x02
+#define NAN_RANGING_INDICATE_EGRESS_MET_MASK   0x04
+
+/* NAN schedule update reason MASKS */
+#define NAN_SCHEDULE_UPDATE_NSS_MASK   0x01
+#define NAN_SCHEDULE_UPDATE_CHANNEL_MASK  0x02
+
+/* NAN pairing bootstrapping method */
+#define NAN_PAIRING_BOOTSTRAPPING_OPPORTUNISTIC_MASK       0x01
+#define NAN_PAIRING_BOOTSTRAPPING_PIN_CODE_DISPLAY_MASK    0x02
+#define NAN_PAIRING_BOOTSTRAPPING_PASSPHRASE_DISPLAY_MASK  0x04
+#define NAN_PAIRING_BOOTSTRAPPING_QR_DISPLAY_MASK          0x08
+#define NAN_PAIRING_BOOTSTRAPPING_NFC_TAG_MASK             0x10
+#define NAN_PAIRING_BOOTSTRAPPING_PIN_CODE_KEYPAD_MASK     0x20
+#define NAN_PAIRING_BOOTSTRAPPING_PASSPHRASE_KEYPAD_MASK   0x40
+#define NAN_PAIRING_BOOTSTRAPPING_QR_SCAN_MASK             0x80
+#define NAN_PAIRING_BOOTSTRAPPING_NFC_READER_MASK          0x100
+#define NAN_PAIRING_BOOTSTRAPPING_SERVICE_MANAGED_MASK     0x4000
+#define NAN_PAIRING_BOOTSTRAPPING_HANDSHAKE_SHIP_MASK      0x8000
+
+/*
+   Structure to set the Service Descriptor Extension
+   Attribute (SDEA) passed as part of NanPublishRequest/
+   NanSubscribeRequest/NanMatchInd.
+*/
+typedef struct {
+    /*
+       Optional configuration of Data Path Enable request.
+       configure flag determines whether configuration needs
+       to be passed or not.
+    */
+    u8 config_nan_data_path;
+    NdpType ndp_type;
+    /*
+       NAN secuirty required flag to indicate
+       if the security is enabled or disabled
+    */
+    NanDataPathSecurityCfgStatus security_cfg;
+    /*
+       NAN ranging required flag to indicate
+       if ranging is enabled on disabled
+    */
+    NanRangingState ranging_state;
+    /*
+      Enable/Disable Ranging report,
+      when configured NanRangeReportInd received
+    */
+    NanRangeReport range_report;
+    /*
+      NAN QOS required flag to indicate
+      if QOS is required or not.
+    */
+    NanQosCfgStatus qos_cfg;
+    /*
+      Config to set FSD with Gas bit
+      in the SDEA Control Field.
+     */
+    u8 config_fsd_gas;
+    u8 enable_fsd_gas;
+
+    /*
+      Config to set FSD Required bit
+      in the SDEA Control Field.
+     */
+    u8 config_fsd_req;
+    u8 enable_fsd_req;
+
+    /*
+      Config to set gtk protection bit
+      in the SDEA Control Field.
+     */
+    u8 gtk_protection;
+} NanSdeaCtrlParams;
+
+/*
+   Nan Ranging Peer Info in MatchInd
+*/
+typedef struct {
+    /*
+       Distance to the NAN device with the MAC address indicated
+       with ranged mac address.
+    */
+    u32 range_measurement_mm;
+    /* Ranging event matching the configuration of continuous/ingress/egress. */
+    u32 ranging_event_type;
+} NanRangeInfo;
+
+/* Nan/NDP Capabilites info */
+typedef struct {
+    u32 max_concurrent_nan_clusters;
+    u32 max_publishes;
+    u32 max_subscribes;
+    u32 max_service_name_len;
+    u32 max_match_filter_len;
+    u32 max_total_match_filter_len;
+    u32 max_service_specific_info_len;
+    u32 max_vsa_data_len;
+    u32 max_mesh_data_len;
+    u32 max_ndi_interfaces;
+    u32 max_ndp_sessions;
+    u32 max_app_info_len;
+    u32 max_queued_transmit_followup_msgs;
+    u32 ndp_supported_bands;
+    u32 cipher_suites_supported;
+    u32 max_scid_len;
+    bool is_ndp_security_supported;
+    u32 max_sdea_service_specific_info_len;
+    u32 max_subscribe_address;
+    u32 ndpe_attr_supported;
+    bool is_instant_mode_supported;
+    bool is_6g_supported;
+    bool is_he_supported;
+    bool is_pairing_supported;
+    bool is_set_cluster_id_supported;
+    bool is_suspension_supported;
+} NanCapabilities;
+
+/*
+  Nan accept policy: Per service basis policy
+  Based on this policy(ALL/NONE), responder side
+  will send ACCEPT/REJECT
+*/
+typedef enum {
+    NAN_SERVICE_ACCEPT_POLICY_NONE = 0,
+    /* Default value */
+    NAN_SERVICE_ACCEPT_POLICY_ALL
+} NanServiceAcceptPolicy;
+
+/*
+  Host can send Vendor specific attributes which the Discovery Engine can
+  enclose in Beacons and/or Service Discovery frames transmitted.
+  Below structure is used to populate that.
+*/
+typedef struct {
+    /*
+       0 = transmit only in the next discovery window
+       1 = transmit in next 16 discovery window
+    */
+    u8 payload_transmit_flag;
+    /*
+       Below flags will determine in which all frames
+       the vendor specific attributes should be included
+    */
+    u8 tx_in_discovery_beacon;
+    u8 tx_in_sync_beacon;
+    u8 tx_in_service_discovery;
+    /* Organizationally Unique Identifier */
+    u32 vendor_oui;
+    /*
+       vendor specific attribute to be transmitted
+       vsa_len : Length of the vsa data.
+     */
+    u32 vsa_len;
+    u8 vsa[NAN_MAX_VSA_DATA_LEN];
+} NanTransmitVendorSpecificAttribute;
+
+
+/*
+  Discovery Engine will forward any Vendor Specific Attributes
+  which it received as part of this structure.
+*/
+/* Mask to determine on which frames attribute was received */
+#define RX_DISCOVERY_BEACON_MASK  0x01
+#define RX_SYNC_BEACON_MASK       0x02
+#define RX_SERVICE_DISCOVERY_MASK 0x04
+typedef struct {
+    /*
+       Frames on which this vendor specific attribute
+       was received. Mask defined above
+    */
+    u8 vsa_received_on;
+    /* Organizationally Unique Identifier */
+    u32 vendor_oui;
+    /* vendor specific attribute */
+    u32 attr_len;
+    u8 vsa[NAN_MAX_VSA_DATA_LEN];
+} NanReceiveVendorSpecificAttribute;
+
+/*
+   NAN Beacon SDF Payload Received structure
+   Discovery engine sends the details of received Beacon or
+   Service Discovery Frames as part of this structure.
+*/
+typedef struct {
+    /* Frame data */
+    u32 frame_len;
+    u8 frame_data[NAN_MAX_FRAME_DATA_LEN];
+} NanBeaconSdfPayloadReceive;
+
+/*
+  Host can set the Periodic scan parameters for each of the
+  3(6, 44, 149) Social channels. Only these channels are allowed
+  any other channels are rejected
+*/
+typedef enum {
+    NAN_CHANNEL_24G_BAND = 0,
+    NAN_CHANNEL_5G_BAND_LOW,
+    NAN_CHANNEL_5G_BAND_HIGH
+} NanChannelIndex;
+
+/*
+   Structure to set the Social Channel Scan parameters
+   passed as part of NanEnableRequest/NanConfigRequest
+*/
+typedef struct {
+    /*
+       Dwell time of each social channel in milliseconds
+       NanChannelIndex corresponds to the respective channel
+       If time set to 0 then the FW default time will be used.
+    */
+    u8 dwell_time[NAN_MAX_SOCIAL_CHANNELS]; // default value 200 msec
+
+    /*
+       Scan period of each social channel in seconds
+       NanChannelIndex corresponds to the respective channel
+       If time set to 0 then the FW default time will be used.
+    */
+    u16 scan_period[NAN_MAX_SOCIAL_CHANNELS]; // default value 20 sec
+} NanSocialChannelScanParams;
+
+/*
+  Host can send Post Connectivity Capability attributes
+  to be included in Service Discovery frames transmitted
+  as part of this structure.
+*/
+typedef struct {
+    /*
+       0 = transmit only in the next discovery window
+       1 = transmit in next 16 discovery window
+    */
+    u8 payload_transmit_flag;
+    /* 1 - Wifi Direct supported 0 - Not supported */
+    u8 is_wfd_supported;
+    /* 1 - Wifi Direct Services supported 0 - Not supported */
+    u8 is_wfds_supported;
+    /* 1 - TDLS supported 0 - Not supported */
+    u8 is_tdls_supported;
+    /* 1 - IBSS supported 0 - Not supported */
+    u8 is_ibss_supported;
+    /* 1 - Mesh supported 0 - Not supported */
+    u8 is_mesh_supported;
+    /*
+       1 - NAN Device currently connect to WLAN Infra AP
+       0 - otherwise
+    */
+    u8 wlan_infra_field;
+} NanTransmitPostConnectivityCapability;
+
+/*
+  Discovery engine providing the post connectivity capability
+  received.
+*/
+typedef struct {
+    /* 1 - Wifi Direct supported 0 - Not supported */
+    u8 is_wfd_supported;
+    /* 1 - Wifi Direct Services supported 0 - Not supported */
+    u8 is_wfds_supported;
+    /* 1 - TDLS supported 0 - Not supported */
+    u8 is_tdls_supported;
+    /* 1 - IBSS supported 0 - Not supported */
+    u8 is_ibss_supported;
+    /* 1 - Mesh supported 0 - Not supported */
+    u8 is_mesh_supported;
+    /*
+       1 - NAN Device currently connect to WLAN Infra AP
+       0 - otherwise
+    */
+    u8 wlan_infra_field;
+} NanReceivePostConnectivityCapability;
+
+/*
+  Indicates the availability interval duration associated with the
+  Availability Intervals Bitmap field
+*/
+typedef enum {
+    NAN_DURATION_16MS = 0,
+    NAN_DURATION_32MS = 1,
+    NAN_DURATION_64MS = 2
+} NanAvailDuration;
+
+/* Further availability per channel information */
+typedef struct {
+    /* Defined above */
+    NanAvailDuration entry_control;
+    /*
+       1 byte field indicating the frequency band the NAN Device
+       will be available as defined in IEEE Std. 802.11-2012
+       Annex E Table E-4 Global Operating Classes
+    */
+    u8 class_val;
+    /*
+       1 byte field indicating the channel the NAN Device
+       will be available.
+    */
+    u8 channel;
+    /*
+        Map Id - 4 bit field which identifies the Further
+        availability map attribute.
+    */
+    u8 mapid;
+    /*
+       divides the time between the beginnings of consecutive Discovery
+       Windows of a given NAN cluster into consecutive time intervals
+       of equal durations. The time interval duration is specified by
+       the Availability Interval Duration subfield of the Entry Control
+       field.
+
+       A Nan device that sets the i-th bit of the Availability
+       Intervals Bitmap to 1 shall be present during the corresponding
+       i-th time interval in the operation channel indicated by the
+       Operating Class and Channel Number fields in the same Availability Entry.
+
+       A Nan device that sets the i-th bit of the Availability Intervals Bitmap to
+       0 may be present during the corresponding i-th time interval in the operation
+       channel indicated by the Operating Class and Channel Number fields in the same
+       Availability Entry.
+
+       The size of the Bitmap is dependent upon the Availability Interval Duration
+       chosen in the Entry Control Field.  The size can be either 1, 2 or 4 bytes long
+
+       - Duration field is equal to 0, only AIB[0] is valid
+       - Duration field is equal to 1, only AIB [0] and AIB [1] is valid
+       - Duration field is equal to 2, AIB [0], AIB [1], AIB [2] and AIB [3] are valid
+    */
+    u32 avail_interval_bitmap;
+} NanFurtherAvailabilityChannel;
+
+/*
+  Further availability map which can be sent and received from
+  Discovery engine
+*/
+typedef struct {
+    /*
+       Number of channels indicates the number of channel
+       entries which is part of fam
+    */
+    u8 numchans;
+    NanFurtherAvailabilityChannel famchan[NAN_MAX_FAM_CHANNELS];
+} NanFurtherAvailabilityMap;
+
+/*
+  Host can send Post-Nan Discovery attributes which the Discovery Engine can
+  enclose in Service Discovery frames
+*/
+/* Possible connection types in Post NAN Discovery attributes */
+typedef enum {
+    NAN_CONN_WLAN_INFRA = 0,
+    NAN_CONN_P2P_OPER = 1,
+    NAN_CONN_WLAN_IBSS = 2,
+    NAN_CONN_WLAN_MESH = 3,
+    NAN_CONN_FURTHER_SERVICE_AVAILABILITY = 4,
+    NAN_CONN_WLAN_RANGING = 5
+} NanConnectionType;
+
+/* Possible device roles in Post NAN Discovery attributes */
+typedef enum {
+    NAN_WLAN_INFRA_AP = 0,
+    NAN_WLAN_INFRA_STA = 1,
+    NAN_P2P_OPER_GO = 2,
+    NAN_P2P_OPER_DEV = 3,
+    NAN_P2P_OPER_CLI = 4
+} NanDeviceRole;
+
+/* Configuration params of NAN Ranging */
+typedef struct {
+    /*
+      Interval in milli sec between two ranging measurements.
+      If the Awake DW intervals in NanEnable/Config are larger
+      than the ranging intervals priority is given to Awake DW
+      Intervals. Only on a match the ranging is initiated for the
+      peer
+    */
+    u32 ranging_interval_msec;
+    /*
+      Flags indicating the type of ranging event to be notified
+      NAN_RANGING_INDICATE_ MASKS are used to set these.
+      BIT0 - Continuous Ranging event notification.
+      BIT1 - Ingress distance is <=.
+      BIT2 - Egress distance is >=.
+    */
+    u32 config_ranging_indications;
+    /* Ingress distance in millimeters (optional) */
+    u32 distance_ingress_mm;
+    /* Egress distance in millmilliimeters (optional) */
+    u32 distance_egress_mm;
+} NanRangingCfg;
+
+/* NAN Ranging request's response */
+typedef struct {
+    /* Publish Id of an earlier Publisher */
+    u16 publish_id;
+    /*
+       A 32 bit Requestor instance Id which is sent to the Application.
+       This Id will be used in subsequent RangeResponse on Subscribe side.
+    */
+    u32 requestor_instance_id;
+    /* Peer MAC addr of Range Requestor */
+    u8 peer_addr[NAN_MAC_ADDR_LEN];
+    /* Response indicating ACCEPT/REJECT/CANCEL of Range Request */
+    NanRangeResponse ranging_response;
+} NanRangeResponseCfg;
+
+/* Structure of Post NAN Discovery attribute */
+typedef struct {
+    /* Connection type of the host */
+    NanConnectionType  type;
+    /*
+       Device role of the host based on
+       the connection type
+    */
+    NanDeviceRole role;
+    /*
+       Flag to send the information as a single shot or repeated
+       for next 16 discovery windows
+       0 - Single_shot
+       1 - next 16 discovery windows
+    */
+    u8 transmit_freq;
+    /* Duration of the availability bitmask */
+    NanAvailDuration duration;
+    /* Availability interval bitmap based on duration */
+    u32 avail_interval_bitmap;
+    /*
+       Mac address depending on the conn type and device role
+       --------------------------------------------------
+       | Conn Type  |  Device Role |  Mac address Usage  |
+       --------------------------------------------------
+       | WLAN_INFRA |  AP/STA      |   BSSID of the AP   |
+       --------------------------------------------------
+       | P2P_OPER   |  GO          |   GO's address      |
+       --------------------------------------------------
+       | P2P_OPER   |  P2P_DEVICE  |   Address of who    |
+       |            |              |   would become GO   |
+       --------------------------------------------------
+       | WLAN_IBSS  |  NA          |   BSSID             |
+       --------------------------------------------------
+       | WLAN_MESH  |  NA          |   BSSID             |
+       --------------------------------------------------
+    */
+    u8 addr[NAN_MAC_ADDR_LEN];
+    /*
+       Mandatory mesh id value if connection type is WLAN_MESH
+       Mesh id contains 0-32 octet identifier and should be
+       as per IEEE Std.802.11-2012 spec.
+    */
+    u16 mesh_id_len;
+    u8 mesh_id[NAN_MAX_MESH_DATA_LEN];
+    /*
+       Optional infrastructure SSID if conn_type is set to
+       NAN_CONN_WLAN_INFRA
+    */
+    u16 infrastructure_ssid_len;
+    u8 infrastructure_ssid_val[NAN_MAX_INFRA_DATA_LEN];
+} NanTransmitPostDiscovery;
+
+/*
+   Discovery engine providing the structure of Post NAN
+   Discovery
+*/
+typedef struct {
+    /* Connection type of the host */
+    NanConnectionType  type;
+    /*
+       Device role of the host based on
+       the connection type
+    */
+    NanDeviceRole role;
+    /* Duration of the availability bitmask */
+    NanAvailDuration duration;
+    /* Availability interval bitmap based on duration */
+    u32 avail_interval_bitmap;
+    /*
+       Map Id - 4 bit field which identifies the Further
+       availability map attribute.
+    */
+    u8 mapid;
+    /*
+       Mac address depending on the conn type and device role
+       --------------------------------------------------
+       | Conn Type  |  Device Role |  Mac address Usage  |
+       --------------------------------------------------
+       | WLAN_INFRA |  AP/STA      |   BSSID of the AP   |
+       --------------------------------------------------
+       | P2P_OPER   |  GO          |   GO's address      |
+       --------------------------------------------------
+       | P2P_OPER   |  P2P_DEVICE  |   Address of who    |
+       |            |              |   would become GO   |
+       --------------------------------------------------
+       | WLAN_IBSS  |  NA          |   BSSID             |
+       --------------------------------------------------
+       | WLAN_MESH  |  NA          |   BSSID             |
+       --------------------------------------------------
+    */
+    u8 addr[NAN_MAC_ADDR_LEN];
+    /*
+       Mandatory mesh id value if connection type is WLAN_MESH
+       Mesh id contains 0-32 octet identifier and should be
+       as per IEEE Std.802.11-2012 spec.
+    */
+    u16 mesh_id_len;
+    u8 mesh_id[NAN_MAX_MESH_DATA_LEN];
+    /*
+       Optional infrastructure SSID if conn_type is set to
+       NAN_CONN_WLAN_INFRA
+    */
+    u16 infrastructure_ssid_len;
+    u8 infrastructure_ssid_val[NAN_MAX_INFRA_DATA_LEN];
+} NanReceivePostDiscovery;
+
+/*
+   NAN device level configuration of SDF and Sync beacons in both
+   2.4/5GHz bands
+*/
+typedef struct {
+    /* Configure 2.4GHz DW Band */
+    u8 config_2dot4g_dw_band;
+    /*
+       Indicates the interval for Sync beacons and SDF's in 2.4GHz band.
+       Valid values of DW Interval are: 1, 2, 3, 4 and 5, 0 is reserved.
+       The SDF includes in OTA when enabled. The publish/subscribe period
+       values don't override the device level configurations.
+    */
+    u32 dw_2dot4g_interval_val; // default value 1
+    /* Configure 5GHz DW Band */
+    u8 config_5g_dw_band;
+    /*
+       Indicates the interval for Sync beacons and SDF's in 5GHz band
+       Valid values of DW Interval are: 1, 2, 3, 4 and 5, 0 no wake up for
+       any interval. The SDF includes in OTA when enabled. The publish/subscribe
+       period values don't override the device level configurations.
+    */
+    u32 dw_5g_interval_val; // default value 1 when 5G is enabled
+} NanConfigDW;
+
+/*
+  Enable Request Message Structure
+  The NanEnableReq message instructs the Discovery Engine to enter an operational state
+*/
+typedef struct {
+    /* Mandatory parameters below */
+    u8 master_pref; // default value 0x02
+    /*
+      A cluster_low value matching cluster_high indicates a request to join
+      a cluster with that value. If the requested cluster is not found the
+      device will start its own cluster.
+    */
+    u16 cluster_low; // default value 0
+    u16 cluster_high; // default value 0xFFFF
+
+    /*
+      Optional configuration of Enable request.
+      Each of the optional parameters have configure flag which
+      determine whether configuration is to be passed or not.
+    */
+    u8 config_support_5g;
+    u8 support_5g_val; // default value 0; turned off by default
+    /*
+       BIT 0 is used to specify to include Service IDs in Sync/Discovery beacons
+       0 - Do not include SIDs in any beacons
+       1 - Include SIDs in all beacons.
+       Rest 7 bits are count field which allows control over the number of SIDs
+       included in the Beacon.  0 means to include as many SIDs that fit into
+       the maximum allow Beacon frame size
+    */
+    u8 config_sid_beacon;
+    u8 sid_beacon_val; // default value 0x01
+    /*
+       The rssi values below should be specified without sign.
+       For eg: -70dBm should be specified as 70.
+    */
+    u8 config_2dot4g_rssi_close;
+    u8 rssi_close_2dot4g_val;    // default value -60 dBm
+
+    u8 config_2dot4g_rssi_middle;
+    u8 rssi_middle_2dot4g_val;    // default value -70 dBm
+
+    u8 config_2dot4g_rssi_proximity;
+    u8 rssi_proximity_2dot4g_val;//  default value -60dBm
+
+    u8 config_hop_count_limit;
+    u8 hop_count_limit_val; //  default value 0x02
+
+    /*
+       Defines 2.4G channel access support
+       0 - No Support
+       1 - Supported
+    */
+    u8 config_2dot4g_support;
+    u8 support_2dot4g_val; // default value 0x01
+    /*
+       Defines 2.4G channels will be used for sync/discovery beacons
+       0 - 2.4G channels not used for beacons
+       1 - 2.4G channels used for beacons
+    */
+    u8 config_2dot4g_beacons;
+    u8 beacon_2dot4g_val; // default value 1
+    /*
+       Defines 2.4G channels will be used for Service Discovery frames
+       0 - 2.4G channels not used for Service Discovery frames
+       1 - 2.4G channels used for Service Discovery frames
+    */
+    u8 config_2dot4g_sdf;
+    u8 sdf_2dot4g_val; // default value 1
+    /*
+       Defines 5G channels will be used for sync/discovery beacons
+       0 - 5G channels not used for beacons
+       1 - 5G channels used for beacons
+    */
+    u8 config_5g_beacons;
+    u8 beacon_5g_val; // default value 1 when 5G is enabled
+    /*
+       Defines 5G channels will be used for Service Discovery frames
+       0 - 5G channels not used for Service Discovery frames
+       1 - 5G channels used for Service Discovery frames
+    */
+    u8 config_5g_sdf;
+    u8 sdf_5g_val; // default value is 0 when 5G is enabled
+    /*
+       1 byte value which defines the RSSI in
+       dBm for a close by Peer in 5 Ghz channels.
+       The rssi values should be specified without sign.
+       For eg: -70dBm should be specified as 70.
+    */
+    u8 config_5g_rssi_close;
+    u8 rssi_close_5g_val; // default value -60dBm when 5G is enabled
+    /*
+       1 byte value which defines the RSSI value in
+       dBm for a close by Peer in 5 Ghz channels.
+       The rssi values should be specified without sign.
+       For eg: -70dBm should be specified as 70.
+    */
+    u8 config_5g_rssi_middle;
+    u8 rssi_middle_5g_val; // default value -75dBm when 5G is enabled
+    /*
+       1 byte value which defines the RSSI filter
+       threshold.  Any Service Descriptors received above this
+       value that are configured for RSSI filtering will be dropped.
+       The rssi values should be specified without sign.
+       For eg: -70dBm should be specified as 70.
+    */
+    u8 config_5g_rssi_close_proximity;
+    u8 rssi_close_proximity_5g_val; // default value -60dBm when 5G is enabled
+    /*
+       1 byte quantity which defines the window size over
+       which the “average RSSI” will be calculated over.
+    */
+    u8 config_rssi_window_size;
+    u8 rssi_window_size_val; // default value 0x08
+    /*
+       The 24 bit Organizationally Unique ID + the 8 bit Network Id.
+    */
+    u8 config_oui;
+    u32 oui_val; // default value {0x51, 0x6F, 0x9A, 0x01, 0x00, 0x00}
+    /*
+       NAN Interface Address, If not configured the Discovery Engine
+       will generate a 6 byte Random MAC.
+    */
+    u8 config_intf_addr;
+    u8 intf_addr_val[NAN_MAC_ADDR_LEN];
+    /*
+       If set to 1, the Discovery Engine will enclose the Cluster
+       Attribute only sent in Beacons in a Vendor Specific Attribute
+       and transmit in a Service Descriptor Frame.
+    */
+    u8 config_cluster_attribute_val;
+    /*
+       The periodicity in seconds between full scan’s to find any new
+       clusters available in the area.  A Full scan should not be done
+       more than every 10 seconds and should not be done less than every
+       30 seconds.
+    */
+    u8 config_scan_params;
+    NanSocialChannelScanParams scan_params_val;
+    /*
+       1 byte quantity which forces the Random Factor to a particular
+       value for all transmitted Sync/Discovery beacons
+    */
+    u8 config_random_factor_force;
+    u8 random_factor_force_val; // default value off and set to 0x00
+    /*
+       1 byte quantity which forces the HC for all transmitted Sync and
+       Discovery Beacon NO matter the real HC being received over the
+       air.
+    */
+    u8 config_hop_count_force;
+    u8 hop_count_force_val; // default value 0x00
+
+    /* channel frequency in MHz to enable Nan on */
+    u8 config_24g_channel;
+    wifi_channel channel_24g_val; // default value channel 0x6
+
+    u8 config_5g_channel;
+    wifi_channel channel_5g_val; // default value channel 44 or 149 regulatory
+                                 // domain
+    /* Configure 2.4/5GHz DW */
+    NanConfigDW config_dw;
+
+    /*
+       By default discovery MAC address randomization is enabled
+       and default interval value is 30 minutes i.e. 1800 seconds.
+       The value 0 is used to disable MAC addr randomization.
+    */
+    u8 config_disc_mac_addr_randomization;
+    u32 disc_mac_addr_rand_interval_sec; // default value 1800 sec
+
+    /*
+      Set/Enable corresponding bits to disable Discovery indications:
+      BIT0 - Disable Discovery MAC Address Event.
+      BIT1 - Disable Started Cluster Event.
+      BIT2 - Disable Joined Cluster Event.
+    */
+    u8 discovery_indication_cfg;  // default value 0x0
+    /*
+       BIT 0 is used to specify to include Service IDs in Sync/Discovery beacons
+       0 - Do not include SIDs in any beacons
+       1 - Include SIDs in all beacons.
+       Rest 7 bits are count field which allows control over the number of SIDs
+       included in the Beacon.  0 means to include as many SIDs that fit into
+       the maximum allow Beacon frame size
+    */
+    u8 config_subscribe_sid_beacon;
+    u32 subscribe_sid_beacon_val; // default value 0x0
+    /*
+       Discovery Beacon Interval config.
+       Default value is 128 msec in 2G DW and 176 msec in 2G/5G DW.
+       When 0 value is passed it is reset to default value of 128 or 176 msec.
+    */
+    u8 config_discovery_beacon_int;
+    u32 discovery_beacon_interval;
+    /*
+       Enable Number of Spatial Streams.
+       This is NAN Power Optimization feature for NAN discovery.
+    */
+    u8 config_nss;
+    // default value is implementation specific and passing 0 sets it to default
+    u32 nss;
+    /*
+       Enable device level NAN Ranging feature.
+       0 - Disable
+       1 - Enable
+    */
+    u8 config_enable_ranging;
+    u32 enable_ranging;
+    /*
+       Enable/Disable DW Early termination.
+       0 - Disable
+       1 - Enable
+    */
+    u8 config_dw_early_termination;
+    u32 enable_dw_termination;
+    /*
+       Indicate whether to use NDPE attribute to bring-up TCP/IP connection.
+       If config_ndpe_attr is not configured, the default behavior is
+       not using NDPE attr, and the capability is not advertised.
+       0 - Not use
+       1 - Use
+    */
+    u8 config_ndpe_attr;
+    u32 use_ndpe_attr;
+    /*
+        Enable NAN v3.1 instant communication mode.
+        0 - Disable
+        1 - Enable
+    */
+    u8 config_enable_instant_mode;
+    u32 enable_instant_mode;
+    /*
+        Config NAN v3.1 instant communication channel frequency selected over NFC/OOB method.
+        If dual band is supported default channel is 149 or 44 as per regulatory domain,
+        else channel 6 (send frequency in MHz).
+        Sometimes depending on country code retrictions, even 149/44 may be restricted
+        in those cases instant channel will be operational only in 2.4GHz.
+        Use wifi_get_usable_channels() API to get supported bands/channels before
+        Instant mode NFC handshake is triggered
+    */
+    u8 config_instant_mode_channel;
+    wifi_channel instant_mode_channel;
+
+    /*
+       Enable/Disable unsync service discovery.
+       0 - Disable
+       1 - Enable
+    */
+    u8 config_unsync_srvdsc;
+    u8 enable_unsync_srvdsc;
+
+    /*
+      Configure regulatory information.
+    */
+    u8 config_reg_info;
+    u8 reg_info_val;
+} NanEnableRequest;
+
+/*
+  NAN pairing config.
+*/
+typedef struct {
+
+    /*
+      Enable Nan pairing setup
+    */
+    u32 enable_pairing_setup;
+
+    /*
+      Enable cache NIK/NPK after Nan pairing setup
+    */
+    u32 enable_pairing_cache;
+
+    /*
+      Enable Nan pairing verification with cached NIK/NPK
+    */
+    u32 enable_pairing_verification;
+
+    /*
+      The set of supported bootstrapping methods.
+    */
+    u16 supported_bootstrapping_methods;
+} NanPairingConfig;
+
+/*
+  Publish Msg Structure
+  Message is used to request the DE to publish the Service Name
+  using the parameters passed into the Discovery Window
+*/
+typedef struct {
+    u16 publish_id;/* id  0 means new publish, any other id is existing publish */
+    u16 ttl; /* how many seconds to run for. 0 means forever until canceled */
+    /*
+       period: Awake DW Interval for publish(service)
+       Indicates the interval between two Discovery Windows in which
+       the device supporting the service is awake to transmit or
+       receive the Service Discovery frames.
+       Valid values of Awake DW Interval are: 1, 2, 4, 8 and 16, value 0 will
+       default to 1.
+    */
+    u16 period;
+    NanPublishType publish_type;/* 0= unsolicited, solicited = 1, 2= both */
+    NanTxType tx_type; /* 0 = broadcast, 1= unicast  if solicited publish */
+    u8 publish_count; /* number of OTA Publish, 0 means forever until canceled */
+    u16 service_name_len; /* length of service name */
+    u8 service_name[NAN_MAX_SERVICE_NAME_LEN];/* UTF-8 encoded string identifying the service */
+    /*
+       Field which specifies how the matching indication to host is controlled.
+       0 - Match and Indicate Once
+       1 - Match and Indicate continuous
+       2 - Match and Indicate never. This means don't indicate the match to the host.
+       3 - Reserved
+    */
+    NanMatchAlg publish_match_indicator;
+
+    /*
+       Sequence of values
+       NAN Device that has invoked a Subscribe method corresponding to this Publish method
+    */
+    u16 service_specific_info_len;
+    u8 service_specific_info[NAN_MAX_SERVICE_SPECIFIC_INFO_LEN];
+
+    /*
+       Ordered sequence of <length, value> pairs which specify further response conditions
+       beyond the service name used to filter subscribe messages to respond to.
+       This is only needed when the PT is set to NAN_SOLICITED or NAN_SOLICITED_UNSOLICITED.
+    */
+    u16 rx_match_filter_len;
+    u8 rx_match_filter[NAN_MAX_MATCH_FILTER_LEN];
+
+    /*
+       Ordered sequence of <length, value> pairs to be included in the Discovery Frame.
+       If present it is always sent in a Discovery Frame
+    */
+    u16 tx_match_filter_len;
+    u8 tx_match_filter[NAN_MAX_MATCH_FILTER_LEN];
+
+    /*
+       flag which specifies that the Publish should use the configured RSSI
+       threshold and the received RSSI in order to filter requests
+       0 – ignore the configured RSSI threshold when running a Service
+           Descriptor attribute or Service ID List Attribute through the DE matching logic.
+       1 – use the configured RSSI threshold when running a Service
+           Descriptor attribute or Service ID List Attribute through the DE matching logic.
+
+    */
+    u8 rssi_threshold_flag;
+
+    /*
+       8-bit bitmap which allows the Host to associate this publish
+       with a particular Post-NAN Connectivity attribute
+       which has been sent down in a NanConfigureRequest/NanEnableRequest
+       message.  If the DE fails to find a configured Post-NAN
+       connectivity attributes referenced by the bitmap,
+       the DE will return an error code to the Host.
+       If the Publish is configured to use a Post-NAN Connectivity
+       attribute and the Host does not refresh the Post-NAN Connectivity
+       attribute the Publish will be canceled and the Host will be sent
+       a PublishTerminatedIndication message.
+    */
+    u8 connmap;
+    /*
+      Set/Enable corresponding bits to disable any indications that follow a publish.
+      BIT0 - Disable publish termination indication.
+      BIT1 - Disable match expired indication.
+      BIT2 - Disable followUp indication received (OTA).
+      BIT3 - Disable publishReplied indication.
+    */
+    u8 recv_indication_cfg;
+    /*
+      Nan accept policy for the specific service(publish)
+    */
+    NanServiceAcceptPolicy service_responder_policy;
+    /* NAN Cipher Suite Type */
+    u32 cipher_type;
+    /*
+       Nan Security Key Info is optional in Discovery phase.
+       PMK or passphrase info can be passed during
+       the NDP session.
+    */
+    NanSecurityKeyInfo key_info;
+
+    /* Security Context Identifiers length */
+    u32 scid_len;
+    /*
+       Security Context Identifier attribute contains PMKID
+       shall be included in NDP setup and response messages.
+       Security Context Identifier, Identifies the Security
+       Context. For NAN Shared Key Cipher Suite, this field
+       contains the 16 octet PMKID identifying the PMK used
+       for setting up the Secure Data Path.
+    */
+    u8 scid[NAN_MAX_SCID_BUF_LEN];
+
+    /* NAN configure service discovery extended attributes */
+    NanSdeaCtrlParams sdea_params;
+
+    /* NAN Ranging configuration */
+    NanRangingCfg ranging_cfg;
+
+    /* Enable/disable NAN serivce Ranging auto response mode */
+    NanRangingAutoResponse ranging_auto_response;
+
+    /*
+      When the ranging_auto_response_cfg is not set, NanRangeRequestInd is
+      received. Nan Range Response to Peer MAC Addr is notified to indicate
+      ACCEPT/REJECT/CANCEL to the requestor.
+    */
+    NanRangeResponseCfg range_response_cfg;
+
+    /*
+       Sequence of values indicating the service specific info in SDEA
+    */
+    u16 sdea_service_specific_info_len;
+    u8 sdea_service_specific_info[NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN];
+
+    /*
+       The Identity key for pairing, used to generate NIRA
+    */
+    u8 nan_identity_key[NAN_IDENTITY_KEY_LEN];
+
+    /*
+      The config for Nan pairing
+    */
+    NanPairingConfig nan_pairing_config;
+
+    /*
+      Specifies whether suspension can be possible in this publish session.
+      The request would fail if enable_suspendability is true but
+      is_suspension_supported is false in NanCapabilities.
+    */
+    bool enable_suspendability;
+
+    /* s3 capabilities */
+    u16 s3_capabilities;
+
+    /* cipher capabilities */
+    u8 cipher_capabilities;
+} NanPublishRequest;
+
+/*
+  Publish Cancel Msg Structure
+  The PublishServiceCancelReq Message is used to request the DE to stop publishing
+  the Service Name identified by the Publish Id in the message.
+*/
+typedef struct {
+    u16 publish_id;
+} NanPublishCancelRequest;
+
+/*
+  NAN Subscribe Structure
+  The SubscribeServiceReq message is sent to the Discovery Engine
+  whenever the Upper layers would like to listen for a Service Name
+*/
+typedef struct {
+    u16 subscribe_id; /* id 0 means new subscribe, non zero is existing subscribe */
+    u16 ttl; /* how many seconds to run for. 0 means forever until canceled */
+    /*
+       period: Awake DW Interval for subscribe(service)
+       Indicates the interval between two Discovery Windows in which
+       the device supporting the service is awake to transmit or
+       receive the Service Discovery frames.
+       Valid values of Awake DW Interval are: 1, 2, 4, 8 and 16, value 0 will
+       default to 1.
+    */
+    u16 period;
+
+    /* Flag which specifies how the Subscribe request shall be processed. */
+    NanSubscribeType subscribe_type; /* 0 - PASSIVE , 1- ACTIVE */
+
+    /* Flag which specifies on Active Subscribes how the Service Response Filter attribute is populated.*/
+    NanSRFType serviceResponseFilter; /* 0 - Bloom Filter, 1 - MAC Addr */
+
+    /* Flag which specifies how the Service Response Filter Include bit is populated.*/
+    NanSRFIncludeType serviceResponseInclude; /* 0=Do not respond if in the Address Set, 1= Respond */
+
+    /* Flag which specifies if the Service Response Filter should be used when creating Subscribes.*/
+    NanSRFState useServiceResponseFilter; /* 0=Do not send the Service Response Filter,1= send */
+
+    /*
+       Flag which specifies if the Service Specific Info is needed in
+       the Publish message before creating the MatchIndication
+    */
+    NanSsiInMatchInd ssiRequiredForMatchIndication; /* 0=Not needed, 1= Required */
+
+    /*
+       Field which specifies how the matching indication to host is controlled.
+       0 - Match and Indicate Once
+       1 - Match and Indicate continuous
+       2 - Match and Indicate never. This means don't indicate the match to the host.
+       3 - Reserved
+    */
+    NanMatchAlg subscribe_match_indicator;
+
+    /*
+       The number of Subscribe Matches which should occur
+       before the Subscribe request is automatically terminated.
+    */
+    u8 subscribe_count; /* If this value is 0 this field is not used by the DE.*/
+
+    u16 service_name_len;/* length of service name */
+    u8 service_name[NAN_MAX_SERVICE_NAME_LEN]; /* UTF-8 encoded string identifying the service */
+
+    /* Sequence of values which further specify the published service beyond the service name*/
+    u16 service_specific_info_len;
+    u8 service_specific_info[NAN_MAX_SERVICE_SPECIFIC_INFO_LEN];
+
+    /*
+       Ordered sequence of <length, value> pairs used to filter out received publish discovery messages.
+       This can be sent both for a Passive or an Active Subscribe
+    */
+    u16 rx_match_filter_len;
+    u8 rx_match_filter[NAN_MAX_MATCH_FILTER_LEN];
+
+    /*
+       Ordered sequence of <length, value> pairs  included in the
+       Discovery Frame when an Active Subscribe is used.
+    */
+    u16 tx_match_filter_len;
+    u8 tx_match_filter[NAN_MAX_MATCH_FILTER_LEN];
+
+    /*
+       Flag which specifies that the Subscribe should use the configured RSSI
+       threshold and the received RSSI in order to filter requests
+       0 – ignore the configured RSSI threshold when running a Service
+           Descriptor attribute or Service ID List Attribute through the DE matching logic.
+       1 – use the configured RSSI threshold when running a Service
+           Descriptor attribute or Service ID List Attribute through the DE matching logic.
+
+    */
+    u8 rssi_threshold_flag;
+
+    /*
+       8-bit bitmap which allows the Host to associate this Active
+       Subscribe with a particular Post-NAN Connectivity attribute
+       which has been sent down in a NanConfigureRequest/NanEnableRequest
+       message.  If the DE fails to find a configured Post-NAN
+       connectivity attributes referenced by the bitmap,
+       the DE will return an error code to the Host.
+       If the Subscribe is configured to use a Post-NAN Connectivity
+       attribute and the Host does not refresh the Post-NAN Connectivity
+       attribute the Subscribe will be canceled and the Host will be sent
+       a SubscribeTerminatedIndication message.
+    */
+    u8 connmap;
+    /*
+       NAN Interface Address, conforming to the format as described in
+       8.2.4.3.2 of IEEE Std. 802.11-2012.
+    */
+    u8 num_intf_addr_present;
+    u8 intf_addr[NAN_MAX_SUBSCRIBE_MAX_ADDRESS][NAN_MAC_ADDR_LEN];
+    /*
+      Set/Enable corresponding bits to disable indications that follow a subscribe.
+      BIT0 - Disable subscribe termination indication.
+      BIT1 - Disable match expired indication.
+      BIT2 - Disable followUp indication received (OTA).
+    */
+    u8 recv_indication_cfg;
+
+    /* NAN Cipher Suite Type */
+    u32 cipher_type;
+    /*
+       Nan Security Key Info is optional in Discovery phase.
+       PMK or passphrase info can be passed during
+       the NDP session.
+    */
+    NanSecurityKeyInfo key_info;
+
+    /* Security Context Identifiers length */
+    u32 scid_len;
+    /*
+       Security Context Identifier attribute contains PMKID
+       shall be included in NDP setup and response messages.
+       Security Context Identifier, Identifies the Security
+       Context. For NAN Shared Key Cipher Suite, this field
+       contains the 16 octet PMKID identifying the PMK used
+       for setting up the Secure Data Path.
+    */
+    u8 scid[NAN_MAX_SCID_BUF_LEN];
+
+    /* NAN configure service discovery extended attributes */
+    NanSdeaCtrlParams sdea_params;
+
+    /* NAN Ranging configuration */
+    NanRangingCfg ranging_cfg;
+
+    /* Enable/disable NAN serivce Ranging auto response mode */
+    NanRangingAutoResponse ranging_auto_response;
+
+    /*
+      When the ranging_auto_response_cfg is not set, NanRangeRequestInd is
+      received. Nan Range Response to Peer MAC Addr is notified to indicate
+      ACCEPT/REJECT/CANCEL to the requestor.
+    */
+    NanRangeResponseCfg range_response_cfg;
+
+    /*
+       Sequence of values indicating the service specific info in SDEA
+    */
+    u16 sdea_service_specific_info_len;
+    u8 sdea_service_specific_info[NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN];
+    /*
+       The Identity key for pairing, used to generate NIRA
+    */
+    u8 nan_identity_key[NAN_IDENTITY_KEY_LEN];
+
+    /*
+      The config for Nan pairing
+    */
+    NanPairingConfig nan_pairing_config;
+
+    /*
+      Specifies whether suspension can be possible in this subscribe session.
+      The request would fail if enable_suspendability is true but
+      is_suspension_supported is false in NanCapabilities.
+    */
+    bool enable_suspendability;
+
+    /* cipher capabilities */
+    u8 cipher_capabilities;
+} NanSubscribeRequest;
+
+/*
+  NAN Subscribe Cancel Structure
+  The SubscribeCancelReq Message is used to request the DE to stop looking for the Service Name.
+*/
+typedef struct {
+    u16 subscribe_id;
+} NanSubscribeCancelRequest;
+
+/*
+  Transmit follow up Structure
+  The TransmitFollowupReq message is sent to the DE to allow the sending of the Service_Specific_Info
+  to a particular MAC address.
+*/
+typedef struct {
+    /* Publish or Subscribe Id of an earlier Publish/Subscribe */
+    u16 publish_subscribe_id;
+
+    /*
+       This Id is the Requestor Instance that is passed as
+       part of earlier MatchInd/FollowupInd message.
+    */
+    u32 requestor_instance_id;
+    u8 addr[NAN_MAC_ADDR_LEN]; /* Unicast address */
+    NanTxPriority priority; /* priority of the request 2=high */
+    NanTransmitWindowType dw_or_faw; /* 0= send in a DW, 1=send in FAW */
+
+    /*
+       Sequence of values which further specify the published service beyond
+       the service name.
+    */
+    u16 service_specific_info_len;
+    u8 service_specific_info[NAN_MAX_SERVICE_SPECIFIC_INFO_LEN];
+    /*
+      Set/Enable corresponding bits to disable responses after followUp.
+      BIT0 - Disable followUp response from FW.
+    */
+    u8 recv_indication_cfg;
+
+    /*
+       Sequence of values indicating the service specific info in SDEA
+    */
+    u16 sdea_service_specific_info_len;
+    u8 sdea_service_specific_info[NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN];
+
+    /*
+       Add shared key descriptor attribute to the Followup request when the
+       flag is set
+    */
+    u8 shared_key_desc_flag;
+} NanTransmitFollowupRequest;
+
+/*
+  Stats Request structure
+  The Discovery Engine can be queried at runtime by the Host processor for statistics
+  concerning various parts of the Discovery Engine.
+*/
+typedef struct {
+    NanStatsType stats_type; /* NAN Statistics Request Type */
+    u8 clear; /* 0= Do not clear the stats and return the current contents , 1= Clear the associated stats  */
+} NanStatsRequest;
+
+/*
+  Suspend Request Structure
+  The SuspendRequest message is used to request that the specified session is suspended.
+  The session can be resumed using the NanResumeRequest message.
+*/
+typedef struct {
+    u16 publish_subscribe_id;
+} NanSuspendRequest;
+
+/*
+  Resume Request Structure
+  The ResumeRequest message is used to request that the specified session is resumed.
+*/
+typedef struct {
+    u16 publish_subscribe_id;
+} NanResumeRequest;
+
+/*
+  Config Structure
+  The NanConfigurationReq message is sent by the Host to the
+  Discovery Engine in order to configure the Discovery Engine during runtime.
+*/
+typedef struct {
+    u8 config_sid_beacon;
+    u8 sid_beacon;
+    u8 config_rssi_proximity;
+    u8 rssi_proximity; // default value -60dBm
+    u8 config_master_pref;
+    u8 master_pref; // default value 0x02
+    /*
+       1 byte value which defines the RSSI filter threshold.
+       Any Service Descriptors received above this value
+       that are configured for RSSI filtering will be dropped.
+       The rssi values should be specified without sign.
+       For eg: -70dBm should be specified as 70.
+    */
+    u8 config_5g_rssi_close_proximity;
+    u8 rssi_close_proximity_5g_val;  // default value -60dBm
+    /*
+      Optional configuration of Configure request.
+      Each of the optional parameters have configure flag which
+      determine whether configuration is to be passed or not.
+    */
+    /*
+       1 byte quantity which defines the window size over
+       which the “average RSSI” will be calculated over.
+    */
+    u8 config_rssi_window_size;
+    u8 rssi_window_size_val; // default value 0x08
+    /*
+       If set to 1, the Discovery Engine will enclose the Cluster
+       Attribute only sent in Beacons in a Vendor Specific Attribute
+       and transmit in a Service Descriptor Frame.
+    */
+    u8 config_cluster_attribute_val;
+    /*
+      The periodicity in seconds between full scan’s to find any new
+      clusters available in the area.  A Full scan should not be done
+      more than every 10 seconds and should not be done less than every
+      30 seconds.
+    */
+    u8 config_scan_params;
+    NanSocialChannelScanParams scan_params_val;
+    /*
+       1 byte quantity which forces the Random Factor to a particular
+       value for all transmitted Sync/Discovery beacons
+    */
+    u8 config_random_factor_force;
+    u8 random_factor_force_val; // default value 0x00
+    /*
+       1 byte quantity which forces the HC for all transmitted Sync and
+       Discovery Beacon NO matter the real HC being received over the
+       air.
+    */
+    u8 config_hop_count_force;
+    u8 hop_count_force_val; // default value of 0
+    /* NAN Post Connectivity Capability */
+    u8 config_conn_capability;
+    NanTransmitPostConnectivityCapability conn_capability_val;
+    /* NAN Post Discover Capability */
+    u8 num_config_discovery_attr;
+    NanTransmitPostDiscovery discovery_attr_val[NAN_MAX_POSTDISCOVERY_LEN];
+    /* NAN Further availability Map */
+    u8 config_fam;
+    NanFurtherAvailabilityMap fam_val;
+    /* Configure 2.4/5GHz DW */
+    NanConfigDW config_dw;
+    /*
+       By default discovery MAC address randomization is enabled
+       and default interval value is 30 minutes i.e. 1800 seconds.
+       The value 0 is used to disable MAC addr randomization.
+    */
+    u8 config_disc_mac_addr_randomization;
+    u32 disc_mac_addr_rand_interval_sec; // default value of 30 minutes
+
+    /*
+      Set/Enable corresponding bits to disable Discovery indications:
+      BIT0 - Disable Discovery MAC Address Event.
+      BIT1 - Disable Started Cluster Event.
+      BIT2 - Disable Joined Cluster Event.
+    */
+    u8 discovery_indication_cfg; // default value of 0
+    /*
+       BIT 0 is used to specify to include Service IDs in Sync/Discovery beacons
+       0 - Do not include SIDs in any beacons
+       1 - Include SIDs in all beacons.
+       Rest 7 bits are count field which allows control over the number of SIDs
+       included in the Beacon.  0 means to include as many SIDs that fit into
+       the maximum allow Beacon frame size
+    */
+    u8 config_subscribe_sid_beacon;
+    u32 subscribe_sid_beacon_val; // default value 0x0
+    /*
+       Discovery Beacon Interval config.
+       Default value is 128 msec in 2G DW and 176 msec in 2G/5G DW.
+       When 0 value is passed it is reset to default value of 128 or 176 msec.
+    */
+    u8 config_discovery_beacon_int;
+    u32 discovery_beacon_interval;
+    /*
+       Enable Number of Spatial Streams.
+       This is NAN Power Optimization feature for NAN discovery.
+    */
+    u8 config_nss;
+    // default value is implementation specific and passing 0 sets it to default
+    u32 nss;
+    /*
+       Enable device level NAN Ranging feature.
+       0 - Disable
+       1 - Enable
+    */
+    u8 config_enable_ranging;
+    u32 enable_ranging;
+    /*
+       Enable/Disable DW Early termination.
+       0 - Disable
+       1 - Enable
+    */
+    u8 config_dw_early_termination;
+    u32 enable_dw_termination;
+    /*
+       Indicate whether to use NDPE attribute to bring-up TCP/IP connection
+       If config_ndpe_attr is not configured, the default behavior is
+       not using NDPE attr, and the capability is not advertised.
+       0 - Not use
+       1 - Use
+    */
+    u8 config_ndpe_attr;
+    u32 use_ndpe_attr;
+    /*
+            Enable NAN v3.1 instant communication mode.
+            0 - Disable
+            1 - Enable
+    */
+    u8 config_enable_instant_mode;
+    u32 enable_instant_mode;
+    /*
+        Config NAN v3.1 instant communication channel selected over NFC/OOB method.
+        If dual band is supported default channel is 149 or 44 as per regulatory domain,
+        else channel 6 (send frequency in MHz).
+        Sometimes depending on country code retrictions, even 149/44 may be restricted
+        in those cases instant channel will be operational only in 2.4GHz.
+        Use wifi_get_usable_channels() API to get supported bands/channels before
+        Instant mode NFC handshake is triggered
+    */
+    u8 config_instant_mode_channel;
+    wifi_channel instant_mode_channel;
+    /*
+       Config cluster ID with the cluster ID selected over NFC/OOB method.
+    */
+    u8 config_cluster_id;
+    u16 cluster_id_val; // default value 0x0
+} NanConfigRequest;
+
+/*
+  TCA Structure
+  The Discovery Engine can be configured to send up Events whenever a configured
+  Threshold Crossing Alert (TCA) Type crosses an integral threshold in a particular direction.
+*/
+typedef struct {
+    NanTcaType tca_type; /* Nan Protocol Threshold Crossing Alert (TCA) Codes */
+
+    /* flag which control whether or not an event is generated for the Rising direction */
+    u8 rising_direction_evt_flag; /* 0 - no event, 1 - event */
+
+    /* flag which control whether or not an event is generated for the Falling direction */
+    u8 falling_direction_evt_flag;/* 0 - no event, 1 - event */
+
+    /* flag which requests a previous TCA request to be cleared from the DE */
+    u8 clear;/*0= Do not clear the TCA, 1=Clear the TCA */
+
+    /* 32 bit value which represents the threshold to be used.*/
+    u32 threshold;
+} NanTCARequest;
+
+/*
+  Beacon Sdf Payload Structure
+  The Discovery Engine can be configured to publish vendor specific attributes as part of
+  beacon or service discovery frame transmitted as part of this request..
+*/
+typedef struct {
+    /*
+       NanVendorAttribute will have the Vendor Specific Attribute which the
+       vendor wants to publish as part of Discovery or Sync or Service discovery frame
+    */
+    NanTransmitVendorSpecificAttribute vsa;
+} NanBeaconSdfPayloadRequest;
+
+/* Publish statistics. */
+typedef struct
+{
+    u32 validPublishServiceReqMsgs;
+    u32 validPublishServiceRspMsgs;
+    u32 validPublishServiceCancelReqMsgs;
+    u32 validPublishServiceCancelRspMsgs;
+    u32 validPublishRepliedIndMsgs;
+    u32 validPublishTerminatedIndMsgs;
+    u32 validActiveSubscribes;
+    u32 validMatches;
+    u32 validFollowups;
+    u32 invalidPublishServiceReqMsgs;
+    u32 invalidPublishServiceCancelReqMsgs;
+    u32 invalidActiveSubscribes;
+    u32 invalidMatches;
+    u32 invalidFollowups;
+    u32 publishCount;
+    u32 publishNewMatchCount;
+    u32 pubsubGlobalNewMatchCount;
+} NanPublishStats;
+
+/* Subscribe statistics. */
+typedef struct
+{
+    u32 validSubscribeServiceReqMsgs;
+    u32 validSubscribeServiceRspMsgs;
+    u32 validSubscribeServiceCancelReqMsgs;
+    u32 validSubscribeServiceCancelRspMsgs;
+    u32 validSubscribeTerminatedIndMsgs;
+    u32 validSubscribeMatchIndMsgs;
+    u32 validSubscribeUnmatchIndMsgs;
+    u32 validSolicitedPublishes;
+    u32 validMatches;
+    u32 validFollowups;
+    u32 invalidSubscribeServiceReqMsgs;
+    u32 invalidSubscribeServiceCancelReqMsgs;
+    u32 invalidSubscribeFollowupReqMsgs;
+    u32 invalidSolicitedPublishes;
+    u32 invalidMatches;
+    u32 invalidFollowups;
+    u32 subscribeCount;
+    u32 bloomFilterIndex;
+    u32 subscribeNewMatchCount;
+    u32 pubsubGlobalNewMatchCount;
+} NanSubscribeStats;
+
+/* NAN DW Statistics*/
+typedef struct
+{
+    /* RX stats */
+    u32 validFrames;
+    u32 validActionFrames;
+    u32 validBeaconFrames;
+    u32 ignoredActionFrames;
+    u32 ignoredBeaconFrames;
+    u32 invalidFrames;
+    u32 invalidActionFrames;
+    u32 invalidBeaconFrames;
+    u32 invalidMacHeaders;
+    u32 invalidPafHeaders;
+    u32 nonNanBeaconFrames;
+
+    u32 earlyActionFrames;
+    u32 inDwActionFrames;
+    u32 lateActionFrames;
+
+    /* TX stats */
+    u32 framesQueued;
+    u32 totalTRSpUpdates;
+    u32 completeByTRSp;
+    u32 completeByTp75DW;
+    u32 completeByTendDW;
+    u32 lateActionFramesTx;
+} NanDWStats;
+
+/* NAN MAC Statistics. */
+typedef struct
+{
+    /* RX stats */
+    u32 validFrames;
+    u32 validActionFrames;
+    u32 validBeaconFrames;
+    u32 ignoredActionFrames;
+    u32 ignoredBeaconFrames;
+    u32 invalidFrames;
+    u32 invalidActionFrames;
+    u32 invalidBeaconFrames;
+    u32 invalidMacHeaders;
+    u32 invalidPafHeaders;
+    u32 nonNanBeaconFrames;
+
+    u32 earlyActionFrames;
+    u32 inDwActionFrames;
+    u32 lateActionFrames;
+
+    /* TX stats */
+    u32 framesQueued;
+    u32 totalTRSpUpdates;
+    u32 completeByTRSp;
+    u32 completeByTp75DW;
+    u32 completeByTendDW;
+    u32 lateActionFramesTx;
+
+    u32 twIncreases;
+    u32 twDecreases;
+    u32 twChanges;
+    u32 twHighwater;
+    u32 bloomFilterIndex;
+} NanMacStats;
+
+/* NAN Sync Statistics*/
+typedef struct
+{
+    u64 currTsf;
+    u64 myRank;
+    u64 currAmRank;
+    u64 lastAmRank;
+    u32 currAmBTT;
+    u32 lastAmBTT;
+    u8  currAmHopCount;
+    u8  currRole;
+    u16 currClusterId;
+
+    u64 timeSpentInCurrRole;
+    u64 totalTimeSpentAsMaster;
+    u64 totalTimeSpentAsNonMasterSync;
+    u64 totalTimeSpentAsNonMasterNonSync;
+    u32 transitionsToAnchorMaster;
+    u32 transitionsToMaster;
+    u32 transitionsToNonMasterSync;
+    u32 transitionsToNonMasterNonSync;
+    u32 amrUpdateCount;
+    u32 amrUpdateRankChangedCount;
+    u32 amrUpdateBTTChangedCount;
+    u32 amrUpdateHcChangedCount;
+    u32 amrUpdateNewDeviceCount;
+    u32 amrExpireCount;
+    u32 mergeCount;
+    u32 beaconsAboveHcLimit;
+    u32 beaconsBelowRssiThresh;
+    u32 beaconsIgnoredNoSpace;
+    u32 beaconsForOurCluster;
+    u32 beaconsForOtherCluster;
+    u32 beaconCancelRequests;
+    u32 beaconCancelFailures;
+    u32 beaconUpdateRequests;
+    u32 beaconUpdateFailures;
+    u32 syncBeaconTxAttempts;
+    u32 syncBeaconTxFailures;
+    u32 discBeaconTxAttempts;
+    u32 discBeaconTxFailures;
+    u32 amHopCountExpireCount;
+    u32 ndpChannelFreq;
+    u32 ndpChannelFreq2;
+    u32 schedUpdateChannelFreq;
+} NanSyncStats;
+
+/* NAN Misc DE Statistics */
+typedef struct
+{
+    u32 validErrorRspMsgs;
+    u32 validTransmitFollowupReqMsgs;
+    u32 validTransmitFollowupRspMsgs;
+    u32 validFollowupIndMsgs;
+    u32 validConfigurationReqMsgs;
+    u32 validConfigurationRspMsgs;
+    u32 validStatsReqMsgs;
+    u32 validStatsRspMsgs;
+    u32 validEnableReqMsgs;
+    u32 validEnableRspMsgs;
+    u32 validDisableReqMsgs;
+    u32 validDisableRspMsgs;
+    u32 validDisableIndMsgs;
+    u32 validEventIndMsgs;
+    u32 validTcaReqMsgs;
+    u32 validTcaRspMsgs;
+    u32 validTcaIndMsgs;
+    u32 invalidTransmitFollowupReqMsgs;
+    u32 invalidConfigurationReqMsgs;
+    u32 invalidStatsReqMsgs;
+    u32 invalidEnableReqMsgs;
+    u32 invalidDisableReqMsgs;
+    u32 invalidTcaReqMsgs;
+} NanDeStats;
+
+/* Publish Response Message structure */
+typedef struct {
+    u16 publish_id;
+} NanPublishResponse;
+
+/* Subscribe Response Message structure */
+typedef struct {
+    u16 subscribe_id;
+} NanSubscribeResponse;
+
+/*
+  Stats Response Message structure
+  The Discovery Engine response to a request by the Host for statistics.
+*/
+typedef struct {
+    NanStatsType stats_type;
+    union {
+        NanPublishStats publish_stats;
+        NanSubscribeStats subscribe_stats;
+        NanMacStats mac_stats;
+        NanSyncStats sync_stats;
+        NanDeStats de_stats;
+        NanDWStats dw_stats;
+    } data;
+} NanStatsResponse;
+
+/* Response returned for Initiators Data request */
+typedef struct {
+    /*
+      Unique token Id generated on the initiator
+      side used for a NDP session between two NAN devices
+    */
+    NanDataPathId ndp_instance_id;
+} NanDataPathRequestResponse;
+
+/* Response returned for Initiators pairing request */
+typedef struct {
+    /*
+      Unique token Id generated on the initiator
+      side used for a pairing session between two NAN devices
+    */
+    u32 paring_instance_id;
+} NanPairingRequestResponse;
+
+/* Response returned for Initiators bootstrapping request */
+typedef struct {
+    /*
+      Unique token Id generated on the initiator
+      side used for a bootstrapping session between two NAN devices
+    */
+    u32 bootstrapping_instance_id;
+} NanBootstrappingRequestResponse;
+
+/*
+  NAN Response messages
+*/
+typedef struct {
+    NanStatusType status; /* contains the result code */
+    char nan_error[NAN_ERROR_STR_LEN]; /* Describe the NAN error type */
+    NanResponseType response_type; /* NanResponseType Definitions */
+    union {
+        NanPublishResponse publish_response;
+        NanSubscribeResponse subscribe_response;
+        NanStatsResponse stats_response;
+        NanDataPathRequestResponse data_request_response;
+        NanCapabilities nan_capabilities;
+        NanPairingRequestResponse pairing_request_response;
+        NanBootstrappingRequestResponse bootstrapping_request_response;
+    } body;
+} NanResponseMsg;
+
+/*
+  Publish Replied Indication
+  The PublishRepliedInd Message is sent by the DE when an Active Subscribe is
+  received over the air and it matches a Solicited PublishServiceReq which had
+  been created with the replied_event_flag set.
+*/
+typedef struct {
+    /*
+       A 32 bit Requestor Instance Id which is sent to the Application.
+       This Id will be sent in any subsequent UnmatchInd/FollowupInd
+       messages
+    */
+    u32 requestor_instance_id;
+    u8 addr[NAN_MAC_ADDR_LEN];
+    /*
+       If RSSI filtering was configured in NanPublishRequest then this
+       field will contain the received RSSI value. 0 if not
+    */
+    u8 rssi_value;
+} NanPublishRepliedInd;
+
+/*
+  Publish Terminated
+  The PublishTerminatedInd message is sent by the DE whenever a Publish
+  terminates from a user-specified timeout or a unrecoverable error in the DE.
+*/
+typedef struct {
+    /* Id returned during the initial Publish */
+    u16 publish_id;
+    /*
+      For all user configured termination NAN_STATUS_SUCCESS
+      and no other reasons expected from firmware.
+    */
+    NanStatusType reason;
+    char nan_reason[NAN_ERROR_STR_LEN]; /* Describe the NAN reason type */
+} NanPublishTerminatedInd;
+
+/* The NIRA used to identify the pairing devices*/
+typedef struct {
+    u8 nonce[NAN_IDENTITY_NONCE_LEN];
+    u8 tag[NAN_IDENTITY_TAG_LEN];
+} NanIdentityResolutionAttribute;
+
+/*
+  Match Indication
+  The MatchInd message is sent once per responding MAC address whenever
+  the Discovery Engine detects a match for a previous SubscribeServiceReq
+  or PublishServiceReq.
+*/
+typedef struct {
+    /* Publish or Subscribe Id of an earlier Publish/Subscribe */
+    u16 publish_subscribe_id;
+    /*
+       A 32 bit Requestor Instance Id which is sent to the Application.
+       This Id will be sent in any subsequent UnmatchInd/FollowupInd
+       messages
+    */
+    u32 requestor_instance_id;
+    u8 addr[NAN_MAC_ADDR_LEN];
+
+    /*
+       Sequence of octets which were received in a Discovery Frame matching the
+       Subscribe Request.
+    */
+    u16 service_specific_info_len;
+    u8 service_specific_info[NAN_MAX_SERVICE_SPECIFIC_INFO_LEN];
+
+    /*
+       Ordered sequence of <length, value> pairs received in the Discovery Frame
+       matching the Subscribe Request.
+    */
+    u16 sdf_match_filter_len;
+    u8 sdf_match_filter[NAN_MAX_MATCH_FILTER_LEN];
+
+    /*
+       flag to indicate if the Match occurred in a Beacon Frame or in a
+       Service Discovery Frame.
+         0 - Match occured in a Service Discovery Frame
+         1 - Match occured in a Beacon Frame
+    */
+    u8 match_occured_flag;
+
+    /*
+       flag to indicate FW is out of resource and that it can no longer
+       track this Service Name. The Host still need to send the received
+       Match_Handle but duplicate MatchInd messages may be received on
+       this Handle until the resource frees up.
+         0 - FW is caching this match
+         1 - FW is unable to cache this match
+    */
+    u8 out_of_resource_flag;
+
+    /*
+       If RSSI filtering was configured in NanSubscribeRequest then this
+       field will contain the received RSSI value. 0 if not.
+       All rssi values should be specified without sign.
+       For eg: -70dBm should be specified as 70.
+    */
+    u8 rssi_value;
+
+    /*
+       optional attributes. Each optional attribute is associated with a flag
+       which specifies whether the attribute is valid or not
+    */
+    /* NAN Post Connectivity Capability received */
+    u8 is_conn_capability_valid;
+    NanReceivePostConnectivityCapability conn_capability;
+
+    /* NAN Post Discover Capability */
+    u8 num_rx_discovery_attr;
+    NanReceivePostDiscovery discovery_attr[NAN_MAX_POSTDISCOVERY_LEN];
+
+    /* NAN Further availability Map */
+    u8 num_chans;
+    NanFurtherAvailabilityChannel famchan[NAN_MAX_FAM_CHANNELS];
+
+    /* NAN Cluster Attribute */
+    u8 cluster_attribute_len;
+    u8 cluster_attribute[NAN_MAX_CLUSTER_ATTRIBUTE_LEN];
+
+    /* NAN Cipher Suite */
+    u32 peer_cipher_type;
+
+    /* Security Context Identifiers length */
+    u32 scid_len;
+    /*
+       Security Context Identifier attribute contains PMKID
+       shall be included in NDP setup and response messages.
+       Security Context Identifier, Identifies the Security
+       Context. For NAN Shared Key Cipher Suite, this field
+       contains the 16 octet PMKID identifying the PMK used
+       for setting up the Secure Data Path.
+    */
+    u8 scid[NAN_MAX_SCID_BUF_LEN];
+
+    /* Peer service discovery extended attributes */
+    NanSdeaCtrlParams peer_sdea_params;
+
+    /*
+      Ranging indication and NanMatchAlg are not tied.
+      Ex: NanMatchAlg can indicate Match_ONCE, but ranging
+      indications can be continuous. All ranging indications
+      depend on SDEA control parameters of ranging required for
+      continuous, and ingress/egress values in the ranging config.
+      Ranging indication data is notified if:
+      1) Ranging required is enabled in SDEA.
+         range info notified continuous.
+      2) if range_limit ingress/egress MASKS are enabled
+         notify once for ingress >= ingress_distance
+         and egress <= egress_distance, same for ingress_egress_both
+      3) if the Awake DW intervals are higher than the ranging intervals,
+         priority is given to the device DW intervalsi.
+    */
+    /*
+      Range Info includes:
+      1) distance to the NAN device with the MAC address indicated
+         with ranged mac address.
+      2) Ranging event matching the configuration of continuous/ingress/egress.
+    */
+    NanRangeInfo range_info;
+
+    /*
+       Sequence of values indicating the service specific info in SDEA
+    */
+    u16 sdea_service_specific_info_len;
+    u8 sdea_service_specific_info[NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN];
+
+    /*
+      The config for Nan pairing set by the peer
+    */
+    NanPairingConfig peer_pairing_config;
+
+    /*
+      The NIRA from peer for Nan pairing verification
+    */
+    NanIdentityResolutionAttribute nira;
+} NanMatchInd;
+
+/*
+  MatchExpired Indication
+  The MatchExpiredInd message is sent whenever the Discovery Engine detects that
+  a previously Matched Service has been gone for too long. If the previous
+  MatchInd message for this Publish/Subscribe Id had the out_of_resource_flag
+  set then this message will not be received
+*/
+typedef struct {
+    /* Publish or Subscribe Id of an earlier Publish/Subscribe */
+    u16 publish_subscribe_id;
+    /*
+       32 bit value sent by the DE in a previous
+       MatchInd/FollowupInd to the application.
+    */
+    u32 requestor_instance_id;
+} NanMatchExpiredInd;
+
+/*
+  Subscribe Terminated
+  The SubscribeTerminatedInd message is sent by the DE whenever a
+  Subscribe terminates from a user-specified timeout or a unrecoverable error in the DE.
+*/
+typedef struct {
+    /* Id returned during initial Subscribe */
+    u16 subscribe_id;
+    /*
+      For all user configured termination NAN_STATUS_SUCCESS
+      and no other reasons expected from firmware.
+    */
+    NanStatusType reason;
+    char nan_reason[NAN_ERROR_STR_LEN]; /* Describe the NAN reason type */
+} NanSubscribeTerminatedInd;
+
+/*
+  Followup Indication Message
+  The FollowupInd message is sent by the DE to the Host whenever it receives a
+  Followup message from another peer.
+*/
+typedef struct {
+    /* Publish or Subscribe Id of an earlier Publish/Subscribe */
+    u16 publish_subscribe_id;
+    /*
+       A 32 bit Requestor instance Id which is sent to the Application.
+       This Id will be used in subsequent UnmatchInd/FollowupInd messages.
+    */
+    u32 requestor_instance_id;
+    u8 addr[NAN_MAC_ADDR_LEN];
+
+    /* Flag which the DE uses to decide if received in a DW or a FAW*/
+    u8 dw_or_faw; /* 0=Received  in a DW, 1 = Received in a FAW*/
+
+    /*
+       Sequence of values which further specify the published service beyond
+       the service name
+    */
+    u16 service_specific_info_len;
+    u8 service_specific_info[NAN_MAX_SERVICE_SPECIFIC_INFO_LEN];
+
+    /*
+       Sequence of values indicating the service specific info in SDEA
+    */
+    u16 sdea_service_specific_info_len;
+    u8 sdea_service_specific_info[NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN];
+} NanFollowupInd;
+
+/*
+   Event data notifying the Mac address of the Discovery engine.
+   which is reported as one of the Discovery engine event
+*/
+typedef struct {
+    u8 addr[NAN_MAC_ADDR_LEN];
+} NanMacAddressEvent;
+
+/*
+   Event data notifying the Cluster address of the cluster
+   which is reported as one of the Discovery engine event
+*/
+typedef struct {
+    u8 addr[NAN_MAC_ADDR_LEN];
+} NanClusterEvent;
+
+/*
+  Discovery Engine Event Indication
+  The Discovery Engine can inform the Host when significant events occur
+  The data following the EventId is dependent upon the EventId type.
+  In other words, each new event defined will carry a different
+  structure of information back to the host.
+*/
+typedef struct {
+    NanDiscEngEventType event_type; /* NAN Protocol Event Codes */
+    union {
+        /*
+           MacAddressEvent which will have 6 byte mac address
+           of the Discovery engine.
+        */
+        NanMacAddressEvent mac_addr;
+        /*
+           Cluster Event Data which will be obtained when the
+           device starts a new cluster or joins a cluster.
+           The event data will have 6 byte octet string of the
+           cluster started or joined.
+        */
+        NanClusterEvent cluster;
+    } data;
+} NanDiscEngEventInd;
+
+/* Cluster size TCA event*/
+typedef struct {
+    /* size of the cluster*/
+    u32 cluster_size;
+} NanTcaClusterEvent;
+
+/*
+  NAN TCA Indication
+  The Discovery Engine can inform the Host when significant events occur.
+  The data following the TcaId is dependent upon the TcaId type.
+  In other words, each new event defined will carry a different structure
+  of information back to the host.
+*/
+typedef struct {
+    NanTcaType tca_type;
+    /* flag which defines if the configured Threshold has risen above the threshold */
+    u8 rising_direction_evt_flag; /* 0 - no event, 1 - event */
+
+    /* flag which defines if the configured Threshold has fallen below the threshold */
+    u8 falling_direction_evt_flag;/* 0 - no event, 1 - event */
+    union {
+        /*
+           This event in obtained when the cluser size threshold
+           is crossed. Event will have the cluster size
+        */
+        NanTcaClusterEvent cluster;
+    } data;
+} NanTCAInd;
+
+/*
+  NAN Disabled Indication
+  The NanDisableInd message indicates to the upper layers that the Discovery
+  Engine has flushed all state and has been shutdown.  When this message is received
+  the DE is guaranteed to have left the NAN cluster it was part of and will have terminated
+  any in progress Publishes or Subscribes.
+*/
+typedef struct {
+    /*
+      Following reasons expected:
+      NAN_STATUS_SUCCESS
+      NAN_STATUS_UNSUPPORTED_CONCURRENCY_NAN_DISABLED
+    */
+    NanStatusType reason;
+    char nan_reason[NAN_ERROR_STR_LEN]; /* Describe the NAN reason type */
+} NanDisabledInd;
+
+/*
+  NAN Beacon or SDF Payload Indication
+  The NanBeaconSdfPayloadInd message indicates to the upper layers that information
+  elements were received either in a Beacon or SDF which needs to be delivered
+  outside of a Publish/Subscribe Handle.
+*/
+typedef struct {
+    /* The MAC address of the peer which sent the attributes.*/
+    u8 addr[NAN_MAC_ADDR_LEN];
+    /*
+       Optional attributes. Each optional attribute is associated with a flag
+       which specifies whether the attribute is valid or not
+    */
+    /* NAN Receive Vendor Specific Attribute*/
+    u8 is_vsa_received;
+    NanReceiveVendorSpecificAttribute vsa;
+
+    /* NAN Beacon or SDF Payload Received*/
+    u8 is_beacon_sdf_payload_received;
+    NanBeaconSdfPayloadReceive data;
+} NanBeaconSdfPayloadInd;
+
+/*
+  Event Indication notifying the
+  transmit followup in progress
+*/
+typedef struct {
+   transaction_id id;
+   /*
+     Following reason codes returned:
+     NAN_STATUS_SUCCESS
+     NAN_STATUS_NO_OTA_ACK
+     NAN_STATUS_PROTOCOL_FAILURE
+   */
+   NanStatusType reason;
+   char nan_reason[NAN_ERROR_STR_LEN]; /* Describe the NAN reason type */
+} NanTransmitFollowupInd;
+
+/*
+  Data request Initiator/Responder
+  app/service related info
+*/
+typedef struct {
+    u16 ndp_app_info_len;
+    u8 ndp_app_info[NAN_DP_MAX_APP_INFO_LEN];
+} NanDataPathAppInfo;
+
+/* QoS configuration */
+typedef enum {
+    NAN_DP_CONFIG_NO_QOS = 0,
+    NAN_DP_CONFIG_QOS
+} NanDataPathQosCfg;
+
+/* Configuration params of Data request Initiator/Responder */
+typedef struct {
+    /* Status Indicating Security/No Security */
+    NanDataPathSecurityCfgStatus security_cfg;
+    NanDataPathQosCfg qos_cfg;
+} NanDataPathCfg;
+
+/* Nan Data Path Initiator requesting a data session */
+typedef struct {
+    /*
+     Unique Instance Id identifying the Responder's service.
+     This is same as publish_id notified on the subscribe side
+     in a publish/subscribe scenario
+    */
+    u32 requestor_instance_id; /* Value 0 for no publish/subscribe */
+
+    /* Config flag for channel request */
+    NanDataPathChannelCfg channel_request_type;
+    /* Channel frequency in MHz to start data-path */
+    wifi_channel channel;
+    /*
+      Discovery MAC addr of the publisher/peer
+    */
+    u8 peer_disc_mac_addr[NAN_MAC_ADDR_LEN];
+    /*
+     Interface name on which this NDP session is to be started.
+     This will be the same interface name provided during interface
+     create.
+    */
+    char ndp_iface[IFNAMSIZ+1];
+    /* Initiator/Responder Security/QoS configuration */
+    NanDataPathCfg ndp_cfg;
+    /* App/Service information of the Initiator */
+    NanDataPathAppInfo app_info;
+    /* NAN Cipher Suite Type */
+    u32 cipher_type;
+    /*
+       Nan Security Key Info is optional in Discovery phase.
+       PMK or passphrase info can be passed during
+       the NDP session.
+    */
+    NanSecurityKeyInfo key_info;
+    /* length of service name */
+    u32 service_name_len;
+    /*
+       UTF-8 encoded string identifying the service name.
+       The service name field is only used if a Nan discovery
+       is not associated with the NDP (out-of-band discovery).
+    */
+    u8 service_name[NAN_MAX_SERVICE_NAME_LEN];
+
+    /* Security Context Identifiers length */
+    u32 scid_len;
+    /*
+       Security Context Identifier attribute contains PMKID
+       shall be included in NDP setup and response messages.
+       Security Context Identifier, Identifies the Security
+       Context. For NAN Shared Key Cipher Suite, this field
+       contains the 16 octet PMKID identifying the PMK used
+       for setting up the Secure Data Path.
+    */
+    u8 scid[NAN_MAX_SCID_BUF_LEN];
+
+    /* Publish or Subscribe Id of an earlier Publish/Subscribe */
+    u16 publish_subscribe_id;
+
+    /* configure CSIA (Cipher Suite Information attribute) capability to specify GTK, IGTK, BIGTK
+       are supported or not
+    */
+    u8 csia_capabilities;
+
+    /* configure GTK(Group Transient Key) protection required or not */
+    u8 gtk_protection;
+
+} NanDataPathInitiatorRequest;
+
+/*
+  Data struct to initiate a data response on the responder side
+  for an indication received with a data request
+*/
+typedef struct {
+    /*
+      Unique token Id generated on the initiator/responder
+      side used for a NDP session between two NAN devices
+    */
+    NanDataPathId ndp_instance_id;
+    /*
+     Interface name on which this NDP session is to be started.
+     This will be the same interface name provided during interface
+     create.
+    */
+    char ndp_iface[IFNAMSIZ+1];
+    /* Initiator/Responder Security/QoS configuration */
+    NanDataPathCfg ndp_cfg;
+    /* App/Service information of the responder */
+    NanDataPathAppInfo app_info;
+    /* Response Code indicating ACCEPT/REJECT/DEFER */
+    NanDataPathResponseCode rsp_code;
+    /* NAN Cipher Suite Type */
+    u32 cipher_type;
+    /*
+       Nan Security Key Info is optional in Discovery phase.
+       PMK or passphrase info can be passed during
+       the NDP session.
+    */
+    NanSecurityKeyInfo key_info;
+    /* length of service name */
+    u32 service_name_len;
+    /*
+       UTF-8 encoded string identifying the service name.
+       The service name field is only used if a Nan discovery
+       is not associated with the NDP (out-of-band discovery).
+    */
+    u8 service_name[NAN_MAX_SERVICE_NAME_LEN];
+
+    /* Security Context Identifiers length */
+    u32 scid_len;
+    /*
+       Security Context Identifier attribute contains PMKID
+       shall be included in NDP setup and response messages.
+       Security Context Identifier, Identifies the Security
+       Context. For NAN Shared Key Cipher Suite, this field
+       contains the 16 octet PMKID identifying the PMK used
+       for setting up the Secure Data Path.
+    */
+    u8 scid[NAN_MAX_SCID_BUF_LEN];
+
+    /* Publish or Subscribe Id of an earlier Publish/Subscribe */
+    u16 publish_subscribe_id;
+
+    /*
+      Discovery MAC addr of the publisher/peer
+    */
+    u8 peer_disc_mac_addr[NAN_MAC_ADDR_LEN];
+
+    /* configure CSIA (Cipher Suite Information attribute) capability to specify GTK, IGTK, BIGTK
+       are supported or not
+    */
+    u8 csia_capabilities;
+
+    /* configure GTK(Group Transient Key) protection required or not */
+    u8 gtk_protection;
+} NanDataPathIndicationResponse;
+
+/* Sub slot parameters */
+typedef struct {
+    u8 entry_control;
+    u16 time_bitmap_control;
+    u32 time_bitmap;
+} NanS3Params;
+
+/* NDP termination info */
+typedef struct {
+    u8 num_ndp_instances;
+    /*
+      Unique token Id generated on the initiator/responder side
+      used for a NDP session between two NAN devices
+    */
+    NanDataPathId ndp_instance_id[];
+} NanDataPathEndRequest;
+
+/*
+  Event indication received on the
+  responder side when a Nan Data request or
+  NDP session is initiated on the Initiator side
+*/
+typedef struct {
+    /*
+      Unique Instance Id corresponding to a service/session.
+      This is similar to the publish_id generated on the
+      publisher side
+    */
+    u16 service_instance_id;
+    /* Discovery MAC addr of the peer/initiator */
+    u8 peer_disc_mac_addr[NAN_MAC_ADDR_LEN];
+    /*
+      Unique token Id generated on the initiator/responder side
+      used for a NDP session between two NAN devices
+    */
+    NanDataPathId ndp_instance_id;
+    /* Initiator/Responder Security/QoS configuration */
+    NanDataPathCfg ndp_cfg;
+    /* App/Service information of the initiator */
+    NanDataPathAppInfo app_info;
+
+    /* Security Context Identifiers length */
+    u32 scid_len;
+    /*
+       Security Context Identifier attribute contains PMKID
+       shall be included in NDP setup and response messages.
+       Security Context Identifier, Identifies the Security
+       Context. For NAN Shared Key Cipher Suite, this field
+       contains the 16 octet PMKID identifying the PMK used
+       for setting up the Secure Data Path.
+    */
+    u8 scid[NAN_MAX_SCID_BUF_LEN];
+
+    /* configure CSIA (Cipher Suite Information attribute) capability to specify GTK, IGTK, BIGTK
+       are supported or not
+    */
+    u8 csia_capabilities;
+
+    /* configure GTK(Group Transient Key) protection required or not */
+    u8 gtk_protection;
+} NanDataPathRequestInd;
+
+/*
+ Event indication of data confirm is received on both
+ initiator and responder side confirming a NDP session
+*/
+typedef struct {
+    /*
+      Unique token Id generated on the initiator/responder side
+      used for a NDP session between two NAN devices
+    */
+    NanDataPathId ndp_instance_id;
+    /*
+      NDI mac address of the peer
+      (required to derive target ipv6 address)
+    */
+    u8 peer_ndi_mac_addr[NAN_MAC_ADDR_LEN];
+    /* App/Service information of Initiator/Responder */
+    NanDataPathAppInfo app_info;
+    /* Response code indicating ACCEPT/REJECT/DEFER */
+    NanDataPathResponseCode rsp_code;
+    /*
+      Reason code indicating the cause for REJECT.
+      NAN_STATUS_SUCCESS and NAN_STATUS_PROTOCOL_FAILURE are
+      expected reason codes.
+    */
+    NanStatusType reason_code;
+    /* Number of channels for which info is indicated */
+    u32 num_channels;
+    /*
+      Data indicating the Channel list and BW of the channel.
+    */
+    NanChannelInfo channel_info[NAN_MAX_CHANNEL_INFO_SUPPORTED];
+} NanDataPathConfirmInd;
+
+/*
+ Event indication of schedule update is received on both
+ initiator and responder when a schedule change occurs
+*/
+typedef struct {
+    /*
+      NMI mac address
+    */
+    u8 peer_mac_addr[NAN_MAC_ADDR_LEN];
+    /*
+      Reason code indicating the cause of schedule update.
+      BIT_0 NSS Update
+      BIT_1 Channel list update
+    */
+    u32 schedule_update_reason_code;
+    /* Number of channels for which info is indicated */
+    u32 num_channels;
+    /*
+      Data indicating the Channel list and BW of the channel.
+    */
+    NanChannelInfo channel_info[NAN_MAX_CHANNEL_INFO_SUPPORTED];
+    /* Number of NDP instance Ids */
+    u8 num_ndp_instances;
+    /*
+      Unique token Id generated on the initiator/responder side
+      used for a NDP session between two NAN devices
+    */
+    NanDataPathId ndp_instance_id[];
+} NanDataPathScheduleUpdateInd;
+
+/*
+  Event indication received on the
+  initiator/responder side terminating
+  a NDP session
+*/
+typedef struct {
+    u8 num_ndp_instances;
+    /*
+      Unique token Id generated on the initiator/responder side
+      used for a NDP session between two NAN devices
+    */
+    NanDataPathId ndp_instance_id[];
+} NanDataPathEndInd;
+
+/*
+  Event indicating Range Request received on the
+  Published side.
+*/
+typedef struct {
+    u16 publish_id;/* id is existing publish */
+    /* Range Requestor's MAC address */
+    u8 range_req_intf_addr[NAN_MAC_ADDR_LEN];
+} NanRangeRequestInd;
+
+/*
+  Event indicating Range report on the
+  Published side.
+*/
+typedef struct {
+    u16 publish_id;/* id is existing publish */
+    /* Range Requestor's MAC address */
+    u8 range_req_intf_addr[NAN_MAC_ADDR_LEN];
+    /*
+       Distance to the NAN device with the MAC address indicated
+       with ranged mac address.
+    */
+    u32 range_measurement_mm;
+} NanRangeReportInd;
+
+/*
+  NAN pairing initator request
+*/
+typedef struct {
+    /*
+       This Id is the Requestor Instance that is passed as
+       part of earlier MatchInd/FollowupInd message.
+    */
+    u32 requestor_instance_id;
+
+    /*
+      Discovery MAC addr of the publisher/peer
+    */
+    u8 peer_disc_mac_addr[NAN_MAC_ADDR_LEN];
+
+    /*
+      Indicate the pairing session is of setup or verification
+    */
+    NanPairingRequestType nan_pairing_request_type;
+
+    /*
+      whether the pairing is opportunistic or password
+    */
+    u8 is_opportunistic;
+
+    /*
+      Security key info used for the pairing setup or verification
+    */
+    NanSecurityKeyInfo key_info;
+    /*
+      AKM used for the pairing verification
+    */
+    NanAkm akm;
+
+    /*
+      Whether should cache the negotiated NIK/NPK for future verification
+    */
+    u8 enable_pairing_cache;
+
+    /*
+      The Identity key for pairing, can be used for pairing verification
+    */
+    u8 nan_identity_key[NAN_IDENTITY_KEY_LEN];
+
+    /*
+      NAN Cipher Suite Type
+    */
+    u32 cipher_type;
+
+} NanPairingRequest;
+
+/*
+  Data struct to initiate a pairing response on the responder side for an indication received with a
+  pairing request
+*/
+typedef struct {
+
+    /*
+      Unique token Id generated on the initiator/responder side
+      used for a pairing session between two NAN devices
+    */
+    u32 pairing_instance_id;
+
+    /*
+      Indicate the pairing session is setup or verification
+    */
+    NanPairingRequestType nan_pairing_request_type;
+
+    /* Response Code indicating ACCEPT/REJECT */
+    NanPairingResponseCode rsp_code;
+
+    /*
+      whether the pairing is opportunistic or password
+    */
+    u8 is_opportunistic;
+
+    /*
+      Security key info used for the pairing setup or verification
+    */
+    NanSecurityKeyInfo key_info;
+
+    /*
+      AKM used for the pairing verification
+    */
+    NanAkm akm;
+
+    /*
+      Whether should cache the negotiated NIK/NPK for future verification
+    */
+    u8 enable_pairing_cache;
+
+    /*
+      The Identity key for pairing, can be used for pairing verification
+    */
+    u8 nan_identity_key[NAN_IDENTITY_KEY_LEN];
+
+    /*
+      NAN Cipher Suite Type
+    */
+    u32 cipher_type;
+} NanPairingIndicationResponse;
+
+typedef struct {
+    /*
+      Unique token Id generated on the initiator/responder side
+      used for a pairing session between two NAN devices
+    */
+    u32 pairing_instance_id;
+} NanPairingEndRequest;
+
+/*
+  Event indication received on the responder side when a Nan pairing session is initiated on the
+  Initiator side
+*/
+typedef struct {
+    /* Publish instance id generated on Publisher side corresponding to a session */
+    u16 publish_subscribe_id;
+    /*
+      This Id is the Requestor Instance that is passed as
+      part of earlier MatchInd/FollowupInd message.
+    */
+    u32 requestor_instance_id;
+    /*
+      Unique Instance Id corresponding to a service/session.
+      This is similar to the publish_id generated on the
+      publisher side
+    */
+    u32 pairing_instance_id;
+    /* Discovery MAC addr of the peer/initiator */
+    u8 peer_disc_mac_addr[NAN_MAC_ADDR_LEN];
+    /* Indicate the pairing session is setup or verification */
+    NanPairingRequestType nan_pairing_request_type;
+    /* Whether should cache the negotiated NIK/NPK for future verification */
+    u8 enable_pairing_cache;
+    /* The NIRA from peer for Nan pairing verification */
+    NanIdentityResolutionAttribute nira;
+} NanPairingRequestInd;
+
+/*
+  The security info negotiate after the pairing setup for caching
+*/
+typedef struct {
+    /* The inentity key of peer device*/
+    u8 peer_nan_identity_key[NAN_IDENTITY_KEY_LEN];
+    /* The inentity key of local device*/
+    u8 local_nan_identity_key[NAN_IDENTITY_KEY_LEN];
+    /* The PMK excahnge between two devices*/
+    NanSecurityPmk npk;
+    /* The AKM used during the key exchange*/
+    NanAkm akm;
+    /* NAN Cipher Suite Type */
+    u32 cipher_type;
+} NpkSecurityAssociation;
+
+/*
+ Event indication of pairing confirm is received on both
+ initiator and responder side confirming a pairing session
+*/
+typedef struct {
+    /*
+      Unique token Id generated on the initiator/responder side
+      used for a pairing session between two NAN devices
+    */
+    u32 pairing_instance_id;
+    /* Response code indicating ACCEPT/REJECT */
+    NanPairingResponseCode rsp_code;
+    /*
+      Reason code indicating the cause for REJECT.
+      NAN_STATUS_SUCCESS and NAN_STATUS_PROTOCOL_FAILURE are
+      expected reason codes.
+    */
+    NanStatusType reason_code;
+    /*
+      Indicate the pairing session is setup or verification
+    */
+    NanPairingRequestType nan_pairing_request_type;
+    /* Whether should cache the negotiated NIK/NPK for future verification */
+    u8 enable_pairing_cache;
+    /*
+      The security association info negotiated in the pairing setup, used for future verification
+    */
+    NpkSecurityAssociation npk_security_association;
+} NanPairingConfirmInd;
+
+/*
+  NAN pairing bootstrapping initiator request
+*/
+typedef struct {
+    /* Publish or Subscribe Id of local Publish/Subscribe */
+    u16 publish_subscribe_id;
+
+    /*
+       This Id is the Requestor Instance that is passed as
+       part of earlier MatchInd/FollowupInd message.
+    */
+    u32 requestor_instance_id;
+
+    /*
+      Discovery MAC addr of the publisher/peer
+    */
+    u8 peer_disc_mac_addr[NAN_MAC_ADDR_LEN];
+
+    /* Proposed bootstrapping method */
+    u16 request_bootstrapping_method;
+
+    /*
+       Sequence of values which further specify the published service beyond
+       the service name.
+    */
+    u16 service_specific_info_len;
+    u8 service_specific_info[NAN_MAX_SERVICE_SPECIFIC_INFO_LEN];
+
+    /*
+       Sequence of values indicating the service specific info in SDEA
+       Used for service managed bootstrapping method
+    */
+    u16 sdea_service_specific_info_len;
+    u8 sdea_service_specific_info[NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN];
+
+    /* Indicates that this is comeback Bootstrapping request */
+    u8 comeback;
+
+    /* The length of cookie. */
+    u32 cookie_length;
+
+    /* Cookie for the follow up request */
+    u8 cookie[];
+
+} NanBootstrappingRequest;
+/*
+ NAN pairing bootstrapping response from responder to a initate request
+*/
+typedef struct {
+    /* Publish or Subscribe Id of local Publish/Subscribe */
+    u16 publish_subscribe_id;
+
+    /*
+       This Id is the Peer Instance that is passed as
+       part of earlier MatchInd/FollowupInd message.
+    */
+    u32 service_instance_id;
+
+    /* Discovery MAC addr of the peer/initiator */
+    u8 peer_disc_mac_addr[NAN_MAC_ADDR_LEN];
+
+    /*
+       Sequence of values which further specify the published service beyond
+       the service name.
+    */
+    u16 service_specific_info_len;
+    u8 service_specific_info[NAN_MAX_SERVICE_SPECIFIC_INFO_LEN];
+
+    /*
+       Sequence of values indicating the service specific info in SDEA
+       Used for service managed bootstrapping method
+    */
+    u16 sdea_service_specific_info_len;
+    u8 sdea_service_specific_info[NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN];
+
+    /* Response Code indicating ACCEPT/REJECT */
+    NanBootstrappingResponseCode rsp_code;
+
+    /* The delay of bootstrapping in seconds */
+    u32 come_back_delay;
+
+    /* The length of cookie. */
+    u32 cookie_length;
+
+    /* Cookie for the follow up response */
+    u8 cookie[];
+
+} NanBootstrappingIndicationResponse;
+
+/*
+  Event indication received on the responder side when a Nan bootsrapping session is initiated on
+  the Initiator side
+*/
+typedef struct {
+    /* Publish or Subscribe Id of an earlier Publish/Subscribe */
+    u16 publish_subscribe_id;
+    /*
+      Unique Instance Id corresponding to a service/session.
+      This is similar to the publish_id generated on the
+      publisher side
+    */
+    u32 bootstrapping_instance_id;
+    /*
+      This Id is the Requestor Instance that is passed as
+      part of earlier MatchInd/FollowupInd message.
+    */
+    u32 requestor_instance_id;
+    /* Discovery MAC addr of the peer/initiator */
+    u8 peer_disc_mac_addr[NAN_MAC_ADDR_LEN];
+    /* Proposed bootstrapping method from peer*/
+    u16 request_bootstrapping_method;
+
+} NanBootstrappingRequestInd;
+
+/*
+ Event indication of bootstapping confirm is received on both
+ initiator side confirming a bootstrapping method
+*/
+typedef struct {
+    /*
+      Unique token Id generated on the initiator/responder side
+      used for a bootstrapping session between two NAN devices
+    */
+    u32 bootstrapping_instance_id;
+    /* Response Code indicating ACCEPT/REJECT */
+    NanBootstrappingResponseCode rsp_code;
+    /*
+      Reason code indicating the cause for REJECT.
+      NAN_STATUS_SUCCESS and NAN_STATUS_PROTOCOL_FAILURE are
+      expected reason codes.
+    */
+    NanStatusType reason_code;
+    /* The delay of bootstrapping in seconds */
+    u32 come_back_delay;
+
+    /* The length of cookie. */
+    u32 cookie_length;
+
+    /* Cookie received from the comeback response */
+    u8 cookie[];
+
+} NanBootstrappingConfirmInd;
+
+/*
+ Event indication the device enter or exist the suspension mode
+*/
+typedef struct {
+    /* Indication the device is suspended or not */
+    bool is_suspended;
+} NanSuspensionModeChangeInd;
+
+/* Response and Event Callbacks */
+typedef struct {
+    /* NotifyResponse invoked to notify the status of the Request */
+    void (*NotifyResponse)(transaction_id id, NanResponseMsg* rsp_data);
+    /* Callbacks for various Events */
+    void (*EventPublishReplied)(NanPublishRepliedInd *event);
+    void (*EventPublishTerminated)(NanPublishTerminatedInd* event);
+    void (*EventMatch) (NanMatchInd* event);
+    void (*EventMatchExpired) (NanMatchExpiredInd* event);
+    void (*EventSubscribeTerminated) (NanSubscribeTerminatedInd* event);
+    void (*EventFollowup) (NanFollowupInd* event);
+    void (*EventDiscEngEvent) (NanDiscEngEventInd* event);
+    void (*EventDisabled) (NanDisabledInd* event);
+    void (*EventTca) (NanTCAInd* event);
+    void (*EventBeaconSdfPayload) (NanBeaconSdfPayloadInd* event);
+    void (*EventDataRequest)(NanDataPathRequestInd* event);
+    void (*EventDataConfirm)(NanDataPathConfirmInd* event);
+    void (*EventDataEnd)(NanDataPathEndInd* event);
+    void (*EventTransmitFollowup) (NanTransmitFollowupInd* event);
+    void (*EventRangeRequest) (NanRangeRequestInd* event);
+    void (*EventRangeReport) (NanRangeReportInd* event);
+    void (*EventScheduleUpdate) (NanDataPathScheduleUpdateInd* event);
+    void (*EventPairingRequest) (NanPairingRequestInd* event);
+    void (*EventPairingConfirm) (NanPairingConfirmInd* event);
+    void (*EventBootstrappingRequest) (NanBootstrappingRequestInd* event);
+    void (*EventBootstrappingConfirm) (NanBootstrappingConfirmInd* event);
+    void (*EventSuspensionModeChange) (NanSuspensionModeChangeInd* event);
+} NanCallbackHandler;
+
+/**@brief nan_enable_request
+ *        Enable NAN functionality
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param NanEnableRequest:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ *                      NAN_STATUS_SUCCESS
+ *                      NAN_STATUS_ALREADY_ENABLED
+ *                      NAN_STATUS_INVALID_PARAM
+ *                      NAN_STATUS_INTERNAL_FAILURE
+ *                      NAN_STATUS_PROTOCOL_FAILURE
+ *                      NAN_STATUS_NAN_NOT_ALLOWED
+ */
+wifi_error nan_enable_request(transaction_id id,
+                              wifi_interface_handle iface,
+                              NanEnableRequest* msg);
+
+/**@brief nan_disbale_request
+ *        Disable NAN functionality.
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param NanDisableRequest:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ *                      NAN_STATUS_SUCCESS
+ *                      NAN_STATUS_PROTOCOL_FAILURE
+ *
+ */
+wifi_error nan_disable_request(transaction_id id,
+                               wifi_interface_handle iface);
+
+/**@brief nan_publish_request
+ *        Publish request to advertize a service
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param NanPublishRequest:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ *                      NAN_STATUS_SUCCESS
+ *                      NAN_STATUS_INVALID_PARAM
+ *                      NAN_STATUS_PROTOCOL_FAILURE
+ *                      NAN_STATUS_NO_RESOURCE_AVAILABLE
+ *                      NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID
+ */
+wifi_error nan_publish_request(transaction_id id,
+                               wifi_interface_handle iface,
+                               NanPublishRequest* msg);
+
+/**@brief nan_publish_cancel_request
+ *        Cancel previous publish request
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param NanPublishCancelRequest:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ *                      NAN_STATUS_SUCCESS
+ *                      NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID
+ *                      NAN_STATUS_INTERNAL_FAILURE
+ */
+wifi_error nan_publish_cancel_request(transaction_id id,
+                                      wifi_interface_handle iface,
+                                      NanPublishCancelRequest* msg);
+
+/**@brief nan_subscribe_request
+ *        Subscribe request to search for a service
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param NanSubscribeRequest:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ *                      NAN_STATUS_SUCCESS
+ *                      NAN_STATUS_INVALID_PARAM
+ *                      NAN_STATUS_PROTOCOL_FAILURE
+ *                      NAN_STATUS_INTERNAL_FAILURE
+ *                      NAN_STATUS_NO_SPACE_AVAILABLE
+ *                      NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID
+ */
+wifi_error nan_subscribe_request(transaction_id id,
+                                 wifi_interface_handle iface,
+                                 NanSubscribeRequest* msg);
+
+/**@brief nan_subscribe_cancel_request
+ *         Cancel previous subscribe requests.
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param NanSubscribeRequest:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ *                      NAN_STATUS_SUCCESS
+ *                      NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID
+ *                      NAN_STATUS_INTERNAL_FAILURE
+ */
+wifi_error nan_subscribe_cancel_request(transaction_id id,
+                                        wifi_interface_handle iface,
+                                        NanSubscribeCancelRequest* msg);
+
+/**@brief nan_transmit_followup_request
+ *         NAN transmit follow up request
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param NanTransmitFollowupRequest:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ *                      NAN_STATUS_SUCCESS
+ *                      NAN_STATUS_INVALID_PARAM
+ *                      NAN_STATUS_INTERNAL_FAILURE
+ *                      NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID
+ *                      NAN_STATUS_INVALID_REQUESTOR_INSTANCE_ID
+ *                      NAN_STATUS_FOLLOWUP_QUEUE_FULL
+ * @return Asynchronous TransmitFollowupInd CB return
+ *                      NAN_STATUS_SUCCESS
+ *                      NAN_STATUS_PROTOCOL_FAILURE
+ *                      NAN_STATUS_NO_OTA_ACK
+ */
+wifi_error nan_transmit_followup_request(transaction_id id,
+                                         wifi_interface_handle iface,
+                                         NanTransmitFollowupRequest* msg);
+
+/**@brief nan_stats_request
+ *        Request NAN statistics from Discovery Engine.
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param NanStatsRequest:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ *                      NAN_STATUS_SUCCESS
+ *                      NAN_STATUS_INTERNAL_FAILURE
+ *                      NAN_STATUS_INVALID_PARAM
+ */
+wifi_error nan_stats_request(transaction_id id,
+                             wifi_interface_handle iface,
+                             NanStatsRequest* msg);
+
+/**@brief nan_config_request
+ *        NAN configuration request.
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param NanConfigRequest:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ *                      NAN_STATUS_SUCCESS
+ *                      NAN_STATUS_INVALID_PARAM
+ *                      NAN_STATUS_PROTOCOL_FAILURE
+ *                      NAN_STATUS_INTERNAL_FAILURE
+ */
+wifi_error nan_config_request(transaction_id id,
+                              wifi_interface_handle iface,
+                              NanConfigRequest* msg);
+
+/**@brief nan_tca_request
+ *        Configure the various Threshold crossing alerts
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param NanStatsRequest:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ *                      NAN_STATUS_SUCCESS
+ *                      NAN_STATUS_INVALID_PARAM
+ *                      NAN_STATUS_INTERNAL_FAILURE
+ */
+wifi_error nan_tca_request(transaction_id id,
+                           wifi_interface_handle iface,
+                           NanTCARequest* msg);
+
+/**@brief nan_beacon_sdf_payload_request
+ *        Set NAN Beacon or sdf payload to discovery engine.
+ *          This instructs the Discovery Engine to begin publishing the
+ *        received payload in any Beacon or Service Discovery Frame transmitted
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param NanStatsRequest:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ *                      NAN_STATUS_SUCCESS
+ *                      NAN_STATUS_INVALID_PARAM
+ *                      NAN_STATUS_INTERNAL_FAILURE
+ */
+wifi_error nan_beacon_sdf_payload_request(transaction_id id,
+                                         wifi_interface_handle iface,
+                                         NanBeaconSdfPayloadRequest* msg);
+
+/* Register NAN callbacks. */
+wifi_error nan_register_handler(wifi_interface_handle iface,
+                                NanCallbackHandler handlers);
+
+/*  Get NAN HAL version. */
+wifi_error nan_get_version(wifi_handle handle,
+                           NanVersion* version);
+
+/**@brief nan_get_capabilities
+ *        Get NAN Capabilities
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ *                      NAN_STATUS_SUCCESS
+ */
+/*  Get NAN capabilities. */
+wifi_error nan_get_capabilities(transaction_id id,
+                                wifi_interface_handle iface);
+
+/* ========== Nan Data Path APIs ================ */
+/**@brief nan_data_interface_create
+ *        Create NAN Data Interface.
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param iface_name:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ *                      NAN_STATUS_SUCCESS
+ *                      NAN_STATUS_INVALID_PARAM
+ *                      NAN_STATUS_INTERNAL_FAILURE
+ */
+wifi_error nan_data_interface_create(transaction_id id,
+                                     wifi_interface_handle iface,
+                                     char* iface_name);
+
+/**@brief nan_data_interface_delete
+ *        Delete NAN Data Interface.
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param iface_name:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ *                      NAN_STATUS_SUCCESS
+ *                      NAN_STATUS_INVALID_PARAM
+ *                      NAN_STATUS_INTERNAL_FAILURE
+ */
+wifi_error nan_data_interface_delete(transaction_id id,
+                                     wifi_interface_handle iface,
+                                     char* iface_name);
+
+/**@brief nan_data_request_initiator
+ *        Initiate a NAN Data Path session.
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param NanDataPathInitiatorRequest:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ *                      NAN_STATUS_SUCCESS
+ *                      NAN_STATUS_INVALID_PARAM
+ *                      NAN_STATUS_INTERNAL_FAILURE
+ *                      NAN_STATUS_PROTOCOL_FAILURE
+ *                      NAN_STATUS_INVALID_REQUESTOR_INSTANCE_ID
+ */
+wifi_error nan_data_request_initiator(transaction_id id,
+                                      wifi_interface_handle iface,
+                                      NanDataPathInitiatorRequest* msg);
+
+/**@brief nan_data_indication_response
+ *         Response to a data indication received
+ *         corresponding to a NDP session. An indication
+ *         is received with a data request and the responder
+ *         will send a data response
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param NanDataPathIndicationResponse:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ *                      NAN_STATUS_SUCCESS
+ *                      NAN_STATUS_INVALID_PARAM
+ *                      NAN_STATUS_INTERNAL_FAILURE
+ *                      NAN_STATUS_PROTOCOL_FAILURE
+ *                      NAN_STATUS_INVALID_NDP_ID
+ */
+wifi_error nan_data_indication_response(transaction_id id,
+                                        wifi_interface_handle iface,
+                                        NanDataPathIndicationResponse* msg);
+
+/**@brief nan_data_end
+ *         NDL termination request: from either Initiator/Responder
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param NanDataPathEndRequest:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ *                      NAN_STATUS_SUCCESS
+ *                      NAN_STATUS_INVALID_PARAM
+ *                      NAN_STATUS_INTERNAL_FAILURE
+ *                      NAN_STATUS_PROTOCOL_FAILURE
+ *                      NAN_STATUS_INVALID_NDP_ID
+ */
+wifi_error nan_data_end(transaction_id id,
+                        wifi_interface_handle iface,
+                        NanDataPathEndRequest* msg);
+/**@brief nan_pairing_request
+ *        Initiate a NAN Pairingsession.
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param NanPairingRequest:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ *                      NAN_STATUS_SUCCESS
+ *                      NAN_STATUS_INVALID_PARAM
+ *                      NAN_STATUS_INTERNAL_FAILURE
+ *                      NAN_STATUS_PROTOCOL_FAILURE
+ *                      NAN_STATUS_INVALID_REQUESTOR_INSTANCE_ID
+ */
+wifi_error nan_pairing_request(transaction_id id, wifi_interface_handle iface,
+                               NanPairingRequest* msg);
+
+/**@brief nan_pairing_indication_response
+ *        Response to a pairing indication received
+ *        corresponding to a pairing session. An indication
+ *        is received with a pairing request and the responder
+ *        will send a pairing response
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param NanPairingIndicationResponse:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ *                      NAN_STATUS_SUCCESS
+ *                      NAN_STATUS_INVALID_PARAM
+ *                      NAN_STATUS_INTERNAL_FAILURE
+ *                      NAN_STATUS_PROTOCOL_FAILURE
+ *                      NAN_STATUS_INVALID_PAIRING_ID
+ */
+wifi_error nan_pairing_indication_response(transaction_id id, wifi_interface_handle iface,
+                                           NanPairingIndicationResponse* msg);
+
+/**@brief nan_pairing_end
+ *        Cancel and remove the existing Pairing setups
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param NanPairingEndRequest:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ *                      NAN_STATUS_SUCCESS
+ *                      NAN_STATUS_INVALID_PARAM
+ *                      NAN_STATUS_INTERNAL_FAILURE
+ *                      NAN_STATUS_PROTOCOL_FAILURE
+ *                      NAN_STATUS_INVALID_PAIRING_ID
+ */
+wifi_error nan_pairing_end(transaction_id id, wifi_interface_handle iface,
+                                                 NanPairingEndRequest* msg);
+
+/**@brief nan_bootstrapping_request
+ *        Initiate a NAN Bootstrapping session.
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param NanBootstrappingRequest:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ *                      NAN_STATUS_SUCCESS
+ *                      NAN_STATUS_INVALID_PARAM
+ *                      NAN_STATUS_INTERNAL_FAILURE
+ *                      NAN_STATUS_PROTOCOL_FAILURE
+ *                      NAN_STATUS_INVALID_REQUESTOR_INSTANCE_ID
+ */
+wifi_error nan_bootstrapping_request(transaction_id id, wifi_interface_handle iface,
+                                     NanBootstrappingRequest* msg);
+
+/**@brief nan_bootstrapping_indication_response
+ *         Response to a pairing indication received
+ *         corresponding to a pairing session. An indication
+ *         is received with a pairing request and the responder
+ *         will send a pairing response
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param NanBootstrappingIndicationResponse:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ *                      NAN_STATUS_SUCCESS
+ *                      NAN_STATUS_INVALID_PARAM
+ *                      NAN_STATUS_INTERNAL_FAILURE
+ *                      NAN_STATUS_PROTOCOL_FAILURE
+ *                      NAN_STATUS_INVALID_BOOTSTRAPPING_ID
+ */
+wifi_error nan_bootstrapping_indication_response(transaction_id id, wifi_interface_handle iface,
+                                                 NanBootstrappingIndicationResponse* msg);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __NAN_H__ */
diff --git a/wifi/legacy_headers/include/hardware_legacy/wifi_offload.h b/wifi/legacy_headers/include/hardware_legacy/wifi_offload.h
new file mode 100644
index 0000000..835614e
--- /dev/null
+++ b/wifi/legacy_headers/include/hardware_legacy/wifi_offload.h
@@ -0,0 +1,32 @@
+#include "wifi_hal.h"
+
+#ifndef __WIFI_HAL_OFFLOAD_H
+#define __WIFI_HAL_OFFLOAD_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+#define ETHER_ADDR_LEN		6	// Ethernet frame address length
+#define N_AVAIL_ID		3	// available mkeep_alive IDs from 1 to 3
+#define MKEEP_ALIVE_IP_PKT_MAX	256     // max size of IP packet for keep alive
+
+/**
+ * Send specified keep alive packet periodically.
+ */
+wifi_error wifi_start_sending_offloaded_packet(wifi_request_id id, wifi_interface_handle iface,
+        u16 ether_type, u8 *ip_packet, u16 ip_packet_len, u8 *src_mac_addr, u8 *dst_mac_addr,
+        u32 period_msec);
+
+/**
+ * Stop sending keep alive packet.
+ */
+wifi_error wifi_stop_sending_offloaded_packet(wifi_request_id id, wifi_interface_handle iface);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /*__WIFI_HAL_OFFLOAD_H */
diff --git a/wifi/legacy_headers/include/hardware_legacy/wifi_twt.h b/wifi/legacy_headers/include/hardware_legacy/wifi_twt.h
new file mode 100644
index 0000000..cb11c78
--- /dev/null
+++ b/wifi/legacy_headers/include/hardware_legacy/wifi_twt.h
@@ -0,0 +1,310 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#ifndef __WIFI_HAL_TWT_H__
+#define __WIFI_HAL_TWT_H__
+
+#include "wifi_hal.h"
+
+/**
+ * New HAL interface to Target Wake Time (TWT).
+ */
+
+/* TWT capabilities supported */
+typedef struct {
+    u8 is_twt_requester_supported; // 0 for not supporting twt requester
+    u8 is_twt_responder_supported; // 0 for not supporting twt responder
+    u8 is_broadcast_twt_supported; // 0 for not supporting broadcast twt
+    u8 is_flexible_twt_supported;  // 0 for not supporting flexible twt schedules
+    u32 min_wake_duration_micros;  // minimum twt wake duration capable in microseconds
+    u32 max_wake_duration_micros;  // maximum twt wake duration capable in microseconds
+    u64 min_wake_interval_micros;  // minimum twt wake interval capable in microseconds
+    u64 max_wake_interval_micros;  // maximum twt wake interval capable in microseconds
+} wifi_twt_capabilities;
+
+/* TWT request parameters to setup or update a TWT session */
+typedef struct {
+    s8  mlo_link_id; // MLO Link id in case TWT is requesting for MLO connection.
+                     // Otherwise UNSPECIFIED.
+    u32 min_wake_duration_micros;  // minimum twt wake duration in microseconds
+    u32 max_wake_duration_micros;  // maximum twt wake duration in microseconds
+    u64 min_wake_interval_micros;  // minimum twt wake interval in microseconds
+    u64 max_wake_interval_micros;  // maximum twt wake interval in microseconds
+} wifi_twt_request;
+
+/* TWT negotiation types */
+typedef enum {
+    WIFI_TWT_NEGO_TYPE_INDIVIDUAL,
+    WIFI_TWT_NEGO_TYPE_BROADCAST,
+} wifi_twt_negotiation_type;
+
+/* TWT session */
+typedef struct {
+    u32 session_id; // a unique identifier for the session
+    s8 mlo_link_id; // link id in case of MLO connection. Otherwise UNSPECIFIED.
+    u32 wake_duration_micros; // TWT service period in microseconds
+    u64 wake_interval_micros; // TWT wake interval for this session in microseconds
+    wifi_twt_negotiation_type negotiation_type; // TWT negotiation type
+    u8 is_trigger_enabled; // 0 if this TWT session is not trigger enabled
+    u8 is_announced;       // 0 if this TWT session is not announced
+    u8 is_implicit;        // 0 if this TWT session is not implicit
+    u8 is_protected;       // 0 if this TWT session is not protected
+    u8 is_updatable;     // 0 if this TWT session is not updatable
+    u8 is_suspendable;   // 0 if this TWT session can not be suspended and resumed
+    u8 is_responder_pm_mode_enabled; // 0 if TWT responder does not intend to go to doze mode
+                                     // outside of TWT service periods
+} wifi_twt_session;
+
+/* TWT session stats */
+typedef struct {
+    u32 avg_pkt_num_tx;  // Average number of Tx packets in each wake duration.
+    u32 avg_pkt_num_rx;  // Average number of Rx packets in each wake duration.
+    u32 avg_tx_pkt_size; // Average bytes per Rx packet in each wake duration.
+    u32 avg_rx_pkt_size; // Average bytes per Rx packet in each wake duration.
+    u32 avg_eosp_dur_us; // Average duration of early terminated SP
+    u32 eosp_count;      // Count of early terminations
+} wifi_twt_session_stats;
+
+/* TWT error codes */
+typedef enum {
+    WIFI_TWT_ERROR_CODE_FAILURE_UNKNOWN,    // unknown failure
+    WIFI_TWT_ERROR_CODE_ALREADY_RESUMED,    // TWT session is already resumed
+    WIFI_TWT_ERROR_CODE_ALREADY_SUSPENDED,  // TWT session is already suspended
+    WIFI_TWT_ERROR_CODE_INVALID_PARAMS,     // invalid parameters
+    WIFI_TWT_ERROR_CODE_MAX_SESSION_REACHED,// maximum number of sessions reached
+    WIFI_TWT_ERROR_CODE_NOT_AVAILABLE,      // requested operation is not available
+    WIFI_TWT_ERROR_CODE_NOT_SUPPORTED,      // requested operation is not supported
+    WIFI_TWT_ERROR_CODE_PEER_NOT_SUPPORTED, // requested operation is not supported by the
+                                            // peer
+    WIFI_TWT_ERROR_CODE_PEER_REJECTED,      // requested operation is rejected by the peer
+    WIFI_TWT_ERROR_CODE_TIMEOUT,            // requested operation is timed out
+} wifi_twt_error_code;
+
+/* TWT teardown reason codes */
+typedef enum {
+    WIFI_TWT_TEARDOWN_REASON_CODE_UNKNOWN,              // unknown reason
+    WIFI_TWT_TEARDOWN_REASON_CODE_LOCALLY_REQUESTED,    // teardown requested by the framework
+    WIFI_TWT_TEARDOWN_REASON_CODE_INTERNALLY_INITIATED, // teardown initiated internally by the
+                                                        // firmware or driver.
+    WIFI_TWT_TEARDOWN_REASON_CODE_PEER_INITIATED,        // teardown initiated by the peer
+} wifi_twt_teardown_reason_code;
+
+/**
+ * TWT events
+ *
+ * Each of the events has a wifi_request_id to match the command responsible for the event. If the
+ * id is 0, the event is an unsolicited.
+ */
+typedef struct {
+    /**
+     * Called to indicate a TWT failure.
+     *
+     * @param id Id used to identify the command. The value 0 indicates no associated command.
+     * @param error_code TWT error code.
+     */
+    void (*on_twt_failure)(wifi_request_id id, wifi_twt_error_code error_code);
+
+    /**
+     * Called when a Target Wake Time session is created. See wifi_twt_session_setup.
+     *
+     * @param id Id used to identify the command.
+     * @param session TWT session created.
+     */
+    void (*on_twt_session_create)(wifi_request_id id, wifi_twt_session session);
+
+    /**
+     * Called when a Target Wake Time session is updated. See wifi_twt_session_update.
+     *
+     * @param id Id used to identify the command. The value 0 indicates no associated command.
+     * @param twtSession TWT session.
+     */
+    void (*on_twt_session_update)(wifi_request_id id, wifi_twt_session session);
+
+    /**
+     * Called when the Target Wake Time session is torn down. See wifi_twt_session_teardown.
+     *
+     * @param id Id used to identify the command. The value 0 indicates no associated command.
+     * @param session_id TWT session id.
+     * @param reason Teardown reason code.
+     */
+    void (*on_twt_session_teardown)(wifi_request_id id, int session_id,
+                                    wifi_twt_teardown_reason_code reason);
+
+    /**
+     * Called when TWT session stats available. See wifi_twt_session_get_stats.
+     *
+     * @param id Id used to identify the command.
+     * @param session_id TWT session id.
+     * @param stats TWT session stats.
+     */
+    void (*on_twt_session_stats)(wifi_request_id id, int session_id, wifi_twt_session_stats stats);
+
+    /**
+     * Called when the Target Wake Time session is suspended. See wifi_twt_session_suspend.
+     *
+     * @param id Id used to identify the command.
+     * @param session_id TWT session id.
+     */
+    void (*on_twt_session_suspend)(wifi_request_id id, int session_id);
+
+    /**
+     * Called when the Target Wake Time session is resumed. See wifi_twt_session_resume.
+     *
+     * @param id Id used to identify the command.
+     * @param session_id TWT session id.
+     */
+    void (*on_twt_session_resume)(wifi_request_id id, int session_id);
+} wifi_twt_events;
+
+/**
+ * Important note: Following legacy HAL TWT interface is deprecated. It will be removed in future.
+ * Please use the new interface listed above.
+ */
+typedef struct {
+    u8 requester_supported; // 0 for not supporting requester
+    u8 responder_supported; // 0 for not supporting responder
+    u8 broadcast_twt_supported; // 0 for not supporting broadcast TWT
+    u8 flexibile_twt_supported; // 0 for not supporting flexible TWT
+} TwtCapability;
+
+typedef struct {
+    TwtCapability device_capability;
+    TwtCapability peer_capability;
+} TwtCapabilitySet;
+
+// For all optional fields below, if no value specify -1
+typedef struct {
+    u8 config_id;        // An unique ID for an individual TWT request
+    u8 negotiation_type; // 0 for individual TWT, 1 for broadcast TWT
+    u8 trigger_type;     // 0 for non-triggered TWT, 1 for triggered TWT
+    s32 wake_dur_us;     // Proposed wake duration in us
+    s32 wake_int_us;     // Average wake interval in us
+    s32 wake_int_min_us; // Min wake interval in us. Optional.
+    s32 wake_int_max_us; // Max wake interval in us. Optional.
+    s32 wake_dur_min_us; // Min wake duration in us. Optional.
+    s32 wake_dur_max_us; // Max wake duration in us. Optional.
+    s32 avg_pkt_size;    // Average bytes of each packet to send in each wake
+                         // duration. Optional.
+    s32 avg_pkt_num;     // Average number of packets to send in each wake
+                         // duration. Optional.
+    s32 wake_time_off_us; // First wake duration time offset in us. Optional.
+} TwtSetupRequest;
+
+typedef enum {
+    TWT_SETUP_SUCCESS = 0, // TWT setup is accepted.
+    TWT_SETUP_REJECT = 1,  // TWT setup is rejected by AP.
+    TWT_SETUP_TIMEOUT = 2, // TWT setup response from AP times out.
+    TWT_SETUP_IE = 3,      // AP sent TWT Setup IE parsing failure.
+    TWT_SETUP_PARAMS = 4,  // AP sent TWT Setup IE Parameters invalid.
+    TWT_SETUP_ERROR = 255, // Generic error
+} TwtSetupReasonCode;
+
+typedef struct {
+    u8 config_id; // An unique ID for an individual TWT request
+    u8 status;    // 0 for success, non-zero for failure
+    TwtSetupReasonCode reason_code;
+    u8 negotiation_type; // 0 for individual TWT, 1 for broadcast TWT
+    u8 trigger_type;     // 0 for non-triggered TWT, 1 for triggered TWT
+    s32 wake_dur_us;     // Proposed wake duration in us
+    s32 wake_int_us;     // Average wake interval in us
+    s32 wake_time_off_us; // First wake duration time offset in us.
+} TwtSetupResponse;
+
+typedef struct {
+    u8 config_id;        // An unique ID for an individual TWT request
+    u8 all_twt;          // 0 for individual setp request, 1 for all TWT
+    u8 negotiation_type; // 0 for individual TWT, 1 for broadcast TWT
+} TwtTeardownRequest;
+
+typedef enum {
+    TWT_TD_RC_HOST = 0,  // Teardown triggered by Host
+    TWT_TD_RC_PEER = 1,  // Peer initiated teardown
+    TWT_TD_RC_MCHAN = 2, // Teardown due to MCHAN Active
+    TWT_TD_RC_MCNX = 3,  // Teardown due to MultiConnection
+    TWT_TD_RC_CSA = 4,   // Teardown due to CSA
+    TWT_TD_RC_BTCX = 5,  // Teardown due to BT Coex
+    TWT_TD_RC_SETUP_FAIL = 6, // Setup fails midway. Teardown all connections
+    TWT_TD_RC_SCHED = 7,   // Teardown by TWT Scheduler
+    TWT_TD_RC_ERROR = 255, // Generic error cases
+} TwtTeardownReason;
+
+typedef struct {
+    u8 config_id; // An unique ID for an individual TWT request
+    u8 all_twt;   // 0 for individual setp request, 1 for all TWT
+    u8 status;    // 0 for success, non-zero for failure
+    TwtTeardownReason reason;
+} TwtTeardownCompletion;
+
+typedef struct {
+    u8 config_id;       // An unique ID for an individual TWT request
+    u8 all_twt;         // 0 for individual setup request, 1 for all TWT
+    s32 resume_time_us; // If -1, TWT is suspended for indefinite time.
+                        // Otherwise, TWT is suspended for resume_time_us
+} TwtInfoFrameRequest;
+
+typedef enum {
+    TWT_INFO_RC_HOST  = 0, // Host initiated TWT Info frame */
+    TWT_INFO_RC_PEER  = 1, // Peer initiated TWT Info frame
+    TWT_INFO_RC_ERROR = 2, // Generic error conditions */
+} TwtInfoFrameReason;
+
+// TWT Info frame triggered externally.
+// Device should not send TwtInfoFrameReceived to Host for internally
+// triggered TWT Info frame during SCAN, MCHAN operations.
+typedef struct {
+    u8 config_id; // An unique ID for an individual TWT request
+    u8 all_twt;   // 0 for individual setup request, 1 for all TWT
+    u8 status;    // 0 for success, non-zero for failure
+    TwtInfoFrameReason reason;
+    u8 twt_resumed; // 1 - TWT resumed, 0 - TWT suspended
+} TwtInfoFrameReceived;
+
+typedef struct {
+    u8 config_id;
+    u32 avg_pkt_num_tx; // Average number of Tx packets in each wake duration.
+    u32 avg_pkt_num_rx; // Average number of Rx packets in each wake duration.
+    u32 avg_tx_pkt_size; // Average bytes per Rx packet in each wake duration.
+    u32 avg_rx_pkt_size; // Average bytes per Rx packet in each wake duration.
+    u32 avg_eosp_dur_us; // Average duration of early terminated SP
+    u32 eosp_count;  // Count of early terminations
+    u32 num_sp; // Count of service period (SP), also known as wake duration.
+} TwtStats;
+
+// Asynchronous notification from the device.
+// For example, TWT was torn down by the device and later when the device is
+// ready, it can send this async notification.
+// This can be expandable in future.
+typedef enum {
+   TWT_NOTIF_ALLOW_TWT  = 1, // Device ready to process TWT Setup request
+} TwtNotification;
+
+typedef struct {
+    TwtNotification notification;
+} TwtDeviceNotify;
+
+// Callbacks for various TWT responses and events
+typedef struct {
+    // Callback for TWT setup response
+    void (*EventTwtSetupResponse)(TwtSetupResponse *event);
+    // Callback for TWT teardown completion
+    void (*EventTwtTeardownCompletion)(TwtTeardownCompletion* event);
+    // Callback for TWT info frame received event
+    void (*EventTwtInfoFrameReceived)(TwtInfoFrameReceived* event);
+    // Callback for TWT notification from the device
+    void (*EventTwtDeviceNotify)(TwtDeviceNotify* event);
+} TwtCallbackHandler;
+
+#endif /* __WIFI_HAL_TWT_H__ */
diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp b/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp
index 58f9be8..6b04aa9 100644
--- a/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp
+++ b/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp
@@ -413,7 +413,7 @@
  * SetCountryCode
  */
 TEST_P(SupplicantStaIfaceAidlTest, SetCountryCode) {
-    const std::vector<uint8_t> countryCode = {'M', 'X'};
+    const std::vector<uint8_t> countryCode = {'U', 'S'};
     EXPECT_TRUE(sta_iface_->setCountryCode(countryCode).isOk());
 }