Add Fingerprint Dialog to SysUI

Bug: 67497360

Test: Modify settings to use new API
Change-Id: I93ef475852c15e4a1a2a54bdd23ae4b8a0b8b7d7
diff --git a/packages/SystemUI/src/com/android/systemui/fingerprint/FingerprintDialogImpl.java b/packages/SystemUI/src/com/android/systemui/fingerprint/FingerprintDialogImpl.java
index 8b6f95c..1b785a2 100644
--- a/packages/SystemUI/src/com/android/systemui/fingerprint/FingerprintDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/fingerprint/FingerprintDialogImpl.java
@@ -16,17 +16,75 @@
 
 package com.android.systemui.fingerprint;
 
+import android.content.Context;
 import android.content.pm.PackageManager;
+import android.hardware.fingerprint.FingerprintDialog;
 import android.hardware.fingerprint.IFingerprintDialogReceiver;
 import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.os.RemoteException;
 import android.util.Log;
+import android.view.WindowManager;
 
+import com.android.internal.os.SomeArgs;
 import com.android.systemui.SystemUI;
 import com.android.systemui.statusbar.CommandQueue;
 
 public class FingerprintDialogImpl extends SystemUI implements CommandQueue.Callbacks {
     private static final String TAG = "FingerprintDialogImpl";
-    private static final boolean DEBUG = false;
+    private static final boolean DEBUG = true;
+
+    protected static final int MSG_SHOW_DIALOG = 1;
+    protected static final int MSG_FINGERPRINT_AUTHENTICATED = 2;
+    protected static final int MSG_FINGERPRINT_HELP = 3;
+    protected static final int MSG_FINGERPRINT_ERROR = 4;
+    protected static final int MSG_HIDE_DIALOG = 5;
+    protected static final int MSG_BUTTON_NEGATIVE = 6;
+    protected static final int MSG_USER_CANCELED = 7;
+    protected static final int MSG_BUTTON_POSITIVE = 8;
+    protected static final int MSG_CLEAR_MESSAGE = 9;
+
+
+    private FingerprintDialogView mDialogView;
+    private WindowManager mWindowManager;
+    private IFingerprintDialogReceiver mReceiver;
+    private boolean mDialogShowing;
+
+    private Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            switch(msg.what) {
+                case MSG_SHOW_DIALOG:
+                    handleShowDialog((SomeArgs) msg.obj);
+                    break;
+                case MSG_FINGERPRINT_AUTHENTICATED:
+                    handleFingerprintAuthenticated();
+                    break;
+                case MSG_FINGERPRINT_HELP:
+                    handleFingerprintHelp((String) msg.obj);
+                    break;
+                case MSG_FINGERPRINT_ERROR:
+                    handleFingerprintError((String) msg.obj);
+                    break;
+                case MSG_HIDE_DIALOG:
+                    handleHideDialog((Boolean) msg.obj);
+                    break;
+                case MSG_BUTTON_NEGATIVE:
+                    handleButtonNegative();
+                    break;
+                case MSG_USER_CANCELED:
+                    handleUserCanceled();
+                    break;
+                case MSG_BUTTON_POSITIVE:
+                    handleButtonPositive();
+                    break;
+                case MSG_CLEAR_MESSAGE:
+                    handleClearMessage();
+                    break;
+            }
+        }
+    };
 
     @Override
     public void start() {
@@ -34,30 +92,129 @@
             return;
         }
         getComponent(CommandQueue.class).addCallbacks(this);
