Persist dialog state across configuration change

Fixes: 132208703

Test: Follow steps in comment#1

Change-Id: I82b77ec1536ce2811fa94f07296d25120e17f241
This commit is contained in:
Kevin Chyn
2019-05-07 20:22:31 -07:00
parent 07b0f138a1
commit 8cfd7a48f6
4 changed files with 364 additions and 36 deletions

View File

@@ -0,0 +1,276 @@
<!--
~ Copyright (C) 2019 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
-->
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt">
<aapt:attr name="android:drawable">
<vector
android:width="60dp"
android:height="60dp"
android:viewportWidth="60"
android:viewportHeight="60">
<group android:name="_R_G">
<group
android:name="_R_G_L_0_G"
android:pivotX="30"
android:pivotY="30"
android:scaleX="1.03"
android:scaleY="1.03">
<path
android:name="_R_G_L_0_G_D_0_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:strokeWidth="2.5"
android:strokeAlpha="1.0"
android:strokeColor="@color/biometric_dialog_gray"
android:trimPathStart="0"
android:trimPathEnd="1"
android:trimPathOffset="0" />
<path
android:name="_R_G_L_0_G_D_1_P_0"
android:pathData=" M33.75 42.75 C32.75,43.77 31.37,44.39 29.83,44.39 C26.8,44.39 24.34,41.93 24.34,38.9 "
android:strokeWidth="2"
android:strokeAlpha="1.0"
android:strokeColor="@color/biometric_dialog_gray"
android:trimPathStart="0"
android:trimPathEnd="1"
android:trimPathOffset="0" />
<path
android:name="_R_G_L_0_G_D_2_P_0"
android:fillAlpha="1.0"
android:fillColor="@color/biometric_dialog_gray"
android:fillType="nonZero"
android:pathData=" M39 23.8 C39,25 39.9,25.9 41.1,25.9 C42.2,25.9 43.2,25 43.2,23.8 C43.2,22.6 42.3,21.7 41.1,21.7 C39.9,21.7 39,22.6 39,23.8c " />
<path
android:name="_R_G_L_0_G_D_3_P_0"
android:fillAlpha="1.0"
android:fillColor="@color/biometric_dialog_gray"
android:fillType="nonZero"
android:pathData=" M16.5 23.8 C16.5,25 17.4,25.9 18.6,25.9 C19.8,25.9 20.7,25 20.7,23.8 C20.7,22.6 19.8,21.7 18.6,21.7 C17.4,21.7 16.5,22.6 16.5,23.8c " />
<path
android:name="_R_G_L_0_G_D_4_P_0"
android:fillAlpha="1.0"
android:fillColor="@color/biometric_dialog_gray"
android:fillType="nonZero"
android:pathData=" M33.33 34.95 C33.33,34.95 28.13,34.95 28.13,34.95 C28.13,34.95 28.13,32.95 28.13,32.95 C28.13,32.95 31.33,32.95 31.33,32.95 C31.33,32.95 31.33,28.45 31.33,28.45 C31.33,28.45 33.33,28.45 33.33,28.45 C33.33,28.45 33.33,34.95 33.33,34.95c " />
</group>
</group>
<group android:name="time_group" />
</vector>
</aapt:attr>
<target android:name="_R_G_L_0_G_D_0_P_0">
<aapt:attr name="android:animation">
<set android:ordering="together">
<objectAnimator
android:duration="500"
android:propertyName="strokeAlpha"
android:startOffset="0"
android:valueFrom="1.0"
android:valueTo="1.0"
android:valueType="floatType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.118,1.266 0.419,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
<objectAnimator
android:duration="500"
android:propertyName="strokeAlpha"
android:startOffset="500"
android:valueFrom="1.0"
android:valueTo="1.0"
android:valueType="floatType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
</set>
</aapt:attr>
</target>
<target android:name="_R_G_L_0_G_D_1_P_0">
<aapt:attr name="android:animation">
<set android:ordering="together">
<objectAnimator
android:duration="500"
android:propertyName="strokeAlpha"
android:startOffset="0"
android:valueFrom="1.0"
android:valueTo="1.0"
android:valueType="floatType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.118,1.266 0.419,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
<objectAnimator
android:duration="500"
android:propertyName="strokeAlpha"
android:startOffset="500"
android:valueFrom="1.0"
android:valueTo="1.0"
android:valueType="floatType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
</set>
</aapt:attr>
</target>
<target android:name="_R_G_L_0_G_D_2_P_0">
<aapt:attr name="android:animation">
<set android:ordering="together">
<objectAnimator
android:duration="500"
android:propertyName="fillAlpha"
android:startOffset="0"
android:valueFrom="1.0"
android:valueTo="1.0"
android:valueType="floatType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.118,1.266 0.419,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
<objectAnimator
android:duration="500"
android:propertyName="fillAlpha"
android:startOffset="500"
android:valueFrom="1.0"
android:valueTo="1.0"
android:valueType="floatType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
</set>
</aapt:attr>
</target>
<target android:name="_R_G_L_0_G_D_3_P_0">
<aapt:attr name="android:animation">
<set android:ordering="together">
<objectAnimator
android:duration="500"
android:propertyName="fillAlpha"
android:startOffset="0"
android:valueFrom="1.0"
android:valueTo="1.0"
android:valueType="floatType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.118,1.266 0.419,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
<objectAnimator
android:duration="500"
android:propertyName="fillAlpha"
android:startOffset="500"
android:valueFrom="1.0"
android:valueTo="1.0"
android:valueType="floatType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
</set>
</aapt:attr>
</target>
<target android:name="_R_G_L_0_G_D_4_P_0">
<aapt:attr name="android:animation">
<set android:ordering="together">
<objectAnimator
android:duration="500"
android:propertyName="fillAlpha"
android:startOffset="0"
android:valueFrom="1.0"
android:valueTo="1.0"
android:valueType="floatType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.118,1.266 0.419,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
<objectAnimator
android:duration="500"
android:propertyName="fillAlpha"
android:startOffset="500"
android:valueFrom="1.0"
android:valueTo="1.0"
android:valueType="floatType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
</set>
</aapt:attr>
</target>
<target android:name="_R_G_L_0_G">
<aapt:attr name="android:animation">
<set android:ordering="together">
<objectAnimator
android:duration="500"
android:propertyName="scaleX"
android:startOffset="0"
android:valueFrom="1.03"
android:valueTo="1"
android:valueType="floatType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
<objectAnimator
android:duration="500"
android:propertyName="scaleY"
android:startOffset="0"
android:valueFrom="1.03"
android:valueTo="1"
android:valueType="floatType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
<objectAnimator
android:duration="500"
android:propertyName="scaleX"
android:startOffset="500"
android:valueFrom="1"
android:valueTo="1.03"
android:valueType="floatType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.204,0.46 0.568,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
<objectAnimator
android:duration="500"
android:propertyName="scaleY"
android:startOffset="500"
android:valueFrom="1"
android:valueTo="1.03"
android:valueType="floatType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.204,0.46 0.568,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
</set>
</aapt:attr>
</target>
<target android:name="time_group">
<aapt:attr name="android:animation">
<set android:ordering="together">
<objectAnimator
android:duration="1017"
android:propertyName="translateX"
android:startOffset="0"
android:valueFrom="0"
android:valueTo="1"
android:valueType="floatType" />
</set>
</aapt:attr>
</target>
</animated-vector>

