Fingerprint virtual HAL checkin (part 3)
- support randomization
- display touch events
- lockout
- cmd and dumpsys
Bug: 230515082
Bug: 230515086
Test: atest FakeFingerprintEngineTest
atest FakeFingerprintEngineUdfpsTest
atest --no-bazel-mode VtsHalBiometricsFingerprintTargetTest
Change-Id: Ia5399c86b7fec90b41d426c2f82cb257f4dc9a8a
diff --git a/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineTest.cpp b/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineTest.cpp
index 32d01f4..a200b39 100644
--- a/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineTest.cpp
+++ b/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineTest.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
#include <aidl/android/hardware/biometrics/fingerprint/BnSessionCallback.h>
#include "FakeFingerprintEngine.h"
+#include "util/Util.h"
using namespace ::android::fingerprint::virt;
using namespace ::aidl::android::hardware::biometrics::fingerprint;
@@ -118,9 +119,9 @@
class FakeFingerprintEngineTest : public ::testing::Test {
protected:
void SetUp() override {
- FingerprintHalProperties::operation_enroll_latency(0);
- FingerprintHalProperties::operation_authenticate_latency(0);
- FingerprintHalProperties::operation_detect_interaction_latency(0);
+ FingerprintHalProperties::operation_enroll_latency({0});
+ FingerprintHalProperties::operation_authenticate_latency({0});
+ FingerprintHalProperties::operation_detect_interaction_latency({0});
mCallback = ndk::SharedRefBase::make<TestSessionCallback>();
}
@@ -128,6 +129,9 @@
FingerprintHalProperties::operation_authenticate_error(0);
FingerprintHalProperties::operation_detect_interaction_error(0);
FingerprintHalProperties::operation_authenticate_acquired("");
+ FingerprintHalProperties::operation_enroll_latency({});
+ FingerprintHalProperties::operation_authenticate_latency({});
+ FingerprintHalProperties::operation_detect_interaction_latency({});
}
FakeFingerprintEngine mEngine;
@@ -291,6 +295,7 @@
}
TEST_F(FakeFingerprintEngineTest, InteractionDetect) {
+ FingerprintHalProperties::detect_interaction(true);
FingerprintHalProperties::enrollments({1, 2});
FingerprintHalProperties::enrollment_hit(2);
FingerprintHalProperties::operation_detect_interaction_acquired("");
@@ -300,6 +305,7 @@
}
TEST_F(FakeFingerprintEngineTest, InteractionDetectCancel) {
+ FingerprintHalProperties::detect_interaction(true);
FingerprintHalProperties::enrollments({1, 2});
FingerprintHalProperties::enrollment_hit(2);
mCancel.set_value();
@@ -309,6 +315,7 @@
}
TEST_F(FakeFingerprintEngineTest, InteractionDetectNotSet) {
+ FingerprintHalProperties::detect_interaction(true);
FingerprintHalProperties::enrollments({1, 2});
FingerprintHalProperties::enrollment_hit({});
mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
@@ -323,6 +330,7 @@
}
TEST_F(FakeFingerprintEngineTest, InteractionDetectError) {
+ FingerprintHalProperties::detect_interaction(true);
FingerprintHalProperties::operation_detect_interaction_error(8);
mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
ASSERT_EQ(0, mCallback->mInteractionDetectedCount);
@@ -331,6 +339,7 @@
}
TEST_F(FakeFingerprintEngineTest, InteractionDetectAcquired) {
+ FingerprintHalProperties::detect_interaction(true);
FingerprintHalProperties::enrollments({1, 2});
FingerprintHalProperties::enrollment_hit(2);
FingerprintHalProperties::operation_detect_interaction_acquired("4,1013");
@@ -435,12 +444,29 @@
std::vector<std::string> badStr{"10c", "100-5", "100-[5,6,7", "100-5,6,7]",
"100,2x0,300", "200-[f]", "a,b"};
std::vector<std::vector<int32_t>> ecV;
- for (const auto s : badStr) {
+ for (const auto& s : badStr) {
ecV = mEngine.parseEnrollmentCapture(s);
ASSERT_EQ(ecV.size(), 0);
}
}
+TEST_F(FakeFingerprintEngineTest, randomLatency) {
+ FingerprintHalProperties::operation_detect_interaction_latency({});
+ ASSERT_EQ(DEFAULT_LATENCY,
+ mEngine.getLatency(FingerprintHalProperties::operation_detect_interaction_latency()));
+ FingerprintHalProperties::operation_detect_interaction_latency({10});
+ ASSERT_EQ(10,
+ mEngine.getLatency(FingerprintHalProperties::operation_detect_interaction_latency()));
+ FingerprintHalProperties::operation_detect_interaction_latency({1, 1000});
+ std::set<int32_t> latencySet;
+ for (int i = 0; i < 100; i++) {
+ latencySet.insert(mEngine.getLatency(
+ FingerprintHalProperties::operation_detect_interaction_latency()));
+ }
+ ASSERT_TRUE(latencySet.size() > 95);
+ FingerprintHalProperties::operation_detect_interaction_latency({});
+}
+
} // namespace aidl::android::hardware::biometrics::fingerprint
int main(int argc, char** argv) {
diff --git a/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineUdfpsTest.cpp b/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineUdfpsTest.cpp
index 7c0021f..f551899 100644
--- a/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineUdfpsTest.cpp
+++ b/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineUdfpsTest.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <aidl/android/hardware/biometrics/fingerprint/BnSessionCallback.h>
#include <android/binder_process.h>
#include <fingerprint.sysprop.h>
#include <gtest/gtest.h>
@@ -29,6 +30,69 @@
namespace aidl::android::hardware::biometrics::fingerprint {
+class TestSessionCallback : public BnSessionCallback {
+ public:
+ ndk::ScopedAStatus onChallengeGenerated(int64_t /*challenge*/) override {
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onChallengeRevoked(int64_t /*challenge*/) override {
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onError(fingerprint::Error /*error*/, int32_t /*vendorCode*/) override {
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onEnrollmentProgress(int32_t /*enrollmentId*/,
+ int32_t /*remaining*/) override {
+ mEnrollmentProgress++;
+ return ndk::ScopedAStatus::ok();
+ };
+
+ ::ndk::ScopedAStatus onAuthenticationSucceeded(int32_t /*enrollmentId*/,
+ const keymaster::HardwareAuthToken&) override {
+ mAuthenticationSuccess++;
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onAuthenticationFailed() override {
+ mAuthenticationFailure++;
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onInteractionDetected() override {
+ mDetectInteraction++;
+ return ndk::ScopedAStatus::ok();
+ };
+ ndk::ScopedAStatus onAcquired(AcquiredInfo /*info*/, int32_t /*vendorCode*/) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus onEnrollmentsEnumerated(
+ const std::vector<int32_t>& /*enrollmentIds*/) override {
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onEnrollmentsRemoved(
+ const std::vector<int32_t>& /*enrollmentIds*/) override {
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onAuthenticatorIdRetrieved(int64_t /*authenticatorId*/) override {
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onAuthenticatorIdInvalidated(int64_t /*authenticatorId*/) override {
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onLockoutPermanent() override { return ndk::ScopedAStatus::ok(); };
+ ndk::ScopedAStatus onLockoutTimed(int64_t /* timeout */) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus onLockoutCleared() override { return ndk::ScopedAStatus::ok(); }
+ ndk::ScopedAStatus onSessionClosed() override { return ndk::ScopedAStatus::ok(); }
+
+ int32_t getAuthenticationCount() { return mAuthenticationSuccess + mAuthenticationFailure; }
+ int32_t getDetectInteractionCount() { return mDetectInteraction; }
+
+ int32_t mAuthenticationSuccess = 0;
+ int32_t mAuthenticationFailure = 0;
+ int32_t mEnrollmentProgress = 0;
+ int32_t mDetectInteraction = 0;
+};
+
class FakeFingerprintEngineUdfpsTest : public ::testing::Test {
protected:
void SetUp() override {}
@@ -65,30 +129,56 @@
}
TEST_F(FakeFingerprintEngineUdfpsTest, getSensorLocationBad) {
- FingerprintHalProperties::sensor_location("");
- SensorLocation sc = mEngine.getSensorLocation();
- ASSERT_TRUE(isDefaultLocation(sc));
-
- auto loc = "100";
- FingerprintHalProperties::sensor_location(loc);
- sc = mEngine.getSensorLocation();
- ASSERT_TRUE(isDefaultLocation(sc));
-
- loc = "10:20";
- FingerprintHalProperties::sensor_location(loc);
- sc = mEngine.getSensorLocation();
- ASSERT_TRUE(isDefaultLocation(sc));
-
- loc = "10,20,5";
- FingerprintHalProperties::sensor_location(loc);
- sc = mEngine.getSensorLocation();
- ASSERT_TRUE(isDefaultLocation(sc));
-
- loc = "a:b:c";
- FingerprintHalProperties::sensor_location(loc);
- sc = mEngine.getSensorLocation();
- ASSERT_TRUE(isDefaultLocation(sc));
+ const std::vector<std::string> badStr{"", "100", "10:20", "10,20,5", "a:b:c"};
+ SensorLocation sc;
+ for (const auto& s : badStr) {
+ FingerprintHalProperties::sensor_location(s);
+ sc = mEngine.getSensorLocation();
+ ASSERT_TRUE(isDefaultLocation(sc));
+ }
}
+TEST_F(FakeFingerprintEngineUdfpsTest, initialization) {
+ ASSERT_TRUE(mEngine.getWorkMode() == FakeFingerprintEngineUdfps::WorkMode::kIdle);
+}
+
+TEST_F(FakeFingerprintEngineUdfpsTest, authenticate) {
+ std::shared_ptr<TestSessionCallback> cb = ndk::SharedRefBase::make<TestSessionCallback>();
+ std::promise<void> cancel;
+ mEngine.authenticateImpl(cb.get(), 1, cancel.get_future());
+ ASSERT_TRUE(mEngine.getWorkMode() == FakeFingerprintEngineUdfps::WorkMode::kAuthenticate);
+ mEngine.onPointerDownImpl(1, 2, 3, 4.0, 5.0);
+ ASSERT_EQ(cb->getAuthenticationCount(), 0);
+ mEngine.onUiReadyImpl();
+ ASSERT_EQ(cb->getAuthenticationCount(), 1);
+}
+
+TEST_F(FakeFingerprintEngineUdfpsTest, enroll) {
+ std::shared_ptr<TestSessionCallback> cb = ndk::SharedRefBase::make<TestSessionCallback>();
+ std::promise<void> cancel;
+ keymaster::HardwareAuthToken hat{.mac = {5, 6}};
+ FingerprintHalProperties::next_enrollment("5:0,0:true");
+ mEngine.enrollImpl(cb.get(), hat, cancel.get_future());
+ ASSERT_TRUE(mEngine.getWorkMode() == FakeFingerprintEngineUdfps::WorkMode::kEnroll);
+ mEngine.onPointerDownImpl(1, 2, 3, 4.0, 5.0);
+ ASSERT_EQ(cb->mEnrollmentProgress, 0);
+ mEngine.onUiReadyImpl();
+ ASSERT_TRUE(cb->mEnrollmentProgress > 0);
+}
+
+TEST_F(FakeFingerprintEngineUdfpsTest, detectInteraction) {
+ FingerprintHalProperties::detect_interaction(true);
+ FingerprintHalProperties::enrollments({1, 2});
+ FingerprintHalProperties::enrollment_hit(2);
+ FingerprintHalProperties::operation_detect_interaction_acquired("");
+ std::shared_ptr<TestSessionCallback> cb = ndk::SharedRefBase::make<TestSessionCallback>();
+ std::promise<void> cancel;
+ mEngine.detectInteractionImpl(cb.get(), cancel.get_future());
+ ASSERT_TRUE(mEngine.getWorkMode() == FakeFingerprintEngineUdfps::WorkMode::kDetectInteract);
+ mEngine.onPointerDownImpl(1, 2, 3, 4.0, 5.0);
+ ASSERT_EQ(cb->getDetectInteractionCount(), 0);
+ mEngine.onUiReadyImpl();
+ ASSERT_EQ(cb->getDetectInteractionCount(), 1);
+}
// More
} // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/tests/FakeLockoutTrackerTest.cpp b/biometrics/fingerprint/aidl/default/tests/FakeLockoutTrackerTest.cpp
new file mode 100644
index 0000000..1b071ee
--- /dev/null
+++ b/biometrics/fingerprint/aidl/default/tests/FakeLockoutTrackerTest.cpp
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android/binder_process.h>
+#include <fingerprint.sysprop.h>
+#include <gtest/gtest.h>
+
+#include <android-base/logging.h>
+
+#include "FakeLockoutTracker.h"
+#include "util/Util.h"
+
+using namespace ::android::fingerprint::virt;
+using namespace ::aidl::android::hardware::biometrics::fingerprint;
+
+namespace aidl::android::hardware::biometrics::fingerprint {
+
+class FakeLockoutTrackerTest : public ::testing::Test {
+ protected:
+ static constexpr int32_t LOCKOUT_TIMED_THRESHOLD = 3;
+ static constexpr int32_t LOCKOUT_PERMANENT_THRESHOLD = 5;
+ static constexpr int32_t LOCKOUT_TIMED_DURATION = 100;
+
+ void SetUp() override {
+ FingerprintHalProperties::lockout_timed_threshold(LOCKOUT_TIMED_THRESHOLD);
+ FingerprintHalProperties::lockout_timed_duration(LOCKOUT_TIMED_DURATION);
+ FingerprintHalProperties::lockout_permanent_threshold(LOCKOUT_PERMANENT_THRESHOLD);
+ }
+
+ void TearDown() override {
+ // reset to default
+ FingerprintHalProperties::lockout_timed_threshold(5);
+ FingerprintHalProperties::lockout_timed_duration(20);
+ FingerprintHalProperties::lockout_permanent_threshold(10000);
+ FingerprintHalProperties::lockout_enable(false);
+ FingerprintHalProperties::lockout(false);
+ }
+
+ FakeLockoutTracker mLockoutTracker;
+};
+
+TEST_F(FakeLockoutTrackerTest, addFailedAttemptDisable) {
+ FingerprintHalProperties::lockout_enable(false);
+ for (int i = 0; i < LOCKOUT_TIMED_THRESHOLD + 1; i++) mLockoutTracker.addFailedAttempt();
+ ASSERT_EQ(mLockoutTracker.getMode(), FakeLockoutTracker::LockoutMode::kNone);
+ mLockoutTracker.reset();
+}
+
+TEST_F(FakeLockoutTrackerTest, addFailedAttemptLockoutTimed) {
+ FingerprintHalProperties::lockout_enable(true);
+ for (int i = 0; i < LOCKOUT_TIMED_THRESHOLD; i++) mLockoutTracker.addFailedAttempt();
+ ASSERT_EQ(mLockoutTracker.getMode(), FakeLockoutTracker::LockoutMode::kTimed);
+ // time left
+ int N = 5;
+ int64_t prevTimeLeft = INT_MIN;
+ for (int i = 0; i < N; i++) {
+ SLEEP_MS(LOCKOUT_TIMED_DURATION / N + 1);
+ int64_t currTimeLeft = mLockoutTracker.getLockoutTimeLeft();
+ ASSERT_TRUE(currTimeLeft > prevTimeLeft);
+ prevTimeLeft = currTimeLeft;
+ }
+ ASSERT_EQ(mLockoutTracker.getMode(), FakeLockoutTracker::LockoutMode::kNone);
+ mLockoutTracker.reset();
+}
+
+TEST_F(FakeLockoutTrackerTest, addFailedAttemptPermanent) {
+ FingerprintHalProperties::lockout_enable(true);
+ for (int i = 0; i < LOCKOUT_PERMANENT_THRESHOLD - 1; i++) mLockoutTracker.addFailedAttempt();
+ ASSERT_NE(mLockoutTracker.getMode(), FakeLockoutTracker::LockoutMode::kPermanent);
+ mLockoutTracker.addFailedAttempt();
+ ASSERT_EQ(mLockoutTracker.getMode(), FakeLockoutTracker::LockoutMode::kPermanent);
+ ASSERT_TRUE(FingerprintHalProperties::lockout());
+ mLockoutTracker.reset();
+}
+
+} // namespace aidl::android::hardware::biometrics::fingerprint
+
+int main(int argc, char** argv) {
+ testing::InitGoogleTest(&argc, argv);
+ ABinderProcess_startThreadPool();
+ return RUN_ALL_TESTS();
+}