Merge "Disable startNetworkScan tests with parameters." into qt-dev
diff --git a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VmsUtils.h b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VmsUtils.h
index f064367..d689e62 100644
--- a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VmsUtils.h
+++ b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VmsUtils.h
@@ -109,20 +109,13 @@
 
 // An enum to represent the result of parsing START_SESSION message from the VMS service.
 enum VmsSessionStatus {
-    // New server session is received if the new client ID is -1 and the new server ID is not an
-    // invalid ID.
+    // When a new session is received, the client should acknowledge it with the correct
+    // IDs in the START_SESSION message.
     kNewServerSession,
-    // Ack to new client session is received if the new client ID is same as the old one and the new
-    // server ID is not an invalid ID.
-    kAckToNewClientSession,
-    // Error codes:
+    // When an acknowledgement it received, the client can start using the connection.
+    kAckToCurrentSession,
     // Invalid message with either invalid format or unexpected data.
-    kInvalidMessage,
-    // Invalid server ID. New ID should always be greater than or equal to max_of(0, current server
-    // ID)
-    kInvalidServiceId,
-    // Invalid client ID. New ID should always be either -1 or the current client ID.
-    kInvalidClientId
+    kInvalidMessage
 };
 
 // Creates an empty base VMS message with some pre-populated default fields.
@@ -235,7 +228,7 @@
 // Takes a start session message, current service ID, current client ID; and returns the type/status
 // of the message. It also populates the new service ID with the correct value.
 VmsSessionStatus parseStartSessionMessage(const VehiclePropValue& start_session,
-                                          const int service_id, const int client_id,
+                                          const int current_service_id, const int current_client_id,
                                           int* new_service_id);
 
 }  // namespace vms
diff --git a/automotive/vehicle/2.0/default/common/src/VmsUtils.cpp b/automotive/vehicle/2.0/default/common/src/VmsUtils.cpp
index a5fcbaf..d346206 100644
--- a/automotive/vehicle/2.0/default/common/src/VmsUtils.cpp
+++ b/automotive/vehicle/2.0/default/common/src/VmsUtils.cpp
@@ -272,27 +272,28 @@
 }
 
 VmsSessionStatus parseStartSessionMessage(const VehiclePropValue& start_session,
-                                          const int service_id, const int client_id,
+                                          const int current_service_id, const int current_client_id,
                                           int* new_service_id) {
     if (isValidVmsMessage(start_session) &&
         parseMessageType(start_session) == VmsMessageType::START_SESSION &&
         start_session.value.int32Values.size() == kSessionIdsSize + 1) {
         *new_service_id = start_session.value.int32Values[1];
         const int new_client_id = start_session.value.int32Values[2];
-        if (*new_service_id < std::max(0, service_id)) {
-            *new_service_id = service_id;
-            return VmsSessionStatus::kInvalidServiceId;
-        }
-        if (new_client_id == -1) {
+        if (new_client_id != current_client_id) {
+            // If the new_client_id = -1, it means the service has newly started.
+            // But if it is not -1 and is different than the current client ID, then
+            // it means that the service did not have the correct client ID. In
+            // both these cases, the client should acknowledge with a START_SESSION
+            // message containing the correct client ID. So here, the status is returned as
+            // kNewServerSession.
             return VmsSessionStatus::kNewServerSession;
+        } else {
+            // kAckToCurrentSession is returned if the new client ID is same as the current one.
+            return VmsSessionStatus::kAckToCurrentSession;
         }
-        if (new_client_id == client_id) {
-            return VmsSessionStatus::kAckToNewClientSession;
-        }
-        *new_service_id = service_id;
-        return VmsSessionStatus::kInvalidClientId;
     }
-    *new_service_id = service_id;
+    // If the message is invalid then persist the old service ID.
+    *new_service_id = current_service_id;
     return VmsSessionStatus::kInvalidMessage;
 }
 
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
index 39fe991..a46de24 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
@@ -242,6 +242,17 @@
 
     {.config =
          {
+             .prop = toInt(VehicleProperty::VEHICLE_SPEED_DISPLAY_UNITS),
+             .access = VehiclePropertyAccess::READ_WRITE,
+             .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+             .configArray = {(int)VehicleUnit::METER_PER_SEC,
+                             (int)VehicleUnit::MILES_PER_HOUR,
+                             (int)VehicleUnit::KILOMETERS_PER_HOUR},
+         },
+     .initialValue = {.int32Values = {(int)VehicleUnit::KILOMETERS_PER_HOUR}}},
+
+    {.config =
+         {
              .prop = toInt(VehicleProperty::INFO_DRIVER_SEAT),
              .access = VehiclePropertyAccess::READ,
              .changeMode = VehiclePropertyChangeMode::STATIC,
diff --git a/automotive/vehicle/2.0/default/tests/VmsUtils_test.cpp b/automotive/vehicle/2.0/default/tests/VmsUtils_test.cpp
index 3716738..7189212 100644
--- a/automotive/vehicle/2.0/default/tests/VmsUtils_test.cpp
+++ b/automotive/vehicle/2.0/default/tests/VmsUtils_test.cpp
@@ -371,25 +371,25 @@
     int new_service_id;
     message->value.int32Values = hidl_vec<int32_t>{toInt(VmsMessageType::START_SESSION), 123, 456};
     EXPECT_EQ(parseStartSessionMessage(*message, -1, 456, &new_service_id),
-              VmsSessionStatus::kAckToNewClientSession);
+              VmsSessionStatus::kAckToCurrentSession);
     EXPECT_EQ(new_service_id, 123);
 }
 
-TEST(VmsUtilsTest, startSessionClientNewlyStartedWithSameServerId) {
+TEST(VmsUtilsTest, startSessionClientNewlyStartedWithSameServerAndClientId) {
     auto message = createBaseVmsMessage(3);
     int new_service_id;
     message->value.int32Values = hidl_vec<int32_t>{toInt(VmsMessageType::START_SESSION), 123, 456};
     EXPECT_EQ(parseStartSessionMessage(*message, 123, 456, &new_service_id),
-              VmsSessionStatus::kAckToNewClientSession);
+              VmsSessionStatus::kAckToCurrentSession);
     EXPECT_EQ(new_service_id, 123);
 }
 
-TEST(VmsUtilsTest, startSessionClientNewlyStartedEdgeCase) {
+TEST(VmsUtilsTest, startSessionWithZeroAsIds) {
     auto message = createBaseVmsMessage(3);
     int new_service_id;
     message->value.int32Values = hidl_vec<int32_t>{toInt(VmsMessageType::START_SESSION), 0, 0};
     EXPECT_EQ(parseStartSessionMessage(*message, 0, 0, &new_service_id),
-              VmsSessionStatus::kAckToNewClientSession);
+              VmsSessionStatus::kAckToCurrentSession);
     EXPECT_EQ(new_service_id, 0);
 }
 
@@ -398,28 +398,19 @@
     int new_service_id;
     message->value.int32Values = hidl_vec<int32_t>{toInt(VmsMessageType::START_SESSION), 120, 456};
     EXPECT_EQ(parseStartSessionMessage(*message, 123, 456, &new_service_id),
-              VmsSessionStatus::kInvalidServiceId);
-    EXPECT_EQ(new_service_id, 123);
+              VmsSessionStatus::kAckToCurrentSession);
+    EXPECT_EQ(new_service_id, 120);
 }
 
-TEST(VmsUtilsTest, startSessionInvalidServiceIdEdgeCase) {
+TEST(VmsUtilsTest, startSessionNegativeServerId) {
     auto message = createBaseVmsMessage(3);
     int new_service_id;
     message->value.int32Values = hidl_vec<int32_t>{toInt(VmsMessageType::START_SESSION), -1, 456};
     EXPECT_EQ(parseStartSessionMessage(*message, -1, 456, &new_service_id),
-              VmsSessionStatus::kInvalidServiceId);
+              VmsSessionStatus::kAckToCurrentSession);
     EXPECT_EQ(new_service_id, -1);
 }
 
