Merge "Revert "libhealthloop: Handle netlink receive buffer overflows"" into main
diff --git a/audio/OWNERS b/audio/OWNERS
index 3671685..80e2765 100644
--- a/audio/OWNERS
+++ b/audio/OWNERS
@@ -2,3 +2,4 @@
 
 elaurent@google.com
 mnaganov@google.com
+yaoshunkai@google.com
diff --git a/audio/aidl/default/EffectContext.cpp b/audio/aidl/default/EffectContext.cpp
index 7b8cfb1..5539177 100644
--- a/audio/aidl/default/EffectContext.cpp
+++ b/audio/aidl/default/EffectContext.cpp
@@ -242,4 +242,17 @@
     LOG(VERBOSE) << __func__ << " : signal client for reopen";
     return RetCode::SUCCESS;
 }
+
+RetCode EffectContext::enable() {
+    return RetCode::SUCCESS;
+}
+
+RetCode EffectContext::disable() {
+    return RetCode::SUCCESS;
+}
+
+RetCode EffectContext::reset() {
+    return RetCode::SUCCESS;
+}
+
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/EffectImpl.cpp b/audio/aidl/default/EffectImpl.cpp
index 7192d97..3e61335 100644
--- a/audio/aidl/default/EffectImpl.cpp
+++ b/audio/aidl/default/EffectImpl.cpp
@@ -246,7 +246,6 @@
             startThread();
             break;
         case CommandId::STOP:
-        case CommandId::RESET:
             RETURN_OK_IF(mState == State::IDLE);
             mState = State::IDLE;
             RETURN_IF(notifyEventFlag(mDataMqNotEmptyEf) != RetCode::SUCCESS, EX_ILLEGAL_STATE,
@@ -254,6 +253,13 @@
             stopThread();
             RETURN_IF_ASTATUS_NOT_OK(commandImpl(command), "commandImplFailed");
             break;
+        case CommandId::RESET:
+            mState = State::IDLE;
+            RETURN_IF(notifyEventFlag(mDataMqNotEmptyEf) != RetCode::SUCCESS, EX_ILLEGAL_STATE,
+                      "notifyEventFlagNotEmptyFailed");
+            stopThread();
+            RETURN_IF_ASTATUS_NOT_OK(commandImpl(command), "commandImplFailed");
+            break;
         default:
             LOG(ERROR) << getEffectNameWithVersion() << __func__ << " instance still processing";
             return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
@@ -266,8 +272,22 @@
 
 ndk::ScopedAStatus EffectImpl::commandImpl(CommandId command) {
     RETURN_IF(!mImplContext, EX_NULL_POINTER, "nullContext");
-    if (command == CommandId::RESET) {
-        mImplContext->resetBuffer();
+    switch (command) {
+        case CommandId::START:
+            mImplContext->enable();
+            break;
+        case CommandId::STOP:
+            mImplContext->disable();
+            break;
+        case CommandId::RESET:
+            mImplContext->disable();
+            mImplContext->reset();
+            mImplContext->resetBuffer();
+            break;
+        default:
+            LOG(ERROR) << __func__ << " commandId " << toString(command) << " not supported";
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "commandIdNotSupported");
     }
     return ndk::ScopedAStatus::ok();
 }
diff --git a/audio/aidl/default/EffectMain.cpp b/audio/aidl/default/EffectMain.cpp
index a300cfd..7a6141a 100644
--- a/audio/aidl/default/EffectMain.cpp
+++ b/audio/aidl/default/EffectMain.cpp
@@ -38,7 +38,7 @@
             candidatePath.append(apexName).append("/etc/").append(kDefaultConfigName);
             LOG(DEBUG) << __func__ << " effect lib path " << candidatePath;
             if (access(candidatePath.c_str(), R_OK) == 0) {
-                return std::move(candidatePath);
+                return candidatePath;
             }
         }
     } else {
diff --git a/audio/aidl/default/Module.cpp b/audio/aidl/default/Module.cpp
index 543efd1..c14d06e 100644
--- a/audio/aidl/default/Module.cpp
+++ b/audio/aidl/default/Module.cpp
@@ -391,7 +391,7 @@
 
 Module::Configuration& Module::getConfig() {
     if (!mConfig) {
-        mConfig = std::move(initializeConfig());
+        mConfig = initializeConfig();
     }
     return *mConfig;
 }
diff --git a/audio/aidl/default/Stream.cpp b/audio/aidl/default/Stream.cpp
index 389860f..eecc972 100644
--- a/audio/aidl/default/Stream.cpp
+++ b/audio/aidl/default/Stream.cpp
@@ -663,10 +663,14 @@
 }
 
 StreamCommonImpl::~StreamCommonImpl() {
-    if (!isClosed()) {
-        LOG(ERROR) << __func__ << ": stream was not closed prior to destruction, resource leak";
-        stopWorker();
-        // The worker and the context should clean up by themselves via destructors.
+    // It is responsibility of the class that implements 'DriverInterface' to call 'cleanupWorker'
+    // in the destructor. Note that 'cleanupWorker' can not be properly called from this destructor
+    // because any subclasses have already been destroyed and thus the 'DriverInterface'
+    // implementation is not valid. Thus, here it can only be asserted whether the subclass has done
+    // its job.
+    if (!mWorkerStopIssued && !isClosed()) {
+        LOG(FATAL) << __func__ << ": the stream implementation must call 'cleanupWorker' "
+                   << "in order to clean up the worker thread.";
     }
 }
 
@@ -770,10 +774,7 @@
 ndk::ScopedAStatus StreamCommonImpl::close() {
     LOG(DEBUG) << __func__;
     if (!isClosed()) {
-        stopWorker();
-        LOG(DEBUG) << __func__ << ": joining the worker thread...";
-        mWorker->join();
-        LOG(DEBUG) << __func__ << ": worker thread joined";
+        stopAndJoinWorker();
         onClose(mWorker->setClosed());
         return ndk::ScopedAStatus::ok();
     } else {
@@ -791,6 +792,20 @@
     return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
 }
 
+void StreamCommonImpl::cleanupWorker() {
+    if (!isClosed()) {
+        LOG(ERROR) << __func__ << ": stream was not closed prior to destruction, resource leak";
+        stopAndJoinWorker();
+    }
+}
+
+void StreamCommonImpl::stopAndJoinWorker() {
+    stopWorker();
+    LOG(DEBUG) << __func__ << ": joining the worker thread...";
+    mWorker->join();
+    LOG(DEBUG) << __func__ << ": worker thread joined";
+}
+
 void StreamCommonImpl::stopWorker() {
     if (auto commandMQ = mContext.getCommandMQ(); commandMQ != nullptr) {
         LOG(DEBUG) << __func__ << ": asking the worker to exit...";
@@ -805,6 +820,7 @@
         }
         LOG(DEBUG) << __func__ << ": done";
     }
+    mWorkerStopIssued = true;
 }
 
 ndk::ScopedAStatus StreamCommonImpl::updateMetadataCommon(const Metadata& metadata) {
diff --git a/audio/aidl/default/alsa/StreamAlsa.cpp b/audio/aidl/default/alsa/StreamAlsa.cpp
index e57d538..f548903 100644
--- a/audio/aidl/default/alsa/StreamAlsa.cpp
+++ b/audio/aidl/default/alsa/StreamAlsa.cpp
@@ -37,6 +37,10 @@
       mConfig(alsa::getPcmConfig(getContext(), mIsInput)),
       mReadWriteRetries(readWriteRetries) {}
 
+StreamAlsa::~StreamAlsa() {
+    cleanupWorker();
+}
+
 ::android::status_t StreamAlsa::init() {
     return mConfig.has_value() ? ::android::OK : ::android::NO_INIT;
 }
diff --git a/audio/aidl/default/bluetooth/StreamBluetooth.cpp b/audio/aidl/default/bluetooth/StreamBluetooth.cpp
index efab470..6e1a811 100644
--- a/audio/aidl/default/bluetooth/StreamBluetooth.cpp
+++ b/audio/aidl/default/bluetooth/StreamBluetooth.cpp
@@ -66,6 +66,10 @@
                                                  1000),
       mBtDeviceProxy(btDeviceProxy) {}
 
+StreamBluetooth::~StreamBluetooth() {
+    cleanupWorker();
+}
+
 ::android::status_t StreamBluetooth::init() {
     std::lock_guard guard(mLock);
     if (mBtDeviceProxy == nullptr) {
diff --git a/audio/aidl/default/include/core-impl/Stream.h b/audio/aidl/default/include/core-impl/Stream.h
index 93ace96..100b4c8 100644
--- a/audio/aidl/default/include/core-impl/Stream.h
+++ b/audio/aidl/default/include/core-impl/Stream.h
@@ -457,6 +457,11 @@
     }
 
     virtual void onClose(StreamDescriptor::State statePriorToClosing) = 0;
+    // Any stream class implementing 'DriverInterface::shutdown' must call 'cleanupWorker' in
+    // the destructor in order to stop and join the worker thread in the case when the client
+    // has not called 'IStreamCommon::close' method.
+    void cleanupWorker();
+    void stopAndJoinWorker();
     void stopWorker();
 
     const StreamContext& mContext;
@@ -464,6 +469,9 @@
     std::unique_ptr<StreamWorkerInterface> mWorker;
     ChildInterface<StreamCommonDelegator> mCommon;
     ConnectedDevices mConnectedDevices;
+
+  private:
+    std::atomic<bool> mWorkerStopIssued = false;
 };
 
 // Note: 'StreamIn/Out' can not be used on their own. Instead, they must be used for defining
diff --git a/audio/aidl/default/include/core-impl/StreamAlsa.h b/audio/aidl/default/include/core-impl/StreamAlsa.h
index 2c3b284..0356946 100644
--- a/audio/aidl/default/include/core-impl/StreamAlsa.h
+++ b/audio/aidl/default/include/core-impl/StreamAlsa.h
@@ -32,6 +32,8 @@
 class StreamAlsa : public StreamCommonImpl {
   public:
     StreamAlsa(StreamContext* context, const Metadata& metadata, int readWriteRetries);
+    ~StreamAlsa();
+
     // Methods of 'DriverInterface'.
     ::android::status_t init() override;
     ::android::status_t drain(StreamDescriptor::DrainMode) override;
diff --git a/audio/aidl/default/include/core-impl/StreamBluetooth.h b/audio/aidl/default/include/core-impl/StreamBluetooth.h
index 7f4239c..357a546 100644
--- a/audio/aidl/default/include/core-impl/StreamBluetooth.h
+++ b/audio/aidl/default/include/core-impl/StreamBluetooth.h
@@ -41,6 +41,8 @@
             const std::shared_ptr<::android::bluetooth::audio::aidl::BluetoothAudioPortAidl>&
                     btDeviceProxy,
             const ::aidl::android::hardware::bluetooth::audio::PcmConfiguration& pcmConfig);
+    ~StreamBluetooth();
+
     // Methods of 'DriverInterface'.
     ::android::status_t init() override;
     ::android::status_t drain(StreamDescriptor::DrainMode) override;
diff --git a/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h b/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h
index 0d50c96..6ea7968 100644
--- a/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h
+++ b/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h
@@ -29,7 +29,9 @@
     StreamRemoteSubmix(
             StreamContext* context, const Metadata& metadata,
             const ::aidl::android::media::audio::common::AudioDeviceAddress& deviceAddress);
+    ~StreamRemoteSubmix();
 
+    // Methods of 'DriverInterface'.
     ::android::status_t init() override;
     ::android::status_t drain(StreamDescriptor::DrainMode) override;
     ::android::status_t flush() override;
diff --git a/audio/aidl/default/include/core-impl/StreamStub.h b/audio/aidl/default/include/core-impl/StreamStub.h
index 3857e0e..22b2020 100644
--- a/audio/aidl/default/include/core-impl/StreamStub.h
+++ b/audio/aidl/default/include/core-impl/StreamStub.h
@@ -23,6 +23,8 @@
 class StreamStub : public StreamCommonImpl {
   public:
     StreamStub(StreamContext* context, const Metadata& metadata);
+    ~StreamStub();
+
     // Methods of 'DriverInterface'.
     ::android::status_t init() override;
     ::android::status_t drain(StreamDescriptor::DrainMode) override;
@@ -42,6 +44,10 @@
     const bool mIsInput;
     bool mIsInitialized = false;  // Used for validating the state machine logic.
     bool mIsStandby = true;       // Used for validating the state machine logic.
+
+    // Used by the worker thread.
+    int64_t mStartTimeNs = 0;
+    long mFramesSinceStart = 0;
 };
 
 class StreamInStub final : public StreamIn, public StreamStub {
diff --git a/audio/aidl/default/include/core-impl/StreamUsb.h b/audio/aidl/default/include/core-impl/StreamUsb.h
index 608f27d..694fccf 100644
--- a/audio/aidl/default/include/core-impl/StreamUsb.h
+++ b/audio/aidl/default/include/core-impl/StreamUsb.h
@@ -29,6 +29,7 @@
 class StreamUsb : public StreamAlsa {
   public:
     StreamUsb(StreamContext* context, const Metadata& metadata);
+
     // Methods of 'DriverInterface'.
     ::android::status_t transfer(void* buffer, size_t frameCount, size_t* actualFrameCount,
                                  int32_t* latencyMs) override;
diff --git a/audio/aidl/default/include/effect-impl/EffectContext.h b/audio/aidl/default/include/effect-impl/EffectContext.h
index 275378e..02a4caa 100644
--- a/audio/aidl/default/include/effect-impl/EffectContext.h
+++ b/audio/aidl/default/include/effect-impl/EffectContext.h
@@ -82,6 +82,10 @@
 
     virtual ::android::hardware::EventFlag* getStatusEventFlag();
 
+    virtual RetCode enable();
+    virtual RetCode disable();
+    virtual RetCode reset();
+
   protected:
     int mVersion = 0;
     size_t mInputFrameSize = 0;
diff --git a/audio/aidl/default/main.cpp b/audio/aidl/default/main.cpp
index 6ab747d..0b3e3ba 100644
--- a/audio/aidl/default/main.cpp
+++ b/audio/aidl/default/main.cpp
@@ -71,6 +71,7 @@
     // For more logs, use VERBOSE, however this may hinder performance.
     // android::base::SetMinimumLogSeverity(::android::base::VERBOSE);
     ABinderProcess_setThreadPoolMaxThreadCount(16);
+    ABinderProcess_startThreadPool();
 
     // Guaranteed log for b/210919187 and logd_integration_test
     LOG(INFO) << "Init for Audio AIDL HAL";
diff --git a/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp b/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp
index a266b54..db105b6 100644
--- a/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp
+++ b/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp
@@ -43,6 +43,10 @@
     mStreamConfig.sampleRate = context->getSampleRate();
 }
 
+StreamRemoteSubmix::~StreamRemoteSubmix() {
+    cleanupWorker();
+}
+
 ::android::status_t StreamRemoteSubmix::init() {
     mCurrentRoute = SubmixRoute::findOrCreateRoute(mDeviceAddress, mStreamConfig);
     if (mCurrentRoute == nullptr) {
diff --git a/audio/aidl/default/stub/StreamStub.cpp b/audio/aidl/default/stub/StreamStub.cpp
index 2422fe4..a3d99a8 100644
--- a/audio/aidl/default/stub/StreamStub.cpp
+++ b/audio/aidl/default/stub/StreamStub.cpp
@@ -39,6 +39,10 @@
       mIsAsynchronous(!!getContext().getAsyncCallback()),
       mIsInput(isInput(metadata)) {}
 
+StreamStub::~StreamStub() {
+    cleanupWorker();
+}
+
 ::android::status_t StreamStub::init() {
     mIsInitialized = true;
     return ::android::OK;
@@ -79,7 +83,6 @@
     if (!mIsInitialized) {
         LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
     }
-    usleep(500);
     mIsStandby = true;
     return ::android::OK;
 }
@@ -88,8 +91,9 @@
     if (!mIsInitialized) {
         LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
     }
-    usleep(500);
     mIsStandby = false;
+    mStartTimeNs = ::android::uptimeNanos();
+    mFramesSinceStart = 0;
     return ::android::OK;
 }
 
@@ -101,14 +105,23 @@
     if (mIsStandby) {
         LOG(FATAL) << __func__ << ": must not happen while in standby";
     }
-    static constexpr float kMicrosPerSecond = MICROS_PER_SECOND;
-    static constexpr float kScaleFactor = .8f;
+    *actualFrameCount = frameCount;
     if (mIsAsynchronous) {
         usleep(500);
     } else {
-        const size_t delayUs = static_cast<size_t>(
-                std::roundf(kScaleFactor * frameCount * kMicrosPerSecond / mSampleRate));
-        usleep(delayUs);
+        mFramesSinceStart += *actualFrameCount;
+        const long bufferDurationUs =
+                (*actualFrameCount) * MICROS_PER_SECOND / mContext.getSampleRate();
+        const auto totalDurationUs =
+                (::android::uptimeNanos() - mStartTimeNs) / NANOS_PER_MICROSECOND;
+        const long totalOffsetUs =
+                mFramesSinceStart * MICROS_PER_SECOND / mContext.getSampleRate() - totalDurationUs;
+        LOG(VERBOSE) << __func__ << ": totalOffsetUs " << totalOffsetUs;
+        if (totalOffsetUs > 0) {
+            const long sleepTimeUs = std::min(totalOffsetUs, bufferDurationUs);
+            LOG(VERBOSE) << __func__ << ": sleeping for " << sleepTimeUs << " us";
+            usleep(sleepTimeUs);
+        }
     }
     if (mIsInput) {
         uint8_t* byteBuffer = static_cast<uint8_t*>(buffer);
@@ -116,7 +129,6 @@
             byteBuffer[i] = std::rand() % 255;
         }
     }
-    *actualFrameCount = frameCount;
     return ::android::OK;
 }
 
diff --git a/audio/aidl/vts/EffectHelper.h b/audio/aidl/vts/EffectHelper.h
index cad1195..0fa170f 100644
--- a/audio/aidl/vts/EffectHelper.h
+++ b/audio/aidl/vts/EffectHelper.h
@@ -397,10 +397,10 @@
                                                               outputBuffer.size(), outputBuffer));
         }
 
