Merge "Camera: Misc VTS test fixes" into tm-dev
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/ConcurrentQueue.h b/automotive/vehicle/aidl/impl/utils/common/include/ConcurrentQueue.h
index 08b56a6..327c0dc 100644
--- a/automotive/vehicle/aidl/impl/utils/common/include/ConcurrentQueue.h
+++ b/automotive/vehicle/aidl/impl/utils/common/include/ConcurrentQueue.h
@@ -33,12 +33,13 @@
 template <typename T>
 class ConcurrentQueue {
   public:
-    void waitForItems() {
+    bool waitForItems() {
         std::unique_lock<std::mutex> lockGuard(mLock);
         android::base::ScopedLockAssertion lockAssertion(mLock);
         while (mQueue.empty() && mIsActive) {
             mCond.wait(lockGuard);
         }
+        return mIsActive;
     }
 
     std::vector<T> flush() {
diff --git a/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h b/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
index 84b6742..2db7675 100644
--- a/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
+++ b/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
@@ -22,6 +22,7 @@
 #include "PendingRequestPool.h"
 #include "SubscriptionManager.h"
 
+#include <ConcurrentQueue.h>
 #include <IVehicleHardware.h>
 #include <VehicleUtils.h>
 #include <aidl/android/hardware/automotive/vehicle/BnVehicle.h>
@@ -31,6 +32,7 @@
 
 #include <memory>
 #include <mutex>
+#include <shared_mutex>
 #include <unordered_map>
 #include <vector>
 
@@ -105,6 +107,8 @@
       public:
         SubscriptionClients(std::shared_ptr<PendingRequestPool> pool) : mPendingRequestPool(pool) {}
 
+        std::shared_ptr<SubscriptionClient> maybeAddClient(const CallbackType& callback);
+
         std::shared_ptr<SubscriptionClient> getClient(const CallbackType& callback);
 
         void removeClient(const AIBinder* clientId);
@@ -119,20 +123,24 @@
         std::shared_ptr<PendingRequestPool> mPendingRequestPool;
     };
 
-    // A wrapper for linkToDeath to enable stubbing for test.
-    class ILinkToDeath {
+    // A wrapper for binder operations to enable stubbing for test.
+    class IBinder {
       public:
-        virtual ~ILinkToDeath() = default;
+        virtual ~IBinder() = default;
 
         virtual binder_status_t linkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient,
                                             void* cookie) = 0;
+
+        virtual bool isAlive(const AIBinder* binder) = 0;
     };
 
-    // A real implementation for ILinkToDeath.
-    class AIBinderLinkToDeathImpl final : public ILinkToDeath {
+    // A real implementation for IBinder.
+    class AIBinderImpl final : public IBinder {
       public:
         binder_status_t linkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient,
                                     void* cookie) override;
+
+        bool isAlive(const AIBinder* binder) override;
     };
 
     // OnBinderDiedContext is a type used as a cookie passed deathRecipient. The deathRecipient's
@@ -143,6 +151,13 @@
         const AIBinder* clientId;
     };
 
+    // BinderDiedUnlinkedEvent represents either an onBinderDied or an onBinderUnlinked event.
+    struct BinderDiedUnlinkedEvent {
+        // true for onBinderDied, false for onBinderUnlinked.
+        bool onBinderDied;
+        const AIBinder* clientId;
+    };
+
     // The default timeout of get or set value requests is 30s.
     // TODO(b/214605968): define TIMEOUT_IN_NANO in IVehicle and allow getValues/setValues/subscribe
     // to specify custom timeouts.
@@ -171,14 +186,20 @@
             GUARDED_BY(mLock);
     // SubscriptionClients is thread-safe.
     std::shared_ptr<SubscriptionClients> mSubscriptionClients;
-    // mLinkToDeathImpl is only going to be changed in test.
-    std::unique_ptr<ILinkToDeath> mLinkToDeathImpl;
+    // mBinderImpl is only going to be changed in test.
+    std::unique_ptr<IBinder> mBinderImpl;
 
     // RecurrentTimer is thread-safe.
     RecurrentTimer mRecurrentTimer;
 
     ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
 
+    // ConcurrentQueue is thread-safe.
+    ConcurrentQueue<BinderDiedUnlinkedEvent> mBinderEvents;
+
+    // A thread to handle onBinderDied or onBinderUnlinked event.
+    std::thread mOnBinderDiedUnlinkedHandlerThread;
+
     android::base::Result<void> checkProperty(
             const aidl::android::hardware::automotive::vehicle::VehiclePropValue& propValue);
 
@@ -207,10 +228,17 @@
 
     void onBinderUnlinkedWithContext(const AIBinder* clientId);
 
-    void monitorBinderLifeCycle(const CallbackType& callback);
+    // Registers a onBinderDied callback for the client if not already registered.
+    // Returns true if the client Binder is alive, false otherwise.
+    bool monitorBinderLifeCycleLocked(const AIBinder* clientId) REQUIRES(mLock);
 
     bool checkDumpPermission();
 
+    // The looping handler function to process all onBinderDied or onBinderUnlinked events in
+    // mBinderEvents.
+    void onBinderDiedUnlinkedHandler();
+
+    // Gets or creates a {@code T} object for the client to or from {@code clients}.
     template <class T>
     static std::shared_ptr<T> getOrCreateClient(
             std::unordered_map<const AIBinder*, std::shared_ptr<T>>* clients,
@@ -239,7 +267,7 @@
     void setTimeout(int64_t timeoutInNano);
 
     // Test-only
-    void setLinkToDeathImpl(std::unique_ptr<ILinkToDeath> impl);
+    void setBinderImpl(std::unique_ptr<IBinder> impl);
 };
 
 }  // namespace vehicle
diff --git a/automotive/vehicle/aidl/impl/vhal/src/ConnectedClient.cpp b/automotive/vehicle/aidl/impl/vhal/src/ConnectedClient.cpp
index 5c5f27e..4cfc2be 100644
--- a/automotive/vehicle/aidl/impl/vhal/src/ConnectedClient.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/src/ConnectedClient.cpp
@@ -67,9 +67,10 @@
     parcelableResults.payloads[0] = result;
     if (ScopedAStatus callbackStatus = callCallback(callback, parcelableResults);
         !callbackStatus.isOk()) {
-        ALOGE("failed to call callback, error: %s, exception: %d, service specific error: %d",
-              callbackStatus.getMessage(), callbackStatus.getExceptionCode(),
-              callbackStatus.getServiceSpecificError());
+        ALOGE("failed to call GetOrSetValueResult callback, client ID: %p, error: %s, "
+              "exception: %d, service specific error: %d",
+              callback->asBinder().get(), callbackStatus.getMessage(),
+              callbackStatus.getExceptionCode(), callbackStatus.getServiceSpecificError());
     }
 }
 
@@ -91,9 +92,10 @@
     if (status.isOk()) {
         if (ScopedAStatus callbackStatus = callCallback(callback, parcelableResults);
             !callbackStatus.isOk()) {
-            ALOGE("failed to call callback, error: %s, exception: %d, service specific error: %d",
-                  callbackStatus.getMessage(), callbackStatus.getExceptionCode(),
-                  callbackStatus.getServiceSpecificError());
+            ALOGE("failed to call GetOrSetValueResults callback, client ID: %p, error: %s, "
+                  "exception: %d, service specific error: %d",
+                  callback->asBinder().get(), callbackStatus.getMessage(),
+                  callbackStatus.getExceptionCode(), callbackStatus.getServiceSpecificError());
         }
         return;
     }
