Update fingerprint VHAL operation lifecycle

Bug: 289410175
Test: atest FakeFingerprintEngineTest
Change-Id: I6da68047be9bf5357c1b4c75ba28fc66c2e3bcc0
diff --git a/biometrics/fingerprint/aidl/default/FakeFingerprintEngine.cpp b/biometrics/fingerprint/aidl/default/FakeFingerprintEngine.cpp
index 5f5455a..9757287 100644
--- a/biometrics/fingerprint/aidl/default/FakeFingerprintEngine.cpp
+++ b/biometrics/fingerprint/aidl/default/FakeFingerprintEngine.cpp
@@ -89,24 +89,29 @@
 }
 
 void FakeFingerprintEngine::fingerDownAction() {
+    bool isTerminal = false;
     LOG(INFO) << __func__;
     switch (mWorkMode) {
         case WorkMode::kAuthenticate:
-            onAuthenticateFingerDown(mCb, mOperationId, mCancel);
+            isTerminal = onAuthenticateFingerDown(mCb, mOperationId, mCancel);
             break;
         case WorkMode::kEnroll:
-            onEnrollFingerDown(mCb, mHat, mCancel);
+            isTerminal = onEnrollFingerDown(mCb, mHat, mCancel);
             break;
         case WorkMode::kDetectInteract:
-            onDetectInteractFingerDown(mCb, mCancel);
+            isTerminal = onDetectInteractFingerDown(mCb, mCancel);
             break;
         default:
             LOG(WARNING) << "unexpected mode: on fingerDownAction(), " << (int)mWorkMode;
             break;
     }
+
+    if (isTerminal) {
+        mWorkMode = WorkMode::kIdle;
+    }
 }
 
-void FakeFingerprintEngine::onEnrollFingerDown(ISessionCallback* cb,
+bool FakeFingerprintEngine::onEnrollFingerDown(ISessionCallback* cb,
                                                const keymaster::HardwareAuthToken& hat,
                                                const std::future<void>& cancel) {
     BEGIN_OP(getLatency(FingerprintHalProperties::operation_enroll_latency()));
@@ -115,7 +120,7 @@
     if (hat.mac.empty()) {
         LOG(ERROR) << "Fail: hat";
         cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
-        return;
+        return true;
     }
 
     // Force error-out
@@ -124,7 +129,7 @@
         LOG(ERROR) << "Fail: operation_enroll_error";
         auto ec = convertError(err);
         cb->onError(ec.first, ec.second);
-        return;
+        return true;
     }
 
     // Format is "<id>:<progress_ms-[acquiredInfo..]>,...:<result>
@@ -133,7 +138,7 @@
     if (parts.size() != 3) {
         LOG(ERROR) << "Fail: invalid next_enrollment:" << nextEnroll;
         cb->onError(Error::VENDOR, 0 /* vendorError */);
-        return;
+        return true;
     }
     auto enrollmentId = std::stoi(parts[0]);
     auto progress = parseEnrollmentCapture(parts[1]);
@@ -149,7 +154,7 @@
             if (shouldCancel(cancel)) {
                 LOG(ERROR) << "Fail: cancel";
                 cb->onError(Error::CANCELED, 0 /* vendorCode */);
-                return;
+                return true;
             }
             auto ac = convertAcquiredInfo(acquired[j]);
             cb->onAcquired(ac.first, ac.second);
@@ -175,9 +180,11 @@
             cb->onEnrollmentProgress(enrollmentId, left);
         }
     }
+
+    return true;
 }
 