-TEST(VmsUtilsTest, startSessionInvalidClientId) {
-    auto message = createBaseVmsMessage(3);
-    int new_service_id;
-    message->value.int32Values = hidl_vec<int32_t>{toInt(VmsMessageType::START_SESSION), 123, 457};
-    EXPECT_EQ(parseStartSessionMessage(*message, 123, 456, &new_service_id),
-              VmsSessionStatus::kInvalidClientId);
-    EXPECT_EQ(new_service_id, 123);
-}
-
 TEST(VmsUtilsTest, startSessionInvalidMessageFormat) {
     auto message = createBaseVmsMessage(2);
     int new_service_id;
diff --git a/biometrics/face/1.0/vts/functional/VtsHalBiometricsFaceV1_0TargetTest.cpp b/biometrics/face/1.0/vts/functional/VtsHalBiometricsFaceV1_0TargetTest.cpp
index 40961f7..d3d7387 100644
--- a/biometrics/face/1.0/vts/functional/VtsHalBiometricsFaceV1_0TargetTest.cpp
+++ b/biometrics/face/1.0/vts/functional/VtsHalBiometricsFaceV1_0TargetTest.cpp
@@ -14,29 +14,24 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "face_hidl_test"
+#define LOG_TAG "biometrics_face_hidl_hal_test"
 
+#include <android/hardware/biometrics/face/1.0/IBiometricsFace.h>
+#include <android/hardware/biometrics/face/1.0/IBiometricsFaceClientCallback.h>
+
+#include <VtsHalHidlTargetCallbackBase.h>
 #include <VtsHalHidlTargetTestBase.h>
 #include <VtsHalHidlTargetTestEnvBase.h>
 #include <android-base/logging.h>
-#include <android-base/properties.h>
-#include <android/hardware/biometrics/face/1.0/IBiometricsFace.h>
-#include <android/hardware/biometrics/face/1.0/IBiometricsFaceClientCallback.h>
-#include <hidl/HidlSupport.h>
-#include <hidl/HidlTransportSupport.h>
-#include <utils/Condition.h>
 
-#include <cinttypes>
+#include <chrono>
 #include <cstdint>
-#include <future>
-#include <utility>
+#include <random>
 
-using android::Condition;
-using android::Mutex;
 using android::sp;
-using android::base::GetUintProperty;
 using android::hardware::hidl_vec;
 using android::hardware::Return;
+using android::hardware::Void;
 using android::hardware::biometrics::face::V1_0::FaceAcquiredInfo;
 using android::hardware::biometrics::face::V1_0::FaceError;
 using android::hardware::biometrics::face::V1_0::Feature;
@@ -48,263 +43,203 @@
 
 namespace {
 
-const uint32_t kTimeout = 3;
-const std::chrono::seconds kTimeoutInSeconds = std::chrono::seconds(kTimeout);
-const uint32_t kUserId = 99;
-const uint32_t kFaceId = 5;
-const char kTmpDir[] = "/data/system/users/0/facedata";
-const int kIterations = 1000;
+// Arbitrary, nonexistent userId
+constexpr uint32_t kUserId = 9;
+// Arbitrary, nonexistent faceId
+constexpr uint32_t kFaceId = 5;
+constexpr uint32_t kTimeoutSec = 3;
+constexpr auto kTimeout = std::chrono::seconds(kTimeoutSec);
+constexpr int kGenerateChallengeIterations = 10;
+constexpr char kFacedataDir[] = "/data/vendor_de/0/facedata";
+constexpr char kCallbackNameOnEnrollResult[] = "onEnrollResult";
+constexpr char kCallbackNameOnAuthenticated[] = "onAuthenticated";
+constexpr char kCallbackNameOnAcquired[] = "onAcquired";
+constexpr char kCallbackNameOnError[] = "onError";
+constexpr char kCallbackNameOnRemoved[] = "onRemoved";
+constexpr char kCallbackNameOnEnumerate[] = "onEnumerate";
+constexpr char kCallbackNameOnLockoutChanged[] = "onLockoutChanged";
 
-const auto kAssertCallbackIsSet = [](const OptionalUint64& res) {
-    ASSERT_EQ(Status::OK, res.status);
-    // Makes sure the "deviceId" represented by "res.value" is not 0.
-    // 0 would mean the HIDL is not available.
-    ASSERT_NE(0UL, res.value);
+// Callback arguments that need to be captured for the tests.
+struct FaceCallbackArgs {
+    // The error passed to the last onError() callback.
+    FaceError error;
+
+    // The userId passed to the last onRemoved() callback.
+    int32_t userId;
 };
 
-// Wait for a callback to occur (signaled by the given future) up to the
-// provided timeout. If the future is invalid or the callback does not come
-// within the given time, returns false.
-template <class ReturnType>
-bool waitForCallback(std::future<ReturnType> future,
-                     std::chrono::milliseconds timeout = kTimeoutInSeconds) {
-    auto expiration = std::chrono::system_clock::now() + timeout;
-    EXPECT_TRUE(future.valid());
-    if (future.valid()) {
-        std::future_status status = future.wait_until(expiration);
-        EXPECT_NE(std::future_status::timeout, status) << "Timed out waiting for callback";
-        if (status == std::future_status::ready) {
-            return true;
-        }
-    }
-    return false;
-}
-
-// Base callback implementation that just logs all callbacks by default
-class FaceCallbackBase : public IBiometricsFaceClientCallback {
+// Test callback class for the BiometricsFace HAL.
+// The HAL will call these callback methods to notify about completed operations
+// or encountered errors.
+class FaceCallback : public ::testing::VtsHalHidlTargetCallbackBase<FaceCallbackArgs>,
+                     public IBiometricsFaceClientCallback {
   public:
     Return<void> onEnrollResult(uint64_t, uint32_t, int32_t, uint32_t) override {
-        ALOGD("Enroll callback called.");
-        return Return<void>();
+        NotifyFromCallback(kCallbackNameOnEnrollResult);
+        return Void();
     }
 
     Return<void> onAuthenticated(uint64_t, uint32_t, int32_t, const hidl_vec<uint8_t>&) override {
-        ALOGD("Authenticated callback called.");
-        return Return<void>();
+        NotifyFromCallback(kCallbackNameOnAuthenticated);
+        return Void();
     }
 
     Return<void> onAcquired(uint64_t, int32_t, FaceAcquiredInfo, int32_t) override {
-        ALOGD("Acquired callback called.");
-        return Return<void>();
+        NotifyFromCallback(kCallbackNameOnAcquired);
+        return Void();
     }
 
-    Return<void> onError(uint64_t, int32_t, FaceError, int32_t) override {
-        ALOGD("Error callback called.");
-        EXPECT_TRUE(false);  // fail any test that triggers an error
-        return Return<void>();
+    Return<void> onError(uint64_t, int32_t, FaceError error, int32_t) override {
+        FaceCallbackArgs args = {};
+        args.error = error;
+        NotifyFromCallback(kCallbackNameOnError, args);
+        return Void();
     }
 
-    Return<void> onRemoved(uint64_t, const hidl_vec<uint32_t>&, int32_t) override {
-        ALOGD("Removed callback called.");
-        return Return<void>();
+    Return<void> onRemoved(uint64_t, const hidl_vec<uint32_t>&, int32_t userId) override {
+        FaceCallbackArgs args = {};
+        args.userId = userId;
+        NotifyFromCallback(kCallbackNameOnRemoved, args);
+        return Void();
     }
 
-    Return<void> onEnumerate(uint64_t, const hidl_vec<uint32_t>&, int32_t /* userId */) override {
-        ALOGD("Enumerate callback called.");
-        return Return<void>();
+    Return<void> onEnumerate(uint64_t, const hidl_vec<uint32_t>&, int32_t) override {
+        NotifyFromCallback(kCallbackNameOnEnumerate);
+        return Void();
     }
 
     Return<void> onLockoutChanged(uint64_t) override {
-        ALOGD("LockoutChanged callback called.");
-        return Return<void>();
+        NotifyFromCallback(kCallbackNameOnLockoutChanged);
+        return Void();
     }
 };
 
-class EnumerateCallback : public FaceCallbackBase {
-  public:
-    Return<void> onEnumerate(uint64_t, const hidl_vec<uint32_t>&, int32_t) override {
-        promise.set_value();
-        return Return<void>();
-    }
-
-    std::promise<void> promise;
-};
-
-class ErrorCallback : public FaceCallbackBase {
-  public:
-    ErrorCallback(bool filterErrors = false, FaceError errorType = FaceError::HW_UNAVAILABLE)
-        : filterErrors(filterErrors), errorType(errorType), hasError(false) {}
-
-    Return<void> onError(uint64_t, int32_t, FaceError error, int32_t) override {
-        if ((filterErrors && errorType == error) || !filterErrors) {
-            hasError = true;
-            this->error = error;
-            promise.set_value();
-        }
-        return Return<void>();
-    }
-
-    bool filterErrors;
-    FaceError errorType;
-    bool hasError;
-    FaceError error;
-    std::promise<void> promise;
-};
-
-class RemoveCallback : public FaceCallbackBase {
-  public:
-    explicit RemoveCallback(int32_t userId) : removeUserId(userId) {}
-
-    Return<void> onRemoved(uint64_t, const hidl_vec<uint32_t>&, int32_t userId) override {
-        EXPECT_EQ(removeUserId, userId);
-        promise.set_value();
-        return Return<void>();
-    }
-
-    int32_t removeUserId;
-    std::promise<void> promise;
-};
-
-class LockoutChangedCallback : public FaceCallbackBase {
-  public:
-    Return<void> onLockoutChanged(uint64_t duration) override {
-        this->hasDuration = true;
-        this->duration = duration;
-        promise.set_value();
-        return Return<void>();
-    }
-    bool hasDuration;
-    uint64_t duration;
-    std::promise<void> promise;
-};
-
-// Test environment for Face HIDL HAL.
+// Test environment for the BiometricsFace HAL.
 class FaceHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
   public:
-    // get the test environment singleton
+    // Get the test environment singleton.
     static FaceHidlEnvironment* Instance() {
         static FaceHidlEnvironment* instance = new FaceHidlEnvironment;
         return instance;
     }
 
     void registerTestServices() override { registerTestService<IBiometricsFace>(); }
+
+  private:
+    FaceHidlEnvironment() = default;
 };
 
+// Test class for the BiometricsFace HAL.
 class FaceHidlTest : public ::testing::VtsHalHidlTargetTestBase {
   public:
     void SetUp() override {
         mService = ::testing::VtsHalHidlTargetTestBase::getService<IBiometricsFace>(
                 FaceHidlEnvironment::Instance()->getServiceName<IBiometricsFace>());
-        ASSERT_FALSE(mService == nullptr);
-        Return<Status> res = mService->setActiveUser(kUserId, kTmpDir);
-        ASSERT_EQ(Status::OK, static_cast<Status>(res));
+        ASSERT_NE(mService, nullptr);
+        mCallback = new FaceCallback();
+        mCallback->SetWaitTimeoutDefault(kTimeout);
+        Return<void> ret1 = mService->setCallback(mCallback, [](const OptionalUint64& res) {
+            ASSERT_EQ(Status::OK, res.status);
+            // Makes sure the "deviceId" represented by "res.value" is not 0.
+            // 0 would mean the HIDL is not available.
+            ASSERT_NE(0UL, res.value);
+        });
+        ASSERT_TRUE(ret1.isOk());
+        Return<Status> ret2 = mService->setActiveUser(kUserId, kFacedataDir);
+        ASSERT_EQ(Status::OK, static_cast<Status>(ret2));
     }
 
     void TearDown() override {}
 
     sp<IBiometricsFace> mService;
+    sp<FaceCallback> mCallback;
 };
 
-// The service should be reachable.
-TEST_F(FaceHidlTest, ConnectTest) {
-    sp<FaceCallbackBase> cb = new FaceCallbackBase();
-    mService->setCallback(cb, kAssertCallbackIsSet);
-}
-
-// Starting the service with null callback should succeed.
-TEST_F(FaceHidlTest, ConnectNullTest) {
-    mService->setCallback(nullptr, kAssertCallbackIsSet);
-}
-
 // generateChallenge should always return a unique, cryptographically secure,
 // non-zero number.
 TEST_F(FaceHidlTest, GenerateChallengeTest) {
     std::map<uint64_t, int> m;
-    for (int i = 0; i < kIterations; ++i) {
-        mService->generateChallenge(kTimeout, [&m](const OptionalUint64& res) {
-            ASSERT_EQ(Status::OK, res.status);
-            EXPECT_NE(0UL, res.value);
-            m[res.value]++;
-            EXPECT_EQ(1UL, m[res.value]);
-        });
+    for (int i = 0; i < kGenerateChallengeIterations; ++i) {
+        Return<void> ret =
+                mService->generateChallenge(kTimeoutSec, [&m](const OptionalUint64& res) {
+                    ASSERT_EQ(Status::OK, res.status);
+                    EXPECT_NE(0UL, res.value);
+                    m[res.value]++;
+                    EXPECT_EQ(1UL, m[res.value]);
+                });
+        ASSERT_TRUE(ret.isOk());
     }
 }
 
 // enroll with an invalid (all zeroes) HAT should fail.
 TEST_F(FaceHidlTest, EnrollZeroHatTest) {
-    sp<ErrorCallback> cb = new ErrorCallback();
-    mService->setCallback(cb, kAssertCallbackIsSet);
-
+    // Filling HAT with zeros
     hidl_vec<uint8_t> token(69);
     for (size_t i = 0; i < 69; i++) {
         token[i] = 0;
     }
 
-    Return<Status> res = mService->enroll(token, kTimeout, {});
-    ASSERT_EQ(Status::OK, static_cast<Status>(res));
+    Return<Status> ret = mService->enroll(token, kTimeoutSec, {});
+    ASSERT_EQ(Status::OK, static_cast<Status>(ret));
 
-    // At least one call to onError should occur
-    ASSERT_TRUE(waitForCallback(cb->promise.get_future()));
-    ASSERT_TRUE(cb->hasError);
+    // onError should be called with a meaningful (nonzero) error.
+    auto res = mCallback->WaitForCallback(kCallbackNameOnError);
+    EXPECT_TRUE(res.no_timeout);
+    EXPECT_EQ(FaceError::UNABLE_TO_PROCESS, res.args->error);
 }
 
 // enroll with an invalid HAT should fail.
 TEST_F(FaceHidlTest, EnrollGarbageHatTest) {
-    sp<ErrorCallback> cb = new ErrorCallback();
-    mService->setCallback(cb, kAssertCallbackIsSet);
-
-    // Filling HAT with invalid data
+    // Filling HAT with pseudorandom invalid data.
+    // Using default seed to make the test reproducible.
+    std::mt19937 gen(std::mt19937::default_seed);
+    std::uniform_int_distribution<uint8_t> dist;
     hidl_vec<uint8_t> token(69);
     for (size_t i = 0; i < 69; ++i) {
-        token[i] = i;
+        token[i] = dist(gen);
     }
 
-    Return<Status> res = mService->enroll(token, kTimeout, {});
-    ASSERT_EQ(Status::OK, static_cast<Status>(res));
+    Return<Status> ret = mService->enroll(token, kTimeoutSec, {});
+    ASSERT_EQ(Status::OK, static_cast<Status>(ret));
 
-    // At least one call to onError should occur
-    ASSERT_TRUE(waitForCallback(cb->promise.get_future()));
-    ASSERT_TRUE(cb->hasError);
+    // onError should be called with a meaningful (nonzero) error.
+    auto res = mCallback->WaitForCallback(kCallbackNameOnError);
+    EXPECT_TRUE(res.no_timeout);
+    EXPECT_EQ(FaceError::UNABLE_TO_PROCESS, res.args->error);
 }
 
 // setFeature with an invalid (all zeros) HAT should fail.
 TEST_F(FaceHidlTest, SetFeatureZeroHatTest) {
-    sp<ErrorCallback> cb = new ErrorCallback();
-    mService->setCallback(cb, kAssertCallbackIsSet);
-
     hidl_vec<uint8_t> token(69);
     for (size_t i = 0; i < 69; i++) {
         token[i] = 0;
     }
 
-    Return<Status> res = mService->setFeature(Feature::REQUIRE_DIVERSITY, false, token, 0);
-    ASSERT_EQ(Status::ILLEGAL_ARGUMENT, static_cast<Status>(res));
+    Return<Status> ret = mService->setFeature(Feature::REQUIRE_DIVERSITY, false, token, 0);
+    ASSERT_EQ(Status::ILLEGAL_ARGUMENT, static_cast<Status>(ret));
 }
 
 // setFeature with an invalid HAT should fail.
 TEST_F(FaceHidlTest, SetFeatureGarbageHatTest) {
-    sp<ErrorCallback> cb = new ErrorCallback();
-    mService->setCallback(cb, kAssertCallbackIsSet);
-
-    // Filling HAT with invalid data
+    // Filling HAT with pseudorandom invalid data.
+    // Using default seed to make the test reproducible.
+    std::mt19937 gen(std::mt19937::default_seed);
+    std::uniform_int_distribution<uint8_t> dist;
     hidl_vec<uint8_t> token(69);
     for (size_t i = 0; i < 69; ++i) {
-        token[i] = i;
+        token[i] = dist(gen);
     }
 
-    Return<Status> res = mService->setFeature(Feature::REQUIRE_DIVERSITY, false, token, 0);
-    ASSERT_EQ(Status::ILLEGAL_ARGUMENT, static_cast<Status>(res));
+    Return<Status> ret = mService->setFeature(Feature::REQUIRE_DIVERSITY, false, token, 0);
+    ASSERT_EQ(Status::ILLEGAL_ARGUMENT, static_cast<Status>(ret));
 }
 
-void assertGetFeatureFails(sp<IBiometricsFace> service, int faceId, Feature feature) {
-    std::promise<void> promise;
-
+void assertGetFeatureFails(const sp<IBiometricsFace>& service, uint32_t faceId, Feature feature) {
     // Features cannot be retrieved for invalid faces.
-    Return<void> res = service->getFeature(feature, faceId, [&promise](const OptionalBool& result) {
+    Return<void> res = service->getFeature(feature, faceId, [](const OptionalBool& result) {
         ASSERT_EQ(Status::ILLEGAL_ARGUMENT, result.status);
-        promise.set_value();
     });
-    ASSERT_TRUE(waitForCallback(promise.get_future()));
+    ASSERT_TRUE(res.isOk());
 }
 
 TEST_F(FaceHidlTest, GetFeatureRequireAttentionTest) {
@@ -317,111 +252,95 @@
 
 // revokeChallenge should always return within the timeout
 TEST_F(FaceHidlTest, RevokeChallengeTest) {
-    sp<FaceCallbackBase> cb = new FaceCallbackBase();
-    mService->setCallback(cb, kAssertCallbackIsSet);
-
     auto start = std::chrono::system_clock::now();
-    mService->revokeChallenge();
+    Return<Status> ret = mService->revokeChallenge();
     auto elapsed = std::chrono::system_clock::now() - start;
-    ASSERT_GE(kTimeoutInSeconds, elapsed);
+    ASSERT_EQ(Status::OK, static_cast<Status>(ret));
+    ASSERT_GE(kTimeout, elapsed);
 }
 
 // The call to getAuthenticatorId should succeed.
 TEST_F(FaceHidlTest, GetAuthenticatorIdTest) {
-    mService->getAuthenticatorId(
+    Return<void> ret = mService->getAuthenticatorId(
             [](const OptionalUint64& res) { ASSERT_EQ(Status::OK, res.status); });
+    ASSERT_TRUE(ret.isOk());
 }
 
 // The call to enumerate should succeed.
 TEST_F(FaceHidlTest, EnumerateTest) {
-    sp<EnumerateCallback> cb = new EnumerateCallback();
-    mService->setCallback(cb, kAssertCallbackIsSet);
-    Return<Status> res = mService->enumerate();
-    ASSERT_EQ(Status::OK, static_cast<Status>(res));
-    ASSERT_TRUE(waitForCallback(cb->promise.get_future()));
+    Return<Status> ret = mService->enumerate();
+    ASSERT_EQ(Status::OK, static_cast<Status>(ret));
+    auto res = mCallback->WaitForCallback(kCallbackNameOnEnumerate);
+    EXPECT_TRUE(res.no_timeout);
 }
 
 // The call to remove should succeed for any faceId
 TEST_F(FaceHidlTest, RemoveFaceTest) {
-    sp<ErrorCallback> cb = new ErrorCallback();
-    mService->setCallback(cb, kAssertCallbackIsSet);
-
     // Remove a face
-    Return<Status> res = mService->remove(kFaceId);
-    ASSERT_EQ(Status::OK, static_cast<Status>(res));
+    Return<Status> ret = mService->remove(kFaceId);
+    ASSERT_EQ(Status::OK, static_cast<Status>(ret));
 }
 
 // Remove should accept 0 to delete all faces
 TEST_F(FaceHidlTest, RemoveAllFacesTest) {
-    sp<ErrorCallback> cb = new ErrorCallback();
-    mService->setCallback(cb, kAssertCallbackIsSet);
-
     // Remove all faces
-    Return<Status> res = mService->remove(0);
-    ASSERT_EQ(Status::OK, static_cast<Status>(res));
+    Return<Status> ret = mService->remove(0);
+    ASSERT_EQ(Status::OK, static_cast<Status>(ret));
 }
 
 // Active user should successfully set to a writable location.
 TEST_F(FaceHidlTest, SetActiveUserTest) {
     // Create an active user
-    Return<Status> res = mService->setActiveUser(2, kTmpDir);
-    ASSERT_EQ(Status::OK, static_cast<Status>(res));
+    Return<Status> ret = mService->setActiveUser(2, kFacedataDir);
+    ASSERT_EQ(Status::OK, static_cast<Status>(ret));
 
     // Reset active user
-    res = mService->setActiveUser(kUserId, kTmpDir);
-    ASSERT_EQ(Status::OK, static_cast<Status>(res));
+    ret = mService->setActiveUser(kUserId, kFacedataDir);
+    ASSERT_EQ(Status::OK, static_cast<Status>(ret));
 }
 
 // Active user should fail to set to an unwritable location.
 TEST_F(FaceHidlTest, SetActiveUserUnwritableTest) {
     // Create an active user to an unwritable location (device root dir)
-    Return<Status> res = mService->setActiveUser(3, "/");
-    ASSERT_NE(Status::OK, static_cast<Status>(res));
+    Return<Status> ret = mService->setActiveUser(3, "/");
+    ASSERT_NE(Status::OK, static_cast<Status>(ret));
 
     // Reset active user
-    res = mService->setActiveUser(kUserId, kTmpDir);
-    ASSERT_EQ(Status::OK, static_cast<Status>(res));
+    ret = mService->setActiveUser(kUserId, kFacedataDir);
+    ASSERT_EQ(Status::OK, static_cast<Status>(ret));
 }
 
 // Active user should fail to set to a null location.
 TEST_F(FaceHidlTest, SetActiveUserNullTest) {
     // Create an active user to a null location.
-    Return<Status> res = mService->setActiveUser(4, nullptr);
-    ASSERT_NE(Status::OK, static_cast<Status>(res));
+    Return<Status> ret = mService->setActiveUser(4, nullptr);
+    ASSERT_NE(Status::OK, static_cast<Status>(ret));
 
     // Reset active user
-    res = mService->setActiveUser(kUserId, kTmpDir);
-    ASSERT_EQ(Status::OK, static_cast<Status>(res));
+    ret = mService->setActiveUser(kUserId, kFacedataDir);
+    ASSERT_EQ(Status::OK, static_cast<Status>(ret));
 }
 
 // Cancel should always return CANCELED from any starting state including
 // the IDLE state.
 TEST_F(FaceHidlTest, CancelTest) {
-    sp<ErrorCallback> cb = new ErrorCallback(true, FaceError::CANCELED);
-    mService->setCallback(cb, kAssertCallbackIsSet);
-
-    Return<Status> res = mService->cancel();
+    Return<Status> ret = mService->cancel();
     // check that we were able to make an IPC request successfully
-    ASSERT_EQ(Status::OK, static_cast<Status>(res));
-
-    // make sure callback was invoked within kTimeoutInSeconds
-    ASSERT_TRUE(waitForCallback(cb->promise.get_future()));
-    // check error should be CANCELED
-    ASSERT_EQ(FaceError::CANCELED, cb->error);
+    ASSERT_EQ(Status::OK, static_cast<Status>(ret));
+    auto res = mCallback->WaitForCallback(kCallbackNameOnError);
+    // make sure callback was invoked within kRevokeChallengeTimeout
+    EXPECT_TRUE(res.no_timeout);
+    EXPECT_EQ(FaceError::CANCELED, res.args->error);
 }
 
 TEST_F(FaceHidlTest, OnLockoutChangedTest) {
-    sp<LockoutChangedCallback> cb = new LockoutChangedCallback();
-    mService->setCallback(cb, kAssertCallbackIsSet);
-
-    // Update active user and ensure lockout duration 0 is received
-    mService->setActiveUser(5, kTmpDir);
+    // Update active user and ensure onLockoutChanged was called.
+    Return<Status> ret = mService->setActiveUser(kUserId + 1, kFacedataDir);
+    ASSERT_EQ(Status::OK, static_cast<Status>(ret));
 
     // Make sure callback was invoked
-    ASSERT_TRUE(waitForCallback(cb->promise.get_future()));
-
-    // Check that duration 0 was received
-    ASSERT_EQ(0, cb->duration);
+    auto res = mCallback->WaitForCallback(kCallbackNameOnLockoutChanged);
+    EXPECT_TRUE(res.no_timeout);
 }
 
 }  // anonymous namespace
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index c94c825..a5369e7 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -607,7 +607,9 @@
 
     struct DeviceCb : public V3_5::ICameraDeviceCallback {
         DeviceCb(CameraHidlTest *parent, int deviceVersion, const camera_metadata_t *staticMeta) :
-                mParent(parent), mDeviceVersion(deviceVersion), mStaticMetadata(staticMeta) {}
+                mParent(parent), mDeviceVersion(deviceVersion) {
+            mStaticMetadata = staticMeta;
+        }
 
         Return<void> processCaptureResult_3_4(
                 const hidl_vec<V3_4::CaptureResult>& results) override;
@@ -631,7 +633,7 @@
 
         CameraHidlTest *mParent; // Parent object
         int mDeviceVersion;
-        const camera_metadata_t *mStaticMetadata;
+        android::hardware::camera::common::V1_0::helper::CameraMetadata mStaticMetadata;
         bool hasOutstandingBuffersLocked();
 
         /* members for requestStreamBuffers() and returnStreamBuffers()*/
@@ -755,7 +757,8 @@
             uint32_t *partialResultCount /*out*/,
             bool *useHalBufManager /*out*/,
             sp<DeviceCb> *cb /*out*/,
-            uint32_t streamConfigCounter = 0);
+            uint32_t streamConfigCounter = 0,
+            bool allowUnsupport = false);
     void configurePreviewStream(const std::string &name, int32_t deviceVersion,
             sp<ICameraProvider> provider,
             const AvailableStream *previewThreshold,
@@ -1193,18 +1196,20 @@
         // Verify final result metadata
         bool isAtLeast_3_5 = mDeviceVersion >= CAMERA_DEVICE_API_VERSION_3_5;
         if (isAtLeast_3_5) {
+            auto staticMetadataBuffer = mStaticMetadata.getAndLock();
             bool isMonochrome = Status::OK ==
-                    CameraHidlTest::isMonochromeCamera(mStaticMetadata);
+                    CameraHidlTest::isMonochromeCamera(staticMetadataBuffer);
             if (isMonochrome) {
                 mParent->verifyMonochromeCameraResult(request->collectedResult);
             }
 
             // Verify logical camera result metadata
             bool isLogicalCamera =
-                    Status::OK == CameraHidlTest::isLogicalMultiCamera(mStaticMetadata);
+                    Status::OK == CameraHidlTest::isLogicalMultiCamera(staticMetadataBuffer);
             if (isLogicalCamera) {
-                mParent->verifyLogicalCameraResult(mStaticMetadata, request->collectedResult);
+                mParent->verifyLogicalCameraResult(staticMetadataBuffer, request->collectedResult);
             }
+            mStaticMetadata.unlock(staticMetadataBuffer);
         }
     }
 
@@ -4055,7 +4060,7 @@
 
     for (const auto& name : cameraDeviceNames) {
         int deviceVersion = getCameraDeviceVersion(name, mProviderType);
-        if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_4) {
+        if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_5) {
             continue;
         }
         std::string version, deviceId;
@@ -4127,8 +4132,13 @@
         configurePreviewStreams3_4(name, deviceVersion, mProvider, &previewThreshold, physicalIds,
                 &session3_4, &session3_5, &previewStream, &halStreamConfig /*out*/,
                 &supportsPartialResults /*out*/, &partialResultCount /*out*/,
-                &useHalBufManager /*out*/, &cb /*out*/);
-        ASSERT_NE(session3_4, nullptr);
+                &useHalBufManager /*out*/, &cb /*out*/, 0 /*streamConfigCounter*/,
+                true /*allowUnsupport*/);
+        if (session3_5 == nullptr) {
+            ret = session3_4->close();
+            ASSERT_TRUE(ret.isOk());
+            continue;
+        }
 
         std::shared_ptr<ResultMetadataQueue> resultQueue;
         auto resultQueueRet =
@@ -5174,7 +5184,8 @@
         uint32_t *partialResultCount /*out*/,
         bool *useHalBufManager /*out*/,
         sp<DeviceCb> *outCb /*out*/,
-        uint32_t streamConfigCounter) {
+        uint32_t streamConfigCounter,
+        bool allowUnsupport) {
     ASSERT_NE(nullptr, session3_4);
     ASSERT_NE(nullptr, session3_5);
     ASSERT_NE(nullptr, halStreamConfig);
@@ -5273,6 +5284,28 @@
             });
     ASSERT_TRUE(ret.isOk());
 
+    ASSERT_TRUE(!allowUnsupport || deviceVersion == CAMERA_DEVICE_API_VERSION_3_5);
+    if (allowUnsupport) {
+        sp<device::V3_5::ICameraDevice> cameraDevice3_5;
+        castDevice(device3_x, deviceVersion, &cameraDevice3_5);
+
+        bool supported = false;
+        ret = cameraDevice3_5->isStreamCombinationSupported(config3_4,
+                [&supported](Status s, bool combStatus) {
+                    ASSERT_TRUE((Status::OK == s) ||
+                            (Status::METHOD_NOT_SUPPORTED == s));
+                    if (Status::OK == s) {
+                        supported = combStatus;
+                    }
+                });
+        ASSERT_TRUE(ret.isOk());
+        // If stream combination is not supported, return null session.
+        if (!supported) {
+            *session3_5 = nullptr;
+            return;
+        }
+    }
+
     if (*session3_5 != nullptr) {
         config3_5.v3_4 = config3_4;
         config3_5.streamConfigCounter = streamConfigCounter;
@@ -5375,7 +5408,7 @@
         ASSERT_EQ(Status::OK, s);
         staticMeta = clone_camera_metadata(
                 reinterpret_cast<const camera_metadata_t*>(metadata.data()));
-         ASSERT_NE(nullptr, staticMeta);
+        ASSERT_NE(nullptr, staticMeta);
     });
     ASSERT_TRUE(ret.isOk());
 
diff --git a/compatibility_matrices/compatibility_matrix.4.xml b/compatibility_matrices/compatibility_matrix.4.xml
index 7d6fc60..01ec172 100644
--- a/compatibility_matrices/compatibility_matrix.4.xml
+++ b/compatibility_matrices/compatibility_matrix.4.xml
@@ -354,6 +354,10 @@
             <instance>slot2</instance>
             <instance>slot3</instance>
         </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.radio</name>
+        <version>1.2</version>
         <interface>
             <name>ISap</name>
             <instance>slot1</instance>
@@ -361,7 +365,13 @@
     </hal>
     <hal format="hidl" optional="true">
         <name>android.hardware.radio.config</name>
-        <version>1.2</version>
+        <!--
+        Note: Devices launching with target-level 4, if implementing the
+        radio config HAL, must provide an implementation of 1.1 IRadioConfig
+        that can handle version 1.2 of IRadioConfigResponse and
+        IRadioConfigIndication.
+        -->
+        <version>1.1</version>
         <interface>
             <name>IRadioConfig</name>
             <instance>default</instance>
diff --git a/health/storage/1.0/vts/functional/VtsHalHealthStorageV1_0TargetTest.cpp b/health/storage/1.0/vts/functional/VtsHalHealthStorageV1_0TargetTest.cpp
index 946e5f2..2365124 100644
--- a/health/storage/1.0/vts/functional/VtsHalHealthStorageV1_0TargetTest.cpp
+++ b/health/storage/1.0/vts/functional/VtsHalHealthStorageV1_0TargetTest.cpp
@@ -35,6 +35,9 @@
 // Dev GC timeout. This is the timeout used by vold.
 const uint64_t kDevGcTimeoutSec = 120;
 const std::chrono::seconds kDevGcTimeout{kDevGcTimeoutSec};
+// Dev GC timeout tolerance. The HAL may not immediately return after the
+// timeout, so include an acceptable tolerance.
+const std::chrono::seconds kDevGcTolerance{3};
 // Time accounted for RPC calls.
 const std::chrono::milliseconds kRpcTime{1000};
 
@@ -156,8 +159,9 @@
     ASSERT_OK(ret);
 
     // Hold test process because HAL can be single-threaded and doing GC.
-    ASSERT_TRUE(ping(kDevGcTimeout + kRpcTime))
-        << "Service must be available after " << toString(kDevGcTimeout + kRpcTime);
+    ASSERT_TRUE(ping(kDevGcTimeout + kDevGcTolerance + kRpcTime))
+            << "Service must be available after "
+            << toString(kDevGcTimeout + kDevGcTolerance + kRpcTime);
 }
 
 /**
@@ -167,7 +171,7 @@
     sp<GcCallback> cb = new GcCallback();
     auto ret = fs->garbageCollect(kDevGcTimeoutSec, cb);
     ASSERT_OK(ret);
-    cb->waitForResult(kDevGcTimeout + kRpcTime, Result::SUCCESS);
+    cb->waitForResult(kDevGcTimeout + kDevGcTolerance + kRpcTime, Result::SUCCESS);
 }
 
 }  // namespace V1_0
diff --git a/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp b/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp
index a7b6c98..3af1df3 100644
--- a/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp
+++ b/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp
@@ -216,8 +216,8 @@
                     std::chrono::system_clock::now();
             std::chrono::time_point<std::chrono::system_clock> reported_time{
                     std::chrono::milliseconds(sw_enforced[i].f.dateTime)};
-            // The test is flaky for EC keys, so a buffer time of 1 second will be added.
-            EXPECT_LE(creation - 1s, reported_time);
+            // The test is flaky for EC keys, so a buffer time of 120 seconds will be added.
+            EXPECT_LE(creation - 120s, reported_time);
             EXPECT_LE(reported_time, now + 1s);
         }
     }
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 6f75a97..728bf69 100644
--- a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
+++ b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
@@ -309,6 +309,11 @@
     return make_string(a, N);
 }
 
+bool avb_verification_enabled() {
+    char value[PROPERTY_VALUE_MAX];
+    return property_get("ro.boot.vbmeta.device_state", value, "") != 0;
+}
+
 }  // namespace
 
 bool verify_attestation_record(const string& challenge, const string& app_id,
@@ -359,26 +364,32 @@
     EXPECT_EQ(0, memcmp(challenge.data(), att_challenge.data(), challenge.length()));
 
     char property_value[PROPERTY_VALUE_MAX] = {};
-    for (int i = 0; i < att_hw_enforced.size(); i++) {
-        if (att_hw_enforced[i].tag == TAG_BOOT_PATCHLEVEL ||
-            att_hw_enforced[i].tag == TAG_VENDOR_PATCHLEVEL) {
-            std::string date = std::to_string(att_hw_enforced[i].f.integer);
-            // strptime seems to require delimiters, but the tag value will be YYYYMMDD
-            date.insert(6, "-");
-            date.insert(4, "-");
-            EXPECT_EQ(date.size(), 10);
-            struct tm time;
-            strptime(date.c_str(), "%Y-%m-%d", &time);
+    // TODO(b/136282179): When running under VTS-on-GSI the TEE-backed
+    // keymaster implementation will report YYYYMM dates instead of YYYYMMDD
+    // for the BOOT_PATCH_LEVEL.
+    if (avb_verification_enabled()) {
+        for (int i = 0; i < att_hw_enforced.size(); i++) {
+            if (att_hw_enforced[i].tag == TAG_BOOT_PATCHLEVEL ||
+                att_hw_enforced[i].tag == TAG_VENDOR_PATCHLEVEL) {
+                std::string date = std::to_string(att_hw_enforced[i].f.integer);
+                // strptime seems to require delimiters, but the tag value will
+                // be YYYYMMDD
+                date.insert(6, "-");
+                date.insert(4, "-");
+                EXPECT_EQ(date.size(), 10);
+                struct tm time;
+                strptime(date.c_str(), "%Y-%m-%d", &time);
 
-            // Day of the month (0-31)
-            EXPECT_GE(time.tm_mday, 0);
-            EXPECT_LT(time.tm_mday, 32);
-            // Months since Jan (0-11)
-            EXPECT_GE(time.tm_mon, 0);
-            EXPECT_LT(time.tm_mon, 12);
-            // Years since 1900
-            EXPECT_GT(time.tm_year, 110);
-            EXPECT_LT(time.tm_year, 200);
+                // Day of the month (0-31)
+                EXPECT_GE(time.tm_mday, 0);
+                EXPECT_LT(time.tm_mday, 32);
+                // Months since Jan (0-11)
+                EXPECT_GE(time.tm_mon, 0);
+                EXPECT_LT(time.tm_mon, 12);
+                // Years since 1900
+                EXPECT_GT(time.tm_year, 110);
+                EXPECT_LT(time.tm_year, 200);
+            }
         }
     }
 
@@ -410,18 +421,20 @@
                                 &verified_boot_state, &device_locked, &verified_boot_hash);
     EXPECT_EQ(ErrorCode::OK, error);
 
-    property_get("ro.boot.vbmeta.digest", property_value, "nogood");
-    EXPECT_NE(strcmp(property_value, "nogood"), 0);
-    string prop_string(property_value);
-    EXPECT_EQ(prop_string.size(), 64);
-    EXPECT_EQ(prop_string, bin2hex(verified_boot_hash));
+    if (avb_verification_enabled()) {
+        property_get("ro.boot.vbmeta.digest", property_value, "nogood");
+        EXPECT_NE(strcmp(property_value, "nogood"), 0);
+        string prop_string(property_value);
+        EXPECT_EQ(prop_string.size(), 64);
+        EXPECT_EQ(prop_string, bin2hex(verified_boot_hash));
 
-    property_get("ro.boot.vbmeta.device_state", property_value, "nogood");
-    EXPECT_NE(property_value, "nogood");
-    if (!strcmp(property_value, "unlocked")) {
-        EXPECT_FALSE(device_locked);
-    } else {
-        EXPECT_TRUE(device_locked);
+        property_get("ro.boot.vbmeta.device_state", property_value, "nogood");
+        EXPECT_NE(strcmp(property_value, "nogood"), 0);
+        if (!strcmp(property_value, "unlocked")) {
+            EXPECT_FALSE(device_locked);
+        } else {
+            EXPECT_TRUE(device_locked);
+        }
     }
 
     // Verified boot key should be all 0's if the boot state is not verified or self signed
diff --git a/media/omx/1.0/vts/functional/common/Android.bp b/media/omx/1.0/vts/functional/common/Android.bp
index cdc52fb..5a79e55 100644
--- a/media/omx/1.0/vts/functional/common/Android.bp
+++ b/media/omx/1.0/vts/functional/common/Android.bp
@@ -29,6 +29,21 @@
         "[email protected]",
         "[email protected]",
         "[email protected]",
+        "[email protected]",
+        "[email protected]",
+        "[email protected]",
+        "[email protected]",
+        "[email protected]",
+        "[email protected]",
+    ],
+    export_static_lib_headers: [
+        "[email protected]",
+        "[email protected]",
+        "[email protected]",
+        "[email protected]",
+        "[email protected]",
+        "[email protected]",
+        "[email protected]",
     ],
 }
 
@@ -40,7 +55,12 @@
     static_libs: [
         "VtsHalMediaOmxV1_0CommonUtil",
         "[email protected]",
+        "[email protected]",
+        "[email protected]",
+        "[email protected]",
+        "[email protected]",
         "[email protected]",
+        "[email protected]",
         "[email protected]",
         "[email protected]",
         "[email protected]",
diff --git a/media/omx/1.0/vts/functional/common/media_hidl_test_common.cpp b/media/omx/1.0/vts/functional/common/media_hidl_test_common.cpp
index f299e36..8d4c022 100644
--- a/media/omx/1.0/vts/functional/common/media_hidl_test_common.cpp
+++ b/media/omx/1.0/vts/functional/common/media_hidl_test_common.cpp
@@ -22,8 +22,11 @@
 #include <android-base/logging.h>
 
 #include <android/hardware/graphics/allocator/2.0/IAllocator.h>
+#include <android/hardware/graphics/allocator/3.0/IAllocator.h>
 #include <android/hardware/graphics/mapper/2.0/IMapper.h>
 #include <android/hardware/graphics/mapper/2.0/types.h>
+#include <android/hardware/graphics/mapper/3.0/IMapper.h>
+#include <android/hardware/graphics/mapper/3.0/types.h>
 #include <android/hardware/media/omx/1.0/IOmx.h>
 #include <android/hardware/media/omx/1.0/IOmxNode.h>
 #include <android/hardware/media/omx/1.0/IOmxObserver.h>
@@ -31,7 +34,9 @@
 #include <android/hidl/allocator/1.0/IAllocator.h>
 #include <android/hidl/memory/1.0/IMapper.h>
 #include <android/hidl/memory/1.0/IMemory.h>
-#include <cutils/atomic.h>
+
+#include <atomic>
+#include <variant>
 
 using ::android::hardware::graphics::common::V1_0::BufferUsage;
 using ::android::hardware::graphics::common::V1_0::PixelFormat;
@@ -195,67 +200,104 @@
                             BufferInfo* buffer, uint32_t nFrameWidth,
                             uint32_t nFrameHeight, int32_t* nStride,
                             int format) {
-    android::hardware::media::omx::V1_0::Status status;
-    sp<android::hardware::graphics::allocator::V2_0::IAllocator> allocator =
-        android::hardware::graphics::allocator::V2_0::IAllocator::getService();
-    ASSERT_NE(nullptr, allocator.get());
+    struct AllocatorV2 : public GrallocV2 {
+        sp<IAllocator> mAllocator;
+        sp<IMapper> mMapper;
+        AllocatorV2(sp<IAllocator>&& allocator, sp<IMapper>&& mapper)
+              : mAllocator{std::move(allocator)}, mMapper{std::move(mapper)} {}
+        AllocatorV2() = default;
+    };
+    struct AllocatorV3 : public GrallocV3 {
+        sp<IAllocator> mAllocator;
+        sp<IMapper> mMapper;
+        AllocatorV3(sp<IAllocator>&& allocator, sp<IMapper>&& mapper)
+              : mAllocator{std::move(allocator)}, mMapper{std::move(mapper)} {}
+        AllocatorV3() = default;
+    };
+    std::variant<AllocatorV2, AllocatorV3> grallocVar;
 
-    sp<android::hardware::graphics::mapper::V2_0::IMapper> mapper =
-        android::hardware::graphics::mapper::V2_0::IMapper::getService();
-    ASSERT_NE(mapper.get(), nullptr);
+    sp<android::hardware::graphics::mapper::V2_0::IMapper> mapper2{};
+    sp<android::hardware::graphics::mapper::V3_0::IMapper> mapper3{};
+    sp<android::hardware::graphics::allocator::V2_0::IAllocator> allocator2{};
+    sp<android::hardware::graphics::allocator::V3_0::IAllocator> allocator3 =
+        android::hardware::graphics::allocator::V3_0::IAllocator::getService();
+    if (allocator3) {
+        mapper3 =
+            android::hardware::graphics::mapper::V3_0::IMapper::getService();
+        ASSERT_NE(nullptr, mapper3.get());
+        grallocVar.emplace<AllocatorV3>(std::move(allocator3), std::move(mapper3));
+    } else {
+        allocator2 =
+            android::hardware::graphics::allocator::V2_0::IAllocator::getService();
+        ASSERT_NE(nullptr, allocator2.get());
+        mapper2 =
+            android::hardware::graphics::mapper::V2_0::IMapper::getService();
+        ASSERT_NE(nullptr, allocator2.get());
+        grallocVar.emplace<AllocatorV2>(std::move(allocator2), std::move(mapper2));
+    }
 
-    android::hardware::graphics::mapper::V2_0::IMapper::BufferDescriptorInfo
-        descriptorInfo;
-    uint32_t usage;
-
-    descriptorInfo.width = nFrameWidth;
-    descriptorInfo.height = nFrameHeight;
-    descriptorInfo.layerCount = 1;
-    descriptorInfo.format = static_cast<PixelFormat>(format);
-    descriptorInfo.usage = static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN);
-    omxNode->getGraphicBufferUsage(
+    android::hardware::media::omx::V1_0::Status status{};
+    uint64_t usage{};
+    ASSERT_TRUE(omxNode->getGraphicBufferUsage(
         portIndex,
         [&status, &usage](android::hardware::media::omx::V1_0::Status _s,
                           uint32_t _n1) {
             status = _s;
             usage = _n1;
-        });
-    if (status == android::hardware::media::omx::V1_0::Status::OK) {
-        descriptorInfo.usage |= usage;
-    }
+        }).isOk());
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
 
-    ::android::hardware::hidl_vec<uint32_t> descriptor;
-    android::hardware::graphics::mapper::V2_0::Error error;
-    mapper->createDescriptor(
-        descriptorInfo, [&error, &descriptor](
-                            android::hardware::graphics::mapper::V2_0::Error _s,
-                            ::android::hardware::hidl_vec<uint32_t> _n1) {
-            error = _s;
-            descriptor = _n1;
-        });
-    ASSERT_EQ(error, android::hardware::graphics::mapper::V2_0::Error::NONE);
+    static std::atomic_int32_t bufferIdCounter{0};
 
-    static volatile int32_t nextId = 0;
-    uint64_t id = static_cast<uint64_t>(getpid()) << 32;
-    allocator->allocate(
-        descriptor, 1,
-        [&](android::hardware::graphics::mapper::V2_0::Error _s, uint32_t _n1,
-            const ::android::hardware::hidl_vec<
-                ::android::hardware::hidl_handle>& _n2) {
-            ASSERT_EQ(android::hardware::graphics::mapper::V2_0::Error::NONE,
-                      _s);
-            *nStride = _n1;
-            buffer->omxBuffer.nativeHandle = _n2[0];
-            buffer->omxBuffer.attr.anwBuffer.width = nFrameWidth;
-            buffer->omxBuffer.attr.anwBuffer.height = nFrameHeight;
-            buffer->omxBuffer.attr.anwBuffer.stride = _n1;
-            buffer->omxBuffer.attr.anwBuffer.format = descriptorInfo.format;
-            buffer->omxBuffer.attr.anwBuffer.usage = descriptorInfo.usage;
-            buffer->omxBuffer.attr.anwBuffer.layerCount =
-                descriptorInfo.layerCount;
-            buffer->omxBuffer.attr.anwBuffer.id =
-                id | static_cast<uint32_t>(android_atomic_inc(&nextId));
-        });
+    std::visit([buffer, nFrameWidth, nFrameHeight, format, usage, nStride](auto&& gralloc) {
+            using Gralloc = std::remove_reference_t<decltype(gralloc)>;
+            using Descriptor = typename Gralloc::Descriptor;
+            using DescriptorInfo = typename Gralloc::DescriptorInfo;
+            using Error = typename Gralloc::Error;
+            using Format = typename Gralloc::Format;
+            using Usage = typename Gralloc::Usage;
+
+            Error error{};
+            Descriptor descriptor{};
+
+            DescriptorInfo descriptorInfo{};
+            descriptorInfo.width = nFrameWidth;
+            descriptorInfo.height = nFrameHeight;
+            descriptorInfo.layerCount = 1;
+            descriptorInfo.format = static_cast<Format>(format);
+            descriptorInfo.usage = usage | Usage(BufferUsage::CPU_READ_OFTEN);
+
+            gralloc.mMapper->createDescriptor(descriptorInfo,
+                    [&error, &descriptor](
+                        Error _s,
+                        const Descriptor& _n1) {
+                    error = _s;
+                    descriptor = _n1;
+                });
+            ASSERT_EQ(error, Error::NONE);
+
+            gralloc.mAllocator->allocate(
+                descriptor, 1,
+                [&](Error _s, uint32_t _n1,
+                    const ::android::hardware::hidl_vec<
+                        ::android::hardware::hidl_handle>& _n2) {
+                    ASSERT_EQ(Error::NONE, _s);
+                    *nStride = _n1;
+                    buffer->omxBuffer.nativeHandle = _n2[0];
+                    buffer->omxBuffer.attr.anwBuffer.width = nFrameWidth;
+                    buffer->omxBuffer.attr.anwBuffer.height = nFrameHeight;
+                    buffer->omxBuffer.attr.anwBuffer.stride = _n1;
+                    buffer->omxBuffer.attr.anwBuffer.format =
+                        static_cast<PixelFormat>(descriptorInfo.format);
+                    buffer->omxBuffer.attr.anwBuffer.usage =
+                        static_cast<uint32_t>(descriptorInfo.usage);
+                    buffer->omxBuffer.attr.anwBuffer.layerCount =
+                        descriptorInfo.layerCount;
+                    buffer->omxBuffer.attr.anwBuffer.id =
+                        (static_cast<uint64_t>(getpid()) << 32) |
+                        bufferIdCounter.fetch_add(1, std::memory_order_relaxed);
+                });
+        }, grallocVar);
 }
 
 // allocate buffers needed on a component port
diff --git a/media/omx/1.0/vts/functional/common/media_hidl_test_common.h b/media/omx/1.0/vts/functional/common/media_hidl_test_common.h
index 1575ba2..08af26b 100644
--- a/media/omx/1.0/vts/functional/common/media_hidl_test_common.h
+++ b/media/omx/1.0/vts/functional/common/media_hidl_test_common.h
@@ -22,6 +22,16 @@
 #endif
 
 #include <getopt.h>
+
+#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
+#include <android/hardware/graphics/allocator/3.0/IAllocator.h>
+#include <android/hardware/graphics/common/1.0/types.h>
+#include <android/hardware/graphics/common/1.1/types.h>
+#include <android/hardware/graphics/common/1.2/types.h>
+#include <android/hardware/graphics/mapper/2.0/IMapper.h>
+#include <android/hardware/graphics/mapper/2.0/types.h>
+#include <android/hardware/graphics/mapper/3.0/IMapper.h>
+#include <android/hardware/graphics/mapper/3.0/types.h>
 #include <media/stagefright/foundation/ALooper.h>
 #include <utils/Condition.h>
 #include <utils/List.h>
@@ -288,6 +298,36 @@
 /*
  * common functions declarations
  */
+struct GrallocV2 {
+    using Format = android::hardware::graphics::common::V1_0::PixelFormat;
+    using Usage = android::hardware::hidl_bitfield<
+            android::hardware::graphics::common::V1_0::BufferUsage>;
+
+    using IAllocator = android::hardware::graphics::allocator::V2_0::IAllocator;
+
+    using IMapper = android::hardware::graphics::mapper::V2_0::IMapper;
+    using Error = android::hardware::graphics::mapper::V2_0::Error;
+    using Descriptor = android::hardware::graphics::mapper::V2_0::BufferDescriptor;
+    using YCbCrLayout = android::hardware::graphics::mapper::V2_0::YCbCrLayout;
+    using DescriptorInfo = IMapper::BufferDescriptorInfo;
+    using Rect = IMapper::Rect;
+};
+
+struct GrallocV3 {
+    using Format = android::hardware::graphics::common::V1_2::PixelFormat;
+    using Usage = android::hardware::hidl_bitfield<
+            android::hardware::graphics::common::V1_2::BufferUsage>;
+
+    using IAllocator = android::hardware::graphics::allocator::V3_0::IAllocator;
+
+    using IMapper = android::hardware::graphics::mapper::V3_0::IMapper;
+    using Error = android::hardware::graphics::mapper::V3_0::Error;
+    using Descriptor = android::hardware::graphics::mapper::V3_0::BufferDescriptor;
+    using YCbCrLayout = android::hardware::graphics::mapper::V3_0::YCbCrLayout;
+    using DescriptorInfo = IMapper::BufferDescriptorInfo;
+    using Rect = IMapper::Rect;
+};
+
 Return<android::hardware::media::omx::V1_0::Status> setRole(
     sp<IOmxNode> omxNode, const char* role);
 
diff --git a/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoEncTest.cpp b/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoEncTest.cpp
index a740a80..2280cee 100644
--- a/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoEncTest.cpp
+++ b/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoEncTest.cpp
@@ -63,6 +63,7 @@
 #include <media_video_hidl_test_common.h>
 #include <system/window.h>
 #include <fstream>
+#include <variant>
 
 static ComponentTestEnvironment* gEnv = nullptr;
 
@@ -364,6 +365,61 @@
     return Void();
 };
 
+// Variant of mappers
+struct MapperV2 : public GrallocV2 {
+    sp<IMapper> mMapper;
+    MapperV2(sp<IMapper>&& mapper): mMapper{std::move(mapper)} {}
+    MapperV2() = default;
+    android::hardware::Return<void> lock(
+            void* buffer,
+            Usage usage,
+            const Rect& rect,
+            const android::hardware::hidl_handle& handle,
+            Error* error,
+            void** data) {
+        return mMapper->lock(buffer, usage, rect, handle,
+                             [error, data](Error e, void* d) {
+                                *error = e;
+                                *data = d;
+                             });
+    }
+};
+struct MapperV3 : public GrallocV3 {
+    sp<IMapper> mMapper;
+    MapperV3(sp<IMapper>&& mapper): mMapper{std::move(mapper)} {}
+    MapperV3() = default;
+    android::hardware::Return<void> lock(
+            void* buffer,
+            Usage usage,
+            const Rect& rect,
+            const android::hardware::hidl_handle& handle,
+            Error* error,
+            void** data) {
+        return mMapper->lock(buffer, usage, rect, handle,
+                             [error, data](Error e, void* d, int32_t, int32_t) {
+                                *error = e;
+                                *data = d;
+                             });
+    }
+};
+using MapperVar = std::variant<MapperV2, MapperV3>;
+// Initializes the MapperVar by trying services of different versions.
+bool initialize(MapperVar& mapperVar) {
+    sp<android::hardware::graphics::mapper::V3_0::IMapper> mapper3 =
+        android::hardware::graphics::mapper::V3_0::IMapper::getService();
+    if (mapper3) {
+        mapperVar.emplace<MapperV3>(std::move(mapper3));
+        return true;
+    }
+    sp<android::hardware::graphics::mapper::V2_0::IMapper> mapper2 =
+        android::hardware::graphics::mapper::V2_0::IMapper::getService();
+    if (mapper2) {
+        mapperVar.emplace<MapperV2>(std::move(mapper2));
+        return true;
+    }
+    return false;
+}
+
 // request VOP refresh
 void requestIDR(sp<IOmxNode> omxNode, OMX_U32 portIndex) {
     android::hardware::media::omx::V1_0::Status status;
@@ -574,150 +630,166 @@
 
 int colorFormatConversion(BufferInfo* buffer, void* buff, PixelFormat format,
                           std::ifstream& eleStream) {
-    sp<android::hardware::graphics::mapper::V2_0::IMapper> mapper =
-        android::hardware::graphics::mapper::V2_0::IMapper::getService();
-    EXPECT_NE(mapper.get(), nullptr);
-    if (mapper.get() == nullptr) return 1;
-
-    android::hardware::hidl_handle fence;
-    android::hardware::graphics::mapper::V2_0::IMapper::Rect rect;
-    android::hardware::graphics::mapper::V2_0::YCbCrLayout ycbcrLayout;
-    android::hardware::graphics::mapper::V2_0::Error error;
-    rect.left = 0;
-    rect.top = 0;
-    rect.width = buffer->omxBuffer.attr.anwBuffer.width;
-    rect.height = buffer->omxBuffer.attr.anwBuffer.height;
-
-    if (format == PixelFormat::YV12 || format == PixelFormat::YCRCB_420_SP ||
-        format == PixelFormat::YCBCR_420_888) {
-        mapper->lockYCbCr(
-            buff, buffer->omxBuffer.attr.anwBuffer.usage, rect, fence,
-            [&](android::hardware::graphics::mapper::V2_0::Error _e,
-                android::hardware::graphics::mapper::V2_0::YCbCrLayout _n1) {
-                error = _e;
-                ycbcrLayout = _n1;
-            });
-        EXPECT_EQ(error,
-                  android::hardware::graphics::mapper::V2_0::Error::NONE);
-        if (error != android::hardware::graphics::mapper::V2_0::Error::NONE)
-            return 1;
-
-        int size = ((rect.width * rect.height * 3) >> 1);
-        char* img = new char[size];
-        if (img == nullptr) return 1;
-        eleStream.read(img, size);
-        if (eleStream.gcount() != size) {
-            delete[] img;
-            return 1;
-        }
-
-        char* imgTmp = img;
-        char* ipBuffer = static_cast<char*>(ycbcrLayout.y);
-        for (size_t y = rect.height; y > 0; --y) {
-            memcpy(ipBuffer, imgTmp, rect.width);
-            ipBuffer += ycbcrLayout.yStride;
-            imgTmp += rect.width;
-        }
-
-        if (format == PixelFormat::YV12)
-            EXPECT_EQ(ycbcrLayout.chromaStep, 1U);
-        else if (format == PixelFormat::YCRCB_420_SP)
-            EXPECT_EQ(ycbcrLayout.chromaStep, 2U);
-
-        ipBuffer = static_cast<char*>(ycbcrLayout.cb);
-        for (size_t y = rect.height >> 1; y > 0; --y) {
-            for (int32_t x = 0; x < (rect.width >> 1); ++x) {
-                ipBuffer[ycbcrLayout.chromaStep * x] = *imgTmp++;
-            }
-            ipBuffer += ycbcrLayout.cStride;
-        }
-        ipBuffer = static_cast<char*>(ycbcrLayout.cr);
-        for (size_t y = rect.height >> 1; y > 0; --y) {
-            for (int32_t x = 0; x < (rect.width >> 1); ++x) {
-                ipBuffer[ycbcrLayout.chromaStep * x] = *imgTmp++;
-            }
-            ipBuffer += ycbcrLayout.cStride;
-        }
-
-        delete[] img;
-
-        mapper->unlock(buff,
-                       [&](android::hardware::graphics::mapper::V2_0::Error _e,
-                           android::hardware::hidl_handle _n1) {
-                           error = _e;
-                           fence = _n1;
-                       });
-        EXPECT_EQ(error,
-                  android::hardware::graphics::mapper::V2_0::Error::NONE);
-        if (error != android::hardware::graphics::mapper::V2_0::Error::NONE)
-            return 1;
-    } else {
-        void* data;
-        mapper->lock(buff, buffer->omxBuffer.attr.anwBuffer.usage, rect, fence,
-                     [&](android::hardware::graphics::mapper::V2_0::Error _e,
-                         void* _n1) {
-                         error = _e;
-                         data = _n1;
-                     });
-        EXPECT_EQ(error,
-                  android::hardware::graphics::mapper::V2_0::Error::NONE);
-        if (error != android::hardware::graphics::mapper::V2_0::Error::NONE)
-            return 1;
-
-        if (format == PixelFormat::BGRA_8888) {
-            char* ipBuffer = static_cast<char*>(data);
-            for (size_t y = rect.height; y > 0; --y) {
-                eleStream.read(ipBuffer, rect.width * 4);
-                if (eleStream.gcount() != rect.width * 4) return 1;
-                ipBuffer += buffer->omxBuffer.attr.anwBuffer.stride * 4;
-            }
-        } else {
-            EXPECT_TRUE(false) << "un expected pixel format";
-            return 1;
-        }
-
-        mapper->unlock(buff,
-                       [&](android::hardware::graphics::mapper::V2_0::Error _e,
-                           android::hardware::hidl_handle _n1) {
-                           error = _e;
-                           fence = _n1;
-                       });
-        EXPECT_EQ(error,
-                  android::hardware::graphics::mapper::V2_0::Error::NONE);
-        if (error != android::hardware::graphics::mapper::V2_0::Error::NONE)
-            return 1;
+    MapperVar mapperVar;
+    if (!initialize(mapperVar)) {
+        EXPECT_TRUE(false) << "failed to obtain mapper service";
+        return 1;
     }
 
-    return 0;
+    return std::visit([buffer, buff, format, &eleStream](auto&& mapper) -> int {
+            using Gralloc = std::remove_reference_t<decltype(mapper)>;
+            using Error = typename Gralloc::Error;
+            using Rect = typename Gralloc::Rect;
+            using Usage = typename Gralloc::Usage;
+            using YCbCrLayout = typename Gralloc::YCbCrLayout;
+
+            android::hardware::hidl_handle fence;
+            Rect rect;
+            YCbCrLayout ycbcrLayout;
+            Error error;
+            rect.left = 0;
+            rect.top = 0;
+            rect.width = buffer->omxBuffer.attr.anwBuffer.width;
+            rect.height = buffer->omxBuffer.attr.anwBuffer.height;
+
+            if (format == PixelFormat::YV12 || format == PixelFormat::YCRCB_420_SP ||
+                format == PixelFormat::YCBCR_420_888) {
+                mapper.mMapper->lockYCbCr(
+                        buff,
+                        static_cast<Usage>(
+                            buffer->omxBuffer.attr.anwBuffer.usage),
+                        rect,
+                        fence,
+                        [&](Error _e,
+                            const YCbCrLayout& _n1) {
+                            error = _e;
+                            ycbcrLayout = _n1;
+                        });
+                EXPECT_EQ(error, Error::NONE);
+                if (error != Error::NONE)
+                    return 1;
+
+                int size = ((rect.width * rect.height * 3) >> 1);
+                char* img = new char[size];
+                if (img == nullptr) return 1;
+                eleStream.read(img, size);
+                if (eleStream.gcount() != size) {
+                    delete[] img;
+                    return 1;
+                }
+
+                char* imgTmp = img;
+                char* ipBuffer = static_cast<char*>(ycbcrLayout.y);
+                for (size_t y = rect.height; y > 0; --y) {
+                    memcpy(ipBuffer, imgTmp, rect.width);
+                    ipBuffer += ycbcrLayout.yStride;
+                    imgTmp += rect.width;
+                }
+
+                if (format == PixelFormat::YV12)
+                    EXPECT_EQ(ycbcrLayout.chromaStep, 1U);
+                else if (format == PixelFormat::YCRCB_420_SP)
+                    EXPECT_EQ(ycbcrLayout.chromaStep, 2U);
+
+                ipBuffer = static_cast<char*>(ycbcrLayout.cb);
+                for (size_t y = rect.height >> 1; y > 0; --y) {
+                    for (int32_t x = 0; x < (rect.width >> 1); ++x) {
+                        ipBuffer[ycbcrLayout.chromaStep * x] = *imgTmp++;
+                    }
+                    ipBuffer += ycbcrLayout.cStride;
+                }
+                ipBuffer = static_cast<char*>(ycbcrLayout.cr);
+                for (size_t y = rect.height >> 1; y > 0; --y) {
+                    for (int32_t x = 0; x < (rect.width >> 1); ++x) {
+                        ipBuffer[ycbcrLayout.chromaStep * x] = *imgTmp++;
+                    }
+                    ipBuffer += ycbcrLayout.cStride;
+                }
+
+                delete[] img;
+
+                mapper.mMapper->unlock(buff,
+                               [&](Error _e,
+                                   const android::hardware::hidl_handle& _n1) {
+                                   error = _e;
+                                   fence = _n1;
+                               });
+                EXPECT_EQ(error, Error::NONE);
+                if (error != Error::NONE)
+                    return 1;
+            } else {
+                void* data;
+                mapper.lock(
+                        buff,
+                        buffer->omxBuffer.attr.anwBuffer.usage,
+                        rect,
+                        fence,
+                        &error,
+                        &data);
+                EXPECT_EQ(error, Error::NONE);
+                if (error != Error::NONE)
+                    return 1;
+
+                if (format == PixelFormat::BGRA_8888) {
+                    char* ipBuffer = static_cast<char*>(data);
+                    for (size_t y = rect.height; y > 0; --y) {
+                        eleStream.read(ipBuffer, rect.width * 4);
+                        if (eleStream.gcount() != rect.width * 4) return 1;
+                        ipBuffer += buffer->omxBuffer.attr.anwBuffer.stride * 4;
+                    }
+                } else {
+                    EXPECT_TRUE(false) << "un expected pixel format";
+                    return 1;
+                }
+
+                mapper.mMapper->unlock(
+                        buff,
+                        [&](Error _e, const android::hardware::hidl_handle& _n1) {
+                            error = _e;
+                            fence = _n1;
+                        });
+                EXPECT_EQ(error, Error::NONE);
+                if (error != Error::NONE)
+                    return 1;
+            }
+
+            return 0;
+        }, mapperVar);
 }
 
 int fillGraphicBuffer(BufferInfo* buffer, PixelFormat format,
                       std::ifstream& eleStream) {
-    sp<android::hardware::graphics::mapper::V2_0::IMapper> mapper =
-        android::hardware::graphics::mapper::V2_0::IMapper::getService();
-    EXPECT_NE(mapper.get(), nullptr);
-    if (mapper.get() == nullptr) return 1;
-
-    void* buff = nullptr;
-    android::hardware::graphics::mapper::V2_0::Error error;
-    mapper->importBuffer(
-        buffer->omxBuffer.nativeHandle,
-        [&](android::hardware::graphics::mapper::V2_0::Error _e, void* _n1) {
-            error = _e;
-            buff = _n1;
-        });
-    EXPECT_EQ(error, android::hardware::graphics::mapper::V2_0::Error::NONE);
-    if (error != android::hardware::graphics::mapper::V2_0::Error::NONE)
+    MapperVar mapperVar;
+    if (!initialize(mapperVar)) {
+        EXPECT_TRUE(false) << "failed to obtain mapper service";
         return 1;
+    }
 
-    if (colorFormatConversion(buffer, buff, format, eleStream)) return 1;
+    return std::visit([buffer, format, &eleStream](auto&& mapper) -> int {
+            using Gralloc = std::remove_reference_t<decltype(mapper)>;
+            using Error = typename Gralloc::Error;
 
-    error = mapper->freeBuffer(buff);
-    EXPECT_EQ(error, android::hardware::graphics::mapper::V2_0::Error::NONE);
-    if (error != android::hardware::graphics::mapper::V2_0::Error::NONE)
-        return 1;
+            void* buff = nullptr;
+            Error error;
+            mapper.mMapper->importBuffer(
+                buffer->omxBuffer.nativeHandle,
+                [&](Error _e, void* _n1) {
+                    error = _e;
+                    buff = _n1;
+                });
+            EXPECT_EQ(error, Error::NONE);
+            if (error != Error::NONE)
+                return 1;
 
-    return 0;
+            if (colorFormatConversion(buffer, buff, format, eleStream)) return 1;
+
+            error = mapper.mMapper->freeBuffer(buff);
+            EXPECT_EQ(error, Error::NONE);
+            if (error != Error::NONE)
+                return 1;
+
+            return 0;
+        }, mapperVar);
 }
 
 int dispatchGraphicBuffer(sp<IOmxNode> omxNode,
diff --git a/radio/1.2/vts/functional/radio_hidl_hal_test.cpp b/radio/1.2/vts/functional/radio_hidl_hal_test.cpp
index bff7481..6b84810 100644
--- a/radio/1.2/vts/functional/radio_hidl_hal_test.cpp
+++ b/radio/1.2/vts/functional/radio_hidl_hal_test.cpp
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-#include <android/hardware/radio/1.1/IRadio.h>
 #include <radio_hidl_hal_utils_v1_2.h>
 
 void RadioHidlTest_v1_2::SetUp() {
@@ -88,25 +87,7 @@
 }
 
 void RadioHidlTest_v1_2::stopNetworkScan() {
-    sp<::android::hardware::radio::V1_1::IRadio> radio_v1_1;
-
-    radio_v1_1 = ::testing::VtsHalHidlTargetTestBase::getService<
-            ::android::hardware::radio::V1_1::IRadio>(
-            RadioHidlEnvironment::Instance()
-                    ->getServiceName<::android::hardware::radio::V1_1::IRadio>(
-                            hidl_string(RADIO_SERVICE_NAME)));
-    if (radio_v1_1 == NULL) {
-        sleep(60);
-        radio_v1_1 = ::testing::VtsHalHidlTargetTestBase::getService<
-                ::android::hardware::radio::V1_1::IRadio>(
-                RadioHidlEnvironment::Instance()
-                        ->getServiceName<::android::hardware::radio::V1_1::IRadio>(
-                                hidl_string(RADIO_SERVICE_NAME)));
-    }
-    ASSERT_NE(nullptr, radio_v1_1.get());
-
     serial = GetRandomSerialNumber();
-
-    radio_v1_1->stopNetworkScan(serial);
+    radio_v1_2->stopNetworkScan(serial);
     EXPECT_EQ(std::cv_status::no_timeout, wait());
 }
diff --git a/radio/1.4/vts/functional/radio_hidl_hal_api.cpp b/radio/1.4/vts/functional/radio_hidl_hal_api.cpp
index a05f0a7..0fcd32d 100644
--- a/radio/1.4/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.4/vts/functional/radio_hidl_hal_api.cpp
@@ -41,6 +41,12 @@
 
     ALOGI("emergencyDial, rspInfo.error = %s\n", toString(radioRsp_v1_4->rspInfo.error).c_str());
     EXPECT_EQ(RadioError::NONE, radioRsp_v1_4->rspInfo.error);
+
+    // Give some time for modem to establish the emergency call channel.
+    sleep(MODEM_EMERGENCY_CALL_ESTABLISH_TIME);
+
+    // Disconnect all the potential established calls to prevent them affecting other tests.
+    clearPotentialEstablishedCalls();
 }
 
 /*
@@ -67,6 +73,12 @@
     ALOGI("emergencyDial_withServices, rspInfo.error = %s\n",
           toString(radioRsp_v1_4->rspInfo.error).c_str());
     EXPECT_EQ(RadioError::NONE, radioRsp_v1_4->rspInfo.error);
+
+    // Give some time for modem to establish the emergency call channel.
+    sleep(MODEM_EMERGENCY_CALL_ESTABLISH_TIME);
+
+    // Disconnect all the potential established calls to prevent them affecting other tests.
+    clearPotentialEstablishedCalls();
 }
 
 /*
@@ -93,6 +105,12 @@
     ALOGI("emergencyDial_withEmergencyRouting, rspInfo.error = %s\n",
           toString(radioRsp_v1_4->rspInfo.error).c_str());
     EXPECT_EQ(RadioError::NONE, radioRsp_v1_4->rspInfo.error);
+
+    // Give some time for modem to establish the emergency call channel.
+    sleep(MODEM_EMERGENCY_CALL_ESTABLISH_TIME);
+
+    // Disconnect all the potential established calls to prevent them affecting other tests.
+    clearPotentialEstablishedCalls();
 }
 
 /*
diff --git a/radio/1.4/vts/functional/radio_hidl_hal_test.cpp b/radio/1.4/vts/functional/radio_hidl_hal_test.cpp
index d2d21ce..63e5f6e 100644
--- a/radio/1.4/vts/functional/radio_hidl_hal_test.cpp
+++ b/radio/1.4/vts/functional/radio_hidl_hal_test.cpp
@@ -87,6 +87,23 @@
     return status;
 }
 
+void RadioHidlTest_v1_4::clearPotentialEstablishedCalls() {
+    // Get the current call Id to hangup the established emergency call.
+    serial = GetRandomSerialNumber();
+    radio_v1_4->getCurrentCalls(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+
+    // Hang up to disconnect the established call channels.
+    for (const ::android::hardware::radio::V1_2::Call& call : radioRsp_v1_4->currentCalls) {
+        serial = GetRandomSerialNumber();
+        radio_v1_4->hangup(serial, call.base.index);
+        ALOGI("Hang up to disconnect the established call channel: %d", call.base.index);
+        EXPECT_EQ(std::cv_status::no_timeout, wait());
+        // Give some time for modem to disconnect the established call channel.
+        sleep(MODEM_EMERGENCY_CALL_DISCONNECT_TIME);
+    }
+}
+
 void RadioHidlTest_v1_4::updateSimCardStatus() {
     serial = GetRandomSerialNumber();
     radio_v1_4->getIccCardStatus(serial);
diff --git a/radio/1.4/vts/functional/radio_hidl_hal_utils_v1_4.h b/radio/1.4/vts/functional/radio_hidl_hal_utils_v1_4.h
index f662472..b07f9c3 100644
--- a/radio/1.4/vts/functional/radio_hidl_hal_utils_v1_4.h
+++ b/radio/1.4/vts/functional/radio_hidl_hal_utils_v1_4.h
@@ -44,6 +44,9 @@
 using ::android::hardware::Void;
 
 #define TIMEOUT_PERIOD 75
+#define MODEM_EMERGENCY_CALL_ESTABLISH_TIME 3
+#define MODEM_EMERGENCY_CALL_DISCONNECT_TIME 3
+
 #define RADIO_SERVICE_NAME "slot1"
 
 class RadioHidlTest_v1_4;
@@ -59,6 +62,9 @@
 
     RadioResponseInfo rspInfo;
 
+    // Call
+    hidl_vec<::android::hardware::radio::V1_2::Call> currentCalls;
+
     // Modem
     bool isModemEnabled;
     bool enableModemResponseToggle;
@@ -725,6 +731,9 @@
     /* Serial number for radio request */
     int serial;
 
+    /* Clear Potential Established Calls */
+    void clearPotentialEstablishedCalls();
+
     /* Update Sim Card Status */
     void updateSimCardStatus();
 
diff --git a/radio/1.4/vts/functional/radio_response.cpp b/radio/1.4/vts/functional/radio_response.cpp
index eac0c68..a849926 100644
--- a/radio/1.4/vts/functional/radio_response.cpp
+++ b/radio/1.4/vts/functional/radio_response.cpp
@@ -77,7 +77,9 @@
     return Void();
 }
 
-Return<void> RadioResponse_v1_4::hangupConnectionResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse_v1_4::hangupConnectionResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_v1_4.notify(info.serial);
     return Void();
 }
 
@@ -729,9 +731,10 @@
 
 Return<void> RadioResponse_v1_4::getCurrentCallsResponse_1_2(
         const RadioResponseInfo& info,
-        const ::android::hardware::hidl_vec<::android::hardware::radio::V1_2::Call>& /*calls*/) {
+        const ::android::hardware::hidl_vec<::android::hardware::radio::V1_2::Call>& calls) {
     rspInfo = info;
     parent_v1_4.notify(info.serial);
+    currentCalls = calls;
     return Void();
 }
 
diff --git a/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp b/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp
index 39053fe..62c5334 100644
--- a/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp
+++ b/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp
@@ -683,11 +683,16 @@
             Result flushResult = flush(sensor.sensorHandle);
             ASSERT_EQ(flushResult, expectedResponse);
         }
-        activate(sensor.sensorHandle, false);
     }
 
     // Wait up to one second for the flush events
     callback.waitForFlushEvents(sensors, flushCalls, 1000 /* timeoutMs */);
+
+    // Deactivate all sensors after waiting for flush events so pending flush events are not
+    // abandoned by the HAL.
+    for (const SensorInfo& sensor : sensors) {
+        activate(sensor.sensorHandle, false);
+    }
     getEnvironment()->unregisterCallback();
 
     // Check that the correct number of flushes are present for each sensor
diff --git a/wifi/supplicant/1.2/vts/functional/supplicant_p2p_iface_hidl_test.cpp b/wifi/supplicant/1.2/vts/functional/supplicant_p2p_iface_hidl_test.cpp
index 36bde16..1b78ac3 100644
--- a/wifi/supplicant/1.2/vts/functional/supplicant_p2p_iface_hidl_test.cpp
+++ b/wifi/supplicant/1.2/vts/functional/supplicant_p2p_iface_hidl_test.cpp
@@ -127,25 +127,33 @@
         });
 }
 
+bool isMacRandomizationSupported(const SupplicantStatus& status) {
+    return status.code != SupplicantStatusCode::FAILURE_ARGS_INVALID;
+}
+
 /*
  * Verify that setMacRandomization successes.
  */
 TEST_F(SupplicantP2pIfaceHidlTest, EnableMacRandomization) {
     p2p_iface_->setMacRandomization(true, [](const SupplicantStatus& status) {
+        if (!isMacRandomizationSupported(status)) return;
         EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
     });
 
     // enable twice
     p2p_iface_->setMacRandomization(true, [](const SupplicantStatus& status) {
+        if (!isMacRandomizationSupported(status)) return;
         EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
     });
 
     p2p_iface_->setMacRandomization(false, [](const SupplicantStatus& status) {
+        if (!isMacRandomizationSupported(status)) return;
         EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
     });
 
     // disable twice
     p2p_iface_->setMacRandomization(false, [](const SupplicantStatus& status) {
+        if (!isMacRandomizationSupported(status)) return;
         EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
     });
 }