@@ -299,10 +301,10 @@
     if (ScopedAStatus callbackStatus =
                 callback->onPropertyEvent(vehiclePropValues, sharedMemoryFileCount);
         !callbackStatus.isOk()) {
-        ALOGE("subscribe: failed to call callback, error: %s, exception: %d, "
-              "service specific error: %d",
-              callbackStatus.getMessage(), callbackStatus.getExceptionCode(),
-              callbackStatus.getServiceSpecificError());
+        ALOGE("subscribe: failed to call UpdateValues callback, client ID: %p, error: %s, "
+              "exception: %d, service specific error: %d",
+              callback->asBinder().get(), callbackStatus.getMessage(),
+              callbackStatus.getExceptionCode(), callbackStatus.getServiceSpecificError());
     }
 }
 
diff --git a/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp b/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
index b50571b..886f897 100644
--- a/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
@@ -80,12 +80,22 @@
 
 }  // namespace
 
-std::shared_ptr<SubscriptionClient> DefaultVehicleHal::SubscriptionClients::getClient(
+std::shared_ptr<SubscriptionClient> DefaultVehicleHal::SubscriptionClients::maybeAddClient(
         const CallbackType& callback) {
     std::scoped_lock<std::mutex> lockGuard(mLock);
     return getOrCreateClient(&mClients, callback, mPendingRequestPool);
 }
 
+std::shared_ptr<SubscriptionClient> DefaultVehicleHal::SubscriptionClients::getClient(
+        const CallbackType& callback) {
+    std::scoped_lock<std::mutex> lockGuard(mLock);
+    const AIBinder* clientId = callback->asBinder().get();
+    if (mClients.find(clientId) == mClients.end()) {
+        return nullptr;
+    }
+    return mClients[clientId];
+}
+
 int64_t DefaultVehicleHal::SubscribeIdByClient::getId(const CallbackType& callback) {
     std::scoped_lock<std::mutex> lockGuard(mLock);
     // This would be initialized to 0 if callback does not exist in the map.
@@ -148,7 +158,8 @@
                 checkHealth(hardwareCopy, subscriptionManagerCopy);
             }));
 