+        // Disable the process
         ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::STOP));
         EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, outputBuffer));
 
-        // Disable the process
         ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::RESET));
     }
 
diff --git a/audio/common/all-versions/default/7.0/HidlUtils.cpp b/audio/common/all-versions/default/7.0/HidlUtils.cpp
index f89c898..bc056e2 100644
--- a/audio/common/all-versions/default/7.0/HidlUtils.cpp
+++ b/audio/common/all-versions/default/7.0/HidlUtils.cpp
@@ -1025,7 +1025,7 @@
             result = BAD_VALUE;
         }
     }
-    std::string fullHalTags{std::move(halTagsBuffer.str())};
+    std::string fullHalTags{halTagsBuffer.str()};
     strncpy(halTags, fullHalTags.c_str(), AUDIO_ATTRIBUTES_TAGS_MAX_SIZE);
     CONVERT_CHECKED(fullHalTags.length() <= AUDIO_ATTRIBUTES_TAGS_MAX_SIZE ? NO_ERROR : BAD_VALUE,
                     result);
diff --git a/automotive/evs/1.1/default/EvsCamera.cpp b/automotive/evs/1.1/default/EvsCamera.cpp
index 520670a..fb598ff 100644
--- a/automotive/evs/1.1/default/EvsCamera.cpp
+++ b/automotive/evs/1.1/default/EvsCamera.cpp
@@ -495,7 +495,7 @@
         }
         if (!stored) {
             // Add a BufferRecord wrapping this handle to our set of available buffers
-            mBuffers.push_back(std::move(BufferRecord(memHandle)));
+            mBuffers.push_back(BufferRecord(memHandle));
         }
 
         mFramesAllowed++;
diff --git a/automotive/evs/aidl/impl/default/src/ConfigManager.cpp b/automotive/evs/aidl/impl/default/src/ConfigManager.cpp
index ba4cdc0..d8961d0 100644
--- a/automotive/evs/aidl/impl/default/src/ConfigManager.cpp
+++ b/automotive/evs/aidl/impl/default/src/ConfigManager.cpp
@@ -199,8 +199,8 @@
 
             CameraParam aParam;
             if (ConfigManagerUtil::convertToEvsCameraParam(nameAttr, aParam)) {
-                aCamera->controls.insert_or_assign(
-                        aParam, std::move(std::make_tuple(minVal, maxVal, stepVal)));
+                aCamera->controls.insert_or_assign(aParam,
+                                                   std::make_tuple(minVal, maxVal, stepVal));
             }
 
             ctrlElem = ctrlElem->NextSiblingElement("control");
