Merge changes I0b38a98a,I6f8e6ec1 into sc-dev
* changes:
IFace: update VTS tests
IFace: update default implementation
diff --git a/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h b/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h
index 79243b6..a92a277 100644
--- a/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h
+++ b/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h
@@ -225,14 +225,6 @@
return isTelephonyDevice(stringToAudioDevice(device));
}
-static inline bool isEchoReferenceDevice(AudioDevice device) {
- return device == AudioDevice::AUDIO_DEVICE_IN_ECHO_REFERENCE;
-}
-
-static inline bool isEchoReferenceDevice(const std::string& device) {
- return isEchoReferenceDevice(stringToAudioDevice(device));
-}
-
static inline bool maybeVendorExtension(const std::string& s) {
// Only checks whether the string starts with the "vendor prefix".
static const std::string vendorPrefix = "VX_";
diff --git a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
index 79ac295..0b3098b 100644
--- a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
@@ -710,8 +710,7 @@
// Returning 'true' when no source is found so the test can fail later with a more clear
// problem description.
return !maybeSourceAddress.has_value() ||
- !(xsd::isTelephonyDevice(maybeSourceAddress.value().deviceType) ||
- xsd::isEchoReferenceDevice(maybeSourceAddress.value().deviceType));
+ !xsd::isTelephonyDevice(maybeSourceAddress.value().deviceType);
}
void createPatchIfNeeded() {
diff --git a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h
index 6667f7a..b927770 100644
--- a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h
+++ b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h
@@ -17,14 +17,19 @@
#pragma once
#include <android-base/logging.h>
+#include <random>
namespace aidl::android::hardware::biometrics::fingerprint {
class FakeFingerprintEngine {
public:
+ FakeFingerprintEngine() : mRandom(std::mt19937::default_seed) {}
+
void generateChallengeImpl(ISessionCallback* cb) {
LOG(INFO) << "generateChallengeImpl";
- cb->onChallengeGenerated(0 /* challenge */);
+ std::uniform_int_distribution<int64_t> dist;
+ auto challenge = dist(mRandom);
+ cb->onChallengeGenerated(challenge);
}
void revokeChallengeImpl(ISessionCallback* cb, int64_t challenge) {
@@ -32,8 +37,13 @@
cb->onChallengeRevoked(challenge);
}
- void enrollImpl(ISessionCallback* cb, const keymaster::HardwareAuthToken& /*hat*/) {
+ void enrollImpl(ISessionCallback* cb, const keymaster::HardwareAuthToken& hat) {
LOG(INFO) << "enrollImpl";
+ // Do proper HAT verification in the real implementation.
+ if (hat.mac.empty()) {
+ cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
+ return;
+ }
cb->onEnrollmentProgress(0 /* enrollmentId */, 0 /* remaining */);
}
@@ -71,6 +81,8 @@
LOG(INFO) << "resetLockoutImpl";
cb->onLockoutCleared();
}
+
+ std::mt19937 mRandom;
};
} // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp b/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp
index f1cfb17..1cd8c76 100644
--- a/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp
+++ b/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp
@@ -35,13 +35,19 @@
class SessionCallback : public BnSessionCallback {
public:
- explicit SessionCallback(std::promise<void>&& promise) : mPromise(std::move(promise)) {}
-
- ndk::ScopedAStatus onChallengeGenerated(int64_t /*challenge*/) override {
+ ndk::ScopedAStatus onChallengeGenerated(int64_t challenge) override {
+ auto lock = std::lock_guard{mMutex};
+ mOnChallengeGeneratedInvoked = true;
+ mGeneratedChallenge = challenge;
+ mCv.notify_one();
return ndk::ScopedAStatus::ok();
}
- ndk::ScopedAStatus onChallengeRevoked(int64_t /*challenge*/) override {
+ ndk::ScopedAStatus onChallengeRevoked(int64_t challenge) override {
+ auto lock = std::lock_guard{mMutex};
+ mOnChallengeRevokedInvoked = true;
+ mRevokedChallenge = challenge;
+ mCv.notify_one();
return ndk::ScopedAStatus::ok();
}
@@ -49,7 +55,11 @@
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{mMutex};
+ mError = error;
+ mOnErrorInvoked = true;
+ mCv.notify_one();
return ndk::ScopedAStatus::ok();
}
@@ -77,63 +87,203 @@
ndk::ScopedAStatus onEnrollmentsEnumerated(
const std::vector<int32_t>& /*enrollmentIds*/) override {
+ auto lock = std::lock_guard{mMutex};
+ mOnEnrollmentsEnumeratedInvoked = true;
+ mCv.notify_one();
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus onEnrollmentsRemoved(
const std::vector<int32_t>& /*enrollmentIds*/) override {
+ auto lock = std::lock_guard{mMutex};
+ mOnEnrollmentsRemovedInvoked = true;
+ mCv.notify_one();
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus onAuthenticatorIdRetrieved(int64_t /*authenticatorId*/) override {
+ auto lock = std::lock_guard{mMutex};
+ mOnAuthenticatorIdRetrievedInvoked = true;
+ mCv.notify_one();
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus onAuthenticatorIdInvalidated(int64_t /*newAuthenticatorId*/) override {
+ auto lock = std::lock_guard{mMutex};
+ mOnAuthenticatorIdInvalidatedInvoked = true;
+ mCv.notify_one();
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus onSessionClosed() override {
- mPromise.set_value();
+ auto lock = std::lock_guard{mMutex};
+ mOnSessionClosedInvoked = true;
+ mCv.notify_one();
return ndk::ScopedAStatus::ok();
}
- private:
- std::promise<void> mPromise;
+ std::mutex mMutex;
+ std::condition_variable mCv;
+ Error mError = Error::UNKNOWN;
+ int64_t mGeneratedChallenge = 0;
+ int64_t mRevokedChallenge = 0;
+ bool mOnChallengeGeneratedInvoked = false;
+ bool mOnChallengeRevokedInvoked = false;
+ bool mOnErrorInvoked = false;
+ bool mOnEnrollmentsEnumeratedInvoked = false;
+ bool mOnEnrollmentsRemovedInvoked = false;
+ bool mOnAuthenticatorIdRetrievedInvoked = false;
+ bool mOnAuthenticatorIdInvalidatedInvoked = false;
+ bool mOnSessionClosedInvoked = false;
};
class Fingerprint : public testing::TestWithParam<std::string> {
protected:
void SetUp() override {
- AIBinder* binder = AServiceManager_waitForService(GetParam().c_str());
- ASSERT_NE(binder, nullptr);
- mHal = IFingerprint::fromBinder(ndk::SpAIBinder(binder));
+ // Prepare the callback.
+ mCb = ndk::SharedRefBase::make<SessionCallback>();
+
+ int retries = 0;
+ bool isOk = false;
+ // If the first attempt to create a session fails, we try to create a session again. The
+ // first attempt might fail if the framework already has an active session. The AIDL
+ // contract doesn't allow to create a new session without closing the old one. However, we
+ // can't close the framework's session from VTS. The expectation here is that the HAL will
+ // crash after the first illegal attempt to create a session, then it will restart, and then
+ // we'll be able to create a session.
+ do {
+ // Get an instance of the HAL.
+ AIBinder* binder = AServiceManager_waitForService(GetParam().c_str());
+ ASSERT_NE(binder, nullptr);
+ mHal = IFingerprint::fromBinder(ndk::SpAIBinder(binder));
+
+ // Create a session.
+ isOk = mHal->createSession(kSensorId, kUserId, mCb, &mSession).isOk();
+ ++retries;
+ } while (!isOk && retries < 2);
+
+ ASSERT_TRUE(isOk);
+ }
+
+ void TearDown() override {
+ // Close the mSession.
+ ASSERT_TRUE(mSession->close().isOk());
+
+ // Make sure the mSession is closed.
+ auto lock = std::unique_lock<std::mutex>(mCb->mMutex);
+ mCb->mCv.wait(lock, [this] { return mCb->mOnSessionClosedInvoked; });
}
std::shared_ptr<IFingerprint> mHal;
+ std::shared_ptr<SessionCallback> mCb;
+ std::shared_ptr<ISession> mSession;
};
-TEST_P(Fingerprint, AuthenticateTest) {
- auto promise = std::promise<void>{};
- auto future = promise.get_future();
- // Prepare the callback.
- auto cb = ndk::SharedRefBase::make<SessionCallback>(std::move(promise));
+TEST_P(Fingerprint, GetSensorPropsWorksTest) {
+ std::vector<SensorProps> sensorProps;
- // Create a session
- std::shared_ptr<ISession> session;
- ASSERT_TRUE(mHal->createSession(kSensorId, kUserId, cb, &session).isOk());
+ // Call the method.
+ ASSERT_TRUE(mHal->getSensorProps(&sensorProps).isOk());
- // Call authenticate
+ // Make sure the sensorProps aren't empty.
+ ASSERT_FALSE(sensorProps.empty());
+ ASSERT_FALSE(sensorProps[0].commonProps.componentInfo.empty());
+}
+
+TEST_P(Fingerprint, EnrollWithBadHatResultsInErrorTest) {
+ // Call the method.
+ auto hat = keymaster::HardwareAuthToken{};
std::shared_ptr<common::ICancellationSignal> cancellationSignal;
- ASSERT_TRUE(session->authenticate(-1 /* operationId */, &cancellationSignal).isOk());
+ ASSERT_TRUE(mSession->enroll(hat, &cancellationSignal).isOk());
- // Get the results
- // TODO(b/166799066): test authenticate.
+ // Make sure an error is returned.
+ auto lock = std::unique_lock{mCb->mMutex};
+ mCb->mCv.wait(lock, [this] { return mCb->mOnErrorInvoked; });
+}
- // Close the session
- ASSERT_TRUE(session->close().isOk());
- auto status = future.wait_for(1s);
- ASSERT_EQ(status, std::future_status::ready);
+TEST_P(Fingerprint, GenerateChallengeProducesUniqueChallengesTest) {
+ static constexpr int kIterations = 100;
+
+ auto challenges = std::set<int>{};
+ for (unsigned int i = 0; i < kIterations; ++i) {
+ // Call the method.
+ ASSERT_TRUE(mSession->generateChallenge().isOk());
+
+ // Check that the generated challenge is unique and not 0.
+ auto lock = std::unique_lock{mCb->mMutex};
+ mCb->mCv.wait(lock, [this] { return mCb->mOnChallengeGeneratedInvoked; });
+ ASSERT_NE(mCb->mGeneratedChallenge, 0);
+ ASSERT_EQ(challenges.find(mCb->mGeneratedChallenge), challenges.end());
+
+ challenges.insert(mCb->mGeneratedChallenge);
+ mCb->mOnChallengeGeneratedInvoked = false;
+ }
+}
+
+TEST_P(Fingerprint, RevokeChallengeWorksForNonexistentChallengeTest) {
+ const int64_t nonexistentChallenge = 123;
+
+ // Call the method.
+ ASSERT_TRUE(mSession->revokeChallenge(nonexistentChallenge).isOk());
+
+ // Check that the challenge is revoked and matches the requested challenge.
+ auto lock = std::unique_lock{mCb->mMutex};
+ mCb->mCv.wait(lock, [this] { return mCb->mOnChallengeRevokedInvoked; });
+ ASSERT_EQ(mCb->mRevokedChallenge, nonexistentChallenge);
+}
+
+TEST_P(Fingerprint, RevokeChallengeWorksForExistentChallengeTest) {
+ // Generate a challenge.
+ ASSERT_TRUE(mSession->generateChallenge().isOk());
+
+ // Wait for the result.
+ auto lock = std::unique_lock{mCb->mMutex};
+ mCb->mCv.wait(lock, [this] { return mCb->mOnChallengeGeneratedInvoked; });
+ lock.unlock();
+
+ // Revoke the challenge.
+ ASSERT_TRUE(mSession->revokeChallenge(mCb->mGeneratedChallenge).isOk());
+
+ // Check that the challenge is revoked and matches the requested challenge.
+ lock.lock();
+ mCb->mCv.wait(lock, [this] { return mCb->mOnChallengeRevokedInvoked; });
+ ASSERT_EQ(mCb->mRevokedChallenge, mCb->mGeneratedChallenge);
+}
+
+TEST_P(Fingerprint, EnumerateEnrollmentsWorksTest) {
+ // Call the method.
+ ASSERT_TRUE(mSession->enumerateEnrollments().isOk());
+
+ // Wait for the result.
+ auto lock = std::unique_lock{mCb->mMutex};
+ mCb->mCv.wait(lock, [this] { return mCb->mOnEnrollmentsEnumeratedInvoked; });
+}
+
+TEST_P(Fingerprint, RemoveEnrollmentsWorksTest) {
+ // Call the method.
+ ASSERT_TRUE(mSession->removeEnrollments({}).isOk());
+
+ // Wait for the result.
+ auto lock = std::unique_lock{mCb->mMutex};
+ mCb->mCv.wait(lock, [this] { return mCb->mOnEnrollmentsRemovedInvoked; });
+}
+
+TEST_P(Fingerprint, GetAuthenticatorIdWorksTest) {
+ // Call the method.
+ ASSERT_TRUE(mSession->getAuthenticatorId().isOk());
+
+ // Wait for the result.
+ auto lock = std::unique_lock{mCb->mMutex};
+ mCb->mCv.wait(lock, [this] { return mCb->mOnAuthenticatorIdRetrievedInvoked; });
+}
+
+TEST_P(Fingerprint, InvalidateAuthenticatorIdWorksTest) {
+ // Call the method.
+ ASSERT_TRUE(mSession->invalidateAuthenticatorId().isOk());
+
+ // Wait for the result.
+ auto lock = std::unique_lock{mCb->mMutex};
+ mCb->mCv.wait(lock, [this] { return mCb->mOnAuthenticatorIdInvalidatedInvoked; });
}
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Fingerprint);