Merge "Audio: Add memory leak checking for HAL" into sc-v2-dev
diff --git a/automotive/vehicle/2.0/default/android.hardware.automotive.vehicle@2.0-service.rc b/automotive/vehicle/2.0/default/android.hardware.automotive.vehicle@2.0-service.rc
index c8c89dc..44f9134 100644
--- a/automotive/vehicle/2.0/default/android.hardware.automotive.vehicle@2.0-service.rc
+++ b/automotive/vehicle/2.0/default/android.hardware.automotive.vehicle@2.0-service.rc
@@ -1,4 +1,4 @@
 service vendor.vehicle-hal-2.0 /vendor/bin/hw/android.hardware.automotive.vehicle@2.0-service
-    class hal
+    class early_hal
     user vehicle_network
     group system inet
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 a85cdf0..f98962b 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
@@ -1027,14 +1027,6 @@
         {
                 .config =
                         {
-                                .prop = toInt(VehicleProperty::STORAGE_ENCRYPTION_BINDING_SEED),
-                                .access = VehiclePropertyAccess::READ_WRITE,
-                                .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                        },
-        },
-        {
-                .config =
-                        {
                                 .prop = toInt(VehicleProperty::WATCHDOG_ALIVE),
                                 .access = VehiclePropertyAccess::WRITE,
                                 .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
diff --git a/biometrics/face/aidl/default/Session.cpp b/biometrics/face/aidl/default/Session.cpp
index 0cb7c95..39f3753 100644
--- a/biometrics/face/aidl/default/Session.cpp
+++ b/biometrics/face/aidl/default/Session.cpp
@@ -107,7 +107,8 @@
 ndk::ScopedAStatus Session::getFeatures() {
     LOG(INFO) << "getFeatures";
     if (cb_) {
-        cb_->onFeaturesRetrieved({});
+        // Must error out with UNABLE_TO_PROCESS when no faces are enrolled.
+        cb_->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorCode */);
     }
     return ndk::ScopedAStatus::ok();
 }
diff --git a/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp b/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp
index 4dc44f1..8906b8d 100644
--- a/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp
+++ b/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp
@@ -60,9 +60,10 @@
         return ndk::ScopedAStatus::ok();
     }
 
