2/n: Refactor common code from FingerprintDialogView

Bug: 111461540

Test: BiometricPromptDemo works
Change-Id: I7077b062f1da0e084a38d5d53248123a82456a48
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java
index 7359daa..327eba7 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java
@@ -116,7 +116,7 @@
         }
         getComponent(CommandQueue.class).addCallbacks(this);
         mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
-        mDialogView = new BiometricDialogView(mContext, mCallback);
+        mDialogView = new FingerprintDialogView(mContext, mCallback);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java
index 9ebd54b..50ee88c 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java
@@ -19,8 +19,6 @@
 import android.content.Context;
 import android.graphics.Color;
 import android.graphics.PixelFormat;
-import android.graphics.drawable.AnimatedVectorDrawable;
-import android.graphics.drawable.Drawable;
 import android.hardware.biometrics.BiometricPrompt;
 import android.os.Binder;
 import android.os.Bundle;
@@ -38,7 +36,6 @@
 import android.view.WindowManager;
 import android.view.animation.Interpolator;
 import android.widget.Button;
-import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
@@ -46,11 +43,9 @@
 import com.android.systemui.R;
 
 /**
- * This class loads the view for the system-provided dialog. The view consists of:
- * Application Icon, Title, Subtitle, Description, Fingerprint Icon, Error/Help message area,
- * and positive/negative buttons.
+ * Abstract base class. Shows a dialog for BiometricPrompt.
  */
