Merge "Camera: Trim required stream combination queries" into main
diff --git a/audio/aidl/Android.bp b/audio/aidl/Android.bp
index 8bb8cd5..b67b9d2 100644
--- a/audio/aidl/Android.bp
+++ b/audio/aidl/Android.bp
@@ -64,6 +64,9 @@
             ],
             min_sdk_version: "31",
         },
+        rust: {
+            enabled: true,
+        },
     },
     versions_with_info: [
         {
@@ -112,6 +115,13 @@
     ],
 }
 
+rust_defaults {
+    name: "latest_android_hardware_audio_common_rust",
+    rustlibs: [
+        latest_android_hardware_audio_common + "-rust",
+    ],
+}
+
 aidl_interface_defaults {
     name: "latest_android_hardware_audio_common_import_interface",
     imports: [
diff --git a/audio/aidl/default/EffectImpl.cpp b/audio/aidl/default/EffectImpl.cpp
index 03de74f..7192d97 100644
--- a/audio/aidl/default/EffectImpl.cpp
+++ b/audio/aidl/default/EffectImpl.cpp
@@ -23,6 +23,9 @@
 #include "include/effect-impl/EffectTypes.h"
 
 using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::kEventFlagDataMqNotEmpty;
+using aidl::android::hardware::audio::effect::kEventFlagNotEmpty;
+using aidl::android::hardware::audio::effect::kReopenSupportedVersion;
 using aidl::android::hardware::audio::effect::State;
 using aidl::android::media::audio::common::PcmType;
 using ::android::hardware::EventFlag;
@@ -43,7 +46,6 @@
 ndk::ScopedAStatus EffectImpl::open(const Parameter::Common& common,
                                     const std::optional<Parameter::Specific>& specific,
                                     OpenEffectReturn* ret) {
-    LOG(DEBUG) << getEffectName() << __func__;
     // effect only support 32bits float
     RETURN_IF(common.input.base.format.pcm != common.output.base.format.pcm ||
                       common.input.base.format.pcm != PcmType::FLOAT_32_BIT,
@@ -54,11 +56,12 @@
     mImplContext = createContext(common);
     RETURN_IF(!mImplContext, EX_NULL_POINTER, "nullContext");
 
-    int version = 0;
-    RETURN_IF(!getInterfaceVersion(&version).isOk(), EX_UNSUPPORTED_OPERATION,
+    RETURN_IF(!getInterfaceVersion(&mVersion).isOk(), EX_UNSUPPORTED_OPERATION,
               "FailedToGetInterfaceVersion");
-    mImplContext->setVersion(version);
+    mImplContext->setVersion(mVersion);
     mEventFlag = mImplContext->getStatusEventFlag();
+    mDataMqNotEmptyEf =
+            mVersion >= kReopenSupportedVersion ? kEventFlagDataMqNotEmpty : kEventFlagNotEmpty;
 
     if (specific.has_value()) {
         RETURN_IF_ASTATUS_NOT_OK(setParameterSpecific(specific.value()), "setSpecParamErr");
@@ -66,8 +69,9 @@
 
     mState = State::IDLE;
     mImplContext->dupeFmq(ret);
-    RETURN_IF(createThread(getEffectName()) != RetCode::SUCCESS, EX_UNSUPPORTED_OPERATION,
-              "FailedToCreateWorker");
+    RETURN_IF(createThread(getEffectNameWithVersion()) != RetCode::SUCCESS,
+              EX_UNSUPPORTED_OPERATION, "FailedToCreateWorker");
+    LOG(INFO) << getEffectNameWithVersion() << __func__;
     return ndk::ScopedAStatus::ok();
 }
 
@@ -89,7 +93,7 @@
         mState = State::INIT;
     }
 
-    RETURN_IF(notifyEventFlag(kEventFlagNotEmpty) != RetCode::SUCCESS, EX_ILLEGAL_STATE,
+    RETURN_IF(notifyEventFlag(mDataMqNotEmptyEf) != RetCode::SUCCESS, EX_ILLEGAL_STATE,
               "notifyEventFlagNotEmptyFailed");
     // stop the worker thread, ignore the return code
     RETURN_IF(destroyThread() != RetCode::SUCCESS, EX_UNSUPPORTED_OPERATION,
@@ -101,13 +105,13 @@
         mImplContext.reset();
     }
 
-    LOG(DEBUG) << getEffectName() << __func__;
+    LOG(INFO) << getEffectNameWithVersion() << __func__;
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus EffectImpl::setParameter(const Parameter& param) {
     std::lock_guard lg(mImplMutex);
-    LOG(VERBOSE) << getEffectName() << __func__ << " with: " << param.toString();
+    LOG(VERBOSE) << getEffectNameWithVersion() << __func__ << " with: " << param.toString();
 
     const auto& tag = param.getTag();
     switch (tag) {
@@ -122,7 +126,7 @@
             return setParameterSpecific(param.get<Parameter::specific>());
         }
         default: {
-            LOG(ERROR) << getEffectName() << __func__ << " unsupportedParameterTag "
+            LOG(ERROR) << getEffectNameWithVersion() << __func__ << " unsupportedParameterTag "
                        << toString(tag);
             return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
                                                                     "ParameterNotSupported");
@@ -147,7 +151,7 @@
             break;
         }
     }
-    LOG(VERBOSE) << getEffectName() << __func__ << id.toString() << param->toString();
+    LOG(VERBOSE) << getEffectNameWithVersion() << __func__ << id.toString() << param->toString();
     return ndk::ScopedAStatus::ok();
 }
 
@@ -180,7 +184,7 @@
                       EX_ILLEGAL_ARGUMENT, "setVolumeStereoFailed");
             break;
         default: {
-            LOG(ERROR) << getEffectName() << __func__ << " unsupportedParameterTag "
+            LOG(ERROR) << getEffectNameWithVersion() << __func__ << " unsupportedParameterTag "
                        << toString(tag);
             return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
                                                                     "commonParamNotSupported");
@@ -214,7 +218,8 @@
             break;
         }
         default: {
-            LOG(DEBUG) << getEffectName() << __func__ << " unsupported tag " << toString(tag);
+            LOG(DEBUG) << getEffectNameWithVersion() << __func__ << " unsupported tag "
+                       << toString(tag);
             return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
                                                                     "tagNotSupported");
         }
@@ -236,7 +241,7 @@
             RETURN_OK_IF(mState == State::PROCESSING);
             RETURN_IF_ASTATUS_NOT_OK(commandImpl(command), "commandImplFailed");
             mState = State::PROCESSING;
-            RETURN_IF(notifyEventFlag(kEventFlagNotEmpty) != RetCode::SUCCESS, EX_ILLEGAL_STATE,
+            RETURN_IF(notifyEventFlag(mDataMqNotEmptyEf) != RetCode::SUCCESS, EX_ILLEGAL_STATE,
                       "notifyEventFlagNotEmptyFailed");
             startThread();
             break;
@@ -244,17 +249,18 @@
         case CommandId::RESET:
             RETURN_OK_IF(mState == State::IDLE);
             mState = State::IDLE;
-            RETURN_IF(notifyEventFlag(kEventFlagNotEmpty) != RetCode::SUCCESS, EX_ILLEGAL_STATE,
+            RETURN_IF(notifyEventFlag(mDataMqNotEmptyEf) != RetCode::SUCCESS, EX_ILLEGAL_STATE,
                       "notifyEventFlagNotEmptyFailed");
             stopThread();
             RETURN_IF_ASTATUS_NOT_OK(commandImpl(command), "commandImplFailed");
             break;
         default:
-            LOG(ERROR) << getEffectName() << __func__ << " instance still processing";
+            LOG(ERROR) << getEffectNameWithVersion() << __func__ << " instance still processing";
             return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
                                                                     "CommandIdNotSupported");
     }
-    LOG(VERBOSE) << getEffectName() << __func__ << " transfer to state: " << toString(mState);
+    LOG(VERBOSE) << getEffectNameWithVersion() << __func__
+                 << " transfer to state: " << toString(mState);
     return ndk::ScopedAStatus::ok();
 }
 
@@ -284,14 +290,14 @@
 
 RetCode EffectImpl::notifyEventFlag(uint32_t flag) {
     if (!mEventFlag) {
-        LOG(ERROR) << getEffectName() << __func__ << ": StatusEventFlag invalid";
+        LOG(ERROR) << getEffectNameWithVersion() << __func__ << ": StatusEventFlag invalid";
         return RetCode::ERROR_EVENT_FLAG_ERROR;
     }
     if (const auto ret = mEventFlag->wake(flag); ret != ::android::OK) {
-        LOG(ERROR) << getEffectName() << __func__ << ": wake failure with ret " << ret;
+        LOG(ERROR) << getEffectNameWithVersion() << __func__ << ": wake failure with ret " << ret;
         return RetCode::ERROR_EVENT_FLAG_ERROR;
     }
-    LOG(VERBOSE) << getEffectName() << __func__ << ": " << std::hex << mEventFlag;
+    LOG(VERBOSE) << getEffectNameWithVersion() << __func__ << ": " << std::hex << mEventFlag;
     return RetCode::SUCCESS;
 }
 