@@ -583,8 +583,8 @@
         CameraCtrl* ptr = reinterpret_cast<CameraCtrl*>(p);
         for (size_t idx = 0; idx < sz; ++idx) {
             CameraCtrl temp = *ptr++;
-            aCamera->controls.insert_or_assign(
-                    temp.cid, std::move(std::make_tuple(temp.min, temp.max, temp.step)));
+            aCamera->controls.insert_or_assign(temp.cid,
+                                               std::make_tuple(temp.min, temp.max, temp.step));
         }
         p = reinterpret_cast<char*>(ptr);
 
@@ -689,8 +689,8 @@
         CameraCtrl* ptr = reinterpret_cast<CameraCtrl*>(p);
         for (size_t idx = 0; idx < sz; ++idx) {
             CameraCtrl temp = *ptr++;
-            aCamera->controls.insert_or_assign(
-                    temp.cid, std::move(std::make_tuple(temp.min, temp.max, temp.step)));
+            aCamera->controls.insert_or_assign(temp.cid,
+                                               std::make_tuple(temp.min, temp.max, temp.step));
         }
         p = reinterpret_cast<char*>(ptr);
 
diff --git a/automotive/evs/aidl/impl/default/src/EvsGlDisplay.cpp b/automotive/evs/aidl/impl/default/src/EvsGlDisplay.cpp
index 5b5cbcc..cf94e38 100644
--- a/automotive/evs/aidl/impl/default/src/EvsGlDisplay.cpp
+++ b/automotive/evs/aidl/impl/default/src/EvsGlDisplay.cpp
@@ -353,7 +353,7 @@
             .buffer =
                     {
                             .description = mBuffer.description,
-                            .handle = std::move(::android::dupToAidl(mBuffer.handle)),
+                            .handle = ::android::dupToAidl(mBuffer.handle),
                     },
             .pixelSizeBytes = 4,  // RGBA_8888 is 4-byte-per-pixel format
             .bufferId = mBuffer.fingerprint,
diff --git a/automotive/evs/aidl/vts/FrameHandler.cpp b/automotive/evs/aidl/vts/FrameHandler.cpp
index e51be67..88c3643 100644
--- a/automotive/evs/aidl/vts/FrameHandler.cpp
+++ b/automotive/evs/aidl/vts/FrameHandler.cpp
@@ -50,12 +50,12 @@
         }
     } else {
         for (auto i = 0; i < handle.fds.size(); ++i) {
-            dup.fds[i] = std::move(handle.fds[i].dup());
+            dup.fds[i] = handle.fds[i].dup();
         }
     }
     dup.ints = handle.ints;
 
-    return std::move(dup);
+    return dup;
 }
 
 HardwareBuffer dupHardwareBuffer(const HardwareBuffer& buffer, bool doDup) {
@@ -64,7 +64,7 @@
             .handle = dupNativeHandle(buffer.handle, doDup),
     };
 
-    return std::move(dup);
+    return dup;
 }
 
 BufferDesc dupBufferDesc(const BufferDesc& src, bool doDup) {
@@ -77,7 +77,7 @@
             .metadata = src.metadata,
     };
 