-    mLinkToDeathImpl = std::make_unique<AIBinderLinkToDeathImpl>();
+    mBinderImpl = std::make_unique<AIBinderImpl>();
+    mOnBinderDiedUnlinkedHandlerThread = std::thread([this] { onBinderDiedUnlinkedHandler(); });
     mDeathRecipient = ScopedAIBinder_DeathRecipient(
             AIBinder_DeathRecipient_new(&DefaultVehicleHal::onBinderDied));
     AIBinder_DeathRecipient_setOnUnlinked(mDeathRecipient.get(),
@@ -158,6 +169,10 @@
 DefaultVehicleHal::~DefaultVehicleHal() {
     // Delete the deathRecipient so that onBinderDied would not be called to reference 'this'.
     mDeathRecipient = ScopedAIBinder_DeathRecipient();
+    mBinderEvents.deactivate();
+    if (mOnBinderDiedUnlinkedHandlerThread.joinable()) {
+        mOnBinderDiedUnlinkedHandlerThread.join();
+    }
 }
 
 void DefaultVehicleHal::onPropertyChangeEvent(
@@ -189,37 +204,41 @@
     return (*clients)[clientId];
 }
 
-void DefaultVehicleHal::monitorBinderLifeCycle(const CallbackType& callback) {
-    AIBinder* clientId = callback->asBinder().get();
-    {
-        std::scoped_lock<std::mutex> lockGuard(mLock);
-        if (mOnBinderDiedContexts.find(clientId) != mOnBinderDiedContexts.end()) {
-            // Already registered.
-            return;
-        }
-    }
-
-    std::unique_ptr<OnBinderDiedContext> context = std::make_unique<OnBinderDiedContext>(
-            OnBinderDiedContext{.vhal = this, .clientId = clientId});
-    binder_status_t status = mLinkToDeathImpl->linkToDeath(clientId, mDeathRecipient.get(),
-                                                           static_cast<void*>(context.get()));
-    if (status == STATUS_OK) {
-        std::scoped_lock<std::mutex> lockGuard(mLock);
+bool DefaultVehicleHal::monitorBinderLifeCycleLocked(const AIBinder* clientId) {
+    OnBinderDiedContext* contextPtr = nullptr;
+    if (mOnBinderDiedContexts.find(clientId) != mOnBinderDiedContexts.end()) {
+        return mBinderImpl->isAlive(clientId);
+    } else {
+        std::unique_ptr<OnBinderDiedContext> context = std::make_unique<OnBinderDiedContext>(
+                OnBinderDiedContext{.vhal = this, .clientId = clientId});
+        // We know context must be alive when we use contextPtr because context would only
+        // be removed in OnBinderUnlinked, which must be called after OnBinderDied.
+        contextPtr = context.get();
         // Insert into a map to keep the context object alive.
         mOnBinderDiedContexts[clientId] = std::move(context);
-    } else {
-        ALOGE("failed to call linkToDeath on client binder, status: %d", static_cast<int>(status));
     }
+
+    // If this function fails, onBinderUnlinked would be called to remove the added context.
+    binder_status_t status = mBinderImpl->linkToDeath(
+            const_cast<AIBinder*>(clientId), mDeathRecipient.get(), static_cast<void*>(contextPtr));
+    if (status == STATUS_OK) {
+        return true;
+    }
+    ALOGE("failed to call linkToDeath on client binder, client may already died, status: %d",
+          static_cast<int>(status));
+    return false;
 }
 
 void DefaultVehicleHal::onBinderDied(void* cookie) {
     OnBinderDiedContext* context = reinterpret_cast<OnBinderDiedContext*>(cookie);
-    context->vhal->onBinderDiedWithContext(context->clientId);
+    // To be handled in mOnBinderDiedUnlinkedHandlerThread. We cannot handle the event in the same
+    // thread because we might be holding the mLock the handler requires.
+    context->vhal->mBinderEvents.push(BinderDiedUnlinkedEvent{true, context->clientId});
 }
 
 void DefaultVehicleHal::onBinderDiedWithContext(const AIBinder* clientId) {
-    ALOGD("binder died");
     std::scoped_lock<std::mutex> lockGuard(mLock);
+    ALOGD("binder died, client ID: %p", clientId);
     mSetValuesClients.erase(clientId);
     mGetValuesClients.erase(clientId);
     mSubscriptionClients->removeClient(clientId);
@@ -227,17 +246,31 @@
 }
 
 void DefaultVehicleHal::onBinderUnlinked(void* cookie) {
-    // Delete the context associated with this cookie.
     OnBinderDiedContext* context = reinterpret_cast<OnBinderDiedContext*>(cookie);
-    context->vhal->onBinderUnlinkedWithContext(context->clientId);
+    // To be handled in mOnBinderDiedUnlinkedHandlerThread. We cannot handle the event in the same
+    // thread because we might be holding the mLock the handler requires.
+    context->vhal->mBinderEvents.push(BinderDiedUnlinkedEvent{false, context->clientId});
 }
 
 void DefaultVehicleHal::onBinderUnlinkedWithContext(const AIBinder* clientId) {
     ALOGD("binder unlinked");
     std::scoped_lock<std::mutex> lockGuard(mLock);
+    // Delete the context associated with this cookie.
     mOnBinderDiedContexts.erase(clientId);
 }
 
+void DefaultVehicleHal::onBinderDiedUnlinkedHandler() {
+    while (mBinderEvents.waitForItems()) {
+        for (BinderDiedUnlinkedEvent& event : mBinderEvents.flush()) {
+            if (event.onBinderDied) {
+                onBinderDiedWithContext(event.clientId);
+            } else {
+                onBinderUnlinkedWithContext(event.clientId);
+            }
+        }
+    }
+}
+
 template std::shared_ptr<DefaultVehicleHal::GetValuesClient>
 DefaultVehicleHal::getOrCreateClient<DefaultVehicleHal::GetValuesClient>(
         std::unordered_map<const AIBinder*, std::shared_ptr<GetValuesClient>>* clients,
@@ -258,6 +291,10 @@
         const VehiclePropValue& value) {
     int64_t subscribeId = subscribeIdByClient->getId(callback);
     auto client = subscriptionClients->getClient(callback);
+    if (client == nullptr) {
+        ALOGW("subscribe[%" PRId64 "]: the client has died", subscribeId);
+        return;
+    }
     if (auto addRequestResult = client->addRequests({subscribeId}); !addRequestResult.ok()) {
         ALOGE("subscribe[%" PRId64 "]: too many pending requests, ignore the getValue request",
               subscribeId);
@@ -336,8 +373,6 @@
 
 ScopedAStatus DefaultVehicleHal::getValues(const CallbackType& callback,
                                            const GetValueRequests& requests) {
-    monitorBinderLifeCycle(callback);
-
     expected<LargeParcelableBase::BorrowedOwnedObject<GetValueRequests>, ScopedAStatus>
             deserializedResults = fromStableLargeParcelable(requests);
     if (!deserializedResults.ok()) {
@@ -379,9 +414,16 @@
 
     std::shared_ptr<GetValuesClient> client;
     {
-        std::scoped_lock<std::mutex> lockGuard(mLock);
+        // Lock to make sure onBinderDied would not be called concurrently.
+        std::scoped_lock lockGuard(mLock);
+        if (!monitorBinderLifeCycleLocked(callback->asBinder().get())) {
+            return ScopedAStatus::fromExceptionCodeWithMessage(EX_TRANSACTION_FAILED,
+                                                               "client died");
+        }
+
         client = getOrCreateClient(&mGetValuesClients, callback, mPendingRequestPool);
     }
+
     // Register the pending hardware requests and also check for duplicate request Ids.
     if (auto addRequestResult = client->addRequests(hardwareRequestIds); !addRequestResult.ok()) {
         ALOGE("getValues[%s]: failed to add pending requests, error: %s",
@@ -414,8 +456,6 @@
 
 ScopedAStatus DefaultVehicleHal::setValues(const CallbackType& callback,
                                            const SetValueRequests& requests) {
-    monitorBinderLifeCycle(callback);
-
     expected<LargeParcelableBase::BorrowedOwnedObject<SetValueRequests>, ScopedAStatus>
             deserializedResults = fromStableLargeParcelable(requests);
     if (!deserializedResults.ok()) {
@@ -467,7 +507,12 @@
 
     std::shared_ptr<SetValuesClient> client;
     {
-        std::scoped_lock<std::mutex> lockGuard(mLock);
+        // Lock to make sure onBinderDied would not be called concurrently.
+        std::scoped_lock lockGuard(mLock);
+        if (!monitorBinderLifeCycleLocked(callback->asBinder().get())) {
+            return ScopedAStatus::fromExceptionCodeWithMessage(EX_TRANSACTION_FAILED,
+                                                               "client died");
+        }
         client = getOrCreateClient(&mSetValuesClients, callback, mPendingRequestPool);
     }
 
@@ -602,8 +647,6 @@
 ScopedAStatus DefaultVehicleHal::subscribe(const CallbackType& callback,
                                            const std::vector<SubscribeOptions>& options,
                                            [[maybe_unused]] int32_t maxSharedMemoryFileCount) {
-    monitorBinderLifeCycle(callback);
-
     // TODO(b/205189110): Use shared memory file count.
     if (auto result = checkSubscribeOptions(options); !result.ok()) {
         ALOGE("subscribe: invalid subscribe options: %s", getErrorMsg(result).c_str());
@@ -635,14 +678,27 @@
             onChangeSubscriptions.push_back(std::move(optionCopy));
         }
     }
-    // Since we have already check the sample rates, the following functions must succeed.
-    if (!onChangeSubscriptions.empty()) {
-        mSubscriptionManager->subscribe(callback, onChangeSubscriptions,
-                                        /*isContinuousProperty=*/false);
-    }
-    if (!continuousSubscriptions.empty()) {
-        mSubscriptionManager->subscribe(callback, continuousSubscriptions,
-                                        /*isContinuousProperty=*/true);
+
+    {
+        // Lock to make sure onBinderDied would not be called concurrently.
+        std::scoped_lock lockGuard(mLock);
+        if (!monitorBinderLifeCycleLocked(callback->asBinder().get())) {
+            return ScopedAStatus::fromExceptionCodeWithMessage(EX_TRANSACTION_FAILED,
+                                                               "client died");
+        }
+
+        // Create a new SubscriptionClient if there isn't an existing one.
+        mSubscriptionClients->maybeAddClient(callback);
+
+        // Since we have already check the sample rates, the following functions must succeed.
+        if (!onChangeSubscriptions.empty()) {
+            mSubscriptionManager->subscribe(callback, onChangeSubscriptions,
+                                            /*isContinuousProperty=*/false);
+        }
+        if (!continuousSubscriptions.empty()) {
+            mSubscriptionManager->subscribe(callback, continuousSubscriptions,
+                                            /*isContinuousProperty=*/true);
+        }
     }
     return ScopedAStatus::ok();
 }
@@ -719,13 +775,18 @@
     return;
 }
 
-binder_status_t DefaultVehicleHal::AIBinderLinkToDeathImpl::linkToDeath(
-        AIBinder* binder, AIBinder_DeathRecipient* recipient, void* cookie) {
+binder_status_t DefaultVehicleHal::AIBinderImpl::linkToDeath(AIBinder* binder,
+                                                             AIBinder_DeathRecipient* recipient,
+                                                             void* cookie) {
     return AIBinder_linkToDeath(binder, recipient, cookie);
 }
 
-void DefaultVehicleHal::setLinkToDeathImpl(std::unique_ptr<ILinkToDeath> impl) {
-    mLinkToDeathImpl = std::move(impl);
+bool DefaultVehicleHal::AIBinderImpl::isAlive(const AIBinder* binder) {
+    return AIBinder_isAlive(binder);
+}
+
+void DefaultVehicleHal::setBinderImpl(std::unique_ptr<IBinder> impl) {
+    mBinderImpl = std::move(impl);
 }
 
 bool DefaultVehicleHal::checkDumpPermission() {
diff --git a/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp b/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
index aafa17e..6f8eb1d 100644
--- a/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
@@ -332,7 +332,9 @@
         mCallbackClient = IVehicleCallback::fromBinder(mBinder);
 
         // Set the linkToDeath to a fake implementation that always returns OK.
-        setTestLinkToDeathImpl();
+        auto binderImpl = std::make_unique<TestBinderImpl>();
+        mBinderImpl = binderImpl.get();
+        mVhal->setBinderImpl(std::move(binderImpl));
     }
 
     void TearDown() override {
@@ -350,10 +352,6 @@
 
     void setTimeout(int64_t timeoutInNano) { mVhal->setTimeout(timeoutInNano); }
 
-    void setTestLinkToDeathImpl() {
-        mVhal->setLinkToDeathImpl(std::make_unique<TestLinkToDeathImpl>());
-    }
-
     size_t countPendingRequests() { return mVhal->mPendingRequestPool->countPendingRequests(); }
 
     size_t countClients() {
@@ -380,6 +378,8 @@
 
     bool hasNoSubscriptions() { return mVhal->mSubscriptionManager->isEmpty(); }
 
+    void setBinderAlive(bool isAlive) { mBinderImpl->setAlive(isAlive); };
+
     static Result<void> getValuesTestCases(size_t size, GetValueRequests& requests,
                                            std::vector<GetValueResult>& expectedResults,
                                            std::vector<GetValueRequest>& expectedHardwareRequests) {
@@ -452,19 +452,31 @@
     }
 
   private:
+    class TestBinderImpl final : public DefaultVehicleHal::IBinder {
+      public:
+        binder_status_t linkToDeath(AIBinder*, AIBinder_DeathRecipient*, void*) override {
+            if (mIsAlive) {
+                return STATUS_OK;
+            } else {
+                return STATUS_FAILED_TRANSACTION;
+            }
+        }
+
+        bool isAlive(const AIBinder*) override { return mIsAlive; }
+
+        void setAlive(bool isAlive) { mIsAlive = isAlive; }
+
+      private:
+        bool mIsAlive = true;
+    };
+
     std::shared_ptr<DefaultVehicleHal> mVhal;
     std::shared_ptr<IVehicle> mVhalClient;
     MockVehicleHardware* mHardwarePtr;
     std::shared_ptr<MockVehicleCallback> mCallback;
     std::shared_ptr<IVehicleCallback> mCallbackClient;
     SpAIBinder mBinder;
-
-    class TestLinkToDeathImpl final : public DefaultVehicleHal::ILinkToDeath {
-      public:
-        binder_status_t linkToDeath(AIBinder*, AIBinder_DeathRecipient*, void*) override {
-            return STATUS_OK;
-        }
-    };
+    TestBinderImpl* mBinderImpl;
 };
 
 TEST_F(DefaultVehicleHalTest, testGetAllPropConfigsSmall) {
@@ -587,7 +599,6 @@
 
     ASSERT_TRUE(getValuesTestCases(5000, requests, expectedResults, expectedHardwareRequests).ok())
             << "requests to hardware mismatch";
-    ;
 
     getHardware()->addGetValueResponses(expectedResults);
 
@@ -806,6 +817,51 @@
     ASSERT_FALSE(status.isOk()) << "duplicate request properties in one request must fail";
 }
 
+TEST_F(DefaultVehicleHalTest, testGetValuesNewClientDied) {
+    GetValueRequests requests;
+    std::vector<GetValueResult> expectedResults;
+    std::vector<GetValueRequest> expectedHardwareRequests;
+
+    ASSERT_TRUE(getValuesTestCases(10, requests, expectedResults, expectedHardwareRequests).ok());
+
+    getHardware()->addGetValueResponses(expectedResults);
+
+    setBinderAlive(false);
+
+    auto status = getClient()->getValues(getCallbackClient(), requests);
+
+    ASSERT_FALSE(status.isOk()) << "getValues must fail if client died";
+    ASSERT_EQ(status.getExceptionCode(), EX_TRANSACTION_FAILED);
+    EXPECT_EQ(countClients(), static_cast<size_t>(0))
+            << "No client should be created if the client binder died";
+}
+
+TEST_F(DefaultVehicleHalTest, testGetValuesExistingClientDied) {
+    GetValueRequests requests;
+    std::vector<GetValueResult> expectedResults;
+    std::vector<GetValueRequest> expectedHardwareRequests;
+
+    ASSERT_TRUE(getValuesTestCases(10, requests, expectedResults, expectedHardwareRequests).ok());
+
+    getHardware()->addGetValueResponses(expectedResults);
+
+    // Try a normal getValue request to cache a GetValueClient first.
+    auto status = getClient()->getValues(getCallbackClient(), requests);
+
+    ASSERT_TRUE(status.isOk()) << "getValues failed: " << status.getMessage();
+    EXPECT_EQ(countClients(), static_cast<size_t>(1));
+
+    // The client binder died before onBinderUnlinked clean up the GetValueClient.
+    setBinderAlive(false);
+
+    status = getClient()->getValues(getCallbackClient(), requests);
+
+    ASSERT_FALSE(status.isOk()) << "getValues must fail if client died";
+    ASSERT_EQ(status.getExceptionCode(), EX_TRANSACTION_FAILED);
+    // The client count should still be 1 but onBinderUnlinked will remove this later.
+    EXPECT_EQ(countClients(), static_cast<size_t>(1));
+}
+
 TEST_F(DefaultVehicleHalTest, testSetValuesSmall) {
     SetValueRequests requests;
     std::vector<SetValueResult> expectedResults;
@@ -1111,7 +1167,8 @@
             << "results mismatch, expect on change event for the updated value";
     ASSERT_FALSE(getCallback()->nextOnPropertyEventResults().has_value())
             << "more results than expected";
-    EXPECT_EQ(countClients(), static_cast<size_t>(1));
+    EXPECT_EQ(countClients(), static_cast<size_t>(2))
+            << "expect 2 clients, 1 subscribe client and 1 setvalue client";
 }
 
 TEST_F(DefaultVehicleHalTest, testSubscribeGlobalOnchangeUnrelatedEventIgnored) {
@@ -1581,12 +1638,28 @@
 
     onBinderDied(context);
 
+    // Sleep for 100ms between checks.
+    int64_t sleep = 100;
+    // Timeout: 10s.
+    int64_t timeout = 10'000'000'000;
+    int64_t stopTime = elapsedRealtimeNano() + timeout;
+    // Wait until the onBinderDied event is handled.
+    while (countClients() != 0u && elapsedRealtimeNano() <= stopTime) {
+        std::this_thread::sleep_for(std::chrono::milliseconds(sleep));
+    }
+
     ASSERT_EQ(countClients(), static_cast<size_t>(0))
             << "expect all clients to be removed when binder died";
     ASSERT_TRUE(hasNoSubscriptions()) << "expect no subscriptions when binder died";
 
     onBinderUnlinked(context);
 
+    stopTime = elapsedRealtimeNano() + timeout;
+    // Wait until the onBinderUnlinked event is handled.
+    while (countOnBinderDiedContexts() != 0u && elapsedRealtimeNano() <= stopTime) {
+        std::this_thread::sleep_for(std::chrono::milliseconds(sleep));
+    }
+
     ASSERT_EQ(countOnBinderDiedContexts(), static_cast<size_t>(0))
             << "expect OnBinderDied context to be deleted when binder is unlinked";
 }
diff --git a/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.cpp b/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.cpp
index 866776e..4b4713d 100644
--- a/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.cpp
+++ b/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.cpp
@@ -39,9 +39,7 @@
 ndk::ScopedAStatus A2dpOffloadAudioProvider::startSession(
     const std::shared_ptr<IBluetoothAudioPort>& host_if,
     const AudioConfiguration& audio_config,
-    const std::vector<LatencyMode>& latency_modes,
-    DataMQDesc* _aidl_return) {
-  latency_modes_ = latency_modes;
+    const std::vector<LatencyMode>& latency_modes, DataMQDesc* _aidl_return) {
   if (audio_config.getTag() != AudioConfiguration::a2dpConfig) {
     LOG(WARNING) << __func__ << " - Invalid Audio Configuration="
                  << audio_config.toString();
@@ -62,8 +60,8 @@
 ndk::ScopedAStatus A2dpOffloadAudioProvider::onSessionReady(
     DataMQDesc* _aidl_return) {
   *_aidl_return = DataMQDesc();
-  BluetoothAudioSessionReport::OnSessionStarted(session_type_, stack_iface_,
-                                                nullptr, *audio_config_);
+  BluetoothAudioSessionReport::OnSessionStarted(
+      session_type_, stack_iface_, nullptr, *audio_config_, latency_modes_);
   return ndk::ScopedAStatus::ok();
 }
 
@@ -71,4 +69,4 @@
 }  // namespace bluetooth
 }  // namespace hardware
 }  // namespace android
-}  // namespace aidl
\ No newline at end of file
+}  // namespace aidl
diff --git a/bluetooth/audio/aidl/default/A2dpSoftwareAudioProvider.cpp b/bluetooth/audio/aidl/default/A2dpSoftwareAudioProvider.cpp
index d2f58f3..59df3a9 100644
--- a/bluetooth/audio/aidl/default/A2dpSoftwareAudioProvider.cpp
+++ b/bluetooth/audio/aidl/default/A2dpSoftwareAudioProvider.cpp
@@ -62,9 +62,7 @@
 ndk::ScopedAStatus A2dpSoftwareAudioProvider::startSession(
     const std::shared_ptr<IBluetoothAudioPort>& host_if,
     const AudioConfiguration& audio_config,
-    const std::vector<LatencyMode>& latency_modes,
-    DataMQDesc* _aidl_return) {
-  latency_modes_ = latency_modes;
+    const std::vector<LatencyMode>& latency_modes, DataMQDesc* _aidl_return) {
   if (audio_config.getTag() != AudioConfiguration::pcmConfig) {
     LOG(WARNING) << __func__ << " - Invalid Audio Configuration="
                  << audio_config.toString();
@@ -92,8 +90,8 @@
   }
   *_aidl_return = data_mq_->dupeDesc();
   auto desc = data_mq_->dupeDesc();
-  BluetoothAudioSessionReport::OnSessionStarted(session_type_, stack_iface_,
-                                                &desc, *audio_config_);
+  BluetoothAudioSessionReport::OnSessionStarted(
+      session_type_, stack_iface_, &desc, *audio_config_, latency_modes_);
   return ndk::ScopedAStatus::ok();
 }
 
@@ -101,4 +99,4 @@
 }  // namespace bluetooth
 }  // namespace hardware
 }  // namespace android
-}  // namespace aidl
\ No newline at end of file
+}  // namespace aidl
diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProvider.h b/bluetooth/audio/aidl/default/BluetoothAudioProvider.h
index 75794e8..a9f830a 100644
--- a/bluetooth/audio/aidl/default/BluetoothAudioProvider.h
+++ b/bluetooth/audio/aidl/default/BluetoothAudioProvider.h
@@ -68,4 +68,4 @@
 }  // namespace bluetooth
 }  // namespace hardware
 }  // namespace android
-}  // namespace aidl
\ No newline at end of file
+}  // namespace aidl
diff --git a/bluetooth/audio/aidl/default/HearingAidAudioProvider.cpp b/bluetooth/audio/aidl/default/HearingAidAudioProvider.cpp
index c754849..e8b01ac 100644
--- a/bluetooth/audio/aidl/default/HearingAidAudioProvider.cpp
+++ b/bluetooth/audio/aidl/default/HearingAidAudioProvider.cpp
@@ -57,9 +57,7 @@
 ndk::ScopedAStatus HearingAidAudioProvider::startSession(
     const std::shared_ptr<IBluetoothAudioPort>& host_if,
     const AudioConfiguration& audio_config,
-    const std::vector<LatencyMode>& latency_modes,
-    DataMQDesc* _aidl_return) {
-  latency_modes_ = latency_modes;
+    const std::vector<LatencyMode>& latency_modes, DataMQDesc* _aidl_return) {
   if (audio_config.getTag() != AudioConfiguration::pcmConfig) {
     LOG(WARNING) << __func__ << " - Invalid Audio Configuration="
                  << audio_config.toString();
@@ -86,8 +84,8 @@
   }
   *_aidl_return = data_mq_->dupeDesc();
   auto desc = data_mq_->dupeDesc();
-  BluetoothAudioSessionReport::OnSessionStarted(session_type_, stack_iface_,
-                                                &desc, *audio_config_);
+  BluetoothAudioSessionReport::OnSessionStarted(
+      session_type_, stack_iface_, &desc, *audio_config_, latency_modes_);
   return ndk::ScopedAStatus::ok();
 }
 