@@ -304,17 +310,17 @@
 }
 
 void EffectImpl::process() {
-    ATRACE_NAME(getEffectName().c_str());
+    ATRACE_NAME(getEffectNameWithVersion().c_str());
     /**
      * wait for the EventFlag without lock, it's ok because the mEfGroup pointer will not change
      * in the life cycle of workerThread (threadLoop).
      */
     uint32_t efState = 0;
     if (!mEventFlag ||
-        ::android::OK != mEventFlag->wait(kEventFlagNotEmpty, &efState, 0 /* no timeout */,
+        ::android::OK != mEventFlag->wait(mDataMqNotEmptyEf, &efState, 0 /* no timeout */,
                                           true /* retry */) ||
-        !(efState & kEventFlagNotEmpty)) {
-        LOG(ERROR) << getEffectName() << __func__ << ": StatusEventFlag - " << mEventFlag
+        !(efState & mDataMqNotEmptyEf)) {
+        LOG(ERROR) << getEffectNameWithVersion() << __func__ << ": StatusEventFlag - " << mEventFlag
                    << " efState - " << std::hex << efState;
         return;
     }
@@ -322,7 +328,8 @@
     {
         std::lock_guard lg(mImplMutex);
         if (mState != State::PROCESSING) {
-            LOG(DEBUG) << getEffectName() << " skip process in state: " << toString(mState);
+            LOG(DEBUG) << getEffectNameWithVersion()
+                       << " skip process in state: " << toString(mState);
             return;
         }
         RETURN_VALUE_IF(!mImplContext, void(), "nullContext");
diff --git a/audio/aidl/default/include/effect-impl/EffectImpl.h b/audio/aidl/default/include/effect-impl/EffectImpl.h
index 21f6502..d3bb7f4 100644
--- a/audio/aidl/default/include/effect-impl/EffectImpl.h
+++ b/audio/aidl/default/include/effect-impl/EffectImpl.h
@@ -89,6 +89,11 @@
     void process() override;
 
   protected:
+    // current Hal version
+    int mVersion = 0;
+    // Use kEventFlagNotEmpty for V1 HAL, kEventFlagDataMqNotEmpty for V2 and above
+    int mDataMqNotEmptyEf = aidl::android::hardware::audio::effect::kEventFlagDataMqNotEmpty;
+
     State mState GUARDED_BY(mImplMutex) = State::INIT;
 
     IEffect::Status status(binder_status_t status, size_t consumed, size_t produced);
@@ -107,6 +112,11 @@
     virtual ndk::ScopedAStatus commandImpl(CommandId id) REQUIRES(mImplMutex);
 
     RetCode notifyEventFlag(uint32_t flag);
+
+    std::string getEffectNameWithVersion() {
+        return getEffectName() + "V" + std::to_string(mVersion);
+    }
+
     ::android::hardware::EventFlag* mEventFlag;
 };
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/vts/EffectHelper.h b/audio/aidl/vts/EffectHelper.h
index 0d1e0dc..0fdf7a7 100644
--- a/audio/aidl/vts/EffectHelper.h
+++ b/audio/aidl/vts/EffectHelper.h
@@ -43,8 +43,10 @@
 using aidl::android::hardware::audio::effect::CommandId;
 using aidl::android::hardware::audio::effect::Descriptor;
 using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::kEventFlagDataMqNotEmpty;
 using aidl::android::hardware::audio::effect::kEventFlagDataMqUpdate;
 using aidl::android::hardware::audio::effect::kEventFlagNotEmpty;
+using aidl::android::hardware::audio::effect::kReopenSupportedVersion;
 using aidl::android::hardware::audio::effect::Parameter;
 using aidl::android::hardware::audio::effect::Range;
 using aidl::android::hardware::audio::effect::State;
@@ -160,7 +162,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();
@@ -171,7 +173,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,
@@ -322,7 +325,10 @@
         ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
 
         // Write from buffer to message queues and calling process
-        EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, inputBuffer));
+        EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, inputBuffer, [&]() {
+            int version = 0;
+            return (mEffect && mEffect->getInterfaceVersion(&version).isOk()) ? version : 0;
+        }()));
 
         // Read the updated message queues into buffer
         EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(statusMQ, 1, outputMQ,
diff --git a/audio/aidl/vts/TestUtils.h b/audio/aidl/vts/TestUtils.h
index 0a5addc..3a6c137 100644
--- a/audio/aidl/vts/TestUtils.h
+++ b/audio/aidl/vts/TestUtils.h
@@ -108,7 +108,7 @@
     ({                                                                                            \
         if ((flags).hwAcceleratorMode ==                                                          \
                     aidl::android::hardware::audio::effect::Flags::HardwareAccelerator::TUNNEL || \
-            (flags).bypass) {                                                                     \
+            (flags).bypass || (flags).offloadIndication) {                                        \
             GTEST_SKIP() << "Skip data path for offload";                                         \
         }                                                                                         \
     })
diff --git a/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp b/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
index 4693f10..5b83d73 100644
--- a/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
@@ -42,7 +42,6 @@
 using aidl::android::hardware::audio::effect::Flags;
 using aidl::android::hardware::audio::effect::IEffect;
 using aidl::android::hardware::audio::effect::IFactory;
-using aidl::android::hardware::audio::effect::kReopenSupportedVersion;
 using aidl::android::hardware::audio::effect::Parameter;
 using aidl::android::hardware::audio::effect::State;
 using aidl::android::media::audio::common::AudioDeviceDescription;
@@ -58,6 +57,7 @@
   public:
     AudioEffectTest() {
         std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
+        mVersion = EffectFactoryHelper::getHalVersion(mFactory);
     }
 
     void SetUp() override {}
@@ -76,6 +76,7 @@
     std::shared_ptr<IFactory> mFactory;
     std::shared_ptr<IEffect> mEffect;
     Descriptor mDescriptor;
+    int mVersion = 0;
 
     void setAndGetParameter(Parameter::Id id, const Parameter& set) {
         Parameter get;
@@ -682,7 +683,7 @@
 
     std::vector<float> buffer;
     EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer));
-    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion));
     EXPECT_NO_FATAL_FAILURE(
             EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer));
 
@@ -722,7 +723,7 @@
     ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
 
     EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer));
-    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion));
     EXPECT_NO_FATAL_FAILURE(
             EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer));
 
@@ -759,7 +760,7 @@
     ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
     ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
     EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer));
-    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion));
     EXPECT_NO_FATAL_FAILURE(
             EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer));
 
@@ -779,7 +780,7 @@
 
     // verify data consume again
     EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer));
-    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion));
     EXPECT_NO_FATAL_FAILURE(
             EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer));
 
@@ -810,7 +811,7 @@
 
     std::vector<float> buffer;
     EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer));
-    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion));
 
     ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
     ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
@@ -844,7 +845,7 @@
 
     std::vector<float> buffer;
     EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer));
-    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion));
     EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer));
 
     ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
@@ -853,7 +854,7 @@
     EXPECT_NO_FATAL_FAILURE(
             EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer));
 
-    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion));
     EXPECT_NO_FATAL_FAILURE(
             EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer));
 
@@ -886,13 +887,13 @@
     ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
     std::vector<float> buffer;
     EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer));
-    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion));
     EXPECT_NO_FATAL_FAILURE(
             EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer));
 
     ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
     ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
-    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion));
     EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer));
 
     ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
@@ -928,7 +929,7 @@
 
     std::vector<float> buffer;
     EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer));
-    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion));
     EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer));
 
     ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
@@ -964,7 +965,7 @@
 
     std::vector<float> buffer1, buffer2;
     EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common1, inputMQ1, buffer1));
-    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ1, inputMQ1, buffer1));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ1, inputMQ1, buffer1, mVersion));
     EXPECT_NO_FATAL_FAILURE(
             EffectHelper::readFromFmq(statusMQ1, 1, outputMQ1, buffer1.size(), buffer1));
 
@@ -975,7 +976,7 @@
     auto outputMQ2 = std::make_unique<EffectHelper::DataMQ>(ret2.outputDataMQ);
     ASSERT_TRUE(outputMQ2->isValid());
     EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common2, inputMQ2, buffer2));
-    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ2, inputMQ2, buffer2));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ2, inputMQ2, buffer2, mVersion));
     EXPECT_NO_FATAL_FAILURE(
             EffectHelper::readFromFmq(statusMQ2, 1, outputMQ2, buffer2.size(), buffer2));
 
diff --git a/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp b/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
index a075423..7a53502 100644
--- a/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
@@ -53,6 +53,7 @@
                 kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
         ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &mOpenEffectReturn, EX_NONE));
         ASSERT_NE(nullptr, mEffect);
