FP won't wake device if daemon dies

Keyguard should retry FP auth if HW unavailable occurs

Fixes: 37483809

Test: enroll FP, turn off screen (enter keyguard)
pid biometrics | xargs adb shell kill -9
after 3 seconds, FP should be able to auth again

Change-Id: Ied3a4c07de655f3145ad40e3b73078fe9b161291
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 7a6ac57..67a2989 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -197,6 +197,11 @@
     private int mFingerprintRunningState = FINGERPRINT_STATE_STOPPED;
     private LockPatternUtils mLockPatternUtils;
 
+    // If FP daemon dies, keyguard should retry after a short delay
+    private int mHardwareUnavailableRetryCount = 0;
+    private static final int HW_UNAVAILABLE_TIMEOUT = 3000; // ms
+    private static final int HW_UNAVAILABLE_RETRY_MAX = 3;
+
     private final Handler mHandler = new Handler() {
         @Override
         public void handleMessage(Message msg) {
@@ -471,6 +476,15 @@
         }
     }
 
+    private Runnable mRetryFingerprintAuthentication = new Runnable() {
+        @Override
+        public void run() {
+            Log.w(TAG, "Retrying fingerprint after HW unavailable, attempt " +
+                    mHardwareUnavailableRetryCount);
+            updateFingerprintListeningState();
+        }
+    };
+
     private void handleFingerprintError(int msgId, String errString) {
         if (msgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED
                 && mFingerprintRunningState == FINGERPRINT_STATE_CANCELLING_RESTARTING) {
@@ -479,6 +493,15 @@
         } else {
             setFingerprintRunningState(FINGERPRINT_STATE_STOPPED);
         }
+
+        if (msgId == FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE) {
+            if (mHardwareUnavailableRetryCount < HW_UNAVAILABLE_RETRY_MAX) {
+                mHardwareUnavailableRetryCount++;
+                mHandler.removeCallbacks(mRetryFingerprintAuthentication);
+                mHandler.postDelayed(mRetryFingerprintAuthentication, HW_UNAVAILABLE_TIMEOUT);
+            }
+        }
+
         for (int i = 0; i < mCallbacks.size(); i++) {
             KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
             if (cb != null) {
@@ -940,6 +963,7 @@
     }
 
     private void handleScreenTurnedOff() {
+        mHardwareUnavailableRetryCount = 0;
         final int count = mCallbacks.size();
         for (int i = 0; i < count; i++) {
             KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
@@ -1072,6 +1096,7 @@
     }
 
     private void updateFingerprintListeningState() {
+        mHandler.removeCallbacks(mRetryFingerprintAuthentication);
         boolean shouldListenForFingerprint = shouldListenForFingerprint();
         if (mFingerprintRunningState == FINGERPRINT_STATE_RUNNING && !shouldListenForFingerprint) {
             stopListeningForFingerprint();