+        mWindowManager =  (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
+        mDialogView = new FingerprintDialogView(mContext, mHandler);
     }
 
     @Override
     public void showFingerprintDialog(Bundle bundle, IFingerprintDialogReceiver receiver) {
-        if (DEBUG) Log.d(TAG, "show fingerprint dialog");
+        if (DEBUG) Log.d(TAG, "showFingerprintDialog");
+        // Remove these messages as they are part of the previous client
+        mHandler.removeMessages(MSG_FINGERPRINT_ERROR);
+        mHandler.removeMessages(MSG_FINGERPRINT_HELP);
+        mHandler.removeMessages(MSG_FINGERPRINT_AUTHENTICATED);
+        SomeArgs args = SomeArgs.obtain();
+        args.arg1 = bundle;
+        args.arg2 = receiver;
+        mHandler.obtainMessage(MSG_SHOW_DIALOG, args).sendToTarget();
     }
 
     @Override
     public void onFingerprintAuthenticated() {
         if (DEBUG) Log.d(TAG, "onFingerprintAuthenticated");
+        mHandler.obtainMessage(MSG_FINGERPRINT_AUTHENTICATED).sendToTarget();
     }
 
     @Override
     public void onFingerprintHelp(String message) {
         if (DEBUG) Log.d(TAG, "onFingerprintHelp: " + message);
+        mHandler.obtainMessage(MSG_FINGERPRINT_HELP, message).sendToTarget();
     }
 
     @Override
     public void onFingerprintError(String error) {
         if (DEBUG) Log.d(TAG, "onFingerprintError: " + error);
+        mHandler.obtainMessage(MSG_FINGERPRINT_ERROR, error).sendToTarget();
     }
 
     @Override
     public void hideFingerprintDialog() {
         if (DEBUG) Log.d(TAG, "hideFingerprintDialog");
+        mHandler.obtainMessage(MSG_HIDE_DIALOG, false /* userCanceled */).sendToTarget();
+    }
+
+    private void handleShowDialog(SomeArgs args) {
+        if (DEBUG) Log.d(TAG, "handleShowDialog");
+        if (mDialogShowing) {
+            Log.w(TAG, "Dialog already showing");
+            return;
+        }
+        mReceiver = (IFingerprintDialogReceiver) args.arg2;
+        mDialogView.setBundle((Bundle)args.arg1);
+        mWindowManager.addView(mDialogView, mDialogView.getLayoutParams());
+        mDialogShowing = true;
+    }
+
+    private void handleFingerprintAuthenticated() {
+        if (DEBUG) Log.d(TAG, "handleFingerprintAuthenticated");
+        handleHideDialog(false /* userCanceled */);
+    }
+
+    private void handleFingerprintHelp(String message) {
+        if (DEBUG) Log.d(TAG, "handleFingerprintHelp: " + message);
+        mDialogView.showHelpMessage(message);
+    }
+
+    private void handleFingerprintError(String error) {
+        if (DEBUG) Log.d(TAG, "handleFingerprintError: " + error);
+        if (!mDialogShowing) {
+            if (DEBUG) Log.d(TAG, "Dialog already dismissed");
+            return;
+        }
+        mDialogView.showErrorMessage(error);
+    }
+
+    private void handleHideDialog(boolean userCanceled) {
+        if (DEBUG) Log.d(TAG, "handleHideDialog");
+        if (!mDialogShowing) {
+            // This can happen if there's a race and we get called from both
+            // onAuthenticated and onError, etc.
+            Log.w(TAG, "Dialog already dismissed, userCanceled: " + userCanceled);
+            return;
+        }
+        if (userCanceled) {
+            try {
+                mReceiver.onDialogDismissed(FingerprintDialog.DISMISSED_REASON_USER_CANCEL);
+            } catch (RemoteException e) {
+                Log.e(TAG, "RemoteException when hiding dialog", e);
+            }
+        }
+        mReceiver = null;
+        mWindowManager.removeView(mDialogView);
+        mDialogShowing = false;
+    }
+
+    private void handleButtonNegative() {
+        if (mReceiver == null) {
+            Log.e(TAG, "Receiver is null");
+            return;
+        }
+        try {
+            mReceiver.onDialogDismissed(FingerprintDialog.DISMISSED_REASON_NEGATIVE);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Remote exception when handling negative button", e);
+        }
+        handleHideDialog(false /* userCanceled */);
+    }
+
+    private void handleButtonPositive() {
+        if (mReceiver == null) {
+            Log.e(TAG, "Receiver is null");
+            return;
+        }
+        try {
+            mReceiver.onDialogDismissed(FingerprintDialog.DISMISSED_REASON_POSITIVE);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Remote exception when handling positive button", e);
+        }
+        handleHideDialog(false /* userCanceled */);
+    }
+
+    private void handleClearMessage() {
+        mDialogView.clearMessage();
+    }
+
+    private void handleUserCanceled() {
+        handleHideDialog(true /* userCanceled */);
     }
 }