-public class BiometricDialogView extends LinearLayout {
+public abstract class BiometricDialogView extends LinearLayout {
 
     private static final String TAG = "BiometricDialogView";
 
@@ -59,10 +54,10 @@
 
     private static final int MSG_CLEAR_MESSAGE = 1;
 
-    private static final int STATE_NONE = 0;
-    private static final int STATE_FINGERPRINT = 1;
-    private static final int STATE_FINGERPRINT_ERROR = 2;
-    private static final int STATE_FINGERPRINT_AUTHENTICATED = 3;
+    protected static final int STATE_NONE = 0;
+    protected static final int STATE_AUTHENTICATING = 1;
+    protected static final int STATE_ERROR = 2;
+    protected static final int STATE_AUTHENTICATED = 3;
 
     private final IBinder mWindowToken = new Binder();
     private final Interpolator mLinearOutSlowIn;
@@ -70,7 +65,6 @@
     private final float mAnimationTranslationOffset;
     private final int mErrorColor;
     private final int mTextColor;
-    private final int mFingerprintColor;
     private final float mDisplayWidth;
     private final DialogViewCallback mCallback;
 
@@ -82,6 +76,11 @@
     private boolean mAnimatingAway;
     private boolean mWasForceRemoved;
 
+    protected abstract int getLayoutResourceId();
+    protected abstract float getAnimationTranslationOffset();
+    protected abstract void updateIcon(int lastState, int newState);
+    protected abstract int getHintStringResource();
+
     private final Runnable mShowAnimationRunnable = new Runnable() {
         @Override
         public void run() {
@@ -119,14 +118,11 @@
         mCallback = callback;
         mLinearOutSlowIn = Interpolators.LINEAR_OUT_SLOW_IN;
         mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
-        mAnimationTranslationOffset = getResources()
-                .getDimension(R.dimen.fingerprint_dialog_animation_translation_offset);
+        mAnimationTranslationOffset = getAnimationTranslationOffset();
         mErrorColor = Color.parseColor(
-                getResources().getString(R.color.fingerprint_dialog_error_color));
+                getResources().getString(R.color.biometric_dialog_error_color));
         mTextColor = Color.parseColor(
-                getResources().getString(R.color.fingerprint_dialog_text_light_color));
-        mFingerprintColor = Color.parseColor(
-                getResources().getString(R.color.fingerprint_dialog_fingerprint_color));
+                getResources().getString(R.color.biometric_dialog_text_light_color));
 
         DisplayMetrics metrics = new DisplayMetrics();
         mWindowManager.getDefaultDisplay().getMetrics(metrics);
@@ -134,7 +130,7 @@
 
         // Create the dialog
         LayoutInflater factory = LayoutInflater.from(getContext());
-        mLayout = (ViewGroup) factory.inflate(R.layout.fingerprint_dialog, this, false);
+        mLayout = (ViewGroup) factory.inflate(getLayoutResourceId(), this, false);
         addView(mLayout);
 
         mDialog = mLayout.findViewById(R.id.dialog);
@@ -195,7 +191,7 @@
         mDialog.getLayoutParams().width = (int) mDisplayWidth;
 
         mLastState = STATE_NONE;
-        updateFingerprintIcon(STATE_FINGERPRINT);
+        updateState(STATE_AUTHENTICATING);
 
         title.setText(mBundle.getCharSequence(BiometricPrompt.KEY_TITLE));
         title.setSelected(true);
@@ -303,17 +299,21 @@
         mBundle = bundle;
     }
 
+    public ViewGroup getLayout() {
+        return mLayout;
+    }
+
     // Clears the temporary message and shows the help message.
     private void handleClearMessage() {
-        updateFingerprintIcon(STATE_FINGERPRINT);
-        mErrorText.setText(R.string.fingerprint_dialog_touch_sensor);
+        updateState(STATE_AUTHENTICATING);
+        mErrorText.setText(getHintStringResource());
         mErrorText.setTextColor(mTextColor);
     }
 
     // Shows an error/help message
     private void showTemporaryMessage(String message) {
         mHandler.removeMessages(MSG_CLEAR_MESSAGE);
-        updateFingerprintIcon(STATE_FINGERPRINT_ERROR);
+        updateState(STATE_ERROR);
         mErrorText.setText(message);
         mErrorText.setTextColor(mErrorColor);
         mErrorText.setContentDescription(message);
@@ -330,61 +330,11 @@
         mCallback.onErrorShown();
     }
 
-    private void updateFingerprintIcon(int newState) {
-        Drawable icon  = getAnimationForTransition(mLastState, newState);
-
-        if (icon == null) {
-            Log.e(TAG, "Animation not found");
-            return;
-        }
-
-        final AnimatedVectorDrawable animation = icon instanceof AnimatedVectorDrawable
-                ? (AnimatedVectorDrawable) icon
-                : null;
-
-        final ImageView fingerprint_icon = mLayout.findViewById(R.id.fingerprint_icon);
-        fingerprint_icon.setImageDrawable(icon);
-
-        if (animation != null && shouldAnimateForTransition(mLastState, newState)) {
-            animation.forceAnimationOnUI();
-            animation.start();
-        }
-
+    private void updateState(int newState) {
+        updateIcon(mLastState, newState);
         mLastState = newState;
     }
 
-    private boolean shouldAnimateForTransition(int oldState, int newState) {
-        if (oldState == STATE_NONE && newState == STATE_FINGERPRINT) {
-            return false;
-        } else if (oldState == STATE_FINGERPRINT && newState == STATE_FINGERPRINT_ERROR) {
-            return true;
-        } else if (oldState == STATE_FINGERPRINT_ERROR && newState == STATE_FINGERPRINT) {
-            return true;
-        } else if (oldState == STATE_FINGERPRINT && newState == STATE_FINGERPRINT_AUTHENTICATED) {
-            // TODO(b/77328470): add animation when fingerprint is authenticated
-            return false;
-        }
-        return false;
-    }
-
-    private Drawable getAnimationForTransition(int oldState, int newState) {
-        int iconRes;
-        if (oldState == STATE_NONE && newState == STATE_FINGERPRINT) {
-            iconRes = R.drawable.fingerprint_dialog_fp_to_error;
-        } else if (oldState == STATE_FINGERPRINT && newState == STATE_FINGERPRINT_ERROR) {
-            iconRes = R.drawable.fingerprint_dialog_fp_to_error;
-        } else if (oldState == STATE_FINGERPRINT_ERROR && newState == STATE_FINGERPRINT) {
-            iconRes = R.drawable.fingerprint_dialog_error_to_fp;
-        } else if (oldState == STATE_FINGERPRINT && newState == STATE_FINGERPRINT_AUTHENTICATED) {
-            // TODO(b/77328470): add animation when fingerprint is authenticated
-            iconRes = R.drawable.fingerprint_dialog_error_to_fp;
-        }
-        else {
-            return null;
-        }
-        return mContext.getDrawable(iconRes);
-    }
-
     public WindowManager.LayoutParams getLayoutParams() {
         final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
                 ViewGroup.LayoutParams.MATCH_PARENT,
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintDialogView.java b/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintDialogView.java
new file mode 100644
index 0000000..9033322
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintDialogView.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.biometrics;
+
+import android.content.Context;
+import android.graphics.drawable.AnimatedVectorDrawable;
+import android.graphics.drawable.Drawable;
+import android.util.Log;
+import android.widget.ImageView;
+
+import com.android.systemui.R;
+
+/**
+ * This class loads the view for the system-provided dialog. The view consists of:
+ * Application Icon, Title, Subtitle, Description, Fingerprint Icon, Error/Help message area,
+ * and positive/negative buttons.
+ */
+public class FingerprintDialogView extends BiometricDialogView {
+    private static final String TAG = "FingerprintDialogView";
+
+    @Override
+    protected int getLayoutResourceId() {
+        return R.layout.fingerprint_dialog;
+    }
+
+    @Override
+    protected int getHintStringResource() {
+        return R.string.fingerprint_dialog_touch_sensor;
+    }
+
+    @Override
+    protected float getAnimationTranslationOffset() {
+        return getResources()
+                .getDimension(R.dimen.fingerprint_dialog_animation_translation_offset);
+    }
+
+    @Override
+    protected void updateIcon(int lastState, int newState) {
+        Drawable icon = getAnimationForTransition(lastState, newState);
+
+        if (icon == null) {
+            Log.e(TAG, "Animation not found");
+            return;
+        }
+
+        final AnimatedVectorDrawable animation = icon instanceof AnimatedVectorDrawable
+                ? (AnimatedVectorDrawable) icon
+                : null;
+
+        final ImageView fingerprint_icon = getLayout().findViewById(R.id.fingerprint_icon);
+        fingerprint_icon.setImageDrawable(icon);
+
+        if (animation != null && shouldAnimateForTransition(lastState, newState)) {
+            animation.forceAnimationOnUI();
+            animation.start();
+        }
+    }
+
+    public FingerprintDialogView(Context context,
+            DialogViewCallback callback) {
+        super(context, callback);
+    }
+
+    private boolean shouldAnimateForTransition(int oldState, int newState) {
+        if (oldState == STATE_NONE && newState == STATE_AUTHENTICATING) {
+            return false;
+        } else if (oldState == STATE_AUTHENTICATING && newState == STATE_ERROR) {
+            return true;
+        } else if (oldState == STATE_ERROR && newState == STATE_AUTHENTICATING) {
+            return true;
+        } else if (oldState == STATE_AUTHENTICATING && newState == STATE_AUTHENTICATED) {
+            // TODO(b/77328470): add animation when fingerprint is authenticated
+            return false;
+        }
+        return false;
+    }
+
+    private Drawable getAnimationForTransition(int oldState, int newState) {
+        int iconRes;
+        if (oldState == STATE_NONE && newState == STATE_AUTHENTICATING) {
+            iconRes = R.drawable.fingerprint_dialog_fp_to_error;
+        } else if (oldState == STATE_AUTHENTICATING && newState == STATE_ERROR) {
+            iconRes = R.drawable.fingerprint_dialog_fp_to_error;
+        } else if (oldState == STATE_ERROR && newState == STATE_AUTHENTICATING) {
+            iconRes = R.drawable.fingerprint_dialog_error_to_fp;
+        } else if (oldState == STATE_AUTHENTICATING && newState == STATE_AUTHENTICATED) {
+            // TODO(b/77328470): add animation when fingerprint is authenticated
+            iconRes = R.drawable.fingerprint_dialog_error_to_fp;
+        } else {
+            return null;
+        }
+        return mContext.getDrawable(iconRes);
+    }
+}
\ No newline at end of file