@@ -95,4 +93,4 @@
 }  // namespace bluetooth
 }  // namespace hardware
 }  // namespace android
-}  // namespace aidl
\ No newline at end of file
+}  // namespace aidl
diff --git a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp
index 1a3c658..0e22e44 100644
--- a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp
+++ b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp
@@ -54,9 +54,7 @@
 ndk::ScopedAStatus LeAudioOffloadAudioProvider::startSession(
     const std::shared_ptr<IBluetoothAudioPort>& host_if,
     const AudioConfiguration& audio_config,
-    const std::vector<LatencyMode>& latency_modes,
-    DataMQDesc* _aidl_return) {
-  latency_modes_ = latency_modes;
+    const std::vector<LatencyMode>& latency_modes, DataMQDesc* _aidl_return) {
   if (audio_config.getTag() != AudioConfiguration::leAudioConfig) {
     LOG(WARNING) << __func__ << " - Invalid Audio Configuration="
                  << audio_config.toString();
@@ -79,8 +77,8 @@
 
 ndk::ScopedAStatus LeAudioOffloadAudioProvider::onSessionReady(
     DataMQDesc* _aidl_return) {
-  BluetoothAudioSessionReport::OnSessionStarted(session_type_, stack_iface_,
-                                                nullptr, *audio_config_);
+  BluetoothAudioSessionReport::OnSessionStarted(
+      session_type_, stack_iface_, nullptr, *audio_config_, latency_modes_);
   *_aidl_return = DataMQDesc();
   return ndk::ScopedAStatus::ok();
 }
@@ -89,4 +87,4 @@
 }  // namespace bluetooth
 }  // namespace hardware
 }  // namespace android
