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

Commit 4e4a6025 authored by Steve Elliott's avatar Steve Elliott
Browse files

[flexiglass] Move to prev scene on dismiss bouncer

We track the previous scene via SceneInteractor.previousScene, and
derive the BouncerScene#destinationScenes flow from it.

Flag: ACONFIG com.android.systemui.scene_container DEVELOPMENT
Fixes: 332967776
Test: manually verify that entering the bouncer from QS and then
dismissing returns to QS scene.

Change-Id: Ib58c628ead27be8af824276c00edb67420025167
parent 33b336fb
Loading
Loading
Loading
Loading
+1 −12
Original line number Diff line number Diff line
@@ -22,11 +22,8 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import com.android.compose.animation.scene.Back
import com.android.compose.animation.scene.ElementKey
import com.android.compose.animation.scene.SceneScope
import com.android.compose.animation.scene.Swipe
import com.android.compose.animation.scene.SwipeDirection
import com.android.compose.animation.scene.UserAction
import com.android.compose.animation.scene.UserActionResult
import com.android.systemui.bouncer.ui.BouncerDialogFactory
@@ -35,9 +32,7 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.ui.composable.ComposableScene
import javax.inject.Inject
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow

object Bouncer {
    object Elements {
@@ -57,13 +52,7 @@ constructor(
    override val key = Scenes.Bouncer

    override val destinationScenes: StateFlow<Map<UserAction, UserActionResult>> =
        MutableStateFlow(
                mapOf(
                    Back to UserActionResult(Scenes.Lockscreen),
                    Swipe(SwipeDirection.Down) to UserActionResult(Scenes.Lockscreen),
                )
            )
            .asStateFlow()
        viewModel.destinationScenes

    @Composable
    override fun SceneScope.Content(
+24 −0
Original line number Diff line number Diff line
@@ -18,6 +18,10 @@ package com.android.systemui.bouncer.ui.viewmodel

import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.compose.animation.scene.Back
import com.android.compose.animation.scene.Swipe
import com.android.compose.animation.scene.SwipeDirection
import com.android.compose.animation.scene.UserActionResult
import com.android.systemui.SysuiTestCase
import com.android.systemui.authentication.data.repository.FakeAuthenticationRepository
import com.android.systemui.authentication.data.repository.fakeAuthenticationRepository
@@ -34,7 +38,10 @@ import com.android.systemui.flags.Flags
import com.android.systemui.flags.fakeFeatureFlagsClassic
import com.android.systemui.kosmos.testScope
import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.shared.model.fakeSceneDataSource
import com.android.systemui.testKosmos
import com.android.systemui.truth.containsEntriesExactly
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertWithMessage
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -193,6 +200,23 @@ class BouncerViewModelTest : SysuiTestCase() {
            assertThat(isFoldSplitRequired).isTrue()
        }

    @Test
    fun destinationScenes() =
        testScope.runTest {
            val destinationScenes by collectLastValue(underTest.destinationScenes)
            kosmos.fakeSceneDataSource.changeScene(Scenes.QuickSettings)
            runCurrent()

            kosmos.fakeSceneDataSource.changeScene(Scenes.Bouncer)
            runCurrent()

            assertThat(destinationScenes)
                .containsEntriesExactly(
                    Back to UserActionResult(Scenes.QuickSettings),
                    Swipe(SwipeDirection.Down) to UserActionResult(Scenes.QuickSettings),
                )
        }

    private fun authMethodsToTest(): List<AuthenticationMethodModel> {
        return listOf(None, Pin, Password, Pattern, Sim)
    }
+32 −0
Original line number Diff line number Diff line
@@ -286,6 +286,38 @@ class SceneContainerStartableTest : SysuiTestCase() {
            assertThat(currentSceneKey).isEqualTo(Scenes.Gone)
        }

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

            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)

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

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

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

    @Test
    fun switchFromLockscreenToGoneWhenDeviceUnlocksWithBypassOn() =
        testScope.runTest {
+8 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.systemui.bouncer.domain.interactor

import com.android.compose.animation.scene.SceneKey
import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor
import com.android.systemui.authentication.domain.interactor.AuthenticationResult
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel.Sim
@@ -26,6 +27,8 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.deviceentry.domain.interactor.DeviceEntryFaceAuthInteractor
import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.model.Scenes
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.async
@@ -47,6 +50,7 @@ constructor(
    private val deviceEntryFaceAuthInteractor: DeviceEntryFaceAuthInteractor,
    private val falsingInteractor: FalsingInteractor,
    private val powerInteractor: PowerInteractor,
    sceneInteractor: SceneInteractor,
) {
    private val _onIncorrectBouncerInput = MutableSharedFlow<Unit>()
    val onIncorrectBouncerInput: SharedFlow<Unit> = _onIncorrectBouncerInput
@@ -80,6 +84,10 @@ constructor(
            }
            .map {}

    /** The scene to show when bouncer is dismissed. */
    val dismissDestination: Flow<SceneKey> =
        sceneInteractor.previousScene.map { it ?: Scenes.Lockscreen }

    /** Notifies that the user has places down a pointer, not necessarily dragging just yet. */
    fun onDown() {
        falsingInteractor.avoidGesture()
+26 −6
Original line number Diff line number Diff line
@@ -21,6 +21,12 @@ import android.app.admin.DevicePolicyResources
import android.content.Context
import android.graphics.Bitmap
import androidx.core.graphics.drawable.toBitmap
import com.android.compose.animation.scene.Back
import com.android.compose.animation.scene.SceneKey
import com.android.compose.animation.scene.Swipe
import com.android.compose.animation.scene.SwipeDirection
import com.android.compose.animation.scene.UserAction
import com.android.compose.animation.scene.UserActionResult
import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
import com.android.systemui.authentication.shared.model.AuthenticationWipeModel
@@ -35,6 +41,7 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.inputmethod.domain.interactor.InputMethodInteractor
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.user.domain.interactor.SelectedUserInteractor
import com.android.systemui.user.ui.viewmodel.UserActionViewModel
import com.android.systemui.user.ui.viewmodel.UserSwitcherViewModel
@@ -82,6 +89,15 @@ class BouncerViewModel(
                initialValue = null,
            )

    val destinationScenes: StateFlow<Map<UserAction, UserActionResult>> =
        bouncerInteractor.dismissDestination
            .map(::destinationSceneMap)
            .stateIn(
                applicationScope,
                SharingStarted.WhileSubscribed(),
                initialValue = destinationSceneMap(Scenes.Lockscreen),
            )

    val message: BouncerMessageViewModel = bouncerMessageViewModel

    val userSwitcherDropdown: StateFlow<List<UserSwitcherDropdownItemViewModel>> =
@@ -310,8 +326,7 @@ class BouncerViewModel(
                { message },
                failedAttempts,
                remainingAttempts,
            )
                ?: message
            ) ?: message
        } else {
            message
        }
@@ -328,8 +343,7 @@ class BouncerViewModel(
                    .KEYGUARD_DIALOG_FAILED_ATTEMPTS_ERASING_PROFILE,
                { message },
                failedAttempts,
            )
                ?: message
            ) ?: message
        } else {
            message
        }
@@ -357,6 +371,12 @@ class BouncerViewModel(
        }
    }

    private fun destinationSceneMap(prevScene: SceneKey) =
        mapOf(
            Back to UserActionResult(prevScene),
            Swipe(SwipeDirection.Down) to UserActionResult(prevScene),
        )

    data class DialogViewModel(
        val text: String,

@@ -400,13 +420,13 @@ object BouncerViewModelModule {
            simBouncerInteractor = simBouncerInteractor,
            authenticationInteractor = authenticationInteractor,
            selectedUserInteractor = selectedUserInteractor,
            devicePolicyManager = devicePolicyManager,
            bouncerMessageViewModel = bouncerMessageViewModel,
            flags = flags,
            selectedUser = userSwitcherViewModel.selectedUser,
            users = userSwitcherViewModel.users,
            userSwitcherMenu = userSwitcherViewModel.menu,
            actionButton = actionButtonInteractor.actionButton,
            devicePolicyManager = devicePolicyManager,
            bouncerMessageViewModel = bouncerMessageViewModel,
        )
    }
}
Loading