-void FakeFingerprintEngine::onAuthenticateFingerDown(ISessionCallback* cb,
+bool FakeFingerprintEngine::onAuthenticateFingerDown(ISessionCallback* cb,
                                                      int64_t /* operationId */,
                                                      const std::future<void>& cancel) {
     BEGIN_OP(getLatency(FingerprintHalProperties::operation_authenticate_latency()));
@@ -191,11 +198,13 @@
     if (N == 0) {
         LOG(ERROR) << "Fail to parse authentiate acquired info: " + acquired;
         cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
-        return;
+        return true;
     }
 
     // got lockout?
-    if (checkSensorLockout(cb)) return;
+    if (checkSensorLockout(cb)) {
+        return FakeLockoutTracker::LockoutMode::kPermanent == mLockoutTracker.getMode();
+    }
 
     int i = 0;
     do {
@@ -203,7 +212,7 @@
             LOG(ERROR) << "Fail: operation_authenticate_fails";
             mLockoutTracker.addFailedAttempt();
             cb->onAuthenticationFailed();
-            return;
+            return false;
         }
 
         auto err = FingerprintHalProperties::operation_authenticate_error().value_or(0);
@@ -211,20 +220,21 @@
             LOG(ERROR) << "Fail: operation_authenticate_error";
             auto ec = convertError(err);
             cb->onError(ec.first, ec.second);
-            return;
+            return true; /* simply terminating current operation for any user inserted error,
+                            revisit if tests need*/
         }
 
         if (FingerprintHalProperties::lockout().value_or(false)) {
             LOG(ERROR) << "Fail: lockout";
             cb->onLockoutPermanent();
             cb->onError(Error::HW_UNAVAILABLE, 0 /* vendorError */);
-            return;
+            return true;
         }
 
         if (shouldCancel(cancel)) {
             LOG(ERROR) << "Fail: cancel";
             cb->onError(Error::CANCELED, 0 /* vendorCode */);
-            return;
+            return true;
         }
 
         if (i < N) {
@@ -242,16 +252,17 @@
     if (id > 0 && isEnrolled) {
         cb->onAuthenticationSucceeded(id, {} /* hat */);
         mLockoutTracker.reset();
-        return;
+        return true;
     } else {
         LOG(ERROR) << "Fail: fingerprint not enrolled";
         cb->onAuthenticationFailed();
         mLockoutTracker.addFailedAttempt();
         checkSensorLockout(cb);
+        return true;
     }
 }
 
-void FakeFingerprintEngine::onDetectInteractFingerDown(ISessionCallback* cb,
+bool FakeFingerprintEngine::onDetectInteractFingerDown(ISessionCallback* cb,
                                                        const std::future<void>& cancel) {
     BEGIN_OP(getLatency(FingerprintHalProperties::operation_detect_interaction_latency()));
 
@@ -266,7 +277,7 @@
     if (N == 0) {
         LOG(ERROR) << "Fail to parse detect interaction acquired info: " + acquired;
         cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
-        return;
+        return true;
     }
 
     int i = 0;
@@ -276,13 +287,13 @@
             LOG(ERROR) << "Fail: operation_detect_interaction_error";
             auto ec = convertError(err);
             cb->onError(ec.first, ec.second);
-            return;
+            return true;
         }
 
         if (shouldCancel(cancel)) {
             LOG(ERROR) << "Fail: cancel";
             cb->onError(Error::CANCELED, 0 /* vendorCode */);
-            return;
+            return true;
         }
 
         if (i < N) {
@@ -299,10 +310,12 @@
     if (id <= 0 || !isEnrolled) {
         LOG(ERROR) << "Fail: not enrolled";
         cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
-        return;
+        return true;
     }
 
     cb->onInteractionDetected();
+
+    return true;
 }
 
 void FakeFingerprintEngine::enumerateEnrollmentsImpl(ISessionCallback* cb) {
diff --git a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h
index 8ac7a95..a06b786 100644
--- a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h
+++ b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h
@@ -94,10 +94,10 @@
     virtual void updateContext(WorkMode mode, ISessionCallback* cb, std::future<void>& cancel,
                                int64_t operationId, const keymaster::HardwareAuthToken& hat);
 
-    void onEnrollFingerDown(ISessionCallback* cb, const keymaster::HardwareAuthToken& hat,
+    bool onEnrollFingerDown(ISessionCallback* cb, const keymaster::HardwareAuthToken& hat,
                             const std::future<void>& cancel);
-    void onAuthenticateFingerDown(ISessionCallback* cb, int64_t, const std::future<void>& cancel);
-    void onDetectInteractFingerDown(ISessionCallback* cb, const std::future<void>& cancel);
+    bool onAuthenticateFingerDown(ISessionCallback* cb, int64_t, const std::future<void>& cancel);
+    bool onDetectInteractFingerDown(ISessionCallback* cb, const std::future<void>& cancel);
 
     WorkMode mWorkMode;
     ISessionCallback* mCb;
diff --git a/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineTest.cpp b/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineTest.cpp
index 86207a5..e7e8a47 100644
--- a/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineTest.cpp
+++ b/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineTest.cpp
@@ -132,6 +132,8 @@
         FingerprintHalProperties::operation_enroll_latency({});
         FingerprintHalProperties::operation_authenticate_latency({});
         FingerprintHalProperties::operation_detect_interaction_latency({});
+        FingerprintHalProperties::operation_authenticate_fails(false);
+        FingerprintHalProperties::operation_detect_interaction_latency({});
     }
 
     FakeFingerprintEngine mEngine;
@@ -185,6 +187,7 @@
     ASSERT_EQ(4, FingerprintHalProperties::enrollments()[0].value());
     ASSERT_EQ(4, mCallback->mLastEnrolled);
     ASSERT_EQ(1, mCallback->mLastAcquiredInfo);
+    ASSERT_EQ(mEngine.getWorkMode(), FakeFingerprintEngine::WorkMode::kIdle);
 }
 
 TEST_F(FakeFingerprintEngineTest, EnrollCancel) {
@@ -239,6 +242,7 @@
     ASSERT_FALSE(mCallback->mAuthenticateFailed);
     ASSERT_EQ(2, mCallback->mLastAuthenticated);
     ASSERT_EQ(1, mCallback->mLastAcquiredInfo);
+    ASSERT_EQ(mEngine.getWorkMode(), FakeFingerprintEngine::WorkMode::kIdle);
 }
 
 TEST_F(FakeFingerprintEngineTest, AuthenticateCancel) {
@@ -293,6 +297,14 @@
     ASSERT_EQ(mCallback->mErrorVendorCode, 9);
 }
 
+TEST_F(FakeFingerprintEngineTest, AuthenticateFails) {
+    FingerprintHalProperties::operation_authenticate_fails(true);
+    mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
+    mEngine.fingerDownAction();
+    ASSERT_TRUE(mCallback->mAuthenticateFailed);
+    ASSERT_EQ(mEngine.getWorkMode(), FakeFingerprintEngine::WorkMode::kAuthenticate);
+}
+
 TEST_F(FakeFingerprintEngineTest, AuthenticateAcquired) {
     FingerprintHalProperties::lockout(false);
     FingerprintHalProperties::enrollments({1, 2});
@@ -318,6 +330,7 @@
     mEngine.fingerDownAction();
     ASSERT_EQ(1, mCallback->mInteractionDetectedCount);
     ASSERT_EQ(1, mCallback->mLastAcquiredInfo);
+    ASSERT_EQ(mEngine.getWorkMode(), FakeFingerprintEngine::WorkMode::kIdle);
 }
 
 TEST_F(FakeFingerprintEngineTest, InteractionDetectCancel) {
@@ -483,7 +496,6 @@
                 FingerprintHalProperties::operation_detect_interaction_latency()));
     }
     ASSERT_TRUE(latencySet.size() > 95);
-    FingerprintHalProperties::operation_detect_interaction_latency({});
 }
 
 }  // namespace aidl::android::hardware::biometrics::fingerprint