-}  // namespace aidl
\ No newline at end of file
+}  // namespace aidl
diff --git a/bluetooth/audio/aidl/default/LeAudioSoftwareAudioProvider.cpp b/bluetooth/audio/aidl/default/LeAudioSoftwareAudioProvider.cpp
index 1f64b43..911c928 100644
--- a/bluetooth/audio/aidl/default/LeAudioSoftwareAudioProvider.cpp
+++ b/bluetooth/audio/aidl/default/LeAudioSoftwareAudioProvider.cpp
@@ -70,9 +70,7 @@
 ndk::ScopedAStatus LeAudioSoftwareAudioProvider::startSession(
     const std::shared_ptr<IBluetoothAudioPort>& host_if,
     const AudioConfiguration& audio_config,
-    const std::vector<LatencyMode>& latency_modes,
-    DataMQDesc* _aidl_return) {
-  latency_modes_ = latency_modes;
+    const std::vector<LatencyMode>& latency_modes, DataMQDesc* _aidl_return) {
   if (audio_config.getTag() != AudioConfiguration::pcmConfig) {
     LOG(WARNING) << __func__ << " - Invalid Audio Configuration="
                  << audio_config.toString();
@@ -134,8 +132,8 @@
   }
   *_aidl_return = data_mq_->dupeDesc();
   auto desc = data_mq_->dupeDesc();
-  BluetoothAudioSessionReport::OnSessionStarted(session_type_, stack_iface_,
-                                                &desc, *audio_config_);
+  BluetoothAudioSessionReport::OnSessionStarted(
+      session_type_, stack_iface_, &desc, *audio_config_, latency_modes_);
   return ndk::ScopedAStatus::ok();
 }
 
@@ -143,4 +141,4 @@
 }  // namespace bluetooth
 }  // namespace hardware
 }  // namespace android