-    return std::move(dup);
+    return dup;
 }
 
 bool comparePayload(const EvsEventDesc& l, const EvsEventDesc& r) {
diff --git a/automotive/vehicle/2.0/default/common/src/VehicleHalManager.cpp b/automotive/vehicle/2.0/default/common/src/VehicleHalManager.cpp
index e34e692..3d6e475 100644
--- a/automotive/vehicle/2.0/default/common/src/VehicleHalManager.cpp
+++ b/automotive/vehicle/2.0/default/common/src/VehicleHalManager.cpp
@@ -583,12 +583,12 @@
     while (*index < options.size()) {
         std::string option = options[*index];
         if (kSetPropOptions.find(option) != kSetPropOptions.end()) {
-            return std::move(values);
+            return values;
         }
         values.push_back(option);
         (*index)++;
     }
-    return std::move(values);
+    return values;
 }
 
 bool VehicleHalManager::parseSetPropOptions(int fd, const hidl_vec<hidl_string>& options,
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHalServer.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHalServer.cpp
index 4704917..86fc70a 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHalServer.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHalServer.cpp
@@ -509,7 +509,7 @@
     int64_t timestamp;
     int32_t areaId = 0;
     if (options[1] == "--setint") {
-        updatedPropValue = std::move(createVehiclePropValue(VehiclePropertyType::INT32, 1));
+        updatedPropValue = createVehiclePropValue(VehiclePropertyType::INT32, 1);
         if (!android::base::ParseInt(options[3], &intValue)) {
             result.buffer += "failed to parse value as int: \"" + options[3] + "\"\n";
             result.buffer += getHelpInfo();
@@ -517,7 +517,7 @@
         }
         updatedPropValue->value.int32Values[0] = intValue;
     } else if (options[1] == "--setbool") {
-        updatedPropValue = std::move(createVehiclePropValue(VehiclePropertyType::BOOLEAN, 1));
+        updatedPropValue = createVehiclePropValue(VehiclePropertyType::BOOLEAN, 1);
         if (options[3] == "true" || options[3] == "True") {
             updatedPropValue->value.int32Values[0] = 1;
         } else if (options[3] == "false" || options[3] == "False") {
@@ -529,7 +529,7 @@
             return result;
         }
     } else {
-        updatedPropValue = std::move(createVehiclePropValue(VehiclePropertyType::FLOAT, 1));
+        updatedPropValue = createVehiclePropValue(VehiclePropertyType::FLOAT, 1);
         if (!android::base::ParseFloat(options[3], &floatValue)) {
             result.buffer += "failed to parse value as float: \"" + options[3] + "\"\n";
             result.buffer += getHelpInfo();
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
index 8dbba19..95647df 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
@@ -1871,7 +1871,7 @@
 
 TEST_F(FakeVehicleHardwareTest, testGetHvacPropNotAvailable) {
     FakeVehicleHardwareTestHelper helper(getHardware());
-    auto hvacPowerOnConfig = std::move(getVehiclePropConfig(toInt(VehicleProperty::HVAC_POWER_ON)));
+    auto hvacPowerOnConfig = getVehiclePropConfig(toInt(VehicleProperty::HVAC_POWER_ON));
     EXPECT_NE(hvacPowerOnConfig, nullptr);
     for (auto& hvacPowerOnAreaConfig : hvacPowerOnConfig->areaConfigs) {
         int hvacPowerAreaId = hvacPowerOnAreaConfig.areaId;
@@ -1882,7 +1882,7 @@
         EXPECT_EQ(status, StatusCode::OK);
 
         for (auto& powerPropId : helper.getHvacPowerDependentProps()) {
-            auto powerPropConfig = std::move(getVehiclePropConfig(powerPropId));
+            auto powerPropConfig = getVehiclePropConfig(powerPropId);
             EXPECT_NE(powerPropConfig, nullptr);
             if (powerPropConfig->access == VehiclePropertyAccess::WRITE) {
                 continue;
@@ -1918,7 +1918,7 @@
 
 TEST_F(FakeVehicleHardwareTest, testSetHvacPropNotAvailable) {
     FakeVehicleHardwareTestHelper helper(getHardware());
-    auto hvacPowerOnConfig = std::move(getVehiclePropConfig(toInt(VehicleProperty::HVAC_POWER_ON)));
+    auto hvacPowerOnConfig = getVehiclePropConfig(toInt(VehicleProperty::HVAC_POWER_ON));
     EXPECT_NE(hvacPowerOnConfig, nullptr);
     for (auto& hvacPowerOnAreaConfig : hvacPowerOnConfig->areaConfigs) {
         int hvacPowerAreaId = hvacPowerOnAreaConfig.areaId;
@@ -1929,7 +1929,7 @@
         EXPECT_EQ(status, StatusCode::OK);
 
         for (auto& powerPropId : helper.getHvacPowerDependentProps()) {
-            auto powerPropConfig = std::move(getVehiclePropConfig(powerPropId));
+            auto powerPropConfig = getVehiclePropConfig(powerPropId);
             EXPECT_NE(powerPropConfig, nullptr);
             if (powerPropConfig->access == VehiclePropertyAccess::READ) {
                 continue;
@@ -1968,7 +1968,7 @@
 
 TEST_F(FakeVehicleHardwareTest, testHvacPowerOnSendCurrentHvacPropValues) {
     FakeVehicleHardwareTestHelper helper(getHardware());
-    auto hvacPowerOnConfig = std::move(getVehiclePropConfig(toInt(VehicleProperty::HVAC_POWER_ON)));
+    auto hvacPowerOnConfig = getVehiclePropConfig(toInt(VehicleProperty::HVAC_POWER_ON));
     EXPECT_NE(hvacPowerOnConfig, nullptr);
     for (auto& hvacPowerOnAreaConfig : hvacPowerOnConfig->areaConfigs) {
         int hvacPowerAreaId = hvacPowerOnAreaConfig.areaId;
@@ -2007,9 +2007,9 @@
 }
 
 TEST_F(FakeVehicleHardwareTest, testHvacDualOnSynchronizesTemp) {
-    auto hvacDualOnConfig = std::move(getVehiclePropConfig(toInt(VehicleProperty::HVAC_DUAL_ON)));
+    auto hvacDualOnConfig = getVehiclePropConfig(toInt(VehicleProperty::HVAC_DUAL_ON));
     auto hvacTemperatureSetConfig =
-            std::move(getVehiclePropConfig(toInt(VehicleProperty::HVAC_TEMPERATURE_SET)));
+            getVehiclePropConfig(toInt(VehicleProperty::HVAC_TEMPERATURE_SET));
     EXPECT_NE(hvacDualOnConfig, nullptr);
     EXPECT_NE(hvacTemperatureSetConfig, nullptr);
     for (auto& hvacTemperatureSetConfig : hvacTemperatureSetConfig->areaConfigs) {
@@ -3605,7 +3605,7 @@
     // Config array values from HVAC_TEMPERATURE_SET in DefaultProperties.json
     auto configs = getHardware()->getAllPropertyConfigs();
     auto hvacTemperatureSetConfig =
-            std::move(getVehiclePropConfig(toInt(VehicleProperty::HVAC_TEMPERATURE_SET)));
+            getVehiclePropConfig(toInt(VehicleProperty::HVAC_TEMPERATURE_SET));
     EXPECT_NE(hvacTemperatureSetConfig, nullptr);
 
     auto& hvacTemperatureSetConfigArray = hvacTemperatureSetConfig->configArray;
diff --git a/automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp b/automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp
index 3d0a524..040b383 100644
--- a/automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp
+++ b/automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp
@@ -290,7 +290,7 @@
 
     for (auto const& [_, record] : mRecordsByPropId) {
         for (auto const& [_, value] : record.values) {
-            allValues.push_back(std::move(mValuePool->obtain(*value)));
+            allValues.push_back(mValuePool->obtain(*value));
         }
     }
 
@@ -309,7 +309,7 @@
     }
 
     for (auto const& [_, value] : record->values) {
-        values.push_back(std::move(mValuePool->obtain(*value)));
+        values.push_back(mValuePool->obtain(*value));
     }
     return values;
 }
diff --git a/automotive/vehicle/aidl/impl/utils/common/test/VehiclePropertyStoreTest.cpp b/automotive/vehicle/aidl/impl/utils/common/test/VehiclePropertyStoreTest.cpp
index 6646b7e..22f5c73 100644
--- a/automotive/vehicle/aidl/impl/utils/common/test/VehiclePropertyStoreTest.cpp
+++ b/automotive/vehicle/aidl/impl/utils/common/test/VehiclePropertyStoreTest.cpp
@@ -328,7 +328,7 @@
 TEST_F(VehiclePropertyStoreTest, testRemoveValuesForProperty) {
     auto values = getTestPropValues();
     for (const auto& value : values) {
-        ASSERT_RESULT_OK(mStore->writeValue(std::move(mValuePool->obtain(value))));
+        ASSERT_RESULT_OK(mStore->writeValue(mValuePool->obtain(value)));
     }
 
     mStore->removeValuesForProperty(toInt(VehicleProperty::INFO_FUEL_CAPACITY));
diff --git a/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp b/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
index 80b069a..c3650c5 100644
--- a/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
+++ b/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
@@ -95,7 +95,7 @@
             std::lock_guard<std::mutex> lockGuard(mLock);
             for (auto& value : values) {
                 int32_t propId = value->getPropId();
-                mEvents[propId].push_back(std::move(value->clone()));
+                mEvents[propId].push_back(value->clone());
             }
         }
         mEventCond.notify_one();
@@ -122,7 +122,7 @@
             return events;
         }
         for (const auto& eventPtr : mEvents[propId]) {
-            events.push_back(std::move(eventPtr->clone()));
+            events.push_back(eventPtr->clone());
         }
         return events;
     }
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
index d0f2a26..a458c5b 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
@@ -139,21 +139,36 @@
                   << toString(session_type_);
         return;
       }
+    } else if(session_type_ == SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH) {
+      if (audio_config.getTag() != AudioConfiguration::hfpConfig) {
+        LOG(ERROR) << __func__ << " invalid audio config type for SessionType ="
+                  << toString(session_type_);
+        return;
+      }
     } else {
       LOG(ERROR) << __func__ << " invalid SessionType ="
                  << toString(session_type_);
       return;
     }
   } else {
-    if (session_type_ !=
-            SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
-        session_type_ !=
+    if (session_type_ ==
+            SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
+        session_type_ ==
             SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
-      return;
-    }
-    if (audio_config.getTag() != AudioConfiguration::leAudioConfig) {
-      LOG(ERROR) << __func__ << " invalid audio config type for SessionType ="
-                 << toString(session_type_);
+      if (audio_config.getTag() != AudioConfiguration::leAudioConfig) {
+        LOG(ERROR) << __func__ << " invalid audio config type for SessionType ="
+                   << toString(session_type_);
+        return;
+      }
+    } else if(session_type_ == SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH) {
+      if (audio_config.getTag() != AudioConfiguration::hfpConfig) {
+        LOG(ERROR) << __func__ << " invalid audio config type for SessionType ="
+                  << toString(session_type_);
+        return;
+      }
+    } else {
+      LOG(ERROR) << __func__
+                 << " invalid SessionType =" << toString(session_type_);
       return;
     }
   }
diff --git a/common/fmq/aidl/Android.bp b/common/fmq/aidl/Android.bp
index 9c1b45d..4a3658e 100644
--- a/common/fmq/aidl/Android.bp
+++ b/common/fmq/aidl/Android.bp
@@ -35,8 +35,7 @@
         ndk: {
             apex_available: [
                 "//apex_available:platform",
-                "com.android.btservices",
-                "com.android.media.swcodec",
+                "//apex_available:anyapex",
             ],
             min_sdk_version: "29",
         },
diff --git a/compatibility_matrices/clear_vars.mk b/compatibility_matrices/clear_vars.mk
index 0e53885..3c62377 100644
--- a/compatibility_matrices/clear_vars.mk
+++ b/compatibility_matrices/clear_vars.mk
@@ -16,10 +16,6 @@
 
 # Clear input variables to BUILD_FRAMEWORK_COMPATIBILITY_MATRIX
 LOCAL_ADD_VBMETA_VERSION :=
-LOCAL_ADD_VBMETA_VERSION_OVERRIDE :=
 LOCAL_ASSEMBLE_VINTF_ENV_VARS :=
-LOCAL_ASSEMBLE_VINTF_ENV_VARS_OVERRIDE :=
-LOCAL_ASSEMBLE_VINTF_ERROR_MESSAGE :=
 LOCAL_ASSEMBLE_VINTF_FLAGS :=
-LOCAL_KERNEL_CONFIG_DATA_PATHS :=
 LOCAL_GEN_FILE_DEPENDENCIES :=
diff --git a/compatibility_matrices/compatibility_matrix.202404.xml b/compatibility_matrices/compatibility_matrix.202404.xml
index 9ea476a..aa6b8f0 100644
--- a/compatibility_matrices/compatibility_matrix.202404.xml
+++ b/compatibility_matrices/compatibility_matrix.202404.xml
@@ -28,7 +28,7 @@
     </hal>
     <hal format="aidl">
         <name>android.hardware.audio.sounddose</name>
-        <version>1-2</version>
+        <version>1-3</version>
         <interface>
             <name>ISoundDoseFactory</name>
             <instance>default</instance>
diff --git a/compatibility_matrices/compatibility_matrix.202504.xml b/compatibility_matrices/compatibility_matrix.202504.xml
index 3e5b74a..62c5650 100644
--- a/compatibility_matrices/compatibility_matrix.202504.xml
+++ b/compatibility_matrices/compatibility_matrix.202504.xml
@@ -26,14 +26,6 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl">
-        <name>android.hardware.audio.sounddose</name>
-        <version>1-3</version>
-        <interface>
-            <name>ISoundDoseFactory</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
     <hal format="aidl" updatable-via-apex="true">
          <name>android.hardware.authsecret</name>
          <version>1</version>
diff --git a/compatibility_matrices/compatibility_matrix.mk b/compatibility_matrices/compatibility_matrix.mk
index d22e510..64cd645 100644
--- a/compatibility_matrices/compatibility_matrix.mk
+++ b/compatibility_matrices/compatibility_matrix.mk
@@ -29,11 +29,7 @@
 #       (corresponds to <avb><vbmeta-version> tag)
 # LOCAL_ASSEMBLE_VINTF_ENV_VARS: Add a list of environment variable names from global variables in
 #       the build system that is lazily evaluated (e.g. PRODUCT_ENFORCE_VINTF_MANIFEST).
-# LOCAL_ASSEMBLE_VINTF_ENV_VARS_OVERRIDE: Add a list of environment variables that is local to
-#       assemble_vintf invocation. Format is "VINTF_ENFORCE_NO_UNUSED_HALS=true".
 # LOCAL_ASSEMBLE_VINTF_FLAGS: Add additional command line arguments to assemble_vintf invocation.
-# LOCAL_KERNEL_CONFIG_DATA_PATHS: Paths to search for kernel config requirements. Format for each is
-#       <kernel version x.y.z>:<path that contains android-base*.config>.
 # LOCAL_GEN_FILE_DEPENDENCIES: A list of additional dependencies for the generated file.
 
 ifndef LOCAL_MODULE
@@ -64,15 +60,11 @@
 ifeq (true,$(strip $(LOCAL_ADD_VBMETA_VERSION)))
 ifeq (true,$(BOARD_AVB_ENABLE))
 $(GEN): $(AVBTOOL)
-# INTERNAL_AVB_SYSTEM_SIGNING_ARGS consists of BOARD_AVB_SYSTEM_KEY_PATH and
-# BOARD_AVB_SYSTEM_ALGORITHM. We should add the dependency of key path, which
-# is a file, here.
 $(GEN): $(BOARD_AVB_SYSTEM_KEY_PATH)
 # Use deferred assignment (=) instead of immediate assignment (:=).
 # Otherwise, cannot get INTERNAL_AVB_SYSTEM_SIGNING_ARGS.
 $(GEN): FRAMEWORK_VBMETA_VERSION = $$("$(AVBTOOL)" add_hashtree_footer \
                            --print_required_libavb_version \
-                           $(INTERNAL_AVB_SYSTEM_SIGNING_ARGS) \
                            $(BOARD_AVB_SYSTEM_ADD_HASHTREE_FOOTER_ARGS))
 else
 $(GEN): FRAMEWORK_VBMETA_VERSION := 0.0
@@ -80,43 +72,17 @@
 $(GEN): PRIVATE_ENV_VARS += FRAMEWORK_VBMETA_VERSION
 endif # LOCAL_ADD_VBMETA_VERSION
 
-ifeq (true,$(strip $(LOCAL_ADD_VBMETA_VERSION_OVERRIDE)))
-ifneq ($(BOARD_OTA_FRAMEWORK_VBMETA_VERSION_OVERRIDE),)
-$(GEN): FRAMEWORK_VBMETA_VERSION_OVERRIDE := $(BOARD_OTA_FRAMEWORK_VBMETA_VERSION_OVERRIDE)
-$(GEN): PRIVATE_ENV_VARS += FRAMEWORK_VBMETA_VERSION_OVERRIDE
-endif
-endif
-
-ifneq (,$(strip $(LOCAL_KERNEL_CONFIG_DATA_PATHS)))
-$(GEN): PRIVATE_KERNEL_CONFIG_DATA_PATHS := $(LOCAL_KERNEL_CONFIG_DATA_PATHS)
-$(GEN): $(foreach pair,$(LOCAL_KERNEL_CONFIG_DATA_PATHS),\
-    $(wildcard $(call word-colon,2,$(pair))/android-base*.config))
-$(GEN): PRIVATE_FLAGS += $(foreach pair,$(PRIVATE_KERNEL_CONFIG_DATA_PATHS),\
-	--kernel=$(call word-colon,1,$(pair)):$(call normalize-path-list,\
-		$(wildcard $(call word-colon,2,$(pair))/android-base*.config)))
-endif
-
 my_matrix_src_files := \
 	$(addprefix $(LOCAL_PATH)/,$(LOCAL_SRC_FILES)) \
 	$(LOCAL_GENERATED_SOURCES)
 
-$(GEN): PRIVATE_ADDITIONAL_ENV_VARS := $(LOCAL_ASSEMBLE_VINTF_ENV_VARS_OVERRIDE)
-
-ifneq (,$(strip $(LOCAL_ASSEMBLE_VINTF_ERROR_MESSAGE)))
-$(GEN): PRIVATE_COMMAND_TAIL := || (echo $(strip $(LOCAL_ASSEMBLE_VINTF_ERROR_MESSAGE)) && false)
-endif
-
 $(GEN): PRIVATE_SRC_FILES := $(my_matrix_src_files)
 $(GEN): $(my_matrix_src_files) $(HOST_OUT_EXECUTABLES)/assemble_vintf
-	$(foreach varname,$(PRIVATE_ENV_VARS),\
-		$(if $(findstring $(varname),$(PRIVATE_ADDITIONAL_ENV_VARS)),\
-			$(error $(varname) should not be overridden by LOCAL_ASSEMBLE_VINTF_ENV_VARS_OVERRIDE.)))
 	$(foreach varname,$(PRIVATE_ENV_VARS),$(varname)="$($(varname))") \
-		$(PRIVATE_ADDITIONAL_ENV_VARS) \
 		$(HOST_OUT_EXECUTABLES)/assemble_vintf \
 		-i $(call normalize-path-list,$(PRIVATE_SRC_FILES)) \
 		-o $@ \
-		$(PRIVATE_FLAGS) $(PRIVATE_COMMAND_TAIL)
+		$(PRIVATE_FLAGS)
 
 LOCAL_PREBUILT_MODULE_FILE := $(GEN)
 LOCAL_SRC_FILES :=
diff --git a/compatibility_matrices/exclude/fcm_exclude.cpp b/compatibility_matrices/exclude/fcm_exclude.cpp
index fca9e1c..b86f399 100644
--- a/compatibility_matrices/exclude/fcm_exclude.cpp
+++ b/compatibility_matrices/exclude/fcm_exclude.cpp
@@ -167,6 +167,7 @@
             "android.hardware.audio.core.sounddose@3",
 
             // Deprecated HALs.
+            "android.hardware.audio.sounddose@3",
             "android.hardware.bluetooth.audio@1",
     };
 
diff --git a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
index f72cf55..012aa3f 100644
--- a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
+++ b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
@@ -1839,7 +1839,7 @@
         writer.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ 0.5f, -1.f);
         execute();
         const auto errors = mReader.takeErrors();
-        EXPECT_EQ(1, errors.size());
+        ASSERT_EQ(1, errors.size());
         EXPECT_EQ(IComposerClient::EX_UNSUPPORTED, errors[0].errorCode);
         GTEST_SUCCEED() << "SetDisplayBrightness is not supported";
         return;
diff --git a/health/utils/libhealthloop/Android.bp b/health/utils/libhealthloop/Android.bp
index b266f67..4ebc575 100644
--- a/health/utils/libhealthloop/Android.bp
+++ b/health/utils/libhealthloop/Android.bp
@@ -21,6 +21,17 @@
     default_applicable_licenses: ["hardware_interfaces_license"],
 }
 
+bpf {
+    name: "filterPowerSupplyEvents.o",
+    srcs: ["filterPowerSupplyEvents.c"],
+    // "vendor: true" because all binaries that use this BPF filter are vendor
+    // binaries.
+    vendor: true,
+}
+
+// Since "required" sections are ignored in static library definitions,
+// filterPowerSupplyEvents.o has been added in
+// build/make/target/product/base_vendor.mk.
 cc_library_static {
     name: "libhealthloop",
     vendor_available: true,
@@ -34,6 +45,7 @@
         "libcutils",
     ],
     header_libs: [
+        "bpf_headers",
         "libbatteryservice_headers",
         "libhealthd_headers",
         "libutils_headers",
@@ -42,3 +54,30 @@
         "include",
     ],
 }
+
+genrule {
+    name: "filterPowerSupplyEvents.h",
+    out: ["filterPowerSupplyEvents.h"],
+    srcs: [":filterPowerSupplyEvents.o"],
+    cmd: "cat $(in) | od -v -tx1 | cut -c9- | grep -v '^$$' | sed 's/^/0x/;s/ /, 0x/g;s/^, //;s/$$/,/' > $(out)",
+}
+
+cc_test_host {
+    name: "filterPowerSupplyEventsTest",
+    team: "trendy_team_pixel_system_sw_storage",
+    srcs: [
+        "filterPowerSupplyEventsTest.cpp",
+    ],
+    shared_libs: [
+        "libbase",
+        "libbpf",
+    ],
+    static_libs: [
+        "libgmock",
+    ],
+    generated_headers: [
+        "filterPowerSupplyEvents.h",
+        "libbpf_headers",
+    ],
+    compile_multilib: "64",
+}
diff --git a/health/utils/libhealthloop/HealthLoop.cpp b/health/utils/libhealthloop/HealthLoop.cpp
index ba7e75a..d43c2d5 100644
--- a/health/utils/libhealthloop/HealthLoop.cpp
+++ b/health/utils/libhealthloop/HealthLoop.cpp
@@ -30,8 +30,12 @@
 #include <cutils/uevent.h>
 #include <healthd/healthd.h>
 
+#include <BpfSyscallWrappers.h>
 #include <health/utils.h>
 
+using android::base::ErrnoError;
+using android::base::Result;
+using android::base::unique_fd;
 using namespace android;
 using namespace std::chrono_literals;
 
@@ -117,7 +121,6 @@
     ScheduleBatteryUpdate();
 }
 
-// TODO(b/140330870): Use BPF instead.
 #define UEVENT_MSG_LEN 2048
 void HealthLoop::UeventEvent(uint32_t /*epevents*/) {
     // No need to lock because uevent_fd_ is guaranteed to be initialized.
@@ -147,8 +150,26 @@
     }
 }
 
+// Attach a BPF filter to the @uevent_fd file descriptor. This fails in recovery mode because BPF is
+// not supported in recovery mode. This fails for kernel versions 5.4 and before because the BPF
+// program is rejected by the BPF verifier of older kernels.
+Result<void> HealthLoop::AttachFilter(int uevent_fd) {
+    static const char prg[] =
+            "/sys/fs/bpf/vendor/prog_filterPowerSupplyEvents_skfilter_power_supply";
+    int filter_fd(bpf::retrieveProgram(prg));
+    if (filter_fd < 0) {
+        return ErrnoError() << "failed to load BPF program " << prg;
+    }
+    if (setsockopt(uevent_fd, SOL_SOCKET, SO_ATTACH_BPF, &filter_fd, sizeof(filter_fd)) < 0) {
+        close(filter_fd);
+        return ErrnoError() << "failed to attach BPF program";
+    }
+    close(filter_fd);
+    return {};
+}
+
 void HealthLoop::UeventInit(void) {
-    uevent_fd_.reset(uevent_open_socket(64 * 1024, true));
+    uevent_fd_.reset(uevent_create_socket(64 * 1024, true));
 
     if (uevent_fd_ < 0) {
         KLOG_ERROR(LOG_TAG, "uevent_init: uevent_open_socket failed\n");
@@ -156,8 +177,25 @@
     }
 
     fcntl(uevent_fd_, F_SETFL, O_NONBLOCK);
+
+    Result<void> attach_result = AttachFilter(uevent_fd_);
+    if (!attach_result.ok()) {
+        std::string error_msg = attach_result.error().message();
+        error_msg +=
+                ". This is expected in recovery mode and also for kernel versions before 5.10.";
+        KLOG_WARNING(LOG_TAG, "%s", error_msg.c_str());
+    } else {
+        KLOG_INFO(LOG_TAG, "Successfully attached the BPF filter to the uevent socket");
+    }
+
     if (RegisterEvent(uevent_fd_, &HealthLoop::UeventEvent, EVENT_WAKEUP_FD))
         KLOG_ERROR(LOG_TAG, "register for uevent events failed\n");
+
+    if (uevent_bind(uevent_fd_.get()) < 0) {
+        uevent_fd_.reset();
+        KLOG_ERROR(LOG_TAG, "uevent_init: binding socket failed\n");
+        return;
+    }
 }
 
 void HealthLoop::WakeAlarmEvent(uint32_t /*epevents*/) {
diff --git a/health/utils/libhealthloop/filterPowerSupplyEvents.c b/health/utils/libhealthloop/filterPowerSupplyEvents.c
new file mode 100644
index 0000000..5296993
--- /dev/null
+++ b/health/utils/libhealthloop/filterPowerSupplyEvents.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <bpf_helpers.h>    // load_word()
+#include <linux/bpf.h>      // struct __sk_buff
+#include <linux/netlink.h>  // struct nlmsghdr
+#include <stdint.h>         // uint32_t
+
+// M4: match 4 bytes. Returns 0 if all bytes match.
+static inline uint32_t M4(struct __sk_buff* skb, unsigned int offset, uint8_t c0, uint8_t c1,
+                          uint8_t c2, uint8_t c3) {
+    return load_word(skb, offset) ^ ((c0 << 24) | (c1 << 16) | (c2 << 8) | c3);
+}
+
+// M2: match 2 bytes. Returns 0 if all bytes match.
+static inline uint16_t M2(struct __sk_buff* skb, unsigned int offset, uint8_t c0, uint8_t c1) {
+    return load_half(skb, offset) ^ ((c0 << 8) | c1);
+}
+
+// M1: match 1 byte. Returns 0 in case of a match.
+static inline uint8_t M1(struct __sk_buff* skb, unsigned int offset, uint8_t c0) {
+    return load_byte(skb, offset) ^ c0;
+}
+
+// Match "\0SUBSYSTEM=". Returns 0 in case of a match.
+#define MATCH_SUBSYSTEM_LENGTH 11
+static inline uint32_t match_subsystem(struct __sk_buff* skb, unsigned int offset) {
+    return M4(skb, offset + 0, '\0', 'S', 'U', 'B') | M4(skb, offset + 4, 'S', 'Y', 'S', 'T') |
+           M2(skb, offset + 8, 'E', 'M') | M1(skb, offset + 10, '=');
+}
+
+// Match "power_supply\0". Returns 0 in case of a match.
+#define MATCH_POWER_SUPPLY_LENGTH 13
+static inline uint32_t match_power_supply(struct __sk_buff* skb, unsigned int offset) {
+    return M4(skb, offset + 0, 'p', 'o', 'w', 'e') | M4(skb, offset + 4, 'r', '_', 's', 'u') |
+           M4(skb, offset + 8, 'p', 'p', 'l', 'y') | M1(skb, offset + 12, '\0');
+}
+
+// The Linux kernel 5.4 BPF verifier rejects this program, probably because of its size. Hence the
+// restriction that the kernel version must be at least 5.10.
+DEFINE_BPF_PROG_KVER("skfilter/power_supply", AID_ROOT, AID_SYSTEM, filterPowerSupplyEvents,
+                     KVER(5, 10, 0))
+(struct __sk_buff* skb) {
+    uint32_t i;
+
+    // The first character matched by match_subsystem() is a '\0'. Starting
+    // right past the netlink message header is fine since the SUBSYSTEM= text
+    // never occurs at the start. See also the kobject_uevent_env() implementation:
+    // https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/lib/kobject_uevent.c?#n473
+    // The upper bound of this loop has been chosen not to exceed the maximum
+    // number of instructions in a BPF program (BPF loops are unrolled).
+    for (i = sizeof(struct nlmsghdr); i < 256; ++i) {
+        if (i + MATCH_SUBSYSTEM_LENGTH > skb->len) {
+            break;
+        }
+        if (match_subsystem(skb, i) == 0) {
+            goto found_subsystem;
+        }
+    }
+
+    // The SUBSYSTEM= text has not been found in the bytes that have been
+    // examined: let the user space software perform filtering.
+    return skb->len;
+
+found_subsystem:
+    i += MATCH_SUBSYSTEM_LENGTH;
+    if (i + MATCH_POWER_SUPPLY_LENGTH <= skb->len && match_power_supply(skb, i) == 0) {
+        return skb->len;
+    }
+    return 0;
+}
+
+LICENSE("Apache 2.0");
+CRITICAL("healthd");
diff --git a/health/utils/libhealthloop/filterPowerSupplyEventsTest.cpp b/health/utils/libhealthloop/filterPowerSupplyEventsTest.cpp
new file mode 100644
index 0000000..e885f0b
--- /dev/null
+++ b/health/utils/libhealthloop/filterPowerSupplyEventsTest.cpp
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/unique_fd.h>
+#include <bpf/libbpf.h>
+#include <gtest/gtest.h>
+#include <linux/bpf.h>  // SO_ATTACH_BPF
+#include <linux/netlink.h>
+#include <netinet/in.h>
+#include <stdio.h>
+#include <sys/socket.h>
+#include <string>
+#include <string_view>
+
+#define ASSERT_UNIX_OK(e) ASSERT_GE(e, 0) << strerror(errno)
+
+// TODO(bvanassche): remove the code below. See also b/357099095.
+#ifndef SO_ATTACH_BPF
+#define SO_ATTACH_BPF 50  // From <asm-generic/socket.h>.
+#endif
+
+using ::android::base::unique_fd;
+using ::testing::ScopedTrace;
+
+struct test_data {
+    bool discarded;
+    std::string_view str;
+};
+
+static const uint8_t binary_bpf_prog[] = {
+#include "filterPowerSupplyEvents.h"
+};
+
+static std::vector<std::unique_ptr<ScopedTrace>>* msg_vec;
+
+std::ostream& operator<<(std::ostream& os, const test_data& td) {
+    os << "{.discarded=" << td.discarded << ", .str=";
+    for (auto c : td.str) {
+        if (isprint(c)) {
+            os << c;
+        } else {
+            os << ".";
+        }
+    }
+    return os << '}';
+}
+
+#define RECORD_ERR_MSG(fmt, ...)                                          \
+    do {                                                                  \
+        char* str;                                                        \
+        if (asprintf(&str, fmt, ##__VA_ARGS__) < 0) break;                \
+        auto st = std::make_unique<ScopedTrace>(__FILE__, __LINE__, str); \
+        msg_vec->emplace_back(std::move(st));                             \
+        free(str);                                                        \
+    } while (0)
+
+int libbpf_print_fn(enum libbpf_print_level, const char* fmt, va_list args) {
+    char* str;
+    if (vasprintf(&str, fmt, args) < 0) {
+        return 0;
+    }
+    msg_vec->emplace_back(std::make_unique<ScopedTrace>(__FILE__, -1, str));
+    free(str);
+    return 0;
+}
+
+static void record_libbpf_output() {
+    libbpf_set_print(libbpf_print_fn);
+}
+
+class filterPseTest : public testing::TestWithParam<test_data> {};
+
+struct ConnectedSockets {
+    unique_fd write_fd;
+    unique_fd read_fd;
+};
+
+// socketpair() only supports AF_UNIX sockets. AF_UNIX sockets do not
+// support BPF filters. Hence connect two TCP sockets with each other.
+static ConnectedSockets ConnectSockets(int domain, int type, int protocol) {
+    int _server_fd = socket(domain, type, protocol);
+    if (_server_fd < 0) {
+        return {};
+    }
+    unique_fd server_fd(_server_fd);
+
+    int _write_fd = socket(domain, type, protocol);
+    if (_write_fd < 0) {
+        RECORD_ERR_MSG("socket: %s", strerror(errno));
+        return {};
+    }
+    unique_fd write_fd(_write_fd);
+
+    struct sockaddr_in sa = {.sin_family = AF_INET, .sin_addr.s_addr = INADDR_ANY};
+    if (bind(_server_fd, (const struct sockaddr*)&sa, sizeof(sa)) < 0) {
+        RECORD_ERR_MSG("bind: %s", strerror(errno));
+        return {};
+    }
+    if (listen(_server_fd, 1) < 0) {
+        RECORD_ERR_MSG("listen: %s", strerror(errno));
+        return {};
+    }
+    socklen_t addr_len = sizeof(sa);
+    if (getsockname(_server_fd, (struct sockaddr*)&sa, &addr_len) < 0) {
+        RECORD_ERR_MSG("getsockname: %s", strerror(errno));
+        return {};
+    }
+    errno = 0;
+    if (connect(_write_fd, (const struct sockaddr*)&sa, sizeof(sa)) < 0 && errno != EINPROGRESS) {
+        RECORD_ERR_MSG("connect: %s", strerror(errno));
+        return {};
+    }
+    int _read_fd = accept(_server_fd, NULL, NULL);
+    if (_read_fd < 0) {
+        RECORD_ERR_MSG("accept: %s", strerror(errno));
+        return {};
+    }
+    unique_fd read_fd(_read_fd);
+
+    return {.write_fd = std::move(write_fd), .read_fd = std::move(read_fd)};
+}
+
+TEST_P(filterPseTest, filterPse) {
+    if (getuid() != 0) {
+        GTEST_SKIP() << "Must be run as root.";
+        return;
+    }
+    if (!msg_vec) {
+        msg_vec = new typeof(*msg_vec);
+    }
+    std::unique_ptr<int, void (*)(int*)> clear_msg_vec_at_end_of_scope(new int, [](int* p) {
+        msg_vec->clear();
+        delete p;
+    });
+    record_libbpf_output();
+
+    auto connected_sockets = ConnectSockets(AF_INET, SOCK_STREAM, 0);
+    unique_fd write_fd = std::move(connected_sockets.write_fd);
+    unique_fd read_fd = std::move(connected_sockets.read_fd);
+
+    ASSERT_UNIX_OK(fcntl(read_fd, F_SETFL, O_NONBLOCK));
+
+    bpf_object* obj = bpf_object__open_mem(binary_bpf_prog, sizeof(binary_bpf_prog), NULL);
+    ASSERT_TRUE(obj) << "bpf_object__open() failed" << strerror(errno);
+
+    // Find the BPF program within the object.
+    bpf_program* prog = bpf_object__find_program_by_name(obj, "filterPowerSupplyEvents");
+    ASSERT_TRUE(prog);
+
+    ASSERT_UNIX_OK(bpf_program__set_type(prog, BPF_PROG_TYPE_SOCKET_FILTER));
+
+    ASSERT_UNIX_OK(bpf_object__load(obj));
+
+    int filter_fd = bpf_program__fd(prog);
+    ASSERT_UNIX_OK(filter_fd);
+
+    int setsockopt_result =
+            setsockopt(read_fd, SOL_SOCKET, SO_ATTACH_BPF, &filter_fd, sizeof(filter_fd));
+    ASSERT_UNIX_OK(setsockopt_result);
+
+    const test_data param = GetParam();
+    const std::string header(sizeof(struct nlmsghdr), '\0');
+    ASSERT_EQ(header.length(), sizeof(struct nlmsghdr));
+    const std::string data = header + std::string(param.str);
+    const size_t len = data.length();
+    std::cerr.write(data.data(), data.length());
+    std::cerr << ")\n";
+    ASSERT_EQ(write(write_fd, data.data(), len), len);
+    std::array<uint8_t, 512> read_buf;
+    int bytes_read = read(read_fd, read_buf.data(), read_buf.size());
+    if (bytes_read < 0) {
+        ASSERT_EQ(errno, EAGAIN);
+        bytes_read = 0;
+    } else {
+        ASSERT_LT(bytes_read, read_buf.size());
+    }
+    EXPECT_EQ(bytes_read, param.discarded ? 0 : len);
+
+    bpf_object__close(obj);
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        filterPse, filterPseTest,
+        testing::Values(test_data{false, "a"},
+                        test_data{true, std::string_view("abc\0SUBSYSTEM=block\0", 20)},
+                        test_data{true, std::string_view("\0SUBSYSTEM=block", 16)},
+                        test_data{true, std::string_view("\0SUBSYSTEM=power_supply", 23)},
+                        test_data{false, std::string_view("\0SUBSYSTEM=power_supply\0", 24)},
+                        test_data{
+                                false,
+                                "012345678901234567890123456789012345678901234567890123456789012345"
+                                "678901234567890123456789012345678901234567890123456789012345678901"
+                                "234567890123456789012345678901234567890123456789012345678901234567"
+                                "890123456789012345678901234567890123456789\0SUBSYSTEM=block\0"}));
diff --git a/health/utils/libhealthloop/include/health/HealthLoop.h b/health/utils/libhealthloop/include/health/HealthLoop.h
index fc3066e..1af7274 100644
--- a/health/utils/libhealthloop/include/health/HealthLoop.h
+++ b/health/utils/libhealthloop/include/health/HealthLoop.h
@@ -20,6 +20,7 @@
 #include <mutex>
 #include <vector>
 
+#include <android-base/result.h>
 #include <android-base/unique_fd.h>
 #include <healthd/healthd.h>
 
@@ -87,6 +88,7 @@
     };
 
     int InitInternal();
+    static android::base::Result<void> AttachFilter(int uevent_fd);
     void MainLoop();
     void WakeAlarmInit();
     void WakeAlarmEvent(uint32_t);
diff --git a/media/bufferpool/aidl/default/BufferPoolClient.cpp b/media/bufferpool/aidl/default/BufferPoolClient.cpp
index ce4ad8e..b61893f 100644
--- a/media/bufferpool/aidl/default/BufferPoolClient.cpp
+++ b/media/bufferpool/aidl/default/BufferPoolClient.cpp
@@ -748,6 +748,10 @@
     } else {
         connection = mRemoteConnection;
     }
+    if (!connection) {
+        ALOGE("connection null: fetchBufferHandle()");
+        return ResultStatus::CRITICAL_ERROR;
+    }
     std::vector<FetchInfo> infos;
     std::vector<FetchResult> results;
     infos.emplace_back(FetchInfo{ToAidl(transactionId), ToAidl(bufferId)});
diff --git a/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp b/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp
index 2fc9e65..6d4936b 100644
--- a/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp
+++ b/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp
@@ -108,7 +108,7 @@
     EXPECT_EQ(NfcStatus::OK, nfc_->open(nfc_cb_));
     // Wait for OPEN_CPLT event
     auto res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
-    EXPECT_TRUE(res.no_timeout);
+    ASSERT_TRUE(res.no_timeout);
     EXPECT_EQ(NfcEvent::OPEN_CPLT, res.args->last_event_);
     EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
 
@@ -118,7 +118,7 @@
     EXPECT_EQ(data.size(), nfc_->write(data));
     // Wait for CORE_RESET_RSP
     res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
-    EXPECT_TRUE(res.no_timeout);
+    ASSERT_TRUE(res.no_timeout);
     EXPECT_GE(6ul, res.args->last_data_.size());
     EXPECT_EQ((int)NfcStatus::OK, res.args->last_data_[3]);
     if (res.args->last_data_.size() == 6) {
@@ -127,7 +127,7 @@
         EXPECT_EQ(4ul, res.args->last_data_.size());
         nci_version = NCI_VERSION_2;
         res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
-        EXPECT_TRUE(res.no_timeout);
+        ASSERT_TRUE(res.no_timeout);
     }
 
     /*
@@ -137,14 +137,14 @@
     EXPECT_EQ(NfcStatus::OK, nfc_->close());
     // Wait for CLOSE_CPLT event
     res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
-    EXPECT_TRUE(res.no_timeout);
+    ASSERT_TRUE(res.no_timeout);
     EXPECT_EQ(NfcEvent::CLOSE_CPLT, res.args->last_event_);
     EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
 
     EXPECT_EQ(NfcStatus::OK, nfc_->open(nfc_cb_));
     // Wait for OPEN_CPLT event
     res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
-    EXPECT_TRUE(res.no_timeout);
+    ASSERT_TRUE(res.no_timeout);
     EXPECT_EQ(NfcEvent::OPEN_CPLT, res.args->last_event_);
     EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
   }
@@ -153,7 +153,7 @@
     EXPECT_EQ(NfcStatus::OK, nfc_->close());
     // Wait for CLOSE_CPLT event
     auto res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
-    EXPECT_TRUE(res.no_timeout);
+    ASSERT_TRUE(res.no_timeout);
     EXPECT_EQ(NfcEvent::CLOSE_CPLT, res.args->last_event_);
     EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
   }
@@ -186,7 +186,7 @@
   EXPECT_EQ(data.size(), nfc_->write(data));
   // Wait for CORE_RESET_RSP
   auto res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
-  EXPECT_TRUE(res.no_timeout);
+  ASSERT_TRUE(res.no_timeout);
 
   /* The response/notification format for CORE_RESET_CMD differs
    * with NCI 1.0 and 2.0. */
@@ -200,7 +200,7 @@
       EXPECT_EQ((int)NfcStatus::OK, res.args->last_data_[3]);
       // Wait for CORE_RESET_NTF
       res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
-      EXPECT_TRUE(res.no_timeout);
+      ASSERT_TRUE(res.no_timeout);
       // Check if reset trigger was due to CORE_RESET_CMD
       EXPECT_LE(8ul, res.args->last_data_.size());
       EXPECT_EQ(2ul, res.args->last_data_[3]);
@@ -221,7 +221,7 @@
   EXPECT_EQ(data.size(), nfc_->write(data));
   // Wait for CORE_RESET_RSP
   auto res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
-  EXPECT_TRUE(res.no_timeout);
+  ASSERT_TRUE(res.no_timeout);
 
   /* The response/notification format for CORE_RESET_CMD differs
    * with NCI 1.0 and 2.0. */
@@ -235,7 +235,7 @@
       EXPECT_EQ((int)NfcStatus::OK, res.args->last_data_[3]);
       // Wait for CORE_RESET_NTF
       res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
-      EXPECT_TRUE(res.no_timeout);
+      ASSERT_TRUE(res.no_timeout);
       // Check if reset trigger was due to CORE_RESET_CMD
       EXPECT_LE(8ul, res.args->last_data_.size());
       EXPECT_EQ(2ul, res.args->last_data_[3]);
@@ -257,7 +257,7 @@
   EXPECT_EQ(data.size(), nfc_->write(data));
   // Wait for RSP
   auto res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
-  EXPECT_TRUE(res.no_timeout);
+  ASSERT_TRUE(res.no_timeout);
   EXPECT_EQ(4ul, res.args->last_data_.size());
   EXPECT_EQ(SYNTAX_ERROR, res.args->last_data_[3]);
 }
@@ -277,14 +277,14 @@
     EXPECT_EQ(data.size(), nfc_->write(data));
     // Wait for CORE_RESET_RSP
     auto res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
-    EXPECT_TRUE(res.no_timeout);
+    ASSERT_TRUE(res.no_timeout);
     EXPECT_EQ((int)NfcStatus::OK, res.args->last_data_[3]);
 
     /* NCI 2.0 sends CORE_RESET_NTF everytime. */
     if (nci_version == NCI_VERSION_2) {
         // Wait for CORE_RESET_NTF
         res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
-        EXPECT_TRUE(res.no_timeout);
+        ASSERT_TRUE(res.no_timeout);
         cmd = CORE_INIT_CMD_NCI20;
     } else {
         cmd = CORE_INIT_CMD;
@@ -294,7 +294,7 @@
     EXPECT_EQ(data.size(), nfc_->write(data));
     // Wait for CORE_INIT_RSP
     res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
-    EXPECT_TRUE(res.no_timeout);
+    ASSERT_TRUE(res.no_timeout);
     EXPECT_EQ((int)NfcStatus::OK, res.args->last_data_[3]);
     // Send an Error Data Packet
     cmd = INVALID_COMMAND;
@@ -307,7 +307,7 @@
         EXPECT_EQ(data.size(), nfc_->write(data));
         // Wait for response with SYNTAX_ERROR
         res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
-        EXPECT_TRUE(res.no_timeout);
+        ASSERT_TRUE(res.no_timeout);
         EXPECT_EQ(4ul, res.args->last_data_.size());
         EXPECT_EQ(SYNTAX_ERROR, res.args->last_data_[3]);
   }
@@ -317,7 +317,7 @@
   EXPECT_EQ(data.size(), nfc_->write(data));
   // Wait for CORE_CONN_CREATE_RSP
   res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
-  EXPECT_TRUE(res.no_timeout);
+  ASSERT_TRUE(res.no_timeout);
   EXPECT_EQ(7ul, res.args->last_data_.size());
   EXPECT_EQ((int)NfcStatus::OK, res.args->last_data_[3]);
 }
@@ -335,14 +335,14 @@
     EXPECT_EQ(data.size(), nfc_->write(data));
     // Wait for CORE_RESET_RSP
     auto res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
-    EXPECT_TRUE(res.no_timeout);
+    ASSERT_TRUE(res.no_timeout);
     EXPECT_EQ((int)NfcStatus::OK, res.args->last_data_[3]);
 
     /* NCI 2.0 sends CORE_RESET_NTF everytime. */
     if (nci_version == NCI_VERSION_2) {
         // Wait for CORE_RESET_NTF
         res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
-        EXPECT_TRUE(res.no_timeout);
+        ASSERT_TRUE(res.no_timeout);
         cmd = CORE_INIT_CMD_NCI20;
     } else {
         cmd = CORE_INIT_CMD;
@@ -352,15 +352,15 @@
     EXPECT_EQ(data.size(), nfc_->write(data));
     // Wait for CORE_INIT_RSP
     res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
-    EXPECT_TRUE(res.no_timeout);
+    ASSERT_TRUE(res.no_timeout);
     EXPECT_EQ((int)NfcStatus::OK, res.args->last_data_[3]);
     cmd = CORE_CONN_CREATE_CMD;
     data = cmd;
     EXPECT_EQ(data.size(), nfc_->write(data));
     // Wait for CORE_CONN_CREATE_RSP
     res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
-    EXPECT_TRUE(res.no_timeout);
-    EXPECT_TRUE(res.no_timeout);
+    ASSERT_TRUE(res.no_timeout);
+    ASSERT_TRUE(res.no_timeout);
     EXPECT_EQ(7ul, res.args->last_data_.size());
     EXPECT_EQ((int)NfcStatus::OK, res.args->last_data_[3]);
     uint8_t conn_id = res.args->last_data_[6];
@@ -414,7 +414,7 @@
   EXPECT_EQ(NfcStatus::OK, nfc_->powerCycle());
   // Wait for NfcEvent.OPEN_CPLT
   auto res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
-  EXPECT_TRUE(res.no_timeout);
+  ASSERT_TRUE(res.no_timeout);
   EXPECT_EQ(NfcEvent::OPEN_CPLT, res.args->last_event_);
   EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
 }
@@ -428,7 +428,7 @@
   EXPECT_EQ(NfcStatus::OK, nfc_->close());
   // Wait for CLOSE_CPLT event
   auto res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
-  EXPECT_TRUE(res.no_timeout);
+  ASSERT_TRUE(res.no_timeout);
   EXPECT_EQ(NfcEvent::CLOSE_CPLT, res.args->last_event_);
   EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
 
@@ -437,7 +437,7 @@
   EXPECT_EQ(NfcStatus::OK, nfc_->open(nfc_cb_));
   // Wait for OPEN_CPLT event
   res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
-  EXPECT_TRUE(res.no_timeout);
+  ASSERT_TRUE(res.no_timeout);
   EXPECT_EQ(NfcEvent::OPEN_CPLT, res.args->last_event_);
   EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
 }
