diff options
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 7dd328a4aad0..14e934fab701 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; @@ -105,6 +107,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; @@ -116,6 +120,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 @@ -163,6 +168,9 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb private final Lazy<ShadeController> mShadeController; private final Lazy<SceneInteractor> mSceneInteractorLazy; + private Job mListenForAlternateBouncerTransitionSteps = null; + private Job mListenForKeyguardAuthenticatedBiometricsHandled = null; + // Local cache of expansion events, to avoid duplicates private float mFraction = -1f; private boolean mTracking = false; @@ -491,6 +499,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. @@ -514,6 +542,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) { @@ -1458,7 +1502,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 562aa6a4f497..b0b9bec4f721 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; @@ -103,6 +106,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; @@ -1045,4 +1050,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(); + } } |