From 852f87ee878703b48a7d11771ff9536e178f132b Mon Sep 17 00:00:00 2001 From: Vincent Wang Date: Wed, 2 Nov 2022 06:41:07 +0000 Subject: [PATCH] Fix biometric prompt disappeared by itself after rotate 180 degrees "onConfigurationChanged" won't be triggered when device rotate from landscape to landscape or portrait to portrait. We need to skip onWindowFocusChanged(false) in above cases to avoid BP closed. Bug: b/246683265 Test: 1. Show BP in landscape 2. Rotate device with 180 degree 3. atest AuthContainerViewTest#testFocusLossAfterRotating Change-Id: I398e52e5cb749d64a3953b6718df08c36498a02d --- .../biometrics/AuthContainerView.java | 17 ++++++----------- .../biometrics/AuthContainerViewTest.kt | 19 +++++++++++++++++++ 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java index 0a2d8ec97ba6d..94f71580901cf 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java @@ -132,8 +132,7 @@ public class AuthContainerView extends LinearLayout private final OnBackInvokedCallback mBackCallback = this::onBackInvoked; private final @Background DelayableExecutor mBackgroundExecutor; - private int mOrientation; - private boolean mSkipFirstLostFocus = false; + private boolean mIsOrientationChanged = false; // Non-null only if the dialog is in the act of dismissing and has not sent the reason yet. @Nullable @AuthDialogCallback.DismissedReason private Integer mPendingCallbackReason; @@ -444,6 +443,7 @@ public class AuthContainerView extends LinearLayout @Override public void onOrientationChanged() { maybeUpdatePositionForUdfps(true /* invalidate */); + mIsOrientationChanged = true; } @Override @@ -452,8 +452,8 @@ public class AuthContainerView extends LinearLayout if (!hasWindowFocus) { //it's a workaround to avoid closing BP incorrectly //BP gets a onWindowFocusChanged(false) and then gets a onWindowFocusChanged(true) - if (mSkipFirstLostFocus) { - mSkipFirstLostFocus = false; + if (mIsOrientationChanged) { + mIsOrientationChanged = false; return; } Log.v(TAG, "Lost window focus, dismissing the dialog"); @@ -465,9 +465,6 @@ public class AuthContainerView extends LinearLayout public void onAttachedToWindow() { super.onAttachedToWindow(); - //save the first orientation - mOrientation = getResources().getConfiguration().orientation; - mWakefulnessLifecycle.addObserver(this); if (Utils.isBiometricAllowed(mConfig.mPromptInfo)) { @@ -623,7 +620,7 @@ public class AuthContainerView extends LinearLayout } if (savedState != null) { - mSkipFirstLostFocus = savedState.getBoolean( + mIsOrientationChanged = savedState.getBoolean( AuthDialog.KEY_BIOMETRIC_ORIENTATION_CHANGED); } @@ -717,9 +714,7 @@ public class AuthContainerView extends LinearLayout mBiometricView != null && mCredentialView == null); outState.putBoolean(AuthDialog.KEY_CREDENTIAL_SHOWING, mCredentialView != null); - if (mOrientation != getResources().getConfiguration().orientation) { - outState.putBoolean(AuthDialog.KEY_BIOMETRIC_ORIENTATION_CHANGED, true); - } + outState.putBoolean(AuthDialog.KEY_BIOMETRIC_ORIENTATION_CHANGED, mIsOrientationChanged); if (mBiometricView != null) { mBiometricView.onSaveState(outState); diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt index d1107c6129775..eaef159e90208 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt @@ -160,6 +160,25 @@ class AuthContainerViewTest : SysuiTestCase() { assertThat(container.parent).isNull() } + @Test + fun testFocusLossAfterRotating() { + val container = initializeFingerprintContainer() + waitForIdleSync() + + val requestID = authContainer?.requestId ?: 0L + + verify(callback).onDialogAnimatedIn(requestID) + container.onOrientationChanged() + container.onWindowFocusChanged(false) + waitForIdleSync() + + verify(callback, never()).onDismissed( + eq(AuthDialogCallback.DISMISSED_USER_CANCELED), + eq(null), /* credentialAttestation */ + eq(requestID) + ) + } + @Test fun testDismissesOnFocusLoss_hidesKeyboardWhenVisible() { val container = initializeFingerprintContainer(