@@ -464,7 +464,7 @@
       EXPECT_EQ(NfcStatus::OK, status);
       // Wait for NfcEvent.POST_INIT_CPLT
       auto res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
-      EXPECT_TRUE(res.no_timeout);
+      ASSERT_TRUE(res.no_timeout);
       EXPECT_EQ(NfcEvent::POST_INIT_CPLT, res.args->last_event_);
   }
 }
@@ -487,7 +487,7 @@
   EXPECT_EQ(NfcStatus::OK, nfc_->close());
   // Wait for CLOSE_CPLT event
   auto res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
-  EXPECT_TRUE(res.no_timeout);
+  ASSERT_TRUE(res.no_timeout);
   EXPECT_EQ(NfcEvent::CLOSE_CPLT, res.args->last_event_);
   EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
 
@@ -496,7 +496,7 @@
   EXPECT_EQ(NfcStatus::OK, nfc_->open(nfc_cb_));
   // Wait for OPEN_CPLT event
   res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
-  EXPECT_TRUE(res.no_timeout);
+  ASSERT_TRUE(res.no_timeout);
   EXPECT_EQ(NfcEvent::OPEN_CPLT, res.args->last_event_);
   EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
 }
@@ -518,7 +518,7 @@
   EXPECT_EQ(NfcStatus::OK, nfc_->close());
   // Wait for CLOSE_CPLT event
   auto res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
