Merge "Return display capability if getDisplayBrightnessSupport is not registered." into qt-dev
diff --git a/broadcastradio/common/tests/Android.bp b/broadcastradio/common/tests/Android.bp
index ef8733c..0ace941 100644
--- a/broadcastradio/common/tests/Android.bp
+++ b/broadcastradio/common/tests/Android.bp
@@ -58,6 +58,7 @@
         "android.hardware.broadcastradio@common-utils-2x-lib",
     ],
     shared_libs: [
+        "libhidlbase",
         "android.hardware.broadcastradio@2.0",
     ],
     test_suites: ["general-tests"],
diff --git a/compatibility_matrices/compatibility_matrix.4.xml b/compatibility_matrices/compatibility_matrix.4.xml
index 6c28761..7d6fc60 100644
--- a/compatibility_matrices/compatibility_matrix.4.xml
+++ b/compatibility_matrices/compatibility_matrix.4.xml
@@ -181,7 +181,12 @@
     </hal>
     <hal format="hidl" optional="true">
         <name>android.hardware.gnss</name>
-        <version>1.0-1</version>
+        <!--
+         - Both versions are listed here as a workaround for libvintf since 2.0 extends 1.1.
+         - Devices launched with Q must support gnss@2.0, see VtsTrebleVendorVintfTest
+         - test DeviceManifestTest#GnssHalVersionCompatibility.
+        -->
+        <version>1.1</version>
         <version>2.0</version>
         <interface>
             <name>IGnss</name>
diff --git a/current.txt b/current.txt
index 9fdab8d..078a9df 100644
--- a/current.txt
+++ b/current.txt
@@ -402,7 +402,7 @@
 b7ecf29927055ec422ec44bf776223f07d79ad9f92ccf9becf167e62c2607e7a android.hardware.keymaster@4.0::IKeymasterDevice
 574e8f1499436fb4075894dcae0b36682427956ecb114f17f1fe22d116a83c6b android.hardware.neuralnetworks@1.0::IPreparedModel
 e75759b40a1c5f97b463b30aab91954012c9ea9e454dde308db853a56796e5a6 android.hardware.neuralnetworks@1.0::types
-d51937a3567a50f239589e40300264c4b57f2c3582c6fc6df082f45eb74d90e3 android.hardware.neuralnetworks@1.1::types
+eb754b58c93e5591613208b4c972811288b0fa16a82430d602f107c91a908b22 android.hardware.neuralnetworks@1.1::types
 1d4a5776614c08b5d794a5ec5ab04697260cbd4b3441d5935cd53ee71d19da02 android.hardware.radio@1.0::IRadioResponse
 ed9da80ec0c96991fd03f0a46107815d0e50f764656e49dba4980fa5c31d5bc3 android.hardware.radio@1.0::types
 1d19720d4fd38b1095f0f555a4bd92b3b12c9b1d0f560b0e9a474cd6dcc20db6 android.hardware.radio@1.2::IRadio
@@ -459,9 +459,9 @@
 5b1f4a4fb88c239e07d76026467a1f2ee0d08f4d52c1805bd93bd7c05e3fe69c android.hardware.drm@1.2::ICryptoFactory
 4895f98e9ef210e9acb01982f5d07b654538377e1404b8db5e19e7858835e9d8 android.hardware.drm@1.2::ICryptoPlugin
 976116b9033b2c222b940109fdf0ffcc29b77cbe631ef6b4fcc2ad5ce8e605f7 android.hardware.drm@1.2::IDrmFactory
-b2efccc6425085f84795a2ca15a09d9a81ffd02f9dc3d30ba21d1a59bdfa253f android.hardware.drm@1.2::IDrmPlugin
-39ca9e88404b6c090f7650455a7ed3fdee9cce4e3a356c9d547f8ff02f2e7fc8 android.hardware.drm@1.2::IDrmPluginListener
-f27baaa587bc3dd9b740cb6928ab812b9b7d105b5187663938aee578105f3c39 android.hardware.drm@1.2::types
+8ef1caf921c3e83a00180f770e3b8e8ff65d8a5c806482e51aa45e6d55f1aec1 android.hardware.drm@1.2::IDrmPlugin
+b778fcce93eb6294446a940e1bae0200da7bd97b91b91977be2dcd31ca58374f android.hardware.drm@1.2::IDrmPluginListener
+564732cbfe5c0895cfbd2bdf84c3f2b0f760ea20f2237c0d388aaeeaef2dd0a9 android.hardware.drm@1.2::types
 44480c912e4ab90b9ed17e56569cd5ca98413a8a2372efb028f4181204b6b73e android.hardware.fastboot@1.0::IFastboot
 7b2989744e3c555292d4b5b829acd09a7b40f96ead62ce54174cd959503b64bb android.hardware.fastboot@1.0::types
 7f460e795f5d1ed5e378935f98c6db4d39497de988aef1b4c2a4a07a6c400392 android.hardware.gnss@2.0::IAGnss
@@ -515,7 +515,7 @@
 92714960d1a53fc2ec557302b41c7cc93d2636d8364a44bd0f85be0c92927ff8 android.hardware.neuralnetworks@1.2::IExecutionCallback
 36e1064c869965dee533c537cefbe87e54db8bd8cd45be7e0e93e00e8a43863a android.hardware.neuralnetworks@1.2::IPreparedModel
 e1c734d1545e1a4ae749ff1dd9704a8e594c59aea7c8363159dc258e93e0df3b android.hardware.neuralnetworks@1.2::IPreparedModelCallback
-30f6da776bf909fc139f2bc4c176b5a74e9db0978240efcd7429d04e221bfaee android.hardware.neuralnetworks@1.2::types
+e3b6176e3bf235c4e0e4e451b0166e396c7ee176cfe167c9147c3d46d7b34f0c android.hardware.neuralnetworks@1.2::types
 cf7a4ba516a638f9b82a249c91fb603042c2d9ca43fd5aad9cf6c0401ed2a5d7 android.hardware.nfc@1.2::INfc
 abf98c2ae08bf765db54edc8068e36d52eb558cff6706b6fd7c18c65a1f3fc18 android.hardware.nfc@1.2::types
 4cb252dc6372a874aef666b92a6e9529915aa187521a700f0789065c3c702ead android.hardware.power.stats@1.0::IPowerStats
diff --git a/drm/1.2/IDrmPlugin.hal b/drm/1.2/IDrmPlugin.hal
index 7d266f4..df09ccf 100644
--- a/drm/1.2/IDrmPlugin.hal
+++ b/drm/1.2/IDrmPlugin.hal
@@ -226,4 +226,22 @@
      * @param sessionId identifies the session the event originated from
      */
     sendSessionLostState(SessionId sessionId);
+
+    /**
+     * Send a keys change event to the listener. The keys change event
+     * indicates the status of each key in the session. Keys can be
+     * indicated as being usable, expired, outputnotallowed or statuspending.
+     *
+     * This method only differs from @1.0 version by the addition of new
+     * KeyStatusType(s) in keyStatusList.
+     *
+     * @param sessionId identifies the session the event originated from
+     * @param keyStatusList indicates the status for each key ID in the
+     * session.
+     * @param hasNewUsableKey indicates if the event includes at least one
+     * key that has become usable.
+     */
+    sendKeysChange_1_2(SessionId sessionId, vec<KeyStatus> keyStatusList,
+            bool hasNewUsableKey);
+
 };
diff --git a/drm/1.2/IDrmPluginListener.hal b/drm/1.2/IDrmPluginListener.hal
index a6bd6c9..e8cb91a 100644
--- a/drm/1.2/IDrmPluginListener.hal
+++ b/drm/1.2/IDrmPluginListener.hal
@@ -36,4 +36,22 @@
      * @param sessionId identifies the session that has been invalidated
      */
      oneway sendSessionLostState(SessionId sessionId);
+
+    /**
+     * Send a keys change event to the listener. The keys change event
+     * indicates the status of each key in the session. Keys can be
+     * indicated as being usable, expired, outputnotallowed or statuspending.
+     *
+     * This method only differs from @1.0 version by the addition of new
+     * KeyStatusType(s) in keyStatusList.
+     *
+     * @param sessionId identifies the session the event originated from
+     * @param keyStatusList indicates the status for each key ID in the
+     * session.
+     * @param hasNewUsableKey indicates if the event includes at least one
+     * key that has become usable.
+     */
+    oneway sendKeysChange_1_2(SessionId sessionId, vec<KeyStatus> keyStatusList,
+            bool hasNewUsableKey);
+
 };
