Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3e6d3d64 authored by Beverly's avatar Beverly
Browse files

Always hide alternate bouncer if it's showing & device unlocked

Also make sure to stay on the current scene if the alternate
bouncer was showing when the device was unlocked if
the shade should continue showing.

The AlternateBouncer isn't it's own scene,
so hiding it is sufficient on
unlocked to show the desired UI when the shade should
be kept open (this differs being unlocked from
the primary bouncer since the primary bouncer is its
own scene).

Bug: 353955910
Flag: com.android.systemui.scene_container
Test: with SFPS enrolled, pull down QS over
the lockscreen and tap on the "edit" icon. Authenticate
with SFPS from the alternate bouncer and observe the device
stays on the quick settings scene with the "Edit QS" UI
showing.
Test: atest SceneContainerStartableTest

Change-Id: I61d6982cec4b70452aa43490227ec21b45f61140
parent 254b854c
Loading
Loading
Loading
Loading
+62 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import com.android.systemui.authentication.data.repository.FakeAuthenticationRep
import com.android.systemui.authentication.data.repository.fakeAuthenticationRepository
import com.android.systemui.authentication.domain.interactor.authenticationInteractor
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
import com.android.systemui.bouncer.data.repository.fakeKeyguardBouncerRepository
import com.android.systemui.bouncer.domain.interactor.bouncerInteractor
import com.android.systemui.bouncer.shared.logging.BouncerUiEvent
import com.android.systemui.classifier.FalsingCollector
@@ -109,6 +110,7 @@ class SceneContainerStartableTest : SysuiTestCase() {
    private val sceneInteractor by lazy { kosmos.sceneInteractor }
    private val bouncerInteractor by lazy { kosmos.bouncerInteractor }
    private val faceAuthRepository by lazy { kosmos.fakeDeviceEntryFaceAuthRepository }
    private val bouncerRepository by lazy { kosmos.fakeKeyguardBouncerRepository }
    private val sysUiState = kosmos.sysUiState
    private val falsingCollector = mock<FalsingCollector>().also { kosmos.falsingCollector = it }
    private val fakeSceneDataSource = kosmos.fakeSceneDataSource
@@ -274,6 +276,66 @@ class SceneContainerStartableTest : SysuiTestCase() {
            assertThat(currentSceneKey).isEqualTo(Scenes.Gone)
        }

    @Test
    fun switchFromLockscreenToGoneAndHideAltBouncerWhenDeviceUnlocked() =
        testScope.runTest {
            val alternateBouncerVisible by
                collectLastValue(bouncerRepository.alternateBouncerVisible)
            val currentSceneKey by collectLastValue(sceneInteractor.currentScene)

            bouncerRepository.setAlternateVisible(true)
            assertThat(alternateBouncerVisible).isTrue()

            prepareState(
                authenticationMethod = AuthenticationMethodModel.Pin,
                isDeviceUnlocked = false,
                initialSceneKey = Scenes.Lockscreen,
            )
            assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen)
            underTest.start()

            kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
                SuccessFingerprintAuthenticationStatus(0, true)
            )

            assertThat(currentSceneKey).isEqualTo(Scenes.Gone)
            assertThat(alternateBouncerVisible).isFalse()
        }

    @Test
    fun stayOnCurrentSceneAndHideAltBouncerWhenDeviceUnlocked_whenLeaveOpenShade() =
        testScope.runTest {
            val alternateBouncerVisible by
                collectLastValue(bouncerRepository.alternateBouncerVisible)
            val currentSceneKey by collectLastValue(sceneInteractor.currentScene)

            kosmos.sysuiStatusBarStateController.leaveOpen = true // leave shade open
            bouncerRepository.setAlternateVisible(true)
            assertThat(alternateBouncerVisible).isTrue()

            val transitionState =
                prepareState(
                    authenticationMethod = AuthenticationMethodModel.Pin,
                    isDeviceUnlocked = false,
                    initialSceneKey = Scenes.Lockscreen,
                )
            assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen)
            underTest.start()
            runCurrent()

            sceneInteractor.changeScene(Scenes.QuickSettings, "switching to qs for test")
            transitionState.value = ObservableTransitionState.Idle(Scenes.QuickSettings)
            runCurrent()
            assertThat(currentSceneKey).isEqualTo(Scenes.QuickSettings)

            kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
                SuccessFingerprintAuthenticationStatus(0, true)
            )

            assertThat(currentSceneKey).isEqualTo(Scenes.QuickSettings)
            assertThat(alternateBouncerVisible).isFalse()
        }

    @Test
    fun switchFromBouncerToQuickSettingsWhenDeviceUnlocked_whenLeaveOpenShade() =
        testScope.runTest {
+25 −20
Original line number Diff line number Diff line
@@ -154,7 +154,6 @@ constructor(
            handleKeyguardEnabledness()
            notifyKeyguardDismissCallbacks()
            refreshLockscreenEnabled()
            handleHideAlternateBouncerOnTransitionToGone()
        } else {
            sceneLogger.logFrameworkEnabled(
                isEnabled = false,
@@ -357,11 +356,10 @@ constructor(
                                )
                        }
                    val isOnLockscreen = renderedScenes.contains(Scenes.Lockscreen)
                    val isOnBouncer =
                        renderedScenes.contains(Scenes.Bouncer) ||
                            alternateBouncerInteractor.isVisibleState()
                    val isAlternateBouncerVisible = alternateBouncerInteractor.isVisibleState()
                    val isOnPrimaryBouncer = renderedScenes.contains(Scenes.Bouncer)
                    if (!deviceUnlockStatus.isUnlocked) {
                        return@mapNotNull if (isOnLockscreen || isOnBouncer) {
                        return@mapNotNull if (isOnLockscreen || isOnPrimaryBouncer) {
                            // Already on lockscreen or bouncer, no need to change scenes.
                            null
                        } else {
@@ -373,15 +371,32 @@ constructor(
                    }

                    if (
                        isOnBouncer &&
                        isOnPrimaryBouncer &&
                            deviceUnlockStatus.deviceUnlockSource == DeviceUnlockSource.TrustAgent
                    ) {
                        uiEventLogger.log(BouncerUiEvent.BOUNCER_DISMISS_EXTENDED_ACCESS)
                    }
                    when {
                        isOnBouncer ->
                            // When the device becomes unlocked in Bouncer, go to previous scene,
                            // or Gone.
                        isAlternateBouncerVisible -> {
                            // When the device becomes unlocked when the alternate bouncer is
                            // showing, always hide the alternate bouncer...
                            alternateBouncerInteractor.hide()

                            // ... and go to Gone or stay on the current scene
                            if (
                                isOnLockscreen ||
                                    !statusBarStateController.leaveOpenOnKeyguardHide()
                            ) {
                                Scenes.Gone to
                                    "device was unlocked with alternate bouncer showing" +
                                        " and shade didn't need to be left open"
                            } else {
                                null
                            }
                        }
                        isOnPrimaryBouncer ->
                            // When the device becomes unlocked in primary Bouncer,
                            // go to previous scene or Gone.
                            if (
                                previousScene.value == Scenes.Lockscreen ||
                                    !statusBarStateController.leaveOpenOnKeyguardHide()
@@ -392,7 +407,7 @@ constructor(
                            } else {
                                val prevScene = previousScene.value
                                (prevScene ?: Scenes.Gone) to
                                    "device was unlocked with bouncer showing," +
                                    "device was unlocked with primary bouncer showing," +
                                        " from sceneKey=$prevScene"
                            }
                        isOnLockscreen ->
@@ -785,14 +800,4 @@ constructor(
                .collectLatest { deviceEntryInteractor.refreshLockscreenEnabled() }
        }
    }

    private fun handleHideAlternateBouncerOnTransitionToGone() {
        applicationScope.launch {
            sceneInteractor.transitionState
                .map { it.isIdle(Scenes.Gone) }
                .distinctUntilChanged()
                .filter { it }
                .collectLatest { alternateBouncerInteractor.hide() }
        }
    }
}