-  EXPECT_TRUE(res.no_timeout);
+  ASSERT_TRUE(res.no_timeout);
   EXPECT_EQ(NfcEvent::CLOSE_CPLT, res.args->last_event_);
   EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
 
@@ -527,7 +527,7 @@
   EXPECT_EQ(NfcStatus::OK, nfc_->open(nfc_cb_));
   // Wait for OPEN_CPLT event
   res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
-  EXPECT_TRUE(res.no_timeout);
+  ASSERT_TRUE(res.no_timeout);
   EXPECT_EQ(NfcEvent::OPEN_CPLT, res.args->last_event_);
   EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
 }
@@ -541,7 +541,7 @@
   EXPECT_EQ(NfcStatus::OK, nfc_->close());
   // Wait for CLOSE_CPLT event
   auto res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
-  EXPECT_TRUE(res.no_timeout);
+  ASSERT_TRUE(res.no_timeout);
   EXPECT_EQ(NfcEvent::CLOSE_CPLT, res.args->last_event_);
   EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
 
@@ -550,7 +550,7 @@
   EXPECT_EQ(NfcStatus::OK, nfc_->open(nfc_cb_));
   // Wait for OPEN_CPLT event
   res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
-  EXPECT_TRUE(res.no_timeout);
+  ASSERT_TRUE(res.no_timeout);
   EXPECT_EQ(NfcEvent::OPEN_CPLT, res.args->last_event_);
   EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
 }