-}  // namespace aidl
\ No newline at end of file
+}  // namespace aidl
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
index e700e7e..37ac967 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
@@ -46,7 +46,8 @@
 
 void BluetoothAudioSession::OnSessionStarted(
     const std::shared_ptr<IBluetoothAudioPort> stack_iface,
-    const DataMQDesc* mq_desc, const AudioConfiguration& audio_config) {
+    const DataMQDesc* mq_desc, const AudioConfiguration& audio_config,
+    const std::vector<LatencyMode>& latency_modes) {
   std::lock_guard<std::recursive_mutex> guard(mutex_);
   if (stack_iface == nullptr) {
     LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_)
@@ -61,6 +62,7 @@
     audio_config_ = nullptr;
   } else {
     stack_iface_ = stack_iface;
+    latency_modes_ = latency_modes;
     LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
               << ", AudioConfiguration=" << audio_config.toString();
     ReportSessionStatus();
@@ -191,14 +193,14 @@
  *
  ***/
 
-bool BluetoothAudioSession::StartStream() {
+bool BluetoothAudioSession::StartStream(bool is_low_latency) {
   std::lock_guard<std::recursive_mutex> guard(mutex_);
   if (!IsSessionReady()) {
     LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
                << " has NO session";
     return false;
   }
-  auto hal_retval = stack_iface_->startStream(false);
+  auto hal_retval = stack_iface_->startStream(is_low_latency);
   if (!hal_retval.isOk()) {
     LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
                  << toString(session_type_) << " failed";
@@ -418,6 +420,7 @@
 
 void BluetoothAudioSession::ReportLowLatencyModeAllowedChanged(bool allowed) {
   std::lock_guard<std::recursive_mutex> guard(mutex_);
+  low_latency_allowed_ = allowed;
   if (observers_.empty()) {
     LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
                  << " has NO port state observer";
@@ -530,7 +533,25 @@
   }
 }
 
-void BluetoothAudioSession::SetLatencyMode(LatencyMode latency_mode) {
+std::vector<LatencyMode> BluetoothAudioSession::GetSupportedLatencyModes() {
+  std::lock_guard<std::recursive_mutex> guard(mutex_);
+  if (!IsSessionReady()) {
+    LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
+               << " has NO session";
+    return std::vector<LatencyMode>();
+  }
+  if (low_latency_allowed_) return latency_modes_;
+  std::vector<LatencyMode> modes;
+  for (LatencyMode mode : latency_modes_) {
+    if (mode == LatencyMode::LOW_LATENCY)
+      // ignore those low latency mode if Bluetooth stack doesn't allow
+      continue;
+    modes.push_back(mode);
+  }
+  return modes;
+}
+
+void BluetoothAudioSession::SetLatencyMode(const LatencyMode& latency_mode) {
   std::lock_guard<std::recursive_mutex> guard(mutex_);
   if (!IsSessionReady()) {
     LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.h b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.h
index 6e390cc..5bf17bd 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.h
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.h
@@ -27,6 +27,7 @@
 
 #include <mutex>
 #include <unordered_map>
+#include <vector>
 
 namespace aidl {
 namespace android {
@@ -120,7 +121,8 @@
    ***/
   void OnSessionStarted(const std::shared_ptr<IBluetoothAudioPort> stack_iface,
                         const DataMQDesc* mq_desc,
-                        const AudioConfiguration& audio_config);
+                        const AudioConfiguration& audio_config,
+                        const std::vector<LatencyMode>& latency_modes);
 
   /***
    * The report function is used to report that the Bluetooth stack has ended
@@ -175,13 +177,15 @@
    * Those control functions are for the bluetooth_audio module to start,
    * suspend, stop stream, to check position, and to update metadata.
    ***/
-  bool StartStream();
+  bool StartStream(bool low_latency);
   bool SuspendStream();
   void StopStream();
   bool GetPresentationPosition(PresentationPosition& presentation_position);
   void UpdateSourceMetadata(const struct source_metadata& source_metadata);
   void UpdateSinkMetadata(const struct sink_metadata& sink_metadata);
-  void SetLatencyMode(LatencyMode latency_mode);
+
+  std::vector<LatencyMode> GetSupportedLatencyModes();
+  void SetLatencyMode(const LatencyMode& latency_mode);
 
   // The control function writes stream to FMQ
   size_t OutWritePcmData(const void* buffer, size_t bytes);
@@ -202,6 +206,8 @@
   std::unique_ptr<DataMQ> data_mq_;
   // audio data configuration for both software and offloading
   std::unique_ptr<AudioConfiguration> audio_config_;
+  std::vector<LatencyMode> latency_modes_;
+  bool low_latency_allowed_ = true;
 
   // saving those registered bluetooth_audio's callbacks
   std::unordered_map<uint16_t, std::shared_ptr<struct PortStatusCallbacks>>
@@ -234,4 +240,4 @@
 }  // namespace bluetooth
 }  // namespace hardware
 }  // namespace android
-}  // namespace aidl
\ No newline at end of file
+}  // namespace aidl
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionControl.h b/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionControl.h
index 451a31f..5b838b0 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionControl.h
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionControl.h
@@ -98,11 +98,12 @@
   stop
    * stream, to check position, and to update metadata.
   ***/
-  static bool StartStream(const SessionType& session_type) {
+  static bool StartStream(const SessionType& session_type,
+                          bool low_latency = false) {
     std::shared_ptr<BluetoothAudioSession> session_ptr =
         BluetoothAudioSessionInstance::GetSessionInstance(session_type);
     if (session_ptr != nullptr) {
-      return session_ptr->StartStream();
+      return session_ptr->StartStream(low_latency);
     }
     return false;
   }
@@ -154,6 +155,25 @@
     }
   }
 
+  static std::vector<LatencyMode> GetSupportedLatencyModes(
+      const SessionType& session_type) {
+    std::shared_ptr<BluetoothAudioSession> session_ptr =
+        BluetoothAudioSessionInstance::GetSessionInstance(session_type);
+    if (session_ptr != nullptr) {
+      return session_ptr->GetSupportedLatencyModes();
+    }
+    return std::vector<LatencyMode>();
+  }
+
+  static void SetLatencyMode(const SessionType& session_type,
+                             const LatencyMode& latency_mode) {
+    std::shared_ptr<BluetoothAudioSession> session_ptr =
+        BluetoothAudioSessionInstance::GetSessionInstance(session_type);
+    if (session_ptr != nullptr) {
+      session_ptr->SetLatencyMode(latency_mode);
+    }
+  }
+
   /***
    * The control API writes stream to FMQ
    ***/
@@ -185,4 +205,4 @@
 }  // namespace bluetooth
 }  // namespace hardware
 }  // namespace android
-}  // namespace aidl
\ No newline at end of file
+}  // namespace aidl
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionReport.h b/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionReport.h
index 03776b5..0350259 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionReport.h
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionReport.h
@@ -33,11 +33,13 @@
   static void OnSessionStarted(
       const SessionType& session_type,
       const std::shared_ptr<IBluetoothAudioPort> host_iface,
-      const DataMQDesc* data_mq, const AudioConfiguration& audio_config) {
+      const DataMQDesc* data_mq, const AudioConfiguration& audio_config,
+      const std::vector<LatencyMode>& latency_modes) {
     std::shared_ptr<BluetoothAudioSession> session_ptr =
         BluetoothAudioSessionInstance::GetSessionInstance(session_type);
     if (session_ptr != nullptr) {
-      session_ptr->OnSessionStarted(host_iface, data_mq, audio_config);
+      session_ptr->OnSessionStarted(host_iface, data_mq, audio_config,
+                                    latency_modes);
     }
   }
 
@@ -96,4 +98,4 @@
 }  // namespace bluetooth
 }  // namespace hardware
 }  // namespace android
