Add more robust handling of daemon crashes

It seems the new fingerprint daemon doesn't recover as quickly as before
and there's a finite chance reconnecting immediately will fail.

This changes the framework to be more robust about recovering by:

1. explicitly connecting to the daemon in isHardwareDetected()
2. ensuring we remove the current client when daemon death is detected
3. reset the daemon whenever we get HW_UNAVAILABLE so we try again

Test: manually kill daemon and verify FingerprintService reconnects

Partial fix for bug 36181191

Change-Id: Id530ed62be58b33af5b5b60083f3a69e4e8cd8bf
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java
index bdba64f..7d97ce4 100644
--- a/services/core/java/com/android/server/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java
@@ -217,6 +217,7 @@
 
     public synchronized IBiometricsFingerprint getFingerprintDaemon() {
         if (mDaemon == null) {
+            Slog.v(TAG, "mDeamon was null, reconnect to fingerprint");
             try {
                 mDaemon = IBiometricsFingerprint.getService();
             } catch (java.util.NoSuchElementException e) {
@@ -292,6 +293,13 @@
                 startClient(mPendingClient, false);
                 mPendingClient = null;
             }
+        } else if (error == FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE) {
+            // If we get HW_UNAVAILABLE, try to connect again later...
+            Slog.w(TAG, "Got ERROR_HW_UNAVAILABLE; try reconnecting next client.");
+            synchronized (this) {
+                mDaemon = null;
+                mHalDeviceId = 0;
+            }
         }
     }
 
@@ -995,7 +1003,8 @@
                     Binder.getCallingUid(), Binder.getCallingPid())) {
                 return false;
             }
-            return mHalDeviceId != 0;
+            IBiometricsFingerprint daemon = getFingerprintDaemon();
+            return daemon != null && mHalDeviceId != 0;
         }
 
         @Override // Binder call