diff options
| author | 2024-03-07 22:10:52 +0000 | |
|---|---|---|
| committer | 2024-03-25 13:25:41 +0000 | |
| commit | df8a36630539838468eb598a4d2d9ec00bb87d71 (patch) | |
| tree | b0940f726d1acd7c6ad0717fdc53d4911fb8ea29 | |
| parent | ce4f1155b930b185f9e9dc6a30fbff2f9fbfea46 (diff) | |
Hide the alternate bouncer after dismiss actions have run
If we hide the alternate bouncer too early, then
sometimes the dismiss action intent will fail. This
CL moves the logic for hiding the alternate bouncer
after a successful biometric auth to when the keyguard
transition to gone is finished.
Flag: None
Flag: ACONFIG com.android.systemui.device_entry_udfps_refactor TEAMFOOD
Fixes: 327570518
Test: test with and without udfps_refactor enabled
Test: atest StatusBarKeyguardViewManagerTest AlternateBouncerViewModelTest
Change-Id: I24c98eeec6c76f777033be88ee2d0d54d31e71f4
Merged-In: I24c98eeec6c76f777033be88ee2d0d54d31e71f4
(cherry picked from commit d553f16a292d4ba7f00ea245884291fc6265a852)
7 files changed, 111 insertions, 1 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractor.kt index 8c87b0c78ea7..893887fad176 100644 --- a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractor.kt @@ -93,6 +93,8 @@ constructor( val keyguardAuthenticatedPrimaryAuth: Flow<Int> = repository.keyguardAuthenticatedPrimaryAuth val keyguardAuthenticatedBiometrics: Flow<Boolean> = repository.keyguardAuthenticatedBiometrics.filterNotNull() + val keyguardAuthenticatedBiometricsHandled: Flow<Unit> = + repository.keyguardAuthenticatedBiometrics.filter { it == null }.map {} val userRequestedBouncerWhenAlreadyAuthenticated: Flow<Int> = repository.userRequestedBouncerWhenAlreadyAuthenticated.filterNotNull() val isShowing: StateFlow<Boolean> = repository.primaryBouncerShow diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/KeyguardBouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/KeyguardBouncerViewModel.kt index 1c9d1f01e89e..e1fea5f9c62a 100644 --- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/KeyguardBouncerViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/KeyguardBouncerViewModel.kt @@ -23,12 +23,14 @@ import com.android.systemui.bouncer.shared.model.BouncerShowMessageModel import com.android.systemui.bouncer.ui.BouncerView import com.android.systemui.bouncer.ui.BouncerViewDelegate import javax.inject.Inject +import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.merge /** Models UI state for the lock screen bouncer; handles user input. */ +@ExperimentalCoroutinesApi class KeyguardBouncerViewModel @Inject constructor( diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerViewBinder.kt index d40021007a2b..3a2781c81f7c 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerViewBinder.kt @@ -102,9 +102,16 @@ object AlternateBouncerViewBinder { launch { viewModel.scrimAlpha.collect { + val wasVisible = alternateBouncerViewContainer.visibility == View.VISIBLE alternateBouncerViewContainer.visibility = if (it < .1f) View.INVISIBLE else View.VISIBLE scrim.viewAlpha = it + if ( + wasVisible && alternateBouncerViewContainer.visibility == View.INVISIBLE + ) { + // view is no longer visible + viewModel.hideAlternateBouncer() + } } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerViewModel.kt index 2526f0aec796..10a9e3bba7f0 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerViewModel.kt @@ -89,4 +89,8 @@ constructor( fun showPrimaryBouncer() { statusBarKeyguardViewManager.showPrimaryBouncer(/* scrimmed */ true) } + + fun hideAlternateBouncer() { + statusBarKeyguardViewManager.hideAlternateBouncer(false) + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java index d1055c77ab8f..9cfedaab89f3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java @@ -76,6 +76,8 @@ import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInterac import com.android.systemui.keyguard.domain.interactor.WindowManagerLockscreenVisibilityInteractor; import com.android.systemui.keyguard.shared.model.DismissAction; import com.android.systemui.keyguard.shared.model.KeyguardDone; +import com.android.systemui.keyguard.shared.model.KeyguardState; +import com.android.systemui.keyguard.shared.model.TransitionStep; import com.android.systemui.navigationbar.NavigationBarView; import com.android.systemui.navigationbar.NavigationModeController; import com.android.systemui.navigationbar.TaskbarDelegate; @@ -101,6 +103,8 @@ import com.android.systemui.util.kotlin.JavaAdapter; import dagger.Lazy; +import kotlin.Unit; + import java.io.PrintWriter; import java.util.ArrayList; import java.util.HashSet; @@ -112,6 +116,7 @@ import javax.inject.Inject; import kotlinx.coroutines.CoroutineDispatcher; import kotlinx.coroutines.ExperimentalCoroutinesApi; +import kotlinx.coroutines.Job; /** * Manages creating, showing, hiding and resetting the keyguard within the status bar. Calls back @@ -158,6 +163,9 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb private final BouncerView mPrimaryBouncerView; private final Lazy<ShadeController> mShadeController; + private Job mListenForAlternateBouncerTransitionSteps = null; + private Job mListenForKeyguardAuthenticatedBiometricsHandled = null; + // Local cache of expansion events, to avoid duplicates private float mFraction = -1f; private boolean mTracking = false; @@ -482,6 +490,26 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb mDockManager.addListener(mDockEventListener); mIsDocked = mDockManager.isDocked(); } + if (mListenForAlternateBouncerTransitionSteps != null) { + mListenForAlternateBouncerTransitionSteps.cancel(null); + } + mListenForAlternateBouncerTransitionSteps = null; + if (mListenForKeyguardAuthenticatedBiometricsHandled != null) { + mListenForKeyguardAuthenticatedBiometricsHandled.cancel(null); + } + mListenForKeyguardAuthenticatedBiometricsHandled = null; + if (!DeviceEntryUdfpsRefactor.isEnabled()) { + mListenForAlternateBouncerTransitionSteps = mJavaAdapter.alwaysCollectFlow( + mKeyguardTransitionInteractor.transitionStepsFromState( + KeyguardState.ALTERNATE_BOUNCER), + this::consumeFromAlternateBouncerTransitionSteps + ); + + mListenForKeyguardAuthenticatedBiometricsHandled = mJavaAdapter.alwaysCollectFlow( + mPrimaryBouncerInteractor.getKeyguardAuthenticatedBiometricsHandled(), + this::consumeKeyguardAuthenticatedBiometricsHandled + ); + } if (KeyguardWmStateRefactor.isEnabled()) { // Show the keyguard views whenever we've told WM that the lockscreen is visible. @@ -500,6 +528,22 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb } } + @VisibleForTesting + void consumeFromAlternateBouncerTransitionSteps(TransitionStep step) { + hideAlternateBouncer(false); + } + + /** + * Required without fix for b/328643370: missing AlternateBouncer (when occluded) => Gone + * transition. + */ + @VisibleForTesting + void consumeKeyguardAuthenticatedBiometricsHandled(Unit handled) { + if (mAlternateBouncerInteractor.isVisibleState()) { + hideAlternateBouncer(false); + } + } + private void consumeShowStatusBarKeyguardView(boolean show) { if (show != mLastShowing) { if (show) { @@ -1441,7 +1485,6 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb mPrimaryBouncerInteractor.notifyKeyguardAuthenticatedBiometrics(strongAuth); if (mAlternateBouncerInteractor.isVisibleState()) { - hideAlternateBouncer(false); executeAfterKeyguardGoneAction(); } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerViewModelTest.kt index 87391cce9136..d410dac1b2e4 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerViewModelTest.kt @@ -28,6 +28,7 @@ import com.android.systemui.keyguard.shared.model.TransitionStep import com.android.systemui.kosmos.testScope import com.android.systemui.statusbar.phone.statusBarKeyguardViewManager import com.android.systemui.testKosmos +import com.android.systemui.util.mockito.any import com.google.common.collect.Range import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -36,6 +37,7 @@ import kotlinx.coroutines.test.runTest import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.JUnit4 +import org.mockito.Mockito.verify @ExperimentalCoroutinesApi @RunWith(JUnit4::class) @@ -48,6 +50,20 @@ class AlternateBouncerViewModelTest : SysuiTestCase() { private val underTest = kosmos.alternateBouncerViewModel @Test + fun showPrimaryBouncer() = + testScope.runTest { + underTest.showPrimaryBouncer() + verify(statusBarKeyguardViewManager).showPrimaryBouncer(any()) + } + + @Test + fun hideAlternateBouncer() = + testScope.runTest { + underTest.hideAlternateBouncer() + verify(statusBarKeyguardViewManager).hideAlternateBouncer(any()) + } + + @Test fun transitionToAlternateBouncer_scrimAlphaUpdate() = testScope.runTest { val scrimAlphas by collectValues(underTest.scrimAlpha) diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java index 3666248d1783..a71555688e48 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java @@ -82,6 +82,9 @@ import com.android.systemui.keyguard.domain.interactor.KeyguardDismissActionInte import com.android.systemui.keyguard.domain.interactor.KeyguardSurfaceBehindInteractor; import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor; import com.android.systemui.keyguard.domain.interactor.WindowManagerLockscreenVisibilityInteractor; +import com.android.systemui.keyguard.shared.model.KeyguardState; +import com.android.systemui.keyguard.shared.model.TransitionState; +import com.android.systemui.keyguard.shared.model.TransitionStep; import com.android.systemui.navigationbar.NavigationModeController; import com.android.systemui.navigationbar.TaskbarDelegate; import com.android.systemui.plugins.ActivityStarter; @@ -101,6 +104,8 @@ import com.android.systemui.util.kotlin.JavaAdapter; import com.google.common.truth.Truth; +import kotlin.Unit; + import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -1039,4 +1044,35 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase { verify(mCentralSurfaces, never()).hideKeyguard(); verify(mPrimaryBouncerInteractor, never()).show(true); } + + @Test + public void altBouncerNotVisible_keyguardAuthenticatedBiometricsHandled() { + clearInvocations(mAlternateBouncerInteractor); + when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(false); + mStatusBarKeyguardViewManager.consumeKeyguardAuthenticatedBiometricsHandled(Unit.INSTANCE); + verify(mAlternateBouncerInteractor, never()).hide(); + } + + @Test + public void altBouncerVisible_keyguardAuthenticatedBiometricsHandled() { + clearInvocations(mAlternateBouncerInteractor); + when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(true); + mStatusBarKeyguardViewManager.consumeKeyguardAuthenticatedBiometricsHandled(Unit.INSTANCE); + verify(mAlternateBouncerInteractor).hide(); + } + + @Test + public void fromAlternateBouncerTransitionStep() { + clearInvocations(mAlternateBouncerInteractor); + mStatusBarKeyguardViewManager.consumeFromAlternateBouncerTransitionSteps( + new TransitionStep( + /* from */ KeyguardState.ALTERNATE_BOUNCER, + /* to */ KeyguardState.GONE, + /* value */ 1f, + TransitionState.FINISHED, + "StatusBarKeyguardViewManagerTest" + ) + ); + verify(mAlternateBouncerInteractor).hide(); + } } |