From 1ef4cb315291c1f11e3860efab5908bee6f92bc7 Mon Sep 17 00:00:00 2001 From: Vincent Wang Date: Fri, 7 Oct 2022 08:35:19 +0000 Subject: [PATCH] Fix UDFPS icon of Biometric Prompt has no response after rotation If configurationChanged occurs when playing BP showing animation, onDialogAnimatedIn() might not be executed. It causes that BiometricService doesn't get the notify from SysUI. To avoid this problem, check the status of BP, if BP is still playing intro animation, cancel the animation & force executed onDialogAnimatedIn() before closing old BP. Bug: b/249698846 Test: 1. Enroll fingerprints & enable auto rotate 2. Play Store logged in user account 3. Open "Play Store" and tap "Add another account" 4. Rotate the DUT from portrait to landscape before the end of BP showing animation Change-Id: Id8d7601cc98d0071d53b36e93962bb800c9bf3bd --- .../systemui/biometrics/AuthContainerView.java | 16 +++++++++++++++- .../systemui/biometrics/AuthContainerViewTest.kt | 16 ++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java index e74d8106b2f06..029cde9420f23 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java @@ -127,7 +127,7 @@ public class AuthContainerView extends LinearLayout private final ScrollView mBiometricScrollView; private final View mPanelView; private final float mTranslationY; - @ContainerState private int mContainerState = STATE_UNKNOWN; + @VisibleForTesting @ContainerState int mContainerState = STATE_UNKNOWN; private final Set mFailedModalities = new HashSet(); private final OnBackInvokedCallback mBackCallback = this::onBackInvoked; @@ -657,11 +657,25 @@ public class AuthContainerView extends LinearLayout wm.addView(this, getLayoutParams(mWindowToken, mConfig.mPromptInfo.getTitle())); } + private void forceExecuteAnimatedIn() { + if (mContainerState == STATE_ANIMATING_IN) { + //clear all animators + if (mCredentialView != null && mCredentialView.isAttachedToWindow()) { + mCredentialView.animate().cancel(); + } + mPanelView.animate().cancel(); + mBiometricView.animate().cancel(); + animate().cancel(); + onDialogAnimatedIn(); + } + } + @Override public void dismissWithoutCallback(boolean animate) { if (animate) { animateAway(false /* sendReason */, 0 /* reason */); } else { + forceExecuteAnimatedIn(); removeWindowIfAttached(); } } 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 d52612b000bc7..e8c760c3e1406 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt @@ -52,6 +52,7 @@ import org.mockito.Mockito.anyInt import org.mockito.Mockito.anyLong import org.mockito.Mockito.eq import org.mockito.Mockito.never +import org.mockito.Mockito.times import org.mockito.Mockito.verify import org.mockito.Mockito.`when` as whenever import org.mockito.junit.MockitoJUnit @@ -122,6 +123,21 @@ class AuthContainerViewTest : SysuiTestCase() { verify(callback).onDialogAnimatedIn(authContainer?.requestId ?: 0L) } + @Test + fun testDismissBeforeIntroEnd() { + val container = initializeFingerprintContainer() + waitForIdleSync() + + // STATE_ANIMATING_IN = 1 + container?.mContainerState = 1 + + container.dismissWithoutCallback(false) + + // the first time is triggered by initializeFingerprintContainer() + // the second time was triggered by dismissWithoutCallback() + verify(callback, times(2)).onDialogAnimatedIn(authContainer?.requestId ?: 0L) + } + @Test fun testDismissesOnFocusLoss() { val container = initializeFingerprintContainer()