View File

@@ -56,11 +56,16 @@ public abstract class BiometricDialogView extends LinearLayout {
private static final String KEY_TRY_AGAIN_VISIBILITY = "key_try_again_visibility";
private static final String KEY_CONFIRM_VISIBILITY = "key_confirm_visibility";
private static final String KEY_STATE = "key_state";
private static final String KEY_ERROR_TEXT_VISIBILITY = "key_error_text_visibility";
private static final String KEY_ERROR_TEXT_STRING = "key_error_text_string";
private static final String KEY_ERROR_TEXT_IS_TEMPORARY = "key_error_text_is_temporary";
private static final String KEY_ERROR_TEXT_COLOR = "key_error_text_color";
private static final int ANIMATION_DURATION_SHOW = 250; // ms
private static final int ANIMATION_DURATION_AWAY = 350; // ms
protected static final int MSG_CLEAR_MESSAGE = 1;
protected static final int MSG_RESET_MESSAGE = 1;
protected static final int STATE_IDLE = 0;
protected static final int STATE_AUTHENTICATING = 1;
@@ -94,7 +99,7 @@ public abstract class BiometricDialogView extends LinearLayout {
private Bundle mBundle;
private Bundle mRestoredState;
private int mState;
private int mState = STATE_IDLE;
private boolean mAnimatingAway;
private boolean mWasForceRemoved;
private boolean mSkipIntro;
@@ -106,7 +111,7 @@ public abstract class BiometricDialogView extends LinearLayout {
protected abstract int getIconDescriptionResourceId();
protected abstract int getDelayAfterAuthenticatedDurationMs();
protected abstract boolean shouldGrayAreaDismissDialog();
protected abstract void handleClearMessage();
protected abstract void handleResetMessage();
protected abstract void updateIcon(int oldState, int newState);
private final Runnable mShowAnimationRunnable = new Runnable() {
@@ -132,8 +137,8 @@ public abstract class BiometricDialogView extends LinearLayout {
@Override
public void handleMessage(Message msg) {
switch(msg.what) {
case MSG_CLEAR_MESSAGE:
handleClearMessage();
case MSG_RESET_MESSAGE:
handleResetMessage();
break;
default:
Log.e(TAG, "Unhandled message: " + msg.what);
@@ -231,14 +236,17 @@ public abstract class BiometricDialogView extends LinearLayout {
public void onSaveState(Bundle bundle) {
bundle.putInt(KEY_TRY_AGAIN_VISIBILITY, mTryAgainButton.getVisibility());
bundle.putInt(KEY_CONFIRM_VISIBILITY, mPositiveButton.getVisibility());
bundle.putInt(KEY_STATE, mState);
bundle.putInt(KEY_ERROR_TEXT_VISIBILITY, mErrorText.getVisibility());
bundle.putCharSequence(KEY_ERROR_TEXT_STRING, mErrorText.getText());
bundle.putBoolean(KEY_ERROR_TEXT_IS_TEMPORARY, mHandler.hasMessages(MSG_RESET_MESSAGE));
bundle.putInt(KEY_ERROR_TEXT_COLOR, mErrorText.getCurrentTextColor());
}
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
mErrorText.setText(getHintStringResourceId());
final ImageView backgroundView = mLayout.findViewById(R.id.background);
if (mUserManager.isManagedProfile(mUserId)) {
@@ -253,14 +261,18 @@ public abstract class BiometricDialogView extends LinearLayout {
}
mNegativeButton.setVisibility(View.VISIBLE);
mErrorText.setVisibility(View.VISIBLE);
if (RotationUtils.getRotation(mContext) != RotationUtils.ROTATION_NONE) {
mDialog.getLayoutParams().width = (int) mDialogWidth;
}
mState = STATE_IDLE;
updateState(STATE_AUTHENTICATING);
if (mRestoredState == null) {
updateState(STATE_AUTHENTICATING);
mErrorText.setText(getHintStringResourceId());
mErrorText.setVisibility(View.VISIBLE);
} else {
updateState(mState);
}
CharSequence titleText = mBundle.getCharSequence(BiometricPrompt.KEY_TITLE);
@@ -329,7 +341,7 @@ public abstract class BiometricDialogView extends LinearLayout {
mWindowManager.removeView(BiometricDialogView.this);
mAnimatingAway = false;
// Set the icons / text back to normal state
handleClearMessage();
handleResetMessage();
showTryAgainButton(false /* show */);
updateState(STATE_IDLE);
}
@@ -401,17 +413,17 @@ public abstract class BiometricDialogView extends LinearLayout {
// Shows an error/help message
protected void showTemporaryMessage(String message) {
mHandler.removeMessages(MSG_CLEAR_MESSAGE);
mHandler.removeMessages(MSG_RESET_MESSAGE);
mErrorText.setText(message);
mErrorText.setTextColor(mErrorColor);
mErrorText.setContentDescription(message);
mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_CLEAR_MESSAGE),
mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_RESET_MESSAGE),
BiometricPrompt.HIDE_DIALOG_DELAY);
}
public void clearTemporaryMessage() {
mHandler.removeMessages(MSG_CLEAR_MESSAGE);
mHandler.obtainMessage(MSG_CLEAR_MESSAGE).sendToTarget();
mHandler.removeMessages(MSG_RESET_MESSAGE);
mHandler.obtainMessage(MSG_RESET_MESSAGE).sendToTarget();
}
/**
@@ -442,7 +454,7 @@ public abstract class BiometricDialogView extends LinearLayout {
public void updateState(int newState) {
if (newState == STATE_PENDING_CONFIRMATION) {
mHandler.removeMessages(MSG_CLEAR_MESSAGE);
mHandler.removeMessages(MSG_RESET_MESSAGE);
mErrorText.setVisibility(View.INVISIBLE);
mPositiveButton.setVisibility(View.VISIBLE);
mPositiveButton.setEnabled(true);
@@ -470,6 +482,19 @@ public abstract class BiometricDialogView extends LinearLayout {
mRestoredState = bundle;
mTryAgainButton.setVisibility(bundle.getInt(KEY_TRY_AGAIN_VISIBILITY));
mPositiveButton.setVisibility(bundle.getInt(KEY_CONFIRM_VISIBILITY));
mState = bundle.getInt(KEY_STATE);
mErrorText.setText(bundle.getCharSequence(KEY_ERROR_TEXT_STRING));
mErrorText.setVisibility(bundle.getInt(KEY_ERROR_TEXT_VISIBILITY));
mErrorText.setTextColor(bundle.getInt(KEY_ERROR_TEXT_COLOR));
if (bundle.getBoolean(KEY_ERROR_TEXT_IS_TEMPORARY)) {
mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_RESET_MESSAGE),
BiometricPrompt.HIDE_DIALOG_DELAY);
}
}
protected int getState() {
return mState;
}
public WindowManager.LayoutParams getLayoutParams() {

View File

@@ -44,6 +44,7 @@ public class FaceDialogView extends BiometricDialogView {
private static final String TAG = "FaceDialogView";
private static final String KEY_DIALOG_SIZE = "key_dialog_size";
private static final String KEY_DIALOG_ANIMATED_IN = "key_dialog_animated_in";
private static final int HIDE_DIALOG_DELAY = 500; // ms
private static final int IMPLICIT_Y_PADDING = 16; // dp
@@ -78,6 +79,10 @@ public class FaceDialogView extends BiometricDialogView {
animateIcon(iconRes, false);
}
public void showStatic(int iconRes) {
mBiometricIcon.setImageDrawable(mContext.getDrawable(iconRes));
}
public void startPulsing() {
mLastPulseDirection = false;
animateIcon(R.drawable.face_dialog_pulse_dark_to_light, true);
@@ -276,13 +281,19 @@ public class FaceDialogView extends BiometricDialogView {
public void onSaveState(Bundle bundle) {
super.onSaveState(bundle);
bundle.putInt(KEY_DIALOG_SIZE, mSize);
bundle.putBoolean(KEY_DIALOG_ANIMATED_IN, mDialogAnimatedIn);
}
@Override
protected void handleClearMessage() {
protected void handleResetMessage() {
mErrorText.setText(getHintStringResourceId());
mErrorText.setTextColor(mTextColor);
if (getState() == STATE_AUTHENTICATING) {
mErrorText.setVisibility(View.VISIBLE);
} else {
mErrorText.setVisibility(View.INVISIBLE);
}
}
@Override
@@ -290,6 +301,7 @@ public class FaceDialogView extends BiometricDialogView {
super.restoreState(bundle);
// Keep in mind that this happens before onAttachedToWindow()
mSize = bundle.getInt(KEY_DIALOG_SIZE);
mDialogAnimatedIn = bundle.getBoolean(KEY_DIALOG_ANIMATED_IN);
}
/**
@@ -386,7 +398,8 @@ public class FaceDialogView extends BiometricDialogView {
protected void updateIcon(int oldState, int newState) {
mIconController.mState = newState;
if (oldState == STATE_IDLE && newState == STATE_AUTHENTICATING) {
if (newState == STATE_AUTHENTICATING) {
mHandler.removeCallbacks(mErrorToIdleAnimationRunnable);
if (mDialogAnimatedIn) {
mIconController.startPulsing();
mErrorText.setVisibility(View.VISIBLE);
@@ -397,25 +410,39 @@ public class FaceDialogView extends BiometricDialogView {
mIconController.animateOnce(R.drawable.face_dialog_dark_to_checkmark);
} else if (oldState == STATE_ERROR && newState == STATE_IDLE) {
mIconController.animateOnce(R.drawable.face_dialog_error_to_idle);
} else if (oldState == STATE_ERROR && newState == STATE_AUTHENTICATING) {
mHandler.removeCallbacks(mErrorToIdleAnimationRunnable);
mIconController.startPulsing();
} else if (oldState == STATE_ERROR && newState == STATE_PENDING_CONFIRMATION) {
mHandler.removeCallbacks(mErrorToIdleAnimationRunnable);
mIconController.animateOnce(R.drawable.face_dialog_wink_from_dark);
} else if (oldState == STATE_ERROR && newState == STATE_AUTHENTICATED) {
mHandler.removeCallbacks(mErrorToIdleAnimationRunnable);
mIconController.animateOnce(R.drawable.face_dialog_dark_to_checkmark);
} else if (oldState == STATE_AUTHENTICATING && newState == STATE_ERROR) {
mIconController.animateOnce(R.drawable.face_dialog_dark_to_error);
mHandler.postDelayed(mErrorToIdleAnimationRunnable, BiometricPrompt.HIDE_DIALOG_DELAY);
} else if (newState == STATE_ERROR) {
// It's easier to only check newState and gate showing the animation on the
// mErrorToIdleAnimationRunnable as a proxy, than add a ton of extra state. For example,
// we may go from error -> error due to configuration change which is valid and we
// should show the animation, or we can go from error -> error by receiving repeated
// acquire messages in which case we do not want to repeatedly start the animation.
if (!mHandler.hasCallbacks(mErrorToIdleAnimationRunnable)) {
mIconController.animateOnce(R.drawable.face_dialog_dark_to_error);
mHandler.postDelayed(mErrorToIdleAnimationRunnable,
BiometricPrompt.HIDE_DIALOG_DELAY);
}
} else if (oldState == STATE_AUTHENTICATING && newState == STATE_AUTHENTICATED) {
mIconController.animateOnce(R.drawable.face_dialog_dark_to_checkmark);
} else if (oldState == STATE_AUTHENTICATING && newState == STATE_PENDING_CONFIRMATION) {
} else if (newState == STATE_PENDING_CONFIRMATION) {
mHandler.removeCallbacks(mErrorToIdleAnimationRunnable);
mIconController.animateOnce(R.drawable.face_dialog_wink_from_dark);
} else if (newState == STATE_IDLE) {
mIconController.showStatic(R.drawable.face_dialog_idle_static);
} else {
Log.w(TAG, "Unknown animation from " + oldState + " -> " + newState);
}
// Note that this must be after the newState == STATE_ERROR check above since this affects
// the logic.
if (oldState == STATE_ERROR && newState == STATE_ERROR) {
// Keep the error icon and text around for a while longer if we keep receiving
// STATE_ERROR
mHandler.removeCallbacks(mErrorToIdleAnimationRunnable);
mHandler.postDelayed(mErrorToIdleAnimationRunnable, BiometricPrompt.HIDE_DIALOG_DELAY);
}
}
@Override

View File

@@ -38,7 +38,7 @@ public class FingerprintDialogView extends BiometricDialogView {
}
@Override
protected void handleClearMessage() {
protected void handleResetMessage() {
updateState(STATE_AUTHENTICATING);
mErrorText.setText(getHintStringResourceId());
mErrorText.setTextColor(mTextColor);
@@ -80,9 +80,7 @@ public class FingerprintDialogView extends BiometricDialogView {
}
protected boolean shouldAnimateForTransition(int oldState, int newState) {
if (oldState == STATE_IDLE && newState == STATE_AUTHENTICATING) {
return false;
} else if (oldState == STATE_AUTHENTICATING && newState == STATE_ERROR) {
if (newState == STATE_ERROR) {
return true;
} else if (oldState == STATE_ERROR && newState == STATE_AUTHENTICATING) {
return true;
@@ -92,6 +90,8 @@ public class FingerprintDialogView extends BiometricDialogView {
} else if (oldState == STATE_ERROR && newState == STATE_AUTHENTICATED) {
// TODO(b/77328470): add animation when fingerprint is authenticated
return false;
} else if (newState == STATE_AUTHENTICATING) {
return false;
}
return false;
}
@@ -109,9 +109,7 @@ public class FingerprintDialogView extends BiometricDialogView {
protected Drawable getAnimationForTransition(int oldState, int newState) {
int iconRes;
if (oldState == STATE_IDLE && newState == STATE_AUTHENTICATING) {
iconRes = R.drawable.fingerprint_dialog_fp_to_error;
} else if (oldState == STATE_AUTHENTICATING && newState == STATE_ERROR) {
if (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;
@@ -121,9 +119,11 @@ public class FingerprintDialogView extends BiometricDialogView {
} else if (oldState == STATE_ERROR && newState == STATE_AUTHENTICATED) {
// TODO(b/77328470): add animation when fingerprint is authenticated
iconRes = R.drawable.fingerprint_dialog_fp_to_error;
} else if (newState == STATE_AUTHENTICATING) {
iconRes = R.drawable.fingerprint_dialog_fp_to_error;
} else {
return null;
}
return mContext.getDrawable(iconRes);
}
}
}