-}  // namespace aidl
\ No newline at end of file
+}  // namespace aidl
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/AutomotiveLensFacing.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/AutomotiveLensFacing.aidl
new file mode 100644
index 0000000..14ad26e
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/AutomotiveLensFacing.aidl
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.camera.metadata;
+@Backing(type="int") @VintfStability
+enum AutomotiveLensFacing {
+  ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_OTHER = 0,
+  ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_FRONT = 1,
+  ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_REAR = 2,
+  ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_LEFT = 3,
+  ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_RIGHT = 4,
+  ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_OTHER = 5,
+  ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_1_LEFT = 6,
+  ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_1_CENTER = 7,
+  ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_1_RIGHT = 8,
+  ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_2_LEFT = 9,
+  ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_2_CENTER = 10,
+  ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_2_RIGHT = 11,
+  ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_3_LEFT = 12,
+  ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_3_CENTER = 13,
+  ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_3_RIGHT = 14,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/AutomotiveLocation.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/AutomotiveLocation.aidl
new file mode 100644
index 0000000..5417bdb
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/AutomotiveLocation.aidl
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.camera.metadata;
+@Backing(type="int") @VintfStability
+enum AutomotiveLocation {
+  ANDROID_AUTOMOTIVE_LOCATION_INTERIOR = 0,
+  ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_OTHER = 1,
+  ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_FRONT = 2,
+  ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_REAR = 3,
+  ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_LEFT = 4,
+  ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_RIGHT = 5,
+  ANDROID_AUTOMOTIVE_LOCATION_EXTRA_OTHER = 6,
+  ANDROID_AUTOMOTIVE_LOCATION_EXTRA_FRONT = 7,
+  ANDROID_AUTOMOTIVE_LOCATION_EXTRA_REAR = 8,
+  ANDROID_AUTOMOTIVE_LOCATION_EXTRA_LEFT = 9,
+  ANDROID_AUTOMOTIVE_LOCATION_EXTRA_RIGHT = 10,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataSection.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataSection.aidl
index dc33836..8bed156 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataSection.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataSection.aidl
@@ -68,5 +68,7 @@
   ANDROID_DISTORTION_CORRECTION = 27,
   ANDROID_HEIC = 28,
   ANDROID_HEIC_INFO = 29,
+  ANDROID_AUTOMOTIVE = 30,
+  ANDROID_AUTOMOTIVE_LENS = 31,
   VENDOR_SECTION = 32768,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataSectionStart.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataSectionStart.aidl
index 3a790b3..1725347 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataSectionStart.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataSectionStart.aidl
@@ -68,5 +68,7 @@
   ANDROID_DISTORTION_CORRECTION_START = 1769472,
   ANDROID_HEIC_START = 1835008,
   ANDROID_HEIC_INFO_START = 1900544,
+  ANDROID_AUTOMOTIVE_START = 1966080,
+  ANDROID_AUTOMOTIVE_LENS_START = 2031616,
   VENDOR_SECTION_START = -2147483648,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataTag.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataTag.aidl
index 432c9fd..13c7924 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataTag.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataTag.aidl
@@ -325,4 +325,6 @@
   ANDROID_HEIC_AVAILABLE_HEIC_STALL_DURATIONS_MAXIMUM_RESOLUTION = 1835013,
   ANDROID_HEIC_INFO_SUPPORTED = 1900544,
   ANDROID_HEIC_INFO_MAX_JPEG_APP_SEGMENTS_COUNT = 1900545,
+  ANDROID_AUTOMOTIVE_LOCATION = 1966080,
+  ANDROID_AUTOMOTIVE_LENS_FACING = 2031616,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LensPoseReference.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LensPoseReference.aidl
index 275d77b..b2d837a 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LensPoseReference.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LensPoseReference.aidl
@@ -41,4 +41,5 @@
   ANDROID_LENS_POSE_REFERENCE_PRIMARY_CAMERA = 0,
   ANDROID_LENS_POSE_REFERENCE_GYROSCOPE = 1,
   ANDROID_LENS_POSE_REFERENCE_UNDEFINED = 2,
+  ANDROID_LENS_POSE_REFERENCE_AUTOMOTIVE = 3,
 }
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/AutomotiveLensFacing.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/AutomotiveLensFacing.aidl
new file mode 100644
index 0000000..704da86
--- /dev/null
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/AutomotiveLensFacing.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+
+package android.hardware.camera.metadata;
+
+/** android.automotive.lens.facing enumeration values
+ * @see ANDROID_AUTOMOTIVE_LENS_FACING
+ */
+@VintfStability
+@Backing(type="int")
+enum AutomotiveLensFacing {
+    ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_OTHER,
+    ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_FRONT,
+    ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_REAR,
+    ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_LEFT,
+    ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_RIGHT,
+    ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_OTHER,
+    ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_1_LEFT,
+    ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_1_CENTER,
+    ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_1_RIGHT,
+    ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_2_LEFT,
+    ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_2_CENTER,
+    ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_2_RIGHT,
+    ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_3_LEFT,
+    ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_3_CENTER,
+    ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_3_RIGHT,
+}
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/AutomotiveLocation.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/AutomotiveLocation.aidl
new file mode 100644
index 0000000..c55563d
--- /dev/null
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/AutomotiveLocation.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+
+package android.hardware.camera.metadata;
+
+/** android.automotive.location enumeration values
+ * @see ANDROID_AUTOMOTIVE_LOCATION
+ */
+@VintfStability
+@Backing(type="int")
+enum AutomotiveLocation {
+    ANDROID_AUTOMOTIVE_LOCATION_INTERIOR,
+    ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_OTHER,
+    ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_FRONT,
+    ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_REAR,
+    ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_LEFT,
+    ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_RIGHT,
+    ANDROID_AUTOMOTIVE_LOCATION_EXTRA_OTHER,
+    ANDROID_AUTOMOTIVE_LOCATION_EXTRA_FRONT,
+    ANDROID_AUTOMOTIVE_LOCATION_EXTRA_REAR,
+    ANDROID_AUTOMOTIVE_LOCATION_EXTRA_LEFT,
+    ANDROID_AUTOMOTIVE_LOCATION_EXTRA_RIGHT,
+}
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataSection.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataSection.aidl
index cc3d3b3..99e28b9 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataSection.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataSection.aidl
@@ -59,5 +59,7 @@
     ANDROID_DISTORTION_CORRECTION,
     ANDROID_HEIC,
     ANDROID_HEIC_INFO,
+    ANDROID_AUTOMOTIVE,
+    ANDROID_AUTOMOTIVE_LENS,
     VENDOR_SECTION = 0x8000,
 }
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataSectionStart.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataSectionStart.aidl
index 93d6f13..62c71e9 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataSectionStart.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataSectionStart.aidl
@@ -61,5 +61,7 @@
     ANDROID_DISTORTION_CORRECTION_START = CameraMetadataSection.ANDROID_DISTORTION_CORRECTION << 16,
     ANDROID_HEIC_START = CameraMetadataSection.ANDROID_HEIC << 16,
     ANDROID_HEIC_INFO_START = CameraMetadataSection.ANDROID_HEIC_INFO << 16,
+    ANDROID_AUTOMOTIVE_START = CameraMetadataSection.ANDROID_AUTOMOTIVE << 16,
+    ANDROID_AUTOMOTIVE_LENS_START = CameraMetadataSection.ANDROID_AUTOMOTIVE_LENS << 16,
     VENDOR_SECTION_START = CameraMetadataSection.VENDOR_SECTION << 16,
 }
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataTag.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataTag.aidl
index f20a06e..fe91dcf 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataTag.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataTag.aidl
@@ -2232,4 +2232,15 @@
      * <p>The maximum number of Jpeg APP segments supported by the camera HAL device.</p>
      */
     ANDROID_HEIC_INFO_MAX_JPEG_APP_SEGMENTS_COUNT,
+    /** android.automotive.location [static, enum, public]
+     *
+     * <p>Location of the cameras on the automotive devices.</p>
+     */
+    ANDROID_AUTOMOTIVE_LOCATION = CameraMetadataSectionStart.ANDROID_AUTOMOTIVE_START,
+    /** android.automotive.lens.facing [static, enum[], public]
+     *
+     * <p>The direction of the camera faces relative to the vehicle body frame and the
+     * passenger seats.</p>
+     */
+    ANDROID_AUTOMOTIVE_LENS_FACING = CameraMetadataSectionStart.ANDROID_AUTOMOTIVE_LENS_START,
 }
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/LensPoseReference.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/LensPoseReference.aidl
index ca18676..3e6034b 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/LensPoseReference.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/LensPoseReference.aidl
@@ -32,4 +32,5 @@
     ANDROID_LENS_POSE_REFERENCE_PRIMARY_CAMERA,
     ANDROID_LENS_POSE_REFERENCE_GYROSCOPE,
     ANDROID_LENS_POSE_REFERENCE_UNDEFINED,