@@ -564,14 +564,14 @@
   EXPECT_EQ(NfcStatus::OK, nfc_->open(nfc_cb_));
   // Wait for OPEN_CPLT event
   auto res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
-  EXPECT_TRUE(res.no_timeout);
+  ASSERT_TRUE(res.no_timeout);
   EXPECT_EQ(NfcEvent::OPEN_CPLT, res.args->last_event_);
   EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
 
   EXPECT_EQ(NfcStatus::OK, nfc_->open(nfc_cb_));
   // Wait for OPEN_CPLT event
   res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
-  EXPECT_TRUE(res.no_timeout);
+  ASSERT_TRUE(res.no_timeout);
   EXPECT_EQ(NfcEvent::OPEN_CPLT, res.args->last_event_);
   EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
 }
diff --git a/nfc/aidl/vts/functional/Android.bp b/nfc/aidl/vts/functional/Android.bp
index 82ce026..f97405e 100644
--- a/nfc/aidl/vts/functional/Android.bp
+++ b/nfc/aidl/vts/functional/Android.bp
@@ -49,6 +49,7 @@
 cc_test {
     name: "VtsNfcBehaviorChangesTest",
     defaults: [
+        "aconfig_lib_cc_shared_link.defaults",
         "VtsHalTargetTestDefaults",
         "use_libaidlvintf_gtest_helper_static",
     ],
@@ -65,6 +66,7 @@
         "system/nfc/utils/include",
     ],
     shared_libs: [
+        "liblog",
         "libbinder",
         "libbinder_ndk",
         "libnativehelper",
diff --git a/radio/aidl/vts/Android.bp b/radio/aidl/vts/Android.bp
index e83a7c1..9521068 100644
--- a/radio/aidl/vts/Android.bp
+++ b/radio/aidl/vts/Android.bp
@@ -25,6 +25,7 @@
 cc_test {
     name: "VtsHalRadioTargetTest",
     defaults: [
+        "aconfig_lib_cc_shared_link.defaults",
         "VtsHalTargetTestDefaults",
         "use_libaidlvintf_gtest_helper_static",
     ],
diff --git a/radio/aidl/vts/radio_sim_test.cpp b/radio/aidl/vts/radio_sim_test.cpp
index 06654c2..e9b68cc 100644
--- a/radio/aidl/vts/radio_sim_test.cpp
+++ b/radio/aidl/vts/radio_sim_test.cpp
@@ -118,7 +118,14 @@
         EXPECT_EQ(CardStatus::STATE_PRESENT, slotStatus.cardState);
         if (CardStatus::STATE_PRESENT == slotStatus.cardState) {
             ASSERT_TRUE(slotStatus.portInfo[0].portActive);
-            EXPECT_EQ(0, cardStatus.slotMap.portId);
+            if (cardStatus.supportedMepMode == aidl::android::hardware::radio::config::
+                                                       MultipleEnabledProfilesMode::MEP_A1 ||
+                cardStatus.supportedMepMode == aidl::android::hardware::radio::config::
+                                                       MultipleEnabledProfilesMode::MEP_A2) {
+                EXPECT_EQ(1, cardStatus.slotMap.portId);
+            } else {
+                EXPECT_EQ(0, cardStatus.slotMap.portId);
+            }
         }
     }
 }
