diff --git a/biometrics/fingerprint/aidl/default/FakeFingerprintEngine.cpp b/biometrics/fingerprint/aidl/default/FakeFingerprintEngine.cpp index ec28846a6a..54076c88e3 100644 --- a/biometrics/fingerprint/aidl/default/FakeFingerprintEngine.cpp +++ b/biometrics/fingerprint/aidl/default/FakeFingerprintEngine.cpp @@ -385,6 +385,11 @@ void FakeFingerprintEngine::resetLockoutImpl(ISessionCallback* cb, cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */); return; } + clearLockout(cb); + isLockoutTimerAborted = true; +} + +void FakeFingerprintEngine::clearLockout(ISessionCallback* cb) { FingerprintHalProperties::lockout(false); cb->onLockoutCleared(); mLockoutTracker.reset(); @@ -574,13 +579,34 @@ bool FakeFingerprintEngine::checkSensorLockout(ISessionCallback* cb) { if (lockoutMode == FakeLockoutTracker::LockoutMode::kPermanent) { LOG(ERROR) << "Fail: lockout permanent"; cb->onLockoutPermanent(); + isLockoutTimerAborted = true; return true; } else if (lockoutMode == FakeLockoutTracker::LockoutMode::kTimed) { int64_t timeLeft = mLockoutTracker.getLockoutTimeLeft(); LOG(ERROR) << "Fail: lockout timed " << timeLeft; cb->onLockoutTimed(timeLeft); + if (isLockoutTimerSupported && !isLockoutTimerStarted) startLockoutTimer(timeLeft, cb); return true; } return false; } + +void FakeFingerprintEngine::startLockoutTimer(int64_t timeout, ISessionCallback* cb) { + BEGIN_OP(0); + std::function action = + std::bind(&FakeFingerprintEngine::lockoutTimerExpired, this, std::placeholders::_1); + std::thread([timeout, action, cb]() { + std::this_thread::sleep_for(std::chrono::milliseconds(timeout)); + action(cb); + }).detach(); + + isLockoutTimerStarted = true; +} +void FakeFingerprintEngine::lockoutTimerExpired(ISessionCallback* cb) { + if (!isLockoutTimerAborted) { + clearLockout(cb); + } + isLockoutTimerStarted = false; + isLockoutTimerAborted = false; +} } // namespace aidl::android::hardware::biometrics::fingerprint diff --git a/biometrics/fingerprint/aidl/default/FakeFingerprintEngineSide.cpp b/biometrics/fingerprint/aidl/default/FakeFingerprintEngineSide.cpp index 6982072dc4..a78cdcdbce 100644 --- a/biometrics/fingerprint/aidl/default/FakeFingerprintEngineSide.cpp +++ b/biometrics/fingerprint/aidl/default/FakeFingerprintEngineSide.cpp @@ -27,6 +27,10 @@ using namespace ::android::fingerprint::virt; namespace aidl::android::hardware::biometrics::fingerprint { +FakeFingerprintEngineSide::FakeFingerprintEngineSide() : FakeFingerprintEngine() { + isLockoutTimerSupported = true; +} + SensorLocation FakeFingerprintEngineSide::defaultSensorLocation() { return SensorLocation{.sensorLocationX = defaultSensorLocationX, .sensorLocationY = defaultSensorLocationY, diff --git a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h index a06b786acd..2450115aaf 100644 --- a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h +++ b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h @@ -114,8 +114,20 @@ class FakeFingerprintEngine { std::vector>& res); int32_t getRandomInRange(int32_t bound1, int32_t bound2); bool checkSensorLockout(ISessionCallback*); + void clearLockout(ISessionCallback* cb); FakeLockoutTracker mLockoutTracker; + + protected: + // lockout timer + void lockoutTimerExpired(ISessionCallback* cb); + bool isLockoutTimerSupported; + bool isLockoutTimerStarted; + bool isLockoutTimerAborted; + + public: + void startLockoutTimer(int64_t timeout, ISessionCallback* cb); + bool getLockoutTimerStarted() { return isLockoutTimerStarted; } }; } // namespace aidl::android::hardware::biometrics::fingerprint diff --git a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngineSide.h b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngineSide.h index c2fc005ffc..67a3ebc467 100644 --- a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngineSide.h +++ b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngineSide.h @@ -28,7 +28,7 @@ class FakeFingerprintEngineSide : public FakeFingerprintEngine { static constexpr int32_t defaultSensorLocationY = 600; static constexpr int32_t defaultSensorRadius = 150; - FakeFingerprintEngineSide() : FakeFingerprintEngine() {} + FakeFingerprintEngineSide(); ~FakeFingerprintEngineSide() {} virtual SensorLocation defaultSensorLocation() override; diff --git a/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineTest.cpp b/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineTest.cpp index bc235a6c65..fe405f4110 100644 --- a/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineTest.cpp +++ b/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineTest.cpp @@ -93,9 +93,13 @@ class TestSessionCallback : public BnSessionCallback { return ndk::ScopedAStatus::ok(); }; ndk::ScopedAStatus onLockoutTimed(int64_t /* timeout */) override { + mLockoutTimed = true; + return ndk::ScopedAStatus::ok(); + } + ndk::ScopedAStatus onLockoutCleared() override { + mLockoutCleared = true; return ndk::ScopedAStatus::ok(); } - ndk::ScopedAStatus onLockoutCleared() override { return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus onSessionClosed() override { return ndk::ScopedAStatus::ok(); } Error mError = Error::UNKNOWN; @@ -110,6 +114,8 @@ class TestSessionCallback : public BnSessionCallback { bool mAuthenticateFailed = false; bool mAuthenticatorIdInvalidated = false; bool mLockoutPermanent = false; + bool mLockoutTimed = false; + bool mLockoutCleared = false; int mInteractionDetectedCount = 0; int32_t mLastAcquiredInfo = -1; int32_t mLastAcquiredVendorCode = -1; @@ -499,6 +505,13 @@ TEST_F(FakeFingerprintEngineTest, randomLatency) { ASSERT_TRUE(latencySet.size() > 95); } +TEST_F(FakeFingerprintEngineTest, lockoutTimer) { + mEngine.startLockoutTimer(200, mCallback.get()); + ASSERT_TRUE(mEngine.getLockoutTimerStarted()); + std::this_thread::sleep_for(std::chrono::milliseconds(210)); + ASSERT_FALSE(mEngine.getLockoutTimerStarted()); + ASSERT_TRUE(mCallback->mLockoutCleared); +} } // namespace aidl::android::hardware::biometrics::fingerprint int main(int argc, char** argv) {