+        mVersion = EffectFactoryHelper::getHalVersion(mFactory);
     }
 
     void TearDownLoudnessEnhancer() {
@@ -114,6 +115,7 @@
     std::shared_ptr<IFactory> mFactory;
     std::shared_ptr<IEffect> mEffect;
     Descriptor mDescriptor;
+    int mVersion = 0;
 };
 
 /**
@@ -190,7 +192,8 @@
         ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
 
         // Write from buffer to message queues and calling process
-        EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(mStatusMQ, mInputMQ, mInputBuffer));
+        EXPECT_NO_FATAL_FAILURE(
+                EffectHelper::writeToFmq(mStatusMQ, mInputMQ, mInputBuffer, mVersion));
 
         // Read the updated message queues into buffer
         EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(mStatusMQ, 1, mOutputMQ,
diff --git a/automotive/audiocontrol/aidl/Android.bp b/automotive/audiocontrol/aidl/Android.bp
index c354069..0eb17fe 100644
--- a/automotive/audiocontrol/aidl/Android.bp
+++ b/automotive/audiocontrol/aidl/Android.bp
@@ -27,6 +27,9 @@
                 "com.android.car.framework",
             ],
         },
+        rust: {
+            enabled: true,
+        },
     },
     versions_with_info: [
         {
@@ -100,3 +103,10 @@
         latest_android_hardware_automotive_audiocontrol + "-java",
     ],
 }
+
+rust_defaults {
+    name: "latest_android_hardware_automotive_audiocontrol_rust",
+    rustlibs: [
+        latest_android_hardware_automotive_audiocontrol + "-rust",
+    ],
+}
diff --git a/automotive/audiocontrol/aidl/rust_impl/Android.bp b/automotive/audiocontrol/aidl/rust_impl/Android.bp
new file mode 100644
index 0000000..062d989
--- /dev/null
+++ b/automotive/audiocontrol/aidl/rust_impl/Android.bp
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+rust_binary {
+    name: "android.hardware.automotive.audiocontrol-V4-rust-service",
+    relative_install_path: "hw",
+    vendor: true,
+    srcs: ["src/*.rs"],
+    crate_root: "src/main.rs",
+    defaults: [
+        "latest_android_hardware_automotive_audiocontrol_rust",
+        "latest_android_hardware_audio_common_rust",
+    ],
+    vintf_fragments: ["audiocontrol-rust-service.xml"],
+    init_rc: ["audiocontrol-rust-service.rc"],
+    rustlibs: [
+        "libbinder_rs",
+    ],
+}
diff --git a/automotive/audiocontrol/aidl/rust_impl/README.md b/automotive/audiocontrol/aidl/rust_impl/README.md
new file mode 100644
index 0000000..ed22356
--- /dev/null
+++ b/automotive/audiocontrol/aidl/rust_impl/README.md
@@ -0,0 +1,13 @@
+# Rust Skeleton Audio Control HAL implementation.
+
+WARNING: This is not a reference audio control HAl implementation and does
+not contain any actual implementation.
+
+This folder contains a skeleton audio control HAL implementation in Rust to
+demonstrate  how vendor may implement a Rust audio control HAL. To run this
+audio control HAL, include
+`android.hardware.automotive.audiocontrol-V4-rust-service` in your image.
+
+This implementation returns `StatusCode::UNKNOWN_ERROR` for all operations
+and does not pass VTS/CTS. Vendor must replace the logic in
+`default_audio_control_hal.rs` with the actual implementation.
diff --git a/automotive/audiocontrol/aidl/rust_impl/audiocontrol-rust-service.rc b/automotive/audiocontrol/aidl/rust_impl/audiocontrol-rust-service.rc
new file mode 100644
index 0000000..88d180d
--- /dev/null
+++ b/automotive/audiocontrol/aidl/rust_impl/audiocontrol-rust-service.rc
@@ -0,0 +1,4 @@
+service vendor.audiocontrol-default /vendor/bin/hw/android.hardware.automotive.audiocontrol-service.example
+    class hal
+    user audioserver
+    group system
diff --git a/automotive/audiocontrol/aidl/rust_impl/audiocontrol-rust-service.xml b/automotive/audiocontrol/aidl/rust_impl/audiocontrol-rust-service.xml
new file mode 100644
index 0000000..e54c1d3
--- /dev/null
+++ b/automotive/audiocontrol/aidl/rust_impl/audiocontrol-rust-service.xml
@@ -0,0 +1,23 @@
+<!--
+  ~ 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.
+  -->
+
+<manifest version="2.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.automotive.audiocontrol</name>
+        <version>4</version>
+        <fqname>IAudioControl/default</fqname>
+    </hal>
+</manifest>
diff --git a/automotive/audiocontrol/aidl/rust_impl/src/default_audio_control_hal.rs b/automotive/audiocontrol/aidl/rust_impl/src/default_audio_control_hal.rs
new file mode 100644
index 0000000..ba0ca23
--- /dev/null
+++ b/automotive/audiocontrol/aidl/rust_impl/src/default_audio_control_hal.rs
@@ -0,0 +1,84 @@
+/*
+ * 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.
+ */
+use android_hardware_automotive_audiocontrol::aidl::android::hardware::automotive::audiocontrol::{
+    AudioFocusChange::AudioFocusChange,
+    AudioGainConfigInfo::AudioGainConfigInfo,
+    DuckingInfo::DuckingInfo,
+    IAudioControl::IAudioControl,
+    IAudioGainCallback::IAudioGainCallback,
+    IFocusListener::IFocusListener,
+    IModuleChangeCallback::IModuleChangeCallback,
+    MutingInfo::MutingInfo,
+    Reasons::Reasons,
+};
+use android_hardware_audio_common::aidl::android::hardware::audio::common::PlaybackTrackMetadata::PlaybackTrackMetadata;
+use binder::{Interface, Result as BinderResult, StatusCode, Strong};
+
+/// This struct is defined to implement IAudioControl AIDL interface.
+pub struct DefaultAudioControlHal;
+
+impl Interface for DefaultAudioControlHal {}
+
+impl IAudioControl for DefaultAudioControlHal {
+    fn onAudioFocusChange(&self, _usage : &str, _zone_id : i32, _focus_change : AudioFocusChange
+        ) -> BinderResult<()> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn onDevicesToDuckChange(&self, _ducking_infos : &[DuckingInfo]) -> BinderResult<()> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn onDevicesToMuteChange(&self, _muting_infos : &[MutingInfo]) -> BinderResult<()> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn registerFocusListener(&self, _listener : &Strong<dyn IFocusListener>) -> BinderResult<()> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn setBalanceTowardRight(&self, _value : f32) -> BinderResult<()> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn setFadeTowardFront(&self, _value : f32) -> BinderResult<()> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn onAudioFocusChangeWithMetaData(&self, _playback_metadata : &PlaybackTrackMetadata,
+            _zone_id : i32, _focus_change : AudioFocusChange) -> BinderResult<()> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn setAudioDeviceGainsChanged(&self, _reasons : &[Reasons], _gains : &[AudioGainConfigInfo]
+        ) -> BinderResult<()> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn registerGainCallback(&self, _callback : &Strong<dyn IAudioGainCallback>
+        ) -> BinderResult<()> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn setModuleChangeCallback(&self, _callback : &Strong<dyn IModuleChangeCallback>
+        ) -> BinderResult<()> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn clearModuleChangeCallback(&self) -> BinderResult<()> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+}
diff --git a/automotive/audiocontrol/aidl/rust_impl/src/main.rs b/automotive/audiocontrol/aidl/rust_impl/src/main.rs
new file mode 100644
index 0000000..2ed4810
--- /dev/null
+++ b/automotive/audiocontrol/aidl/rust_impl/src/main.rs
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+mod default_audio_control_hal;
+
+use android_hardware_automotive_audiocontrol::aidl::android::hardware::automotive::audiocontrol::IAudioControl::BnAudioControl;
+use crate::default_audio_control_hal::DefaultAudioControlHal;
+
+fn main() {
+    binder::ProcessState::start_thread_pool();
+    let my_service = DefaultAudioControlHal;
+    let service_name = "android.hardware.automotive.audiocontrol.IAudioControl/default";
+    let my_service_binder = BnAudioControl::new_binder(
+        my_service,
+        binder::BinderFeatures::default(),
+    );
+    binder::add_service(service_name, my_service_binder.as_binder())
+    		.expect(format!("Failed to register {}?", service_name).as_str());
+    // Does not return.
+    binder::ProcessState::join_thread_pool()
+}
diff --git a/automotive/can/1.0/default/tests/fuzzer/Android.bp b/automotive/can/1.0/default/tests/fuzzer/Android.bp
index 01c8a9d..16030d8 100644
--- a/automotive/can/1.0/default/tests/fuzzer/Android.bp
+++ b/automotive/can/1.0/default/tests/fuzzer/Android.bp
@@ -48,7 +48,8 @@
     ],
     fuzz_config: {
         cc: [
-            "android-media-fuzzing-reports@google.com",
+            "chrisweir@google.com",
+            "twasilczyk@google.com",
         ],
         componentid: 533764,
         hotlists: [
diff --git a/automotive/evs/aidl/impl/default/include/EvsVideoEmulatedCamera.h b/automotive/evs/aidl/impl/default/include/EvsVideoEmulatedCamera.h
index a850d65..9d1610a 100644
--- a/automotive/evs/aidl/impl/default/include/EvsVideoEmulatedCamera.h
+++ b/automotive/evs/aidl/impl/default/include/EvsVideoEmulatedCamera.h
@@ -93,6 +93,8 @@
 
     bool initialize();
 
+    bool initializeMediaCodec();
+
     void generateFrames();
 
     void renderOneFrame();
diff --git a/automotive/evs/aidl/impl/default/src/EvsCamera.cpp b/automotive/evs/aidl/impl/default/src/EvsCamera.cpp
index bc3bfdd..005c71f 100644
--- a/automotive/evs/aidl/impl/default/src/EvsCamera.cpp
+++ b/automotive/evs/aidl/impl/default/src/EvsCamera.cpp
@@ -198,9 +198,14 @@
     auto status = ndk::ScopedAStatus::ok();
     {
         std::unique_lock lck(mMutex);
+        if (mStreamState != StreamState::RUNNING) {
+            // We're already in the middle of the procedure to stop current data
+            // stream.
+            return status;
+        }
+
         if ((!preVideoStreamStop_locked(status, lck) || !stopVideoStreamImpl_locked(status, lck) ||
-             !postVideoStreamStop_locked(status, lck)) &&
-            !status.isOk()) {
+             !postVideoStreamStop_locked(status, lck)) && !status.isOk()) {
             needShutdown = true;
         }
     }
diff --git a/automotive/evs/aidl/impl/default/src/EvsVideoEmulatedCamera.cpp b/automotive/evs/aidl/impl/default/src/EvsVideoEmulatedCamera.cpp
index e3f7b5e..480c28d 100644
--- a/automotive/evs/aidl/impl/default/src/EvsVideoEmulatedCamera.cpp
+++ b/automotive/evs/aidl/impl/default/src/EvsVideoEmulatedCamera.cpp
@@ -81,6 +81,10 @@
         }
     }
 
+    return initializeMediaCodec();
+}
+
+bool EvsVideoEmulatedCamera::initializeMediaCodec() {
     // Initialize Media Codec and file format.
     std::unique_ptr<AMediaFormat, FormatDeleter> format;
     const char* mime;
@@ -304,6 +308,13 @@
         LOG(ERROR) << __func__
                    << ": Received error in releasing output buffer. Error code: " << release_status;
     }