diff --git a/drm/1.2/types.hal b/drm/1.2/types.hal
index 28c8e67..87218a4 100644
--- a/drm/1.2/types.hal
+++ b/drm/1.2/types.hal
@@ -16,6 +16,7 @@
 
 package android.hardware.drm@1.2;
 
+import @1.0::KeyStatusType;
 import @1.0::Status;
 import @1.1::HdcpLevel;
 
@@ -93,3 +94,25 @@
  * set in methods that take a KeySetId as an input parameter.
  */
 typedef vec<uint8_t> KeySetId;
+
+enum KeyStatusType : @1.0::KeyStatusType {
+    /**
+     * The key is not yet usable to decrypt media because the start
+     * time is in the future. The key must become usable when
+     * its start time is reached.
+     */
+    USABLEINFUTURE
+};
+
+/**
+ * Used by sendKeysChange_1_2 to report the usability status of each key to the
+ * app.
+ *
+ * This struct only differs from @1.0 version by the addition of new
+ * KeyStatusType(s).
+ *
+ */
+struct KeyStatus {
+    KeySetId keyId;
+    KeyStatusType type;
+};
diff --git a/drm/1.2/vts/functional/drm_hal_common.cpp b/drm/1.2/vts/functional/drm_hal_common.cpp
index b9a8425..bfffbe8 100644
--- a/drm/1.2/vts/functional/drm_hal_common.cpp
+++ b/drm/1.2/vts/functional/drm_hal_common.cpp
@@ -56,6 +56,7 @@
 namespace vts {
 
 const char *kCallbackLostState = "LostState";
+const char *kCallbackKeysChange = "KeysChange";
 
 drm_vts::VendorModules *DrmHalTest::gVendorModules = nullptr;
 
@@ -64,7 +65,19 @@
  */
 
 Return<void> DrmHalPluginListener::sendSessionLostState(const hidl_vec<uint8_t>& sessionId) {
-    NotifyFromCallback(kCallbackLostState, sessionId);
+    ListenerEventArgs args;
+    args.sessionId = sessionId;
+    NotifyFromCallback(kCallbackLostState, args);
+    return Void();
+}
+
+Return<void> DrmHalPluginListener::sendKeysChange_1_2(const hidl_vec<uint8_t>& sessionId,
+        const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
+    ListenerEventArgs args;
+    args.sessionId = sessionId;
+    args.keyStatusList = keyStatusList;
+    args.hasNewUsableKey = hasNewUsableKey;
+    NotifyFromCallback(kCallbackKeysChange, args);
     return Void();
 }
 
diff --git a/drm/1.2/vts/functional/drm_hal_common.h b/drm/1.2/vts/functional/drm_hal_common.h
index 1b95dde..e348664 100644
--- a/drm/1.2/vts/functional/drm_hal_common.h
+++ b/drm/1.2/vts/functional/drm_hal_common.h
@@ -37,7 +37,7 @@
 
 using ::android::hardware::drm::V1_0::EventType;
 using ::android::hardware::drm::V1_0::KeyedVector;
-using ::android::hardware::drm::V1_0::KeyStatus;
+using KeyStatusV1_0 = ::android::hardware::drm::V1_0::KeyStatus;
 using ::android::hardware::drm::V1_0::KeyType;
 using ::android::hardware::drm::V1_0::Mode;
 using ::android::hardware::drm::V1_0::Pattern;
@@ -46,10 +46,6 @@
 
 using ::android::hardware::drm::V1_1::ICryptoFactory;
 
-using ::android::hardware::drm::V1_2::ICryptoPlugin;
-using ::android::hardware::drm::V1_2::IDrmFactory;
-using ::android::hardware::drm::V1_2::IDrmPlugin;
-using ::android::hardware::drm::V1_2::IDrmPluginListener;
 using StatusV1_2 = ::android::hardware::drm::V1_2::Status;
 
 using ::android::hardware::hidl_array;
@@ -166,9 +162,16 @@
  *  Event Handling tests
  */
 extern const char *kCallbackLostState;
+extern const char *kCallbackKeysChange;
+
+struct ListenerEventArgs {
+    SessionId sessionId;
+    hidl_vec<KeyStatus> keyStatusList;
+    bool hasNewUsableKey;
+};
 
 class DrmHalPluginListener
-    : public ::testing::VtsHalHidlTargetCallbackBase<SessionId>,
+    : public ::testing::VtsHalHidlTargetCallbackBase<ListenerEventArgs>,
       public IDrmPluginListener {
 public:
     DrmHalPluginListener() {
@@ -183,10 +186,13 @@
             int64_t) override { return Void(); }
 
     virtual Return<void> sendKeysChange(const hidl_vec<uint8_t>&,
-            const hidl_vec<KeyStatus>&, bool) override { return Void(); }
+            const hidl_vec<KeyStatusV1_0>&, bool) override { return Void(); }
 
     virtual Return<void> sendSessionLostState(const hidl_vec<uint8_t>& sessionId) override;
 
+    virtual Return<void> sendKeysChange_1_2(const hidl_vec<uint8_t>&,
+            const hidl_vec<KeyStatus>&, bool) override;
+
 };
 
 }  // namespace vts
diff --git a/drm/1.2/vts/functional/drm_hal_test.cpp b/drm/1.2/vts/functional/drm_hal_test.cpp
index 252ebb9..37ecc25 100644
--- a/drm/1.2/vts/functional/drm_hal_test.cpp
+++ b/drm/1.2/vts/functional/drm_hal_test.cpp
@@ -28,6 +28,8 @@
 using ::android::hardware::drm::V1_1::SecurityLevel;
 using ::android::hardware::drm::V1_2::HdcpLevel;
 using ::android::hardware::drm::V1_2::KeySetId;
+using ::android::hardware::drm::V1_2::KeyStatus;
+using ::android::hardware::drm::V1_2::KeyStatusType;
 using ::android::hardware::drm::V1_2::OfflineLicenseState;
 
 using ::android::hardware::drm::V1_2::vts::DrmHalClearkeyTest;
@@ -35,6 +37,7 @@
 using ::android::hardware::drm::V1_2::vts::DrmHalTest;
 using ::android::hardware::drm::V1_2::vts::DrmHidlEnvironment;
 using ::android::hardware::drm::V1_2::vts::kCallbackLostState;
+using ::android::hardware::drm::V1_2::vts::kCallbackKeysChange;
 
 using ::android::hardware::hidl_string;
 
@@ -275,6 +278,35 @@
 }
 
 /**
+ * Simulate the plugin sending keys change and make sure
+ * the listener gets them.
+ */
+TEST_P(DrmHalTest, ListenerKeysChange) {
+    RETURN_IF_SKIPPED;
+    sp<DrmHalPluginListener> listener = new DrmHalPluginListener();
+    auto res = drmPlugin->setListener(listener);
+    EXPECT_OK(res);
+
+    auto sessionId = openSession();
+    const hidl_vec<KeyStatus> keyStatusList = {
+        {{1}, KeyStatusType::USABLE},
+        {{2}, KeyStatusType::EXPIRED},
+        {{3}, KeyStatusType::OUTPUTNOTALLOWED},
+        {{4}, KeyStatusType::STATUSPENDING},
+        {{5}, KeyStatusType::INTERNALERROR},
+        {{6}, KeyStatusType::USABLEINFUTURE},
+    };
+
+    drmPlugin->sendKeysChange_1_2(sessionId, keyStatusList, true);
+    auto result = listener->WaitForCallback(kCallbackKeysChange);
+    EXPECT_TRUE(result.no_timeout);
+    EXPECT_TRUE(result.args);
+    EXPECT_EQ(sessionId, result.args->sessionId);
+    EXPECT_EQ(keyStatusList, result.args->keyStatusList);
+    closeSession(sessionId);
+}
+
+/**
  *  CryptoPlugin Decrypt tests
  */
 
@@ -452,7 +484,7 @@
     auto result = listener->WaitForCallback(kCallbackLostState);
     EXPECT_TRUE(result.no_timeout);
     EXPECT_TRUE(result.args);
