diff --git a/packages/SystemUI/res/drawable/face_dialog_error_to_face.xml b/packages/SystemUI/res/drawable/face_dialog_error_to_face.xml
new file mode 100644
index 0000000000000..75311f44dfe3e
--- /dev/null
+++ b/packages/SystemUI/res/drawable/face_dialog_error_to_face.xml
@@ -0,0 +1,517 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/face_dialog_face_blue_to_checkmark.xml b/packages/SystemUI/res/drawable/face_dialog_face_blue_to_checkmark.xml
new file mode 100644
index 0000000000000..e4ace67577c39
--- /dev/null
+++ b/packages/SystemUI/res/drawable/face_dialog_face_blue_to_checkmark.xml
@@ -0,0 +1,637 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/face_dialog_face_gray_to_checkmark.xml b/packages/SystemUI/res/drawable/face_dialog_face_gray_to_checkmark.xml
new file mode 100644
index 0000000000000..b09f69b742bb9
--- /dev/null
+++ b/packages/SystemUI/res/drawable/face_dialog_face_gray_to_checkmark.xml
@@ -0,0 +1,637 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/face_dialog_face_gray_to_face_blue.xml b/packages/SystemUI/res/drawable/face_dialog_face_gray_to_face_blue.xml
new file mode 100644
index 0000000000000..9259dc7bb9774
--- /dev/null
+++ b/packages/SystemUI/res/drawable/face_dialog_face_gray_to_face_blue.xml
@@ -0,0 +1,178 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/face_dialog_face_to_error.xml b/packages/SystemUI/res/drawable/face_dialog_face_to_error.xml
new file mode 100644
index 0000000000000..a96d21addb2b7
--- /dev/null
+++ b/packages/SystemUI/res/drawable/face_dialog_face_to_error.xml
@@ -0,0 +1,473 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/face_dialog_icon.xml b/packages/SystemUI/res/drawable/face_dialog_icon.xml
deleted file mode 100644
index 6d28b5a105f2e..0000000000000
--- a/packages/SystemUI/res/drawable/face_dialog_icon.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/fingerprint_dialog_error_to_fp.xml b/packages/SystemUI/res/drawable/fingerprint_dialog_error_to_fp.xml
index af25e44bd7460..8f411f4c07feb 100644
--- a/packages/SystemUI/res/drawable/fingerprint_dialog_error_to_fp.xml
+++ b/packages/SystemUI/res/drawable/fingerprint_dialog_error_to_fp.xml
@@ -18,336 +18,268 @@
xmlns:aapt="http://schemas.android.com/aapt">
+ android:width="60dp"
+ android:height="60dp"
+ android:viewportHeight="60"
+ android:viewportWidth="60">
-
-
-
-
-
-
-
-
-
-
+ android:name="_R_G_L_1_G_N_4_T_0"
+ android:translateX="30"
+ android:translateY="30">
+ android:name="_R_G_L_1_G"
+ android:pivotX="114"
+ android:pivotY="114"
+ android:scaleX="0.42200000000000004"
+ android:scaleY="0.42200000000000004"
+ android:translateX="-114"
+ android:translateY="-114">
+ android:name="_R_G_L_1_G_D_0_P_0"
+ android:pathData=" M79.63 67.24 C79.63,67.24 111.5,47.42 147.83,67.24 "
+ android:strokeAlpha="1"
+ android:strokeColor="?android:attr/colorAccent"
+ android:strokeLineCap="round"
+ android:strokeLineJoin="round"
+ android:strokeWidth="5.5"
+ android:trimPathEnd="0"
+ android:trimPathOffset="0"
+ android:trimPathStart="0" />
+
+
+
+
+
+
+ android:name="_R_G_L_0_G"
+ android:translateX="-30.05"
+ android:translateY="-30">
+
+
+
+
+
+
+ android:name="_R_G_L_0_G_D_2_P_0"
+ android:pathData=" M30 6.2 C16.9,6.2 6.3,16.8 6.3,30 C6.3,43.2 16.9,53.8 30,53.8 C43.1,53.8 53.8,43.2 53.8,30 C53.8,16.8 43.1,6.2 30,6.2c "
+ android:strokeAlpha="1"
+ android:strokeColor="?android:attr/colorError"
+ android:strokeLineCap="round"
+ android:strokeLineJoin="round"
+ android:strokeWidth="2.5"
+ android:trimPathEnd="1"
+ android:trimPathOffset="0"
+ android:trimPathStart="0" />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
-
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -357,153 +289,125 @@
-
+
-
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
+
@@ -513,7 +417,7 @@
-
+
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/fingerprint_dialog_fp_to_error.xml b/packages/SystemUI/res/drawable/fingerprint_dialog_fp_to_error.xml
index 1a7a846b140eb..89b822840b14c 100644
--- a/packages/SystemUI/res/drawable/fingerprint_dialog_fp_to_error.xml
+++ b/packages/SystemUI/res/drawable/fingerprint_dialog_fp_to_error.xml
@@ -18,614 +18,133 @@
xmlns:aapt="http://schemas.android.com/aapt">
+ android:width="60dp"
+ android:height="60dp"
+ android:viewportHeight="60"
+ android:viewportWidth="60">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ android:name="_R_G_L_1_G_N_4_T_0"
+ android:translateX="30"
+ android:translateY="30">
+ android:name="_R_G_L_1_G"
+ android:pivotX="114"
+ android:pivotY="114"
+ android:scaleX="0.42244"
+ android:scaleY="0.42244"
+ android:translateX="-114"
+ android:translateY="-114">
+ android:name="_R_G_L_1_G_D_0_P_0"
+ android:pathData=" M79.63 67.24 C79.63,67.24 111.5,47.42 147.83,67.24 "
+ android:strokeAlpha="1"
+ android:strokeColor="?android:attr/colorAccent"
+ android:strokeLineCap="round"
+ android:strokeLineJoin="round"
+ android:strokeWidth="5.5"
+ android:trimPathEnd="1"
+ android:trimPathOffset="0"
+ android:trimPathStart="0" />
+
+
+
+
+
+
+ android:name="_R_G_L_0_G"
+ android:translateX="-30.05"
+ android:translateY="-30">
+
+
+
+
+
+
+ android:name="_R_G_L_0_G_D_2_P_0"
+ android:pathData=" M30 6.2 C16.9,6.2 6.3,16.8 6.3,30 C6.3,43.2 16.9,53.8 30,53.8 C43.1,53.8 53.8,43.2 53.8,30 C53.8,16.8 43.1,6.2 30,6.2c "
+ android:strokeAlpha="1"
+ android:strokeColor="?android:attr/colorError"
+ android:strokeLineCap="round"
+ android:strokeLineJoin="round"
+ android:strokeWidth="2.5"
+ android:trimPathEnd="1"
+ android:trimPathOffset="0"
+ android:trimPathStart="1" />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -633,6 +152,163 @@
android:duration="167"
android:propertyName="trimPathStart"
android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -641,11 +317,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -654,185 +374,18 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -842,7 +395,7 @@
-
+
\ No newline at end of file
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index b3567f892c44f..d5f29badd8938 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -130,6 +130,7 @@
#80000000
+ #ffbdc1c6
#ccffffff
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java
index ba89fe662a655..3167b9e0a4582 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java
@@ -240,7 +240,10 @@ public class BiometricDialogImpl extends SystemUI implements CommandQueue.Callba
mConfirmShowing = true;
mCurrentDialog.showConfirmationButton(true /* show */);
} else {
- handleHideDialog(false /* userCanceled */);
+ mCurrentDialog.updateState(BiometricDialogView.STATE_AUTHENTICATED);
+ mHandler.postDelayed(() -> {
+ handleHideDialog(false /* userCanceled */);
+ }, mCurrentDialog.getDelayAfterAuthenticatedDurationMs());
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java
index e085f23682141..9934bfd11f12f 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java
@@ -21,6 +21,7 @@ import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
+import android.graphics.drawable.AnimatedVectorDrawable;
import android.graphics.drawable.Drawable;
import android.hardware.biometrics.BiometricPrompt;
import android.os.Binder;
@@ -63,7 +64,8 @@ public abstract class BiometricDialogView extends LinearLayout {
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;
+ protected static final int STATE_PENDING_CONFIRMATION = 3;
+ protected static final int STATE_AUTHENTICATED = 4;
private final IBinder mWindowToken = new Binder();
private final Interpolator mLinearOutSlowIn;
@@ -77,6 +79,8 @@ public abstract class BiometricDialogView extends LinearLayout {
private final DialogViewCallback mCallback;
private ViewGroup mLayout;
+ private final Button mPositiveButton;
+ private final Button mNegativeButton;
private final TextView mErrorText;
private Bundle mBundle;
private final LinearLayout mDialog;
@@ -90,10 +94,12 @@ public abstract class BiometricDialogView extends LinearLayout {
private boolean mPendingShowTryAgain;
private boolean mPendingShowConfirm;
- protected abstract void updateIcon(int lastState, int newState);
protected abstract int getHintStringResourceId();
protected abstract int getAuthenticatedAccessibilityResourceId();
protected abstract int getIconDescriptionResourceId();
+ protected abstract Drawable getAnimationForTransition(int oldState, int newState);
+ protected abstract boolean shouldAnimateForTransition(int oldState, int newState);
+ protected abstract int getDelayAfterAuthenticatedDurationMs();
private final Runnable mShowAnimationRunnable = new Runnable() {
@Override
@@ -178,10 +184,10 @@ public abstract class BiometricDialogView extends LinearLayout {
final View space = mLayout.findViewById(R.id.space);
final View leftSpace = mLayout.findViewById(R.id.left_space);
final View rightSpace = mLayout.findViewById(R.id.right_space);
- final Button negative = mLayout.findViewById(R.id.button2);
- final Button positive = mLayout.findViewById(R.id.button1);
final ImageView icon = mLayout.findViewById(R.id.biometric_icon);
final Button tryAgain = mLayout.findViewById(R.id.button_try_again);
+ mNegativeButton = mLayout.findViewById(R.id.button2);
+ mPositiveButton = mLayout.findViewById(R.id.button1);
icon.setContentDescription(getResources().getString(getIconDescriptionResourceId()));
@@ -189,12 +195,15 @@ public abstract class BiometricDialogView extends LinearLayout {
setDismissesDialog(leftSpace);
setDismissesDialog(rightSpace);
- negative.setOnClickListener((View v) -> {
+ mNegativeButton.setOnClickListener((View v) -> {
mCallback.onNegativePressed();
});
- positive.setOnClickListener((View v) -> {
- mCallback.onPositivePressed();
+ mPositiveButton.setOnClickListener((View v) -> {
+ updateState(STATE_AUTHENTICATED);
+ mHandler.postDelayed(() -> {
+ mCallback.onPositivePressed();
+ }, getDelayAfterAuthenticatedDurationMs());
});
tryAgain.setOnClickListener((View v) -> {
@@ -215,7 +224,6 @@ public abstract class BiometricDialogView extends LinearLayout {
final TextView title = mLayout.findViewById(R.id.title);
final TextView subtitle = mLayout.findViewById(R.id.subtitle);
final TextView description = mLayout.findViewById(R.id.description);
- final Button negative = mLayout.findViewById(R.id.button2);
final ImageView backgroundView = mLayout.findViewById(R.id.background);
if (mUserManager.isManagedProfile(mUserId)) {
@@ -229,6 +237,9 @@ public abstract class BiometricDialogView extends LinearLayout {
backgroundView.setBackgroundColor(R.color.biometric_dialog_dim_color);
}
+ mNegativeButton.setVisibility(View.VISIBLE);
+ mErrorText.setVisibility(View.VISIBLE);
+
if (RotationUtils.getRotation(mContext) != RotationUtils.ROTATION_NONE) {
mDialog.getLayoutParams().width = (int) mDialogWidth;
}
@@ -258,7 +269,7 @@ public abstract class BiometricDialogView extends LinearLayout {
description.setText(descriptionText);
}
- negative.setText(mBundle.getCharSequence(BiometricPrompt.KEY_NEGATIVE_TEXT));
+ mNegativeButton.setText(mBundle.getCharSequence(BiometricPrompt.KEY_NEGATIVE_TEXT));
showTryAgainButton(mPendingShowTryAgain);
showConfirmationButton(mPendingShowConfirm);
@@ -280,10 +291,32 @@ public abstract class BiometricDialogView extends LinearLayout {
mSkipIntro = false;
}
+ protected void updateIcon(int lastState, int newState) {
+ final 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 imageView = getLayout().findViewById(R.id.biometric_icon);
+ imageView.setImageDrawable(icon);
+
+ if (animation != null && shouldAnimateForTransition(lastState, newState)) {
+ animation.forceAnimationOnUI();
+ animation.start();
+ }
+ }
+
private void setDismissesDialog(View v) {
v.setClickable(true);
v.setOnTouchListener((View view, MotionEvent event) -> {
- mCallback.onUserCanceled();
+ if (mLastState != STATE_AUTHENTICATED) {
+ mCallback.onUserCanceled();
+ }
return true;
});
}
@@ -302,6 +335,7 @@ public abstract class BiometricDialogView extends LinearLayout {
showTryAgainButton(false /* show */);
mPendingShowTryAgain = false;
mPendingShowConfirm = false;
+ updateState(STATE_NONE);
}
};
@@ -362,11 +396,11 @@ public abstract class BiometricDialogView extends LinearLayout {
}
public void showConfirmationButton(boolean show) {
- final Button positive = mLayout.findViewById(R.id.button1);
if (show) {
- positive.setVisibility(View.VISIBLE);
+ updateState(STATE_PENDING_CONFIRMATION);
+ mPositiveButton.setVisibility(View.VISIBLE);
} else {
- positive.setVisibility(View.GONE);
+ mPositiveButton.setVisibility(View.GONE);
}
}
@@ -411,7 +445,15 @@ public abstract class BiometricDialogView extends LinearLayout {
mCallback.onErrorShown();
}
- private void updateState(int newState) {
+ public void updateState(int newState) {
+ if (newState == STATE_PENDING_CONFIRMATION) {
+ mErrorText.setVisibility(View.INVISIBLE);
+ } else if (newState == STATE_AUTHENTICATED) {
+ mPositiveButton.setVisibility(View.GONE);
+ mNegativeButton.setVisibility(View.GONE);
+ mErrorText.setVisibility(View.INVISIBLE);
+ }
+
updateIcon(mLastState, newState);
mLastState = newState;
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/FaceDialogView.java b/packages/SystemUI/src/com/android/systemui/biometrics/FaceDialogView.java
index feef3a6dc1336..de3f9471a6bae 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/FaceDialogView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/FaceDialogView.java
@@ -18,16 +18,18 @@ package com.android.systemui.biometrics;
import android.content.Context;
import android.graphics.drawable.Drawable;
-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,
+ * Application Icon, Title, Subtitle, Description, Biometric Icon, Error/Help message area,
* and positive/negative buttons.
*/
public class FaceDialogView extends BiometricDialogView {
+
+ private static final int HIDE_DIALOG_DELAY = 500; // ms
+
public FaceDialogView(Context context,
DialogViewCallback callback) {
super(context, callback);
@@ -53,10 +55,46 @@ public class FaceDialogView extends BiometricDialogView {
}
@Override
- protected void updateIcon(int lastState, int newState) {
- Drawable icon = mContext.getDrawable(R.drawable.face_dialog_icon);
+ protected 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_PENDING_CONFIRMATION) {
+ return true;
+ } else if (oldState == STATE_PENDING_CONFIRMATION && newState == STATE_AUTHENTICATED) {
+ return true;
+ } else if (oldState == STATE_AUTHENTICATING && newState == STATE_AUTHENTICATED) {
+ return true;
+ }
+ return false;
+ }
- final ImageView faceIcon = getLayout().findViewById(R.id.biometric_icon);
- faceIcon.setImageDrawable(icon);
+ @Override
+ protected int getDelayAfterAuthenticatedDurationMs() {
+ return HIDE_DIALOG_DELAY;
+ }
+
+ @Override
+ protected Drawable getAnimationForTransition(int oldState, int newState) {
+ int iconRes;
+ if (oldState == STATE_NONE && newState == STATE_AUTHENTICATING) {
+ iconRes = R.drawable.face_dialog_face_to_error;
+ } else if (oldState == STATE_AUTHENTICATING && newState == STATE_ERROR) {
+ iconRes = R.drawable.face_dialog_face_to_error;
+ } else if (oldState == STATE_ERROR && newState == STATE_AUTHENTICATING) {
+ iconRes = R.drawable.face_dialog_error_to_face;
+ } else if (oldState == STATE_AUTHENTICATING && newState == STATE_PENDING_CONFIRMATION) {
+ iconRes = R.drawable.face_dialog_face_gray_to_face_blue;
+ } else if (oldState == STATE_PENDING_CONFIRMATION && newState == STATE_AUTHENTICATED) {
+ iconRes = R.drawable.face_dialog_face_blue_to_checkmark;
+ } else if (oldState == STATE_AUTHENTICATING && newState == STATE_AUTHENTICATED) {
+ iconRes = R.drawable.face_dialog_face_gray_to_checkmark;
+ } else {
+ return null;
+ }
+ return mContext.getDrawable(iconRes);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintDialogView.java b/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintDialogView.java
index 38a69a90f0bb5..1a6cee281c843 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintDialogView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintDialogView.java
@@ -17,21 +17,21 @@
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,
+ * Application Icon, Title, Subtitle, Description, Biometric Icon, Error/Help message area,
* and positive/negative buttons.
*/
public class FingerprintDialogView extends BiometricDialogView {
- private static final String TAG = "FingerprintDialogView";
+ public FingerprintDialogView(Context context,
+ DialogViewCallback callback) {
+ super(context, callback);
+ }
@Override
protected int getHintStringResourceId() {
return R.string.fingerprint_dialog_touch_sensor;
@@ -48,33 +48,7 @@ public class FingerprintDialogView extends BiometricDialogView {
}
@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 fingerprintIcon = getLayout().findViewById(R.id.biometric_icon);
- fingerprintIcon.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) {
+ protected boolean shouldAnimateForTransition(int oldState, int newState) {
if (oldState == STATE_NONE && newState == STATE_AUTHENTICATING) {
return false;
} else if (oldState == STATE_AUTHENTICATING && newState == STATE_ERROR) {
@@ -88,7 +62,13 @@ public class FingerprintDialogView extends BiometricDialogView {
return false;
}
- private Drawable getAnimationForTransition(int oldState, int newState) {
+ @Override
+ protected int getDelayAfterAuthenticatedDurationMs() {
+ return 0;
+ }
+
+ @Override
+ protected Drawable getAnimationForTransition(int oldState, int newState) {
int iconRes;
if (oldState == STATE_NONE && newState == STATE_AUTHENTICATING) {
iconRes = R.drawable.fingerprint_dialog_fp_to_error;
@@ -98,7 +78,7 @@ public class FingerprintDialogView extends BiometricDialogView {
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;
+ iconRes = R.drawable.fingerprint_dialog_fp_to_error;
} else {
return null;
}
diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java
index a381477b01cbb..36ca4dcbea33e 100644
--- a/services/core/java/com/android/server/biometrics/BiometricService.java
+++ b/services/core/java/com/android/server/biometrics/BiometricService.java
@@ -373,6 +373,13 @@ public class BiometricService extends SystemService {
public void onAuthenticationSucceeded(boolean requireConfirmation, byte[] token)
throws RemoteException {
try {
+ // Should never happen, log this to catch bad HAL behavior (e.g. auth succeeded
+ // after user dismissed/canceled dialog).
+ if (mCurrentAuthSession == null) {
+ Slog.e(TAG, "onAuthenticationSucceeded(): Auth session is null");
+ return;
+ }
+
if (!requireConfirmation) {
mActivityTaskManager.unregisterTaskStackListener(mTaskStackListener);
KeyStore.getInstance().addAuthToken(token);
@@ -398,6 +405,13 @@ public class BiometricService extends SystemService {
public void onAuthenticationFailed(int cookie, boolean requireConfirmation)
throws RemoteException {
try {
+ // Should never happen, log this to catch bad HAL behavior (e.g. auth succeeded
+ // after user dismissed/canceled dialog).
+ if (mCurrentAuthSession == null) {
+ Slog.e(TAG, "onAuthenticationFailed(): Auth session is null");
+ return;
+ }
+
mStatusBarService.onBiometricHelp(getContext().getResources().getString(
com.android.internal.R.string.biometric_not_recognized));
if (requireConfirmation) {
@@ -486,6 +500,13 @@ public class BiometricService extends SystemService {
@Override
public void onAcquired(int acquiredInfo, String message) throws RemoteException {
+ // Should never happen, log this to catch bad HAL behavior (e.g. auth succeeded
+ // after user dismissed/canceled dialog).
+ if (mCurrentAuthSession == null) {
+ Slog.e(TAG, "onAcquired(): Auth session is null");
+ return;
+ }
+
if (acquiredInfo != BiometricConstants.BIOMETRIC_ACQUIRED_GOOD) {
try {
mStatusBarService.onBiometricHelp(message);