+
+    if ((info.flags & AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM) != 0) {
+        LOG(INFO) << "Start video playback from the beginning.";
+        AMediaExtractor_seekTo(mVideoExtractor.get(), /* seekPosUs= */ 0,
+                               AMEDIAEXTRACTOR_SEEK_CLOSEST_SYNC);
+        AMediaCodec_flush(mVideoCodec.get());
+    }
 }
 
 void EvsVideoEmulatedCamera::initializeParameters() {
@@ -337,11 +348,24 @@
         std::unique_lock<std::mutex>& /* lck */) {
     mStream = receiver;
 
-    const media_status_t status = AMediaCodec_start(mVideoCodec.get());
-    if (status != AMEDIA_OK) {
-        LOG(ERROR) << __func__ << ": Received error in starting decoder. Error code: " << status
-                   << ".";
-        return false;
+    if (auto status = AMediaCodec_start(mVideoCodec.get()); status != AMEDIA_OK) {
+        LOG(INFO) << __func__ << ": Received error in starting decoder. "
+                     << "Trying again after resetting this emulated device.";
+
+        if (!initializeMediaCodec()) {
+            LOG(ERROR) << __func__ << ": Failed to re-configure the media codec.";
+            return false;
+        }
+
+        AMediaExtractor_seekTo(mVideoExtractor.get(), /* seekPosUs= */ 0,
+                               AMEDIAEXTRACTOR_SEEK_CLOSEST_SYNC);
+        AMediaCodec_flush(mVideoCodec.get());
+
+        if(auto status = AMediaCodec_start(mVideoCodec.get()); status != AMEDIA_OK) {
+            LOG(ERROR) << __func__ << ": Received error again in starting decoder. "
+                       << "Error code: " << status;
+            return false;
+        }
     }
     mCaptureThread = std::thread([this]() { generateFrames(); });
 
@@ -364,6 +388,12 @@
     if (!Base::postVideoStreamStop_locked(status, lck)) {
         return false;
     }
+
+    EvsEventDesc event = { .aType = EvsEventType::STREAM_STOPPED, };
+    if (auto result = mStream->notify(event); !result.isOk()) {
+        LOG(WARNING) << "Failed to notify the end of the stream.";
+    }
+
     mStream = nullptr;
     return true;
 }
diff --git a/automotive/remoteaccess/test_grpc_server/impl/src/TestWakeupClientServiceImpl.cpp b/automotive/remoteaccess/test_grpc_server/impl/src/TestWakeupClientServiceImpl.cpp
index 5d33fcb..515dc98 100644
--- a/automotive/remoteaccess/test_grpc_server/impl/src/TestWakeupClientServiceImpl.cpp
+++ b/automotive/remoteaccess/test_grpc_server/impl/src/TestWakeupClientServiceImpl.cpp
@@ -169,7 +169,8 @@
     Looper::setForThread(mLooper);
 
     while (true) {
-        mLooper->pollAll(/*timeoutMillis=*/-1);
+        // Don't use pollAll since it might swallow wake.
+        mLooper->pollOnce(/*timeoutMillis=*/-1);
         if (mServerStopped) {
             return;
         }
diff --git a/automotive/remoteaccess/test_grpc_server/impl/test/TestWakeupClientServiceImplUnitTest.cpp b/automotive/remoteaccess/test_grpc_server/impl/test/TestWakeupClientServiceImplUnitTest.cpp
index dd08e32..a7927f5 100644
--- a/automotive/remoteaccess/test_grpc_server/impl/test/TestWakeupClientServiceImplUnitTest.cpp
+++ b/automotive/remoteaccess/test_grpc_server/impl/test/TestWakeupClientServiceImplUnitTest.cpp
@@ -53,6 +53,9 @@
   public:
     virtual void SetUp() override {
         int selectedPort = 0;
+        mServerStarted = false;
+        mService.reset();
+        mServer.reset();
         mServerThread = std::thread([this, &selectedPort] {
             mService = std::make_unique<MyTestWakeupClientServiceImpl>();
             ServerBuilder builder;
diff --git a/automotive/vehicle/aidl/aidl_test/Android.bp b/automotive/vehicle/aidl/aidl_test/Android.bp
index 2dc9ee1..ea6a710 100644
--- a/automotive/vehicle/aidl/aidl_test/Android.bp
+++ b/automotive/vehicle/aidl/aidl_test/Android.bp
@@ -49,7 +49,7 @@
     name: "VehiclePropertyAnnotationJavaTest",
     srcs: [
         "VehiclePropertyAnnotationJavaTest.java",
-        ":IVehicleGeneratedJavaFiles",
+        ":IVehicleGeneratedJavaFiles-V3",
     ],
     static_libs: [
         "android.hardware.automotive.vehicle-V3-java",
diff --git a/automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h b/automotive/vehicle/aidl/generated_lib/3/cpp/AccessForVehicleProperty.h
similarity index 100%
rename from automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h
rename to automotive/vehicle/aidl/generated_lib/3/cpp/AccessForVehicleProperty.h
diff --git a/automotive/vehicle/aidl/generated_lib/cpp/Android.bp b/automotive/vehicle/aidl/generated_lib/3/cpp/Android.bp
similarity index 95%
rename from automotive/vehicle/aidl/generated_lib/cpp/Android.bp
rename to automotive/vehicle/aidl/generated_lib/3/cpp/Android.bp
index 11d3693..83043e5 100644
--- a/automotive/vehicle/aidl/generated_lib/cpp/Android.bp
+++ b/automotive/vehicle/aidl/generated_lib/3/cpp/Android.bp
@@ -19,7 +19,7 @@
 }
 
 cc_library_headers {
-    name: "IVehicleGeneratedHeaders",
+    name: "IVehicleGeneratedHeaders-V3",
     vendor_available: true,
     local_include_dirs: ["."],
     export_include_dirs: ["."],
diff --git a/automotive/vehicle/aidl/generated_lib/cpp/ChangeModeForVehicleProperty.h b/automotive/vehicle/aidl/generated_lib/3/cpp/ChangeModeForVehicleProperty.h
similarity index 100%
rename from automotive/vehicle/aidl/generated_lib/cpp/ChangeModeForVehicleProperty.h
rename to automotive/vehicle/aidl/generated_lib/3/cpp/ChangeModeForVehicleProperty.h
diff --git a/automotive/vehicle/aidl/generated_lib/cpp/VersionForVehicleProperty.h b/automotive/vehicle/aidl/generated_lib/3/cpp/VersionForVehicleProperty.h
similarity index 100%
rename from automotive/vehicle/aidl/generated_lib/cpp/VersionForVehicleProperty.h
rename to automotive/vehicle/aidl/generated_lib/3/cpp/VersionForVehicleProperty.h
diff --git a/automotive/vehicle/aidl/generated_lib/java/AccessForVehicleProperty.java b/automotive/vehicle/aidl/generated_lib/3/java/AccessForVehicleProperty.java
similarity index 100%
rename from automotive/vehicle/aidl/generated_lib/java/AccessForVehicleProperty.java
rename to automotive/vehicle/aidl/generated_lib/3/java/AccessForVehicleProperty.java
diff --git a/automotive/vehicle/aidl/generated_lib/java/Android.bp b/automotive/vehicle/aidl/generated_lib/3/java/Android.bp
similarity index 94%
rename from automotive/vehicle/aidl/generated_lib/java/Android.bp
rename to automotive/vehicle/aidl/generated_lib/3/java/Android.bp
index 1d612e8..b98fcbd 100644
--- a/automotive/vehicle/aidl/generated_lib/java/Android.bp
+++ b/automotive/vehicle/aidl/generated_lib/3/java/Android.bp
@@ -19,7 +19,7 @@
 }
 
 filegroup {
-    name: "IVehicleGeneratedJavaFiles",
+    name: "IVehicleGeneratedJavaFiles-V3",
     srcs: [
         "*.java",
     ],
diff --git a/automotive/vehicle/aidl/generated_lib/java/ChangeModeForVehicleProperty.java b/automotive/vehicle/aidl/generated_lib/3/java/ChangeModeForVehicleProperty.java
similarity index 100%
rename from automotive/vehicle/aidl/generated_lib/java/ChangeModeForVehicleProperty.java
rename to automotive/vehicle/aidl/generated_lib/3/java/ChangeModeForVehicleProperty.java
diff --git a/automotive/vehicle/aidl/generated_lib/java/EnumForVehicleProperty.java b/automotive/vehicle/aidl/generated_lib/3/java/EnumForVehicleProperty.java
similarity index 100%
rename from automotive/vehicle/aidl/generated_lib/java/EnumForVehicleProperty.java
rename to automotive/vehicle/aidl/generated_lib/3/java/EnumForVehicleProperty.java
diff --git a/automotive/vehicle/aidl/generated_lib/java/UnitsForVehicleProperty.java b/automotive/vehicle/aidl/generated_lib/3/java/UnitsForVehicleProperty.java
similarity index 100%
rename from automotive/vehicle/aidl/generated_lib/java/UnitsForVehicleProperty.java
rename to automotive/vehicle/aidl/generated_lib/3/java/UnitsForVehicleProperty.java
diff --git a/automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h b/automotive/vehicle/aidl/generated_lib/4/cpp/AccessForVehicleProperty.h
similarity index 100%
copy from automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h
copy to automotive/vehicle/aidl/generated_lib/4/cpp/AccessForVehicleProperty.h
diff --git a/automotive/vehicle/aidl/generated_lib/cpp/Android.bp b/automotive/vehicle/aidl/generated_lib/4/cpp/Android.bp
similarity index 81%
copy from automotive/vehicle/aidl/generated_lib/cpp/Android.bp
copy to automotive/vehicle/aidl/generated_lib/4/cpp/Android.bp
index 11d3693..6ece865 100644
--- a/automotive/vehicle/aidl/generated_lib/cpp/Android.bp
+++ b/automotive/vehicle/aidl/generated_lib/4/cpp/Android.bp
@@ -25,3 +25,11 @@
     export_include_dirs: ["."],
     defaults: ["VehicleHalInterfaceDefaults"],
 }
+
+cc_library_headers {
+    name: "IVehicleGeneratedHeaders-V4",
+    vendor_available: true,
+    local_include_dirs: ["."],
+    export_include_dirs: ["."],
+    defaults: ["VehicleHalInterfaceDefaults"],
+}
diff --git a/automotive/vehicle/aidl/generated_lib/cpp/ChangeModeForVehicleProperty.h b/automotive/vehicle/aidl/generated_lib/4/cpp/ChangeModeForVehicleProperty.h
similarity index 100%
copy from automotive/vehicle/aidl/generated_lib/cpp/ChangeModeForVehicleProperty.h
copy to automotive/vehicle/aidl/generated_lib/4/cpp/ChangeModeForVehicleProperty.h
diff --git a/automotive/vehicle/aidl/generated_lib/cpp/VersionForVehicleProperty.h b/automotive/vehicle/aidl/generated_lib/4/cpp/VersionForVehicleProperty.h
similarity index 100%
copy from automotive/vehicle/aidl/generated_lib/cpp/VersionForVehicleProperty.h
copy to automotive/vehicle/aidl/generated_lib/4/cpp/VersionForVehicleProperty.h
diff --git a/automotive/vehicle/aidl/generated_lib/java/AccessForVehicleProperty.java b/automotive/vehicle/aidl/generated_lib/4/java/AccessForVehicleProperty.java
similarity index 100%
copy from automotive/vehicle/aidl/generated_lib/java/AccessForVehicleProperty.java
copy to automotive/vehicle/aidl/generated_lib/4/java/AccessForVehicleProperty.java
diff --git a/automotive/vehicle/aidl/generated_lib/java/Android.bp b/automotive/vehicle/aidl/generated_lib/4/java/Android.bp
similarity index 89%
copy from automotive/vehicle/aidl/generated_lib/java/Android.bp
copy to automotive/vehicle/aidl/generated_lib/4/java/Android.bp
index 1d612e8..f3c96f5 100644
--- a/automotive/vehicle/aidl/generated_lib/java/Android.bp
+++ b/automotive/vehicle/aidl/generated_lib/4/java/Android.bp
@@ -24,3 +24,10 @@
         "*.java",
     ],
 }
+
+filegroup {
+    name: "IVehicleGeneratedJavaFiles-V4",
+    srcs: [
+        "*.java",
+    ],
+}
diff --git a/automotive/vehicle/aidl/generated_lib/java/ChangeModeForVehicleProperty.java b/automotive/vehicle/aidl/generated_lib/4/java/ChangeModeForVehicleProperty.java
similarity index 100%
copy from automotive/vehicle/aidl/generated_lib/java/ChangeModeForVehicleProperty.java
copy to automotive/vehicle/aidl/generated_lib/4/java/ChangeModeForVehicleProperty.java
diff --git a/automotive/vehicle/aidl/generated_lib/java/EnumForVehicleProperty.java b/automotive/vehicle/aidl/generated_lib/4/java/EnumForVehicleProperty.java
similarity index 100%
copy from automotive/vehicle/aidl/generated_lib/java/EnumForVehicleProperty.java
copy to automotive/vehicle/aidl/generated_lib/4/java/EnumForVehicleProperty.java
diff --git a/automotive/vehicle/aidl/generated_lib/java/UnitsForVehicleProperty.java b/automotive/vehicle/aidl/generated_lib/4/java/UnitsForVehicleProperty.java
similarity index 100%
copy from automotive/vehicle/aidl/generated_lib/java/UnitsForVehicleProperty.java
copy to automotive/vehicle/aidl/generated_lib/4/java/UnitsForVehicleProperty.java
diff --git a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/Android.bp b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/Android.bp
index 75a3541..0a33e5b 100644
--- a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/Android.bp
+++ b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/Android.bp
@@ -27,7 +27,7 @@
     defaults: ["VehicleHalDefaults"],
     static_libs: ["VehicleHalUtils"],
     header_libs: [
-        "IVehicleGeneratedHeaders",
+        "IVehicleGeneratedHeaders-V3",
     ],
     shared_libs: ["libjsoncpp"],
 }
@@ -44,7 +44,7 @@
     defaults: ["VehicleHalDefaults"],
     static_libs: ["VehicleHalUtils"],
     header_libs: [
-        "IVehicleGeneratedHeaders",
+        "IVehicleGeneratedHeaders-V3",
         "libbinder_headers",
     ],
     cflags: ["-DENABLE_VEHICLE_HAL_TEST_PROPERTIES"],
@@ -59,7 +59,7 @@
     defaults: ["VehicleHalDefaults"],
     static_libs: ["VehicleHalUtils"],
     header_libs: [
-        "IVehicleGeneratedHeaders",
+        "IVehicleGeneratedHeaders-V3",
     ],
     shared_libs: ["libjsoncpp"],
 }
diff --git a/automotive/vehicle/aidl/impl/default_config/test/Android.bp b/automotive/vehicle/aidl/impl/default_config/test/Android.bp
index 651ed90..70933be 100644
--- a/automotive/vehicle/aidl/impl/default_config/test/Android.bp
+++ b/automotive/vehicle/aidl/impl/default_config/test/Android.bp
@@ -31,7 +31,7 @@
         "libgtest",
     ],
     header_libs: [
-        "IVehicleGeneratedHeaders",
+        "IVehicleGeneratedHeaders-V3",
     ],
     shared_libs: [
         "libjsoncpp",
@@ -57,7 +57,7 @@
         "-DENABLE_VEHICLE_HAL_TEST_PROPERTIES",
     ],
     header_libs: [
-        "IVehicleGeneratedHeaders",
+        "IVehicleGeneratedHeaders-V3",
     ],
     shared_libs: [
         "libjsoncpp",
diff --git a/automotive/vehicle/aidl/impl/vhal/Android.bp b/automotive/vehicle/aidl/impl/vhal/Android.bp
index ae1102f..5cc071d 100644
--- a/automotive/vehicle/aidl/impl/vhal/Android.bp
+++ b/automotive/vehicle/aidl/impl/vhal/Android.bp
@@ -66,7 +66,7 @@
     ],
     header_libs: [
         "IVehicleHardware",
-        "IVehicleGeneratedHeaders",
+        "IVehicleGeneratedHeaders-V3",
     ],
     shared_libs: [
         "libbinder_ndk",
diff --git a/automotive/vehicle/tools/generate_annotation_enums.py b/automotive/vehicle/tools/generate_annotation_enums.py
index f279767..460e9f9 100755
--- a/automotive/vehicle/tools/generate_annotation_enums.py
+++ b/automotive/vehicle/tools/generate_annotation_enums.py
@@ -17,9 +17,9 @@
 """A script to generate Java files and CPP header files based on annotations in VehicleProperty.aidl
 
    Need ANDROID_BUILD_TOP environmental variable to be set. This script will update
-   ChangeModeForVehicleProperty.h and AccessForVehicleProperty.h under generated_lib/cpp and
+   ChangeModeForVehicleProperty.h and AccessForVehicleProperty.h under generated_lib/version/cpp and
    ChangeModeForVehicleProperty.java, AccessForVehicleProperty.java, EnumForVehicleProperty.java
-   UnitsForVehicleProperty.java under generated_lib/java.
+   UnitsForVehicleProperty.java under generated_lib/version/java.
 
    Usage:
    $ python generate_annotation_enums.py
@@ -31,22 +31,20 @@
 import sys
 import tempfile
 
+# Keep this updated with the latest in-development property version.
+PROPERTY_VERSION = '4'
+
 PROP_AIDL_FILE_PATH = ('hardware/interfaces/automotive/vehicle/aidl_property/android/hardware/' +
     'automotive/vehicle/VehicleProperty.aidl')
-CHANGE_MODE_CPP_FILE_PATH = ('hardware/interfaces/automotive/vehicle/aidl/generated_lib/cpp/' +
-    'ChangeModeForVehicleProperty.h')
-ACCESS_CPP_FILE_PATH = ('hardware/interfaces/automotive/vehicle/aidl/generated_lib/cpp/' +
-    'AccessForVehicleProperty.h')
-CHANGE_MODE_JAVA_FILE_PATH = ('hardware/interfaces/automotive/vehicle/aidl/generated_lib/java/' +
-    'ChangeModeForVehicleProperty.java')
-ACCESS_JAVA_FILE_PATH = ('hardware/interfaces/automotive/vehicle/aidl/generated_lib/java/' +
-    'AccessForVehicleProperty.java')
-ENUM_JAVA_FILE_PATH = ('hardware/interfaces/automotive/vehicle/aidl/generated_lib/java/' +
-                         'EnumForVehicleProperty.java')
-UNITS_JAVA_FILE_PATH = ('hardware/interfaces/automotive/vehicle/aidl/generated_lib/java/' +
-                       'UnitsForVehicleProperty.java')
-VERSION_CPP_FILE_PATH = ('hardware/interfaces/automotive/vehicle/aidl/generated_lib/cpp/' +
-    'VersionForVehicleProperty.h')
+GENERATED_LIB = ('hardware/interfaces/automotive/vehicle/aidl/generated_lib/' + PROPERTY_VERSION +
+        '/')
+CHANGE_MODE_CPP_FILE_PATH = GENERATED_LIB + '/cpp/ChangeModeForVehicleProperty.h'
+ACCESS_CPP_FILE_PATH = GENERATED_LIB + '/cpp/AccessForVehicleProperty.h'
+CHANGE_MODE_JAVA_FILE_PATH = GENERATED_LIB + '/java/ChangeModeForVehicleProperty.java'
+ACCESS_JAVA_FILE_PATH = GENERATED_LIB + '/java/AccessForVehicleProperty.java'
+ENUM_JAVA_FILE_PATH = GENERATED_LIB + '/java/EnumForVehicleProperty.java'
+UNITS_JAVA_FILE_PATH = GENERATED_LIB + '/java/UnitsForVehicleProperty.java'
+VERSION_CPP_FILE_PATH = GENERATED_LIB + '/cpp/VersionForVehicleProperty.h'
 SCRIPT_PATH = 'hardware/interfaces/automotive/vehicle/tools/generate_annotation_enums.py'
 
 TAB = '    '
diff --git a/automotive/vehicle/vts/Android.bp b/automotive/vehicle/vts/Android.bp
index 67d0d34..40aec59 100644
--- a/automotive/vehicle/vts/Android.bp
+++ b/automotive/vehicle/vts/Android.bp
@@ -43,7 +43,7 @@
         "vhalclient_defaults",
     ],
     header_libs: [
-        "IVehicleGeneratedHeaders",
+        "IVehicleGeneratedHeaders-V3",
     ],
     test_suites: [
         "general-tests",
diff --git a/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp b/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
index 30661a2..608a328 100644
--- a/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
+++ b/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
@@ -603,6 +603,7 @@
                      << "skip testing";
     }
 
+    // Subscribe to PERF_VEHICLE_SPEED using the max sample rate.
     auto client = mVhalClient->getSubscriptionClient(mCallback);
     ASSERT_NE(client, nullptr) << "Failed to get subscription client";
     SubscribeOptionsBuilder builder(propId);
@@ -616,18 +617,17 @@
                                              ", error: %s",
                                              propId, result.error().message().c_str());
 
-    ASSERT_TRUE(mCallback->waitForExpectedEvents(propId, 1, std::chrono::seconds(2)))
-            << "Must get at least 1 events within 2 seconds after subscription for rate: "
-            << maxSampleRate;
-
     // Sleep for 1 seconds to wait for more possible events to arrive.
     std::this_thread::sleep_for(std::chrono::seconds(1));
 
     client->unsubscribe({propId});
 
     auto events = mCallback->getEvents(propId);
-    if (events.size() == 1) {
-        // We only received one event, the value is not changing so nothing to check here.
+    if (events.size() <= 1) {
+        // We received 0 or 1 event, the value is not changing so nothing to check here.
+        // If all VHAL clients are subscribing to PERF_VEHICLE_SPEED with VUR on, then we
+        // will receive 0 event. If there are other VHAL clients subscribing to PERF_VEHICLE_SPEED
+        // with VUR off, then we will receive 1 event which is the initial value.
         return;
     }
 
diff --git a/biometrics/OWNERS b/biometrics/OWNERS
index 58998c1..a0a5e51 100644
--- a/biometrics/OWNERS
+++ b/biometrics/OWNERS
@@ -1,8 +1,10 @@
-ilyamaty@google.com
+# Bug component: 879035
+
+include platform/frameworks/base:/services/core/java/com/android/server/biometrics/OWNERS
+
 jeffpu@google.com
 jbolinger@google.com
 joshmccloskey@google.com
 diyab@google.com
 austindelgado@google.com
 spdonghao@google.com
-wenhuiy@google.com
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfoAndVendorCode.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfoAndVendorCode.aidl
new file mode 100644
index 0000000..c1dc51c
--- /dev/null
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfoAndVendorCode.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.biometrics.fingerprint;
+/* @hide */
+@VintfStability
+union AcquiredInfoAndVendorCode {
+  android.hardware.biometrics.fingerprint.AcquiredInfo acquiredInfo = android.hardware.biometrics.fingerprint.AcquiredInfo.UNKNOWN;
+  int vendorCode;
+}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/EnrollmentProgressStep.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/EnrollmentProgressStep.aidl
new file mode 100644
index 0000000..173ac17
--- /dev/null
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/EnrollmentProgressStep.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.biometrics.fingerprint;
+/* @hide */
+@VintfStability
+parcelable EnrollmentProgressStep {
+  int durationMs;
+  android.hardware.biometrics.fingerprint.AcquiredInfoAndVendorCode[] acquiredInfoAndVendorCodes;
+}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IVirtualHal.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IVirtualHal.aidl
index 2c7e1a0..33ae83c 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IVirtualHal.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IVirtualHal.aidl
@@ -37,24 +37,26 @@
 interface IVirtualHal {
   oneway void setEnrollments(in int[] id);
   oneway void setEnrollmentHit(in int hit_id);
+  oneway void setNextEnrollment(in android.hardware.biometrics.fingerprint.NextEnrollment next_enrollment);
   oneway void setAuthenticatorId(in long id);
   oneway void setChallenge(in long challenge);
   oneway void setOperationAuthenticateFails(in boolean fail);
   oneway void setOperationAuthenticateLatency(in int[] latencyMs);
   oneway void setOperationAuthenticateDuration(in int durationMs);
   oneway void setOperationAuthenticateError(in int error);
-  oneway void setOperationAuthenticateAcquired(in int[] acquired);
+  oneway void setOperationAuthenticateAcquired(in android.hardware.biometrics.fingerprint.AcquiredInfoAndVendorCode[] acquired);
   oneway void setOperationEnrollError(in int error);
   oneway void setOperationEnrollLatency(in int[] latencyMs);
   oneway void setOperationDetectInteractionLatency(in int[] latencyMs);
   oneway void setOperationDetectInteractionError(in int error);
   oneway void setOperationDetectInteractionDuration(in int durationMs);
-  oneway void setOperationDetectInteractionAcquired(in int[] acquired);
+  oneway void setOperationDetectInteractionAcquired(in android.hardware.biometrics.fingerprint.AcquiredInfoAndVendorCode[] acquired);
   oneway void setLockout(in boolean lockout);
   oneway void setLockoutEnable(in boolean enable);
   oneway void setLockoutTimedThreshold(in int threshold);
   oneway void setLockoutTimedDuration(in int durationMs);
   oneway void setLockoutPermanentThreshold(in int threshold);
+  oneway void resetConfigurations();
   oneway void setType(in android.hardware.biometrics.fingerprint.FingerprintSensorType type);
   oneway void setSensorId(in int id);
   oneway void setSensorStrength(in android.hardware.biometrics.common.SensorStrength strength);
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/NextEnrollment.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/NextEnrollment.aidl
new file mode 100644
index 0000000..75ed070
--- /dev/null
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/NextEnrollment.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.biometrics.fingerprint;
+/* @hide */
+@VintfStability
+parcelable NextEnrollment {
+  int id;
+  android.hardware.biometrics.fingerprint.EnrollmentProgressStep[] progressSteps;
+  boolean result = true;
+}
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfoAndVendorCode.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfoAndVendorCode.aidl
new file mode 100644
index 0000000..c7be950
--- /dev/null
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfoAndVendorCode.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.biometrics.fingerprint;
+
+import android.hardware.biometrics.fingerprint.AcquiredInfo;
+
+/**
+ * @hide
+ */
+@VintfStability
+union AcquiredInfoAndVendorCode {
+    /**
+     * Acquired info as specified in AcqauiredInfo.aidl
+     */
+    AcquiredInfo acquiredInfo = AcquiredInfo.UNKNOWN;
+
+    /**
+     * Vendor specific code
+     */
+    int vendorCode;
+}
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/EnrollmentProgressStep.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/EnrollmentProgressStep.aidl
new file mode 100644
index 0000000..bf038f6
--- /dev/null
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/EnrollmentProgressStep.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.biometrics.fingerprint;
+
+import android.hardware.biometrics.fingerprint.AcquiredInfoAndVendorCode;
+
+/**
+ * @hide
+ */
+@VintfStability
+parcelable EnrollmentProgressStep {
+    /**
+     * The duration of the enrollment step in milli-seconds
+     */
+    int durationMs;
+
+    /**
+     * The sequence of acquired info and vendor code to be issued by HAL during the step.
+     * The codes are evenly spreaded over the duration
+     */
+    AcquiredInfoAndVendorCode[] acquiredInfoAndVendorCodes;
+}
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IVirtualHal.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IVirtualHal.aidl
index 1599394..cb9135e 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IVirtualHal.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IVirtualHal.aidl
@@ -17,7 +17,9 @@
 package android.hardware.biometrics.fingerprint;
 
 import android.hardware.biometrics.common.SensorStrength;
+import android.hardware.biometrics.fingerprint.AcquiredInfoAndVendorCode;
 import android.hardware.biometrics.fingerprint.FingerprintSensorType;
+import android.hardware.biometrics.fingerprint.NextEnrollment;
 import android.hardware.biometrics.fingerprint.SensorLocation;
 
 /**
@@ -54,6 +56,15 @@
     void setEnrollmentHit(in int hit_id);
 
     /**
+     * setNextEnrollment
+     *
+     * Set the next enrollment behavior
+     *
+     * @param next_enrollment specifies enrollment id, progress stages and final result
+     */
+    void setNextEnrollment(in NextEnrollment next_enrollment);
+
+    /**
      * setAuthenticatorId
      *
      * Set authenticator id in virtual HAL, the id is returned in ISession#getAuthenticatorId() call
@@ -137,7 +148,7 @@
      *
      * @param acquired[], one or more acquired info codes
      */
-    void setOperationAuthenticateAcquired(in int[] acquired);
+    void setOperationAuthenticateAcquired(in AcquiredInfoAndVendorCode[] acquired);
 
     /**
      * setOperationEnrollError
@@ -226,7 +237,7 @@
      *
      * @param acquired[], one or more acquired info codes
      */
-    void setOperationDetectInteractionAcquired(in int[] acquired);
+    void setOperationDetectInteractionAcquired(in AcquiredInfoAndVendorCode[] acquired);
 
     /**
      * setLockout
@@ -285,6 +296,13 @@
     void setLockoutPermanentThreshold(in int threshold);
 
     /**
+     * resetConfigurations
+     *
+     * Reset all virtual hal configurations to default values
+     */
+    void resetConfigurations();
+
+    /**
      * The following functions are used to configure Fingerprint Virtual HAL sensor properties
      *  refer to SensorProps.aidl and CommonProps.aidl for details of each property
      */
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/NextEnrollment.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/NextEnrollment.aidl
new file mode 100644
index 0000000..4b50850
--- /dev/null
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/NextEnrollment.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.biometrics.fingerprint;
+
+/**
+ * @hide
+ */
+@VintfStability
+parcelable NextEnrollment {
+    /**
+     *  Identifier of the next enrollment if successful
+     */
+    int id;
+
+    /**
+     *  Specification of the progress steps of the next enrollment, each step consists of duration
+     *  and sequence of acquired info codes to be generated by HAL.
+     *  See EnrollmentProgressStep.aidl for more details
+     */
+    android.hardware.biometrics.fingerprint.EnrollmentProgressStep[] progressSteps;
+
+    /**
+     * Success or failure of the next enrollment
+     */
+    boolean result = true;
+}
diff --git a/biometrics/fingerprint/aidl/default/VirtualHal.cpp b/biometrics/fingerprint/aidl/default/VirtualHal.cpp
index d2baaf5..e107d2f 100644
--- a/biometrics/fingerprint/aidl/default/VirtualHal.cpp
+++ b/biometrics/fingerprint/aidl/default/VirtualHal.cpp
@@ -27,6 +27,8 @@
 
 namespace aidl::android::hardware::biometrics::fingerprint {
 
+using Tag = AcquiredInfoAndVendorCode::Tag;
+
 ::ndk::ScopedAStatus VirtualHal::setEnrollments(const std::vector<int32_t>& enrollments) {
     Fingerprint::cfg().sourcedFromAidl();
     Fingerprint::cfg().setopt<OptIntVec>("enrollments", intVec2OptIntVec(enrollments));
@@ -39,6 +41,42 @@
     return ndk::ScopedAStatus::ok();
 }
 
+::ndk::ScopedAStatus VirtualHal::setNextEnrollment(
+        const ::aidl::android::hardware::biometrics::fingerprint::NextEnrollment& next_enrollment) {
+    Fingerprint::cfg().sourcedFromAidl();
+    std::ostringstream os;
+    os << next_enrollment.id << ":";
+
+    int stepSize = next_enrollment.progressSteps.size();
+    for (int i = 0; i < stepSize; i++) {
+        auto& step = next_enrollment.progressSteps[i];
+        os << step.durationMs;
+        int acSize = step.acquiredInfoAndVendorCodes.size();
+        for (int j = 0; j < acSize; j++) {
+            if (j == 0) os << "-[";
+            auto& acquiredInfoAndVendorCode = step.acquiredInfoAndVendorCodes[j];
+            if (acquiredInfoAndVendorCode.getTag() == AcquiredInfoAndVendorCode::vendorCode)
+                os << acquiredInfoAndVendorCode.get<Tag::vendorCode>();
+            else if (acquiredInfoAndVendorCode.getTag() == AcquiredInfoAndVendorCode::acquiredInfo)
+                os << (int)acquiredInfoAndVendorCode.get<Tag::acquiredInfo>();
+            else
+                LOG(FATAL) << "ERROR: wrong AcquiredInfoAndVendorCode union tag";
+            if (j == acSize - 1)
+                os << "]";
+            else
+                os << ",";
+        }
+        if (i == stepSize - 1)
+            os << ":";
+        else
+            os << ",";
+    }
+
+    os << (next_enrollment.result ? "true" : "false");
+    Fingerprint::cfg().set<std::string>("next_enrollment", os.str());
+    return ndk::ScopedAStatus::ok();
+}
+
 ::ndk::ScopedAStatus VirtualHal::setAuthenticatorId(int64_t in_id) {
     Fingerprint::cfg().sourcedFromAidl();
     Fingerprint::cfg().set<int64_t>("authenticator_id", in_id);
@@ -87,10 +125,10 @@
 }
 
 ::ndk::ScopedAStatus VirtualHal::setOperationAuthenticateAcquired(
-        const std::vector<int32_t>& in_acquired) {
+        const std::vector<AcquiredInfoAndVendorCode>& in_acquired) {
     Fingerprint::cfg().sourcedFromAidl();
     Fingerprint::cfg().setopt<OptIntVec>("operation_authenticate_acquired",
-                                         intVec2OptIntVec(in_acquired));
+                                         acquiredInfoVec2OptIntVec(in_acquired));
     return ndk::ScopedAStatus::ok();
 }
 
@@ -139,10 +177,10 @@
 }
 
 ::ndk::ScopedAStatus VirtualHal::setOperationDetectInteractionAcquired(
-        const std::vector<int32_t>& in_acquired) {
+        const std::vector<AcquiredInfoAndVendorCode>& in_acquired) {
     Fingerprint::cfg().sourcedFromAidl();
     Fingerprint::cfg().setopt<OptIntVec>("operation_detect_interaction_acquired",
-                                         intVec2OptIntVec(in_acquired));
+                                         acquiredInfoVec2OptIntVec(in_acquired));
     return ndk::ScopedAStatus::ok();
 }
 
@@ -188,6 +226,12 @@
     return ndk::ScopedAStatus::ok();
 }
 
+::ndk::ScopedAStatus VirtualHal::resetConfigurations() {
+    Fingerprint::cfg().sourcedFromAidl();
+    Fingerprint::cfg().init();
+    return ndk::ScopedAStatus::ok();
+}
+
 ::ndk::ScopedAStatus VirtualHal::setType(
         ::aidl::android::hardware::biometrics::fingerprint::FingerprintSensorType in_type) {
     Fingerprint::cfg().sourcedFromAidl();
@@ -254,6 +298,23 @@
     return optIntVec;
 }
 
+OptIntVec VirtualHal::acquiredInfoVec2OptIntVec(
+        const std::vector<AcquiredInfoAndVendorCode>& in_vec) {
+    OptIntVec optIntVec;
+    std::transform(in_vec.begin(), in_vec.end(), std::back_inserter(optIntVec),
+                   [](AcquiredInfoAndVendorCode ac) {
+                       int value;
+                       if (ac.getTag() == AcquiredInfoAndVendorCode::acquiredInfo)
+                           value = (int)ac.get<Tag::acquiredInfo>();
+                       else if (ac.getTag() == AcquiredInfoAndVendorCode::vendorCode)
+                           value = ac.get<Tag::vendorCode>();
+                       else
+                           LOG(FATAL) << "ERROR: wrong AcquiredInfoAndVendorCode tag";
+                       return std::optional<int>(value);
+                   });
+    return optIntVec;
+}
+
 ::ndk::ScopedAStatus VirtualHal::sanityCheckLatency(const std::vector<int32_t>& in_latency) {
     if (in_latency.size() == 0 || in_latency.size() > 2) {
         return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
diff --git a/biometrics/fingerprint/aidl/default/include/VirtualHal.h b/biometrics/fingerprint/aidl/default/include/VirtualHal.h
index 6cc4b66..e5f62fc 100644
--- a/biometrics/fingerprint/aidl/default/include/VirtualHal.h
+++ b/biometrics/fingerprint/aidl/default/include/VirtualHal.h
@@ -28,6 +28,9 @@
 
     ::ndk::ScopedAStatus setEnrollments(const std::vector<int32_t>& in_id) override;
     ::ndk::ScopedAStatus setEnrollmentHit(int32_t in_hit_id) override;
+    ::ndk::ScopedAStatus setNextEnrollment(
+            const ::aidl::android::hardware::biometrics::fingerprint::NextEnrollment&
+                    in_next_enrollment) override;
     ::ndk::ScopedAStatus setAuthenticatorId(int64_t in_id) override;
     ::ndk::ScopedAStatus setChallenge(int64_t in_challenge) override;
     ::ndk::ScopedAStatus setOperationAuthenticateFails(bool in_fail) override;
@@ -36,7 +39,7 @@
     ::ndk::ScopedAStatus setOperationAuthenticateDuration(int32_t in_duration) override;
     ::ndk::ScopedAStatus setOperationAuthenticateError(int32_t in_error) override;
     ::ndk::ScopedAStatus setOperationAuthenticateAcquired(
-            const std::vector<int32_t>& in_acquired) override;
+            const std::vector<AcquiredInfoAndVendorCode>& in_acquired) override;
     ::ndk::ScopedAStatus setOperationEnrollError(int32_t in_error) override;
     ::ndk::ScopedAStatus setOperationEnrollLatency(const std::vector<int32_t>& in_latency) override;
     ::ndk::ScopedAStatus setOperationDetectInteractionLatency(
@@ -44,12 +47,13 @@
     ::ndk::ScopedAStatus setOperationDetectInteractionError(int32_t in_error) override;
     ::ndk::ScopedAStatus setOperationDetectInteractionDuration(int32_t in_duration) override;
     ::ndk::ScopedAStatus setOperationDetectInteractionAcquired(
-            const std::vector<int32_t>& in_acquired) override;
+            const std::vector<AcquiredInfoAndVendorCode>& in_acquired) override;
     ::ndk::ScopedAStatus setLockout(bool in_lockout) override;
     ::ndk::ScopedAStatus setLockoutEnable(bool in_enable) override;
     ::ndk::ScopedAStatus setLockoutTimedThreshold(int32_t in_threshold) override;
     ::ndk::ScopedAStatus setLockoutTimedDuration(int32_t in_duration) override;
     ::ndk::ScopedAStatus setLockoutPermanentThreshold(int32_t in_threshold) override;
+    ::ndk::ScopedAStatus resetConfigurations() override;
     ::ndk::ScopedAStatus setType(
             ::aidl::android::hardware::biometrics::fingerprint::FingerprintSensorType in_type)
             override;
@@ -66,6 +70,7 @@
 
   private:
     OptIntVec intVec2OptIntVec(const std::vector<int32_t>& intVec);
+    OptIntVec acquiredInfoVec2OptIntVec(const std::vector<AcquiredInfoAndVendorCode>& intVec);
     ::ndk::ScopedAStatus sanityCheckLatency(const std::vector<int32_t>& in_latency);
     Fingerprint* mFp;
 };
diff --git a/biometrics/fingerprint/aidl/default/tests/VirtualHalTest.cpp b/biometrics/fingerprint/aidl/default/tests/VirtualHalTest.cpp
index d8495d1..3fe0b2a 100644
--- a/biometrics/fingerprint/aidl/default/tests/VirtualHalTest.cpp
+++ b/biometrics/fingerprint/aidl/default/tests/VirtualHalTest.cpp
@@ -100,6 +100,27 @@
     ASSERT_TRUE(Fingerprint::cfg().get<int32_t>("enrollment_hit") == 11);
 }
 
+TEST_F(VirtualHalTest, next_enrollment) {
+    struct {
+        std::string nextEnrollmentStr;
+        fingerprint::NextEnrollment nextEnrollment;
+    } testData[] = {
+            {"1:20:true", {1, {{20}}, true}},
+            {"1:50,60,70:true", {1, {{50}, {60}, {70}}, true}},
+            {"2:50-[8],60,70-[2,1002,1]:false",
+             {2,
+              {{50, {{AcquiredInfo::START}}},
+               {60},
+               {70, {{AcquiredInfo::PARTIAL}, {1002}, {AcquiredInfo::GOOD}}}},
+              false}},
+    };
+
+    for (auto& d : testData) {
+        mVhal->setNextEnrollment(d.nextEnrollment);
+        ASSERT_TRUE(Fingerprint::cfg().get<std::string>("next_enrollment") == d.nextEnrollmentStr);
+    }
+}
+
 TEST_F(VirtualHalTest, authenticator_id_int64) {
     mVhal->setAuthenticatorId(12345678900);
     ASSERT_TRUE(Fingerprint::cfg().get<int64_t>("authenticator_id") == 12345678900);
@@ -111,12 +132,16 @@
 }
 
 TEST_F(VirtualHalTest, operationAuthenticateAcquired_int32_vector) {
-    std::vector<int32_t> ac{1, 2, 3, 4, 5, 6, 7};
+    using Tag = AcquiredInfoAndVendorCode::Tag;
+    std::vector<AcquiredInfoAndVendorCode> ac{
+            {AcquiredInfo::START}, {AcquiredInfo::PARTIAL}, {1023}};
     mVhal->setOperationAuthenticateAcquired(ac);
     OptIntVec ac_get = Fingerprint::cfg().getopt<OptIntVec>("operation_authenticate_acquired");
     ASSERT_TRUE(ac_get.size() == ac.size());
     for (int i = 0; i < ac.size(); i++) {
-        ASSERT_TRUE(ac[i] == ac_get[i]);
+        int acCode = (ac[i].getTag() == Tag::acquiredInfo) ? (int)ac[i].get<Tag::acquiredInfo>()
+                                                           : ac[i].get<Tag::vendorCode>();
+        ASSERT_TRUE(acCode == ac_get[i]);
     }
 }
 
@@ -212,7 +237,7 @@
     mVhal->setOperationEnrollError(5);
     mVhal->setOperationEnrollLatency({4, 5});
     mVhal->setOperationDetectInteractionError(6);
-    mVhal->setOperationDetectInteractionAcquired({4, 3, 2});
+    mVhal->setOperationDetectInteractionAcquired({{AcquiredInfo::START}, {AcquiredInfo::GOOD}});
     mVhal->setLockout(false);
     mVhal->setLockoutEnable(false);
     mVhal->setSensorId(5);
diff --git a/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp b/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp
index 140b956..aaf436f 100644
--- a/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp
+++ b/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp
@@ -1095,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/utils/Android.bp b/bluetooth/audio/utils/Android.bp
index cecf8f0..779a90f 100644
--- a/bluetooth/audio/utils/Android.bp
+++ b/bluetooth/audio/utils/Android.bp
@@ -51,6 +51,7 @@
         "libxsdc-utils",
     ],
     defaults: [
+        "aconfig_lib_cc_static_link.defaults",
         "latest_android_hardware_bluetooth_audio_ndk_shared",
     ],
     shared_libs: [
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/broadcastradio/aidl/Android.bp b/broadcastradio/aidl/Android.bp
index 1540944..82ee949 100644
--- a/broadcastradio/aidl/Android.bp
+++ b/broadcastradio/aidl/Android.bp
@@ -36,6 +36,9 @@
             sdk_version: "module_current",
             min_sdk_version: "Tiramisu",
         },
+        rust: {
+            enabled: true,
+        },
     },
     versions_with_info: [
         {
@@ -68,3 +71,10 @@
         latest_android_hardware_broadcastradio + "-java",
     ],
 }
+
+rust_defaults {
+    name: "latest_android_hardware_broadcastradio_rust",
+    rustlibs: [
+        latest_android_hardware_broadcastradio + "-rust",
+    ],
+}
diff --git a/broadcastradio/aidl/rust_impl/Android.bp b/broadcastradio/aidl/rust_impl/Android.bp
new file mode 100644
index 0000000..d6f984e
--- /dev/null
+++ b/broadcastradio/aidl/rust_impl/Android.bp
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+rust_binary {
+    name: "android.hardware.broadcastradio-rust-service",
+    relative_install_path: "hw",
+    vendor: true,
+    srcs: ["src/*.rs"],
+    crate_root: "src/main.rs",
+    defaults: [
+        "latest_android_hardware_broadcastradio_rust",
+    ],
+    vintf_fragments: ["broadcastradio-rust-service.xml"],
+    init_rc: ["broadcastradio-rust-service.rc"],
+    rustlibs: [
+        "libbinder_rs",
+    ],
+}
diff --git a/broadcastradio/aidl/rust_impl/README.md b/broadcastradio/aidl/rust_impl/README.md
new file mode 100644
index 0000000..17e0c18
--- /dev/null
+++ b/broadcastradio/aidl/rust_impl/README.md
@@ -0,0 +1,13 @@
+# Rust Skeleton BroadcastRadio HAL implementation.
+
+WARNING: This is not a reference BroadcastRadio HAL implementation and does
+not contain any actual implementation.
+
+This folder contains a skeleton broadcast radio HAL implementation in Rust to
+demonstrate  how vendor may implement a Rust broadcast radio HAL. To run this
+broadcast radio HAL, include `android.hardware.broadcastradio-rust-service`
+in your image.
+
+This implementation returns `StatusCode::UNKNOWN_ERROR` for all operations
+and does not pass VTS/CTS. Vendor must replace the logic in
+`default_broadcastradio_hal.rs` with the actual implementation
\ No newline at end of file
diff --git a/broadcastradio/aidl/rust_impl/broadcastradio-rust-service.rc b/broadcastradio/aidl/rust_impl/broadcastradio-rust-service.rc
new file mode 100644
index 0000000..4dad616
--- /dev/null
+++ b/broadcastradio/aidl/rust_impl/broadcastradio-rust-service.rc
@@ -0,0 +1,5 @@
+service vendor.broadcastradio-default /vendor/bin/hw/android.hardware.broadcastradio-service.default
+    interface aidl android.hardware.broadcastradio.IBroadcastRadio/amfm
+    class hal
+    user audioserver
+    group audio
diff --git a/broadcastradio/aidl/rust_impl/broadcastradio-rust-service.xml b/broadcastradio/aidl/rust_impl/broadcastradio-rust-service.xml
new file mode 100644
index 0000000..ced2d78
--- /dev/null
+++ b/broadcastradio/aidl/rust_impl/broadcastradio-rust-service.xml
@@ -0,0 +1,23 @@
+<!--
+  ~ 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.
+  -->
+
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.broadcastradio</name>
+        <version>2</version>
+        <fqname>IBroadcastRadio/amfm</fqname>
+    </hal>
+</manifest>
diff --git a/broadcastradio/aidl/rust_impl/src/default_broadcastradio_hal.rs b/broadcastradio/aidl/rust_impl/src/default_broadcastradio_hal.rs
new file mode 100644
index 0000000..ea2f9d3
--- /dev/null
+++ b/broadcastradio/aidl/rust_impl/src/default_broadcastradio_hal.rs
@@ -0,0 +1,107 @@
+/*
+ * 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.
+ */
+use android_hardware_broadcastradio::aidl::android::hardware::broadcastradio::{
+    AmFmRegionConfig::AmFmRegionConfig,
+    AnnouncementType::AnnouncementType,
+    ConfigFlag::ConfigFlag,
+    DabTableEntry::DabTableEntry,
+    IAnnouncementListener::IAnnouncementListener,
+    IBroadcastRadio::IBroadcastRadio,
+    ICloseHandle::ICloseHandle,
+    ITunerCallback::ITunerCallback,
+    ProgramFilter::ProgramFilter,
+    ProgramSelector::ProgramSelector,
+    Properties::Properties,
+    VendorKeyValue::VendorKeyValue,
+};
+use binder::{Interface, Result as BinderResult, StatusCode, Strong};
+use std::vec::Vec;
+
+/// This struct is defined to implement IBroadcastRadio AIDL interface.
+pub struct DefaultBroadcastRadioHal;
+
+impl Interface for DefaultBroadcastRadioHal {}
+
+impl IBroadcastRadio for DefaultBroadcastRadioHal {
+    fn getAmFmRegionConfig(&self, _full : bool) -> BinderResult<AmFmRegionConfig> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn getDabRegionConfig(&self) -> BinderResult<Vec<DabTableEntry>> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn getProperties(&self) -> BinderResult<Properties> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn getImage(&self, _id : i32) -> BinderResult<Vec<u8>> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn setTunerCallback(&self, _callback : &Strong<dyn ITunerCallback>) -> BinderResult<()> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn unsetTunerCallback(&self) -> BinderResult<()> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn tune(&self, _program : &ProgramSelector) -> BinderResult<()> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn seek(&self, _direction_up : bool, _skip_sub_channel : bool) -> BinderResult<()> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn step(&self, _direction_up : bool) -> BinderResult<()> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn cancel(&self) -> BinderResult<()> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn startProgramListUpdates(&self, _filter : &ProgramFilter) -> BinderResult<()> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn stopProgramListUpdates(&self) -> BinderResult<()> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn isConfigFlagSet(&self, _flag : ConfigFlag) -> BinderResult<bool> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn setConfigFlag(&self, _flag : ConfigFlag, _value : bool) -> BinderResult<()> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn setParameters(&self, _parameters : &[VendorKeyValue]) -> BinderResult<Vec<VendorKeyValue>> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn getParameters(&self, _parameters : &[String]) -> BinderResult<Vec<VendorKeyValue>> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn registerAnnouncementListener(&self, _listener : &Strong<dyn IAnnouncementListener>,
+            _enabled : &[AnnouncementType]) -> BinderResult<Strong<dyn ICloseHandle>> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+}
diff --git a/broadcastradio/aidl/rust_impl/src/main.rs b/broadcastradio/aidl/rust_impl/src/main.rs
new file mode 100644
index 0000000..c0bc055
--- /dev/null
+++ b/broadcastradio/aidl/rust_impl/src/main.rs
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+ mod default_broadcastradio_hal;
+
+use android_hardware_broadcastradio::aidl::android::hardware::broadcastradio::IBroadcastRadio::BnBroadcastRadio;
+use crate::default_broadcastradio_hal::DefaultBroadcastRadioHal;
+
+fn main() {
+    binder::ProcessState::start_thread_pool();
+    let my_service = DefaultBroadcastRadioHal;
+    let service_name = "android.hardware.broadcastradio.IBroadcastRadio/amfm";
+    let my_service_binder = BnBroadcastRadio::new_binder(
+        my_service,
+        binder::BinderFeatures::default(),
+    );
+    binder::add_service(service_name, my_service_binder.as_binder())
+    		.expect(format!("Failed to register {}?", service_name).as_str());
+    // Does not return.
+    binder::ProcessState::join_thread_pool()
+}
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index c8e683c..82666ae 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -8140,7 +8140,7 @@
             ANDROID_LENS_POSE_REFERENCE, &entry);
     if (0 == retcode && entry.count > 0) {
         uint8_t poseReference = entry.data.u8[0];
-        ASSERT_TRUE(poseReference <= ANDROID_LENS_POSE_REFERENCE_UNDEFINED &&
+        ASSERT_TRUE(poseReference <= ANDROID_LENS_POSE_REFERENCE_AUTOMOTIVE &&
                 poseReference >= ANDROID_LENS_POSE_REFERENCE_PRIMARY_CAMERA);
     }
 
diff --git a/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp b/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
index 368e954..31e8014 100644
--- a/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
+++ b/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
@@ -341,6 +341,10 @@
             ret = device->getSessionCharacteristics(config, &session_chars);
             ASSERT_TRUE(ret.isOk());
             verifySessionCharacteristics(session_chars, camera_chars);
+
+            ret = mSession->close();
+            mSession = nullptr;
+            ASSERT_TRUE(ret.isOk());
         }
     } else {
         ALOGI("getSessionCharacteristics: Test skipped.\n");
diff --git a/camera/provider/aidl/vts/camera_aidl_test.cpp b/camera/provider/aidl/vts/camera_aidl_test.cpp
index 1d6f013..a01fb04 100644
--- a/camera/provider/aidl/vts/camera_aidl_test.cpp
+++ b/camera/provider/aidl/vts/camera_aidl_test.cpp
@@ -694,8 +694,8 @@
     retcode = find_camera_metadata_ro_entry(metadata, ANDROID_LENS_POSE_REFERENCE, &entry);
     if (0 == retcode && entry.count > 0) {
         uint8_t poseReference = entry.data.u8[0];
-        ASSERT_TRUE(poseReference <= ANDROID_LENS_POSE_REFERENCE_UNDEFINED &&
-                    poseReference >= ANDROID_LENS_POSE_REFERENCE_PRIMARY_CAMERA);
+        ASSERT_TRUE(poseReference <= ANDROID_LENS_POSE_REFERENCE_AUTOMOTIVE &&
+                poseReference >= ANDROID_LENS_POSE_REFERENCE_PRIMARY_CAMERA);
     }
 
     retcode =
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/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp
index 9381a0a..4309187 100644
--- a/gnss/aidl/vts/gnss_hal_test_cases.cpp
+++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp
@@ -1714,7 +1714,8 @@
  * 2. verify the SvStatus are received at expected interval
  */
 TEST_P(GnssHalTest, TestSvStatusIntervals) {
-    if (aidl_gnss_hal_->getInterfaceVersion() <= 2) {
+    // Only runs on devices launched in Android 15+
+    if (aidl_gnss_hal_->getInterfaceVersion() <= 3) {
         return;
     }
     ALOGD("TestSvStatusIntervals");
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/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/security/keymint/aidl/default/Android.bp b/security/keymint/aidl/default/Android.bp
index 0cf53cf..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",
@@ -46,6 +53,13 @@
     ],
 }
 
+// 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",
diff --git a/security/keymint/aidl/default/main.rs b/security/keymint/aidl/default/main.rs
index 055c698..47143f4 100644
--- a/security/keymint/aidl/default/main.rs
+++ b/security/keymint/aidl/default/main.rs
@@ -17,11 +17,15 @@
 //! 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 be implemented in a secure environment**.
+//! 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};
+use log::{debug, error, info, warn};
 use std::ops::DerefMut;
 use std::sync::{mpsc, Arc, Mutex};
 
@@ -62,7 +66,7 @@
         error!("{}", panic_info);
     }));
 
-    info!("Insecure KeyMint HAL service is starting.");
+    warn!("Insecure KeyMint HAL service is starting.");
 
     info!("Starting thread pool now.");
     binder::ProcessState::start_thread_pool();
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index b65218f..65a4645 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>
@@ -3588,6 +3589,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
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/threadnetwork/aidl/default/main.cpp b/threadnetwork/aidl/default/main.cpp
index 8419041..26683bf 100644
--- a/threadnetwork/aidl/default/main.cpp
+++ b/threadnetwork/aidl/default/main.cpp
@@ -26,24 +26,29 @@
 using aidl::android::hardware::threadnetwork::IThreadChip;
 using aidl::android::hardware::threadnetwork::ThreadChip;
 
+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);
+}
+}
+
 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]);
-
-        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));
+        addThreadChip(id, argv[id + 1]);
     }
 
     ALOGI("Thread Network HAL is running");
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;