-    EXPECT_EQ(sessionId, *(result.args));
+    EXPECT_EQ(sessionId, result.args->sessionId);
 }
 
 /**
diff --git a/gnss/2.0/vts/functional/gnss_hal_test.cpp b/gnss/2.0/vts/functional/gnss_hal_test.cpp
index da6092b..a9f858c 100644
--- a/gnss/2.0/vts/functional/gnss_hal_test.cpp
+++ b/gnss/2.0/vts/functional/gnss_hal_test.cpp
@@ -23,42 +23,26 @@
 using ::android::hardware::gnss::common::Utils;
 
 // Implementations for the main test class for GNSS HAL
-GnssHalTest::GnssHalTest()
-    : info_called_count_(0),
-      capabilities_called_count_(0),
-      measurement_corrections_capabilities_called_count_(0),
-      location_called_count_(0),
-      name_called_count_(0),
-      notify_count_(0) {}
-
 void GnssHalTest::SetUp() {
     gnss_hal_ = ::testing::VtsHalHidlTargetTestBase::getService<IGnss>(
         GnssHidlEnvironment::Instance()->getServiceName<IGnss>());
-    list_vec_gnss_sv_info_.clear();
     ASSERT_NE(gnss_hal_, nullptr);
 
     SetUpGnssCallback();
 }
 
 void GnssHalTest::TearDown() {
-    // Reset counters
-    info_called_count_ = 0;
-    capabilities_called_count_ = 0;
-    measurement_corrections_capabilities_called_count_ = 0;
-    location_called_count_ = 0;
-    name_called_count_ = 0;
-    measurement_called_count_ = 0;
-
     if (gnss_hal_ != nullptr) {
         gnss_hal_->cleanup();
+        gnss_hal_ = nullptr;
     }
-    if (notify_count_ > 0) {
-        ALOGW("%d unprocessed callbacks discarded", notify_count_);
-    }
+
+    // Set to nullptr to destruct the callback event queues and warn of any unprocessed events.
+    gnss_cb_ = nullptr;
 }
 
 void GnssHalTest::SetUpGnssCallback() {
-    gnss_cb_ = new GnssCallback(*this);
+    gnss_cb_ = new GnssCallback();
     ASSERT_NE(gnss_cb_, nullptr);
 
     auto result = gnss_hal_->setCallback_2_0(gnss_cb_);
@@ -72,13 +56,13 @@
     /*
      * All capabilities, name and systemInfo callbacks should trigger
      */
-    EXPECT_EQ(std::cv_status::no_timeout, wait(TIMEOUT_SEC));
-    EXPECT_EQ(std::cv_status::no_timeout, wait(TIMEOUT_SEC));
-    EXPECT_EQ(std::cv_status::no_timeout, wait(TIMEOUT_SEC));
+    EXPECT_TRUE(gnss_cb_->capabilities_cbq_.retrieve(gnss_cb_->last_capabilities_, TIMEOUT_SEC));
+    EXPECT_TRUE(gnss_cb_->info_cbq_.retrieve(gnss_cb_->last_info_, TIMEOUT_SEC));
+    EXPECT_TRUE(gnss_cb_->name_cbq_.retrieve(gnss_cb_->last_name_, TIMEOUT_SEC));
 