-    ndk::ScopedAStatus onError(Error error, int32_t /*vendorCode*/) override {
+    ndk::ScopedAStatus onError(Error error, int32_t vendorCode) override {
         auto lock = std::lock_guard<std::mutex>{mMutex};
         mError = error;
+        mVendorCode = vendorCode;
         mOnErrorInvoked = true;
         mCv.notify_one();
         return ndk::ScopedAStatus::ok();
@@ -141,6 +142,7 @@
     std::mutex mMutex;
     std::condition_variable mCv;
     Error mError = Error::UNKNOWN;
+    int32_t mVendorCode = 0;
     int64_t mGeneratedChallenge = 0;
     int64_t mRevokedChallenge = 0;
     bool mOnChallengeGeneratedInvoked = false;
@@ -218,6 +220,8 @@
     // Make sure an error is returned.
     auto lock = std::unique_lock{mCb->mMutex};
     mCb->mCv.wait(lock, [this] { return mCb->mOnErrorInvoked; });
+    EXPECT_EQ(mCb->mError, Error::UNABLE_TO_PROCESS);
+    EXPECT_EQ(mCb->mVendorCode, 0);
 }
 
 TEST_P(Face, GenerateChallengeProducesUniqueChallengesTest) {
@@ -287,13 +291,15 @@
     mCb->mCv.wait(lock, [this] { return mCb->mOnEnrollmentsRemovedInvoked; });
 }
 
-TEST_P(Face, GetFeaturesWorksTest) {
+TEST_P(Face, GetFeaturesWithoutEnrollmentsResultsInUnableToProcess) {
     // Call the method.
     ASSERT_TRUE(mSession->getFeatures().isOk());
 
     // Wait for the result.
     auto lock = std::unique_lock{mCb->mMutex};
-    mCb->mCv.wait(lock, [this] { return mCb->mOnFeaturesRetrievedInvoked; });
+    mCb->mCv.wait(lock, [this] { return mCb->mOnErrorInvoked; });
+    EXPECT_EQ(mCb->mError, Error::UNABLE_TO_PROCESS);
+    EXPECT_EQ(mCb->mVendorCode, 0);
 }
 
 TEST_P(Face, GetAuthenticatorIdWorksTest) {
diff --git a/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp b/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp
index 54ba79d..ecfe66c 100644
--- a/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp
+++ b/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp
@@ -17,6 +17,7 @@
 #define LOG_TAG "graphics_composer_hidl_hal_test@2.3"
 
 #include <algorithm>
+#include <numeric>
 
 #include <android-base/logging.h>
 #include <android-base/properties.h>
@@ -155,16 +156,31 @@
 TEST_P(GraphicsComposerHidlTest, GetDisplayIdentificationData) {
     uint8_t port0;
     std::vector<uint8_t> data0;
-    if (mComposerClient->getDisplayIdentificationData(mPrimaryDisplay, &port0, &data0)) {
-        uint8_t port1;
-        std::vector<uint8_t> data1;
-        ASSERT_TRUE(mComposerClient->getDisplayIdentificationData(mPrimaryDisplay, &port1, &data1));
 
-        ASSERT_EQ(port0, port1) << "ports are not stable";
-        ASSERT_TRUE(data0.size() == data1.size() &&
-                    std::equal(data0.begin(), data0.end(), data1.begin()))
-            << "data is not stable";
+    if (!mComposerClient->getDisplayIdentificationData(mPrimaryDisplay, &port0, &data0)) {
+        return;
     }
+
+    ASSERT_FALSE(data0.empty());
+    constexpr size_t kEdidBlockSize = 128;
+    ASSERT_TRUE(data0.size() % kEdidBlockSize == 0)
+            << "EDID blob length is not a multiple of " << kEdidBlockSize;
+
+    const uint8_t kEdidHeader[] = {0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00};
+    ASSERT_TRUE(std::equal(std::begin(kEdidHeader), std::end(kEdidHeader), data0.begin()))
+            << "EDID blob doesn't start with the fixed EDID header";
+    ASSERT_EQ(0, std::accumulate(data0.begin(), data0.begin() + kEdidBlockSize,
+                                 static_cast<uint8_t>(0)))
+            << "EDID base block doesn't checksum";
+
+    uint8_t port1;
+    std::vector<uint8_t> data1;
+    ASSERT_TRUE(mComposerClient->getDisplayIdentificationData(mPrimaryDisplay, &port1, &data1));
+
+    ASSERT_EQ(port0, port1) << "ports are not stable";
+    ASSERT_TRUE(data0.size() == data1.size() &&
+                std::equal(data0.begin(), data0.end(), data1.begin()))
+            << "data is not stable";
 }
 
 /**
diff --git a/radio/1.5/vts/functional/radio_hidl_hal_api.cpp b/radio/1.5/vts/functional/radio_hidl_hal_api.cpp
index 0b49b36..d108951 100644
--- a/radio/1.5/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.5/vts/functional/radio_hidl_hal_api.cpp
@@ -1251,8 +1251,20 @@
  * Test IRadio.getBarringInfo() for the response returned.
  */
 TEST_P(RadioHidlTest_v1_5, getBarringInfo) {
+    // If the previous setRadioPower_1_5_emergencyCall_cancelled test has just finished.
+    // Due to radio restarting, modem may need a little more time to acquire network service
+    // and barring infos. If voice status is in-service, waiting 3s to get barring infos ready.
+    // Or waiting 10s if voice status is not in-service.
     serial = GetRandomSerialNumber();
+    radio_v1_5->getVoiceRegistrationState_1_5(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    if (isVoiceInService(radioRsp_v1_5->voiceRegResp.regState)) {
+        sleep(BARRING_INFO_MAX_WAIT_TIME_SECONDS);
+    } else {
+        sleep(VOICE_SERVICE_MAX_WAIT_TIME_SECONDS);
+    }
 
+    serial = GetRandomSerialNumber();
     Return<void> res = radio_v1_5->getBarringInfo(serial);
     EXPECT_EQ(std::cv_status::no_timeout, wait());
     EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
diff --git a/radio/1.5/vts/functional/radio_hidl_hal_utils_v1_5.h b/radio/1.5/vts/functional/radio_hidl_hal_utils_v1_5.h
index 87ce675..65442ca 100644
--- a/radio/1.5/vts/functional/radio_hidl_hal_utils_v1_5.h
+++ b/radio/1.5/vts/functional/radio_hidl_hal_utils_v1_5.h
@@ -51,6 +51,8 @@
 #define TIMEOUT_PERIOD 75
 #define MODEM_EMERGENCY_CALL_ESTABLISH_TIME 3
 #define MODEM_EMERGENCY_CALL_DISCONNECT_TIME 3
+#define VOICE_SERVICE_MAX_WAIT_TIME_SECONDS 10
+#define BARRING_INFO_MAX_WAIT_TIME_SECONDS 3
 
 #define RADIO_SERVICE_NAME "slot1"
 
@@ -69,6 +71,7 @@
 
     // Call
     hidl_vec<::android::hardware::radio::V1_2::Call> currentCalls;
+    ::android::hardware::radio::V1_2::VoiceRegStateResult voiceRegResp;
 
     // Modem
     bool isModemEnabled;
diff --git a/radio/1.5/vts/functional/radio_response.cpp b/radio/1.5/vts/functional/radio_response.cpp
index 9b6d450..3d6fc17 100644
--- a/radio/1.5/vts/functional/radio_response.cpp
+++ b/radio/1.5/vts/functional/radio_response.cpp
@@ -763,8 +763,9 @@
 
 Return<void> RadioResponse_v1_5::getVoiceRegistrationStateResponse_1_2(
         const RadioResponseInfo& info,
-        const ::android::hardware::radio::V1_2::VoiceRegStateResult& /*voiceRegResponse*/) {
+        const ::android::hardware::radio::V1_2::VoiceRegStateResult& voiceRegResponse) {
     rspInfo = info;
+    voiceRegResp = voiceRegResponse;
     parent_v1_5.notify(info.serial);
     return Void();
 }
@@ -989,8 +990,9 @@
 
 Return<void> RadioResponse_v1_5::getVoiceRegistrationStateResponse_1_5(
         const RadioResponseInfo& info,
-        const ::android::hardware::radio::V1_5::RegStateResult& /*regResponse*/) {
+        const ::android::hardware::radio::V1_5::RegStateResult& regResponse) {
     rspInfo = info;
+    voiceRegResp.regState = regResponse.regState;
     parent_v1_5.notify(info.serial);
     return Void();
 }