+    ANDROID_LENS_POSE_REFERENCE_AUTOMOTIVE,
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl
index 769f803..bbc9c46 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl
@@ -798,7 +798,7 @@
      * idle period.
      *
      * This function should only be called if the display reports support for
-     * DisplayCapability.DISPLAY_IDLE from getDisplayCapabilities.
+     * DisplayCapability.DISPLAY_IDLE_TIMER from getDisplayCapabilities.
      *
      * @param display is the display to which the idle timer is set.
      * @param timeoutMs is the minimum requirements of idle period in milliseconds. Panel
diff --git a/radio/aidl/android/hardware/radio/data/IRadioData.aidl b/radio/aidl/android/hardware/radio/data/IRadioData.aidl
index 724b515..0171d39 100644
--- a/radio/aidl/android/hardware/radio/data/IRadioData.aidl
+++ b/radio/aidl/android/hardware/radio/data/IRadioData.aidl
@@ -65,7 +65,7 @@
     /**
      * Deactivate packet data connection and remove from the data call list. An
      * unsolDataCallListChanged() must be sent when data connection is deactivated.
-     * A return value of RadioError::RADIO_NOT_AVAILABLE will remove the network from the list.
+     * Any return value other than RadioError::NONE will remove the network from the list.
      *
      * @param serial Serial number of request.
      * @param cid Data call id.
diff --git a/radio/aidl/android/hardware/radio/data/IRadioDataResponse.aidl b/radio/aidl/android/hardware/radio/data/IRadioDataResponse.aidl
index 1cb8ff3..88b6c1b 100644
--- a/radio/aidl/android/hardware/radio/data/IRadioDataResponse.aidl
+++ b/radio/aidl/android/hardware/radio/data/IRadioDataResponse.aidl
@@ -67,8 +67,8 @@
      *
      * Valid errors returned:
      *   RadioError:REQUEST_NOT_SUPPORTED may be returned when HAL 1.2 or higher is supported.
-     *   RadioError:NONE
-     *   RadioError:RADIO_NOT_AVAILABLE will remove the network from the list.
+     *   RadioError:NONE indicates success. Any other error will remove the network from the list.
+     *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:INVALID_CALL_ID
      *   RadioError:INVALID_STATE
      *   RadioError:INVALID_ARGUMENTS
diff --git a/security/keymint/aidl/vts/functional/SecureElementProvisioningTest.cpp b/security/keymint/aidl/vts/functional/SecureElementProvisioningTest.cpp
index 83ee188..6f13867 100644
--- a/security/keymint/aidl/vts/functional/SecureElementProvisioningTest.cpp
+++ b/security/keymint/aidl/vts/functional/SecureElementProvisioningTest.cpp
@@ -63,6 +63,9 @@
 map<SecurityLevel, shared_ptr<IKeyMintDevice>> SecureElementProvisioningTest::keymints_;
 
 TEST_F(SecureElementProvisioningTest, ValidConfigurations) {
+    if (keymints_.empty()) {
+        GTEST_SKIP() << "Test not applicable to device with no KeyMint devices";
+    }
     // TEE is required
     ASSERT_EQ(keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT), 1);
     // StrongBox is optional
@@ -70,6 +73,9 @@
 }
 
 TEST_F(SecureElementProvisioningTest, TeeOnly) {
+    if (keymints_.empty()) {
+        GTEST_SKIP() << "Test not applicable to device with no KeyMint devices";
+    }
     ASSERT_EQ(keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT), 1);
     auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second;
     ASSERT_NE(tee, nullptr);
@@ -105,6 +111,9 @@
 }
 
 TEST_F(SecureElementProvisioningTest, TeeDoesNotImplementStrongBoxMethods) {
+    if (keymints_.empty()) {
+        GTEST_SKIP() << "Test not applicable to device with no KeyMint devices";
+    }
     ASSERT_EQ(keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT), 1);
     auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second;
     ASSERT_NE(tee, nullptr);
@@ -122,7 +131,10 @@
 }
 
 TEST_F(SecureElementProvisioningTest, StrongBoxDoesNotImplementTeeMethods) {
-    if (keymints_.count(SecurityLevel::STRONGBOX) == 0) return;
+    if (keymints_.count(SecurityLevel::STRONGBOX) == 0) {
+        // Need a StrongBox to provision.
+        GTEST_SKIP() << "Test not applicable to device with no StrongBox KeyMint device";
+    }
 
     auto sb = keymints_.find(SecurityLevel::STRONGBOX)->second;
     ASSERT_NE(sb, nullptr);
@@ -135,7 +147,10 @@
 }
 
 TEST_F(SecureElementProvisioningTest, UnimplementedTest) {
-    if (keymints_.count(SecurityLevel::STRONGBOX) == 0) return;  // Need a StrongBox to provision.
+    if (keymints_.count(SecurityLevel::STRONGBOX) == 0) {
+        // Need a StrongBox to provision.
+        GTEST_SKIP() << "Test not applicable to device with no StrongBox KeyMint device";
+    }
 
     ASSERT_EQ(keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT), 1);
     auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second;
@@ -166,7 +181,10 @@
 }
 
 TEST_F(SecureElementProvisioningTest, ChallengeQualityTest) {
-    if (keymints_.count(SecurityLevel::STRONGBOX) == 0) return;  // Need a StrongBox to provision.
+    if (keymints_.count(SecurityLevel::STRONGBOX) == 0) {
+        // Need a StrongBox to provision.
+        GTEST_SKIP() << "Test not applicable to device with no StrongBox KeyMint device";
+    }
 
     ASSERT_EQ(keymints_.count(SecurityLevel::STRONGBOX), 1);
     auto sb = keymints_.find(SecurityLevel::STRONGBOX)->second;
@@ -186,7 +204,10 @@
 }
 
 TEST_F(SecureElementProvisioningTest, ProvisioningTest) {
-    if (keymints_.count(SecurityLevel::STRONGBOX) == 0) return;  // Need a StrongBox to provision.
+    if (keymints_.count(SecurityLevel::STRONGBOX) == 0) {
+        // Need a StrongBox to provision.
+        GTEST_SKIP() << "Test not applicable to device with no StrongBox KeyMint device";
+    }
 
     ASSERT_EQ(keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT), 1);
     auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second;
@@ -215,7 +236,10 @@
 }
 
 TEST_F(SecureElementProvisioningTest, InvalidProvisioningTest) {
-    if (keymints_.count(SecurityLevel::STRONGBOX) == 0) return;  // Need a StrongBox to provision.
+    if (keymints_.count(SecurityLevel::STRONGBOX) == 0) {
+        // Need a StrongBox to provision.
+        GTEST_SKIP() << "Test not applicable to device with no StrongBox KeyMint device";
+    }
 
     ASSERT_EQ(keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT), 1);
     auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second;
diff --git a/wifi/netlinkinterceptor/vts/functional/Android.bp b/wifi/netlinkinterceptor/vts/functional/Android.bp
index 33284e8..80608a7 100644
--- a/wifi/netlinkinterceptor/vts/functional/Android.bp
+++ b/wifi/netlinkinterceptor/vts/functional/Android.bp
@@ -34,13 +34,13 @@
         "interceptor_aidl_test.cpp",
     ],
     shared_libs: [
-        "android.hardware.net.nlinterceptor-V1-ndk",
         "libbase",
         "libbinder_ndk",
     ],
     static_libs: [
-        "libgmock",
+        "android.hardware.net.nlinterceptor-V1-ndk",
         "android.hardware.automotive.can@libnetdevice",
+        "libgmock",
         "libnl++",
     ],
     test_suites: [