Fix BiometricDialog onConfigChange crash

BiometricDialog was crashing during orientation changes due to
incorrectly tracked window state.

Test: With BiometricPromptDemo, orientation changes work again
Test: Unplub USB, enable battery saver, start authentication,
      plug in USB. Changes from dark theme to light theme
Test: BiometricDialog width is correct before/after rotation

Change-Id: Id6021f3defded1bfd71c008b4ebdab2e13f9f515
Fixes: 118835751
This commit is contained in:
Kevin Chyn
2018-11-01 16:47:12 -07:00
parent 2e00765493
commit 02129b19f1
2 changed files with 26 additions and 17 deletions

View File

@@ -66,7 +66,7 @@ public class BiometricDialogImpl extends SystemUI implements CommandQueue.Callba
public void handleMessage(Message msg) {
switch(msg.what) {
case MSG_SHOW_DIALOG:
handleShowDialog((SomeArgs) msg.obj);
handleShowDialog((SomeArgs) msg.obj, false /* skipAnimation */);
break;
case MSG_BIOMETRIC_AUTHENTICATED:
handleBiometricAuthenticated();
@@ -178,7 +178,7 @@ public class BiometricDialogImpl extends SystemUI implements CommandQueue.Callba
mHandler.obtainMessage(MSG_HIDE_DIALOG, false /* userCanceled */).sendToTarget();
}
private void handleShowDialog(SomeArgs args) {
private void handleShowDialog(SomeArgs args, boolean skipAnimation) {
mCurrentDialogArgs = args;
final int type = args.argi1;
mCurrentDialog = mDialogs.get(type);
@@ -195,6 +195,7 @@ public class BiometricDialogImpl extends SystemUI implements CommandQueue.Callba
mReceiver = (IBiometricPromptReceiver) args.arg2;
mCurrentDialog.setBundle((Bundle)args.arg1);
mCurrentDialog.setRequireConfirmation((boolean)args.arg3);
mCurrentDialog.setSkipIntro(skipAnimation);
mWindowManager.addView(mCurrentDialog, mCurrentDialog.getLayoutParams());
mDialogShowing = true;
}
@@ -278,15 +279,15 @@ public class BiometricDialogImpl extends SystemUI implements CommandQueue.Callba
@Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
final boolean wasShowing = mDialogShowing;
if (mDialogShowing) {
mCurrentDialog.forceRemove();
mDialogShowing = false;
}
createDialogs();
if (mDialogShowing) {
mCurrentDialog = mDialogs.get(mCurrentDialogArgs.argi1);
mCurrentDialog.forceRemove(); // Prevents intro animation when reattaching.
mDialogShowing = false;
handleShowDialog(mCurrentDialogArgs);
if (wasShowing) {
handleShowDialog(mCurrentDialogArgs, true /* skipAnimation */);
}
}
}

View File

@@ -66,7 +66,7 @@ public abstract class BiometricDialogView extends LinearLayout {
private final float mAnimationTranslationOffset;
private final int mErrorColor;
private final int mTextColor;
private final float mDisplayWidth;
private final float mDialogWidth;
private final DialogViewCallback mCallback;
private ViewGroup mLayout;
@@ -76,6 +76,7 @@ public abstract class BiometricDialogView extends LinearLayout {
private int mLastState;
private boolean mAnimatingAway;
private boolean mWasForceRemoved;
private boolean mSkipIntro;
protected boolean mRequireConfirmation;
protected abstract void updateIcon(int lastState, int newState);
@@ -131,7 +132,7 @@ public abstract class BiometricDialogView extends LinearLayout {
DisplayMetrics metrics = new DisplayMetrics();
mWindowManager.getDefaultDisplay().getMetrics(metrics);
mDisplayWidth = metrics.widthPixels;
mDialogWidth = Math.min(metrics.widthPixels, metrics.heightPixels);
// Create the dialog
LayoutInflater factory = LayoutInflater.from(getContext());
@@ -198,8 +199,7 @@ public abstract class BiometricDialogView extends LinearLayout {
final Button negative = mLayout.findViewById(R.id.button2);
final Button positive = mLayout.findViewById(R.id.button1);
mDialog.getLayoutParams().width = (int) mDisplayWidth;
mDialog.getLayoutParams().width = (int) mDialogWidth;
mLastState = STATE_NONE;
updateState(STATE_AUTHENTICATING);
@@ -228,20 +228,21 @@ public abstract class BiometricDialogView extends LinearLayout {
negative.setText(mBundle.getCharSequence(BiometricPrompt.KEY_NEGATIVE_TEXT));
if (!mWasForceRemoved) {
// Dim the background and slide the dialog up
mDialog.setTranslationY(mAnimationTranslationOffset);
mLayout.setAlpha(0f);
postOnAnimation(mShowAnimationRunnable);
} else {
if (mWasForceRemoved || mSkipIntro) {
// Show the dialog immediately
mLayout.animate().cancel();
mDialog.animate().cancel();
mDialog.setAlpha(1.0f);
mDialog.setTranslationY(0);
mLayout.setAlpha(1.0f);
} else {
// Dim the background and slide the dialog up
mDialog.setTranslationY(mAnimationTranslationOffset);
mLayout.setAlpha(0f);
postOnAnimation(mShowAnimationRunnable);
}
mWasForceRemoved = false;
mSkipIntro = false;
}
private void setDismissesDialog(View v) {
@@ -296,6 +297,13 @@ public abstract class BiometricDialogView extends LinearLayout {
mWasForceRemoved = true;
}
/**
* Skip the intro animation
*/
public void setSkipIntro(boolean skip) {
mSkipIntro = skip;
}
public boolean isAnimatingAway() {
return mAnimatingAway;
}