-    EXPECT_EQ(capabilities_called_count_, 1);
-    EXPECT_EQ(info_called_count_, 1);
-    EXPECT_EQ(name_called_count_, 1);
+    EXPECT_EQ(gnss_cb_->capabilities_cbq_.calledCount(), 1);
+    EXPECT_EQ(gnss_cb_->info_cbq_.calledCount(), 1);
+    EXPECT_EQ(gnss_cb_->name_cbq_.calledCount(), 1);
 }
 
 void GnssHalTest::StopAndClearLocations() {
@@ -92,9 +76,9 @@
      * the last reply for final startup messages to arrive (esp. system
      * info.)
      */
-    while (wait(TIMEOUT_SEC) == std::cv_status::no_timeout) {
+    while (gnss_cb_->location_cbq_.retrieve(gnss_cb_->last_location_, TIMEOUT_SEC)) {
     }
-    location_called_count_ = 0;
+    gnss_cb_->location_cbq_.reset();
 }
 
 void GnssHalTest::SetPositionMode(const int min_interval_msec, const bool low_power_mode) {
@@ -121,19 +105,22 @@
      */
     const int kFirstGnssLocationTimeoutSeconds = 75;
 
-    wait(kFirstGnssLocationTimeoutSeconds);
-    EXPECT_EQ(location_called_count_, 1);
+    EXPECT_TRUE(gnss_cb_->location_cbq_.retrieve(gnss_cb_->last_location_,
+                                                 kFirstGnssLocationTimeoutSeconds));
+    int locationCalledCount = gnss_cb_->location_cbq_.calledCount();
+    EXPECT_EQ(locationCalledCount, 1);
 
-    if (location_called_count_ > 0) {
+    if (locationCalledCount > 0) {
         // don't require speed on first fix
-        CheckLocation(last_location_, false);
+        CheckLocation(gnss_cb_->last_location_, false);
         return true;
     }
     return false;
 }
 
 void GnssHalTest::CheckLocation(const GnssLocation_2_0& location, bool check_speed) {
-    const bool check_more_accuracies = (info_called_count_ > 0 && last_info_.yearOfHw >= 2017);
+    const bool check_more_accuracies =
+            (gnss_cb_->info_cbq_.calledCount() > 0 && gnss_cb_->last_info_.yearOfHw >= 2017);
 
     Utils::checkLocation(location.v1_0, check_speed, check_more_accuracies);
 }
@@ -148,77 +135,47 @@
     EXPECT_TRUE(StartAndCheckFirstLocation());
 
     for (int i = 1; i < count; i++) {
-        EXPECT_EQ(std::cv_status::no_timeout, wait(kLocationTimeoutSubsequentSec));
-        EXPECT_EQ(location_called_count_, i + 1);
+        EXPECT_TRUE(gnss_cb_->location_cbq_.retrieve(gnss_cb_->last_location_,
+                                                     kLocationTimeoutSubsequentSec));
+        int locationCalledCount = gnss_cb_->location_cbq_.calledCount();
+        EXPECT_EQ(locationCalledCount, i + 1);
         // Don't cause confusion by checking details if no location yet
-        if (location_called_count_ > 0) {
+        if (locationCalledCount > 0) {
             // Should be more than 1 location by now, but if not, still don't check first fix speed
-            CheckLocation(last_location_, location_called_count_ > 1);
+            CheckLocation(gnss_cb_->last_location_, locationCalledCount > 1);
         }
     }
 }
 
-void GnssHalTest::notify() {
-    {
-        std::unique_lock<std::mutex> lock(mtx_);
-        notify_count_++;
-    }
-    cv_.notify_one();
-}
-
-std::cv_status GnssHalTest::wait(int timeout_seconds) {
-    std::unique_lock<std::mutex> lock(mtx_);
-
-    auto status = std::cv_status::no_timeout;
-    while (notify_count_ == 0) {
-        status = cv_.wait_for(lock, std::chrono::seconds(timeout_seconds));
-        if (status == std::cv_status::timeout) return status;
-    }
-    notify_count_--;
-    return status;
-}
-
-std::cv_status GnssHalTest::waitForMeasurementCorrectionsCapabilities(int timeout_seconds) {
-    std::unique_lock<std::mutex> lock(mtx_);
-    auto status = std::cv_status::no_timeout;
-    while (measurement_corrections_capabilities_called_count_ == 0) {
-        status = cv_.wait_for(lock, std::chrono::seconds(timeout_seconds));
-        if (status == std::cv_status::timeout) return status;
-    }
-    notify_count_--;
-    return status;
-}
+GnssHalTest::GnssCallback::GnssCallback()
+    : info_cbq_("system_info"),
+      name_cbq_("name"),
+      capabilities_cbq_("capabilities"),
+      location_cbq_("location"),
+      sv_info_cbq_("sv_info") {}
 
 Return<void> GnssHalTest::GnssCallback::gnssSetSystemInfoCb(
         const IGnssCallback_1_0::GnssSystemInfo& info) {
     ALOGI("Info received, year %d", info.yearOfHw);
-    parent_.info_called_count_++;
-    parent_.last_info_ = info;
-    parent_.notify();
+    info_cbq_.store(info);
     return Void();
 }
 
 Return<void> GnssHalTest::GnssCallback::gnssSetCapabilitesCb(uint32_t capabilities) {
     ALOGI("Capabilities received %d", capabilities);
-    parent_.capabilities_called_count_++;
-    parent_.last_capabilities_ = capabilities;
-    parent_.notify();
+    capabilities_cbq_.store(capabilities);
     return Void();
 }
 
 Return<void> GnssHalTest::GnssCallback::gnssSetCapabilitiesCb_2_0(uint32_t capabilities) {
     ALOGI("Capabilities (v2.0) received %d", capabilities);
-    parent_.capabilities_called_count_++;
-    parent_.last_capabilities_ = capabilities;
-    parent_.notify();
+    capabilities_cbq_.store(capabilities);
     return Void();
 }
 
 Return<void> GnssHalTest::GnssCallback::gnssNameCb(const android::hardware::hidl_string& name) {
     ALOGI("Name received: %s", name.c_str());
-    parent_.name_called_count_++;
-    parent_.last_name_ = name;
-    parent_.notify();
+    name_cbq_.store(name);
     return Void();
 }
 
@@ -235,40 +192,32 @@
 }
 
 Return<void> GnssHalTest::GnssCallback::gnssLocationCbImpl(const GnssLocation_2_0& location) {
-    parent_.location_called_count_++;
-    parent_.last_location_ = location;
-    parent_.notify();
+    location_cbq_.store(location);
     return Void();
 }
 
 Return<void> GnssHalTest::GnssCallback::gnssSvStatusCb(const IGnssCallback_1_0::GnssSvStatus&) {
     ALOGI("gnssSvStatusCb");
-
-    return Void();
-}
-
-Return<void> GnssHalTest::GnssMeasurementCallback::gnssMeasurementCb_2_0(
-    const IGnssMeasurementCallback_2_0::GnssData& data) {
-    ALOGD("GnssMeasurement received. Size = %d", (int)data.measurements.size());
-    parent_.measurement_called_count_++;
-    parent_.last_measurement_ = data;
-    parent_.notify();
-    return Void();
-}
-
-Return<void> GnssHalTest::GnssMeasurementCorrectionsCallback::setCapabilitiesCb(
-        uint32_t capabilities) {
-    ALOGI("GnssMeasurementCorrectionsCallback capabilities received %d", capabilities);
-    parent_.measurement_corrections_capabilities_called_count_++;
-    parent_.last_measurement_corrections_capabilities_ = capabilities;
-    parent_.notify();
     return Void();
 }
 
 Return<void> GnssHalTest::GnssCallback::gnssSvStatusCb_2_0(
         const hidl_vec<IGnssCallback_2_0::GnssSvInfo>& svInfoList) {
     ALOGI("gnssSvStatusCb_2_0. Size = %d", (int)svInfoList.size());
-    parent_.list_vec_gnss_sv_info_.emplace_back(svInfoList);
-    parent_.notify();
+    sv_info_cbq_.store(svInfoList);
+    return Void();
+}
+
+Return<void> GnssHalTest::GnssMeasurementCallback::gnssMeasurementCb_2_0(
+    const IGnssMeasurementCallback_2_0::GnssData& data) {
+    ALOGD("GnssMeasurement received. Size = %d", (int)data.measurements.size());
+    measurement_cbq_.store(data);
+    return Void();
+}
+
+Return<void> GnssHalTest::GnssMeasurementCorrectionsCallback::setCapabilitiesCb(
+        uint32_t capabilities) {
+    ALOGI("GnssMeasurementCorrectionsCallback capabilities received %d", capabilities);
+    capabilities_cbq_.store(capabilities);
     return Void();
 }
diff --git a/gnss/2.0/vts/functional/gnss_hal_test.h b/gnss/2.0/vts/functional/gnss_hal_test.h
index 737815f..05e37d3 100644
--- a/gnss/2.0/vts/functional/gnss_hal_test.h
+++ b/gnss/2.0/vts/functional/gnss_hal_test.h
@@ -22,7 +22,7 @@
 #include <VtsHalHidlTargetTestEnvBase.h>
 
 #include <condition_variable>
-#include <list>
+#include <deque>
 #include <mutex>
 
 using android::hardware::hidl_vec;
@@ -65,27 +65,61 @@
 // The main test class for GNSS HAL.
 class GnssHalTest : public ::testing::VtsHalHidlTargetTestBase {
    public:
-    GnssHalTest();
-
     virtual void SetUp() override;
 
     virtual void TearDown() override;
 
-    /* Used as a mechanism to inform the test that a callback has occurred */
-    void notify();
+    /* Producer/consumer queue for storing/retrieving callback events from GNSS HAL */
+    template <class T>
+    class CallbackQueue {
+      public:
+        CallbackQueue(const std::string& name) : name_(name), called_count_(0){};
+        ~CallbackQueue() { reset(); }
 
-    /* Test code calls this function to wait for a callback */
-    std::cv_status wait(int timeout_seconds);
+        /* Adds callback event to the end of the queue. */
+        void store(const T& event);
 
-    std::cv_status waitForMeasurementCorrectionsCapabilities(int timeout_seconds);
+        /*
+         * Removes the callack event at the front of the queue, stores it in event parameter
+         * and returns true. Returns false on timeout and event is not populated.
+         */
+        bool retrieve(T& event, int timeout_seconds);
+
+        /* Returns the number of events pending to be retrieved from the callback event queue. */
+        int size() const;
+
+        /* Returns the number of callback events received since last reset(). */
+        int calledCount() const;
+
+        /* Clears the callback event queue and resets the calledCount() to 0. */
+        void reset();
+
+      private:
+        CallbackQueue(const CallbackQueue&) = delete;
+        CallbackQueue& operator=(const CallbackQueue&) = delete;
+
+        std::string name_;
+        int called_count_;
+        mutable std::recursive_mutex mtx_;
+        std::condition_variable_any cv_;
+        std::deque<T> events_;
+    };
 
     /* Callback class for data & Event. */
     class GnssCallback : public IGnssCallback_2_0 {
       public:
-        GnssHalTest& parent_;
+        IGnssCallback_1_0::GnssSystemInfo last_info_;
+        android::hardware::hidl_string last_name_;
+        uint32_t last_capabilities_;
+        GnssLocation_2_0 last_location_;
 
-        GnssCallback(GnssHalTest& parent) : parent_(parent){};
+        CallbackQueue<IGnssCallback_1_0::GnssSystemInfo> info_cbq_;
+        CallbackQueue<android::hardware::hidl_string> name_cbq_;
+        CallbackQueue<uint32_t> capabilities_cbq_;
+        CallbackQueue<GnssLocation_2_0> location_cbq_;
+        CallbackQueue<hidl_vec<IGnssCallback_2_0::GnssSvInfo>> sv_info_cbq_;
 
+        GnssCallback();
         virtual ~GnssCallback() = default;
 
         // Dummy callback handlers
@@ -125,9 +159,10 @@
 
     /* Callback class for GnssMeasurement. */
     class GnssMeasurementCallback : public IGnssMeasurementCallback_2_0 {
-       public:
-        GnssHalTest& parent_;
-        GnssMeasurementCallback(GnssHalTest& parent) : parent_(parent){};
+      public:
+        CallbackQueue<IGnssMeasurementCallback_2_0::GnssData> measurement_cbq_;
+
+        GnssMeasurementCallback() : measurement_cbq_("measurement"){};
         virtual ~GnssMeasurementCallback() = default;
 
         // Methods from V1_0::IGnssMeasurementCallback follow.
@@ -147,8 +182,10 @@
     /* Callback class for GnssMeasurementCorrections. */
     class GnssMeasurementCorrectionsCallback : public IMeasurementCorrectionsCallback {
       public:
-        GnssHalTest& parent_;
-        GnssMeasurementCorrectionsCallback(GnssHalTest& parent) : parent_(parent){};
+        uint32_t last_capabilities_;
+        CallbackQueue<uint32_t> capabilities_cbq_;
+
+        GnssMeasurementCorrectionsCallback() : capabilities_cbq_("capabilities"){};
         virtual ~GnssMeasurementCorrectionsCallback() = default;
 
         // Methods from V1_0::IMeasurementCorrectionsCallback follow.
@@ -203,32 +240,51 @@
     void SetPositionMode(const int min_interval_msec, const bool low_power_mode);
 
     sp<IGnss> gnss_hal_;         // GNSS HAL to call into
-    sp<IGnssCallback_2_0> gnss_cb_;  // Primary callback interface
-
-    // TODO: make these variables thread-safe.
-    /* Count of calls to set the following items, and the latest item (used by
-     * test.)
-     */
-    int info_called_count_;
-    int capabilities_called_count_;
-    int measurement_corrections_capabilities_called_count_;
-    int location_called_count_;
-    int measurement_called_count_;
-    int name_called_count_;
-
-    IGnssCallback_1_0::GnssSystemInfo last_info_;
-    uint32_t last_capabilities_;
-    uint32_t last_measurement_corrections_capabilities_;
-    GnssLocation_2_0 last_location_;
-    IGnssMeasurementCallback_2_0::GnssData last_measurement_;
-    android::hardware::hidl_string last_name_;
-
-    list<hidl_vec<IGnssCallback_2_0::GnssSvInfo>> list_vec_gnss_sv_info_;
-
-  private:
-    std::mutex mtx_;
-    std::condition_variable cv_;
-    int notify_count_;
+    sp<GnssCallback> gnss_cb_;   // Primary callback interface
 };
 
+template <class T>
+void GnssHalTest::CallbackQueue<T>::store(const T& event) {
+    std::unique_lock<std::recursive_mutex> lock(mtx_);
+    events_.push_back(event);
+    ++called_count_;
+    lock.unlock();
+    cv_.notify_all();
+}
+
+template <class T>
+bool GnssHalTest::CallbackQueue<T>::retrieve(T& event, int timeout_seconds) {
+    std::unique_lock<std::recursive_mutex> lock(mtx_);
+    cv_.wait_for(lock, std::chrono::seconds(timeout_seconds), [&] { return !events_.empty(); });
+    if (events_.empty()) {
+        return false;
+    }
+    event = events_.front();
+    events_.pop_front();
+    return true;
+}
+
+template <class T>
+int GnssHalTest::CallbackQueue<T>::size() const {
+    std::unique_lock<std::recursive_mutex> lock(mtx_);
+    return events_.size();
+}
+
+template <class T>
+int GnssHalTest::CallbackQueue<T>::calledCount() const {
+    std::unique_lock<std::recursive_mutex> lock(mtx_);
+    return called_count_;
+}
+
+template <class T>
+void GnssHalTest::CallbackQueue<T>::reset() {
+    std::unique_lock<std::recursive_mutex> lock(mtx_);
+    if (!events_.empty()) {
+        ALOGW("%u unprocessed events discarded in callback queue %s", (unsigned int)events_.size(),
+              name_.c_str());
+    }
+    events_.clear();
+    called_count_ = 0;
+}
+
 #endif  // GNSS_HAL_TEST_H_
diff --git a/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp b/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp
index be182a9..155afd6 100644
--- a/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp
+++ b/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp
@@ -29,6 +29,7 @@
 using IGnssMeasurement_1_1 = android::hardware::gnss::V1_1::IGnssMeasurement;
 using IGnssMeasurement_1_0 = android::hardware::gnss::V1_0::IGnssMeasurement;
 using IAGnssRil_2_0 = android::hardware::gnss::V2_0::IAGnssRil;
+using IAGnssRil_1_0 = android::hardware::gnss::V1_0::IAGnssRil;
 using IAGnss_2_0 = android::hardware::gnss::V2_0::IAGnss;
 using IAGnss_1_0 = android::hardware::gnss::V1_0::IAGnss;
 using IAGnssCallback_2_0 = android::hardware::gnss::V2_0::IAGnssCallback;
@@ -53,10 +54,10 @@
 TEST_F(GnssHalTest, SetupTeardownCreateCleanup) {}
 
 /*
- * TestGnssMeasurementCallback:
+ * TestGnssMeasurementExtension:
  * Gets the GnssMeasurementExtension and verifies that it returns an actual extension.
  */
-TEST_F(GnssHalTest, TestGnssMeasurementCallback) {
+TEST_F(GnssHalTest, TestGnssMeasurementExtension) {
     auto gnssMeasurement_2_0 = gnss_hal_->getExtensionGnssMeasurement_2_0();
     auto gnssMeasurement_1_1 = gnss_hal_->getExtensionGnssMeasurement_1_1();
     auto gnssMeasurement_1_0 = gnss_hal_->getExtensionGnssMeasurement();
@@ -125,16 +126,21 @@
  * TestAGnssRilExtension:
  * Gets the AGnssRilExtension and verifies that it returns an actual extension.
  *
- * The GNSS HAL 2.0 implementation must support @2.0::IAGnssRil interface due to the deprecation
- * of framework network API methods needed to support the @1.0::IAGnssRil interface.
- *
- * TODO (b/121287858): Enforce gnss@2.0 HAL package is supported on devices launched with Q or later
+ * If IAGnssRil interface is supported, then the GNSS HAL 2.0 implementation must support
+ * @2.0::IAGnssRil interface due to the deprecation of framework network API methods needed
+ * to support the @1.0::IAGnssRil interface.
  */
 TEST_F(GnssHalTest, TestAGnssRilExtension) {
-    auto agnssRil = gnss_hal_->getExtensionAGnssRil_2_0();
-    ASSERT_TRUE(agnssRil.isOk());
-    sp<IAGnssRil_2_0> iAGnssRil = agnssRil;
-    ASSERT_NE(iAGnssRil, nullptr);
+    auto agnssRil_2_0 = gnss_hal_->getExtensionAGnssRil_2_0();
+    ASSERT_TRUE(agnssRil_2_0.isOk());
+    sp<IAGnssRil_2_0> iAGnssRil_2_0 = agnssRil_2_0;
+    if (iAGnssRil_2_0 == nullptr) {
+        // Verify IAGnssRil 1.0 is not supported.
+        auto agnssRil_1_0 = gnss_hal_->getExtensionAGnssRil();
+        ASSERT_TRUE(agnssRil_1_0.isOk());
+        sp<IAGnssRil_1_0> iAGnssRil_1_0 = agnssRil_1_0;
+        ASSERT_EQ(iAGnssRil_1_0, nullptr);
+    }
 }
 
 /*
@@ -146,7 +152,9 @@
     auto agnssRil = gnss_hal_->getExtensionAGnssRil_2_0();
     ASSERT_TRUE(agnssRil.isOk());
     sp<IAGnssRil_2_0> iAGnssRil = agnssRil;
-    ASSERT_NE(iAGnssRil, nullptr);
+    if (iAGnssRil == nullptr) {
+        return;
+    }
 
     // Update GNSS HAL that a network has connected.
     IAGnssRil_2_0::NetworkAttributes networkAttributes = {
@@ -185,16 +193,17 @@
         return;
     }
 
-    sp<IGnssMeasurementCallback_2_0> callback = new GnssMeasurementCallback(*this);
-
+    sp<GnssMeasurementCallback> callback = new GnssMeasurementCallback();
     auto result = iGnssMeasurement->setCallback_2_0(callback, /* enableFullTracking= */ true);
     ASSERT_TRUE(result.isOk());
     EXPECT_EQ(result, IGnssMeasurement_1_0::GnssMeasurementStatus::SUCCESS);
 
-    wait(kFirstGnssMeasurementTimeoutSeconds);
-    EXPECT_EQ(measurement_called_count_, 1);
-    ASSERT_TRUE(last_measurement_.measurements.size() > 0);
-    for (auto measurement : last_measurement_.measurements) {
+    IGnssMeasurementCallback_2_0::GnssData lastMeasurement;
+    ASSERT_TRUE(callback->measurement_cbq_.retrieve(lastMeasurement,
+                                                    kFirstGnssMeasurementTimeoutSeconds));
+    EXPECT_EQ(callback->measurement_cbq_.calledCount(), 1);
+    ASSERT_TRUE(lastMeasurement.measurements.size() > 0);
+    for (auto measurement : lastMeasurement.measurements) {
         // Verify CodeType is valid.
         ASSERT_NE(measurement.codeType, "");
 
@@ -219,44 +228,35 @@
 
 /*
  * TestAGnssExtension:
- * Gets the AGnssExtension and verifies that it supports @2.0::IAGnss interface by invoking
- * a method.
+ * Gets the AGnssExtension and verifies that it returns an actual extension.
  *
- * The GNSS HAL 2.0 implementation must support @2.0::IAGnss interface due to the deprecation
- * of framework network API methods needed to support the @1.0::IAGnss interface.
- *
- * TODO (b/121287858): Enforce gnss@2.0 HAL package is supported on devices launched with Q or later
+ * If IAGnss interface is supported, then the GNSS HAL 2.0 implementation must support
+ * @2.0::IAGnss interface due to the deprecation of framework network API methods needed
+ * to support the @1.0::IAGnss interface.
  */
 TEST_F(GnssHalTest, TestAGnssExtension) {
-    // Verify IAGnss 2.0 is supported.
-    auto agnss = gnss_hal_->getExtensionAGnss_2_0();
-    ASSERT_TRUE(agnss.isOk());
-    sp<IAGnss_2_0> iAGnss = agnss;
-    ASSERT_NE(iAGnss, nullptr);
+    auto agnss_2_0 = gnss_hal_->getExtensionAGnss_2_0();
+    ASSERT_TRUE(agnss_2_0.isOk());
+    sp<IAGnss_2_0> iAGnss_2_0 = agnss_2_0;
+    if (iAGnss_2_0 == nullptr) {
+        // Verify IAGnss 1.0 is not supported.
+        auto agnss_1_0 = gnss_hal_->getExtensionAGnss();
+        ASSERT_TRUE(agnss_1_0.isOk());
+        sp<IAGnss_1_0> iAGnss_1_0 = agnss_1_0;
+        ASSERT_EQ(iAGnss_1_0, nullptr);
+        return;
+    }
 
     // Set SUPL server host/port
-    auto result = iAGnss->setServer(IAGnssCallback_2_0::AGnssType::SUPL, "supl.google.com", 7275);
+    auto result =
+            iAGnss_2_0->setServer(IAGnssCallback_2_0::AGnssType::SUPL, "supl.google.com", 7275);
     ASSERT_TRUE(result.isOk());
     EXPECT_TRUE(result);
 }
 
 /*
- * TestAGnssExtension_1_0_Deprecation:
- * Gets the @1.0::IAGnss extension and verifies that it is a nullptr.
- *
- * TODO (b/121287858): Enforce gnss@2.0 HAL package is supported on devices launched with Q or later
- */
-TEST_F(GnssHalTest, TestAGnssExtension_1_0_Deprecation) {
-    // Verify IAGnss 1.0 is not supported.
-    auto agnss_1_0 = gnss_hal_->getExtensionAGnss();
-    ASSERT_TRUE(!agnss_1_0.isOk() || ((sp<IAGnss_1_0>)agnss_1_0) == nullptr);
-}
-
-/*
  * TestGnssNiExtension_Deprecation:
  * Gets the @1.0::IGnssNi extension and verifies that it is a nullptr.
- *
- * TODO (b/121287858): Enforce gnss@2.0 HAL package is supported on devices launched with Q or later
  */
 TEST_F(GnssHalTest, TestGnssNiExtension_Deprecation) {
     // Verify IGnssNi 1.0 is not supported.
@@ -266,22 +266,19 @@
 
 /*
  * TestGnssVisibilityControlExtension:
- * Gets the GnssVisibilityControlExtension and verifies that it supports the
- * gnss.visibility_control@1.0::IGnssVisibilityControl interface by invoking a method.
- *
- * The GNSS HAL 2.0 implementation must support gnss.visibility_control@1.0::IGnssVisibilityControl.
- *
- * TODO (b/121287858): Enforce gnss@2.0 HAL package is supported on devices launched with Q or later
+ * Gets the GnssVisibilityControlExtension and if it is not null, verifies that it supports
+ * the gnss.visibility_control@1.0::IGnssVisibilityControl interface by invoking a method.
  */
 TEST_F(GnssHalTest, TestGnssVisibilityControlExtension) {
-    // Verify IGnssVisibilityControl is supported.
     auto gnssVisibilityControl = gnss_hal_->getExtensionVisibilityControl();
     ASSERT_TRUE(gnssVisibilityControl.isOk());
     sp<IGnssVisibilityControl> iGnssVisibilityControl = gnssVisibilityControl;
-    ASSERT_NE(iGnssVisibilityControl, nullptr);
+    if (iGnssVisibilityControl == nullptr) {
+        return;
+    }
 
     // Set non-framework proxy apps.
-    hidl_vec<hidl_string> proxyApps{"ims.example.com", "mdt.example.com"};
+    hidl_vec<hidl_string> proxyApps{"com.example.ims", "com.example.mdt"};
     auto result = iGnssVisibilityControl->enableNfwLocationAccess(proxyApps);
     ASSERT_TRUE(result.isOk());
     EXPECT_TRUE(result);
@@ -294,7 +291,7 @@
  * capability flag is set.
  */
 TEST_F(GnssHalTest, TestGnssMeasurementCorrectionsCapabilities) {
-    if (!(last_capabilities_ & IGnssCallback::Capabilities::MEASUREMENT_CORRECTIONS)) {
+    if (!(gnss_cb_->last_capabilities_ & IGnssCallback::Capabilities::MEASUREMENT_CORRECTIONS)) {
         return;
     }
 
@@ -304,15 +301,15 @@
     ASSERT_NE(iMeasurementCorrections, nullptr);
 
     // Setup measurement corrections callback.
-    sp<IMeasurementCorrectionsCallback> iMeasurementCorrectionsCallback =
-            new GnssMeasurementCorrectionsCallback(*this);
-    iMeasurementCorrections->setCallback(iMeasurementCorrectionsCallback);
+    sp<GnssMeasurementCorrectionsCallback> callback = new GnssMeasurementCorrectionsCallback();
+    iMeasurementCorrections->setCallback(callback);
 
     const int kMeasurementCorrectionsCapabilitiesTimeoutSeconds = 5;
-    waitForMeasurementCorrectionsCapabilities(kMeasurementCorrectionsCapabilitiesTimeoutSeconds);
-    ASSERT_TRUE(measurement_corrections_capabilities_called_count_ > 0);
+    callback->capabilities_cbq_.retrieve(callback->last_capabilities_,
+                                         kMeasurementCorrectionsCapabilitiesTimeoutSeconds);
+    ASSERT_TRUE(callback->capabilities_cbq_.calledCount() > 0);
     using Capabilities = IMeasurementCorrectionsCallback::Capabilities;
-    ASSERT_TRUE((last_measurement_corrections_capabilities_ &
+    ASSERT_TRUE((callback->last_capabilities_ &
                  (Capabilities::LOS_SATS | Capabilities::EXCESS_PATH_LENGTH)) != 0);
 }
 
@@ -322,7 +319,7 @@
  * gnss.measurement_corrections@1.0::IMeasurementCorrections interface by invoking a method.
  */
 TEST_F(GnssHalTest, TestGnssMeasurementCorrections) {
-    if (!(last_capabilities_ & IGnssCallback::Capabilities::MEASUREMENT_CORRECTIONS)) {
+    if (!(gnss_cb_->last_capabilities_ & IGnssCallback::Capabilities::MEASUREMENT_CORRECTIONS)) {
         return;
     }
 
@@ -332,13 +329,14 @@
     sp<IMeasurementCorrections> iMeasurementCorrections = measurementCorrections;
     ASSERT_NE(iMeasurementCorrections, nullptr);
 
-    sp<IMeasurementCorrectionsCallback> iMeasurementCorrectionsCallback =
-            new GnssMeasurementCorrectionsCallback(*this);
-    iMeasurementCorrections->setCallback(iMeasurementCorrectionsCallback);
+    sp<GnssMeasurementCorrectionsCallback> callback = new GnssMeasurementCorrectionsCallback();
+    iMeasurementCorrections->setCallback(callback);
 
     const int kMeasurementCorrectionsCapabilitiesTimeoutSeconds = 5;
-    waitForMeasurementCorrectionsCapabilities(kMeasurementCorrectionsCapabilitiesTimeoutSeconds);
-    ASSERT_TRUE(measurement_corrections_capabilities_called_count_ > 0);
+    callback->capabilities_cbq_.retrieve(callback->last_capabilities_,
+                                         kMeasurementCorrectionsCapabilitiesTimeoutSeconds);
+    ASSERT_TRUE(callback->capabilities_cbq_.calledCount() > 0);
+
     // Set a mock MeasurementCorrections.
     auto result = iMeasurementCorrections->setCorrections(Utils::getMockMeasurementCorrections());
     ASSERT_TRUE(result.isOk());
@@ -363,22 +361,23 @@
         return;
     }
 
-    sp<IGnssMeasurementCallback_2_0> callback = new GnssMeasurementCallback(*this);
-
+    sp<GnssMeasurementCallback> callback = new GnssMeasurementCallback();
     auto result = iGnssMeasurement->setCallback_2_0(callback, /* enableFullTracking= */ true);
     ASSERT_TRUE(result.isOk());
     EXPECT_EQ(result, IGnssMeasurement_1_0::GnssMeasurementStatus::SUCCESS);
 
-    wait(kFirstGnssMeasurementTimeoutSeconds);
-    EXPECT_EQ(measurement_called_count_, 1);
+    IGnssMeasurementCallback_2_0::GnssData lastMeasurement;
+    ASSERT_TRUE(callback->measurement_cbq_.retrieve(lastMeasurement,
+                                                    kFirstGnssMeasurementTimeoutSeconds));
+    EXPECT_EQ(callback->measurement_cbq_.calledCount(), 1);
 
-    ASSERT_TRUE((int)last_measurement_.elapsedRealtime.flags <=
+    ASSERT_TRUE((int)lastMeasurement.elapsedRealtime.flags <=
                 (int)(ElapsedRealtimeFlags::HAS_TIMESTAMP_NS |
                       ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS));
 
     // We expect a non-zero timestamp when set.
-    if (last_measurement_.elapsedRealtime.flags & ElapsedRealtimeFlags::HAS_TIMESTAMP_NS) {
-        ASSERT_TRUE(last_measurement_.elapsedRealtime.timestampNs != 0);
+    if (lastMeasurement.elapsedRealtime.flags & ElapsedRealtimeFlags::HAS_TIMESTAMP_NS) {
+        ASSERT_TRUE(lastMeasurement.elapsedRealtime.timestampNs != 0);
     }
 
     iGnssMeasurement->close();
@@ -387,13 +386,13 @@
 TEST_F(GnssHalTest, TestGnssLocationElapsedRealtime) {
     StartAndCheckFirstLocation();
 
-    ASSERT_TRUE((int)last_location_.elapsedRealtime.flags <=
+    ASSERT_TRUE((int)gnss_cb_->last_location_.elapsedRealtime.flags <=
                 (int)(ElapsedRealtimeFlags::HAS_TIMESTAMP_NS |
                       ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS));
 
     // We expect a non-zero timestamp when set.
-    if (last_location_.elapsedRealtime.flags & ElapsedRealtimeFlags::HAS_TIMESTAMP_NS) {
-        ASSERT_TRUE(last_location_.elapsedRealtime.timestampNs != 0);
+    if (gnss_cb_->last_location_.elapsedRealtime.flags & ElapsedRealtimeFlags::HAS_TIMESTAMP_NS) {
+        ASSERT_TRUE(gnss_cb_->last_location_.elapsedRealtime.timestampNs != 0);
     }
 
     StopAndClearLocations();
@@ -402,23 +401,16 @@
 // This test only verify that injectBestLocation_2_0 does not crash.
 TEST_F(GnssHalTest, TestInjectBestLocation_2_0) {
     StartAndCheckFirstLocation();
-    gnss_hal_->injectBestLocation_2_0(last_location_);
+    gnss_hal_->injectBestLocation_2_0(gnss_cb_->last_location_);
     StopAndClearLocations();
 }
 
 /*
  * TestGnssBatchingExtension:
- * Gets the GnssBatchingExtension and verifies that it supports either the @1.0::IGnssBatching
- * or @2.0::IGnssBatching extension.
+ * Gets the @2.0::IGnssBatching extension and verifies that it doesn't return an error. Support
+ * for this interface is optional.
  */
 TEST_F(GnssHalTest, TestGnssBatchingExtension) {
-    auto gnssBatching_V2_0 = gnss_hal_->getExtensionGnssBatching_2_0();
-    ASSERT_TRUE(gnssBatching_V2_0.isOk());
-
-    auto gnssBatching_V1_0 = gnss_hal_->getExtensionGnssBatching();
-    ASSERT_TRUE(gnssBatching_V1_0.isOk());
-
-    sp<IGnssBatching_V1_0> iGnssBatching_V1_0 = gnssBatching_V1_0;
-    sp<IGnssBatching_V2_0> iGnssBatching_V2_0 = gnssBatching_V2_0;
-    ASSERT_TRUE(iGnssBatching_V1_0 != nullptr || iGnssBatching_V2_0 != nullptr);
+    auto gnssBatching_2_0 = gnss_hal_->getExtensionGnssBatching_2_0();
+    ASSERT_TRUE(gnssBatching_2_0.isOk());
 }
diff --git a/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp b/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp
index 4018aea..3c408b7 100644
--- a/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp
+++ b/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp
@@ -850,10 +850,37 @@
     ASSERT_NO_FATAL_FAILURE(layer =
                                 mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount));
 
+    auto handle = allocate();
+    ASSERT_NE(nullptr, handle);
+    IComposerClient::Rect displayFrame{0, 0, mDisplayWidth, mDisplayHeight};
+
     mWriter->selectDisplay(mPrimaryDisplay);
     mWriter->selectLayer(layer);
+    mWriter->setLayerBuffer(0, handle, -1);
+    mWriter->setLayerCompositionType(IComposerClient::Composition::CURSOR);
+    mWriter->setLayerDisplayFrame(displayFrame);
+    mWriter->setLayerPlaneAlpha(1);
+    mWriter->setLayerSourceCrop({0, 0, (float)mDisplayWidth, (float)mDisplayHeight});
+    mWriter->setLayerTransform(static_cast<Transform>(0));
+    mWriter->setLayerVisibleRegion(std::vector<IComposerClient::Rect>(1, displayFrame));
+    mWriter->setLayerZOrder(10);
+    mWriter->setLayerBlendMode(IComposerClient::BlendMode::NONE);
+    mWriter->setLayerSurfaceDamage(std::vector<IComposerClient::Rect>(1, displayFrame));
+    mWriter->setLayerDataspace(Dataspace::UNKNOWN);
+    mWriter->validateDisplay();
+
+    execute();
+    if (mReader->mCompositionChanges.size() != 0) {
+        GTEST_SUCCEED() << "Composition change requested, skipping test";
+        return;
+    }
+    mWriter->presentDisplay();
+    ASSERT_EQ(0, mReader->mErrors.size());
+
     mWriter->setLayerCursorPosition(1, 1);
     mWriter->setLayerCursorPosition(0, 0);
+    mWriter->validateDisplay();
+    mWriter->presentDisplay();
     execute();
 }
 
diff --git a/graphics/composer/2.3/utils/vts/ComposerVts.cpp b/graphics/composer/2.3/utils/vts/ComposerVts.cpp
index b763209..d4f5b3a 100644
--- a/graphics/composer/2.3/utils/vts/ComposerVts.cpp
+++ b/graphics/composer/2.3/utils/vts/ComposerVts.cpp
@@ -192,10 +192,8 @@
 
 bool ComposerClient::getDisplayBrightnessSupport(Display display) {
     bool support = false;
-    mClient->getDisplayBrightnessSupport(display, [&](const auto& error, const auto& tmpSupport) {
-        ASSERT_EQ(Error::NONE, error) << "failed to get brightness support";
-        support = tmpSupport;
-    });
+    mClient->getDisplayBrightnessSupport(
+            display, [&](const auto& /*error*/, const auto& tmpSupport) { support = tmpSupport; });
     return support;
 }
 
diff --git a/graphics/mapper/2.1/utils/passthrough/include/mapper-passthrough/2.1/Gralloc0Hal.h b/graphics/mapper/2.1/utils/passthrough/include/mapper-passthrough/2.1/Gralloc0Hal.h
index b704fdb..18fbb6d 100644
--- a/graphics/mapper/2.1/utils/passthrough/include/mapper-passthrough/2.1/Gralloc0Hal.h
+++ b/graphics/mapper/2.1/utils/passthrough/include/mapper-passthrough/2.1/Gralloc0Hal.h
@@ -34,34 +34,48 @@
 template <typename Hal>
 class Gralloc0HalImpl : public V2_0::passthrough::detail::Gralloc0HalImpl<Hal> {
    public:
-    Error validateBufferSize(const native_handle_t* /*bufferHandle*/,
-                             const IMapper::BufferDescriptorInfo& /*descriptorInfo*/,
-                             uint32_t /*stride*/) override {
-        // need a gralloc0 extension to really validate
-        return Error::NONE;
-    }
+     Error validateBufferSize(const native_handle_t* bufferHandle,
+                              const IMapper::BufferDescriptorInfo& descriptorInfo,
+                              uint32_t stride) override {
+         if (!mModule->validateBufferSize) {
+             return Error::NONE;
+         }
 
-    Error getTransportSize(const native_handle_t* bufferHandle, uint32_t* outNumFds,
-                           uint32_t* outNumInts) override {
-        // need a gralloc0 extension to get the transport size
-        *outNumFds = bufferHandle->numFds;
-        *outNumInts = bufferHandle->numInts;
-        return Error::NONE;
+         int32_t ret = mModule->validateBufferSize(
+                 mModule, bufferHandle, descriptorInfo.width, descriptorInfo.height,
+                 static_cast<int32_t>(descriptorInfo.format),
+                 static_cast<uint64_t>(descriptorInfo.usage), stride);
+         return static_cast<Error>(ret);
+     }
+     Error getTransportSize(const native_handle_t* bufferHandle, uint32_t* outNumFds,
+                            uint32_t* outNumInts) override {
+         if (!mModule->getTransportSize) {
+             *outNumFds = bufferHandle->numFds;
+             *outNumInts = bufferHandle->numInts;
+             return Error::NONE;
+         }
+
+         int32_t ret = mModule->getTransportSize(mModule, bufferHandle, outNumFds, outNumInts);
+         return static_cast<Error>(ret);
     }
 
     Error createDescriptor_2_1(const IMapper::BufferDescriptorInfo& descriptorInfo,
                                BufferDescriptor* outDescriptor) override {
         return createDescriptor(
-            V2_0::IMapper::BufferDescriptorInfo{
-                descriptorInfo.width, descriptorInfo.height, descriptorInfo.layerCount,
-                static_cast<common::V1_0::PixelFormat>(descriptorInfo.format), descriptorInfo.usage,
-            },
-            outDescriptor);
+                V2_0::IMapper::BufferDescriptorInfo{
+                        descriptorInfo.width,
+                        descriptorInfo.height,
+                        descriptorInfo.layerCount,
+                        static_cast<common::V1_0::PixelFormat>(descriptorInfo.format),
+                        descriptorInfo.usage,
+                },
+                outDescriptor);
     }
 
    private:
     using BaseType2_0 = V2_0::passthrough::detail::Gralloc0HalImpl<Hal>;
     using BaseType2_0::createDescriptor;
+    using BaseType2_0::mModule;
 };
 
 }  // namespace detail
diff --git a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
index cf12e2a..3d37e9f 100644
--- a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
+++ b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
@@ -371,7 +371,7 @@
             strptime(date.c_str(), "%Y-%m-%d", &time);
 
             // Day of the month (0-31)
-            EXPECT_GT(time.tm_mday, 0);
+            EXPECT_GE(time.tm_mday, 0);
             EXPECT_LT(time.tm_mday, 32);
             // Months since Jan (0-11)
             EXPECT_GE(time.tm_mon, 0);
diff --git a/neuralnetworks/1.1/types.hal b/neuralnetworks/1.1/types.hal
index 335b803..73705bb 100644
--- a/neuralnetworks/1.1/types.hal
+++ b/neuralnetworks/1.1/types.hal
@@ -138,7 +138,7 @@
      *
      * Supported tensor {@link OperandType}:
      * * {@link OperandType::TENSOR_FLOAT32}
-     * * {@link OperandType::TENSOR_QUANT8_ASYMM}
+     * * {@link OperandType::TENSOR_QUANT8_ASYMM} (the pad value is undefined)
      *
      * Supported tensor rank: up to 4
      *
@@ -161,6 +161,9 @@
      *          output0.dimension[i] =
      *              padding[i, 0] + input0.dimension[i] + padding[i, 1]
      *
+     *      NOTE: The pad value for {@link ANEURALNETWORKS_TENSOR_QUANT8_ASYMM}
+     *      is undefined.
+     *
      * Available since API level 28.
      */
     PAD = 32,
diff --git a/neuralnetworks/1.2/types.hal b/neuralnetworks/1.2/types.hal
index a6abfc3..c2e8f22 100644
--- a/neuralnetworks/1.2/types.hal
+++ b/neuralnetworks/1.2/types.hal
@@ -1999,7 +1999,8 @@
      * Supported tensor {@link OperandType}:
      * * {@link OperandType::TENSOR_FLOAT16} (since API level 29)
      * * {@link OperandType::TENSOR_FLOAT32}
-     * * {@link OperandType::TENSOR_QUANT8_ASYMM}
+     * * {@link OperandType::TENSOR_QUANT8_ASYMM} (full support since API
+     *   level 29, see the output section)
      *
      * Supported tensor rank: up to 4
      *
@@ -2022,6 +2023,10 @@
      *          output0.dimension[i] =
      *              padding[i, 0] + input0.dimension[i] + padding[i, 1]
      *
+     *      NOTE: Before API level 29, the pad value for
+     *      {@link ANEURALNETWORKS_TENSOR_QUANT8_ASYMM} is undefined.
+     *      Since API level 29, the pad value is always the logical zero.
+     *
      * Available since API level 28.
      */
     PAD = @1.1::OperationType:PAD,
diff --git a/neuralnetworks/1.2/vts/functional/ValidateBurst.cpp b/neuralnetworks/1.2/vts/functional/ValidateBurst.cpp
index 386c141..8bb4934 100644
--- a/neuralnetworks/1.2/vts/functional/ValidateBurst.cpp
+++ b/neuralnetworks/1.2/vts/functional/ValidateBurst.cpp
@@ -25,6 +25,7 @@
 #include "Utils.h"
 
 #include <android-base/logging.h>
+#include <cstring>
 
 namespace android {
 namespace hardware {
@@ -317,12 +318,91 @@
     }
 }
 
+static bool isSanitized(const FmqResultDatum& datum) {
+    using Discriminator = FmqResultDatum::hidl_discriminator;
+
+    // check to ensure the padding values in the returned
+    // FmqResultDatum::OperandInformation are initialized to 0
+    if (datum.getDiscriminator() == Discriminator::operandInformation) {
+        static_assert(
+                offsetof(FmqResultDatum::OperandInformation, isSufficient) == 0,
+                "unexpected value for offset of FmqResultDatum::OperandInformation::isSufficient");
+        static_assert(
+                sizeof(FmqResultDatum::OperandInformation::isSufficient) == 1,
+                "unexpected value for size of FmqResultDatum::OperandInformation::isSufficient");
+        static_assert(offsetof(FmqResultDatum::OperandInformation, numberOfDimensions) == 4,
+                      "unexpected value for offset of "
+                      "FmqResultDatum::OperandInformation::numberOfDimensions");
+        static_assert(sizeof(FmqResultDatum::OperandInformation::numberOfDimensions) == 4,
+                      "unexpected value for size of "
+                      "FmqResultDatum::OperandInformation::numberOfDimensions");
+        static_assert(sizeof(FmqResultDatum::OperandInformation) == 8,
+                      "unexpected value for size of "
+                      "FmqResultDatum::OperandInformation");
+
+        constexpr size_t paddingOffset =
+                offsetof(FmqResultDatum::OperandInformation, isSufficient) +
+                sizeof(FmqResultDatum::OperandInformation::isSufficient);
+        constexpr size_t paddingSize =
+                offsetof(FmqResultDatum::OperandInformation, numberOfDimensions) - paddingOffset;
+
+        FmqResultDatum::OperandInformation initialized{};
+        std::memset(&initialized, 0, sizeof(initialized));
+
+        const char* initializedPaddingStart =
+                reinterpret_cast<const char*>(&initialized) + paddingOffset;
+        const char* datumPaddingStart =
+                reinterpret_cast<const char*>(&datum.operandInformation()) + paddingOffset;
+
+        return std::memcmp(datumPaddingStart, initializedPaddingStart, paddingSize) == 0;
+    }
+
+    // there are no other padding initialization checks required, so return true
+    // for any sum-type that isn't FmqResultDatum::OperandInformation
+    return true;
+}
+
+static void validateBurstSanitized(const sp<IPreparedModel>& preparedModel,
+                                   const std::vector<Request>& requests) {
+    // create burst
+    std::unique_ptr<RequestChannelSender> sender;
+    std::unique_ptr<ResultChannelReceiver> receiver;
+    sp<ExecutionBurstCallback> callback = new ExecutionBurstCallback();
+    sp<IBurstContext> context;
+    ASSERT_NO_FATAL_FAILURE(createBurst(preparedModel, callback, &sender, &receiver, &context));
+    ASSERT_NE(nullptr, sender.get());
+    ASSERT_NE(nullptr, receiver.get());
+    ASSERT_NE(nullptr, context.get());
+
+    // validate each request
+    for (const Request& request : requests) {
+        // load memory into callback slots
+        std::vector<intptr_t> keys;
+        keys.reserve(request.pools.size());
+        std::transform(request.pools.begin(), request.pools.end(), std::back_inserter(keys),
+                       [](const auto& pool) { return reinterpret_cast<intptr_t>(&pool); });
+        const std::vector<int32_t> slots = callback->getSlots(request.pools, keys);
+
+        // send valid request
+        ASSERT_TRUE(sender->send(request, MeasureTiming::YES, slots));
+
+        // receive valid result
+        auto serialized = receiver->getPacketBlocking();
+        ASSERT_TRUE(serialized.has_value());
+
+        // sanitize result
+        ASSERT_TRUE(std::all_of(serialized->begin(), serialized->end(), isSanitized))
+                << "The result serialized data is not properly sanitized";
+    }
+}
+
 ///////////////////////////// ENTRY POINT //////////////////////////////////
 
 void ValidationTest::validateBurst(const sp<IPreparedModel>& preparedModel,
                                    const std::vector<Request>& requests) {
     ASSERT_NO_FATAL_FAILURE(validateBurstSerialization(preparedModel, requests));
     ASSERT_NO_FATAL_FAILURE(validateBurstFmqLength(preparedModel, requests));
+    ASSERT_NO_FATAL_FAILURE(validateBurstSanitized(preparedModel, requests));
 }
 
 }  // namespace functional