Indicating fingerprint error messages on the bouncer now

Also ensure that error messages are surfaced when the screen
comes on such that the user knows why his fingerprint is not
working.

Bug: 22035466
Bug: 22524101
Change-Id: I00b0e833cdb8a3475545ba75b8cb7bf7a419dfd4
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 31c94f7..54f91da 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -16,18 +16,13 @@
 
 package com.android.systemui.statusbar;
 
-import com.android.internal.app.IBatteryStats;
-import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.keyguard.KeyguardUpdateMonitorCallback;
-import com.android.systemui.R;
-import com.android.systemui.statusbar.phone.KeyguardIndicationTextView;
-
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.res.Resources;
 import android.graphics.Color;
+import android.hardware.fingerprint.FingerprintManager;
 import android.os.BatteryManager;
 import android.os.BatteryStats;
 import android.os.Handler;
@@ -40,8 +35,16 @@
 import android.util.Log;
 import android.view.View;
 
+import com.android.internal.app.IBatteryStats;
+import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.keyguard.KeyguardUpdateMonitorCallback;
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.KeyguardIndicationTextView;
+import com.android.systemui.statusbar.phone.LockIcon;
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
+
 /**
- * Controls the little text indicator on the keyguard.
+ * Controls the indications and error messages shown on the Keyguard
  */
 public class KeyguardIndicationController {
 
@@ -49,6 +52,8 @@
     private static final boolean DEBUG_CHARGING_CURRENT = false;
 
     private static final int MSG_HIDE_TRANSIENT = 1;
+    private static final int MSG_CLEAR_FP_MSG = 2;
+    private static final long TRANSIENT_FP_ERROR_TIMEOUT = 1300;
 
     private final Context mContext;
     private final KeyguardIndicationTextView mTextView;
@@ -56,6 +61,8 @@
 
     private final int mSlowThreshold;
     private final int mFastThreshold;
+    private final LockIcon mLockIcon;
+    private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
 
     private String mRestingIndication;
     private String mTransientIndication;
@@ -66,10 +73,13 @@
     private boolean mPowerCharged;
     private int mChargingSpeed;
     private int mChargingCurrent;
+    private String mMessageToShowOnScreenOn;
 
-    public KeyguardIndicationController(Context context, KeyguardIndicationTextView textView) {
+    public KeyguardIndicationController(Context context, KeyguardIndicationTextView textView,
+                                        LockIcon lockIcon) {
         mContext = context;
         mTextView = textView;
+        mLockIcon = lockIcon;
 
         Resources res = context.getResources();
         mSlowThreshold = res.getInteger(R.integer.config_chargingSlowlyThreshold);
@@ -216,6 +226,64 @@
             mChargingSpeed = status.getChargingSpeed(mSlowThreshold, mFastThreshold);
             updateIndication();
         }
+
+        @Override
+        public void onFingerprintHelp(int msgId, String helpString) {
+            KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
+            if (!updateMonitor.isUnlockingWithFingerprintAllowed()) {
+                return;
+            }
+            int errorColor = mContext.getResources().getColor(R.color.system_warning_color, null);
+            if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
+                mStatusBarKeyguardViewManager.showBouncerMessage(helpString, errorColor);
+            } else if (updateMonitor.isDeviceInteractive()) {
+                mLockIcon.setTransientFpError(true);
+                showTransientIndication(helpString, errorColor);
+                mHandler.removeMessages(MSG_CLEAR_FP_MSG);
+                mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_CLEAR_FP_MSG),
+                        TRANSIENT_FP_ERROR_TIMEOUT);
+            }
+        }
+
+        @Override
+        public void onFingerprintError(int msgId, String errString) {
+            KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
+            if (!updateMonitor.isUnlockingWithFingerprintAllowed()
+                    || msgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED) {
+                return;
+            }
+            int errorColor = mContext.getResources().getColor(R.color.system_warning_color, null);
+            if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
+                mStatusBarKeyguardViewManager.showBouncerMessage(errString, errorColor);
+            } else if (updateMonitor.isDeviceInteractive()) {
+                    showTransientIndication(errString, errorColor);
+                    // We want to keep this message around in case the screen was off
+                    mHandler.removeMessages(MSG_HIDE_TRANSIENT);
+                    hideTransientIndicationDelayed(5000);
+             } else {
+                    mMessageToShowOnScreenOn = errString;
+            }
+        }
+
+        @Override
+        public void onScreenTurnedOn() {
+            if (mMessageToShowOnScreenOn != null) {
+                int errorColor = mContext.getResources().getColor(R.color.system_warning_color,
+                        null);
+                showTransientIndication(mMessageToShowOnScreenOn, errorColor);
+                // We want to keep this message around in case the screen was off
+                mHandler.removeMessages(MSG_HIDE_TRANSIENT);
+                hideTransientIndicationDelayed(5000);
+                mMessageToShowOnScreenOn = null;
+            }
+        }
+
+        @Override
+        public void onFingerprintRunningStateChanged(boolean running) {
+            if (running) {
+                mMessageToShowOnScreenOn = null;
+            }
+        }
     };
 
     BroadcastReceiver mReceiver = new BroadcastReceiver() {
@@ -233,7 +301,15 @@
             if (msg.what == MSG_HIDE_TRANSIENT && mTransientIndication != null) {
                 mTransientIndication = null;
                 updateIndication();
+            } else if (msg.what == MSG_CLEAR_FP_MSG) {
+                mLockIcon.setTransientFpError(false);
+                hideTransientIndication();
             }
         }
     };
+
+    public void setStatusBarKeyguardViewManager(
+            StatusBarKeyguardViewManager statusBarKeyguardViewManager) {
+        mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
+    }
 }