diff --git a/security/keymint/support/fuzzer/keymint_attestation_fuzzer.cpp b/security/keymint/support/fuzzer/keymint_attestation_fuzzer.cpp
index bd781ac..1757997 100644
--- a/security/keymint/support/fuzzer/keymint_attestation_fuzzer.cpp
+++ b/security/keymint/support/fuzzer/keymint_attestation_fuzzer.cpp
@@ -151,7 +151,7 @@
 
 extern "C" int LLVMFuzzerInitialize(int /* *argc */, char /* ***argv */) {
     ::ndk::SpAIBinder binder(AServiceManager_waitForService(kServiceName.c_str()));
-    gKeyMint = std::move(IKeyMintDevice::fromBinder(binder));
+    gKeyMint = IKeyMintDevice::fromBinder(binder);
     LOG_ALWAYS_FATAL_IF(!gKeyMint, "Failed to get IKeyMintDevice instance.");
     return 0;
 }
diff --git a/security/keymint/support/remote_prov_utils.cpp b/security/keymint/support/remote_prov_utils.cpp
index 6638775..29124af 100644
--- a/security/keymint/support/remote_prov_utils.cpp
+++ b/security/keymint/support/remote_prov_utils.cpp
@@ -974,15 +974,16 @@
 
 ErrMsgOr<hwtrust::DiceChain::Kind> getDiceChainKind() {
     int vendor_api_level = ::android::base::GetIntProperty("ro.vendor.api_level", -1);
-    switch (vendor_api_level) {
-        case __ANDROID_API_T__:
-            return hwtrust::DiceChain::Kind::kVsr13;
-        case __ANDROID_API_U__:
-            return hwtrust::DiceChain::Kind::kVsr14;
-        case 202404: /* TODO(b/315056516) Use a version macro for vendor API 24Q2 */
-            return hwtrust::DiceChain::Kind::kVsr15;
-        default:
-            return "Unsupported vendor API level: " + std::to_string(vendor_api_level);
+    if (vendor_api_level == __ANDROID_API_T__) {
+        return hwtrust::DiceChain::Kind::kVsr13;
+    } else if (vendor_api_level == __ANDROID_API_U__) {
+        return hwtrust::DiceChain::Kind::kVsr14;
+    } else if (vendor_api_level == 202404) {
+        return hwtrust::DiceChain::Kind::kVsr15;
+    } else if (vendor_api_level > 202404) {
+        return hwtrust::DiceChain::Kind::kVsr16;
+    } else {
+        return "Unsupported vendor API level: " + std::to_string(vendor_api_level);
     }
 }
 
diff --git a/security/rkp/aidl/android/hardware/security/keymint/generateCertificateRequestV2.cddl b/security/rkp/aidl/android/hardware/security/keymint/generateCertificateRequestV2.cddl
index 3c43238..40cf685 100644
--- a/security/rkp/aidl/android/hardware/security/keymint/generateCertificateRequestV2.cddl
+++ b/security/rkp/aidl/android/hardware/security/keymint/generateCertificateRequestV2.cddl
@@ -62,9 +62,13 @@
 SignerName = tstr
 
 UdsCertChain = [
-    2* X509Certificate      ; Root -> ... -> Leaf. "Root" is the vendor self-signed
-                            ; cert, "Leaf" contains UDS_Public. There may also be
-                            ; intermediate certificates between Root and Leaf.
+    + X509Certificate       ; Root -> ... -> Leaf. "Root" is the vendor self-signed
+                            ; cert, "Leaf" contains UDS_Public. It's recommended to
+                            ; have at least 3 certificates in the chain.
+                            ; The Root certificate is recommended to be generated in an air-gapped,
+                            ; HSM-based secure environment. The intermediate signing keys may be
+                            ; online, and should be rotated regularly (e.g. annually). Additionally,
+                            ; the intermediate certificates may contain product family identifiers.
 ]
 
 ; A bstr containing a DER-encoded X.509 certificate (RSA, NIST P-curve, or EdDSA)